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:
27
FasdDesktopUi/Basics/Converter/LanguageCultureConverter.cs
Normal file
27
FasdDesktopUi/Basics/Converter/LanguageCultureConverter.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Converter
|
||||
{
|
||||
[ValueConversion(typeof(string), typeof(XmlLanguage))]
|
||||
internal class LanguageCultureConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is string tag))
|
||||
return Binding.DoNothing;
|
||||
|
||||
return XmlLanguage.GetLanguage(tag);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is XmlLanguage lang))
|
||||
return Binding.DoNothing;
|
||||
|
||||
return lang.IetfLanguageTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace FasdDesktopUi.Basics
|
||||
var http = GetHttpHelper(false);
|
||||
|
||||
var searchResultInfoClass = cF4sdIdentityEntry.GetFromSearchResult(enumF4sdSearchResultClass.Computer);
|
||||
var parameter = new cF4SDServerQuickActionParameters() { Action = ServerAction.Action, Category = ServerAction.Category, ParamaterType = ServerAction.ParameterType, Identities = dataProvider.Identities, AdjustableParameter = ParameterDictionary };
|
||||
var parameter = new cF4SDServerQuickActionParameters() { Action = ServerAction.Action, Category = ServerAction.Category, ParameterType = ServerAction.ParameterType, Identities = dataProvider.Identities, AdjustableParameter = ParameterDictionary };
|
||||
var payload = JsonConvert.SerializeObject(parameter);
|
||||
|
||||
var result = await http.PostJsonAsync("api/QuickAction/Run", payload, 15000, CancellationToken.None);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ namespace FasdDesktopUi.Basics.Models
|
||||
heartBeat
|
||||
}
|
||||
|
||||
public bool IsActive = true;
|
||||
public enumOnlineStatus ApiConnectionStatus { get; private set; } = enumOnlineStatus.notSpecified;
|
||||
|
||||
public bool ApplicationIsExiting { get; set; } = false;
|
||||
|
||||
public readonly Version MinServerVersion = new Version("0.0.0.0");
|
||||
|
||||
@@ -64,16 +66,15 @@ namespace FasdDesktopUi.Basics.Models
|
||||
|
||||
public static cConnectionStatusHelper Instance { get; set; }
|
||||
|
||||
public bool IsAuthorizationSupported { get; private set; } = false;
|
||||
private bool IsAuthorizationSupported { get; set; } = false;
|
||||
private System.Timers.Timer timer;
|
||||
|
||||
#region Lock Elements Connecion Status
|
||||
private readonly object connectionStatusCheckLock = new object();
|
||||
private enumCheckRunning IsConnectionStatusCheckRunning = enumCheckRunning.no;
|
||||
private int OnlineCheckCounter = 0;
|
||||
#endregion
|
||||
|
||||
public enumOnlineStatus ApiConnectionStatus = enumOnlineStatus.notSpecified;
|
||||
|
||||
public cConnectionStatusHelper()
|
||||
{
|
||||
ApiConnectionStatus = enumOnlineStatus.offline;
|
||||
@@ -125,44 +126,47 @@ namespace FasdDesktopUi.Basics.Models
|
||||
return (timerInterval, shortInterval);
|
||||
}
|
||||
|
||||
private void HandleConnectionStatus(enumConnectionStatus status, ref int timerInterval, int timerInteralShort)
|
||||
private enumOnlineStatus HandleConnectionStatus(enumConnectionStatus status, ref int timerInterval, int timerInteralShort)
|
||||
{
|
||||
var newStatus = ApiConnectionStatus;
|
||||
switch (status)
|
||||
{
|
||||
case enumConnectionStatus.unknown:
|
||||
case enumConnectionStatus.serverNotFound:
|
||||
if (ApiConnectionStatus != enumOnlineStatus.offline)
|
||||
ApiConnectionStatus = enumOnlineStatus.offline;
|
||||
if (newStatus != enumOnlineStatus.offline)
|
||||
newStatus = enumOnlineStatus.offline;
|
||||
timerInterval = timerInteralShort;
|
||||
LogEntry("RunConnectionStatusCheckAsync: Exit due to status 'serverNotFound'");
|
||||
break;
|
||||
case enumConnectionStatus.serverResponseError:
|
||||
ApiConnectionStatus = enumOnlineStatus.connectionError;
|
||||
newStatus = enumOnlineStatus.connectionError;
|
||||
timerInterval = timerInteralShort;
|
||||
LogEntry("RunConnectionStatusCheckAsync: Exit due to status 'serverResponseError'");
|
||||
break;
|
||||
case enumConnectionStatus.incompatibleServerVersion:
|
||||
LogEntry("RunConnectionStatusCheckAsync: Exit due to status 'incompatibleServerVersion'");
|
||||
ApiConnectionStatus = enumOnlineStatus.incompatibleServerVersion;
|
||||
newStatus = enumOnlineStatus.incompatibleServerVersion;
|
||||
break;
|
||||
case enumConnectionStatus.serverStarting:
|
||||
ApiConnectionStatus = enumOnlineStatus.serverStarting;
|
||||
newStatus = enumOnlineStatus.serverStarting;
|
||||
break;
|
||||
case enumConnectionStatus.serverNotConfigured:
|
||||
ApiConnectionStatus = enumOnlineStatus.serverNotConfigured;
|
||||
newStatus = enumOnlineStatus.serverNotConfigured;
|
||||
break;
|
||||
case enumConnectionStatus.connected:
|
||||
if (cCockpitConfiguration.Instance == null || cF4SDCockpitXmlConfig.Instance == null)
|
||||
ApiConnectionStatus = enumOnlineStatus.illegalConfig;
|
||||
newStatus = enumOnlineStatus.illegalConfig;
|
||||
else if (ApiConnectionStatus != enumOnlineStatus.online)
|
||||
ApiConnectionStatus = enumOnlineStatus.online;
|
||||
newStatus = enumOnlineStatus.online;
|
||||
break;
|
||||
}
|
||||
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
public async Task RunConnectionStatusCheckAsync(SplashScreenView splashScreen)
|
||||
{
|
||||
if (!IsActive)
|
||||
if (ApplicationIsExiting)
|
||||
return;
|
||||
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
@@ -195,7 +199,7 @@ namespace FasdDesktopUi.Basics.Models
|
||||
cCheckConnectionResult connectionResult = await cFasdCockpitCommunicationBase.Instance.CheckConnection(MinServerVersion);
|
||||
IsAuthorizationSupported = connectionResult?.ApiConnectionInfo?.SupportAuthorisation ?? false;
|
||||
|
||||
HandleConnectionStatus(connectionResult.ConnectionStatus, ref timerInterval, shortTimerInterval);
|
||||
ApiConnectionStatus = HandleConnectionStatus(connectionResult.ConnectionStatus, ref timerInterval, shortTimerInterval);
|
||||
if (connectionResult.ConnectionStatus != enumConnectionStatus.connected)
|
||||
return;
|
||||
|
||||
@@ -210,7 +214,12 @@ namespace FasdDesktopUi.Basics.Models
|
||||
var configTasks = await Task.WhenAll(loadConfigFilesTask, getCockpitConfig);
|
||||
|
||||
if (configTasks.Any(t => t == false))
|
||||
{
|
||||
LogEntry("Connection status check wasn't successfull. Could not retrieve all configurations.", LogLevels.Warning);
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
await RunConnectionStatusCheckAsync(splashScreen);
|
||||
return;
|
||||
}
|
||||
if (cFasdCockpitConfig.Instance?.Global != null && cCockpitConfiguration.Instance?.GlobalConfig != null)
|
||||
{
|
||||
cFasdCockpitConfig.Instance.Global.Load(cCockpitConfiguration.Instance.GlobalConfig);
|
||||
@@ -225,33 +234,34 @@ namespace FasdDesktopUi.Basics.Models
|
||||
}
|
||||
if (IsAuthorizationSupported)
|
||||
{
|
||||
if (userInfo is null || DateTime.UtcNow > userInfo.RenewUntil)
|
||||
{
|
||||
Dispatcher.CurrentDispatcher.Invoke(() => splashScreen?.SetStatusText(cMultiLanguageSupport.GetItem("StartUp.SplashScreen.AuthenticateUser")));
|
||||
ApiConnectionStatus = enumOnlineStatus.unauthorized;
|
||||
const string cockpitUserRole = "Cockpit.User";
|
||||
Dispatcher.CurrentDispatcher.Invoke(() => splashScreen?.SetStatusText(cMultiLanguageSupport.GetItem("StartUp.SplashScreen.AuthenticateUser")));
|
||||
ApiConnectionStatus = enumOnlineStatus.unauthorized;
|
||||
const string cockpitUserRole = "Cockpit.User";
|
||||
#if isNewFeature
|
||||
const string cockpitTicketAgentRole = "Cockpit.TicketAgent";
|
||||
#endif
|
||||
if (userInfo is null || DateTime.UtcNow > userInfo.RenewUntil)
|
||||
{
|
||||
userInfo = await cFasdCockpitCommunicationBase.Instance.WinLogon();
|
||||
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
|
||||
{
|
||||
cFasdCockpitCommunicationBase.CockpitUserInfo = userInfo;
|
||||
}
|
||||
if (userInfo?.Roles is null || !userInfo.Roles.Contains(cockpitUserRole))
|
||||
{
|
||||
Dispatcher.CurrentDispatcher.Invoke(() => splashScreen?.SetStatusText(cMultiLanguageSupport.GetItem("StartUp.SplashScreen.NoAuthorization")));
|
||||
LogEntry($"Cockpit User ({userInfo?.Name} with Id {userInfo?.Id}, has not the required permissions.", LogLevels.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Run(async () => await cFasdCockpitConfig.Instance.InstantiateAnalyticsAsync(cFasdCockpitConfig.SessionId));
|
||||
ApiConnectionStatus = enumOnlineStatus.online;
|
||||
}
|
||||
|
||||
if (userInfo?.Roles is null || !userInfo.Roles.Contains(cockpitUserRole))
|
||||
{
|
||||
Dispatcher.CurrentDispatcher.Invoke(() => splashScreen?.SetStatusText(cMultiLanguageSupport.GetItem("StartUp.SplashScreen.NoAuthorization")));
|
||||
LogEntry($"Cockpit User ({userInfo?.Name} with Id {userInfo?.Id}, has not the required permissions.", LogLevels.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Run(async () => await cFasdCockpitConfig.Instance.InstantiateAnalyticsAsync(cFasdCockpitConfig.SessionId));
|
||||
ApiConnectionStatus = enumOnlineStatus.online;
|
||||
#if isNewFeature
|
||||
if (userInfo.Roles.Contains(cockpitTicketAgentRole))
|
||||
cCockpitConfiguration.Instance.ticketSupport.EditTicket = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -280,9 +290,9 @@ namespace FasdDesktopUi.Basics.Models
|
||||
}
|
||||
|
||||
if (App.M42OptionMenuItem != null)
|
||||
App.Current.MainWindow.Dispatcher.Invoke(() =>
|
||||
Dispatcher.CurrentDispatcher.Invoke(() =>
|
||||
{
|
||||
App.M42OptionMenuItem.Enabled = userInfo != null;
|
||||
App.M42OptionMenuItem.Enabled = userInfo != null;
|
||||
});
|
||||
|
||||
// check, if the are logons needed
|
||||
@@ -291,6 +301,7 @@ namespace FasdDesktopUi.Basics.Models
|
||||
await cFasdCockpitConfig.Instance.CheckServerQuickActionAvailabilityAsync();
|
||||
await cFasdCockpitCommunicationBase.Instance.InitializeAfterOnlineAsync();
|
||||
cFasdCockpitConfig.Instance.OnUiSettingsChanged();
|
||||
await Task.Run(async () => await cFasdCockpitConfig.Instance.InstantiateAnalyticsAsync(cFasdCockpitConfig.SessionId));
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -312,7 +323,7 @@ namespace FasdDesktopUi.Basics.Models
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
if (IsActive)
|
||||
if (!ApplicationIsExiting)
|
||||
{
|
||||
if (ApiConnectionStatus == enumOnlineStatus.online)
|
||||
NotifyerSupport.SetNotifyIcon("Default", null, NotifyerSupport.enumIconAlignment.BottomRight);
|
||||
@@ -334,6 +345,7 @@ namespace FasdDesktopUi.Basics.Models
|
||||
}
|
||||
finally
|
||||
{
|
||||
OnlineCheckCounter++;
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
|
||||
175
FasdDesktopUi/Basics/Models/DTOs/MenuDataBaseDto.cs
Normal file
175
FasdDesktopUi/Basics/Models/DTOs/MenuDataBaseDto.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using C4IT.FASD.Base;
|
||||
using F4SD_AdaptableIcon;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace FasdDesktopUi.Basics.Models.DTOs
|
||||
{
|
||||
// __ __ ____ ____
|
||||
// | |__| || || \
|
||||
// | | | | | | | o )
|
||||
// | | | | | | | _/
|
||||
// | ` ' | | | | |
|
||||
// \ / | | | |
|
||||
// \_/\_/ |____||__|
|
||||
|
||||
// the following classes are work in Progress and shouldn't been used
|
||||
|
||||
[Obsolete]
|
||||
internal readonly struct IconInfo
|
||||
{
|
||||
public IconData? Overlay { get; }
|
||||
public double IconScale { get; }
|
||||
public bool IsInactive { get; }
|
||||
public string Description { get; }
|
||||
|
||||
public IconInfo(bool isInactive = default, string description = null, IconData? overlay = null, double iconScale = 1.0)
|
||||
{
|
||||
Overlay = overlay;
|
||||
IsInactive = isInactive;
|
||||
Description = description;
|
||||
IconScale = iconScale;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal abstract class MenuDataBaseDto
|
||||
{
|
||||
private readonly IconData _icon;
|
||||
|
||||
public string Title { get; set; }
|
||||
public string SubTitle { get; set; }
|
||||
public cUiActionBase Action { get; set; }
|
||||
public IconInfo IconInformation { get; set; }
|
||||
public int PositoinIndex { get; set; }
|
||||
|
||||
protected MenuDataBaseDto() { }
|
||||
|
||||
protected MenuDataBaseDto(cFasdBaseConfigMenuItem menuItemDefinition)
|
||||
{
|
||||
_icon = IconDataConverter.Convert(menuItemDefinition.Icon);
|
||||
Title = menuItemDefinition.Names.GetValue();
|
||||
}
|
||||
|
||||
internal virtual IconData GetIcon() => _icon;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class ContainerMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
public IList<MenuDataBaseDto> SubMenuData { get; set; } = new List<MenuDataBaseDto>();
|
||||
|
||||
public ContainerMenuDataDto(cFasdMenuSection sectionDefintion) : base(sectionDefintion)
|
||||
{
|
||||
Action = new cSubMenuAction(true); // todo rework subMenuAction
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class LoadingMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
private readonly IconData _icon = new IconData(enumInternGif.loadingSpinner);
|
||||
|
||||
public LoadingMenuDataDto(string loadingText)
|
||||
{
|
||||
Title = loadingText;
|
||||
}
|
||||
|
||||
internal override IconData GetIcon() => _icon;
|
||||
|
||||
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class SearchResultMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
private readonly cFasdApiSearchResultEntry _searchResultEntry;
|
||||
public enumF4sdSearchResultClass Type { get => _searchResultEntry.Type; }
|
||||
|
||||
public SearchResultMenuDataDto(cFasdApiSearchResultEntry searchResultEntry)
|
||||
{
|
||||
_searchResultEntry = searchResultEntry;
|
||||
//Action = new cUiProcessSearchRelationAction()
|
||||
}
|
||||
|
||||
internal override IconData GetIcon()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case enumF4sdSearchResultClass.Computer:
|
||||
return new IconData(enumInternIcons.misc_computer);
|
||||
case enumF4sdSearchResultClass.User:
|
||||
return new IconData(enumInternIcons.misc_user);
|
||||
case enumF4sdSearchResultClass.Phone:
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_phone);
|
||||
case enumF4sdSearchResultClass.Ticket:
|
||||
break;
|
||||
case enumF4sdSearchResultClass.VirtualSession:
|
||||
break;
|
||||
case enumF4sdSearchResultClass.MobileDevice:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class SearchRelationMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
private readonly cF4sdApiSearchResultRelation _searchRelation;
|
||||
public enumF4sdSearchResultClass Type { get => _searchRelation.Type; }
|
||||
public DateTime LastUsed { get; private set; }
|
||||
public double UsingFactor { get; private set; }
|
||||
public Dictionary<string, string> AdditionalInfos { get; private set; } // todo check
|
||||
|
||||
public bool IsUsedForCaseEnrichtment { get; set; } // todo check
|
||||
|
||||
public string TrailingText { get; set; }
|
||||
|
||||
public SearchRelationMenuDataDto(cF4sdApiSearchResultRelation searchRelation)
|
||||
{
|
||||
_searchRelation = searchRelation;
|
||||
//Action = new cUiProcessSearchRelationAction()
|
||||
}
|
||||
|
||||
internal override IconData GetIcon()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class QuickActionMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
public QuickActionMenuDataDto(cFasdQuickAction quickActionDefinition) : base(quickActionDefinition)
|
||||
{
|
||||
Action = cUiActionBase.GetUiAction(quickActionDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class QuickTipMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
public QuickTipMenuDataDto(cFasdQuickTip quickTipDefinition) : base(quickTipDefinition)
|
||||
{
|
||||
Title = quickTipDefinition.Names.GetValue();
|
||||
Action = new cUiQuickTipAction(quickTipDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
internal sealed class CopyTemplateMenuDataDto : MenuDataBaseDto
|
||||
{
|
||||
public CopyTemplateMenuDataDto(cCopyTemplate copyActionDefintion) : base(copyActionDefintion)
|
||||
{
|
||||
Action = new cUiCopyAction(copyActionDefintion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,6 +119,9 @@ namespace FasdDesktopUi.Basics.Models
|
||||
{
|
||||
try
|
||||
{
|
||||
if (actionSteps is null)
|
||||
return;
|
||||
|
||||
foreach (var step in actionSteps)
|
||||
{
|
||||
if (step.StepType.Equals(type) && step.QuickActionName.Equals(quickActionName))
|
||||
|
||||
@@ -1,199 +1,292 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using C4IT.FASD.Base;
|
||||
using F4SD_AdaptableIcon;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Models
|
||||
{
|
||||
//todo: check what properties can/should be set via constructor
|
||||
|
||||
public class cMenuDataBase
|
||||
{
|
||||
public string MenuText { get; set; }
|
||||
|
||||
public string SubMenuText { get; set; }
|
||||
|
||||
public string TrailingText { get; set; }
|
||||
|
||||
public IconData MenuIcon { get; set; }
|
||||
|
||||
public double MenuIconSize { get; set; } = 1.0;
|
||||
|
||||
public int IconPositionIndex { get; set; }
|
||||
|
||||
public object Data { get; set; }
|
||||
|
||||
public List<string> MenuSections { get; set; }
|
||||
|
||||
public cUiActionBase UiAction { get; set; }
|
||||
|
||||
public cMenuDataBase()
|
||||
{
|
||||
}
|
||||
public cMenuDataBase(cFasdBaseConfigMenuItem menuItem)
|
||||
{
|
||||
MenuText = menuItem.Names.GetValue(Default: null);
|
||||
MenuIcon = IconDataConverter.Convert(menuItem.Icon);
|
||||
MenuSections = menuItem.Sections;
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdQuickAction quickAction, Enums.enumActionDisplayType display) : this(quickAction)
|
||||
{
|
||||
SetUiActionDisplayType(display);
|
||||
}
|
||||
|
||||
|
||||
public cMenuDataBase(cFasdQuickAction quickAction) : this((cFasdBaseConfigMenuItem)quickAction)
|
||||
{
|
||||
var tempUiAction = cUiActionBase.GetUiAction(quickAction);
|
||||
tempUiAction.Name = quickAction.Name;
|
||||
tempUiAction.Description = quickAction.Descriptions?.GetValue(Default: null);
|
||||
tempUiAction.AlternativeDescription = quickAction.AlternativeDescriptions?.GetValue(Default: null);
|
||||
UiAction = tempUiAction;
|
||||
}
|
||||
|
||||
public cMenuDataBase(cCopyTemplate copyTemplate) : this((cFasdBaseConfigMenuItem)copyTemplate)
|
||||
{
|
||||
UiAction = new cUiCopyAction(copyTemplate) { Name = copyTemplate.Name, Description = copyTemplate.Descriptions.GetValue(Default: null), DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdMenuSection menuSection) : this((cFasdBaseConfigMenuItem)menuSection)
|
||||
{
|
||||
IconPositionIndex = -1;
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdQuickTip quickTip) : this((cFasdBaseConfigMenuItem)quickTip)
|
||||
{
|
||||
UiAction = new cUiQuickTipAction(quickTip) { DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
|
||||
public void SetUiActionDisplayType(Enums.enumActionDisplayType display)
|
||||
{
|
||||
if (this.UiAction != null)
|
||||
this.UiAction.DisplayType = display;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class cMenuDataContainer : cMenuDataBase
|
||||
{
|
||||
public string ContainerName { get; private set; }
|
||||
public List<cMenuDataBase> SubMenuData { get; set; }
|
||||
|
||||
public cMenuDataContainer()
|
||||
{
|
||||
UiAction = new cSubMenuAction(true) { Name = MenuText, DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
|
||||
public cMenuDataContainer(cFasdMenuSection menuSection) : base(menuSection)
|
||||
{
|
||||
ContainerName = menuSection.TechName;
|
||||
UiAction = new cSubMenuAction(true) { Name = MenuText, DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
}
|
||||
|
||||
public class cMenuDataSearchResult : cMenuDataBase
|
||||
{
|
||||
public cMenuDataSearchResult(string menuText, ISearchUiProvider SearchUiProvider, List<cFasdApiSearchResultEntry> searchResults) : base()
|
||||
{
|
||||
if (searchResults?.Count <= 0)
|
||||
return;
|
||||
|
||||
MenuText = menuText;
|
||||
UiAction = new cUiProcessSearchResultAction(menuText, SearchUiProvider, searchResults);
|
||||
var firstSearchResult = searchResults.First();
|
||||
MenuIcon = GetMenuIcon(firstSearchResult.Type, firstSearchResult.Infos);
|
||||
}
|
||||
|
||||
static public IconData GetMenuIcon(enumF4sdSearchResultClass searchResultClass, Dictionary<string, string> infos)
|
||||
{
|
||||
switch (searchResultClass)
|
||||
{
|
||||
case enumF4sdSearchResultClass.Computer:
|
||||
return new IconData(enumInternIcons.misc_computer);
|
||||
case enumF4sdSearchResultClass.User:
|
||||
return new IconData(enumInternIcons.misc_user);
|
||||
case enumF4sdSearchResultClass.Phone:
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_phone);
|
||||
case enumF4sdSearchResultClass.Ticket:
|
||||
return new IconData(enumInternIcons.misc_ticket);
|
||||
case enumF4sdSearchResultClass.MobileDevice:
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_smartphone);
|
||||
case enumF4sdSearchResultClass.VirtualSession:
|
||||
if (!infos.TryGetValue("Status", out string status))
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_cloud_off);
|
||||
else if (status == nameof(enumCitrixSessionStatus.Active))
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_cloud_queue);
|
||||
else
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_cloud_off);
|
||||
default:
|
||||
return new IconData(MaterialIcons.MaterialIconType.ic_more_vert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class cMenuDataSearchRelation : cMenuDataBase
|
||||
{
|
||||
public readonly DateTime LastUsed;
|
||||
public readonly double UsingLevel = 0;
|
||||
public readonly Dictionary<string, string> Infos = null;
|
||||
public bool IsMatchingRelation = false;
|
||||
public bool IsUsedForCaseEnrichment = false;
|
||||
|
||||
public readonly cF4sdApiSearchResultRelation searchResultRelation = null;
|
||||
|
||||
public cMenuDataSearchRelation(cF4sdApiSearchResultRelation searchResultRelation)
|
||||
{
|
||||
try
|
||||
{
|
||||
UiAction = null;
|
||||
|
||||
if (searchResultRelation is null)
|
||||
return;
|
||||
|
||||
this.searchResultRelation = searchResultRelation;
|
||||
MenuText = searchResultRelation.DisplayName;
|
||||
Data = searchResultRelation;
|
||||
LastUsed = searchResultRelation.LastUsed;
|
||||
UsingLevel = searchResultRelation.UsingLevel;
|
||||
Infos = searchResultRelation.Infos;
|
||||
MenuIcon = cMenuDataSearchResult.GetMenuIcon(searchResultRelation.Type, searchResultRelation.Infos);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class cMenuDataLoading : cMenuDataBase
|
||||
{
|
||||
public cMenuDataLoading(string LoadingText)
|
||||
{
|
||||
MenuText = LoadingText;
|
||||
}
|
||||
}
|
||||
|
||||
public class cFilteredResults
|
||||
{
|
||||
public bool AutoContinue { get; set; } = false;
|
||||
public cFasdApiSearchResultCollection Results { get; set; }
|
||||
|
||||
public cF4sdApiSearchResultRelation PreSelectedRelation { get; set; }
|
||||
|
||||
public cFilteredResults()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public cFilteredResults(cFasdApiSearchResultCollection _results)
|
||||
{
|
||||
Results = _results ?? new cFasdApiSearchResultCollection();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.MultiLanguage;
|
||||
|
||||
using F4SD_AdaptableIcon;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Models
|
||||
{
|
||||
//todo: check what properties can/should be set via constructor
|
||||
|
||||
public class cMenuDataBase
|
||||
{
|
||||
public string MenuText { get; set; }
|
||||
|
||||
public string SubMenuText { get; set; }
|
||||
|
||||
public string TrailingText { get; set; }
|
||||
|
||||
public MenuIconInfo MenuIcon { get; set; }
|
||||
|
||||
public double MenuIconSize { get; set; } = 1.0;
|
||||
|
||||
public int IconPositionIndex { get; set; }
|
||||
|
||||
public object Data { get; set; }
|
||||
|
||||
public List<string> MenuSections { get; set; }
|
||||
|
||||
public cUiActionBase UiAction { get; set; }
|
||||
|
||||
public class MenuIconInfo
|
||||
{
|
||||
public readonly IconData Icon;
|
||||
public readonly IconData? Overlay;
|
||||
public readonly bool IsInactive;
|
||||
public readonly string Description;
|
||||
|
||||
public MenuIconInfo(IconData icon, string Description = null, bool isInactive = false, IconData? overlay = null)
|
||||
{
|
||||
Icon = icon;
|
||||
IsInactive = isInactive;
|
||||
this.Description = Description;
|
||||
Overlay = overlay;
|
||||
}
|
||||
}
|
||||
|
||||
public cMenuDataBase()
|
||||
{
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdBaseConfigMenuItem menuItem)
|
||||
{
|
||||
MenuText = menuItem.Names.GetValue(Default: null);
|
||||
MenuIcon = new MenuIconInfo(IconDataConverter.Convert(menuItem.Icon));
|
||||
MenuSections = menuItem.Sections;
|
||||
|
||||
if (!string.IsNullOrEmpty(menuItem.Section))
|
||||
MenuSections.Add(menuItem.Section);
|
||||
|
||||
MenuSections = MenuSections.Distinct().ToList();
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdQuickAction quickAction, Enums.enumActionDisplayType display) : this(quickAction)
|
||||
{
|
||||
SetUiActionDisplayType(display);
|
||||
}
|
||||
|
||||
|
||||
public cMenuDataBase(cFasdQuickAction quickAction) : this((cFasdBaseConfigMenuItem)quickAction)
|
||||
{
|
||||
var tempUiAction = cUiActionBase.GetUiAction(quickAction);
|
||||
tempUiAction.Name = quickAction.Name;
|
||||
tempUiAction.Description = quickAction.Descriptions?.GetValue(Default: null);
|
||||
tempUiAction.AlternativeDescription = quickAction.AlternativeDescriptions?.GetValue(Default: null);
|
||||
UiAction = tempUiAction;
|
||||
}
|
||||
|
||||
public cMenuDataBase(cCopyTemplate copyTemplate) : this((cFasdBaseConfigMenuItem)copyTemplate)
|
||||
{
|
||||
UiAction = new cUiCopyAction(copyTemplate) { Name = copyTemplate.Name, Description = copyTemplate.Descriptions.GetValue(Default: null), DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdMenuSection menuSection) : this((cFasdBaseConfigMenuItem)menuSection)
|
||||
{
|
||||
IconPositionIndex = -1;
|
||||
}
|
||||
|
||||
public cMenuDataBase(cFasdQuickTip quickTip) : this((cFasdBaseConfigMenuItem)quickTip)
|
||||
{
|
||||
UiAction = new cUiQuickTipAction(quickTip) { DisplayType = Enums.enumActionDisplayType.enabled, Name = quickTip.Name };
|
||||
}
|
||||
|
||||
public void SetUiActionDisplayType(Enums.enumActionDisplayType display)
|
||||
{
|
||||
if (this.UiAction != null)
|
||||
this.UiAction.DisplayType = display;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class cMenuDataContainer : cMenuDataBase
|
||||
{
|
||||
public string ContainerName { get; private set; }
|
||||
public List<cMenuDataBase> SubMenuData { get; set; } = new List<cMenuDataBase>();
|
||||
|
||||
public cMenuDataContainer()
|
||||
{
|
||||
UiAction = new cSubMenuAction(true) { Name = MenuText, DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
|
||||
public cMenuDataContainer(cFasdMenuSection menuSection) : base(menuSection)
|
||||
{
|
||||
ContainerName = menuSection.TechName;
|
||||
UiAction = new cSubMenuAction(true) { Name = MenuText, DisplayType = Enums.enumActionDisplayType.enabled };
|
||||
}
|
||||
}
|
||||
|
||||
public class cMenuDataSearchResult : cMenuDataBase
|
||||
{
|
||||
public cMenuDataSearchResult(string menuText, ISearchUiProvider SearchUiProvider, List<cFasdApiSearchResultEntry> searchResults) : base()
|
||||
{
|
||||
if (searchResults?.Count <= 0)
|
||||
return;
|
||||
|
||||
MenuText = menuText;
|
||||
UiAction = new cUiProcessSearchResultAction(menuText, SearchUiProvider, searchResults);
|
||||
var firstSearchResult = searchResults.First();
|
||||
MenuIcon = GetMenuIcon(firstSearchResult.Type, firstSearchResult.Infos);
|
||||
}
|
||||
|
||||
static private MenuIconInfo GetTicketIcon(Dictionary<string, string> infos)
|
||||
{
|
||||
bool isInactive = false;
|
||||
if (infos.TryGetValue("StatusId", out var ticketStatusId))
|
||||
{
|
||||
if (Enum.TryParse(ticketStatusId, true, out enumTicketStatus ticketStatus))
|
||||
{
|
||||
switch (ticketStatus)
|
||||
{
|
||||
case enumTicketStatus.Closed:
|
||||
isInactive = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string description = null;
|
||||
var overlay = isInactive ? (IconData?)new IconData(enumInternIcons.misc_disabledOverlay) : null;
|
||||
if (isInactive)
|
||||
{
|
||||
}
|
||||
if (infos.TryGetValue("TicketType", out var ticketType))
|
||||
{
|
||||
if (Enum.TryParse(ticketType, true, out enumTicketType parsedTicketType))
|
||||
{
|
||||
switch (parsedTicketType)
|
||||
{
|
||||
case enumTicketType.Incident:
|
||||
if (isInactive)
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.Incident.Closed");
|
||||
else
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.Incident.Active");
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_bug_report), description, isInactive, overlay);
|
||||
case enumTicketType.ServiceRequest:
|
||||
if (isInactive)
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.ServiceRequest.Closed");
|
||||
else
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.ServiceRequest.Active");
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_room_service), description, isInactive, overlay);
|
||||
case enumTicketType.UnclassifiedTicket:
|
||||
if (isInactive)
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.Unclassified.Closed");
|
||||
else
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.Unclassified.Active");
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_confirmation_number), description, isInactive, overlay);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isInactive)
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.Ticket.Closed");
|
||||
else
|
||||
description = cMultiLanguageSupport.GetItem("Searchbar.Item.Ticket.Active");
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_mail_outline), description, isInactive, overlay);
|
||||
}
|
||||
|
||||
static private MenuIconInfo GetVirtualSessionIcon(Dictionary<string, string> infos)
|
||||
{
|
||||
if (infos.TryGetValue("Status", out string status))
|
||||
{
|
||||
if (status == nameof(enumCitrixSessionStatus.Active))
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_cloud_queue));
|
||||
}
|
||||
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_cloud_off));
|
||||
}
|
||||
|
||||
static public MenuIconInfo GetMenuIcon(enumF4sdSearchResultClass searchResultClass, Dictionary<string, string> infos)
|
||||
{
|
||||
switch (searchResultClass)
|
||||
{
|
||||
case enumF4sdSearchResultClass.Computer:
|
||||
return new MenuIconInfo(new IconData(enumInternIcons.misc_computer));
|
||||
case enumF4sdSearchResultClass.User:
|
||||
return new MenuIconInfo(new IconData(enumInternIcons.misc_user));
|
||||
case enumF4sdSearchResultClass.Phone:
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_phone));
|
||||
case enumF4sdSearchResultClass.Ticket:
|
||||
return GetTicketIcon(infos);
|
||||
case enumF4sdSearchResultClass.MobileDevice:
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_smartphone));
|
||||
case enumF4sdSearchResultClass.VirtualSession:
|
||||
return GetVirtualSessionIcon(infos);
|
||||
default:
|
||||
return new MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_more_vert));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class cMenuDataSearchRelation : cMenuDataBase
|
||||
{
|
||||
public readonly DateTime LastUsed;
|
||||
public readonly double UsingLevel = 0;
|
||||
public readonly Dictionary<string, string> Infos = null;
|
||||
public bool IsMatchingRelation = false;
|
||||
public bool IsUsedForCaseEnrichment = false;
|
||||
|
||||
public readonly cF4sdApiSearchResultRelation searchResultRelation = null;
|
||||
|
||||
public cMenuDataSearchRelation(cF4sdApiSearchResultRelation searchResultRelation)
|
||||
{
|
||||
try
|
||||
{
|
||||
UiAction = null;
|
||||
|
||||
if (searchResultRelation is null)
|
||||
return;
|
||||
|
||||
this.searchResultRelation = searchResultRelation;
|
||||
MenuText = searchResultRelation.DisplayName;
|
||||
Data = searchResultRelation;
|
||||
LastUsed = searchResultRelation.LastUsed;
|
||||
UsingLevel = searchResultRelation.UsingLevel;
|
||||
Infos = searchResultRelation.Infos;
|
||||
MenuIcon = cMenuDataSearchResult.GetMenuIcon(searchResultRelation.Type, searchResultRelation.Infos);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class cMenuDataLoading : cMenuDataBase
|
||||
{
|
||||
public cMenuDataLoading(string LoadingText)
|
||||
{
|
||||
MenuText = LoadingText;
|
||||
}
|
||||
}
|
||||
|
||||
public class cFilteredResults
|
||||
{
|
||||
public bool AutoContinue { get; set; } = false;
|
||||
public cFasdApiSearchResultCollection Results { get; set; }
|
||||
|
||||
public cF4sdApiSearchResultRelation PreSelectedRelation { get; set; }
|
||||
|
||||
public cFilteredResults()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public cFilteredResults(cFasdApiSearchResultCollection _results)
|
||||
{
|
||||
Results = _results ?? new cFasdApiSearchResultCollection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace FasdDesktopUi.Basics.Models
|
||||
|
||||
try
|
||||
{
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
cUtility.RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
var outputTable = dataProvider.HealthCardDataHelper.HealthCardRawData.GetTableByName(valueAdress.ValueTable, true);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using FasdDesktopUi.Basics.Enums;
|
||||
using FasdDesktopUi.Basics.Services.Models;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
|
||||
using System.Linq;
|
||||
using static C4IT.FASD.Base.cF4SDHealthCardRawData;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Models
|
||||
@@ -17,5 +18,17 @@ namespace FasdDesktopUi.Basics.Models
|
||||
public cUiActionBase UiActionTitle { get; set; } = null;
|
||||
public cUiActionBase UiActionValue { get; set; } = null;
|
||||
public cHealthCardDetailsTable ValuedDetails { get; set; } = null;
|
||||
|
||||
public cWidgetValueModel() { }
|
||||
|
||||
public cWidgetValueModel(CockpitValueDisplayData displayData, enumHighlightColor highlightColor, cUiActionBase titleUiAction)
|
||||
{
|
||||
Title = displayData?.Title;
|
||||
Value = displayData?.Values?.FirstOrDefault() ?? (displayData.IsLoading ? "..." : null);
|
||||
HighlightIn = highlightColor;
|
||||
IsLoading = displayData?.IsLoading ?? true;
|
||||
UiActionTitle = titleUiAction;
|
||||
UiActionValue = displayData?.UiActions?.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,18 +286,20 @@ namespace FasdDesktopUi.Basics
|
||||
public bool isSeen { get; set; } = false;
|
||||
|
||||
protected DateTime LastRefresh = DateTime.MinValue;
|
||||
public IRelationService RelationService { get; private set; }
|
||||
public List<cFasdApiSearchResultEntry> SelectedSearchResult { get; private set; }
|
||||
public List<cF4sdApiSearchResultRelation> Relations { get; protected set; }
|
||||
|
||||
public ISearchUiProvider SearchUiProvider { get; private set; }
|
||||
|
||||
public cSearchHistoryEntryBase(string DisplayText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, ISearchUiProvider SearchUiProvider)
|
||||
public cSearchHistoryEntryBase(string DisplayText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, ISearchUiProvider SearchUiProvider, IRelationService relationService)
|
||||
{
|
||||
this.DisplayText = DisplayText;
|
||||
this.isSeen = isSeen;
|
||||
this.SelectedSearchResult = selectedSearchResult;
|
||||
this.Relations = relations;
|
||||
this.SearchUiProvider = SearchUiProvider;
|
||||
RelationService = relationService;
|
||||
LastRefresh = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
@@ -313,7 +315,7 @@ namespace FasdDesktopUi.Basics
|
||||
{
|
||||
public string HeaderText { get; private set; }
|
||||
|
||||
public cSearchHistorySearchResultEntry(string DisplayText, string HeaderText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, ISearchUiProvider SearchUiProvider) : base(DisplayText, selectedSearchResult, relations, SearchUiProvider)
|
||||
public cSearchHistorySearchResultEntry(string DisplayText, string HeaderText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, ISearchUiProvider SearchUiProvider, IRelationService relationService) : base(DisplayText, selectedSearchResult, relations, SearchUiProvider, relationService)
|
||||
{
|
||||
this.HeaderText = HeaderText;
|
||||
LastRefresh = DateTime.UtcNow;
|
||||
@@ -337,7 +339,7 @@ namespace FasdDesktopUi.Basics
|
||||
{
|
||||
public cF4sdApiSearchResultRelation SelectedRelation { get; private set; }
|
||||
|
||||
public cSearchHistoryRelationEntry(string DisplayText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, cF4sdApiSearchResultRelation selectedRealtion, ISearchUiProvider SearchUiProvider) : base(DisplayText, selectedSearchResult, relations, SearchUiProvider)
|
||||
public cSearchHistoryRelationEntry(string DisplayText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, cF4sdApiSearchResultRelation selectedRealtion, ISearchUiProvider SearchUiProvider, IRelationService relationService) : base(DisplayText, selectedSearchResult, relations, SearchUiProvider, relationService)
|
||||
{
|
||||
SelectedRelation = selectedRealtion;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using C4IT.FASD.Base;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.Models
|
||||
{
|
||||
public class CockpitValueDisplayData
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public IList<string> Values { get; set; }
|
||||
public IList<enumHealthCardStateLevel> Levels { get; set; }
|
||||
public bool IsLoading { get; set; }
|
||||
public IList<cUiActionBase> UiActions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -19,20 +19,31 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
|
||||
public static QuickActionProtocollEntry GetQuickActionProtocollEntry(cFasdQuickAction quickActionDefinition, cQuickActionCopyData quickActionCopyData)
|
||||
{
|
||||
string ascii = GetAscii(quickActionDefinition, quickActionCopyData);
|
||||
string html = GetHtml(quickActionDefinition, quickActionCopyData);
|
||||
string currentLanguage = cMultiLanguageSupport.CurrentLanguage;
|
||||
|
||||
return new QuickActionProtocollEntry(ascii, html)
|
||||
try
|
||||
{
|
||||
Id = quickActionDefinition.Id,
|
||||
Name = quickActionDefinition.Name,
|
||||
ExecutionTypeId = (int)quickActionDefinition.ExecutionType,
|
||||
WasRunningOnAffectedDevice = quickActionCopyData.WasRunningOnAffectedDevice,
|
||||
AffectedDeviceName = quickActionCopyData.AffectedDeviceName,
|
||||
ResultCode = (int?)quickActionCopyData.QuickActionOutput?.ResultCode,
|
||||
ErrorMessage = quickActionCopyData.QuickActionOutput?.ErrorDescription,
|
||||
MeasureValues = GetQuickActionHtmlValueComparison(quickActionCopyData.MeasureValues)
|
||||
};
|
||||
cMultiLanguageSupport.CurrentLanguage = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage ?? currentLanguage;
|
||||
|
||||
string ascii = GetAscii(quickActionDefinition, quickActionCopyData);
|
||||
string html = GetHtml(quickActionDefinition, quickActionCopyData);
|
||||
|
||||
return new QuickActionProtocollEntry(ascii, html)
|
||||
{
|
||||
Id = quickActionDefinition.Id,
|
||||
Name = quickActionDefinition.Name,
|
||||
ExecutionTypeId = (int)quickActionDefinition.ExecutionType,
|
||||
WasRunningOnAffectedDevice = quickActionCopyData.WasRunningOnAffectedDevice,
|
||||
AffectedDeviceName = quickActionCopyData.AffectedDeviceName,
|
||||
ResultCode = (int?)quickActionCopyData.QuickActionOutput?.ResultCode,
|
||||
ErrorMessage = quickActionCopyData.QuickActionOutput?.ErrorDescription,
|
||||
MeasureValues = GetQuickActionHtmlValueComparison(quickActionCopyData.MeasureValues)
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
cMultiLanguageSupport.CurrentLanguage = currentLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
internal static cQuickActionCopyData GetCopyData(cFasdQuickAction quickActionDefinition, cSupportCaseDataProvider dataProvider, bool wasRunningOnAffectedDevice, cQuickActionOutput quickActionOutput, List<cQuickActionMeasureValue> measureValues)
|
||||
@@ -93,7 +104,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
{
|
||||
string ascii = string.Empty;
|
||||
|
||||
ascii += GetQuickActionAsciiDescription(quickActionDefinition,copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode);
|
||||
ascii += GetQuickActionAsciiDescription(quickActionDefinition, copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode);
|
||||
ascii += GetQuickActionAsciiError(copyData.QuickActionOutput?.ErrorDescription);
|
||||
ascii += GetQuickActionAsciiOutput(quickActionDefinition, copyData.QuickActionOutput);
|
||||
ascii += GetQuickActionAsciiValueComparisonString(copyData.MeasureValues);
|
||||
@@ -101,7 +112,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
return ascii;
|
||||
}
|
||||
|
||||
private static string GetQuickActionAsciiDescription(cFasdQuickAction quickActionDefinition,string quickActionName, string deviceName, bool wasRunningOnAffectedDevice, DateTime executionTime, enumQuickActionSuccess? quickActionStatus)
|
||||
private static string GetQuickActionAsciiDescription(cFasdQuickAction quickActionDefinition, string quickActionName, string deviceName, bool wasRunningOnAffectedDevice, DateTime executionTime, enumQuickActionSuccess? quickActionStatus)
|
||||
{
|
||||
string asciiDescription = string.Empty;
|
||||
try
|
||||
@@ -125,7 +136,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
rawDescription = cMultiLanguageSupport.GetItem("QuickAction.RemoteSession.Copy.Description");
|
||||
|
||||
}
|
||||
|
||||
|
||||
asciiDescription = string.Format(rawDescription, quickActionName, deviceName, executionTime.ToString("g", new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)), quickActionStatusString);
|
||||
}
|
||||
catch (Exception E)
|
||||
@@ -259,7 +270,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
|
||||
output += AsciiSeperator + cMultiLanguageSupport.GetItem("QuickAction.Copy.Measure");
|
||||
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
cUtility.RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
foreach (var measureValue in measureValues)
|
||||
@@ -299,7 +310,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
|
||||
try
|
||||
{
|
||||
output += GetQuickActionHtmlDescription(quickActionDefinition,copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode);
|
||||
output += GetQuickActionHtmlDescription(quickActionDefinition, copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode);
|
||||
output += GetQuickActionHtmlError(copyData.QuickActionOutput?.ErrorDescription);
|
||||
output += GetQuickActionHtmlOutput(quickActionDefinition, copyData.QuickActionOutput);
|
||||
output += GetQuickActionHtmlValueComparison(copyData.MeasureValues);
|
||||
@@ -331,7 +342,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
}
|
||||
|
||||
var rawDescription = wasRunningOnAffectedDevice ? cMultiLanguageSupport.GetItem("QuickAction.Remote.Copy.Description.Html") : cMultiLanguageSupport.GetItem("QuickAction.Local.Copy.Description.Html");
|
||||
if(quickActionDefinition.Section == enumDataHistoryOrigin.Citrix.ToString())
|
||||
if (quickActionDefinition.Section == enumDataHistoryOrigin.Citrix.ToString())
|
||||
{
|
||||
rawDescription = cMultiLanguageSupport.GetItem("QuickAction.RemoteSession.Copy.Description.Html");
|
||||
|
||||
@@ -479,7 +490,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
|
||||
|
||||
output += "<p>" + cMultiLanguageSupport.GetItem("QuickAction.Copy.Measure.Html") + "</p>";
|
||||
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
cUtility.RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
foreach (var measureValue in measureValues)
|
||||
|
||||
@@ -9,8 +9,10 @@ namespace FasdDesktopUi.Basics.Services.RelationService
|
||||
public interface IRelationService
|
||||
{
|
||||
event EventHandler<StagedSearchResultRelationsEventArgs> RelationsFound;
|
||||
event EventHandler RelationsReset;
|
||||
|
||||
IEnumerable<cF4sdApiSearchResultRelation> GetLoadedRelations();
|
||||
void Reset();
|
||||
IReadOnlyList<cF4sdApiSearchResultRelation> GetLoadedRelations();
|
||||
Task<cF4sdStagedSearchResultRelationTaskId> LoadRelationsAsync(IEnumerable<cFasdApiSearchResultEntry> relatedTo, CancellationToken token = default);
|
||||
IRelationService Clone();
|
||||
}
|
||||
|
||||
@@ -14,8 +14,17 @@ namespace FasdDesktopUi.Basics.Services.RelationService
|
||||
{
|
||||
internal class RelationService : IRelationService
|
||||
{
|
||||
private readonly object _relationsLock = new object();
|
||||
private IEnumerable<cF4sdApiSearchResultRelation> _relations = new List<cF4sdApiSearchResultRelation>();
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
lock (_relationsLock)
|
||||
_relations = _relations.Where(r => r.Type == enumF4sdSearchResultClass.User).ToList();
|
||||
|
||||
RelationsReset?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously loads relations for the specified search results.
|
||||
/// </summary>
|
||||
@@ -27,24 +36,14 @@ namespace FasdDesktopUi.Basics.Services.RelationService
|
||||
{
|
||||
try
|
||||
{
|
||||
_relations = relatedTo?.Select(searchResult => new cF4sdApiSearchResultRelation(searchResult)).ToList() ?? new List<cF4sdApiSearchResultRelation>();
|
||||
lock (_relationsLock)
|
||||
_relations = relatedTo?.Select(searchResult => new cF4sdApiSearchResultRelation(searchResult)).ToList() ?? new List<cF4sdApiSearchResultRelation>();
|
||||
cF4sdStagedSearchResultRelationTaskId gatherRelationTask = await cFasdCockpitCommunicationBase.Instance.StartGatheringRelations(relatedTo, token);
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
const int maxRetryCount = 10;
|
||||
for (int i = 0; i < maxRetryCount; i++)
|
||||
{
|
||||
cF4sdStagedSearchResultRelations stagedRelations = await cFasdCockpitCommunicationBase.Instance.GetStagedRelations(gatherRelationTask.Id, token);
|
||||
stagedRelations.MergeAsRelationInfosWith(relatedTo);
|
||||
if (gatherRelationTask is null)
|
||||
return null;
|
||||
|
||||
_relations = _relations.Union(stagedRelations.Relations);
|
||||
RelationsFound?.Invoke(this, new StagedSearchResultRelationsEventArgs() { RelatedTo = relatedTo, StagedResultRelations = stagedRelations, RelationService = this });
|
||||
|
||||
if (stagedRelations?.IsComplete ?? false)
|
||||
break;
|
||||
}
|
||||
});
|
||||
_ = Task.Run(async () => await GatherRelationsAsync(gatherRelationTask.Id, relatedTo, token));
|
||||
|
||||
return gatherRelationTask;
|
||||
}
|
||||
@@ -56,15 +55,56 @@ namespace FasdDesktopUi.Basics.Services.RelationService
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<cF4sdApiSearchResultRelation> GetLoadedRelations() => _relations;
|
||||
private async Task GatherRelationsAsync(Guid gatherTaskId, IEnumerable<cFasdApiSearchResultEntry> relatedTo, CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
const int maxRetryCount = 10;
|
||||
for (int i = 0; i < maxRetryCount; i++)
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
await cFasdCockpitCommunicationBase.Instance.StopGatheringRelations(gatherTaskId, CancellationToken.None);
|
||||
return;
|
||||
}
|
||||
|
||||
cF4sdStagedSearchResultRelations stagedRelations = await cFasdCockpitCommunicationBase.Instance.GetStagedRelations(gatherTaskId, token);
|
||||
|
||||
if (stagedRelations is null)
|
||||
continue;
|
||||
|
||||
stagedRelations.MergeAsRelationInfosWith(relatedTo);
|
||||
|
||||
lock (_relationsLock)
|
||||
_relations = _relations.Union(stagedRelations.Relations).ToList();
|
||||
|
||||
RelationsFound?.Invoke(this, new StagedSearchResultRelationsEventArgs() { RelatedTo = relatedTo, StagedResultRelations = stagedRelations, RelationService = this });
|
||||
|
||||
if (stagedRelations?.IsComplete ?? false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<cF4sdApiSearchResultRelation> GetLoadedRelations()
|
||||
{
|
||||
lock (_relationsLock)
|
||||
return _relations.ToList();
|
||||
}
|
||||
|
||||
public IRelationService Clone()
|
||||
{
|
||||
RelationService copy = (RelationService)MemberwiseClone();
|
||||
copy._relations = _relations.Select(r => r).ToList();
|
||||
RelationService copy = new RelationService();
|
||||
lock (_relationsLock)
|
||||
copy._relations = _relations.ToList();
|
||||
return copy;
|
||||
}
|
||||
|
||||
public event EventHandler RelationsReset;
|
||||
public event EventHandler<StagedSearchResultRelationsEventArgs> RelationsFound;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using F4SD.Gamification.Services;
|
||||
using FasdCockpitBase.Models.RemoteDesktopConnection;
|
||||
using FasdCockpitCommunication.RemoteDesktopCommunication;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.RemoteDesktop
|
||||
{
|
||||
internal static class AgentRemoteDesktopService
|
||||
{
|
||||
private static readonly Dictionary<Guid, Process> _viewerProcesses = new Dictionary<Guid, Process>();
|
||||
|
||||
internal static async Task<RemoteDesktopConnectionStatusResult> StartRemoteDesktopConnectionAsync(AgentRemoteClientInfo clientInfo, bool isElevated, CancellationToken token = default)
|
||||
{
|
||||
const int maxRetryCount = 20;
|
||||
TimeSpan baseDelay = TimeSpan.FromSeconds(0.5);
|
||||
|
||||
AgentRemoteDesktopConnecitonDetails connectionDetails = await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.InitiateConnection<AgentRemoteDesktopConnecitonDetails>(clientInfo, isElevated, token);
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Initiated);
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Canceled);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Canceled);
|
||||
}
|
||||
|
||||
if (connectionDetails is null)
|
||||
{
|
||||
LogEntry("Could not initiate remote connection.", C4IT.Logging.LogLevels.Warning);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Unknown);
|
||||
}
|
||||
|
||||
if (connectionDetails.Errors != null && connectionDetails.Errors.Count > 0)
|
||||
{
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Error);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Error) { Errors = connectionDetails.Errors.Select(e => e.Message).ToArray() };
|
||||
}
|
||||
|
||||
RemoteDesktopConnectionStatusResult connectionStatus = null;
|
||||
|
||||
for (int i = 0; i < maxRetryCount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
connectionStatus = await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.GetConnectionStatus(connectionDetails.ConnectionId, token);
|
||||
LogEntry($"Update {i} RemoteDesktop connection status: {connectionStatus}", C4IT.Logging.LogLevels.Debug);
|
||||
|
||||
if (token.IsCancellationRequested || IsRemoteConnectionEstablished(connectionStatus.Status))
|
||||
break;
|
||||
|
||||
await Task.Delay(TimeSpan.FromTicks(baseDelay.Ticks * i));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Canceled);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Canceled);
|
||||
}
|
||||
|
||||
RemoteConnetionStatusChanged?.Invoke(null, connectionStatus.Status);
|
||||
|
||||
if (connectionStatus.Status != RemoteDesktopConnectionStatus.Accepted)
|
||||
{
|
||||
LogEntry($"Could not connect to remote desktop. Status: {connectionStatus}", C4IT.Logging.LogLevels.Warning);
|
||||
return new RemoteDesktopConnectionStatusResult(connectionStatus.Status);
|
||||
}
|
||||
|
||||
StartViewer(connectionDetails);
|
||||
|
||||
GamificationService.TrackAction(F4SD.Gamification.CockpitAction.StartRemoteConnection);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Connected);
|
||||
}
|
||||
|
||||
private static bool IsRemoteConnectionEstablished(RemoteDesktopConnectionStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case RemoteDesktopConnectionStatus.Accepted:
|
||||
case RemoteDesktopConnectionStatus.Connected:
|
||||
case RemoteDesktopConnectionStatus.Finished:
|
||||
case RemoteDesktopConnectionStatus.Canceled:
|
||||
return true;
|
||||
case RemoteDesktopConnectionStatus.Unknown:
|
||||
case RemoteDesktopConnectionStatus.Initiated:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void StartViewer(AgentRemoteDesktopConnecitonDetails connectionDetails)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo info = new ProcessStartInfo(GetViewerPath())
|
||||
{
|
||||
Arguments = $"-connectionId {connectionDetails.ConnectionId} -phoenixServiceUrl {connectionDetails.PhoenixServiceUrl} -secret {connectionDetails.Secret}"
|
||||
};
|
||||
|
||||
Process process = Process.Start(info);
|
||||
_viewerProcesses.Add(connectionDetails.ConnectionId, process);
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Connected);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task StopRemoteDesktopConnection(Guid connectionId, CancellationToken token = default)
|
||||
{
|
||||
await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.StopConnection(connectionId, token);
|
||||
|
||||
if (_viewerProcesses.TryGetValue(connectionId, out var process))
|
||||
process.Close();
|
||||
}
|
||||
|
||||
internal static string GetViewerPath()
|
||||
{
|
||||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Phoenix\Phoenix.Viewer.exe").ToString();
|
||||
}
|
||||
|
||||
internal static EventHandler<RemoteDesktopConnectionStatus> RemoteConnetionStatusChanged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using C4IT.FASD.Base;
|
||||
using FasdDesktopUi.Basics.Enums;
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
{
|
||||
internal static class MenuDataFactory
|
||||
{
|
||||
internal static cMenuDataBase GetByName(string name, cNamedParameterList namedParameterEntries, IEnumerable<enumFasdInformationClass> availableInformationClasses)
|
||||
{
|
||||
if (!cF4SDCockpitXmlConfig.Instance.MenuItems.TryGetValue(name, out var menuDataDefinition))
|
||||
return null;
|
||||
|
||||
return Create(menuDataDefinition, namedParameterEntries, availableInformationClasses);
|
||||
}
|
||||
|
||||
internal static cMenuDataBase Create(cFasdBaseConfigMenuItem definition, cNamedParameterList namedParameterEntries, IEnumerable<enumFasdInformationClass> availableInformationClasses)
|
||||
{
|
||||
cMenuDataBase menuData;
|
||||
|
||||
switch (definition)
|
||||
{
|
||||
case cFasdQuickAction quickActionDefinition:
|
||||
menuData = new cMenuDataBase(quickActionDefinition);
|
||||
break;
|
||||
case cCopyTemplate copyTemplate:
|
||||
menuData = new cMenuDataBase(copyTemplate);
|
||||
break;
|
||||
case cFasdMenuSection sectionDefinition:
|
||||
menuData = new cMenuDataContainer(sectionDefinition);
|
||||
break;
|
||||
case cFasdQuickTip quickTip:
|
||||
menuData = new cMenuDataBase(quickTip);
|
||||
break;
|
||||
default:
|
||||
menuData = new cMenuDataBase(definition);
|
||||
break;
|
||||
}
|
||||
|
||||
enumActionDisplayType displayType = ActionDisplayTypeInspector.GetDisplayType(definition, namedParameterEntries, availableInformationClasses);
|
||||
menuData.SetUiActionDisplayType(displayType);
|
||||
|
||||
return menuData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using FasdCockpitCommunication.RemoteDesktopCommunication;
|
||||
using FasdDesktopUi.Basics.CustomEvents;
|
||||
using FasdDesktopUi.Basics.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.Services.Models;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase.Processors;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using FasdDesktopUi.Pages.DetailsPage.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -12,18 +17,18 @@ using static C4IT.Logging.cLogManager;
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to manage the <see cref="ISupportCase"/> for the UI via the <see cref="SupportCaseProcessor"/>
|
||||
/// Used to manage the <see cref="ISupportCase"/> for the UI via the <see cref="ISupportCaseProcessor"/>
|
||||
/// </summary>
|
||||
public class SupportCaseController
|
||||
{
|
||||
private SupportCaseProcessor _supportCaseProcessor;
|
||||
private ISupportCaseProcessor _supportCaseProcessor;
|
||||
private cF4sdApiSearchResultRelation _focusedRelation;
|
||||
private readonly Dictionary<enumFasdInformationClass, cF4sdApiSearchResultRelation> _selectedRelations = new Dictionary<enumFasdInformationClass, cF4sdApiSearchResultRelation>();
|
||||
private cHealthCard _selectedHealthcard = null;
|
||||
private bool _hasDirectionConnection = false;
|
||||
public cSupportCaseDataProvider SupportCaseDataProviderArtifact { get => _supportCaseProcessor?.SupportCaseDataProviderArtifact; }
|
||||
|
||||
internal void SetSupportCaseProcessor(SupportCaseProcessor supportCaseProcessor, IEnumerable<cF4sdIdentityEntry> preselectedIdentities)
|
||||
internal void SetSupportCaseProcessor(ISupportCaseProcessor supportCaseProcessor, IEnumerable<cF4sdIdentityEntry> preselectedIdentities)
|
||||
{
|
||||
IEnumerable<cF4sdApiSearchResultRelation> preselectedRelations = GetPreselectedRelations(supportCaseProcessor.GetCaseRelations(), preselectedIdentities);
|
||||
|
||||
@@ -88,6 +93,9 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
{
|
||||
CaseDataChanged?.Invoke(this, e);
|
||||
|
||||
if (e.DataTables.Any(t => !t.Name.StartsWith("Computation_")))
|
||||
_supportCaseProcessor.ProcessComputations(e.Relation, _supportCaseProcessor.GetHealthcardFor(e.Relation).Prerequisites.Computations.Values);
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await UpdateStatusOfSelectedRelations();
|
||||
@@ -220,7 +228,7 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
relationEntry.Value.Infos[StatusString] = statusValue;
|
||||
}
|
||||
|
||||
IEnumerable<cHeadingDataModel> newHeadingData = SupportCaseHeadingController.GetHeadingData(_selectedRelations);
|
||||
IEnumerable<cHeadingDataModel> newHeadingData = GetHeadingData();
|
||||
HeadingDataChanged?.Invoke(this, new HeadingDataEventArgs(newHeadingData));
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -234,18 +242,209 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.LastDataRequest = DateTime.Now;
|
||||
await _supportCaseProcessor.UpdateLatestCaseDataFor(_focusedRelation);
|
||||
}
|
||||
public cCopyTemplate GetCopyTemplate()
|
||||
{
|
||||
string defaultCopyTemplate = _selectedHealthcard?.DefaultCopyTemplate
|
||||
?? cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.DefaultTemplate.Name
|
||||
?? string.Empty;
|
||||
|
||||
public List<List<cWidgetValueModel>> GetWidgetData()
|
||||
=> _supportCaseProcessor.GetWidgetData(_focusedRelation);
|
||||
Dictionary<string, cCopyTemplate> copyTemplates = cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates?.CopyTemplates;
|
||||
|
||||
if (copyTemplates?.TryGetValue(defaultCopyTemplate, out cCopyTemplate _defaultCopyTemplate) ?? false)
|
||||
return _defaultCopyTemplate;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
public List<List<cWidgetValueModel>> GetWidgetsData()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<List<cWidgetValueModel>> widgetsData = new List<List<cWidgetValueModel>>();
|
||||
cHealthCard currentHealthCard = _supportCaseProcessor.GetHealthcardFor(_focusedRelation);
|
||||
IEnumerable<cHealthCardStateCategory> widgetsDefinition = currentHealthCard.CategoriesStatic.StateCategories;
|
||||
|
||||
foreach (var widgetDefinition in widgetsDefinition)
|
||||
{
|
||||
List<cWidgetValueModel> widgetData = new List<cWidgetValueModel>();
|
||||
|
||||
foreach (var widgetValueDefinition in widgetDefinition.States)
|
||||
{
|
||||
CockpitValueDisplayData displayData = _supportCaseProcessor.GetCockpitValueDisplayData(widgetValueDefinition, _focusedRelation, true);
|
||||
cUiActionBase uiAction = _supportCaseProcessor.GetUiAction(widgetValueDefinition);
|
||||
|
||||
var widgetValue = new cWidgetValueModel(displayData, GetHighlightColor(displayData?.Levels?.FirstOrDefault() ?? enumHealthCardStateLevel.None), uiAction);
|
||||
|
||||
if (widgetValue?.UiActionValue != null && ShouldHideUiActionValue(widgetValue.Value))
|
||||
widgetValue.UiActionValue.DisplayType = enumActionDisplayType.hidden;
|
||||
|
||||
widgetData.Add(widgetValue);
|
||||
}
|
||||
|
||||
widgetsData.Add(widgetData);
|
||||
}
|
||||
|
||||
return widgetsData;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
return null;
|
||||
}
|
||||
|
||||
bool ShouldHideUiActionValue(string widgetValue)
|
||||
=> string.IsNullOrWhiteSpace(widgetValue) || widgetValue == "0";
|
||||
}
|
||||
|
||||
public cDetailsPageDataHistoryDataModel GetHistoryData()
|
||||
=> _supportCaseProcessor.GetHistoryData(_focusedRelation);
|
||||
=> ((SupportCaseProcessor)_supportCaseProcessor).GetHistoryData(_focusedRelation);
|
||||
|
||||
public List<cContainerCollectionData> GetContainerData()
|
||||
=> _supportCaseProcessor.GetContainerData(_focusedRelation);
|
||||
=> ((SupportCaseProcessor)_supportCaseProcessor).GetContainerData(_focusedRelation);
|
||||
|
||||
public List<cMenuDataBase> GetMenuBarData()
|
||||
=> _supportCaseProcessor.GetMenuBarData(_focusedRelation);
|
||||
public IEnumerable<cMenuDataBase> GetMenuData()
|
||||
{
|
||||
var menuBarDatas = cF4SDCockpitXmlConfig.Instance.MenuItems.ToDictionary(config => config.Key, config => (Config: config.Value, MenuValue: MenuDataFactory.Create(config.Value, _supportCaseProcessor.SupportCaseDataProviderArtifact.NamedParameterEntries, _selectedRelations.Values.Select(r => cF4sdIdentityEntry.GetFromSearchResult(r.Type)).ToList())));
|
||||
|
||||
try
|
||||
{
|
||||
List<string> menuBarDatasAddedToSection = new List<string>();
|
||||
|
||||
foreach (var menuBarData in menuBarDatas.Values)
|
||||
{
|
||||
bool isPinned = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.QuickActionsPinned.Contains(menuBarData.Config.Name);
|
||||
menuBarData.MenuValue.IconPositionIndex = isPinned ? cF4SDCockpitXmlConfig.Instance.HealthCardConfig.QuickActionsPinned.IndexOf(menuBarData.Config.Name) : -1;
|
||||
|
||||
// Same Logic in GetFilteredMenuData()
|
||||
bool hasBeenAddedToSection = TryAddMenuDataToSection(ref menuBarDatas, menuBarData.Config.Section, menuBarData.MenuValue);
|
||||
|
||||
foreach (var section in menuBarData.Config.Sections)
|
||||
{
|
||||
// todo add test for adding to multiple sections
|
||||
hasBeenAddedToSection = TryAddMenuDataToSection(ref menuBarDatas, section, menuBarData.MenuValue) || hasBeenAddedToSection; // order is relevent, because data has to be added to section
|
||||
}
|
||||
|
||||
if (hasBeenAddedToSection)
|
||||
menuBarDatasAddedToSection.Add(menuBarData.Config.Name);
|
||||
}
|
||||
|
||||
foreach (var menuBarData in menuBarDatasAddedToSection)
|
||||
{
|
||||
if (cF4SDCockpitXmlConfig.Instance.HealthCardConfig.QuickActionsPinned.Contains(menuBarData))
|
||||
continue;
|
||||
|
||||
menuBarDatas.Remove(menuBarData);
|
||||
}
|
||||
|
||||
return menuBarDatas.Values.Select(data => data.MenuValue);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
return new List<cMenuDataBase>();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<cMenuDataBase> GetFilteredMenuData(MenuDataFilter filterQuery)
|
||||
{
|
||||
Dictionary<string, (cFasdBaseConfigMenuItem Config, cMenuDataBase MenuValue)> menuBarDatas = cF4SDCockpitXmlConfig.Instance.MenuItems.ToDictionary(config => config.Key, config => (Config: config.Value, MenuValue: MenuDataFactory.Create(config.Value, _supportCaseProcessor.SupportCaseDataProviderArtifact.NamedParameterEntries, _selectedRelations.Values.Select(r => cF4sdIdentityEntry.GetFromSearchResult(r.Type)).ToList())));
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var menuBarData in menuBarDatas.Values)
|
||||
{
|
||||
// Same Logic in GetMenuData()
|
||||
bool hasBeenAddedToSection = TryAddMenuDataToSection(ref menuBarDatas, menuBarData.Config.Section, menuBarData.MenuValue);
|
||||
|
||||
foreach (var section in menuBarData.Config.Sections)
|
||||
{
|
||||
// todo add test for adding to multiple sections
|
||||
hasBeenAddedToSection = TryAddMenuDataToSection(ref menuBarDatas, section, menuBarData.MenuValue) || hasBeenAddedToSection; // order is relevent, because data has to be added to section
|
||||
}
|
||||
}
|
||||
|
||||
return menuBarDatas.Values.Select(data => data.MenuValue)
|
||||
.Where(md => md.MenuText.ToLower().Contains(filterQuery?.SearchString?.ToLower()));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
return new List<cMenuDataBase>();
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryAddMenuDataToSection(ref Dictionary<string, (cFasdBaseConfigMenuItem Config, cMenuDataBase MenuValue)> menuBarDatas, string section, cMenuDataBase menuData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(section))
|
||||
return false;
|
||||
|
||||
if (!menuBarDatas.TryGetValue(section, out var sectionMenuBar))
|
||||
return false;
|
||||
|
||||
if (!(sectionMenuBar.MenuValue is cMenuDataContainer containerData))
|
||||
return false;
|
||||
|
||||
if (containerData.UiAction is cSubMenuAction subMenuAction)
|
||||
{
|
||||
if (!subMenuAction.SubMenuData.Any(item => item.MenuText == menuData.MenuText)) // todo SubMenuData maybe better as Dictionary<Guid, cMenuDataBase>
|
||||
subMenuAction.SubMenuData.Add(menuData);
|
||||
|
||||
if (!containerData.SubMenuData.Any(item => item.MenuText == menuData.MenuText))
|
||||
containerData.SubMenuData.Add(menuData);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal IEnumerable<cHeadingDataModel> GetHeadingData()
|
||||
=> SupportCaseHeadingController.GetHeadingData(_selectedRelations);
|
||||
|
||||
private static enumHighlightColor GetHighlightColor(enumHealthCardStateLevel level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case enumHealthCardStateLevel.None:
|
||||
return enumHighlightColor.none;
|
||||
case enumHealthCardStateLevel.Ok:
|
||||
return enumHighlightColor.green;
|
||||
case enumHealthCardStateLevel.Warning:
|
||||
return enumHighlightColor.orange;
|
||||
case enumHealthCardStateLevel.Error:
|
||||
return enumHighlightColor.red;
|
||||
case enumHealthCardStateLevel.Info:
|
||||
return enumHighlightColor.blue;
|
||||
default:
|
||||
return enumHighlightColor.none;
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<cF4sdApiSearchResultRelation> GetRelationsOf(enumFasdInformationClass informationClass)
|
||||
{
|
||||
return _supportCaseProcessor.GetCaseRelations().FirstOrDefault(r => r.Key == informationClass);
|
||||
}
|
||||
|
||||
internal AgentRemoteClientInfo GetAgentClientInfo()
|
||||
{
|
||||
if (_focusedRelation.Type != enumF4sdSearchResultClass.Computer)
|
||||
return null;
|
||||
|
||||
int deviceId = 0;
|
||||
int userId = 0;
|
||||
|
||||
bool hasAllRequiredNamedParameters =
|
||||
_supportCaseProcessor.TryGetNamedParameterValue(_focusedRelation, SupportCaseProcessor.AgentOrganisationCodeNamedParameterName, out int organisationId)
|
||||
&& _supportCaseProcessor.TryGetNamedParameterValue(_focusedRelation, SupportCaseProcessor.AgentUserIdNamedParameterName, out userId)
|
||||
&& _supportCaseProcessor.TryGetNamedParameterValue(_focusedRelation, SupportCaseProcessor.AgentDeviceIdNamedParameterName, out deviceId);
|
||||
|
||||
if (!hasAllRequiredNamedParameters)
|
||||
return null;
|
||||
|
||||
return new AgentRemoteClientInfo()
|
||||
{
|
||||
DeviceCode = deviceId,
|
||||
AccountCode = userId,
|
||||
OrganisationCode = organisationId
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the currently for a support case relevant and shown relations have been updated.
|
||||
@@ -264,4 +463,15 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
|
||||
public event EventHandler<HeadingDataEventArgs> HeadingDataChanged;
|
||||
}
|
||||
|
||||
public class MenuDataFilter
|
||||
{
|
||||
public string SearchString { get; set; }
|
||||
|
||||
public MenuDataFilter(string searchString = null)
|
||||
{
|
||||
SearchString = searchString;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
|
||||
{
|
||||
case enumF4sdSearchResultClass.Computer:
|
||||
case enumF4sdSearchResultClass.User:
|
||||
case enumF4sdSearchResultClass.Phone:
|
||||
isOnline = string.Equals(statusValue, "Online", StringComparison.InvariantCultureIgnoreCase);
|
||||
break;
|
||||
case enumF4sdSearchResultClass.Ticket:
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
void AddCaseRelations(ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> relations);
|
||||
ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> GetCaseRelations();
|
||||
Task LoadSupportCaseDataAsync(cF4sdApiSearchResultRelation relation, IEnumerable<string> tablesToLoad);
|
||||
IEnumerable<object> GetSupportCaseHealthcardData(cF4sdApiSearchResultRelation relation, cValueAddress valueAddress);
|
||||
IList<object> GetSupportCaseHealthcardData(cF4sdApiSearchResultRelation relation, cValueAddress valueAddress, bool getStatic);
|
||||
void UpdateSupportCaseDataCache(cF4sdApiSearchResultRelation relation, IEnumerable<cF4SDHealthCardRawData.cHealthCardTable> tables);
|
||||
void InvalidateCaseDataCacheFor(cF4sdApiSearchResultRelation relation);
|
||||
void InvalidateLatestCaseDataCacheFor(cF4sdApiSearchResultRelation relation, out ICollection<cF4SDHealthCardRawData.cHealthCardTable> invalidatedTables);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using C4IT.FASD.Base;
|
||||
using FasdDesktopUi.Basics.CustomEvents;
|
||||
using FasdDesktopUi.Basics.Services.Models;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase.Processors
|
||||
{
|
||||
internal interface ISupportCaseProcessor
|
||||
{
|
||||
cSupportCaseDataProvider SupportCaseDataProviderArtifact { get; }
|
||||
|
||||
event EventHandler<RelationEventArgs> AvailableCaseRelationsAdded;
|
||||
event EventHandler<SupportCaseDataEventArgs> CaseDataChanged;
|
||||
|
||||
void SetSupportCase(ISupportCase supportCase);
|
||||
CockpitValueDisplayData GetCockpitValueDisplayData(cHealthCardStateBase displayValueDefinition, cF4sdApiSearchResultRelation relation, bool getStatic);
|
||||
Task LoadSupportCaseDataAsync(cF4sdApiSearchResultRelation relation, IEnumerable<string> tablesToLoad);
|
||||
void ProcessComputations(cF4sdApiSearchResultRelation relation, IEnumerable<cHealthCardComputationBase> computations);
|
||||
Task UpdateLatestCaseDataFor(cF4sdApiSearchResultRelation relation);
|
||||
ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> GetCaseRelations();
|
||||
cHealthCard GetHealthcardFor(cF4sdApiSearchResultRelation relation);
|
||||
cUiActionBase GetUiAction(cHealthCardStateBase stateDefinition);
|
||||
bool TryGetNamedParameterValue<T>(cF4sdApiSearchResultRelation relation, string parameterName, out T value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using C4IT.F4SD.DisplayFormatting;
|
||||
using C4IT.FASD.Base;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase.Processors
|
||||
{
|
||||
internal class SupportCaseDetailsValueProcessesor
|
||||
{
|
||||
/// <summary>
|
||||
/// Transform a value to a <seealso cref="cF4SDHealthCardRawData.cHealthCardDetailsTable"/>
|
||||
/// </summary>
|
||||
/// <param name="rawValue">Raw value in form of CSV or JSON</param>
|
||||
/// <param name="stateDetailsValued">Details definition the transformation is based on</param>
|
||||
/// <returns></returns>
|
||||
internal static cF4SDHealthCardRawData.cHealthCardDetailsTable GetDetailsTable(object rawValue, cHealthCardDetailsValued stateDetailsValued)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rawValue is null)
|
||||
return null;
|
||||
|
||||
var stringValue = cUtility.RawValueFormatter.GetDisplayValue(rawValue, RawValueType.STRING);
|
||||
|
||||
if (stringValue is null)
|
||||
return null;
|
||||
|
||||
List<object[]> tableValues = stateDetailsValued.Format == cHealthCardDetailsValued.ValuedFormat.json
|
||||
? ParseJson(stringValue, stateDetailsValued)
|
||||
: ParseCsv(stringValue, stateDetailsValued);
|
||||
|
||||
tableValues = tableValues ?? new List<object[]>();
|
||||
|
||||
var detailedValueTable = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
|
||||
{
|
||||
Name = "Details-" + stateDetailsValued.ParentState.Name,
|
||||
Columns = stateDetailsValued.Select(v => v.Names.GetValue()).ToList(),
|
||||
Values = new Dictionary<int, List<object[]>>() { { 0, tableValues } }
|
||||
};
|
||||
|
||||
return detailedValueTable;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static List<object[]> ParseJson(string text, cHealthCardDetailsValued details)
|
||||
{
|
||||
try
|
||||
{
|
||||
var jObjects = JsonConvert.DeserializeObject<List<JObject>>(text);
|
||||
if (jObjects == null || jObjects.Count == 0)
|
||||
return new List<object[]>();
|
||||
|
||||
var values = new List<object[]>();
|
||||
foreach (JObject jObject in jObjects)
|
||||
{
|
||||
var valueRow = new object[details.Count];
|
||||
for (int i = 0; i < details.Count; i++)
|
||||
valueRow[i] = null;
|
||||
|
||||
foreach (var jProp in jObject.Properties())
|
||||
{
|
||||
var name = jProp.Name;
|
||||
var index = details.FindIndex(v => v.Column.Equals(name, StringComparison.InvariantCultureIgnoreCase));
|
||||
if (index < 0)
|
||||
continue;
|
||||
|
||||
var column = details[index];
|
||||
if (jProp.Value is JValue jValue)
|
||||
{
|
||||
var value = jValue.Value;
|
||||
valueRow[index] = cUtility.RawValueFormatter.GetDisplayValue(value, column.DisplayType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
values.Add(valueRow);
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new List<object[]>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static List<object[]> ParseCsv(string text, cHealthCardDetailsValued details)
|
||||
{
|
||||
var values = new List<object[]>();
|
||||
var rows = text.Split(details.RowSeparator);
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(row))
|
||||
continue;
|
||||
|
||||
var entry = new List<object>();
|
||||
if (details.ColSeparator == null)
|
||||
{
|
||||
entry.Add(row.Trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
var columns = row.Split((char)details.ColSeparator);
|
||||
foreach (var column in columns)
|
||||
entry.Add(column?.Trim());
|
||||
}
|
||||
|
||||
while (entry.Count < details.Count)
|
||||
entry.Add(null);
|
||||
|
||||
values.Add(entry.ToArray());
|
||||
}
|
||||
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a display string based on StateDetails and its values
|
||||
/// </summary>
|
||||
internal static string GetDetailStringValue(cHealthCardDetailsBase details, cF4SDHealthCardRawData.cHealthCardDetailsTable detailTableValueTable)
|
||||
{
|
||||
if (detailTableValueTable?.Values is null || detailTableValueTable.Values.Count == 0)
|
||||
return null;
|
||||
|
||||
var tableValues = detailTableValueTable.Values.First().Value;
|
||||
if (detailTableValueTable.Columns.Count >= 1 && tableValues.Count == 1)
|
||||
return cUtility.RawValueFormatter.GetDisplayValue(detailTableValueTable.Values.First().Value.First()?.First(), details.First().DisplayType);
|
||||
else
|
||||
return cUtility.RawValueFormatter.GetDisplayValue(detailTableValueTable.Values.First().Value.Count, RawValueType.STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,643 @@
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using C4IT.Logging;
|
||||
using FasdDesktopUi.Basics.CustomEvents;
|
||||
using FasdDesktopUi.Basics.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.Services.Models;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase.Controllers;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using FasdDesktopUi.Pages.DetailsPage.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase.Processors
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for processing raw data of a <see cref="ISupportCase"/> for the UI in a certain way.
|
||||
/// </summary>
|
||||
internal class SupportCaseProcessor : ISupportCaseProcessor
|
||||
{
|
||||
internal const string AgentDeviceIdNamedParameterName = "F4SD_Agent_DeviceId";
|
||||
internal const string AgentUserIdNamedParameterName = "F4SD_Agent_UserId";
|
||||
internal const string AgentOrganisationCodeNamedParameterName = "F4SD_Agent_OrganisationId";
|
||||
|
||||
private ISupportCase _supportCase;
|
||||
public cSupportCaseDataProvider SupportCaseDataProviderArtifact { get => _supportCase?.SupportCaseDataProviderArtifact; }
|
||||
|
||||
private readonly Dictionary<cF4sdApiSearchResultRelation, cDetailsPageData> _detailsPageDataCache = new Dictionary<cF4sdApiSearchResultRelation, cDetailsPageData>();
|
||||
|
||||
private readonly Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, object>> _namedParameterCache = new Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, object>>();
|
||||
|
||||
private readonly Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, IList<object>>> _computationCache = new Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, IList<object>>>();
|
||||
|
||||
public void SetSupportCase(ISupportCase supportCase)
|
||||
{
|
||||
if (_supportCase != null)
|
||||
{
|
||||
_supportCase.CaseRelationsAdded -= HandleSupportCaseRelationsAdded;
|
||||
_supportCase.SupportCaseDataCacheHasChanged -= HandleSupportCaseDataCacheHasChanged;
|
||||
}
|
||||
|
||||
_supportCase = supportCase;
|
||||
|
||||
_supportCase.CaseRelationsAdded += HandleSupportCaseRelationsAdded;
|
||||
_supportCase.SupportCaseDataCacheHasChanged += HandleSupportCaseDataCacheHasChanged;
|
||||
}
|
||||
|
||||
private void HandleSupportCaseRelationsAdded(object sender, RelationEventArgs e)
|
||||
=> AvailableCaseRelationsAdded?.Invoke(this, e);
|
||||
|
||||
private async void HandleSupportCaseDataCacheHasChanged(object sender, SupportCaseDataEventArgs e)
|
||||
{
|
||||
bool isArtifactShowingCorrectHealthCard
|
||||
= SupportCaseDataProviderArtifact.HealthCardDataHelper.SelectedHealthCard == GetHealthcardFor(e.Relation);
|
||||
|
||||
if (!isArtifactShowingCorrectHealthCard)
|
||||
{
|
||||
// todo this can probably be removed, as soon as the last dependency of the SupportCaseDataProviderArtifact is gone.
|
||||
// till then the detailspageData gets overriden with the detailspageData of the new relation.
|
||||
// However, the removal shouldn't be much of a problem, due to the fact the Artifact also stores the raw data
|
||||
_detailsPageDataCache.Remove(e.Relation);
|
||||
return;
|
||||
}
|
||||
await EnsureDetailsPageDataCachedAsync(e.Relation).ConfigureAwait(false);
|
||||
|
||||
UpdateNamedParameters(e.Relation, e.DataTables);
|
||||
CaseDataChanged?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private async Task EnsureDetailsPageDataCachedAsync(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
if (!_detailsPageDataCache.TryGetValue(relation, out var cachedData))
|
||||
{
|
||||
_detailsPageDataCache[relation] = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync().ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
cDetailsPageData detailData = _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataWithoutHeading();
|
||||
cachedData.WidgetData = detailData.WidgetData;
|
||||
cachedData.DataHistoryList = detailData.DataHistoryList;
|
||||
cachedData.MenuBarData = detailData.MenuBarData;
|
||||
cachedData.DataContainerCollectionList = detailData.DataContainerCollectionList;
|
||||
}
|
||||
|
||||
private void UpdateNamedParameters(cF4sdApiSearchResultRelation relation, IEnumerable<cF4SDHealthCardRawData.cHealthCardTable> dataTables)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_namedParameterCache.ContainsKey(relation))
|
||||
_namedParameterCache.Add(relation, new Dictionary<string, object>());
|
||||
|
||||
var healthcard = GetHealthcardFor(relation);
|
||||
|
||||
foreach (var namedParameter in cHealthCardPrerequisites.GetNamedParameters(healthcard).Values)
|
||||
{
|
||||
var table = dataTables.FirstOrDefault(t => t.Name == namedParameter.DatabaseInfo.ValueTable);
|
||||
|
||||
if (table is null)
|
||||
continue;
|
||||
|
||||
if (!table.Columns.TryGetValue(namedParameter.DatabaseInfo.ValueColumn, out var column))
|
||||
continue;
|
||||
|
||||
string value = cUtility.RawValueFormatter.GetDisplayValue(column.Values.FirstOrDefault(), namedParameter.Display);
|
||||
_namedParameterCache[relation][namedParameter.ParameterName] = value;
|
||||
}
|
||||
|
||||
AddDefaultNamedParameters();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
|
||||
void AddDefaultNamedParameters()
|
||||
{
|
||||
var table = dataTables.FirstOrDefault(t => t.Name == "agnt-computer");
|
||||
|
||||
if (table != null)
|
||||
{
|
||||
if (table.Columns.TryGetValue("id", out var agentDeviceIdColumn))
|
||||
_namedParameterCache[relation][AgentDeviceIdNamedParameterName] = agentDeviceIdColumn.Values.FirstOrDefault();
|
||||
}
|
||||
|
||||
table = dataTables.FirstOrDefault(t => t.Name == "agnt-user");
|
||||
|
||||
if (table != null)
|
||||
{
|
||||
if (table.Columns.TryGetValue("id", out var agentUserColumn))
|
||||
_namedParameterCache[relation][AgentUserIdNamedParameterName] = agentUserColumn.Values.FirstOrDefault();
|
||||
}
|
||||
|
||||
_namedParameterCache[relation][AgentOrganisationCodeNamedParameterName] = cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadSupportCaseDataAsync(cF4sdApiSearchResultRelation relation, IEnumerable<string> tablesToLoad)
|
||||
{
|
||||
_ = Task.Run(async () => await _supportCase.LoadSupportCaseDataAsync(relation, tablesToLoad.Where(t => !t.Contains("-details-"))));
|
||||
|
||||
await EnsureDetailsPageDataCachedAsync(relation).ConfigureAwait(false);
|
||||
_supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.UpdateNamedParameterEntries();
|
||||
|
||||
CaseDataChanged?.Invoke(this, new SupportCaseDataEventArgs());
|
||||
}
|
||||
|
||||
public void ProcessComputations(cF4sdApiSearchResultRelation relation, IEnumerable<cHealthCardComputationBase> computations)
|
||||
{
|
||||
if (!_computationCache.ContainsKey(relation))
|
||||
_computationCache.Add(relation, new Dictionary<string, IList<object>>());
|
||||
|
||||
var cachedComputations = _computationCache[relation];
|
||||
|
||||
var computationTables = new List<cF4SDHealthCardRawData.cHealthCardTable>();
|
||||
foreach (cHealthCardComputationBase computation in computations)
|
||||
{
|
||||
AddComputationTable(computation);
|
||||
AddComputationTableStatic(computation);
|
||||
}
|
||||
CaseDataChanged?.Invoke(this, new SupportCaseDataEventArgs() { Relation = relation, DataTables = computationTables });
|
||||
|
||||
void AddComputationTable(cHealthCardComputationBase computation)
|
||||
{
|
||||
var computationTable = new cF4SDHealthCardRawData.cHealthCardTable() { Name = $"Computation_{computation.Name}", AlternateStaticTable = $"Computation_{computation.Name}_latest" };
|
||||
var computationColumn = new cF4SDHealthCardRawData.cHealthCardTableColumn(computationTable);
|
||||
|
||||
for (int i = 0; i < cF4SDCockpitXmlConfig.Instance.HealthCardConfig.SearchResultAge; i++)
|
||||
{
|
||||
object[] valuesRequiredToCompute = computation.Values
|
||||
.Where(v => v.ValueTable != null && v.ValueColumn != null)
|
||||
.Select(v => _supportCase.GetSupportCaseHealthcardData(relation, v, false)?.ElementAtOrDefault(i))
|
||||
.ToArray();
|
||||
|
||||
object computedValue = computation.Compute(valuesRequiredToCompute);
|
||||
computationColumn.Values.Add(computedValue);
|
||||
}
|
||||
|
||||
computationTable.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() { ["default"] = computationColumn };
|
||||
computationTables.Add(computationTable);
|
||||
|
||||
cachedComputations[computation.Name] = computationColumn.Values;
|
||||
}
|
||||
void AddComputationTableStatic(cHealthCardComputationBase computation)
|
||||
{
|
||||
var computationTableStatic = new cF4SDHealthCardRawData.cHealthCardTable() { Name = $"Computation_{computation.Name}_latest" };
|
||||
var computationColumnStatic = new cF4SDHealthCardRawData.cHealthCardTableColumn(computationTableStatic);
|
||||
object[] staticValuesRequiredToCompute = computation.Values
|
||||
.Where(v => v.ValueTable != null && v.ValueColumn != null)
|
||||
.Select(v => _supportCase.GetSupportCaseHealthcardData(relation, v, true)?.ElementAtOrDefault(0))
|
||||
.ToArray();
|
||||
|
||||
object computedStaticValue = computation.Compute(staticValuesRequiredToCompute);
|
||||
computationColumnStatic.Values.Add(computedStaticValue);
|
||||
computationTableStatic.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>() { ["default"] = computationColumnStatic };
|
||||
computationTables.Add(computationTableStatic);
|
||||
cachedComputations[$"{computation.Name}_latest"] = computationColumnStatic.Values;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task UpdateLatestCaseDataFor(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
try
|
||||
{
|
||||
int? agentUserId = relation.Identities.FirstOrDefault(i => i.Class == enumFasdInformationClass.User)?.agentId;
|
||||
int? agentDeviceId = relation.Identities.FirstOrDefault(i => i.Class == enumFasdInformationClass.Computer)?.agentId;
|
||||
|
||||
await ActualizeDataAsync(agentUserId, agentDeviceId);
|
||||
_supportCase.InvalidateLatestCaseDataCacheFor(relation, out var invalidatedTables);
|
||||
_detailsPageDataCache.Remove(relation);
|
||||
await _supportCase.LoadSupportCaseDataAsync(relation, invalidatedTables.Where(t => !t.Name.StartsWith("Computation_")).Select(t => t.Name));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<enumActualizeStatus> ActualizeDataAsync(int? agentUserId, int? agentDeviceId)
|
||||
{
|
||||
var status = enumActualizeStatus.unknown;
|
||||
|
||||
if (!agentUserId.HasValue && !agentDeviceId.HasValue)
|
||||
return status;
|
||||
|
||||
try
|
||||
{
|
||||
TimeSpan refreshDelay = TimeSpan.FromMilliseconds(500);
|
||||
const int maxPollCount = 20;
|
||||
|
||||
if (!agentDeviceId.HasValue)
|
||||
{
|
||||
LogEntry("Coudldn't acutalize data. There was no valid AgentDeviceId found.", LogLevels.Error);
|
||||
return status;
|
||||
}
|
||||
|
||||
var taskId = await cFasdCockpitCommunicationBase.Instance.ActualizeAgentData(agentDeviceId.Value, agentUserId);
|
||||
|
||||
if (taskId == Guid.Empty)
|
||||
return enumActualizeStatus.failed;
|
||||
|
||||
enumFasdInformationClass informationClass = agentUserId != null ? enumFasdInformationClass.User : enumFasdInformationClass.Computer;
|
||||
int pollCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = await cFasdCockpitCommunicationBase.Instance.GetActualizeAgentDataStatus(taskId, informationClass);
|
||||
|
||||
if (status == enumActualizeStatus.unknown)
|
||||
{
|
||||
pollCount++;
|
||||
if (pollCount >= maxPollCount)
|
||||
return status;
|
||||
|
||||
await Task.Delay(refreshDelay);
|
||||
}
|
||||
} while (status == enumActualizeStatus.unknown);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> GetCaseRelations()
|
||||
=> _supportCase.GetCaseRelations();
|
||||
|
||||
public cHealthCard GetHealthcardFor(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
var availableHealthCards = cF4SDCockpitXmlConfig.Instance?.HealthCardConfig?.HealthCards?.Values;
|
||||
|
||||
if (availableHealthCards is null || availableHealthCards.Count == 0)
|
||||
return null;
|
||||
|
||||
return availableHealthCards
|
||||
.FirstOrDefault(hc =>
|
||||
hc.InformationClasses.All(i => i == cF4sdIdentityEntry.GetFromSearchResult(relation.Type))
|
||||
&& HasCockpitUserRequiredRoles(hc.RequiredRoles));
|
||||
}
|
||||
|
||||
private static bool HasCockpitUserRequiredRoles(List<string> requiredRoles)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (requiredRoles is null || requiredRoles.Count == 0)
|
||||
return true;
|
||||
|
||||
List<string> roles = null;
|
||||
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
|
||||
{
|
||||
roles = cFasdCockpitCommunicationBase.CockpitUserInfo?.Roles;
|
||||
}
|
||||
if (roles is null || roles.Count == 0)
|
||||
return false;
|
||||
|
||||
foreach (var requiredRole in requiredRoles)
|
||||
{
|
||||
if (roles.Contains(requiredRole, StringComparer.InvariantCultureIgnoreCase))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public cDetailsPageDataHistoryDataModel GetHistoryData(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
cDetailsPageDataHistoryDataModel historyData = null;
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
historyData = detailsData?.DataHistoryList;
|
||||
|
||||
return historyData ?? new cDetailsPageDataHistoryDataModel();
|
||||
}
|
||||
|
||||
public List<cContainerCollectionData> GetContainerData(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
List<cContainerCollectionData> containerData = null;
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
containerData = detailsData?.DataContainerCollectionList;
|
||||
|
||||
return containerData ?? new List<cContainerCollectionData>();
|
||||
}
|
||||
|
||||
public CockpitValueDisplayData GetCockpitValueDisplayData(cHealthCardStateBase displayValueDefinition, cF4sdApiSearchResultRelation relation, bool getStatic)
|
||||
{
|
||||
IList<object> rawValues = GetRawValues(displayValueDefinition, relation, getStatic);
|
||||
|
||||
cHealthCardStateBase definitionForLevel = GetDefinitionForLevel(displayValueDefinition);
|
||||
IList<enumHealthCardStateLevel> predefinedLevel = GetPredefinedLevels(displayValueDefinition, relation, getStatic);
|
||||
|
||||
cF4SDHealthCardRawData.cHealthCardDetailsTable valueDetailsTable = null;
|
||||
|
||||
if (displayValueDefinition?.Details is cHealthCardDetailsValued detailsValued)
|
||||
valueDetailsTable = SupportCaseDetailsValueProcessesor.GetDetailsTable(rawValues?.FirstOrDefault(), detailsValued);
|
||||
|
||||
return new CockpitValueDisplayData()
|
||||
{
|
||||
IsLoading = false,
|
||||
Title = displayValueDefinition?.Names.GetValue(),
|
||||
Values = rawValues?.Select(raw => GetDisplayValue(raw, displayValueDefinition, valueDetailsTable)).ToList(),
|
||||
Levels = predefinedLevel ?? rawValues?.Select(raw => GetLevel(raw, definitionForLevel, 0)).ToList(),
|
||||
UiActions = GetValueUiActions(displayValueDefinition, valueDetailsTable)
|
||||
};
|
||||
}
|
||||
|
||||
private IList<object> GetRawValues(cHealthCardStateBase stateDefinition, cF4sdApiSearchResultRelation relation, bool getStatic)
|
||||
{
|
||||
const string computationPrefix = "Computation_";
|
||||
if (stateDefinition?.DatabaseInfo?.ValueTable?.StartsWith(computationPrefix) ?? false)
|
||||
if (_computationCache.TryGetValue(relation, out var cachedComputationValues))
|
||||
if (cachedComputationValues.TryGetValue(stateDefinition.DatabaseInfo.ValueTable.Substring(computationPrefix.Length) + (getStatic ? "_latest" : string.Empty), out var computedValues))
|
||||
return computedValues;
|
||||
|
||||
return _supportCase.GetSupportCaseHealthcardData(relation, stateDefinition.DatabaseInfo, getStatic);
|
||||
}
|
||||
|
||||
private IList<cUiActionBase> GetValueUiActions(cHealthCardStateBase stateDefinition, cF4SDHealthCardRawData.cHealthCardDetailsTable detailedValueTable)
|
||||
{
|
||||
if (stateDefinition.Details is null)
|
||||
return null;
|
||||
|
||||
List<cUiActionBase> uiActions = new List<cUiActionBase>(cF4SDCockpitXmlConfig.Instance.HealthCardConfig.SearchResultAge);
|
||||
|
||||
for (int i = 0; i < cF4SDCockpitXmlConfig.Instance.HealthCardConfig.SearchResultAge; i++)
|
||||
{
|
||||
uiActions.Add(new cShowDetailedDataAction(stateDefinition, i, detailedValueTable) { DisplayType = enumActionDisplayType.enabled });
|
||||
}
|
||||
|
||||
return uiActions;
|
||||
|
||||
}
|
||||
|
||||
private IList<enumHealthCardStateLevel> GetHighestLevels(List<IList<enumHealthCardStateLevel>> allLevels, bool isNotTransparent)
|
||||
{
|
||||
var highestLevels = new List<enumHealthCardStateLevel>();
|
||||
int maxLevelCount = allLevels?.Where(l => l != null).Select(l => l.Count).DefaultIfEmpty(0).Max() ?? 0;
|
||||
|
||||
for (int i = 0; i < maxLevelCount; i++)
|
||||
{
|
||||
enumHealthCardStateLevel highestLevel = enumHealthCardStateLevel.None;
|
||||
|
||||
foreach (var levels in allLevels)
|
||||
{
|
||||
if (levels == null || levels.Count <= i)
|
||||
continue;
|
||||
|
||||
highestLevel = (enumHealthCardStateLevel)Math.Max((int)highestLevel, (int)levels[i]);
|
||||
if (highestLevel == enumHealthCardStateLevel.Error)
|
||||
break;
|
||||
}
|
||||
|
||||
if (highestLevel <= enumHealthCardStateLevel.Ok)
|
||||
highestLevel = isNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
|
||||
highestLevels.Add(highestLevel);
|
||||
}
|
||||
|
||||
return highestLevels;
|
||||
}
|
||||
|
||||
private string GetDisplayValue(object rawValue, cHealthCardStateBase displayValueDefinition, cF4SDHealthCardRawData.cHealthCardDetailsTable detailedValueTable)
|
||||
{
|
||||
if (displayValueDefinition?.Details != null && detailedValueTable != null)
|
||||
return SupportCaseDetailsValueProcessesor.GetDetailStringValue(displayValueDefinition.Details, detailedValueTable);
|
||||
else if (displayValueDefinition is cHealthCardStateTranslation translationDefinition)
|
||||
return GetTranslationValue(rawValue, translationDefinition);
|
||||
else if (displayValueDefinition is cHealthCardStateAggregation)
|
||||
return "Ø";
|
||||
else
|
||||
return cUtility.RawValueFormatter.GetDisplayValue(rawValue, displayValueDefinition.DisplayType);
|
||||
}
|
||||
|
||||
private string GetTranslationValue(object rawValue, cHealthCardStateTranslation translationDefinition)
|
||||
{
|
||||
ITranslatorObject abstractTranslation = cF4SDHealthCardConfig.GetTranslationsWithName(translationDefinition, translationDefinition.Translation);
|
||||
if (!(abstractTranslation is cHealthCardTranslator translation))
|
||||
return null;
|
||||
|
||||
if (rawValue is null)
|
||||
return translation.DefaultTranslation?.Translation?.GetValue();
|
||||
|
||||
string defaultValue = translation.DefaultTranslation?.Translation?.GetValue() ?? rawValue.ToString();
|
||||
|
||||
foreach (var translationEntry in translation.Translations)
|
||||
{
|
||||
if (translationEntry.Values.Any(v => string.Equals(rawValue.ToString(), v, StringComparison.InvariantCultureIgnoreCase)))
|
||||
return translationEntry.Translation.GetValue();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static enumHealthCardStateLevel GetLevel(object rawValue, cHealthCardStateBase stateDefinition, int referenceDays)
|
||||
{
|
||||
if (stateDefinition is null || rawValue is null)
|
||||
return enumHealthCardStateLevel.None;
|
||||
|
||||
if (stateDefinition is cHealthCardStateAggregation)
|
||||
throw new NotImplementedException();
|
||||
|
||||
try
|
||||
{
|
||||
if (stateDefinition is cHealthCardStateLevel levelDefinition)
|
||||
{
|
||||
var valueDouble = cF4SDHealthCardRawData.GetDouble(rawValue);
|
||||
if (valueDouble != null)
|
||||
{
|
||||
if (levelDefinition.IsDirectionUp)
|
||||
return valueDouble >= levelDefinition.Error ? enumHealthCardStateLevel.Error : valueDouble >= levelDefinition.Warning ? enumHealthCardStateLevel.Warning : stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
else
|
||||
return valueDouble <= levelDefinition.Error ? enumHealthCardStateLevel.Error : valueDouble <= levelDefinition.Warning ? enumHealthCardStateLevel.Warning : stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
}
|
||||
}
|
||||
else if (stateDefinition is cHealthCardStateVersion stateVersion)
|
||||
{
|
||||
Version valueVersion = cF4SDHealthCardRawData.GetVersion(rawValue);
|
||||
|
||||
if (valueVersion is null)
|
||||
return enumHealthCardStateLevel.None;
|
||||
|
||||
if (stateVersion.IsDirectionUp)
|
||||
return valueVersion >= stateVersion.Error ? enumHealthCardStateLevel.Error : valueVersion >= stateVersion.Warning ? enumHealthCardStateLevel.Warning : stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
else
|
||||
return valueVersion <= stateVersion.Error ? enumHealthCardStateLevel.Error : valueVersion <= stateVersion.Warning ? enumHealthCardStateLevel.Warning : stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
|
||||
}
|
||||
else if (stateDefinition is cHealthCardStateDateTime stateDateTime)
|
||||
{
|
||||
DateTime? valueDateTime = cF4SDHealthCardRawData.GetDateTime(rawValue);
|
||||
if (valueDateTime is null)
|
||||
return enumHealthCardStateLevel.None;
|
||||
|
||||
DateTime tempDateTime = valueDateTime.Value;
|
||||
double differenceHours = Math.Floor((DateTime.UtcNow.AddDays(-referenceDays) - tempDateTime).TotalHours);
|
||||
|
||||
if (stateDateTime.IsDirectionUp)
|
||||
return differenceHours >= stateDateTime.ErrorHours ? enumHealthCardStateLevel.Error : differenceHours >= stateDateTime.WarningHours ? enumHealthCardStateLevel.Warning : stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
else
|
||||
return differenceHours <= stateDateTime.ErrorHours ? enumHealthCardStateLevel.Error : differenceHours <= stateDateTime.WarningHours ? enumHealthCardStateLevel.Warning : stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Ok : enumHealthCardStateLevel.None;
|
||||
|
||||
}
|
||||
else if (stateDefinition is cHealthCardStateInfo)
|
||||
{
|
||||
return stateDefinition.IsNotTransparent ? enumHealthCardStateLevel.Info : enumHealthCardStateLevel.None;
|
||||
}
|
||||
else if (stateDefinition is cHealthCardStateTranslation stateTranslation)
|
||||
{
|
||||
ITranslatorObject abstractTranslation = cF4SDHealthCardConfig.GetTranslationsWithName(stateTranslation, stateTranslation.Translation);
|
||||
if (!(abstractTranslation is cHealthCardTranslator translation))
|
||||
return enumHealthCardStateLevel.None;
|
||||
|
||||
enumHealthCardStateLevel translationStateLevel = translation.DefaultTranslation?.StateLevel ?? enumHealthCardStateLevel.Info;
|
||||
foreach (var translationEntry in translation.Translations)
|
||||
{
|
||||
if (translationEntry.Values.Any(v => string.Equals(rawValue.ToString(), v, StringComparison.InvariantCultureIgnoreCase)))
|
||||
translationStateLevel = translationEntry.StateLevel;
|
||||
}
|
||||
|
||||
if (!stateTranslation.IsNotTransparent && (translationStateLevel == enumHealthCardStateLevel.Ok || translationStateLevel == enumHealthCardStateLevel.Info))
|
||||
return enumHealthCardStateLevel.None;
|
||||
else
|
||||
return translationStateLevel;
|
||||
}
|
||||
else if (stateDefinition is cHealthCardStateRefLink)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
return enumHealthCardStateLevel.None;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
return enumHealthCardStateLevel.None;
|
||||
}
|
||||
}
|
||||
|
||||
public cUiActionBase GetUiAction(cHealthCardStateBase stateDefinition)
|
||||
{
|
||||
if (stateDefinition?.QuickActions is null || stateDefinition.QuickActions.Count == 0)
|
||||
return null;
|
||||
|
||||
return stateDefinition.QuickActions.Count == 1
|
||||
? GetSingleUiAction(stateDefinition)
|
||||
: GetMultipleUiActions(stateDefinition);
|
||||
}
|
||||
|
||||
private cHealthCardStateBase GetDefinitionForLevel(cHealthCardStateBase displayValueDefinition)
|
||||
{
|
||||
if (displayValueDefinition is cHealthCardStateRefLink stateRefLink)
|
||||
return cF4SDHealthCardConfig.GetReferencableStateWithName(stateRefLink, stateRefLink.Reference);
|
||||
|
||||
return displayValueDefinition;
|
||||
}
|
||||
|
||||
private IList<enumHealthCardStateLevel> GetPredefinedLevels(cHealthCardStateBase displayValueDefinition, cF4sdApiSearchResultRelation relation, bool getStatic)
|
||||
{
|
||||
if (displayValueDefinition is cHealthCardStateRefLink stateRefLink)
|
||||
{
|
||||
cHealthCardStateBase definition = cF4SDHealthCardConfig.GetReferencableStateWithName(stateRefLink, stateRefLink.Reference);
|
||||
CockpitValueDisplayData displayData = GetCockpitValueDisplayData(definition, relation, getStatic);
|
||||
return GetHighestLevels(new List<IList<enumHealthCardStateLevel>> { displayData.Levels }, stateRefLink.IsNotTransparent);
|
||||
}
|
||||
|
||||
if (displayValueDefinition is cHealthCardStateAggregation stateAggregation)
|
||||
{
|
||||
List<IList<enumHealthCardStateLevel>> allLevels = stateAggregation.States.Select(s => GetCockpitValueDisplayData(s, relation, getStatic).Levels).ToList();
|
||||
return GetHighestLevels(allLevels, stateAggregation.IsNotTransparent);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private cUiActionBase GetSingleUiAction(cHealthCardStateBase stateDefinition)
|
||||
{
|
||||
string quickActionName = stateDefinition.QuickActions?.FirstOrDefault();
|
||||
if (string.IsNullOrWhiteSpace(quickActionName))
|
||||
return null;
|
||||
|
||||
cUiActionBase uiAction = MenuDataFactory.GetByName(quickActionName, SupportCaseDataProviderArtifact.NamedParameterEntries, SupportCaseDataProviderArtifact.CaseRelations.Select(r => r.Key))?.UiAction;
|
||||
|
||||
if (uiAction is cUiQuickAction uiQuickAction)
|
||||
uiQuickAction.QuickActionRecommendation = new cRecommendationDataModel { Category = quickActionName, Recommendation = stateDefinition.Descriptions.GetValue() };
|
||||
|
||||
return uiAction;
|
||||
}
|
||||
|
||||
private cUiActionBase GetMultipleUiActions(cHealthCardStateBase stateDefinition)
|
||||
{
|
||||
List<cMenuDataBase> menuDatas = stateDefinition.QuickActions
|
||||
.Select(quickActionName => MenuDataFactory.GetByName(quickActionName, SupportCaseDataProviderArtifact.NamedParameterEntries, SupportCaseDataProviderArtifact.CaseRelations.Select(r => r.Key)))
|
||||
.Where(menuData => menuData?.UiAction != null)
|
||||
.Select(menuData =>
|
||||
{
|
||||
if (menuData.UiAction is cUiQuickAction uiQuickAction)
|
||||
uiQuickAction.QuickActionRecommendation = new cRecommendationDataModel
|
||||
{
|
||||
Category = stateDefinition.Names.GetValue(),
|
||||
Recommendation = stateDefinition.Descriptions.GetValue()
|
||||
};
|
||||
return menuData;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (menuDatas == null || menuDatas.Count == 0)
|
||||
return null;
|
||||
|
||||
if (menuDatas.Count == 1)
|
||||
return menuDatas[0].UiAction;
|
||||
|
||||
return new cSubMenuAction(false)
|
||||
{
|
||||
SubMenuData = menuDatas,
|
||||
Name = stateDefinition.Names.GetValue(),
|
||||
Description = stateDefinition.Descriptions.GetValue(),
|
||||
DisplayType = enumActionDisplayType.enabled
|
||||
};
|
||||
}
|
||||
|
||||
public bool TryGetNamedParameterValue<T>(cF4sdApiSearchResultRelation relation, string parameterName, out T value)
|
||||
{
|
||||
value = default;
|
||||
|
||||
if (!_namedParameterCache.TryGetValue(relation, out var namedParameters))
|
||||
return false;
|
||||
|
||||
if (!namedParameters.TryGetValue(parameterName, out var namedParameter))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = (T)Convert.ChangeType(namedParameter, typeof(T));
|
||||
}
|
||||
catch
|
||||
{
|
||||
LogEntry($"Found named parameter, but can not be converted to type: {typeof(T)}. Value: {namedParameter} Actual type: {namedParameter.GetType()}", LogLevels.Info);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when newly available relations for a support case were added.
|
||||
/// </summary>
|
||||
public event EventHandler<RelationEventArgs> AvailableCaseRelationsAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the data set of a support case has changed.
|
||||
/// </summary>
|
||||
public event EventHandler<SupportCaseDataEventArgs> CaseDataChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase.Processors
|
||||
{
|
||||
internal class SupportCaseProcessorFactory
|
||||
{
|
||||
private readonly static Dictionary<Guid, SupportCaseProcessor> _supportCaseProccesors = new Dictionary<Guid, SupportCaseProcessor>();
|
||||
private readonly static Dictionary<Guid, ISupportCaseProcessor> _supportCaseProccesors = new Dictionary<Guid, ISupportCaseProcessor>();
|
||||
|
||||
internal static SupportCaseProcessor Get(Guid id)
|
||||
internal static ISupportCaseProcessor Get(Guid id)
|
||||
{
|
||||
if (!_supportCaseProccesors.ContainsKey(id))
|
||||
_supportCaseProccesors.Add(id, new SupportCaseProcessor());
|
||||
@@ -34,13 +34,19 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
~SupportCase()
|
||||
{
|
||||
if (_relationService != null)
|
||||
{
|
||||
_relationService.RelationsReset -= HandleRelationsReset;
|
||||
_relationService.RelationsFound -= HandleRelationsFound;
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (_relationService != null)
|
||||
_relationService.RelationsFound += HandleRelationsFound;
|
||||
if (_relationService is null)
|
||||
return;
|
||||
|
||||
_relationService.RelationsReset += HandleRelationsReset;
|
||||
_relationService.RelationsFound += HandleRelationsFound;
|
||||
}
|
||||
|
||||
public ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> GetCaseRelations()
|
||||
@@ -69,13 +75,13 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
|
||||
foreach (var relationType in relations)
|
||||
{
|
||||
if (_caseRelations.TryGetValue(relationType.Key, out var caseRelation))
|
||||
caseRelation = caseRelation.Union(relationType).ToList();
|
||||
if (_caseRelations.ContainsKey(relationType.Key))
|
||||
_caseRelations[relationType.Key] = _caseRelations[relationType.Key].Union(relationType).ToList();
|
||||
else
|
||||
_caseRelations.Add(relationType.Key, relationType.ToList());
|
||||
|
||||
if (SupportCaseDataProviderArtifact?.CaseRelations?.TryGetValue(relationType.Key, out var caseRelations) ?? false)
|
||||
caseRelations = caseRelations.Union(relationType).ToList();
|
||||
if (SupportCaseDataProviderArtifact?.CaseRelations?.ContainsKey(relationType.Key) ?? false)
|
||||
SupportCaseDataProviderArtifact.CaseRelations[relationType.Key] = SupportCaseDataProviderArtifact.CaseRelations[relationType.Key].Union(relationType).ToList();
|
||||
else
|
||||
SupportCaseDataProviderArtifact?.CaseRelations?.Add(relationType.Key, relationType.ToList());
|
||||
}
|
||||
@@ -134,7 +140,6 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
UpdateSupportCaseDataCache(relation, rawData?.Tables?.Values);
|
||||
|
||||
isDataComplete = rawData?.Tables?
|
||||
.Where(table => table.Key.StartsWith("Computation_") == false)
|
||||
.All(table => !table.Value.IsIncomplete && !table.Value.Columns.Values.Any(c => c.IsIncomplete)) ?? false;
|
||||
}
|
||||
|
||||
@@ -279,15 +284,25 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetSupportCaseHealthcardData(cF4sdApiSearchResultRelation relation, cValueAddress valueAddress)
|
||||
public IList<object> GetSupportCaseHealthcardData(cF4sdApiSearchResultRelation relation, cValueAddress valueAddress, bool getStatic)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_supportCaseDataCache.TryGetValue(valueAddress.ValueTable, out var tables))
|
||||
if (!TryGetTable(relation, valueAddress, out var table))
|
||||
return null;
|
||||
|
||||
if (!tables.TryGetValue(relation, out var table))
|
||||
return null;
|
||||
if (getStatic && !string.IsNullOrEmpty(table.AlternateStaticTable))
|
||||
{
|
||||
cValueAddress staticValueAdress = new cValueAddress()
|
||||
{
|
||||
DayIndex = valueAddress.DayIndex,
|
||||
ValueTable = table.AlternateStaticTable,
|
||||
ValueColumn = valueAddress.ValueColumn
|
||||
};
|
||||
|
||||
if (TryGetTable(relation, staticValueAdress, out var staticTable))
|
||||
table = staticTable;
|
||||
}
|
||||
|
||||
if (!table.Columns.TryGetValue(valueAddress.ValueColumn, out var column))
|
||||
return null;
|
||||
@@ -302,6 +317,28 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool TryGetTable(cF4sdApiSearchResultRelation relation, cValueAddress valueAddress, out cF4SDHealthCardRawData.cHealthCardTable table)
|
||||
{
|
||||
table = null;
|
||||
|
||||
if (valueAddress is null)
|
||||
return false;
|
||||
|
||||
if (!_supportCaseDataCache.TryGetValue(valueAddress.ValueTable, out var tables))
|
||||
return false;
|
||||
|
||||
if (!tables.TryGetValue(relation, out table))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void HandleRelationsReset(object sender, EventArgs e)
|
||||
{
|
||||
_caseRelations.Clear();
|
||||
AddCaseRelations(_relationService?.GetLoadedRelations());
|
||||
}
|
||||
|
||||
private void HandleRelationsFound(object sender, StagedSearchResultRelationsEventArgs e)
|
||||
{
|
||||
AddCaseRelations(e.StagedResultRelations.Relations);
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using C4IT.Logging;
|
||||
using FasdDesktopUi.Basics.CustomEvents;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Pages.DetailsPage.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.SupportCase
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for processing raw data of a <see cref="ISupportCase"/> for the UI in a certain way.
|
||||
/// </summary>
|
||||
internal class SupportCaseProcessor
|
||||
{
|
||||
private ISupportCase _supportCase;
|
||||
public cSupportCaseDataProvider SupportCaseDataProviderArtifact { get => _supportCase?.SupportCaseDataProviderArtifact; }
|
||||
|
||||
private readonly Dictionary<cF4sdApiSearchResultRelation, cDetailsPageData> _detailsPageDataCache = new Dictionary<cF4sdApiSearchResultRelation, cDetailsPageData>();
|
||||
|
||||
private readonly Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, object>> _namedParameterCache = new Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, object>>();
|
||||
|
||||
internal void SetSupportCase(ISupportCase supportCase)
|
||||
{
|
||||
if (_supportCase != null)
|
||||
{
|
||||
_supportCase.CaseRelationsAdded -= HandleSupportCaseRelationsAdded;
|
||||
_supportCase.SupportCaseDataCacheHasChanged -= HandleSupportCaseDataCacheHasChanged;
|
||||
}
|
||||
|
||||
_supportCase = supportCase;
|
||||
|
||||
_supportCase.CaseRelationsAdded += HandleSupportCaseRelationsAdded;
|
||||
_supportCase.SupportCaseDataCacheHasChanged += HandleSupportCaseDataCacheHasChanged;
|
||||
}
|
||||
|
||||
private void HandleSupportCaseRelationsAdded(object sender, RelationEventArgs e)
|
||||
=> AvailableCaseRelationsAdded?.Invoke(this, e);
|
||||
|
||||
private async void HandleSupportCaseDataCacheHasChanged(object sender, SupportCaseDataEventArgs e)
|
||||
{
|
||||
bool isArtifactShowingCorrectHealthCard
|
||||
= SupportCaseDataProviderArtifact.HealthCardDataHelper.SelectedHealthCard == GetHealthcardFor(e.Relation);
|
||||
|
||||
if (!isArtifactShowingCorrectHealthCard)
|
||||
{
|
||||
// todo this can probably be removed, as soon as the last dependency of the SupportCaseDataProviderArtifact is gone.
|
||||
// till then the detailspageData gets overriden with the detailspageData of the new relation.
|
||||
// However, the removal shouldn't be much of a problem, due to the fact the Artifact also stores the raw data
|
||||
_detailsPageDataCache.Remove(e.Relation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(e.Relation, out var cachedData))
|
||||
{
|
||||
cDetailsPageData detailData = _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataWithoutHeading();
|
||||
cachedData.WidgetData = detailData.WidgetData;
|
||||
cachedData.DataHistoryList = detailData.DataHistoryList;
|
||||
cachedData.MenuBarData = detailData.MenuBarData;
|
||||
cachedData.DataContainerCollectionList = detailData.DataContainerCollectionList;
|
||||
}
|
||||
else
|
||||
{
|
||||
_detailsPageDataCache[e.Relation] = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync();
|
||||
}
|
||||
|
||||
UpdateNamedParameters(e.Relation, e.DataTables);
|
||||
CaseDataChanged?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void UpdateNamedParameters(cF4sdApiSearchResultRelation relation, IEnumerable<cF4SDHealthCardRawData.cHealthCardTable> dataTables)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_namedParameterCache.ContainsKey(relation))
|
||||
_namedParameterCache.Add(relation, new Dictionary<string, object>());
|
||||
|
||||
var healthcard = GetHealthcardFor(relation);
|
||||
|
||||
foreach (var namedParameter in cHealthCardPrerequisites.GetNamedParameters(healthcard).Values)
|
||||
{
|
||||
var table = dataTables.FirstOrDefault(t => t.Name == namedParameter.DatabaseInfo.ValueTable);
|
||||
|
||||
if (table is null)
|
||||
continue;
|
||||
|
||||
if (!table.Columns.TryGetValue(namedParameter.DatabaseInfo.ValueColumn, out var column))
|
||||
continue;
|
||||
|
||||
string value = cUtility.RawValueFormatter.GetDisplayValue(column.Values.FirstOrDefault(), namedParameter.Display);
|
||||
_namedParameterCache[relation][namedParameter.ParameterName] = value;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadSupportCaseDataAsync(cF4sdApiSearchResultRelation relation, IEnumerable<string> tablesToLoad)
|
||||
{
|
||||
_ = Task.Run(async () => await _supportCase.LoadSupportCaseDataAsync(relation, tablesToLoad.Where(t => !t.Contains("-details-"))));
|
||||
|
||||
if (!_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
{
|
||||
detailsData = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync();
|
||||
_detailsPageDataCache.Add(relation, detailsData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.UpdateNamedParameterEntries();
|
||||
}
|
||||
|
||||
CaseDataChanged?.Invoke(this, new SupportCaseDataEventArgs());
|
||||
}
|
||||
|
||||
public async Task UpdateLatestCaseDataFor(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
try
|
||||
{
|
||||
int? agentUserId = relation.Identities.FirstOrDefault(i => i.Class == enumFasdInformationClass.User)?.agentId;
|
||||
int? agentDeviceId = relation.Identities.FirstOrDefault(i => i.Class == enumFasdInformationClass.Computer)?.agentId;
|
||||
|
||||
await ActualizeDataAsync(agentUserId, agentDeviceId);
|
||||
_supportCase.InvalidateLatestCaseDataCacheFor(relation, out var invalidatedTables);
|
||||
_detailsPageDataCache.Remove(relation);
|
||||
await _supportCase.LoadSupportCaseDataAsync(relation, invalidatedTables.Where(t => !t.Name.StartsWith("Computation_")).Select(t => t.Name));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<enumActualizeStatus> ActualizeDataAsync(int? agentUserId, int? agentDeviceId)
|
||||
{
|
||||
var status = enumActualizeStatus.unknown;
|
||||
|
||||
if (!agentUserId.HasValue && !agentDeviceId.HasValue)
|
||||
return status;
|
||||
|
||||
try
|
||||
{
|
||||
TimeSpan refreshDelay = TimeSpan.FromMilliseconds(500);
|
||||
const int maxPollCount = 20;
|
||||
|
||||
if (!agentDeviceId.HasValue)
|
||||
{
|
||||
LogEntry("Coudldn't acutalize data. There was no valid AgentDeviceId found.", LogLevels.Error);
|
||||
return status;
|
||||
}
|
||||
|
||||
var taskId = await cFasdCockpitCommunicationBase.Instance.ActualizeAgentData(agentDeviceId.Value, agentUserId);
|
||||
|
||||
if (taskId == Guid.Empty)
|
||||
return enumActualizeStatus.failed;
|
||||
|
||||
enumFasdInformationClass informationClass = agentUserId != null ? enumFasdInformationClass.User : enumFasdInformationClass.Computer;
|
||||
int pollCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = await cFasdCockpitCommunicationBase.Instance.GetActualizeAgentDataStatus(taskId, informationClass);
|
||||
|
||||
if (status == enumActualizeStatus.unknown)
|
||||
{
|
||||
pollCount++;
|
||||
if (pollCount >= maxPollCount)
|
||||
return status;
|
||||
|
||||
await Task.Delay(refreshDelay);
|
||||
}
|
||||
} while (status == enumActualizeStatus.unknown);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
internal ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> GetCaseRelations()
|
||||
=> _supportCase.GetCaseRelations();
|
||||
|
||||
internal cHealthCard GetHealthcardFor(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
var availableHealthCards = cF4SDCockpitXmlConfig.Instance?.HealthCardConfig?.HealthCards?.Values;
|
||||
|
||||
if (availableHealthCards is null || availableHealthCards.Count == 0)
|
||||
return null;
|
||||
|
||||
return availableHealthCards
|
||||
.FirstOrDefault(hc =>
|
||||
hc.InformationClasses.All(i => i == cF4sdIdentityEntry.GetFromSearchResult(relation.Type))
|
||||
&& HasCockpitUserRequiredRoles(hc.RequiredRoles));
|
||||
}
|
||||
|
||||
private static bool HasCockpitUserRequiredRoles(List<string> requiredRoles)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (requiredRoles is null || requiredRoles.Count == 0)
|
||||
return true;
|
||||
|
||||
List<string> roles = null;
|
||||
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
|
||||
{
|
||||
roles = cFasdCockpitCommunicationBase.CockpitUserInfo?.Roles;
|
||||
}
|
||||
if (roles is null || roles.Count == 0)
|
||||
return false;
|
||||
|
||||
foreach (var requiredRole in requiredRoles)
|
||||
{
|
||||
if (roles.Contains(requiredRole, StringComparer.InvariantCultureIgnoreCase))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<List<cWidgetValueModel>> GetWidgetData(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
List<List<cWidgetValueModel>> widgetData = null;
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
widgetData = detailsData?.WidgetData;
|
||||
|
||||
return widgetData ?? new List<List<cWidgetValueModel>>();
|
||||
}
|
||||
|
||||
public cDetailsPageDataHistoryDataModel GetHistoryData(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
cDetailsPageDataHistoryDataModel historyData = null;
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
historyData = detailsData?.DataHistoryList;
|
||||
|
||||
return historyData ?? new cDetailsPageDataHistoryDataModel();
|
||||
}
|
||||
|
||||
public List<cContainerCollectionData> GetContainerData(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
List<cContainerCollectionData> containerData = null;
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
containerData = detailsData?.DataContainerCollectionList;
|
||||
|
||||
return containerData ?? new List<cContainerCollectionData>();
|
||||
}
|
||||
|
||||
public List<cMenuDataBase> GetMenuBarData(cF4sdApiSearchResultRelation relation)
|
||||
{
|
||||
List<cMenuDataBase> menuData = null;
|
||||
|
||||
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
|
||||
menuData = detailsData?.MenuBarData;
|
||||
|
||||
return menuData ?? new List<cMenuDataBase>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when newly available relations for a support case were added.
|
||||
/// </summary>
|
||||
public event EventHandler<RelationEventArgs> AvailableCaseRelationsAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the data set of a support case has changed.
|
||||
/// </summary>
|
||||
public event EventHandler<SupportCaseDataEventArgs> CaseDataChanged;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,9 @@ using FasdDesktopUi.Basics.Services.SupportCase;
|
||||
using FasdDesktopUi.Basics.Services.RelationService;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase.Controllers;
|
||||
using C4IT.F4SD.SupportCaseProtocoll.Models;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase.Processors;
|
||||
using F4SD.Gamification;
|
||||
using F4SD.Gamification.Services;
|
||||
|
||||
|
||||
namespace FasdDesktopUi.Basics
|
||||
@@ -178,7 +181,7 @@ namespace FasdDesktopUi.Basics
|
||||
return null;
|
||||
|
||||
HashSet<string> requiredTables = cHealthCard.GetRequiredTables(_result.HealthCardDataHelper.SelectedHealthCard); // todo the healthcard is not selected at this point
|
||||
detailsPage.WidgetCollection.WidgetDataList = supportCaseController.GetWidgetData();
|
||||
detailsPage.WidgetCollection.WidgetDataList = supportCaseController.GetWidgetsData();
|
||||
detailsPage.DataHistoryCollectionUserControl.HistoryDataList = supportCaseController.GetHistoryData();
|
||||
detailsPage.CustomizableSectionUc.ContainerCollections = supportCaseController.GetContainerData();
|
||||
|
||||
@@ -269,6 +272,7 @@ namespace FasdDesktopUi.Basics
|
||||
|
||||
TimerView.ResetTimer();
|
||||
CaseChanged?.Invoke(this, new EventArgs());
|
||||
GamificationService.TrackAction(CockpitAction.CaseOpened);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -308,7 +312,7 @@ namespace FasdDesktopUi.Basics
|
||||
var nettoTime = workTimes["NettoWorkingTime"];
|
||||
|
||||
var caseParameter = new cF4SDCaseStatusParameters() { CaseId = tempCaseId, StatusId = CaseStatus.Finished, ActiveTime = (double)nettoTime };
|
||||
tasks.Add(cFasdCockpitCommunicationBase.Instance.UpdateCase(caseParameter, TimerView.caseTimes));
|
||||
tasks.Add(cFasdCockpitCommunicationBase.Instance.UpdateCase(caseParameter, TimerView.CaseTimes));
|
||||
caseAliveTimer?.Stop();
|
||||
caseAliveTimer?.Dispose();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
using C4IT.F4SD.DisplayFormatting;
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.MultiLanguage;
|
||||
using FasdCockpitBase.Models.RemoteDesktopConnection;
|
||||
using FasdCockpitCommunication.RemoteDesktopCommunication;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.Services.RemoteDesktop;
|
||||
using FasdDesktopUi.Basics.UserControls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UiActions.NativeActions
|
||||
{
|
||||
internal class RemoteConnectionAction
|
||||
{
|
||||
internal const string NativeActionName = "StartAgentRemoteConnection";
|
||||
|
||||
internal static void UpdatePrerequesites(FasdNativeQuickAction nativeQuickAction)
|
||||
{
|
||||
nativeQuickAction.CheckFilePath = AgentRemoteDesktopService.GetViewerPath();
|
||||
}
|
||||
|
||||
internal static cDataCanvasDataModel GetQuickActionData(cFasdQuickAction quickActionConfig, cQuickActionStatusMonitorModel.RunQuickActionDelegate quickAction)
|
||||
{
|
||||
var detailedDataQuickActionHistory = new cDetailedDataModel()
|
||||
{
|
||||
Heading = cMultiLanguageSupport.GetItem("DetailsPage.History"),
|
||||
FullDetailedData = new List<object>() { new List<object>() { "Status", cMultiLanguageSupport.GetItem("QuickAction.Revision.ExecutionTime") } }
|
||||
};
|
||||
|
||||
|
||||
return new cDataCanvasDataModel()
|
||||
{
|
||||
RecommendationData = null,
|
||||
QuickActionStatusMonitorData = new cQuickActionStatusMonitorModel()
|
||||
{
|
||||
ActionName = quickActionConfig.Names.GetValue(),
|
||||
ActionSteps = new List<cQuickActionStatusMonitorModel.cQuickActionStep>()
|
||||
{
|
||||
new cQuickActionStatusMonitorModel.cQuickActionStep(cMultiLanguageSupport.GetItem("QuickAction.Remote.UserAcceptance"), quickActionConfig.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.waitingForUserAcceptance),
|
||||
new cQuickActionStatusMonitorModel.cQuickActionStep(cMultiLanguageSupport.GetItem("QuickAction.Phoenix.StartViewer"), quickActionConfig.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running)
|
||||
},
|
||||
QuickActionDefinition = quickActionConfig,
|
||||
RunQuickAction = quickAction
|
||||
},
|
||||
DetailedData = detailedDataQuickActionHistory,
|
||||
};
|
||||
}
|
||||
|
||||
private static bool TryGetNamedParameterValue(cNamedParameterList namedParameters, string namedParameterName, string quickActionName, QuickActionStatusMonitor statusMonitor, out int namedParameterValue)
|
||||
{
|
||||
namedParameterValue = -1;
|
||||
bool hasNamedParameterValue = true;
|
||||
|
||||
if (!namedParameters.TryGetValue(namedParameterName, out var namedParameter))
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(statusMonitor.QuickActionData.ActionSteps);
|
||||
statusMonitor.QuickActionOutputs.Add(new cF4sdQuickActionRevision.cOutput() { Values = $"Named parameter \"{namedParameterName}\" is missing. Try to refresh data." });
|
||||
hasNamedParameterValue = false;
|
||||
}
|
||||
|
||||
if (!int.TryParse(namedParameter.GetValue(), out namedParameterValue))
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(statusMonitor.QuickActionData.ActionSteps);
|
||||
statusMonitor.QuickActionOutputs.Add(new cF4sdQuickActionRevision.cOutput() { Values = $"Named parameter \"{namedParameterName}\" is missing. Try to refresh data." });
|
||||
hasNamedParameterValue = false;
|
||||
}
|
||||
|
||||
return hasNamedParameterValue;
|
||||
}
|
||||
|
||||
private static bool TryGetClientInfo(string quickActionName, QuickActionStatusMonitor statusMonitor, cNamedParameterList namedParameters, out AgentRemoteClientInfo clientInfo)
|
||||
{
|
||||
clientInfo = null;
|
||||
try
|
||||
{
|
||||
bool hasClientInfo = true;
|
||||
|
||||
if (!TryGetNamedParameterValue(namedParameters, "AgentUserId", quickActionName, statusMonitor, out var userId))
|
||||
hasClientInfo = false;
|
||||
|
||||
if (!TryGetNamedParameterValue(namedParameters, "AgentDeviceId", quickActionName, statusMonitor, out var deviceId))
|
||||
hasClientInfo = false;
|
||||
|
||||
|
||||
int? organizationId = cCockpitConfiguration.Instance?.agentApiConfiguration?.OrganizationCode;
|
||||
|
||||
if (organizationId is null)
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(statusMonitor.QuickActionData.ActionSteps);
|
||||
hasClientInfo = false;
|
||||
}
|
||||
|
||||
clientInfo = new AgentRemoteClientInfo() { AccountCode = userId, DeviceCode = deviceId, OrganisationCode = organizationId.Value };
|
||||
|
||||
return hasClientInfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task<List<object>> RunQuickAction(string quickActionName, QuickActionStatusMonitor statusMonitor, cNamedParameterList namedParameters, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
statusMonitor.QuickActionOutputs.Clear();
|
||||
|
||||
var errorOutput = new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
||||
|
||||
if (!TryGetClientInfo(quickActionName, statusMonitor, namedParameters, out var clientInfo))
|
||||
return errorOutput;
|
||||
|
||||
AgentRemoteDesktopService.RemoteConnetionStatusChanged += HandleConnectionStatusChanged;
|
||||
RemoteDesktopConnectionStatusResult connectionStatus = await AgentRemoteDesktopService.StartRemoteDesktopConnectionAsync(clientInfo, true, token);
|
||||
|
||||
switch (connectionStatus.Status)
|
||||
{
|
||||
case RemoteDesktopConnectionStatus.Accepted:
|
||||
case RemoteDesktopConnectionStatus.Connected:
|
||||
case RemoteDesktopConnectionStatus.Finished:
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(statusMonitor?.QuickActionData?.ActionSteps, quickActionName, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.waitingForUserAcceptance, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedSuccessfull"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
||||
case RemoteDesktopConnectionStatus.Canceled:
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(statusMonitor?.QuickActionData?.ActionSteps);
|
||||
return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Canceled"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
||||
case RemoteDesktopConnectionStatus.Error:
|
||||
|
||||
foreach (var error in connectionStatus.Errors)
|
||||
{
|
||||
var quickactionOutput = new cF4sdQuickActionRevision.cOutput() { Values = error };
|
||||
statusMonitor.QuickActionOutputs.Add(quickactionOutput);
|
||||
}
|
||||
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(statusMonitor?.QuickActionData?.ActionSteps, quickActionName, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.waitingForUserAcceptance, enumQuickActionRevisionStatus.finishedWithError);
|
||||
return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
||||
default:
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(statusMonitor?.QuickActionData?.ActionSteps, quickActionName, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.waitingForUserAcceptance, enumQuickActionRevisionStatus.finishedWithError);
|
||||
return errorOutput;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
AgentRemoteDesktopService.RemoteConnetionStatusChanged -= HandleConnectionStatusChanged;
|
||||
}
|
||||
|
||||
void HandleConnectionStatusChanged(object sender, RemoteDesktopConnectionStatus e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case RemoteDesktopConnectionStatus.Accepted:
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(statusMonitor?.QuickActionData?.ActionSteps, quickActionName, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.waitingForUserAcceptance, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
break;
|
||||
case RemoteDesktopConnectionStatus.Connected:
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(statusMonitor?.QuickActionData?.ActionSteps, quickActionName, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
break;
|
||||
case RemoteDesktopConnectionStatus.Canceled:
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(statusMonitor?.QuickActionData?.ActionSteps);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,7 +337,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
shouldHideRow = true;
|
||||
}
|
||||
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
cUtility.RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
foreach (var index in rawColumnIndexes)
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using C4IT.Logging;
|
||||
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UserControls;
|
||||
@@ -19,7 +13,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
public class cSubMenuAction : cUiActionBase
|
||||
{
|
||||
public bool UseTempData { get; private set; }
|
||||
public List<cMenuDataBase> SubMenuData { get; set; }
|
||||
public List<cMenuDataBase> SubMenuData { get; set; } = new List<cMenuDataBase>();
|
||||
|
||||
public cSubMenuAction(bool UseTempData)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
return new cUiDemoQuickAction(QuickActionDemo);
|
||||
else if (quickAction is cF4sdQuickActionServer serverQuickAction)
|
||||
return new cUiServerQuickAction(serverQuickAction);
|
||||
else if (quickAction is FasdNativeQuickAction nativeQuickAction)
|
||||
return new UiNativeQuickAction(nativeQuickAction);
|
||||
else
|
||||
return new cUiDummyQuickAction(quickAction);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ using System.Windows;
|
||||
using FasdDesktopUi.Basics.UserControls;
|
||||
using C4IT.FASD.Base;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using F4SD.Gamification;
|
||||
using F4SD.Gamification.Services;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UiActions
|
||||
{
|
||||
@@ -36,6 +38,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
if (sender is CustomMenuItem senderElement)
|
||||
await cUtility.ChangeIconToCheckAsync(senderElement.MenuItemIcon);
|
||||
|
||||
GamificationService.TrackAction(CockpitAction.CopyTemplateClicked);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception E)
|
||||
|
||||
@@ -78,6 +78,9 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
public override async Task<List<object>> ProcessActionAsync(CancellationToken token, Dictionary<cAdjustableParameter, object> ParameterDictionary = null)
|
||||
{
|
||||
var runningId = Guid.NewGuid();
|
||||
StatusMonitor.CurrentRunningQuickActionId = runningId;
|
||||
|
||||
var _finshedStatus = enumQuickActionRevisionStatus.finishedSuccessfull;
|
||||
if (quickActionDemo.SimulatedClientConnect > 0)
|
||||
{
|
||||
@@ -86,7 +89,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
_finshedStatus = enumQuickActionRevisionStatus.canceled;
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, quickActionDemo.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.connectingToClient, _finshedStatus);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, quickActionDemo.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.connectingToClient, _finshedStatus);
|
||||
}
|
||||
|
||||
if (quickActionDemo.SimulatedRuntime > 0)
|
||||
@@ -98,14 +101,16 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
if (token.IsCancellationRequested)
|
||||
_finshedStatus = enumQuickActionRevisionStatus.canceled;
|
||||
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, quickActionDemo.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, _finshedStatus);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, quickActionDemo.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, _finshedStatus);
|
||||
}
|
||||
|
||||
string _msg;
|
||||
if (_finshedStatus == enumQuickActionRevisionStatus.canceled)
|
||||
{
|
||||
_msg = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Canceled");
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(StatusMonitor.QuickActionData.ActionSteps);
|
||||
|
||||
if (StatusMonitor.CurrentRunningQuickActionId == runningId)
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(StatusMonitor.QuickActionData.ActionSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -133,8 +133,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
{
|
||||
var ResultRevision = GetRevisionOutput(_actionResult);
|
||||
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
|
||||
if (ResultRevision.Output == null)
|
||||
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.finished });
|
||||
@@ -182,8 +182,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
}
|
||||
else
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
|
||||
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.error, ErrorDescription = cMultiLanguageSupport.GetItem("QuickAction.Copy.Output.Cancel") });
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
if (string.IsNullOrEmpty(webRequestUrl))
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
|
||||
return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
||||
}
|
||||
@@ -112,8 +112,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
if (!token.IsCancellationRequested)
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
|
||||
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.finished });
|
||||
|
||||
@@ -134,8 +134,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
}
|
||||
else
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, LocalQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
|
||||
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.error, ErrorDescription = cMultiLanguageSupport.GetItem("QuickAction.Copy.Output.Cancel") });
|
||||
|
||||
|
||||
49
FasdDesktopUi/Basics/UiActions/UiNativeQuickAction.cs
Normal file
49
FasdDesktopUi/Basics/UiActions/UiNativeQuickAction.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using C4IT.FASD.Base;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UiActions.NativeActions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UiActions
|
||||
{
|
||||
internal class UiNativeQuickAction : cUiQuickAction
|
||||
{
|
||||
private readonly string _nativeActionName;
|
||||
|
||||
public UiNativeQuickAction(FasdNativeQuickAction quickActionConfig) : base(quickActionConfig)
|
||||
{
|
||||
_nativeActionName = quickActionConfig.NativeName;
|
||||
}
|
||||
|
||||
public override Task<cDataCanvasDataModel> GetQuickActionDataAsync(cSupportCaseDataProvider dataProvider, bool isDetailedLayout)
|
||||
{
|
||||
DataProvider = dataProvider;
|
||||
|
||||
switch (_nativeActionName)
|
||||
{
|
||||
case RemoteConnectionAction.NativeActionName:
|
||||
return Task.FromResult(RemoteConnectionAction.GetQuickActionData(QuickActionConfig, ProcessActionAsync));
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<List<object>> ProcessActionAsync(CancellationToken token, Dictionary<cAdjustableParameter, object> parameterDictionary = null)
|
||||
{
|
||||
return await RunNativeAction(_nativeActionName, token);
|
||||
}
|
||||
|
||||
private async Task<List<object>> RunNativeAction(string actionName, CancellationToken token)
|
||||
{
|
||||
switch (actionName)
|
||||
{
|
||||
case RemoteConnectionAction.NativeActionName:
|
||||
return await RemoteConnectionAction.RunQuickAction(QuickActionConfig.Name, StatusMonitor, DataProvider?.NamedParameterEntries, token);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,14 +33,11 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
await HistoryEntry.RefreshAsync();
|
||||
}
|
||||
|
||||
// todo set relationService
|
||||
IRelationService relationService = new RelationService();
|
||||
|
||||
switch (HistoryEntry)
|
||||
{
|
||||
case cSearchHistorySearchResultEntry SearchEntry:
|
||||
HistoryEntry.SearchUiProvider.SetSearchHistoryVisibility(true);
|
||||
HistoryEntry.SearchUiProvider.ShowSearchRelations(SearchEntry, relationService, HistoryEntry.SearchUiProvider);
|
||||
HistoryEntry.SearchUiProvider.ShowSearchRelations(SearchEntry, HistoryEntry.RelationService, HistoryEntry.SearchUiProvider);
|
||||
return true;
|
||||
case cSearchHistoryRelationEntry RelationEntry:
|
||||
string caseObjectName = RelationEntry.SelectedRelation.DisplayName;
|
||||
@@ -58,7 +55,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
}
|
||||
}
|
||||
HistoryEntry.isSeen = true;
|
||||
dataProvider = await cSupportCaseDataProvider.GetDataProviderForAsync(RelationEntry.SelectedRelation, relationService);
|
||||
dataProvider = await cSupportCaseDataProvider.GetDataProviderForAsync(RelationEntry.SelectedRelation, HistoryEntry.RelationService);
|
||||
if (dataProvider is null)
|
||||
{
|
||||
Debug.Assert(true, "Could not start a data provider for the selected criterias.");
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.Logging;
|
||||
using C4IT.MultiLanguage;
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using C4IT.MultiLanguage;
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using FasdDesktopUi.Basics.Services.RelationService;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
@@ -61,21 +61,21 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_selectedRelation == null)
|
||||
{
|
||||
Debug.Assert(true, "A new support case can't be opend, if we have no selected relation or seach result");
|
||||
LogEntry("A new support case can't be opend, if we have no sselected relation or seach result", LogLevels.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TicketDeepLinkHelper.TryOpenTicketRelationExternally(_selectedRelation))
|
||||
return false;
|
||||
|
||||
// check, if have an active support case
|
||||
var supportCaseActive = dataProvider?.IsActive ?? false;
|
||||
if (_selectedRelation == null)
|
||||
{
|
||||
Debug.Assert(true, "A new support case can't be opend, if we have no selected relation or seach result");
|
||||
LogEntry("A new support case can't be opend, if we have no sselected relation or seach result", LogLevels.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TicketExternalLinkHelper.TryOpenTicketRelationExternally(_selectedRelation))
|
||||
return false;
|
||||
|
||||
// check, if have an active support case
|
||||
var supportCaseActive = dataProvider?.IsActive ?? false;
|
||||
|
||||
// create the search histroy entry
|
||||
var _seachHistoryEntry = new cSearchHistoryRelationEntry(Name, _selectedSearchResult, _relations, _selectedRelation, _searchUiProvider);
|
||||
var _seachHistoryEntry = new cSearchHistoryRelationEntry(Name, _selectedSearchResult, _relations, _selectedRelation, _searchUiProvider, _relationService);
|
||||
cSearchManager.Instance.ReplaceEntry(_seachHistoryEntry, _searchHistoryEntry);
|
||||
|
||||
// show the loading information
|
||||
@@ -96,9 +96,12 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
// get the new data provider for the support call informations (get it from the cache or create a new one)
|
||||
dataProvider = await cSupportCaseDataProvider.GetDataProviderForAsync(_selectedRelation, _relationService);
|
||||
|
||||
bool shouldLoadRelationsForSelectedRelation = _selectedRelation.Type == enumF4sdSearchResultClass.User;
|
||||
if (shouldLoadRelationsForSelectedRelation)
|
||||
StartLoadingRelationsFor(_selectedRelation);
|
||||
bool shouldLoadRelationsForSelectedRelation = _selectedRelation.Type == enumF4sdSearchResultClass.User;
|
||||
if (shouldLoadRelationsForSelectedRelation)
|
||||
{
|
||||
_relationService.Reset();
|
||||
StartLoadingRelationsFor(_selectedRelation);
|
||||
}
|
||||
|
||||
if (dataProvider is null)
|
||||
{
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
private async Task<bool> ProcessSearchResultRelationAsync(string name, List<cF4sdApiSearchResultRelation> caseRelations, cF4sdApiSearchResultRelation selectedRelation)
|
||||
{
|
||||
var relationSearchResult = new cSearchHistorySearchResultEntry(_searchResults.FirstOrDefault().DisplayName, _searchResults.FirstOrDefault().DisplayName, _searchResults, caseRelations, _searchUiProvider);
|
||||
var relationSearchResult = new cSearchHistorySearchResultEntry(_searchResults.FirstOrDefault().DisplayName, _searchResults.FirstOrDefault().Name, _searchResults, caseRelations, _searchUiProvider, _relationService);
|
||||
string displayName = !string.IsNullOrWhiteSpace(selectedRelation?.Name) ? $"{name} → {selectedRelation.Name}" : name;
|
||||
|
||||
cUiProcessSearchRelationAction action
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
if (QuickActionConfig is null)
|
||||
return;
|
||||
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
cUtility.RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
cUtility.RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
shouldRunImmidiate = QuickActionConfig.RunImmediate;
|
||||
|
||||
@@ -85,6 +85,9 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
{
|
||||
try
|
||||
{
|
||||
var runningId = Guid.NewGuid();
|
||||
StatusMonitor.CurrentRunningQuickActionId = runningId;
|
||||
|
||||
int agentDeviceId = int.MinValue;
|
||||
int? agentUserIdNullable = null;
|
||||
var startTime = DateTime.UtcNow;
|
||||
@@ -132,11 +135,12 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
if (!token.IsCancellationRequested)
|
||||
{
|
||||
StatusMonitor.QuickActionOutputs.Add(QuickActionResult.Output);
|
||||
if (StatusMonitor.CurrentRunningQuickActionId == runningId)
|
||||
StatusMonitor.QuickActionOutputs.Add(QuickActionResult.Output);
|
||||
var status = quickActionOutput?.IsError == true ? enumQuickActionRevisionStatus.finishedWithError : QuickActionResult.Status;
|
||||
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, RemoteQuickAction.Name, enumActionStepType.running, status);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, RemoteQuickAction.Name, enumActionStepType.main, status);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, RemoteQuickAction.Name, enumActionStepType.running, status);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, RemoteQuickAction.Name, enumActionStepType.main, status);
|
||||
|
||||
cQuickActionCopyData copyData = QuickActionProtocollEntryOutput.GetCopyData(RemoteQuickAction, DataProvider, true, protocollOutput, StatusMonitor.MeasureValues);
|
||||
QuickActionProtocollEntry protocollEntry = QuickActionProtocollEntryOutput.GetQuickActionProtocollEntry(RemoteQuickAction, copyData);
|
||||
@@ -145,7 +149,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
}
|
||||
else
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(StatusMonitor.QuickActionData.ActionSteps);
|
||||
if (StatusMonitor.CurrentRunningQuickActionId == runningId)
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(StatusMonitor.QuickActionData.ActionSteps);
|
||||
|
||||
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.error, ErrorDescription = cMultiLanguageSupport.GetItem("QuickAction.Copy.Output.Cancel") });
|
||||
|
||||
@@ -303,7 +308,7 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
|
||||
foreach (var actionStepToUpdate in actionStepsToUpdate)
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, RemoteQuickAction.Name, actionStepToUpdate, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, RemoteQuickAction.Name, actionStepToUpdate, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
}
|
||||
|
||||
if (quickActionStatus == enumQuickActionStatus.Finished || quickActionStatus == enumQuickActionStatus.Cancelled)
|
||||
|
||||
@@ -134,8 +134,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
{
|
||||
var ResultRevision = GetRevisionOutput(_actionResult);
|
||||
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.finishedSuccessfull);
|
||||
|
||||
if (!string.IsNullOrEmpty(_actionResult.StandardOutput))
|
||||
try
|
||||
@@ -198,8 +198,8 @@ namespace FasdDesktopUi.Basics.UiActions
|
||||
}
|
||||
else
|
||||
{
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main, enumQuickActionRevisionStatus.canceled);
|
||||
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor?.QuickActionData?.ActionSteps, ServerQuickAction.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.running, enumQuickActionRevisionStatus.canceled);
|
||||
|
||||
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.error, ErrorDescription = cMultiLanguageSupport.GetItem("QuickAction.Copy.Output.Cancel") });
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
MouseLeftButtonUp="MenuItemBorder_Click"
|
||||
TouchDown="MenuItemBorder_Click"
|
||||
MouseEnter="MenuItemBorder_MouseEnter"
|
||||
MouseLeave="MenuItemBorder_MouseLeave">
|
||||
MouseLeave="MenuItemBorder_MouseLeave"
|
||||
>
|
||||
|
||||
<Grid x:Name="MenuItemContent">
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -31,12 +32,14 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ico:AdaptableIcon x:Name="MenuItemIcon"
|
||||
Grid.Column="0" />
|
||||
Grid.Column="0"
|
||||
/>
|
||||
|
||||
<ico:AdaptableIcon x:Name="MenuItemOverlayIcon"
|
||||
Grid.Column="0"
|
||||
BorderPadding="10 10 0 0"
|
||||
Margin="0 0 -5 -5"/>
|
||||
Visibility="Collapsed"
|
||||
IsHitTestVisible="False"
|
||||
/>
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
Margin="15 0 15 0"
|
||||
|
||||
@@ -1,186 +1,207 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
|
||||
using C4IT.FASD.Base;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using MaterialIcons;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class CustomMenuItem : UserControl
|
||||
{
|
||||
#region Properties
|
||||
|
||||
#region MenuData
|
||||
|
||||
private cMenuDataBase _menuData = new cMenuDataBase();
|
||||
|
||||
private readonly bool _isLean;
|
||||
|
||||
public cMenuDataBase MenuData
|
||||
{
|
||||
get { return _menuData; }
|
||||
set
|
||||
{
|
||||
if (_menuData != value)
|
||||
{
|
||||
_menuData = value;
|
||||
MenuDataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuDataChanged()
|
||||
{
|
||||
if (MenuData.MenuIcon.Intern != null)
|
||||
MenuItemIcon.SelectedInternIcon = MenuData.MenuIcon.Intern;
|
||||
else if (MenuData.MenuIcon.Material != null)
|
||||
MenuItemIcon.SelectedMaterialIcon = MenuData.MenuIcon.Material;
|
||||
|
||||
MenuItemIcon.IconHeight = MenuData.MenuIconSize * MenuItemIcon.IconHeight;
|
||||
MenuItemIcon.IconWidth = MenuData.MenuIconSize * MenuItemIcon.IconWidth;
|
||||
|
||||
switch (MenuData.UiAction?.DisplayType)
|
||||
{
|
||||
case Enums.enumActionDisplayType.hidden:
|
||||
//todo: add hidden state
|
||||
break;
|
||||
case Enums.enumActionDisplayType.disabled:
|
||||
MenuItemContent.SetValue(OpacityProperty, 0.5);
|
||||
MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.NoHover");
|
||||
MenuItemBorder.SetValue(ToolTipProperty, string.IsNullOrWhiteSpace(MenuData.UiAction.AlternativeDescription) ? MenuData.UiAction.Description : MenuData.UiAction.AlternativeDescription);
|
||||
try
|
||||
{
|
||||
MenuItemBorder.MouseLeftButtonUp -= MenuItemBorder_Click;
|
||||
MenuItemBorder.TouchDown -= MenuItemBorder_Click;
|
||||
}
|
||||
catch { }
|
||||
break;
|
||||
case Enums.enumActionDisplayType.enabled:
|
||||
MenuItemContent.ClearValue(OpacityProperty);
|
||||
MenuItemBorder.ClearValue(IsHitTestVisibleProperty);
|
||||
break;
|
||||
}
|
||||
|
||||
MenuItemBorder.ToolTip = !string.IsNullOrEmpty(MenuData.UiAction?.Description) ? MenuData.UiAction?.Description : null;
|
||||
ToolTip = !string.IsNullOrEmpty(MenuData.UiAction?.Description) ? MenuData.UiAction?.Description : null;
|
||||
CustomTextBlock.Text = MenuData.MenuText;
|
||||
CustomTextBlockBottom.Text = MenuData.MenuText;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(MenuData.TrailingText))
|
||||
{
|
||||
CustomTrailingTextBlock.Text = string.Empty;
|
||||
CustomTrailingTextBlock.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomTrailingTextBlock.Text = MenuData.TrailingText;
|
||||
CustomTrailingTextBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
DrawEnhancedMenuInformation();
|
||||
}
|
||||
|
||||
private void DrawEnhancedMenuInformation()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (MenuData is cMenuDataContainer containerMenuData)
|
||||
DrawContainer(containerMenuData);
|
||||
else if (MenuData is cMenuDataSearchRelation searchRelationMenuData)
|
||||
DrawSearchRelation(searchRelationMenuData);
|
||||
else if (MenuData is cMenuDataLoading)
|
||||
LoadingIcon.Visibility = Visibility.Visible;
|
||||
else
|
||||
DrawDefault();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
void DrawContainer(cMenuDataContainer containerMenuData)
|
||||
{
|
||||
SubMenuCounterBorder.Visibility = Visibility.Visible;
|
||||
var count = 0;
|
||||
foreach (var entry in containerMenuData.SubMenuData)
|
||||
{
|
||||
if (entry.UiAction?.DisplayType == null || entry.UiAction?.DisplayType == Enums.enumActionDisplayType.enabled)
|
||||
count++;
|
||||
}
|
||||
if (count == 0)
|
||||
SubMenuCounterTextBlock.Text = "-";
|
||||
else
|
||||
SubMenuCounterTextBlock.Text = count.ToString();
|
||||
}
|
||||
|
||||
void DrawSearchRelation(cMenuDataSearchRelation searchRelationMenuData)
|
||||
{
|
||||
if (!(searchRelationMenuData.Data is cF4sdApiSearchResultRelation relationData))
|
||||
return;
|
||||
|
||||
if (searchRelationMenuData.IsMatchingRelation)
|
||||
{
|
||||
LoadingIcon.SelectedMaterialIcon = MaterialIconType.ic_link;
|
||||
LoadingIcon.ClearValue(StyleProperty);
|
||||
LoadingIcon.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
|
||||
if (relationData.Type is enumF4sdSearchResultClass.Ticket)
|
||||
{
|
||||
if (relationData.Infos is null)
|
||||
return;
|
||||
|
||||
if (relationData.Infos.TryGetValue("Summary", out var ticketSummary))
|
||||
{
|
||||
CustomTextBlockBottom.Text = ticketSummary;
|
||||
CustomTextBlockBorderBottom.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
if (relationData.Infos.TryGetValue("StatusId", out var ticketStatusId))
|
||||
{
|
||||
Enum.TryParse(ticketStatusId, true, out enumTicketStatus ticketStatus);
|
||||
|
||||
switch (ticketStatus)
|
||||
{
|
||||
case enumTicketStatus.Unknown:
|
||||
break;
|
||||
case enumTicketStatus.New:
|
||||
case enumTicketStatus.InProgress:
|
||||
case enumTicketStatus.OnHold:
|
||||
MenuItemIcon.SelectedMaterialIcon = MaterialIconType.ic_drafts;
|
||||
break;
|
||||
case enumTicketStatus.Closed:
|
||||
MenuItemIcon.SelectedMaterialIcon = MaterialIconType.ic_mail;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRelationGrid.Visibility = Visibility.Visible;
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
|
||||
using C4IT.FASD.Base;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using MaterialIcons;
|
||||
|
||||
using F4SD_AdaptableIcon;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class CustomMenuItem : UserControl
|
||||
{
|
||||
#region Properties
|
||||
|
||||
#region MenuData
|
||||
|
||||
private cMenuDataBase _menuData = new cMenuDataBase();
|
||||
|
||||
private readonly bool _isLean;
|
||||
|
||||
public cMenuDataBase MenuData
|
||||
{
|
||||
get { return _menuData; }
|
||||
set
|
||||
{
|
||||
if (_menuData != value)
|
||||
{
|
||||
_menuData = value;
|
||||
MenuDataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setIcon(AdaptableIcon.AdaptableIcon icon, IconData data)
|
||||
{
|
||||
var _visibilty = Visibility.Visible;
|
||||
if (data.Intern != null)
|
||||
icon.SelectedInternIcon = data.Intern;
|
||||
else if (data.Material != null)
|
||||
icon.SelectedMaterialIcon = data.Material;
|
||||
else
|
||||
_visibilty = Visibility.Hidden;
|
||||
|
||||
icon.IconHeight = MenuData.MenuIconSize * icon.IconHeight;
|
||||
icon.IconWidth = MenuData.MenuIconSize * icon.IconWidth;
|
||||
|
||||
icon.Visibility = _visibilty;
|
||||
}
|
||||
|
||||
private void MenuDataChanged()
|
||||
{
|
||||
setIcon(MenuItemIcon, MenuData.MenuIcon?.Icon ?? new IconData());
|
||||
|
||||
|
||||
if (MenuData.MenuIcon?.Overlay != null)
|
||||
setIcon(MenuItemOverlayIcon, (IconData)MenuData.MenuIcon.Overlay);
|
||||
else
|
||||
MenuItemOverlayIcon.Visibility = Visibility.Collapsed;
|
||||
|
||||
if (MenuData.MenuIcon?.IsInactive == true)
|
||||
{
|
||||
MenuItemIcon.Opacity = 0.7;
|
||||
MenuItemOverlayIcon.Opacity = 0.7;
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuItemIcon.Opacity = 1.0;
|
||||
MenuItemOverlayIcon.Opacity = 1.0;
|
||||
}
|
||||
|
||||
if (MenuData.MenuIcon?.Description != null)
|
||||
{
|
||||
MenuItemIcon.ToolTip = new CustomMenuItemToolTipTemplate(MenuData.MenuIcon.Description);
|
||||
ToolTipService.SetInitialShowDelay(MenuItemIcon, 300);
|
||||
ToolTipService.SetBetweenShowDelay(MenuItemIcon, 600);
|
||||
ToolTipService.SetPlacement(MenuItemIcon, System.Windows.Controls.Primitives.PlacementMode.Top);
|
||||
ToolTipService.SetHorizontalOffset(MenuItemIcon, 20);
|
||||
ToolTipService.SetVerticalOffset(MenuItemIcon, 20);
|
||||
}
|
||||
|
||||
string toolTip = MenuData.UiAction?.Description;
|
||||
switch (MenuData.UiAction?.DisplayType)
|
||||
{
|
||||
case Enums.enumActionDisplayType.hidden:
|
||||
//todo: add hidden state
|
||||
break;
|
||||
case Enums.enumActionDisplayType.disabled:
|
||||
MenuItemContent.SetValue(OpacityProperty, 0.5);
|
||||
MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.NoHover");
|
||||
if (!string.IsNullOrWhiteSpace(MenuData.UiAction.AlternativeDescription))
|
||||
toolTip = MenuData.UiAction.AlternativeDescription;
|
||||
try
|
||||
{
|
||||
MenuItemBorder.MouseLeftButtonUp -= MenuItemBorder_Click;
|
||||
MenuItemBorder.TouchDown -= MenuItemBorder_Click;
|
||||
}
|
||||
catch { }
|
||||
break;
|
||||
case Enums.enumActionDisplayType.enabled:
|
||||
MenuItemContent.ClearValue(OpacityProperty);
|
||||
MenuItemBorder.ClearValue(IsHitTestVisibleProperty);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(toolTip))
|
||||
MenuItemBorder.ToolTip = toolTip;
|
||||
|
||||
CustomTextBlock.Text = MenuData.MenuText;
|
||||
CustomTextBlockBottom.Text = MenuData.MenuText;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(MenuData.TrailingText))
|
||||
{
|
||||
CustomTrailingTextBlock.Text = string.Empty;
|
||||
CustomTrailingTextBlock.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomTrailingTextBlock.Text = MenuData.TrailingText;
|
||||
CustomTrailingTextBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
DrawEnhancedMenuInformation();
|
||||
}
|
||||
|
||||
private void DrawEnhancedMenuInformation()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (MenuData is cMenuDataContainer containerMenuData)
|
||||
DrawContainer(containerMenuData);
|
||||
else if (MenuData is cMenuDataSearchRelation searchRelationMenuData)
|
||||
DrawSearchRelation(searchRelationMenuData);
|
||||
else if (MenuData is cMenuDataLoading)
|
||||
LoadingIcon.Visibility = Visibility.Visible;
|
||||
else
|
||||
DrawDefault();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
void DrawContainer(cMenuDataContainer containerMenuData)
|
||||
{
|
||||
SubMenuCounterBorder.Visibility = Visibility.Visible;
|
||||
var count = 0;
|
||||
foreach (var entry in containerMenuData.SubMenuData)
|
||||
{
|
||||
if (entry.UiAction?.DisplayType == null || entry.UiAction?.DisplayType == Enums.enumActionDisplayType.enabled)
|
||||
count++;
|
||||
}
|
||||
if (count == 0)
|
||||
SubMenuCounterTextBlock.Text = "-";
|
||||
else
|
||||
SubMenuCounterTextBlock.Text = count.ToString();
|
||||
}
|
||||
|
||||
void DrawSearchRelation(cMenuDataSearchRelation searchRelationMenuData)
|
||||
{
|
||||
if (!(searchRelationMenuData.Data is cF4sdApiSearchResultRelation relationData))
|
||||
return;
|
||||
|
||||
if (searchRelationMenuData.IsMatchingRelation)
|
||||
{
|
||||
LoadingIcon.SelectedMaterialIcon = MaterialIconType.ic_link;
|
||||
LoadingIcon.ClearValue(StyleProperty);
|
||||
LoadingIcon.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
|
||||
if (relationData.Type is enumF4sdSearchResultClass.Ticket)
|
||||
{
|
||||
if (relationData.Infos is null)
|
||||
return;
|
||||
|
||||
if (relationData.Infos.TryGetValue("Summary", out var ticketSummary))
|
||||
{
|
||||
CustomTextBlockBottom.Text = ticketSummary;
|
||||
CustomTextBlockBorderBottom.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchRelationGrid.Visibility = Visibility.Visible;
|
||||
|
||||
if (searchRelationMenuData.LastUsed == DateTime.MinValue)
|
||||
{
|
||||
LessThanTextBlock.Text= string.Empty;
|
||||
LessThanTextBlock.Text = string.Empty;
|
||||
LessThanTextBlock.Visibility = Visibility.Collapsed;
|
||||
LastSeenTextBox.Visibility = Visibility.Collapsed;
|
||||
|
||||
ActivityIndicator.Width = 0;
|
||||
ActivityIndicator.Visibility = Visibility.Collapsed;
|
||||
ActivityTextBlock.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
LastSeenTextBox.Visibility = Visibility.Collapsed;
|
||||
|
||||
ActivityIndicator.Width = 0;
|
||||
ActivityIndicator.Visibility = Visibility.Collapsed;
|
||||
ActivityTextBlock.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
var lastUsedTimeSpan = DateTime.UtcNow - searchRelationMenuData.LastUsed;
|
||||
LanguageDefinitionsConverter valueConverter = new LanguageDefinitionsConverter();
|
||||
string lastSeenText = null;
|
||||
@@ -194,86 +215,97 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
LessThanTextBlock.Text = lastSeenText;
|
||||
LessThanTextBlock.Visibility = Visibility.Visible;
|
||||
LastSeenTextBox.Visibility = Visibility.Visible;
|
||||
|
||||
ActivityIndicator.Width = Math.Max(ActivityIndicator.Width * relationData.UsingLevel, ActivityIndicator.Width * 0.1);
|
||||
ActivityIndicator.Visibility = Visibility.Visible;
|
||||
ActivityTextBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DrawDefault()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(MenuData.SubMenuText))
|
||||
return;
|
||||
|
||||
CustomTextBlockBottom.Text = MenuData.SubMenuText;
|
||||
CustomTextBlockBorderBottom.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public CustomMenuItem(bool isLean)
|
||||
{
|
||||
_isLean = isLean;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
private void MenuItemBorder_Click(object sender, InputEventArgs e)
|
||||
{
|
||||
if (MenuData.UiAction == null)
|
||||
return;
|
||||
|
||||
cUiActionBase.RaiseEvent(MenuData.UiAction, this, this);
|
||||
}
|
||||
|
||||
#region Hover
|
||||
|
||||
private void MenuItemBorder_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
cUtility.SetTickerTextAnimation(CustomTextBlock, CustomTextBlockBorder);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CustomTextBlockBottom.Text) is false)
|
||||
cUtility.SetTickerTextAnimation(CustomTextBlockBottom, CustomTextBlockBorderBottom);
|
||||
}
|
||||
|
||||
private void MenuItemBorder_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
CustomTextBlock.TextTrimming = TextTrimming.CharacterEllipsis;
|
||||
CustomTextBlock.BeginAnimation(MarginProperty, null);
|
||||
|
||||
CustomTextBlockBorder.ClearValue(WidthProperty);
|
||||
CustomTextBlockBorderBottom.ClearValue(WidthProperty);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CustomTextBlockBottom.Text) is false)
|
||||
{
|
||||
CustomTextBlockBottom.TextTrimming = TextTrimming.CharacterEllipsis;
|
||||
CustomTextBlockBottom.BeginAnimation(MarginProperty, null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public void ShowDetailHeadings(bool showDetails)
|
||||
{
|
||||
SearchRelationGrid.ColumnDefinitions[0].Width =
|
||||
showDetails ? new GridLength(1, GridUnitType.Auto) : new GridLength(0);
|
||||
}
|
||||
|
||||
private void CustomMenuItemUc_Initialized(object sender, EventArgs e)
|
||||
{
|
||||
if (_isLean)
|
||||
MenuItemBorder.Height = 30;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
LastSeenTextBox.Visibility = Visibility.Visible;
|
||||
|
||||
ActivityIndicator.Width = Math.Max(ActivityIndicator.Width * relationData.UsingLevel, ActivityIndicator.Width * 0.1);
|
||||
ActivityIndicator.Visibility = Visibility.Visible;
|
||||
ActivityTextBlock.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DrawDefault()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(MenuData.SubMenuText))
|
||||
return;
|
||||
|
||||
CustomTextBlockBottom.Text = MenuData.SubMenuText;
|
||||
CustomTextBlockBorderBottom.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public CustomMenuItem(bool isLean)
|
||||
{
|
||||
_isLean = isLean;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
private void MenuItemBorder_Click(object sender, InputEventArgs e)
|
||||
{
|
||||
if (MenuData.UiAction == null)
|
||||
return;
|
||||
|
||||
if (MenuData.UiAction is cSubMenuAction subMenuAction)
|
||||
{
|
||||
bool useTempData = subMenuAction.UseTempData;
|
||||
|
||||
if (useTempData)
|
||||
{
|
||||
QuickActionSelector.Instance.Search.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
cUiActionBase.RaiseEvent(MenuData.UiAction, this, this);
|
||||
|
||||
}
|
||||
|
||||
#region Hover
|
||||
|
||||
private void MenuItemBorder_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
cUtility.SetTickerTextAnimation(CustomTextBlock, CustomTextBlockBorder);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CustomTextBlockBottom.Text) is false)
|
||||
cUtility.SetTickerTextAnimation(CustomTextBlockBottom, CustomTextBlockBorderBottom);
|
||||
}
|
||||
|
||||
private void MenuItemBorder_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
CustomTextBlock.TextTrimming = TextTrimming.CharacterEllipsis;
|
||||
CustomTextBlock.BeginAnimation(MarginProperty, null);
|
||||
|
||||
CustomTextBlockBorder.ClearValue(WidthProperty);
|
||||
CustomTextBlockBorderBottom.ClearValue(WidthProperty);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CustomTextBlockBottom.Text) is false)
|
||||
{
|
||||
CustomTextBlockBottom.TextTrimming = TextTrimming.CharacterEllipsis;
|
||||
CustomTextBlockBottom.BeginAnimation(MarginProperty, null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public void ShowDetailHeadings(bool showDetails)
|
||||
{
|
||||
SearchRelationGrid.ColumnDefinitions[0].Width =
|
||||
showDetails ? new GridLength(1, GridUnitType.Auto) : new GridLength(0);
|
||||
}
|
||||
|
||||
private void CustomMenuItemUc_Initialized(object sender, EventArgs e)
|
||||
{
|
||||
if (_isLean)
|
||||
MenuItemBorder.Height = 30;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<ToolTip x:Class="FasdDesktopUi.Basics.UserControls.CustomMenuItemToolTipTemplate"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FasdDesktopUi.Basics.UserControls"
|
||||
mc:Ignorable="d"
|
||||
>
|
||||
<ToolTip.Template>
|
||||
<ControlTemplate>
|
||||
<Border BorderBrush="{DynamicResource FontColor.Menu.Categories}" BorderThickness="1" CornerRadius="5"
|
||||
Background="{DynamicResource BackgroundColor.Menu.Categories}"
|
||||
>
|
||||
<TextBlock Text="{Binding Text, RelativeSource={RelativeSource AncestorType=ToolTip}}"
|
||||
Foreground="{DynamicResource FontColor.Menu.Categories}"
|
||||
TextWrapping="Wrap"
|
||||
MaxWidth="300"
|
||||
Margin="8,3,8,5"
|
||||
/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</ToolTip.Template>
|
||||
</ToolTip>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class CustomMenuItemToolTipTemplate : ToolTip
|
||||
{
|
||||
public static readonly DependencyProperty TextProperty =
|
||||
DependencyProperty.Register("Text", typeof(string), typeof(CustomMenuItemToolTipTemplate), new PropertyMetadata("This is a default popup text."));
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return (string)GetValue(TextProperty); }
|
||||
set { SetValue(TextProperty, value); }
|
||||
}
|
||||
|
||||
public CustomMenuItemToolTipTemplate(string content = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
Text = content;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,8 @@
|
||||
Style="{DynamicResource SettingsPage.Close.Icon}"
|
||||
BorderPadding="5"
|
||||
SelectedMaterialIcon="ic_remove"
|
||||
MouseLeftButtonUp="CollapseButton_MouseLeftButtonUp"
|
||||
TouchDown="CollapseButton_TouchDown" />
|
||||
MouseLeftButtonUp="CollapseButton_Click"
|
||||
TouchDown="CollapseButton_Click" />
|
||||
|
||||
<TextBlock Style="{DynamicResource DetailsPage.DataHistory.TitleColumn.OverviewTitle}"
|
||||
Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=QuickAction.Parameter}" />
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.Logging;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
@@ -104,13 +93,13 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
switch (parameterValue)
|
||||
{
|
||||
case cAdjustableParameterBoolean booleanParameter:
|
||||
AddBooleanParameter(parameter.Key, booleanParameter);
|
||||
AddBooleanParameter(booleanParameter);
|
||||
break;
|
||||
case cAdjustableParameterNumerical numericalParameter:
|
||||
AddNumericalParameter(parameter.Key, numericalParameter);
|
||||
AddNumericalParameter(numericalParameter);
|
||||
break;
|
||||
case cAdjustableParameterDropDown dropDownParameter:
|
||||
AddDropDownParameter(parameter.Key, dropDownParameter);
|
||||
AddDropDownParameter(dropDownParameter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -140,7 +129,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
#region Helper
|
||||
|
||||
private void AddBooleanParameter(string parameterKey, cAdjustableParameterBoolean booleanParameter)
|
||||
private void AddBooleanParameter(cAdjustableParameterBoolean booleanParameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -157,7 +146,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
outerPanel.Children.Add(valueCheckBox);
|
||||
|
||||
TextBlock parameterNameTextBlock = new TextBlock() { Text = booleanParameter.Names.GetValue(), Margin = new Thickness(0, 0, 7.5, 0) };
|
||||
if(!string.IsNullOrEmpty(booleanParameter.Descriptions.GetValue()))
|
||||
if (!string.IsNullOrEmpty(booleanParameter.Descriptions.GetValue()))
|
||||
{
|
||||
parameterNameTextBlock.ToolTip = booleanParameter.Descriptions.GetValue();
|
||||
}
|
||||
@@ -172,7 +161,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNumericalParameter(string parameterKey, cAdjustableParameterNumerical numericalParameter)
|
||||
private void AddNumericalParameter(cAdjustableParameterNumerical numericalParameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -185,20 +174,11 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
valueTextBox.SetResourceReference(BackgroundProperty, "BackgroundColor.DetailsPage.DataHistory.TitleColumn");
|
||||
valueTextBox.SetResourceReference(BorderBrushProperty, "BackgroundColor.DetailsPage.DataHistory.ValueColumn");
|
||||
|
||||
valueTextBox.PreviewKeyDown += ((sender, e) =>
|
||||
valueTextBox.TextChanged += (sender, e) =>
|
||||
{
|
||||
if (double.TryParse(valueTextBox.Text, out var parsedValue))
|
||||
ParameterValues[numericalParameter] = parsedValue;
|
||||
});
|
||||
|
||||
valueTextBox.PreviewTextInput += new TextCompositionEventHandler((sender, e) =>
|
||||
{
|
||||
var plannedValue = valueTextBox.Text.Insert(valueTextBox.CaretIndex, e.Text);
|
||||
if (double.TryParse(plannedValue, out var parsedValue))
|
||||
ParameterValues[numericalParameter] = parsedValue;
|
||||
else
|
||||
e.Handled = true;
|
||||
});
|
||||
};
|
||||
|
||||
DockPanel.SetDock(valueTextBox, Dock.Right);
|
||||
outerPanel.Children.Add(valueTextBox);
|
||||
@@ -219,7 +199,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
private void AddDropDownParameter(string parameterKey, cAdjustableParameterDropDown dropDownParameter)
|
||||
private void AddDropDownParameter(cAdjustableParameterDropDown dropDownParameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -227,8 +207,12 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
ParameterValues[dropDownParameter] = dropDownParameter.Default;
|
||||
|
||||
ComboBox valueComboBox = new ComboBox() { SelectedItem = dropDownParameter.Default, MinWidth = 125 };
|
||||
valueComboBox.Style = (Style)FindResource("DarkComboBox");
|
||||
ComboBox valueComboBox = new ComboBox
|
||||
{
|
||||
SelectedItem = dropDownParameter.Default,
|
||||
MinWidth = 125,
|
||||
Style = (Style)FindResource("DarkComboBox")
|
||||
};
|
||||
|
||||
valueComboBox.DropDownOpened += (sender, e) => cFocusInvoker.InvokeGotFocus(this, e);
|
||||
valueComboBox.DropDownClosed += (sender, e) => cFocusInvoker.InvokeLostFocus(this, e);
|
||||
@@ -346,9 +330,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
#region CollapseButton_Click
|
||||
|
||||
private void CollapseButton_Click()
|
||||
private void CollapseButton_Click(object sender, InputEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -360,17 +342,5 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private void CollapseButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
CollapseButton_Click();
|
||||
}
|
||||
|
||||
private void CollapseButton_TouchDown(object sender, TouchEventArgs e)
|
||||
{
|
||||
CollapseButton_Click();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
Visibility="{Binding ElementName=DataCanvasUc, Path=IsDetailedLayout, Converter={StaticResource BoolToVisibility}}"
|
||||
IsCloseButtonVisible="{Binding ElementName=DataCanvasUc, Path=DataCanvasData, Converter={StaticResource IsCloseButtonVisible}, ConverterParameter={x:Static converter:enumDataCanvasTypes.detailedData} }" />
|
||||
|
||||
<local:DynamicChart x:Name="DynamicChartUc"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:DynamicChart x:Name="DynamicChartUc"
|
||||
HorizontalAlignment="Stretch"
|
||||
Width="385"
|
||||
Visibility="{Binding ElementName=DataCanvasUc, Path=IsDetailedLayout, Converter={StaticResource BoolToVisibility}}"
|
||||
IsCloseButtonVisible="{Binding ElementName=DataCanvasUc, Path=DataCanvasData, Converter={StaticResource IsCloseButtonVisible}, ConverterParameter={x:Static converter:enumDataCanvasTypes.detailedData} }" />
|
||||
|
||||
|
||||
<local:DetailedRecommendation x:Name="RecommendationUc"
|
||||
Width="{Binding ElementName=DetailedDataUc, Path=ActualWidth, UpdateSourceTrigger=PropertyChanged}"
|
||||
MinWidth="300"
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
using C4IT.Logging;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Pages.DetailsPage.Models;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
@@ -63,7 +50,9 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
_me.dataProvider.HealthCardDataHelper.LoadingHelper.DataRefreshed += _me.HealthCardDataHelper_DataRefreshed;
|
||||
}
|
||||
|
||||
_me.QuickActionStatusUc.CancelQuickAction();
|
||||
bool isSameQuickAction = oldData?.QuickActionStatusMonitorData?.QuickActionDefinition?.Id == newData?.QuickActionStatusMonitorData?.QuickActionDefinition?.Id;
|
||||
if (!isSameQuickAction && newData?.QuickActionStatusMonitorData?.QuickActionDefinition?.RunImmediate != true)
|
||||
_me.QuickActionStatusUc.CancelQuickAction();
|
||||
|
||||
_me.RecommendationUc.RecommendationData = _me.DataCanvasData.RecommendationData;
|
||||
_me.RecommendationUc.CloseButtonClickedAction = _me.CloseDataCanvas;
|
||||
|
||||
@@ -2,21 +2,10 @@
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Pages.DetailsPage.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
@@ -27,7 +16,18 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
#region RecommendationData
|
||||
|
||||
public static readonly DependencyProperty RecommendationDataProperty =
|
||||
DependencyProperty.Register("RecommendationData", typeof(cRecommendationDataModel), typeof(DetailedRecommendation), new PropertyMetadata(new cRecommendationDataModel()));
|
||||
DependencyProperty.Register("RecommendationData", typeof(cRecommendationDataModel), typeof(DetailedRecommendation), new PropertyMetadata(new cRecommendationDataModel(), new PropertyChangedCallback(HandleRecommendationDataChanged)));
|
||||
|
||||
private static void HandleRecommendationDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is DetailedRecommendation recommendationUc))
|
||||
return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(recommendationUc.RecommendationData?.Recommendation))
|
||||
recommendationUc.Visibility = Visibility.Collapsed;
|
||||
else
|
||||
recommendationUc.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public cRecommendationDataModel RecommendationData
|
||||
{
|
||||
@@ -66,7 +66,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
if (d is DetailedRecommendation recommendation && e.NewValue is IconData iconData)
|
||||
{
|
||||
IconHelper.SetIconValue(recommendation.RecommendationIcon, iconData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string PrimaryIconColorResourceName
|
||||
@@ -99,8 +99,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
private void CloseButton_Click()
|
||||
{
|
||||
if (CloseButtonClickedAction != null)
|
||||
CloseButtonClickedAction.Invoke();
|
||||
CloseButtonClickedAction?.Invoke();
|
||||
}
|
||||
|
||||
private void CloseButton_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
|
||||
@@ -3,6 +3,7 @@ using C4IT.F4SD.SupportCaseProtocoll.Models;
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.MultiLanguage;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using F4SD.Gamification;
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.Services.ProtocollService;
|
||||
@@ -21,6 +22,7 @@ using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using F4SD.Gamification.Services;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
@@ -30,6 +32,16 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
private bool secretsAreShown = false;
|
||||
private readonly IRawValueFormatter _rawValueFormatter = new RawValueFormatter();
|
||||
|
||||
private static object _currentQuickActionLock = new object();
|
||||
|
||||
private Guid _currentRunningQuickActionId;
|
||||
|
||||
public Guid CurrentRunningQuickActionId
|
||||
{
|
||||
get { lock (_currentQuickActionLock) { return _currentRunningQuickActionId; } }
|
||||
set { lock (_currentQuickActionLock) { _currentRunningQuickActionId = value; } }
|
||||
}
|
||||
|
||||
#region Helperclasses QuickAction Output
|
||||
|
||||
public abstract class cQuickActionOutput
|
||||
@@ -38,7 +50,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
public cQuickActionOutput(cF4sdQuickActionRevision.cOutput scriptOutput)
|
||||
{
|
||||
_rawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
_rawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
_rawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
ErrorCode = scriptOutput.ErrorCode;
|
||||
ErrorDescription = scriptOutput.ErrorDescription;
|
||||
@@ -804,7 +816,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
if (measureValues?.Count <= 0)
|
||||
return;
|
||||
|
||||
_rawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
_rawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
_rawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
for (int i = 0; i < measureValues.Count; i++)
|
||||
@@ -1006,7 +1018,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
else if (QuickActionData.ActionSteps.All(step => step.Status == enumQuickActionRevisionStatus.finishedSuccessfull))
|
||||
status = enumQuickActionRevisionStatus.finishedSuccessfull;
|
||||
|
||||
RaiseEvent(new QuickActionEventArgs(QuickActionFinishedEvent, this) { QuickActionResult = result, QuickActionStatus = status, QuickAction = QuickActionData.QuickActionDefinition});
|
||||
RaiseEvent(new QuickActionEventArgs(QuickActionFinishedEvent, this) { QuickActionResult = result, QuickActionStatus = status, QuickAction = QuickActionData.QuickActionDefinition });
|
||||
|
||||
CopyButton.Visibility = Visibility.Visible;
|
||||
|
||||
@@ -1022,6 +1034,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
finally
|
||||
{
|
||||
VisualizeQuickActionFinish(status);
|
||||
GamificationService.TrackAction(CockpitAction.QuickActionExecuted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
40
FasdDesktopUi/Basics/UserControls/FooterButton.xaml
Normal file
40
FasdDesktopUi/Basics/UserControls/FooterButton.xaml
Normal file
@@ -0,0 +1,40 @@
|
||||
<UserControl x:Class="FasdDesktopUi.Basics.UserControls.FooterButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FasdDesktopUi.Basics.UserControls"
|
||||
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
|
||||
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="35"
|
||||
d:DesignWidth="230"
|
||||
x:Name="FooterBtn">
|
||||
|
||||
<UserControl.Resources>
|
||||
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid x:Name="MainGrid"
|
||||
x:FieldModifier="private"
|
||||
Visibility="Collapsed">
|
||||
<Border x:Name="MainBorder"
|
||||
Style="{DynamicResource Menu.MainCategory}"
|
||||
CornerRadius="7.5"
|
||||
Height="35"
|
||||
MouseLeftButtonUp="Button_Click"
|
||||
TouchDown="Button_Click">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ico:AdaptableIcon x:Name="ButtonIcon"
|
||||
Margin="0 0 10 0" />
|
||||
<TextBlock x:Name="ButtonLabel"
|
||||
FontSize="16"
|
||||
Text="{Binding ElementName=FooterBtn, Path=LabelText}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<local:Badge Text="Beta"
|
||||
Margin="-12.5"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
84
FasdDesktopUi/Basics/UserControls/FooterButton.xaml.cs
Normal file
84
FasdDesktopUi/Basics/UserControls/FooterButton.xaml.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using C4IT.MultiLanguage;
|
||||
using F4SD_AdaptableIcon;
|
||||
using FasdDesktopUi.Basics.Converter;
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class FooterButton : UserControl
|
||||
{
|
||||
public string LabelText
|
||||
{
|
||||
get { return (string)GetValue(LabelTextProperty); }
|
||||
set { SetValue(LabelTextProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LabelTextProperty =
|
||||
DependencyProperty.Register(nameof(LabelText), typeof(string), typeof(FooterButton), new PropertyMetadata(string.Empty));
|
||||
|
||||
|
||||
public cUiQuickAction QuickAction
|
||||
{
|
||||
get { return (cUiQuickAction)GetValue(QuickActionProperty); }
|
||||
set { SetValue(QuickActionProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty QuickActionProperty =
|
||||
DependencyProperty.Register(nameof(QuickAction), typeof(cUiQuickAction), typeof(FooterButton), new PropertyMetadata(null, new PropertyChangedCallback(HandleQuickActionChanged)));
|
||||
|
||||
private static void HandleQuickActionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is FooterButton button))
|
||||
return;
|
||||
|
||||
button.UpdateButtonProperties();
|
||||
}
|
||||
|
||||
private void UpdateButtonProperties()
|
||||
{
|
||||
MainGrid.Visibility = QuickAction is null ? Visibility.Collapsed : Visibility.Visible;
|
||||
|
||||
string tooltip = QuickAction != null ? null : cMultiLanguageSupport.GetItem("RemoteConnection.Button.Disabled");
|
||||
SetEnableButton(QuickAction != null && QuickAction.DisplayType == Enums.enumActionDisplayType.enabled, tooltip);
|
||||
|
||||
IconData iconData = IconDataConverter.Convert(QuickAction.QuickActionConfig.Icon);
|
||||
IconHelper.SetIconValue(ButtonIcon, iconData);
|
||||
}
|
||||
|
||||
public FooterButton()
|
||||
{
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void Button_Click(object sender, InputEventArgs e)
|
||||
{
|
||||
if (QuickAction is null)
|
||||
return;
|
||||
|
||||
SetEnableButton(false);
|
||||
cUiActionBase.RaiseEvent(QuickAction, this, this);
|
||||
SetEnableButton(true);
|
||||
}
|
||||
|
||||
internal void SetEnableButton(bool isEnabled, string tooltip = null)
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
MainBorder.SetResourceReference(StyleProperty, "Menu.MainCategory");
|
||||
MainBorder.ClearValue(OpacityProperty);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.NoHover");
|
||||
MainBorder.Opacity = 0.5;
|
||||
}
|
||||
|
||||
MainBorder.ToolTip = tooltip;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<UserControl x:Class="FasdDesktopUi.Basics.UserControls.Gamification.LevelTracker"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FasdDesktopUi.Basics.UserControls.Gamification"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource FontColor.DetailsPage.DataHistory.TitleColumn.MainTitle}" />
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Grid Margin="10 0">
|
||||
<Border BorderBrush="{DynamicResource Color.FunctionMarker}"
|
||||
CornerRadius="50"
|
||||
BorderThickness="6"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="#01010101"
|
||||
Height="45"
|
||||
Width="45">
|
||||
</Border>
|
||||
|
||||
<TextBlock x:Name="LevelValueTextBlock"
|
||||
TextAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
FontWeight="Bold"
|
||||
FontSize="20" />
|
||||
|
||||
<Ellipse x:Name="CoverEllipse"
|
||||
Stroke="{DynamicResource Color.AppBackground}"
|
||||
Opacity="0.5"
|
||||
StrokeThickness="7"
|
||||
Height="46"
|
||||
Width="46"
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<Ellipse.RenderTransform>
|
||||
<RotateTransform Angle="-90" />
|
||||
</Ellipse.RenderTransform>
|
||||
</Ellipse>
|
||||
</Grid>
|
||||
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility"
|
||||
Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=FrameworkElement}, Path=IsMouseOver}"
|
||||
Value="True">
|
||||
<Setter Property="Visibility"
|
||||
Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
|
||||
<TextBlock x:Name="LevelTitelTextBlock"
|
||||
FontWeight="Bold"
|
||||
FontSize="18" />
|
||||
<TextBlock x:Name="XpTextBlock"
|
||||
FontWeight="Light"
|
||||
FontSize="14" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
</UserControl>
|
||||
@@ -0,0 +1,39 @@
|
||||
using F4SD.Gamification;
|
||||
using F4SD.Gamification.Services;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls.Gamification
|
||||
{
|
||||
public partial class LevelTracker : UserControl
|
||||
{
|
||||
public LevelTracker()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private double GetCircumferenceOfCoverEllipse()
|
||||
{
|
||||
return (2 * Math.PI * (CoverEllipse.Height / 2.0 - CoverEllipse.StrokeThickness / 2.0)) / CoverEllipse.StrokeThickness;
|
||||
}
|
||||
|
||||
protected override void OnInitialized(EventArgs e)
|
||||
{
|
||||
CoverEllipse.StrokeDashArray = new DoubleCollection() { GetCircumferenceOfCoverEllipse() };
|
||||
LevelService.ExperiencePointsChanged += UpdateExperiencePoints;
|
||||
|
||||
base.OnInitialized(e);
|
||||
}
|
||||
|
||||
private void UpdateExperiencePoints(object sender, LevelEventArgs e)
|
||||
{
|
||||
LevelValueTextBlock.Text = e.CurrentLevel.ToString();
|
||||
double relativeProgress = (double)e.CurrentXp / (double)e.XpRequiredForLevelUp;
|
||||
CoverEllipse.StrokeDashOffset = (GetCircumferenceOfCoverEllipse() * relativeProgress) * -1.0;
|
||||
|
||||
LevelTitelTextBlock.Text = e.LevelTitle;
|
||||
XpTextBlock.Text = $"{e.CurrentXp} / {e.XpRequiredForLevelUp} XP";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<UserControl x:Class="FasdDesktopUi.Basics.UserControls.InformationClassSearchBar"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FasdDesktopUi.Basics.UserControls"
|
||||
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
|
||||
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
Name="_this"
|
||||
IsVisibleChanged="BlurInvoker_IsActiveChanged">
|
||||
|
||||
<UserControl.Resources>
|
||||
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
|
||||
CornerRadius="17.5"
|
||||
Margin="-2.5"
|
||||
Padding="2.5"
|
||||
VerticalAlignment="Bottom"
|
||||
x:Name="BackgroundBorder"
|
||||
x:FieldModifier="private">
|
||||
|
||||
<DockPanel>
|
||||
<ico:AdaptableIcon x:Name="PhoneCallIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
Visibility="Collapsed"
|
||||
SelectedMaterialIcon="ic_phone" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="ComputerCallIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
Visibility="Collapsed"
|
||||
SelectedInternIcon="misc_computer" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="UserCallIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
Visibility="Collapsed"
|
||||
SelectedInternIcon="misc_user" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="WarningIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
PrimaryIconColor="{DynamicResource HighlightColor.Orange}"
|
||||
Visibility="Collapsed"
|
||||
SelectedInternIcon="status_bad" />
|
||||
|
||||
<local:SearchBar x:Name="InnerSearchBar"
|
||||
x:FieldModifier="private"
|
||||
SearchButtonSize="{Binding SearchButtonSize, ElementName=_this}"
|
||||
CloseButtonSize="{Binding CloseButtonSize, ElementName=_this}"
|
||||
PlaceholderText="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Searchbar.Placeholder.UserName}"
|
||||
ShowCloseButton="True"
|
||||
ShowSearchButton="True"
|
||||
SearchValueChanged="InnerSearchBar_SearchValueChanged"
|
||||
CancelledSearch="InnerSearchBar_CancelledSearch" />
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,287 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using C4IT.Logging;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using C4IT.MultiLanguage;
|
||||
using C4IT.FASD.Base;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class InformationClassSearchBar : UserControl, IBlurInvoker
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public enum eSearchStatus { message, active, fixedResult }
|
||||
public eSearchStatus SearchStatus { get; private set; } = eSearchStatus.message;
|
||||
|
||||
private static CancellationTokenSource _currentSearchTaskToken = null;
|
||||
private static Guid? _currentSearchTaskId = null;
|
||||
private static readonly object _currentSearchTaskLock = new object();
|
||||
|
||||
private readonly Dictionary<enumF4sdSearchResultClass, UIElement> _searchIcons = null;
|
||||
|
||||
public delegate Task ChangedSearchValueDelegate(cFilteredResults results);
|
||||
public ChangedSearchValueDelegate ChangedSearchValue { get; set; } = null;
|
||||
|
||||
public Action CancledSearchAction { get; set; }
|
||||
|
||||
public bool BlurInvoker_IsActive => IsVisible;
|
||||
|
||||
public string SearchValue => InnerSearchBar.SearchValue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dependency Properties
|
||||
|
||||
public static readonly DependencyProperty SearchButtonSizeProperty =
|
||||
DependencyProperty.Register(nameof(SearchButtonSize), typeof(double), typeof(InformationClassSearchBar), new PropertyMetadata(30.0));
|
||||
|
||||
public double SearchButtonSize
|
||||
{
|
||||
get => (double)GetValue(SearchButtonSizeProperty);
|
||||
set => SetValue(SearchButtonSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CloseButtonSizeProperty =
|
||||
DependencyProperty.Register(nameof(CloseButtonSize), typeof(double), typeof(InformationClassSearchBar), new PropertyMetadata(30.0));
|
||||
|
||||
public double CloseButtonSize
|
||||
{
|
||||
get => (double)GetValue(CloseButtonSizeProperty);
|
||||
set => SetValue(CloseButtonSizeProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public InformationClassSearchBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_searchIcons = new Dictionary<enumF4sdSearchResultClass, UIElement>
|
||||
{
|
||||
{ enumF4sdSearchResultClass.Phone, PhoneCallIndicator },
|
||||
{ enumF4sdSearchResultClass.User, UserCallIndicator },
|
||||
{ enumF4sdSearchResultClass.Computer, ComputerCallIndicator }
|
||||
};
|
||||
}
|
||||
|
||||
public void BlurInvoker_IsActiveChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
BlurInvoker.InvokeVisibilityChanged(this, new EventArgs());
|
||||
|
||||
if (e.NewValue is bool newVisible)
|
||||
{
|
||||
if (!newVisible)
|
||||
{
|
||||
InnerSearchBar.IsInputEnabled = true;
|
||||
InnerSearchBar.ShowSearchButton = true;
|
||||
WarningIndicator.Visibility = Visibility.Collapsed;
|
||||
TicketOverview.Instance?.ResetSelection();
|
||||
foreach (var entry in _searchIcons.Values)
|
||||
entry.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
SetApiStatus();
|
||||
}
|
||||
|
||||
if (Visibility == Visibility.Visible)
|
||||
Dispatcher.BeginInvoke((Action)(() => InnerSearchBar.FocusInput()), DispatcherPriority.Render);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
SearchStatus = eSearchStatus.message;
|
||||
InnerSearchBar.Clear();
|
||||
}
|
||||
|
||||
public void ActivateManualSearch()
|
||||
{
|
||||
SearchStatus = eSearchStatus.active;
|
||||
InnerSearchBar.ShowSearchButton = true;
|
||||
WarningIndicator.Visibility = Visibility.Collapsed;
|
||||
foreach (var entry in _searchIcons.Values)
|
||||
entry.Visibility = Visibility.Collapsed;
|
||||
|
||||
InnerSearchBar.Clear();
|
||||
InnerSearchBar.IsInputEnabled = true;
|
||||
InnerSearchBar.FocusInput();
|
||||
}
|
||||
|
||||
public void SetSearchText(string search)
|
||||
{
|
||||
SearchStatus = eSearchStatus.active;
|
||||
InnerSearchBar.SetSearchText(search);
|
||||
}
|
||||
|
||||
public void SetSpinnerVisibility(Visibility visibility)
|
||||
{
|
||||
InnerSearchBar.SetSpinnerVisibility(visibility);
|
||||
}
|
||||
|
||||
public async Task SetFixedSearchResultAsync(enumF4sdSearchResultClass resultClass, string search, cFilteredResults result)
|
||||
{
|
||||
SearchStatus = eSearchStatus.fixedResult;
|
||||
InnerSearchBar.IsInputEnabled = false;
|
||||
InnerSearchBar.ShowSearchButton = false;
|
||||
WarningIndicator.Visibility = Visibility.Collapsed;
|
||||
|
||||
foreach (var entryIcon in _searchIcons)
|
||||
entryIcon.Value.Visibility = entryIcon.Key == resultClass ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
InnerSearchBar.SetSearchText(search);
|
||||
|
||||
if (ChangedSearchValue != null)
|
||||
await ChangedSearchValue.Invoke(result);
|
||||
}
|
||||
|
||||
public void SetApiStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
var status = cConnectionStatusHelper.Instance?.ApiConnectionStatus;
|
||||
if (status == null)
|
||||
return;
|
||||
|
||||
bool isEnabled = false;
|
||||
string txt = null;
|
||||
switch (status)
|
||||
{
|
||||
case cConnectionStatusHelper.enumOnlineStatus.online:
|
||||
isEnabled = true;
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.connectionError:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ConnectError");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.incompatibleServerVersion:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.IncompatibleVersion");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.serverStarting:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ServerStarting");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.serverNotConfigured:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ServerNotConfigured");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.illegalConfig:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.IllegalConfig");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.unauthorized:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.Unauthorized");
|
||||
break;
|
||||
default:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.Offline");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isEnabled)
|
||||
{
|
||||
SearchStatus = eSearchStatus.message;
|
||||
InnerSearchBar.SetSearchText(txt);
|
||||
InnerSearchBar.IsInputEnabled = false;
|
||||
WarningIndicator.Visibility = Visibility.Visible;
|
||||
InnerSearchBar.ShowSearchButton = false;
|
||||
foreach (var entry in _searchIcons.Values)
|
||||
entry.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CancelRunningSearchTaskAsync()
|
||||
{
|
||||
lock (_currentSearchTaskLock)
|
||||
{
|
||||
if (_currentSearchTaskToken != null)
|
||||
{
|
||||
LogEntry("Canceling current running search...");
|
||||
_currentSearchTaskToken.Cancel(true);
|
||||
_currentSearchTaskToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
Guid? currentTaskId = null;
|
||||
lock (_currentSearchTaskLock)
|
||||
{
|
||||
if (_currentSearchTaskId != null)
|
||||
{
|
||||
currentTaskId = _currentSearchTaskId;
|
||||
_currentSearchTaskId = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentTaskId != null)
|
||||
{
|
||||
LogEntry("Sending a search stop...");
|
||||
await cFasdCockpitCommunicationBase.Instance.GetSearchResultsStop((Guid)currentTaskId, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
|
||||
private async void InnerSearchBar_SearchValueChanged(object sender, string searchValue)
|
||||
{
|
||||
MethodBase cm = null;
|
||||
if (cLogManager.DefaultLogger.IsDebug) { cm = MethodBase.GetCurrentMethod(); LogMethodBegin(cm); }
|
||||
|
||||
try
|
||||
{
|
||||
await CancelRunningSearchTaskAsync();
|
||||
|
||||
lock (_currentSearchTaskLock)
|
||||
{
|
||||
LogEntry("Start running new search...");
|
||||
SearchValueChanged?.Invoke(this, searchValue);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (cm != null) LogMethodEnd(cm);
|
||||
}
|
||||
}
|
||||
|
||||
private void InnerSearchBar_CancelledSearch(object sender, RoutedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
RaiseCancledSearchEvent();
|
||||
|
||||
if (cConnectionStatusHelper.Instance?.ApiConnectionStatus == cConnectionStatusHelper.enumOnlineStatus.online)
|
||||
InnerSearchBar.Clear();
|
||||
|
||||
CancledSearchAction?.Invoke();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<string> SearchValueChanged;
|
||||
|
||||
public static readonly RoutedEvent CancledSearchEvent =
|
||||
EventManager.RegisterRoutedEvent(nameof(CancledSearch), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(InformationClassSearchBar));
|
||||
|
||||
public event RoutedEventHandler CancledSearch
|
||||
{
|
||||
add => AddHandler(CancledSearchEvent, value);
|
||||
remove => RemoveHandler(CancledSearchEvent, value);
|
||||
}
|
||||
|
||||
private void RaiseCancledSearchEvent()
|
||||
{
|
||||
RaiseEvent(new RoutedEventArgs(CancledSearchEvent));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using C4IT.FASD.Base;
|
||||
using F4SD_AdaptableIcon;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase;
|
||||
using FasdDesktopUi.Basics.Services.SupportCase.Controllers;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using FasdDesktopUi.Pages;
|
||||
using FasdDesktopUi.Pages.SearchPage;
|
||||
|
||||
using C4IT.FASD.Base;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using F4SD_AdaptableIcon;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
@@ -26,6 +26,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
#region PopUpIsVisible
|
||||
|
||||
public SupportCaseController SupportCaseController { get; set; }
|
||||
|
||||
internal static readonly DependencyPropertyKey PopUpIsVisibleKey = DependencyProperty.RegisterReadOnly("PopUpIsVisible", typeof(bool), typeof(MenuBar), new PropertyMetadata(false));
|
||||
|
||||
public static readonly DependencyProperty PopUpIsVisibleProperty = PopUpIsVisibleKey.DependencyProperty;
|
||||
@@ -109,7 +111,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
AdaptableIcon.AdaptableIcon menuIcon = new AdaptableIcon.AdaptableIcon() { Style = menuPinnedIconStyle };
|
||||
|
||||
IconData icon = sortedMenuData[i].MenuIcon;
|
||||
IconData icon = sortedMenuData[i].MenuIcon.Icon;
|
||||
if (icon.Intern != null)
|
||||
menuIcon.SelectedInternIcon = icon.Intern;
|
||||
else if(icon.Material != null)
|
||||
@@ -142,17 +144,23 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
if (sortedMenuData[i].IconPositionIndex >= 0)
|
||||
MenuBarStackPanel.Children.Insert(MenuBarStackPanel.Children.Count - 1, menuIcon);
|
||||
}
|
||||
|
||||
if (cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.DefaultTemplate != null)
|
||||
|
||||
cCopyTemplate defaultCopyTemplate = null;
|
||||
defaultCopyTemplate = SupportCaseController?.GetCopyTemplate();
|
||||
|
||||
|
||||
if (defaultCopyTemplate != null)
|
||||
{
|
||||
|
||||
|
||||
var copyIcon = new AdaptableIcon.AdaptableIcon()
|
||||
{
|
||||
Style = menuPinnedIconStyle,
|
||||
SelectedInternIcon = enumInternIcons.menuBar_copy,
|
||||
ToolTip = cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.DefaultTemplate.Descriptions.GetValue(Default: null),
|
||||
ToolTip = defaultCopyTemplate?.Descriptions.GetValue(Default: null),
|
||||
};
|
||||
|
||||
copyIcon.Tag = new cMenuDataBase() { IconPositionIndex = 2, MenuIcon = new F4SD_AdaptableIcon.IconData(enumInternIcons.menuBar_copy), UiAction = new cUiCopyAction(cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.DefaultTemplate) };
|
||||
copyIcon.Tag = new cMenuDataBase() { IconPositionIndex = 2, MenuIcon = new cMenuDataBase.MenuIconInfo(new F4SD_AdaptableIcon.IconData(enumInternIcons.menuBar_copy)), UiAction = new cUiCopyAction(defaultCopyTemplate) };
|
||||
|
||||
copyIcon.MouseLeftButtonUp += MenuItem_MouseUp;
|
||||
copyIcon.TouchDown += MenuItem_TouchDown;
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
TextChanged="NotepadRichTextBox_TextChanged"
|
||||
Foreground="{DynamicResource FontColor.DetailsPage.Widget}"
|
||||
Background="{DynamicResource BackgroundColor.DetailsPage.Widget.Title}"
|
||||
SpellCheck.IsEnabled="True"
|
||||
SelectionChanged="NotepadRichTextBox_SelectionChanged"
|
||||
IsVisibleChanged="NotepadRichTextBox_IsVisibleChanged"
|
||||
GotKeyboardFocus="NotepadRichTextBox_GotKeyboardFocus">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using C4IT.FASD.Base;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Helper;
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -8,6 +9,7 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Threading;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
@@ -109,7 +111,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
|
||||
_me.LockNotepadIcon.SelectedInternIcon = _me.IsLocked ? F4SD_AdaptableIcon.Enums.enumInternIcons.lock_closed : F4SD_AdaptableIcon.Enums.enumInternIcons.lock_open;
|
||||
|
||||
|
||||
_me.CloseNotepadIcon.IsEnabled = _me.IsLocked ? false : true;
|
||||
|
||||
}
|
||||
@@ -147,9 +149,9 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch(Exception E)
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
@@ -172,8 +174,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
|
||||
|
||||
|
||||
private void NotepadRichTextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -309,7 +311,11 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
if (DataProvider is null)
|
||||
return;
|
||||
|
||||
Dispatcher.Invoke(() => DataProvider.SaveCaseNotes());
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
SetLanguageOfDocument();
|
||||
DataProvider.SaveCaseNotes();
|
||||
});
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -317,9 +323,19 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLanguageOfDocument()
|
||||
{
|
||||
if (cF4SDCockpitXmlConfig.Instance.HealthCardConfig?.ProtocollLanguage != null)
|
||||
{
|
||||
var languageTag = XmlLanguage.GetLanguage(cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage);
|
||||
TextRange range = new TextRange(NotepadRichTextBox.Document.ContentStart, NotepadRichTextBox.Document.ContentEnd);
|
||||
range.ApplyPropertyValue(FrameworkElement.LanguageProperty, languageTag);
|
||||
}
|
||||
}
|
||||
|
||||
private void NotepadRichTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
|
||||
|
||||
saveTimer?.Stop();
|
||||
saveTimer?.Start();
|
||||
|
||||
@@ -734,7 +750,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
return;
|
||||
}
|
||||
NotepadVisibilityChanged?.Invoke(this, true);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<UserControl.Resources>
|
||||
<converter:NullValueToVisibilityConverter x:Key="NullToVisibility" />
|
||||
<converter:LanguageDefinitionsConverter x:Key="LanguageConverter" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Padding="10"
|
||||
@@ -37,7 +38,7 @@
|
||||
Style="{DynamicResource Menu.Selector.Icon.Lock}"
|
||||
MouseUp="LockButton_MouseUp"
|
||||
TouchDown="LockButton_TouchDown"
|
||||
MouseLeave="LockButton_MouseLeave"/>
|
||||
MouseLeave="LockButton_MouseLeave" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="BackButton"
|
||||
DockPanel.Dock="Left"
|
||||
@@ -74,9 +75,22 @@
|
||||
|
||||
</DockPanel>
|
||||
|
||||
<local:SearchBar x:Name="Search"
|
||||
DockPanel.Dock="Top"
|
||||
PlaceholderText="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Searchbar.Placeholder}"
|
||||
ShowCloseButton="False"
|
||||
SearchButtonSize="26"
|
||||
DebounceInterval="0"
|
||||
SearchBackground="{DynamicResource BackgroundColor.DetailsPage.Widget.Title}"
|
||||
SearchValueChanged="SearchBar_SearchValueChanged"
|
||||
Margin="0 0 0 10"
|
||||
Focusable="True"
|
||||
Height="26" />
|
||||
|
||||
<local:CustomMenu x:Name="SubMenuUc"
|
||||
DockPanel.Dock="Top"
|
||||
MenuDataList="{Binding ElementName=QuickActionSelectorUc, Path=QuickActionList}" />
|
||||
MenuDataList="{Binding ElementName=QuickActionSelectorUc, Path=QuickActionList}"
|
||||
Width="270"/>
|
||||
|
||||
</DockPanel>
|
||||
|
||||
|
||||
@@ -1,23 +1,13 @@
|
||||
using System;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UiActions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.Logging;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using static FasdDesktopUi.Basics.UserControls.InformationClassSearchBar;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
@@ -25,9 +15,12 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public event EventHandler<string> SearchValueChanged;
|
||||
public Action CloseButtonClickedAction { get; set; }
|
||||
public Action<bool> LockStatusChanged { get; set; }
|
||||
|
||||
public static QuickActionSelector Instance;
|
||||
|
||||
#region IsLocked DependencyProperty
|
||||
|
||||
public bool IsLocked
|
||||
@@ -49,7 +42,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
return;
|
||||
}
|
||||
|
||||
_me.CloseButton.IsEnabled = _me.IsLocked ? false : true;
|
||||
_me.CloseButton.IsEnabled = !_me.IsLocked;
|
||||
|
||||
}
|
||||
catch (Exception E)
|
||||
@@ -110,10 +103,13 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
public QuickActionSelector()
|
||||
{
|
||||
InitializeComponent();
|
||||
Search.ActivateManualSearch();
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public void BlurInvoker_IsActiveChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
Search.IsInputEnabled = this.Visibility == Visibility.Visible;
|
||||
BlurInvoker.InvokeVisibilityChanged(this, new EventArgs());
|
||||
}
|
||||
|
||||
@@ -178,7 +174,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
#region CloseButton
|
||||
|
||||
private void CloseButton_Click()
|
||||
public void CloseButton_Click()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -187,9 +183,16 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
QuickActionList = null;
|
||||
Visibility = Visibility.Collapsed;
|
||||
Search.IsEnabled = true;
|
||||
|
||||
if (CloseButtonClickedAction != null)
|
||||
CloseButtonClickedAction.Invoke();
|
||||
Window window = Window.GetWindow(this);
|
||||
if (window != null)
|
||||
{
|
||||
FocusManager.SetFocusedElement(window, window);
|
||||
Keyboard.Focus(window);
|
||||
}
|
||||
|
||||
CloseButtonClickedAction?.Invoke();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -217,6 +220,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
TempQuickActionSelectorHeading = null;
|
||||
QuickActionList = TempQuickActionList;
|
||||
TempQuickActionList = null;
|
||||
Search.IsEnabled = true;
|
||||
Search.FocusInput();
|
||||
}
|
||||
|
||||
private void BackButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
@@ -230,5 +235,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SearchBar_SearchValueChanged(object sender, string e)
|
||||
=> SearchValueChanged?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
set { SetValue(QuickTipNameProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for QuickTipName. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty QuickTipNameProperty =
|
||||
DependencyProperty.Register("QuickTipName", typeof(string), typeof(QuickTipStatusMonitor), new PropertyMetadata("Quick Tip Name"));
|
||||
|
||||
@@ -44,7 +43,6 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
set { SetValue(QuickTipIconProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for QuickTipIcon. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty QuickTipIconProperty =
|
||||
DependencyProperty.Register("QuickTipIcon", typeof(IconData), typeof(QuickTipStatusMonitor), new PropertyMetadata(new IconData(enumInternIcons.none)));
|
||||
|
||||
@@ -58,7 +56,6 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
set { SetValue(QuickTipElementDataProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for QuickTipElementData. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty QuickTipElementDataProperty =
|
||||
DependencyProperty.Register("QuickTipElementData", typeof(List<cUiQuickTipElement>), typeof(QuickTipStatusMonitor), new PropertyMetadata(new List<cUiQuickTipElement>(), HandleQuickTipElementDataChanged));
|
||||
|
||||
@@ -94,20 +91,6 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
|
||||
#endregion
|
||||
|
||||
#region HasFocusIndex
|
||||
|
||||
public int HasFocusIndex
|
||||
{
|
||||
get { return (int)GetValue(HasFocusIndexProperty); }
|
||||
set { SetValue(HasFocusIndexProperty, value); }
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for HasFocusIndex. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty HasFocusIndexProperty =
|
||||
DependencyProperty.Register("HasFocusIndex", typeof(int), typeof(QuickTipStatusMonitor), new PropertyMetadata(0));
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public QuickTipStatusMonitor()
|
||||
@@ -255,8 +238,14 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
return;
|
||||
|
||||
bool wasSuccessfull = step.SuccessState == enumQuickActionSuccess.finished || step.SuccessState == enumQuickActionSuccess.successfull;
|
||||
|
||||
string currentLanguage = cMultiLanguageSupport.CurrentLanguage;
|
||||
cMultiLanguageSupport.CurrentLanguage = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage ?? currentLanguage;
|
||||
|
||||
ProtocollEntryBase protocollEntry = QuickTipStepProtocollEntryOutput.GetQuickTipStepProtocollEntry(step.StepData.QuickTipElementDefinition, wasSuccessfull);
|
||||
|
||||
cMultiLanguageSupport.CurrentLanguage = currentLanguage;
|
||||
|
||||
F4SDProtocoll.Instance.Add(protocollEntry);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -331,26 +320,40 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
QuickTipElementData = new List<cUiQuickTipElement>();
|
||||
}
|
||||
|
||||
private void CancelButton_Click(object sender, InputEventArgs args) => CancelQuickTip();
|
||||
private void CancelButton_Click(object sender, InputEventArgs args) => TryCancelQuickTip();
|
||||
|
||||
private void CancelQuickTip()
|
||||
/// <returns>If QuickTip could be canceled</returns>
|
||||
internal bool TryCancelQuickTip()
|
||||
{
|
||||
if (_stepList.Any(step => step.SuccessState != enumQuickActionSuccess.unknown))
|
||||
if (CustomMessageBox.Show(cMultiLanguageSupport.GetItem("QuickTips.Dialog.Cancel"), "Quick Tip", enumHealthCardStateLevel.Warning, null, true) != true)
|
||||
return;
|
||||
return false;
|
||||
|
||||
Visibility = Visibility.Collapsed;
|
||||
|
||||
int finishedStepCount = _stepList.Count(step => step.SuccessState == enumQuickActionSuccess.finished);
|
||||
AddQuickTipEndToProtocoll(QuickTipName, finishedStepCount, _stepList.Count, true);
|
||||
QuickTipElementData = new List<cUiQuickTipElement>();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AddQuickTipEndToProtocoll(string quickTipName, int finishedStepCount, int totalStepCount, bool wasCanceled)
|
||||
{
|
||||
string ascii = wasCanceled ? cMultiLanguageSupport.GetItem("QuickTips.Copy.Cancel") : cMultiLanguageSupport.GetItem("QuickTips.Copy.Finish");
|
||||
ascii = string.Format(ascii, quickTipName, finishedStepCount, totalStepCount);
|
||||
F4SDProtocoll.Instance.Add(new TextualProtocollEntry(ascii, ascii));
|
||||
string currentLanguage = cMultiLanguageSupport.CurrentLanguage;
|
||||
|
||||
try
|
||||
{
|
||||
cMultiLanguageSupport.CurrentLanguage = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage ?? currentLanguage;
|
||||
|
||||
string ascii = wasCanceled ? cMultiLanguageSupport.GetItem("QuickTips.Copy.Cancel") : cMultiLanguageSupport.GetItem("QuickTips.Copy.Finish");
|
||||
ascii = string.Format(ascii, quickTipName, finishedStepCount, totalStepCount);
|
||||
|
||||
F4SDProtocoll.Instance.Add(new TextualProtocollEntry(ascii, ascii));
|
||||
}
|
||||
finally
|
||||
{
|
||||
cMultiLanguageSupport.CurrentLanguage = currentLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
private void QuickTipStatusMonitorUc_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
@@ -358,9 +361,21 @@ namespace FasdDesktopUi.Basics.UserControls.QuickTip
|
||||
if (!IsVisible)
|
||||
return;
|
||||
|
||||
string ascii = cMultiLanguageSupport.GetItem("QuickTips.Copy.Start");
|
||||
ascii = string.Format(ascii, QuickTipName);
|
||||
F4SDProtocoll.Instance.Add(new TextualProtocollEntry(ascii, ascii));
|
||||
string currentLanguage = cMultiLanguageSupport.CurrentLanguage;
|
||||
|
||||
try
|
||||
{
|
||||
cMultiLanguageSupport.CurrentLanguage = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage ?? currentLanguage;
|
||||
|
||||
string ascii = cMultiLanguageSupport.GetItem("QuickTips.Copy.Start");
|
||||
ascii = string.Format(ascii, QuickTipName);
|
||||
|
||||
F4SDProtocoll.Instance.Add(new TextualProtocollEntry(ascii, ascii));
|
||||
}
|
||||
finally
|
||||
{
|
||||
cMultiLanguageSupport.CurrentLanguage = currentLanguage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,19 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FasdDesktopUi.Basics.UserControls"
|
||||
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
|
||||
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
Name="_this"
|
||||
IsVisibleChanged="BlurInvoker_IsActiveChanged"
|
||||
Name="Search"
|
||||
Loaded="SearchBar_Loaded">
|
||||
|
||||
<UserControl.Resources>
|
||||
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
|
||||
<Border Background="{Binding ElementName=Search, Path=SearchBackground}"
|
||||
CornerRadius="17.5"
|
||||
Margin="-2.5"
|
||||
Padding="2.5"
|
||||
@@ -29,47 +27,15 @@
|
||||
<ico:AdaptableIcon x:Name="SearchButton"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Visibility="{Binding ShowSearchButton, ElementName=Search, Converter={StaticResource BoolToVisibility}}"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
MouseUp="SearchButton_Click"
|
||||
TouchDown="SearchButton_Click"
|
||||
IconBackgroundColor="Transparent"
|
||||
IconHeight="{Binding SearchButtonSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
IconWidth="{Binding SearchButtonSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
IconHeight="{Binding SearchButtonSize, ElementName=Search}"
|
||||
IconWidth="{Binding SearchButtonSize, ElementName=Search}"
|
||||
SelectedInternIcon="menuBar_search" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="PhoneCallIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
Visibility="Collapsed"
|
||||
SelectedMaterialIcon="ic_phone" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="ComputerCallIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
Visibility="Collapsed"
|
||||
SelectedInternIcon="misc_computer" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="UserCallIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
Visibility="Collapsed"
|
||||
SelectedInternIcon="misc_user" />
|
||||
|
||||
<ico:AdaptableIcon x:Name="WarningIndicator"
|
||||
x:FieldModifier="private"
|
||||
DockPanel.Dock="Left"
|
||||
Style="{DynamicResource Menu.MenuBar.PinnedIcon}"
|
||||
IconBackgroundColor="Transparent"
|
||||
PrimaryIconColor="#FFFF8800"
|
||||
Visibility="Collapsed"
|
||||
SelectedInternIcon="status_bad" />
|
||||
|
||||
<Grid DockPanel.Dock="Left">
|
||||
|
||||
<TextBlock IsHitTestVisible="False"
|
||||
@@ -83,7 +49,7 @@
|
||||
<DataTrigger Binding="{Binding Text, ElementName=SearchTextBox}"
|
||||
Value="">
|
||||
<Setter Property="Text"
|
||||
Value="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Searchbar.Placeholder.UserName}" />
|
||||
Value="{Binding PlaceholderText, ElementName=Search}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
@@ -92,7 +58,8 @@
|
||||
|
||||
<TextBox x:Name="SearchTextBox"
|
||||
x:FieldModifier="private"
|
||||
Text="{Binding ElementName=_this, Path=SearchValue, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}"
|
||||
IsEnabled="{Binding IsInputEnabled, ElementName=Search}"
|
||||
Text="{Binding ElementName=Search, Path=SearchValue, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}"
|
||||
Style="{DynamicResource SearchBar.TextBox}" />
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
@@ -114,11 +81,13 @@
|
||||
</TransformGroup>
|
||||
</ico:AdaptableIcon.RenderTransform>
|
||||
</ico:AdaptableIcon>
|
||||
|
||||
<ico:AdaptableIcon x:Name="CloseButton"
|
||||
x:FieldModifier="private"
|
||||
Visibility="{Binding ShowCloseButton, ElementName=Search, Converter={StaticResource BoolToVisibility}}"
|
||||
Style="{DynamicResource SettingsPage.Close.Icon}"
|
||||
IconHeight="{Binding CloseButtonSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
IconWidth="{Binding CloseButtonSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
IconHeight="{Binding CloseButtonSize, ElementName=Search}"
|
||||
IconWidth="{Binding CloseButtonSize, ElementName=Search}"
|
||||
Margin="-3 0 0 0"
|
||||
Padding="0"
|
||||
ToolTip="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Global.NavBar.Close}"
|
||||
|
||||
@@ -1,38 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using C4IT.Logging;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
using C4IT.MultiLanguage;
|
||||
using C4IT.FASD.Base;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
public partial class SearchBar : UserControl, IBlurInvoker
|
||||
public partial class SearchBar : UserControl
|
||||
{
|
||||
private const int constTimeBetweenKeystrokes = 250;
|
||||
|
||||
#region Propeties
|
||||
public enum eSearchStatus { message, active, fixedResult };
|
||||
public eSearchStatus SearchStatus { get; private set; } = eSearchStatus.message;
|
||||
|
||||
#region Search Value Property
|
||||
|
||||
private readonly DispatcherTimer _searchTimer = new DispatcherTimer();
|
||||
|
||||
private static CancellationTokenSource _currentSearchTaskToken = null;
|
||||
private static Guid? _currentSearchTaskId = null;
|
||||
private static readonly object _currentSearchTaskLock = new object();
|
||||
#region Dependency Properties
|
||||
|
||||
public static readonly DependencyProperty SearchButtonSizeProperty =
|
||||
DependencyProperty.Register(nameof(SearchButtonSize), typeof(double), typeof(SearchBar), new PropertyMetadata(30.0));
|
||||
|
||||
public double SearchButtonSize
|
||||
{
|
||||
get => (double)GetValue(SearchButtonSizeProperty);
|
||||
set => SetValue(SearchButtonSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CloseButtonSizeProperty =
|
||||
DependencyProperty.Register(nameof(CloseButtonSize), typeof(double), typeof(SearchBar), new PropertyMetadata(30.0));
|
||||
|
||||
public double CloseButtonSize
|
||||
{
|
||||
get => (double)GetValue(CloseButtonSizeProperty);
|
||||
set => SetValue(CloseButtonSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowCloseButtonProperty =
|
||||
DependencyProperty.Register(nameof(ShowCloseButton), typeof(bool), typeof(SearchBar), new PropertyMetadata(true));
|
||||
|
||||
public bool ShowCloseButton
|
||||
{
|
||||
get => (bool)GetValue(ShowCloseButtonProperty);
|
||||
set => SetValue(ShowCloseButtonProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ShowSearchButtonProperty =
|
||||
DependencyProperty.Register(nameof(ShowSearchButton), typeof(bool), typeof(SearchBar), new PropertyMetadata(true));
|
||||
|
||||
public bool ShowSearchButton
|
||||
{
|
||||
get => (bool)GetValue(ShowSearchButtonProperty);
|
||||
set => SetValue(ShowSearchButtonProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PlaceholderTextProperty =
|
||||
DependencyProperty.Register(nameof(PlaceholderText), typeof(string), typeof(SearchBar), new PropertyMetadata(string.Empty));
|
||||
|
||||
public string PlaceholderText
|
||||
{
|
||||
get => (string)GetValue(PlaceholderTextProperty);
|
||||
set => SetValue(PlaceholderTextProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DebounceIntervalProperty =
|
||||
DependencyProperty.Register(nameof(DebounceInterval), typeof(TimeSpan), typeof(SearchBar),
|
||||
new PropertyMetadata(TimeSpan.FromMilliseconds(250), OnDebounceIntervalChanged));
|
||||
|
||||
public TimeSpan DebounceInterval
|
||||
{
|
||||
get => (TimeSpan)GetValue(DebounceIntervalProperty);
|
||||
set => SetValue(DebounceIntervalProperty, value);
|
||||
}
|
||||
|
||||
private static void OnDebounceIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
((SearchBar)d)._searchTimer.Interval = (TimeSpan)e.NewValue;
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsInputEnabledProperty =
|
||||
DependencyProperty.Register(nameof(IsInputEnabled), typeof(bool), typeof(SearchBar), new PropertyMetadata(true));
|
||||
|
||||
public bool IsInputEnabled
|
||||
{
|
||||
get => (bool)GetValue(IsInputEnabledProperty);
|
||||
set => SetValue(IsInputEnabledProperty, value);
|
||||
}
|
||||
|
||||
public SolidColorBrush SearchBackground
|
||||
{
|
||||
get { return (SolidColorBrush)GetValue(SearchBackgroundProperty); }
|
||||
set { SetValue(SearchBackgroundProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SearchBackgroundProperty =
|
||||
DependencyProperty.Register(nameof(SearchBackground), typeof(SolidColorBrush), typeof(SearchBar), new PropertyMetadata(null));
|
||||
|
||||
#endregion
|
||||
|
||||
#region SearchValue
|
||||
|
||||
private string _searchValue = null;
|
||||
public string SearchValue
|
||||
@@ -43,111 +104,49 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
if (value != _searchValue)
|
||||
{
|
||||
_searchValue = value;
|
||||
if (SearchStatus == eSearchStatus.active)
|
||||
if (IsInputEnabled)
|
||||
HandleSearchValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<enumF4sdSearchResultClass, UIElement> _searchIcons = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<string> SearchValueChanged;
|
||||
|
||||
public delegate Task ChangedSearchValueDelegate(cFilteredResults results);
|
||||
public static readonly RoutedEvent CancelledSearchEvent =
|
||||
EventManager.RegisterRoutedEvent(nameof(CancelledSearch), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SearchBar));
|
||||
|
||||
public ChangedSearchValueDelegate ChangedSearchValue { get; set; } = null;
|
||||
|
||||
public Action CancledSearchAction { get; set; }
|
||||
|
||||
public bool BlurInvoker_IsActive => IsVisible;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dependency Propertys
|
||||
|
||||
public double SearchButtonSize
|
||||
public event RoutedEventHandler CancelledSearch
|
||||
{
|
||||
get { return (double)GetValue(SearchButtonSizeProperty); }
|
||||
set { SetValue(SearchButtonSizeProperty, value); }
|
||||
add => AddHandler(CancelledSearchEvent, value);
|
||||
remove => RemoveHandler(CancelledSearchEvent, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SearchButtonSizeProperty =
|
||||
DependencyProperty.Register("SearchButtonSize", typeof(double), typeof(SearchBar), new PropertyMetadata(30.0));
|
||||
|
||||
public double CloseButtonSize
|
||||
{
|
||||
get { return (double)GetValue(CloseButtonSizeProperty); }
|
||||
set { SetValue(CloseButtonSizeProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CloseButtonSizeProperty =
|
||||
DependencyProperty.Register("CloseButtonSize", typeof(double), typeof(SearchBar), new PropertyMetadata(30.0));
|
||||
#endregion
|
||||
|
||||
public SearchBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_searchIcons = new Dictionary<enumF4sdSearchResultClass, UIElement>()
|
||||
{
|
||||
{ enumF4sdSearchResultClass.Phone, PhoneCallIndicator },
|
||||
{ enumF4sdSearchResultClass.User, UserCallIndicator },
|
||||
{ enumF4sdSearchResultClass.Computer, ComputerCallIndicator }
|
||||
};
|
||||
}
|
||||
|
||||
public void BlurInvoker_IsActiveChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
BlurInvoker.InvokeVisibilityChanged(this, new EventArgs());
|
||||
|
||||
if (e.NewValue is bool newVisible)
|
||||
{
|
||||
if (newVisible == false)
|
||||
{
|
||||
SearchTextBox.IsEnabled = true;
|
||||
SearchButton.Visibility = Visibility.Visible;
|
||||
WarningIndicator.Visibility = Visibility.Collapsed;
|
||||
TicketOverview.Instance?.ResetSelection();
|
||||
foreach (var Entry in _searchIcons.Values)
|
||||
Entry.Visibility = Visibility.Collapsed;
|
||||
|
||||
}
|
||||
SetApiStatus();
|
||||
}
|
||||
|
||||
if (Visibility == Visibility.Visible)
|
||||
{
|
||||
var _h = Dispatcher.BeginInvoke((Action)delegate { Keyboard.Focus(SearchTextBox); }, DispatcherPriority.Render);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
SearchStatus = eSearchStatus.message;
|
||||
SearchTextBox.Text = null;
|
||||
}
|
||||
|
||||
public void ActivateManualSearch()
|
||||
{
|
||||
SearchStatus = eSearchStatus.active;
|
||||
SearchButton.Visibility = Visibility.Visible;
|
||||
WarningIndicator.Visibility = Visibility.Collapsed;
|
||||
foreach (var Entry in _searchIcons.Values)
|
||||
Entry.Visibility = Visibility.Collapsed;
|
||||
|
||||
SearchTextBox.Text = null;
|
||||
SearchTextBox.IsEnabled = true;
|
||||
SearchTextBox.Focus();
|
||||
Keyboard.Focus(SearchTextBox);
|
||||
}
|
||||
|
||||
public void SetSearchText(string search)
|
||||
{
|
||||
SearchStatus = eSearchStatus.active;
|
||||
SearchTextBox.Text = search;
|
||||
SearchTextBox.CaretIndex = search.Length;
|
||||
SearchTextBox.CaretIndex = search?.Length ?? 0;
|
||||
SearchTextBox.Focus();
|
||||
Keyboard.Focus(SearchTextBox);
|
||||
}
|
||||
|
||||
public void FocusInput()
|
||||
{
|
||||
SearchTextBox.Focus();
|
||||
Keyboard.Focus(SearchTextBox);
|
||||
}
|
||||
@@ -157,165 +156,18 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
Dispatcher.Invoke(() => SearchSpinner.Visibility = visibility);
|
||||
}
|
||||
|
||||
public async Task SetFixedSearchResultAsync(enumF4sdSearchResultClass Class, string search, cFilteredResults result)
|
||||
{
|
||||
SearchStatus = eSearchStatus.fixedResult;
|
||||
SearchTextBox.IsEnabled = false;
|
||||
SearchButton.Visibility = Visibility.Collapsed;
|
||||
WarningIndicator.Visibility = Visibility.Collapsed;
|
||||
|
||||
foreach (var entryIcon in _searchIcons)
|
||||
{
|
||||
if (Class == entryIcon.Key)
|
||||
entryIcon.Value.Visibility = Visibility.Visible;
|
||||
else
|
||||
entryIcon.Value.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
SearchTextBox.Text = search;
|
||||
|
||||
if (ChangedSearchValue != null)
|
||||
await ChangedSearchValue.Invoke(result);
|
||||
}
|
||||
|
||||
public void SetApiStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
var Status = cConnectionStatusHelper.Instance?.ApiConnectionStatus;
|
||||
if (Status == null)
|
||||
return;
|
||||
|
||||
bool IsEnabled = false;
|
||||
string txt = null;
|
||||
switch (Status)
|
||||
{
|
||||
case cConnectionStatusHelper.enumOnlineStatus.online:
|
||||
IsEnabled = true;
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.connectionError:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ConnectError");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.incompatibleServerVersion:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.IncompatibleVersion");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.serverStarting:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ServerStarting");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.serverNotConfigured:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ServerNotConfigured");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.illegalConfig:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.IllegalConfig");
|
||||
break;
|
||||
case cConnectionStatusHelper.enumOnlineStatus.unauthorized:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.Unauthorized");
|
||||
break;
|
||||
default:
|
||||
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.Offline");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsEnabled)
|
||||
{
|
||||
SearchStatus = eSearchStatus.message;
|
||||
SearchTextBox.Text = txt;
|
||||
SearchTextBox.IsEnabled = false;
|
||||
WarningIndicator.Visibility = Visibility.Visible;
|
||||
SearchButton.Visibility = Visibility.Collapsed;
|
||||
foreach (var Entry in _searchIcons.Values)
|
||||
Entry.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CancelRunningSearchTaskAsync()
|
||||
{
|
||||
// cancel the search task, in case of a running search task
|
||||
lock (_currentSearchTaskLock)
|
||||
{
|
||||
if (_currentSearchTaskToken != null)
|
||||
{
|
||||
LogEntry("Canceling current running search...");
|
||||
_currentSearchTaskToken.Cancel(true);
|
||||
_currentSearchTaskToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
// send a stop to the server, in case of a running search task
|
||||
Guid? currentTaskId = null;
|
||||
lock (_currentSearchTaskLock)
|
||||
{
|
||||
if (_currentSearchTaskId != null)
|
||||
{
|
||||
currentTaskId = _currentSearchTaskId;
|
||||
_currentSearchTaskId = null;
|
||||
}
|
||||
}
|
||||
if (currentTaskId != null)
|
||||
{
|
||||
LogEntry("Sending a search stop...");
|
||||
await cFasdCockpitCommunicationBase.Instance.GetSearchResultsStop((Guid)currentTaskId, CancellationToken.None);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async void UpdateSearchResultsTick(object sender, EventArgs e)
|
||||
{
|
||||
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
||||
|
||||
try
|
||||
{
|
||||
_searchTimer.Stop();
|
||||
|
||||
await CancelRunningSearchTaskAsync();
|
||||
|
||||
lock (_currentSearchTaskLock)
|
||||
{
|
||||
LogEntry("Start running new search...");
|
||||
SearchValueChanged?.Invoke(this, SearchValue);
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (CM != null) LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSearchValueChanged()
|
||||
{
|
||||
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
||||
if (_searchTimer.IsEnabled)
|
||||
_searchTimer.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
if (!SearchTextBox.IsEnabled)
|
||||
return;
|
||||
_searchTimer.Start();
|
||||
}
|
||||
|
||||
if (_searchTimer.IsEnabled)
|
||||
_searchTimer.Stop();
|
||||
|
||||
_searchTimer.Start();
|
||||
|
||||
_ = Task.Run(async () => { await CancelRunningSearchTaskAsync(); });
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (CM != null) LogMethodEnd(CM);
|
||||
}
|
||||
private void SearchTimerTick(object sender, EventArgs e)
|
||||
{
|
||||
_searchTimer.Stop();
|
||||
SearchValueChanged?.Invoke(this, SearchValue);
|
||||
}
|
||||
|
||||
private void SearchButton_Click(object sender, InputEventArgs e)
|
||||
@@ -323,40 +175,28 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
SearchTextBox.Focus();
|
||||
}
|
||||
|
||||
#region CancledSearch Event
|
||||
|
||||
public static readonly RoutedEvent CancledSearchEvent = EventManager.RegisterRoutedEvent("CancledSearch", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SearchBar));
|
||||
|
||||
public event RoutedEventHandler CancledSearch
|
||||
{
|
||||
add { AddHandler(CancledSearchEvent, value); }
|
||||
remove { RemoveHandler(CancledSearchEvent, value); }
|
||||
}
|
||||
|
||||
private void RaiseCancledSearchEvent()
|
||||
{
|
||||
RoutedEventArgs newEventArgs = new RoutedEventArgs(CancledSearchEvent);
|
||||
RaiseEvent(newEventArgs);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void CloseButton_Click(object sender, InputEventArgs e)
|
||||
{
|
||||
RaiseCancledSearchEvent();
|
||||
|
||||
if (cConnectionStatusHelper.Instance?.ApiConnectionStatus == cConnectionStatusHelper.enumOnlineStatus.online)
|
||||
SearchTextBox.Text = null;
|
||||
|
||||
CancledSearchAction?.Invoke();
|
||||
RaiseEvent(new RoutedEventArgs(CancelledSearchEvent));
|
||||
}
|
||||
|
||||
private void SearchBar_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_searchTimer.Stop();
|
||||
_searchTimer.Interval = TimeSpan.FromMilliseconds(constTimeBetweenKeystrokes);
|
||||
_searchTimer.Tick += UpdateSearchResultsTick;
|
||||
_searchTimer.Interval = DebounceInterval;
|
||||
_searchTimer.Tick += SearchTimerTick;
|
||||
BackgroundBorder.CornerRadius = new CornerRadius(BackgroundBorder.ActualHeight / 2.0);
|
||||
}
|
||||
|
||||
internal void ActivateManualSearch()
|
||||
{
|
||||
Search.Clear();
|
||||
Search.IsInputEnabled = true;
|
||||
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
Search.FocusInput();
|
||||
}), DispatcherPriority.Input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
MenuData = new cMenuDataBase()
|
||||
{
|
||||
MenuText = cMultiLanguageSupport.GetItem("SearchBar.NoResults"),
|
||||
MenuIcon = new IconData(enumInternIcons.menuBar_search_noResults)
|
||||
MenuIcon = new cMenuDataBase.MenuIconInfo(new IconData(enumInternIcons.menuBar_search_noResults))
|
||||
}
|
||||
};
|
||||
MainStackPanel.Children.Add(resultItemControl);
|
||||
@@ -236,7 +236,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
var menuData = new cMenuDataBase() { MenuText = historyEntry.DisplayText, UiAction = new cUiProcessSearchHistoryEntry(historyEntry) };
|
||||
if (historyEntry.isSeen)
|
||||
{
|
||||
menuData.MenuIcon = new IconData(MaterialIcons.MaterialIconType.ic_visibility);
|
||||
menuData.MenuIcon = new cMenuDataBase.MenuIconInfo(new IconData(MaterialIcons.MaterialIconType.ic_visibility));
|
||||
menuData.MenuIconSize = 0.75;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,31 +5,33 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FasdDesktopUi.Basics.UserControls"
|
||||
xmlns:config="clr-namespace:C4IT.FASD.Base;assembly=F4SD-Cockpit-Client-Base"
|
||||
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
|
||||
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
|
||||
xmlns:vd="clr-namespace:FasdDesktopUi.Basics.Converter"
|
||||
xmlns:vc="clr-namespace:C4IT.MultiLanguage;assembly=F4SD-Cockpit-Client-Base"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Initialized="UserControl_Initialized">
|
||||
Initialized="UserControl_Initialized">
|
||||
|
||||
<UserControl.Resources>
|
||||
<vd:LanguageDefinitionsConverter x:Key="LanguageConverter"/>
|
||||
|
||||
<!-- Style für den Hovereffekt -->
|
||||
<Style x:Key="PauseButtonHoverStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<vd:LanguageDefinitionsConverter x:Key="LanguageConverter" />
|
||||
|
||||
<Style x:Key="PauseButtonHoverStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="Background"
|
||||
Value="Transparent" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource Background.Menu.Icon.Hover}"/>
|
||||
<Trigger Property="IsMouseOver"
|
||||
Value="True">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource Background.Menu.Icon.Hover}" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Padding="8"
|
||||
@@ -45,71 +47,72 @@
|
||||
ToolTip="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=TimerView.Time.ToolTip}"
|
||||
Foreground="{DynamicResource Color.Menu.Icon}" />
|
||||
</Border>
|
||||
|
||||
<Border Padding="20 5 5 5"
|
||||
|
||||
<Border Padding="20 5 5 5"
|
||||
Grid.Column="1"
|
||||
Width="Auto"
|
||||
Height="33"
|
||||
Cursor="Hand"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="5"
|
||||
CornerRadius="5"
|
||||
Margin="-5 0 0 0"
|
||||
ToolTip="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=TimerView.Pausebutton.ToolTip}"
|
||||
Style="{DynamicResource PauseButtonHoverStyle}"
|
||||
MouseLeftButtonUp="Border_MouseLeftButtonUp" TouchDown="Border_TouchDown"
|
||||
>
|
||||
MouseLeftButtonUp="Border_Click"
|
||||
TouchDown="Border_Click">
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
|
||||
<ico:AdaptableIcon Grid.Column="1"
|
||||
<ico:AdaptableIcon Grid.Column="1"
|
||||
x:Name="PauseButton"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="-15 0 5 0"
|
||||
Margin="-15 0 5 0"
|
||||
Panel.ZIndex="2"
|
||||
BorderPadding="0"
|
||||
IconHeight="22"
|
||||
IconWidth="22"
|
||||
SelectedMaterialIcon="ic_pause_circle_outline"
|
||||
SelectedMaterialIcon="ic_pause_circle_outline"
|
||||
IconBackgroundColor="Transparent">
|
||||
<ico:AdaptableIcon.Resources>
|
||||
<Style TargetType="ico:AdaptableIcon"
|
||||
BasedOn="{StaticResource Menu.MenuBar.PinnedIcon.Pinned}">
|
||||
<Setter Property="PrimaryIconColor"
|
||||
Value="{DynamicResource FontColor.Menu.Categories}"/>
|
||||
Value="{DynamicResource FontColor.Menu.Categories}" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=Border}, Path=IsMouseOver}"
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=Border}, Path=IsMouseOver}"
|
||||
Value="True">
|
||||
<Setter Property="PrimaryIconColor"
|
||||
Value="{DynamicResource FontColor.Menu.Categories.Hover}"/>
|
||||
<Setter Property="PrimaryIconColor"
|
||||
Value="{DynamicResource Color.FunctionMarker}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ico:AdaptableIcon.Resources>
|
||||
</ico:AdaptableIcon>
|
||||
|
||||
<TextBlock Grid.Column="2" Text="Pause">
|
||||
<TextBlock Grid.Column="2"
|
||||
Text="Pause">
|
||||
<TextBlock.Resources>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center"/>
|
||||
Value="Center" />
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Center"/>
|
||||
Value="Center" />
|
||||
<Setter Property="FontSize"
|
||||
Value="16"/>
|
||||
Value="16" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource FontColor.Menu.Categories}"/>
|
||||
Value="{DynamicResource FontColor.Menu.Categories}" />
|
||||
<Setter Property="Margin"
|
||||
Value="0 0 0 2"/>
|
||||
Value="0 0 0 2" />
|
||||
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=Border}, Path=IsMouseOver}"
|
||||
Value="True">
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource FontColor.Menu.Categories.Hover}"/>
|
||||
Value="{DynamicResource Color.FunctionMarker}" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
@@ -15,18 +15,18 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
public event EventHandler<EventArgs> OnPauseStarted;
|
||||
|
||||
private static List<DateTime> startTimes = new List<DateTime>();
|
||||
private static List<DateTime> endTimes = new List<DateTime>();
|
||||
private static List<DateTime> pausedTimesStart = new List<DateTime>();
|
||||
private static List<DateTime> pausedTimesEnd = new List<DateTime>();
|
||||
private static readonly List<DateTime> _startTimes = new List<DateTime>();
|
||||
private static readonly List<DateTime> _endTimes = new List<DateTime>();
|
||||
private static readonly List<DateTime> _pausedTimesStart = new List<DateTime>();
|
||||
private static readonly List<DateTime> _pausedTimesEnd = new List<DateTime>();
|
||||
|
||||
public static List<cF4SDCaseTime> caseTimes = new List<cF4SDCaseTime>();
|
||||
private static Dictionary<string, object> finalWorkingTimes = new Dictionary<string, object>();
|
||||
public static List<cF4SDCaseTime> CaseTimes = new List<cF4SDCaseTime>();
|
||||
private static Dictionary<string, object> _finalWorkingTimes = new Dictionary<string, object>();
|
||||
|
||||
private static DispatcherTimer timer;
|
||||
private static TimeSpan elapsedTime;
|
||||
private static TimeSpan totalPausedTime = TimeSpan.Zero;
|
||||
private static TimeSpan pauseDuration;
|
||||
private static DispatcherTimer _timer;
|
||||
private static TimeSpan _elapsedTime;
|
||||
private static TimeSpan _totalPausedTime = TimeSpan.Zero;
|
||||
private static TimeSpan _pauseDuration;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -39,13 +39,13 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
|
||||
public static void ResetTimer()
|
||||
{
|
||||
startTimes.Clear();
|
||||
endTimes.Clear();
|
||||
pausedTimesEnd.Clear();
|
||||
pausedTimesStart.Clear();
|
||||
finalWorkingTimes.Clear();
|
||||
elapsedTime = TimeSpan.Zero;
|
||||
caseTimes.Clear();
|
||||
_startTimes.Clear();
|
||||
_endTimes.Clear();
|
||||
_pausedTimesEnd.Clear();
|
||||
_pausedTimesStart.Clear();
|
||||
_finalWorkingTimes.Clear();
|
||||
_elapsedTime = TimeSpan.Zero;
|
||||
CaseTimes.Clear();
|
||||
|
||||
StartTimer();
|
||||
}
|
||||
@@ -54,8 +54,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
try
|
||||
{
|
||||
startTimes?.Add(DateTime.UtcNow);
|
||||
timer?.Start();
|
||||
_startTimes?.Add(DateTime.UtcNow);
|
||||
_timer?.Start();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -67,8 +67,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
try
|
||||
{
|
||||
endTimes?.Add(DateTime.UtcNow);
|
||||
timer?.Stop();
|
||||
_endTimes?.Add(DateTime.UtcNow);
|
||||
_timer?.Stop();
|
||||
UpdateTimerControl();
|
||||
}
|
||||
catch (Exception E)
|
||||
@@ -83,7 +83,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
ResetTimer();
|
||||
|
||||
timer = new DispatcherTimer(TimeSpan.FromSeconds(1.0), DispatcherPriority.Loaded, new EventHandler((s, args) =>
|
||||
_timer = new DispatcherTimer(TimeSpan.FromSeconds(1.0), DispatcherPriority.Loaded, new EventHandler((s, args) =>
|
||||
{
|
||||
try { UpdateTimerControl(); }
|
||||
catch { }
|
||||
@@ -100,8 +100,8 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
try
|
||||
{
|
||||
TimerControl.Text = elapsedTime.ToString(@"hh\:mm\:ss");
|
||||
elapsedTime = elapsedTime.Add(TimeSpan.FromSeconds(1.0));
|
||||
TimerControl.Text = _elapsedTime.ToString(@"hh\:mm\:ss");
|
||||
_elapsedTime = _elapsedTime.Add(TimeSpan.FromSeconds(1.0));
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -113,44 +113,44 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
try
|
||||
{
|
||||
var currentDate = DateTime.Now.Date.ToString("d");
|
||||
var startDateTime = startTimes.First();
|
||||
var currentDate = DateTime.UtcNow.Date.ToString("d");
|
||||
var startDateTime = _startTimes.First();
|
||||
var endDateTime = DateTime.UtcNow;
|
||||
var bruttoWorkingTime = TimeSpan.Zero;
|
||||
var nettoWorkingTime = TimeSpan.Zero;
|
||||
|
||||
if (pausedTimesStart.Count == 0)
|
||||
if (_pausedTimesStart.Count == 0)
|
||||
{
|
||||
totalPausedTime = TimeSpan.Zero;
|
||||
_totalPausedTime = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
if (pausedTimesEnd.Count > 0)
|
||||
if (_pausedTimesEnd.Count > 0)
|
||||
{
|
||||
totalPausedTime = TimeSpan.Zero;
|
||||
_totalPausedTime = TimeSpan.Zero;
|
||||
|
||||
for (int i = 0; i < pausedTimesStart.Count; i++)
|
||||
for (int i = 0; i < _pausedTimesStart.Count; i++)
|
||||
{
|
||||
var start = pausedTimesStart[i];
|
||||
var end = pausedTimesEnd[i];
|
||||
var start = _pausedTimesStart[i];
|
||||
var end = _pausedTimesEnd[i];
|
||||
|
||||
pauseDuration = end - start;
|
||||
_pauseDuration = end - start;
|
||||
|
||||
totalPausedTime += pauseDuration;
|
||||
_totalPausedTime += _pauseDuration;
|
||||
}
|
||||
}
|
||||
|
||||
bruttoWorkingTime = endDateTime - startDateTime;
|
||||
|
||||
nettoWorkingTime = bruttoWorkingTime - totalPausedTime;
|
||||
nettoWorkingTime = bruttoWorkingTime - _totalPausedTime;
|
||||
|
||||
finalWorkingTimes = new Dictionary<string, object>()
|
||||
_finalWorkingTimes = new Dictionary<string, object>()
|
||||
{
|
||||
{"CurrentDate", currentDate},
|
||||
{"StartTime", startTimes.First()},
|
||||
{"StartTime", _startTimes.First()},
|
||||
{"EndTime", endDateTime },
|
||||
{"BruttoWorkingTime", bruttoWorkingTime },
|
||||
{"NettoWorkingTime", nettoWorkingTime.TotalSeconds },
|
||||
{"TotalPausedTime", totalPausedTime }
|
||||
{"TotalPausedTime", _totalPausedTime }
|
||||
};
|
||||
}
|
||||
catch (Exception E)
|
||||
@@ -158,7 +158,7 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return finalWorkingTimes;
|
||||
return _finalWorkingTimes;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -169,13 +169,13 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
try
|
||||
{
|
||||
if (timer?.IsEnabled == true)
|
||||
if (_timer?.IsEnabled == true)
|
||||
return;
|
||||
|
||||
timer?.Start();
|
||||
pausedTimesEnd?.Add(DateTime.UtcNow);
|
||||
_timer?.Start();
|
||||
_pausedTimesEnd?.Add(DateTime.UtcNow);
|
||||
|
||||
caseTimes.Add(new cF4SDCaseTime()
|
||||
CaseTimes.Add(new cF4SDCaseTime()
|
||||
{
|
||||
StatusId = CaseStatus.InProgress,
|
||||
CaseTime = DateTime.UtcNow
|
||||
@@ -191,10 +191,10 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
{
|
||||
try
|
||||
{
|
||||
timer?.Stop();
|
||||
pausedTimesStart?.Add(DateTime.UtcNow);
|
||||
_timer?.Stop();
|
||||
_pausedTimesStart?.Add(DateTime.UtcNow);
|
||||
|
||||
caseTimes.Add(new cF4SDCaseTime()
|
||||
CaseTimes.Add(new cF4SDCaseTime()
|
||||
{
|
||||
StatusId = CaseStatus.OnHold,
|
||||
CaseTime = DateTime.UtcNow
|
||||
@@ -209,17 +209,9 @@ namespace FasdDesktopUi.Basics.UserControls
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
PauseButton_Click();
|
||||
}
|
||||
private void Border_Click(object sender, InputEventArgs e)
|
||||
=> PauseButton_Click();
|
||||
|
||||
#endregion
|
||||
|
||||
private void Border_TouchDown(object sender, TouchEventArgs e)
|
||||
{
|
||||
PauseButton_Click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
using C4IT.F4SD.DisplayFormatting;
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.MultiLanguage;
|
||||
using F4SD_AdaptableIcon.Enums;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UserControls;
|
||||
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -362,7 +360,7 @@ namespace FasdDesktopUi.Basics
|
||||
try
|
||||
{
|
||||
FormattingOptions options = new FormattingOptions() { ReferenceDate = DateTime.UtcNow.AddDays(_v.ReferenceDays), TimeZone = TimeZoneInfo.Local };
|
||||
RawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
RawValueFormatter.SetDefaultCulture(cFasdCockpitConfig.Instance.SelectedCulture);
|
||||
RawValueFormatter.SetDefaultTimeZone(TimeZoneInfo.Local);
|
||||
|
||||
var _strVal = RawValueFormatter.GetDisplayValue(_v.Value, _v.StateDefinition.DisplayType, options);
|
||||
@@ -468,5 +466,11 @@ namespace FasdDesktopUi.Basics
|
||||
|
||||
#endregion
|
||||
|
||||
public static string GetShortDatePattern()
|
||||
{
|
||||
string datePattern = cFasdCockpitConfig.Instance.SelectedCulture.DateTimeFormat.ShortDatePattern;
|
||||
datePattern = Regex.Replace(datePattern, @"(^|[/.\-\s])y{1,4}($|[/.\-\s]?)", "");
|
||||
return datePattern.Trim('/', '.', '-', ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user