feat: expand cockpit integrations and support workflows
Add Phoenix remote desktop, action connector, documentation engine, and gamification support. Refactor support-case processing and search/action UI, and update installer assets and dependencies.
This commit is contained in:
126
FasdDesktopUi/Basics/Helper/ActionDisplayTypeInspector.cs
Normal file
126
FasdDesktopUi/Basics/Helper/ActionDisplayTypeInspector.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using C4IT.FASD.Base;
|
||||
using FasdDesktopUi.Basics.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Helper
|
||||
{
|
||||
internal static class ActionDisplayTypeInspector
|
||||
{
|
||||
internal static enumActionDisplayType GetDisplayType(cFasdBaseConfigMenuItem menuDataDefinition, cNamedParameterList namedParameterEntries, IEnumerable<enumFasdInformationClass> availableInformationClasses)
|
||||
{
|
||||
if (menuDataDefinition.IsHidden)
|
||||
return enumActionDisplayType.hidden;
|
||||
else if (IsEnabled(menuDataDefinition, namedParameterEntries, availableInformationClasses))
|
||||
return enumActionDisplayType.enabled;
|
||||
else
|
||||
return enumActionDisplayType.disabled;
|
||||
}
|
||||
|
||||
private static bool IsEnabled(cFasdBaseConfigMenuItem menuDataDefinition, cNamedParameterList namedParameterEntries, IEnumerable<enumFasdInformationClass> availableInformationClasses)
|
||||
{
|
||||
if (!HasRequiredInformationClasses(menuDataDefinition, availableInformationClasses))
|
||||
return false;
|
||||
|
||||
if (menuDataDefinition is cFasdQuickAction quickActionDefinition && !IsQuickActionEnabled(quickActionDefinition, namedParameterEntries))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsQuickActionEnabled(cFasdQuickAction quickActionDefinition, cNamedParameterList namedParameterEntries)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(quickActionDefinition.CheckFilePath) && !FileExists(quickActionDefinition.CheckFilePath))
|
||||
return false;
|
||||
|
||||
if (!string.IsNullOrEmpty(quickActionDefinition.CheckRegistryEntry) && !RegistryEntryExists(quickActionDefinition.CheckRegistryEntry))
|
||||
return false;
|
||||
|
||||
if (namedParameterEntries is null)
|
||||
return true;
|
||||
|
||||
cNamedParameterEntryBase namedParameterValue = null;
|
||||
if (!string.IsNullOrEmpty(quickActionDefinition.CheckNamedParameter) && !namedParameterEntries.TryGetValue(quickActionDefinition.CheckNamedParameter, out namedParameterValue))
|
||||
return false;
|
||||
|
||||
if (namedParameterValue != null && quickActionDefinition.CheckNamedParameterValues != null && !quickActionDefinition.CheckNamedParameterValues.Contains(namedParameterValue.GetValue()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool HasRequiredInformationClasses(cFasdBaseConfigMenuItem definition, IEnumerable<enumFasdInformationClass> availableInformationClasses)
|
||||
{
|
||||
if (definition?.InformationClasses is null)
|
||||
return true;
|
||||
|
||||
if (definition.InformationClasses.Count == 0)
|
||||
return true;
|
||||
|
||||
if (definition.InformationClasses.Any(i => !availableInformationClasses.Contains(i)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool FileExists(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return true;
|
||||
|
||||
var specialFolders = Enum.GetValues(typeof(Environment.SpecialFolder)).Cast<Environment.SpecialFolder>();
|
||||
|
||||
foreach (var specialFolder in specialFolders)
|
||||
{
|
||||
string specialFolderName = $"%{specialFolder}%";
|
||||
string specialFolderPath = Environment.GetFolderPath(specialFolder);
|
||||
path = path.Replace(specialFolderName, specialFolderPath);
|
||||
}
|
||||
|
||||
path = Environment.ExpandEnvironmentVariables(path);
|
||||
return File.Exists(path);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool RegistryEntryExists(string entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(entry))
|
||||
return true;
|
||||
|
||||
string rootPath = entry.Split('\\')[0];
|
||||
entry = entry.Replace(rootPath, "").Remove(0, 1);
|
||||
|
||||
switch (rootPath)
|
||||
{
|
||||
case "HKEY_LOCAL_MACHINE":
|
||||
case "HKLM":
|
||||
return Registry.LocalMachine.OpenSubKey(entry) != null;
|
||||
case "HKEY_CURRENT_USER":
|
||||
case "HKCU":
|
||||
return Registry.CurrentUser.OpenSubKey(entry) != null;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
using C4IT.Configuration;
|
||||
using C4IT.F4SD.DisplayFormatting;
|
||||
@@ -27,7 +26,6 @@ using FasdDesktopUi.Pages.SlimPage.Models;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
using static C4IT.FASD.Base.cF4SDHealthCardRawData;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
@@ -80,7 +78,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
{
|
||||
this.dataProvider = dataProvider;
|
||||
_menuDataProvider = new MenuItemDataProvider(dataProvider);
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
cUtility.RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
HistoryData = new cHealthCardHistoryDataHelper(this);
|
||||
@@ -149,7 +147,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
if (informationClasses is null)
|
||||
return null;
|
||||
|
||||
foreach (var healthCard in cF4SDCockpitXmlConfig.Instance?.HealthCardConfig?.HealthCards.Values)
|
||||
foreach (var healthCard in cF4SDCockpitXmlConfig.Instance?.HealthCardConfig?.HealthCards?.Values)
|
||||
{
|
||||
bool found = true;
|
||||
|
||||
@@ -250,7 +248,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
{
|
||||
List<object> output = new List<object>();
|
||||
|
||||
if (healthCardColumn?.Values == null)
|
||||
if (healthCardColumn?.Values == null || startingIndex < 0)
|
||||
return output;
|
||||
|
||||
try
|
||||
@@ -453,13 +451,9 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
|
||||
var stateValue = GetStateValueAt(stateDefinition.DatabaseInfo, dayIndex, isStatic);
|
||||
|
||||
enumHighlightColor? tempColor = null;
|
||||
if (stateValue != null)
|
||||
{
|
||||
tempColor = GetHighlightColor(stateValue, stateDefinition, dayIndex, isStatic);
|
||||
if (tempColor == enumHighlightColor.none && stateValue != null)
|
||||
tempColor = enumHighlightColor.green;
|
||||
}
|
||||
enumHighlightColor? tempColor = GetHighlightColor(stateValue, stateDefinition, dayIndex, isStatic);
|
||||
if (tempColor == enumHighlightColor.none && stateValue != null)
|
||||
tempColor = enumHighlightColor.green;
|
||||
|
||||
if (output == null)
|
||||
output = tempColor;
|
||||
@@ -492,7 +486,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
}
|
||||
else
|
||||
{
|
||||
FormattingOptions options = new FormattingOptions() { ReferenceDate = DateTime.UtcNow.Date.AddDays(columnIndex), TimeZone = TimeZoneInfo.Local };
|
||||
FormattingOptions options = new FormattingOptions() { ReferenceDate = DateTime.UtcNow.Date.AddDays(-columnIndex), TimeZone = TimeZoneInfo.Local };
|
||||
var _c = cUtility.RawValueFormatter.GetDisplayValue(value, Requirements.valueState.DisplayType, options);
|
||||
if (!string.IsNullOrWhiteSpace(_c))
|
||||
cellContent.Content = _c;
|
||||
@@ -689,11 +683,19 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
{
|
||||
if (NamedParameters == null)
|
||||
return false;
|
||||
var _invert = false;
|
||||
if (namedParameter.StartsWith("!"))
|
||||
{
|
||||
_invert = true;
|
||||
namedParameter = namedParameter.Remove(0, 1);
|
||||
}
|
||||
if (!NamedParameters.TryGetValue(namedParameter, out var entry))
|
||||
return false;
|
||||
return _invert;
|
||||
|
||||
var entryValue = entry.GetValue();
|
||||
cConfigRegistryHelper.ReadFromStringBoolean(entryValue, out var result);
|
||||
if (_invert)
|
||||
result = !result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1113,11 +1115,14 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const string defaultCopyTemplateParameterName = "Copy_default";
|
||||
if (!dataProvider.NamedParameterEntries.ContainsKey(defaultCopyTemplateParameterName))
|
||||
{
|
||||
|
||||
string defaultCopyTemplate = cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.DefaultTemplate.Name;
|
||||
dataProvider.NamedParameterEntries.Add(defaultCopyTemplateParameterName, new cNamedParameterEntryCopyTemplate(dataProvider, defaultCopyTemplate));
|
||||
|
||||
dataProvider.NamedParameterEntries.Add(defaultCopyTemplateParameterName, new cNamedParameterEntryCopyTemplate(dataProvider, SelectedHealthCard.DefaultCopyTemplate != null ? SelectedHealthCard.DefaultCopyTemplate : defaultCopyTemplate));
|
||||
}
|
||||
|
||||
foreach (var copyTemplate in cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.CopyTemplates)
|
||||
@@ -1202,8 +1207,8 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
var historySectionValueColumns = new List<DetailsPageDataHistoryColumnModel>(valueColumnCount);
|
||||
for (int i = 0; i < valueColumnCount; i++)
|
||||
{
|
||||
CultureInfo culture = new CultureInfo(cMultiLanguageSupport.CurrentLanguage);
|
||||
var valueColumnHeader = i != 0 ? DateTime.Today.AddDays(-i).ToString(cMultiLanguageSupport.GetItem("Global.Date.Format.ShortDateWithDay", "ddd. dd.MM."), culture) : cMultiLanguageSupport.GetItem("Global.Date.Today");
|
||||
CultureInfo culture = cFasdCockpitConfig.Instance.SelectedCulture;
|
||||
var valueColumnHeader = i != 0 ? DateTime.Today.AddDays(-i).ToString($"ddd. {cUtility.GetShortDatePattern()}") : cMultiLanguageSupport.GetItem("Global.Date.Today");
|
||||
var summaryStatusColor = parent.GetSummaryStatusColor(stateCategoryDefinition.States, false, i);
|
||||
var valueColumn = new DetailsPageDataHistoryColumnModel() { ColumnValues = new List<cDataHistoryValueModel>(), Content = valueColumnHeader, HighlightColor = summaryStatusColor ?? enumHighlightColor.none };
|
||||
historySectionValueColumns.Add(valueColumn);
|
||||
@@ -2165,6 +2170,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
|
||||
bool isDataIncomplete = true;
|
||||
await LoadingRawDataCriticalSection.EnterAsync();
|
||||
|
||||
try
|
||||
{
|
||||
lock (HealthCardRawData)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using C4IT.FASD.Base;
|
||||
using FasdDesktopUi.Basics.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase.Processors;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
@@ -15,7 +16,6 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
internal class MenuItemDataProvider
|
||||
{
|
||||
private readonly cSupportCaseDataProvider _dataProvider;
|
||||
|
||||
private const int defaultPinnedActionCount = 3; //search, notepad, copyTicketInformation
|
||||
|
||||
public MenuItemDataProvider(cSupportCaseDataProvider dataProvider)
|
||||
@@ -58,7 +58,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
return menuItemData;
|
||||
}
|
||||
|
||||
private cMenuDataBase GetMenuItem(cFasdBaseConfigMenuItem menuItemConfig)
|
||||
internal cMenuDataBase GetMenuItem(cFasdBaseConfigMenuItem menuItemConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -81,7 +81,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
|
||||
if (menuItem != null)
|
||||
{
|
||||
if (!cHealthCardDataHelper.IsUiVisible(menuItemConfig, _dataProvider.NamedParameterEntries))
|
||||
if (_dataProvider != null && !cHealthCardDataHelper.IsUiVisible(menuItemConfig, _dataProvider.NamedParameterEntries))
|
||||
menuItem.SetUiActionDisplayType(enumActionDisplayType.hidden);
|
||||
}
|
||||
return menuItem;
|
||||
@@ -129,7 +129,7 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
}
|
||||
|
||||
|
||||
private bool HasAllRequirements(cFasdQuickAction quickAction)
|
||||
internal bool HasAllRequirements(cFasdQuickAction quickAction)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -137,9 +137,14 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
return false;
|
||||
|
||||
// if CheckNamedParamter the value of NamedParameter is set and if required equals one of the necessary values
|
||||
bool hasRequiredNamedParameter = quickAction.CheckNamedParameter is null
|
||||
|| (_dataProvider.NamedParameterEntries.TryGetValue(quickAction.CheckNamedParameter, out var namedParameterEntry)
|
||||
&& (quickAction.CheckNamedParameterValues is null || quickAction.CheckNamedParameterValues.Count == 0 || quickAction.CheckNamedParameterValues.Contains(namedParameterEntry.GetValue())));
|
||||
bool hasRequiredNamedParameter = true;
|
||||
|
||||
if (_dataProvider != null)
|
||||
{
|
||||
hasRequiredNamedParameter = quickAction.CheckNamedParameter is null
|
||||
|| (_dataProvider.NamedParameterEntries.TryGetValue(quickAction.CheckNamedParameter, out var namedParameterEntry)
|
||||
&& (quickAction.CheckNamedParameterValues is null || quickAction.CheckNamedParameterValues.Count == 0 || quickAction.CheckNamedParameterValues.Contains(namedParameterEntry.GetValue())));
|
||||
}
|
||||
|
||||
if (!hasRequiredNamedParameter)
|
||||
return false;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.Logging;
|
||||
|
||||
using FasdDesktopUi.Basics;
|
||||
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Helper
|
||||
{
|
||||
internal static class TicketDeepLinkHelper
|
||||
internal static class TicketExternalLinkHelper
|
||||
{
|
||||
internal static bool TryOpenTicketRelationExternally(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
@@ -16,127 +20,51 @@ namespace FasdDesktopUi.Basics.Helper
|
||||
if (relation == null || relation.Type != enumF4sdSearchResultClass.Ticket)
|
||||
return false;
|
||||
|
||||
var ticketConfig = cFasdCockpitConfig.Instance?.Global?.TicketConfiguration;
|
||||
if (ticketConfig == null)
|
||||
// check how we should open this ticket (intern, extern or both)
|
||||
var ticketType = GetTicketType(relation);
|
||||
var processing = ShouldOpenExternally(ticketType);
|
||||
|
||||
// check if we have a valid user id in the id list => if not we could open this ticket only extern.
|
||||
var hasUser = relation.Identities.Any(e => (e.Class == enumFasdInformationClass.User && e.Id != null && e.Id != Guid.Empty));
|
||||
if (!hasUser)
|
||||
processing = enumTicketProcessing.Extern;
|
||||
|
||||
if (processing == enumTicketProcessing.Intern)
|
||||
return false;
|
||||
|
||||
var activityType = GetActivityType(relation);
|
||||
var openExternally = ShouldOpenExternally(ticketConfig, activityType);
|
||||
|
||||
if (!openExternally)
|
||||
return false;
|
||||
|
||||
var url = BuildTicketDeepLink(relation.id, activityType);
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
return false;
|
||||
if (relation?.Infos?.TryGetValue("TicketLink", out var ticketLink) == true && !string.IsNullOrWhiteSpace(ticketLink))
|
||||
new cBrowsers().Start("default", ticketLink);
|
||||
|
||||
new cBrowsers().Start("default", url);
|
||||
return true;
|
||||
return processing == enumTicketProcessing.Extern;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetActivityType(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
if (relation?.Infos != null && relation.Infos.TryGetValue("ActivityType", out var activityTypeValue))
|
||||
return activityTypeValue;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool ShouldOpenExternally(cF4sdTicketConfig ticketConfig, string activityType)
|
||||
{
|
||||
if (ticketConfig == null)
|
||||
return false;
|
||||
|
||||
if (TryGetOverride(ticketConfig.OpenActivitiesExternallyOverrides, activityType, out var overrideValue))
|
||||
return overrideValue;
|
||||
|
||||
return ticketConfig.OpenActivitiesExternally;
|
||||
}
|
||||
|
||||
private static bool TryGetOverride(IEnumerable<string> overrides, string activityType, out bool value)
|
||||
{
|
||||
value = false;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(activityType) || overrides == null)
|
||||
return false;
|
||||
|
||||
foreach (var entry in overrides)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(entry))
|
||||
continue;
|
||||
|
||||
var parts = entry.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length != 2)
|
||||
continue;
|
||||
|
||||
var typeName = parts[0].Trim();
|
||||
if (!string.Equals(typeName, activityType, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
if (!TryParseBool(parts[1], out value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryParseBool(string value, out bool result)
|
||||
{
|
||||
result = false;
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return false;
|
||||
|
||||
switch (value.Trim().ToLowerInvariant())
|
||||
{
|
||||
case "true":
|
||||
case "1":
|
||||
case "yes":
|
||||
result = true;
|
||||
return true;
|
||||
case "false":
|
||||
case "0":
|
||||
case "no":
|
||||
result = false;
|
||||
return true;
|
||||
default:
|
||||
return bool.TryParse(value, out result);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static string BuildTicketDeepLink(Guid ticketId, string activityType)
|
||||
private static enumTicketType GetTicketType(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
if (ticketId == Guid.Empty)
|
||||
return null;
|
||||
|
||||
var server = cCockpitConfiguration.Instance?.m42ServerConfiguration?.Server;
|
||||
if (string.IsNullOrWhiteSpace(server))
|
||||
return null;
|
||||
|
||||
var baseUrl = server.TrimEnd('/');
|
||||
if (!baseUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
|
||||
!baseUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
if (relation?.Infos != null && relation.Infos.TryGetValue("TicketType", out var ticketTypeValue))
|
||||
{
|
||||
baseUrl = "https://" + baseUrl;
|
||||
if (Enum.TryParse<enumTicketType>(ticketTypeValue, true, out var ticketType))
|
||||
return ticketType;
|
||||
}
|
||||
if (!baseUrl.EndsWith("/wm", StringComparison.OrdinalIgnoreCase))
|
||||
baseUrl += "/wm";
|
||||
return enumTicketType.Ticket;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(activityType))
|
||||
return null;
|
||||
private static enumTicketProcessing ShouldOpenExternally(enumTicketType ticketType)
|
||||
{
|
||||
var ticketConfig = cFasdCockpitConfig.Instance?.Global?.TicketConfiguration;
|
||||
if (ticketConfig == null)
|
||||
return enumTicketProcessing.Extern;
|
||||
|
||||
var viewOptionsJson = $"{{\"embedded\":false,\"objectId\":\"{ticketId}\",\"type\":\"{activityType}\",\"viewType\":\"preview\",\"archived\":0}}";
|
||||
var viewOptionsEncoded = Uri.EscapeDataString(viewOptionsJson);
|
||||
if (ticketConfig.TicketProcessing?.TryGetValue(ticketType, out var processing) == true)
|
||||
return processing;
|
||||
|
||||
return $"{baseUrl}/app-ServiceDesk/?view-options={viewOptionsEncoded}";
|
||||
return ticketConfig.DefaultProcessing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user