diff --git a/FasdDesktopUi/Basics/Helper/TicketDeepLinkHelper.cs b/FasdDesktopUi/Basics/Helper/TicketDeepLinkHelper.cs index a712e0a..a28f450 100644 --- a/FasdDesktopUi/Basics/Helper/TicketDeepLinkHelper.cs +++ b/FasdDesktopUi/Basics/Helper/TicketDeepLinkHelper.cs @@ -1,85 +1,142 @@ using System; +using System.Collections.Generic; 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 bool TryOpenTicketRelationExternally(cF4sdApiSearchResultRelation relation) - { - try - { - if (relation == null || relation.Type != enumF4sdSearchResultClass.Ticket) - return false; - - var ticketConfig = cFasdCockpitConfig.Instance?.Global?.TicketConfiguration; - if (ticketConfig == null) - return false; - - var isIncident = IsIncidentRelation(relation, out var activityType); - var openExternally = isIncident - ? ticketConfig.OpenIncidentsExternally - : ticketConfig.OpenTicketsExternally; +using FasdDesktopUi.Basics; +using static C4IT.Logging.cLogManager; + +namespace FasdDesktopUi.Basics.Helper +{ + internal static class TicketDeepLinkHelper + { + internal static bool TryOpenTicketRelationExternally(cF4sdApiSearchResultRelation relation) + { + try + { + if (relation == null || relation.Type != enumF4sdSearchResultClass.Ticket) + return false; + + var ticketConfig = cFasdCockpitConfig.Instance?.Global?.TicketConfiguration; + if (ticketConfig == null) + 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)) + if (string.IsNullOrWhiteSpace(url)) + return false; + + new cBrowsers().Start("default", url); + return true; + } + 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 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; - new cBrowsers().Start("default", url); return true; } - catch (Exception ex) - { - LogException(ex); - } return false; } - internal static bool IsIncidentRelation(cF4sdApiSearchResultRelation relation, out string activityType) + private static bool TryParseBool(string value, out bool result) { - activityType = null; - - if (relation?.Infos != null && relation.Infos.TryGetValue("ActivityType", out var activityTypeValue)) - activityType = activityTypeValue; - - if (string.IsNullOrWhiteSpace(activityType)) + result = false; + if (string.IsNullOrWhiteSpace(value)) return false; - return activityType.IndexOf("Incident", StringComparison.OrdinalIgnoreCase) >= 0; - } - - internal static string BuildTicketDeepLink(Guid ticketId, string activityType) - { - 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)) + switch (value.Trim().ToLowerInvariant()) { - baseUrl = "https://" + baseUrl; + 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); } - if (!baseUrl.EndsWith("/wm", StringComparison.OrdinalIgnoreCase)) - baseUrl += "/wm"; - - if (string.IsNullOrWhiteSpace(activityType)) - return null; - - var viewOptionsJson = $"{{\"embedded\":false,\"objectId\":\"{ticketId}\",\"type\":\"{activityType}\",\"viewType\":\"preview\",\"archived\":0}}"; - var viewOptionsEncoded = Uri.EscapeDataString(viewOptionsJson); - - return $"{baseUrl}/app-ServiceDesk/?view-options={viewOptionsEncoded}"; } - } -} + + internal static string BuildTicketDeepLink(Guid ticketId, string activityType) + { + 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)) + { + baseUrl = "https://" + baseUrl; + } + if (!baseUrl.EndsWith("/wm", StringComparison.OrdinalIgnoreCase)) + baseUrl += "/wm"; + + if (string.IsNullOrWhiteSpace(activityType)) + return null; + + var viewOptionsJson = $"{{\"embedded\":false,\"objectId\":\"{ticketId}\",\"type\":\"{activityType}\",\"viewType\":\"preview\",\"archived\":0}}"; + var viewOptionsEncoded = Uri.EscapeDataString(viewOptionsJson); + + return $"{baseUrl}/app-ServiceDesk/?view-options={viewOptionsEncoded}"; + } + } +} diff --git a/FasdDesktopUi/Basics/Services/SupportCase/SupportCase.cs b/FasdDesktopUi/Basics/Services/SupportCase/SupportCase.cs index b6dec9b..671aedc 100644 --- a/FasdDesktopUi/Basics/Services/SupportCase/SupportCase.cs +++ b/FasdDesktopUi/Basics/Services/SupportCase/SupportCase.cs @@ -140,8 +140,8 @@ namespace FasdDesktopUi.Basics.Services.SupportCase { return tablesToLoad.All(t => _rawDataCache.TryGetValue(relation, out var cachedRawData) - && cachedRawData.Tables.TryGetValue(t, out var cachedTable) - && !cachedTable.IsIncomplete && !cachedTable.Columns.Values.Any(c => c.IsIncomplete) + && (cachedRawData?.Tables?.TryGetValue(t, out var cachedTable) ?? false) + && cachedTable != null && !cachedTable.IsIncomplete && !cachedTable.Columns.Values.Any(c => c.IsIncomplete) ); } diff --git a/FasdDesktopUi/Basics/SupportCaseDataProvider.cs b/FasdDesktopUi/Basics/SupportCaseDataProvider.cs index c7c57de..92b0610 100644 --- a/FasdDesktopUi/Basics/SupportCaseDataProvider.cs +++ b/FasdDesktopUi/Basics/SupportCaseDataProvider.cs @@ -237,7 +237,7 @@ namespace FasdDesktopUi.Basics if (relationToFocus is null) return selectedRelation; - relationToFocus.Identities = selectedRelation.Identities; + relationToFocus.Identities = selectedRelation.Identities.Clone(); return relationToFocus; } catch (Exception ex) @@ -672,7 +672,6 @@ namespace FasdDesktopUi.Basics ComputerRemoved |= relationIdentity.Class == enumFasdInformationClass.Computer; ComputerAdded |= relationIdentity.Class == enumFasdInformationClass.Computer; } - relationIdentity.CopyTo(existingIdentity); } } diff --git a/FasdDesktopUi/Config/LanguageDefinitions.xml b/FasdDesktopUi/Config/LanguageDefinitions.xml index 962fad5..3df34b6 100644 --- a/FasdDesktopUi/Config/LanguageDefinitions.xml +++ b/FasdDesktopUi/Config/LanguageDefinitions.xml @@ -153,7 +153,7 @@ User is not authorized for Cockpit usage - Nutzer ist nicht für die Cockpit-Nutzung authorisiert + Nutzer ist nicht für die Cockpit-Nutzung autorisiert @@ -280,7 +280,7 @@ Not authorized - Nicht authorisiert + Nicht autorisiert