Compare commits

...

10 Commits

Author SHA1 Message Date
Meik
9f2c3fefc1 aktueller Stand 2026-02-23 15:10:44 +01:00
Meik
1b9a1260f0 Align ticket overview availability with search authorization status 2026-02-23 13:44:13 +01:00
Meik
1215cadd6c revert badge sparkle effect 2026-02-20 16:24:08 +01:00
Meik
485a209a26 git push Merge branch 'bugfix/esc-ticketdropdown-hang' 2026-02-20 16:21:02 +01:00
Meik
e154353af8 bugfix dropdown closing by ESC 2026-02-20 16:15:28 +01:00
Meik
234eacaecf Fix ESC handling in ticket completion dropdowns 2026-02-20 14:55:35 +01:00
Meik
dd0e7bdc99 bugfixing sid deeplink 2026-02-20 14:36:47 +01:00
Meik
e6968e29eb aktueller stand 2026-02-19 13:22:30 +01:00
Meik
610e479e69 diff 2026-02-19 11:20:53 +01:00
Meik
b132755215 aktueller stand 2026-02-13 11:32:06 +01:00
33 changed files with 5884 additions and 5035 deletions

View File

@@ -47,7 +47,7 @@ namespace C4IT.FASD.Cockpit.Communication
public abstract Task<bool> KeepAliveSession(Guid sessionId); public abstract Task<bool> KeepAliveSession(Guid sessionId);
public abstract Task<bool> ReportQuickAction(cF4SDQuickActionParameters quickActionParameters); public abstract Task<bool> ReportQuickAction(cF4SDQuickActionParameters quickActionParameters);
public abstract Task<cCollectorStatusInfo> CheckCollectorStatusAsync();
public static bool Debug_apiValues = false; public static bool Debug_apiValues = false;
public static bool Debug_apiTiming = false; public static bool Debug_apiTiming = false;

View File

@@ -25,6 +25,7 @@ using Newtonsoft.Json.Linq;
using static C4IT.Logging.cLogManager; using static C4IT.Logging.cLogManager;
using C4IT.Configuration; using C4IT.Configuration;
using System.Runtime.InteropServices.WindowsRuntime;
namespace C4IT.FASD.Cockpit.Communication namespace C4IT.FASD.Cockpit.Communication
{ {
@@ -566,6 +567,38 @@ namespace C4IT.FASD.Cockpit.Communication
return false; return false;
} }
public override async Task<cCollectorStatusInfo> CheckCollectorStatusAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
var apiError = 0;
var timeStart = DateTime.UtcNow;
try
{
var http = GetHttpHelper(false);
var result = await http.GetHttpJson("api/CheckCollectorStatus", 15000, CancellationToken.None);
if (!result.IsOk)
{
apiError = (int)result.Status;
return null;
}
var strXml = JsonConvert.DeserializeObject<cCollectorStatusInfo>(result.Result);
return strXml;
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (Debug_apiTiming) SaveApiTimingEntry("Check Collector Status", timeStart, apiError);
LogMethodEnd(CM);
}
return null;
}
public override async Task<cFasdBaseConfig> GetConfiguration(enumFasdConfigurationType configType) public override async Task<cFasdBaseConfig> GetConfiguration(enumFasdConfigurationType configType)
{ {
@@ -2124,6 +2157,6 @@ namespace C4IT.FASD.Cockpit.Communication
return null; return null;
} }
} }
} }

View File

@@ -1862,5 +1862,9 @@ namespace C4IT.FASD.Cockpit.Communication
return null; return null;
} }
public override Task<cCollectorStatusInfo> CheckCollectorStatusAsync()
{
throw new NotImplementedException();
}
} }
} }

View File

@@ -0,0 +1,472 @@
{
"TicketsNew": {
"Personal": [
{
"TicketId": "2e9cb83d-ecb7-c93b-e8e4-08daaa97265f",
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
"DisplayName": "TCK00186",
"Summary": "Mein OneDrive synchronisiert nicht mehr",
"UserDisplayName": "Ticket, Timo",
"UserAccount": "TT007",
"UserDomain": "CONTOSO",
"StatusId": "New"
}
],
"Role": [
{
"TicketId": "bb2e4a9d-2c1e-4b32-8f75-6e7c9f99f2d4",
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
"DisplayName": "TCK00761",
"Summary": "VPN-Verbindung bricht nach wenigen Minuten ab",
"UserDisplayName": "Ticket, Timo",
"UserAccount": "TT007",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "d63e5ea1-0785-4998-82ad-9a9e5a0f8c37",
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
"DisplayName": "TCK00765",
"Summary": "Teams-Benachrichtigungen kommen verzögert an",
"UserDisplayName": "Ticket, Timo",
"UserAccount": "TT007",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "f7771fde-33ba-421a-8d9b-cdf468e7541c",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "TCK00403",
"Summary": "Neuer Monitor fuer Hotline Arbeitsplatz",
"UserDisplayName": "Busch, Andrea",
"UserAccount": "AB014",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "6294eec7-fb80-42f3-8ce8-7f7982ae200c",
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
"DisplayName": "TCK00404",
"Summary": "Monitor flackert seit Firmware Update",
"UserDisplayName": "Anwender, Peter",
"UserAccount": "PA010",
"UserDomain": "CONTOSO",
"StatusId": "New"
}
]
},
"TicketsActive": {
"Personal": [
{
"TicketId": "75e08a29-4103-41d6-962c-009c3342bc46",
"UserId": "6180aa17-ba2d-455a-bf2f-ec4a075c2d64",
"DisplayName": "TCK00406",
"Summary": "CAD Software startet nach Update nicht mehr",
"UserDisplayName": "Kohl, Carlos",
"UserAccount": "CK102",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
],
"Role": [
{
"TicketId": "2e9cb83d-ecb7-c93b-e8e4-08daaa97265f",
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
"DisplayName": "TCK00405",
"Summary": "OneDrive Synchronisation bleibt haengen",
"UserDisplayName": "Ticket, Timo",
"UserAccount": "TT007",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "ff62a3e2-5004-4a8c-b71c-7ebb1877d1a4",
"UserId": "0fad5e21-5a29-44c6-b532-46f862ea8694",
"DisplayName": "TCK00407",
"Summary": "Netzlaufwerk Projekt X nicht erreichbar",
"UserDisplayName": "Hanova, Hans",
"UserAccount": "HH101",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
]
},
"TicketsCritical": {
"Personal": [
{
"TicketId": "1507691c-6d47-4ae3-83b3-ef483d84a246",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "TCK00408",
"Summary": "VPN Konzentrator in Aussenstelle offline",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "5c6d981e-9e67-4fde-b249-8c6288d325a7",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "TCK00409",
"Summary": "SAP Produktionsauftrag bricht ab",
"UserDisplayName": "Boss, Bernd",
"UserAccount": "BB003",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
],
"Role": [
{
"TicketId": "1507691c-6d47-4ae3-83b3-ef483d84a246",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "TCK00408",
"Summary": "VPN Konzentrator in Aussenstelle offline",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "9b7710d4-72da-4b2a-9d0c-be02575d2c52",
"UserId": "a2c35ad1-7cc7-4b2b-9aa5-d03fdaecd155",
"DisplayName": "TCK00410",
"Summary": "WLAN im Lager faellt minutenweise aus",
"UserDisplayName": "Kiefer, Maximilian",
"UserAccount": "MK009",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "5c6d981e-9e67-4fde-b249-8c6288d325a7",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "TCK00409",
"Summary": "SAP Produktionsauftrag bricht ab",
"UserDisplayName": "Boss, Bernd",
"UserAccount": "BB003",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
]
},
"TicketsNewInfo": {
"Personal": [
{
"TicketId": "de403992-98cb-4476-9e04-d645ab22e6de",
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
"DisplayName": "TCK00411",
"Summary": "Rueckfrage zur Passwort Ruecksetzung beantworten",
"UserDisplayName": "Ticket, Timo",
"UserAccount": "TT007",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
},
{
"TicketId": "7c29dd33-1247-453c-9db6-f7a59107d276",
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
"DisplayName": "TCK00412",
"Summary": "Techniker bittet um Rueckmeldung zum Notebook",
"UserDisplayName": "Anwender, Peter",
"UserAccount": "PA010",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
}
],
"Role": [
{
"TicketId": "de403992-98cb-4476-9e04-d645ab22e6de",
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
"DisplayName": "TCK00411",
"Summary": "Rueckfrage zur Passwort Ruecksetzung beantworten",
"UserDisplayName": "Ticket, Timo",
"UserAccount": "TT007",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
},
{
"TicketId": "b207822d-7e1c-42a7-b8c9-4246f711dd18",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "TCK00413",
"Summary": "Wartungsfenster fuer Firewall verschieben",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
}
]
},
"IncidentNew": {
"Personal": [
{
"TicketId": "e0ba7c81-f9b1-4e99-a4d6-efecc5e4312e",
"UserId": "f69dd1a9-591f-4004-b950-264238663bf0",
"DisplayName": "INC00401",
"Summary": "Teams Telefonie ist fuer Standort Sued offline",
"UserDisplayName": "Ottmann, Thomas",
"UserAccount": "TO011",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "a8deb50d-9f15-4371-9ebc-a28791f27d5c",
"UserId": "76f86d28-862c-4fa2-9062-8367be7fbd92",
"DisplayName": "INC00402",
"Summary": "SharePoint Bereich Vertrieb laedt extrem langsam",
"UserDisplayName": "Virtual, Vera",
"UserAccount": "VV004",
"UserDomain": "CONTOSO",
"StatusId": "New"
}
],
"Role": [
{
"TicketId": "fe15284f-f553-4434-8b59-7d8b9f481bf7",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "INC00403",
"Summary": "Firewall Cluster meldet Sync Fehler",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "9cdddacf-9395-476b-811a-09c5f1491d4b",
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
"DisplayName": "INC00404",
"Summary": "CRM Anmeldung liefert Timeout fuer Kundencenter",
"UserDisplayName": "Anwender, Peter",
"UserAccount": "PA010",
"UserDomain": "CONTOSO",
"StatusId": "New"
}
]
},
"IncidentActive": {
"Personal": [
{
"TicketId": "7e852bb9-420b-4caa-b79a-9178d793fc06",
"UserId": "a2c35ad1-7cc7-4b2b-9aa5-d03fdaecd155",
"DisplayName": "INC00405",
"Summary": "Windows Rollout haengt auf mehreren Clients",
"UserDisplayName": "Kiefer, Maximilian",
"UserAccount": "MK009",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "3c3c70cf-5c60-4ecc-9313-b5f9c1968fc7",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "INC00406",
"Summary": "Remotedesktop Sitzung trennt nach wenigen Minuten",
"UserDisplayName": "Busch, Andrea",
"UserAccount": "AB014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
],
"Role": [
{
"TicketId": "486df93d-15b6-41d4-b902-2c1e1838c74b",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "INC00407",
"Summary": "Firewall Cluster meldet weiterhin Sync Fehler",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "86da28b0-013b-4542-bcff-175044d5bb02",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "INC00408",
"Summary": "Produktionslinie meldet keine Sensordaten",
"UserDisplayName": "Zufall, Rainer",
"UserAccount": "RZ011",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "a1cf6635-a5c4-4401-b4f0-60b9c65b4d75",
"UserId": "0fad5e21-5a29-44c6-b532-46f862ea8694",
"DisplayName": "INC00409",
"Summary": "Exchange Transportdienst setzt Mails in Warteschlange",
"UserDisplayName": "Hanova, Hans",
"UserAccount": "HH101",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
]
},
"IncidentCritical": {
"Personal": [
{
"TicketId": "9aae7eca-39d7-441e-8b33-5fc6f34765c8",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "INC00410",
"Summary": "Kuehlung im Rechenzentrum U3 ausgefallen",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
],
"Role": [
{
"TicketId": "9aae7eca-39d7-441e-8b33-5fc6f34765c8",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "INC00410",
"Summary": "Kuehlung im Rechenzentrum U3 ausgefallen",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "130ec52f-dac3-427d-803e-e7cf67e4a744",
"UserId": "f69dd1a9-591f-4004-b950-264238663bf0",
"DisplayName": "INC00411",
"Summary": "Kartenzahlung in den Filialen nicht moeglich",
"UserDisplayName": "Ottmann, Thomas",
"UserAccount": "TO011",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "b7d22b65-c11e-459c-ac31-5b1c08e4118d",
"UserId": "8c3ca0fb-f18c-4893-ad83-290e6e02f352",
"DisplayName": "INC00412",
"Summary": "Datenbank Cluster benoetigt manuellen Failover",
"UserDisplayName": "Perschmann, Paul",
"UserAccount": "PP201",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
]
},
"IncidentNewInfo": {
"Personal": [
{
"TicketId": "d1a2c544-4f59-4f2b-875f-3621a23d4228",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "INC00413",
"Summary": "Backup Team hat Rueckfrage zur Sicherung",
"UserDisplayName": "Busch, Andrea",
"UserAccount": "AB014",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
}
],
"Role": [
{
"TicketId": "74846c1b-9a97-420f-8bf2-91e88aa0516a",
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
"DisplayName": "INC00415",
"Summary": "Lieferant bittet um Rueckmeldung zu Offsite Backup",
"UserDisplayName": "Anwender, Peter",
"UserAccount": "PA010",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
},
{
"TicketId": "1372b3cf-5d87-4099-ab83-ec0cccf7194e",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "INC00416",
"Summary": "Fernwartung benoetigt Zugangsdaten zur SPS",
"UserDisplayName": "Zufall, Rainer",
"UserAccount": "RZ011",
"UserDomain": "CONTOSO",
"StatusId": "OnHold"
}
]
},
"UnassignedTickets": {
"Personal": [
{
"TicketId": "e2e49f85-1a81-47e8-935b-d76898c155f6",
"UserId": "76f86d28-862c-4fa2-9062-8367be7fbd92",
"DisplayName": "TCK00414",
"Summary": "Pool Notebook fuer Schulungsteilnehmer fehlt",
"UserDisplayName": "Virtual, Vera",
"UserAccount": "VV004",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "ebe8818e-b197-411e-b56e-40b77b623ae2",
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
"DisplayName": "TCK00415",
"Summary": "Etikettendrucker im Lager meldet Papierstau",
"UserDisplayName": "Anwender, Peter",
"UserAccount": "PA010",
"UserDomain": "CONTOSO",
"StatusId": "New"
}
],
"Role": [
{
"TicketId": "e2e49f85-1a81-47e8-935b-d76898c155f6",
"UserId": "76f86d28-862c-4fa2-9062-8367be7fbd92",
"DisplayName": "TCK00414",
"Summary": "Pool Notebook fuer Schulungsteilnehmer fehlt",
"UserDisplayName": "Virtual, Vera",
"UserAccount": "VV004",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "ebe8818e-b197-411e-b56e-40b77b623ae2",
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
"DisplayName": "TCK00415",
"Summary": "Etikettendrucker im Lager meldet Papierstau",
"UserDisplayName": "Anwender, Peter",
"UserAccount": "PA010",
"UserDomain": "CONTOSO",
"StatusId": "New"
},
{
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "TCK00416",
"Summary": "Ueberwachung meldet sporadische Alarme",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "New"
}
]
},
"UnassignedTicketsCritical": {
"Personal": [
{
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "TCK00416",
"Summary": "Ueberwachung meldet sporadische Alarme",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
],
"Role": [
{
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
"DisplayName": "TCK00416",
"Summary": "Ueberwachung meldet sporadische Alarme",
"UserDisplayName": "Seifert, Dominik",
"UserAccount": "DS014",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
},
{
"TicketId": "d427dc61-9842-4464-b37a-612878d3de0f",
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
"DisplayName": "TCK00417",
"Summary": "Produktionsroboter steht nach Not Aus",
"UserDisplayName": "Boss, Bernd",
"UserAccount": "BB003",
"UserDomain": "CONTOSO",
"StatusId": "InProgress"
}
]
}
}

View File

@@ -48,7 +48,7 @@ namespace FasdCockpitCommunicationDemo
public string Description { get; set; } public string Description { get; set; }
public string DescriptionHtml { get; set; } public string DescriptionHtml { get; set; }
public int Priority { get; set; } public int Priority { get; set; }
public string Category { get; set; } //todo: replace with tree structure public string Category { get; set; }
public string ActivityType { get; set; } public string ActivityType { get; set; }
public string Solution { get; set; } public string Solution { get; set; }
public string SolutionHtml { get; set; } public string SolutionHtml { get; set; }

View File

@@ -0,0 +1,16 @@
using System;
namespace FasdCockpitCommunicationDemo
{
public class TicketOverviewRelationDefinition
{
public Guid TicketId { get; set; }
public Guid UserId { get; set; }
public string DisplayName { get; set; }
public string Summary { get; set; }
public string StatusId { get; set; }
public string UserDisplayName { get; set; }
public string UserAccount { get; set; }
public string UserDomain { get; set; }
}
}

View File

@@ -669,11 +669,11 @@ namespace FasdDesktopUi
{ {
userInfo = cFasdCockpitCommunicationBase.CockpitUserInfo; userInfo = cFasdCockpitCommunicationBase.CockpitUserInfo;
} }
if (!string.IsNullOrEmpty(cCockpitConfiguration.Instance?.m42ServerConfiguration?.Server)) if (cFasdCockpitConfig.Instance.HasM42Configuration())
if (userInfo?.possibleLogons != null) if (userInfo?.possibleLogons != null)
{ {
if (userInfo.possibleLogons.Contains(enumAdditionalAuthentication.M42WinLogon)) if (userInfo.possibleLogons.Contains(enumAdditionalAuthentication.M42WinLogon))
{ {
if (App.M42OptionMenuItem != null) if (App.M42OptionMenuItem != null)
{ {
App.M42OptionMenuItem.Visible = true; App.M42OptionMenuItem.Visible = true;

View File

@@ -110,6 +110,9 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
{ {
try try
{ {
if (_focusedRelation == relation)
return;
_selectedHealthcard = _supportCaseProcessor.GetHealthcardFor(relation); _selectedHealthcard = _supportCaseProcessor.GetHealthcardFor(relation);
HashSet<string> requiredTables = cHealthCard.GetRequiredTables(_selectedHealthcard); HashSet<string> requiredTables = cHealthCard.GetRequiredTables(_selectedHealthcard);
_ = Task.Run(async () => await _supportCaseProcessor.LoadSupportCaseDataAsync(relation, requiredTables)); _ = Task.Run(async () => await _supportCaseProcessor.LoadSupportCaseDataAsync(relation, requiredTables));

View File

@@ -16,6 +16,8 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
private readonly Dictionary<string, Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData.cHealthCardTable>> _supportCaseDataCache = new Dictionary<string, Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData.cHealthCardTable>>(); private readonly Dictionary<string, Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData.cHealthCardTable>> _supportCaseDataCache = new Dictionary<string, Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData.cHealthCardTable>>();
private readonly Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData> _rawDataCache = new Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData>(); // todo remove, currently only used for SupportCaseDataProviderArtifact private readonly Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData> _rawDataCache = new Dictionary<cF4sdApiSearchResultRelation, cF4SDHealthCardRawData>(); // todo remove, currently only used for SupportCaseDataProviderArtifact
private readonly ICollection<cF4sdApiSearchResultRelation> _relationsCurrentlyLoadingData = new HashSet<cF4sdApiSearchResultRelation>();
internal readonly Guid Id; internal readonly Guid Id;
private readonly IRelationService _relationService; private readonly IRelationService _relationService;
public cSupportCaseDataProvider SupportCaseDataProviderArtifact { get; } public cSupportCaseDataProvider SupportCaseDataProviderArtifact { get; }
@@ -65,19 +67,18 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
if (relations is null) if (relations is null)
return; return;
foreach (var relationType in relations) foreach (var relationType in relations)
{ {
//TODO Max fragen obs passt! Bug: in den Ticketrelations (Header Ticketauswahl) sind nur zwei Tickets sichtbar anstatt 5 oder mehr.. if (_caseRelations.TryGetValue(relationType.Key, out var caseRelation))
if (_caseRelations.TryGetValue(relationType.Key, out var caseRelation)) caseRelation = caseRelation.Union(relationType).ToList();
_caseRelations[relationType.Key] = caseRelation.Union(relationType).ToList(); else
else _caseRelations.Add(relationType.Key, relationType.ToList());
_caseRelations.Add(relationType.Key, relationType.ToList());
if (SupportCaseDataProviderArtifact?.CaseRelations?.TryGetValue(relationType.Key, out var caseRelations) ?? false)
if (SupportCaseDataProviderArtifact?.CaseRelations?.TryGetValue(relationType.Key, out var caseRelations) ?? false) caseRelations = caseRelations.Union(relationType).ToList();
SupportCaseDataProviderArtifact.CaseRelations[relationType.Key] = caseRelations.Union(relationType).ToList(); else
else SupportCaseDataProviderArtifact?.CaseRelations?.Add(relationType.Key, relationType.ToList());
SupportCaseDataProviderArtifact?.CaseRelations?.Add(relationType.Key, relationType.ToList()); }
}
CaseRelationsAdded?.Invoke(this, new RelationEventArgs() { Relations = relations }); CaseRelationsAdded?.Invoke(this, new RelationEventArgs() { Relations = relations });
} }
@@ -91,6 +92,11 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
{ {
try try
{ {
if (_relationsCurrentlyLoadingData.Contains(relation))
return;
_relationsCurrentlyLoadingData.Add(relation);
cF4SDHealthCardRawData rawData = null; cF4SDHealthCardRawData rawData = null;
// todo this is only a temporary fix. Currently the tablesToLoad contain also detail tables // todo this is only a temporary fix. Currently the tablesToLoad contain also detail tables
@@ -131,11 +137,17 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
.Where(table => table.Key.StartsWith("Computation_") == false) .Where(table => table.Key.StartsWith("Computation_") == false)
.All(table => !table.Value.IsIncomplete && !table.Value.Columns.Values.Any(c => c.IsIncomplete)) ?? false; .All(table => !table.Value.IsIncomplete && !table.Value.Columns.Values.Any(c => c.IsIncomplete)) ?? false;
} }
SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.LastDataRequest = DateTime.Now;
} }
catch (Exception ex) catch (Exception ex)
{ {
LogException(ex); LogException(ex);
} }
finally
{
_relationsCurrentlyLoadingData.Remove(relation);
}
bool IsRawDataCacheComplete() bool IsRawDataCacheComplete()
{ {
@@ -236,12 +248,12 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
table.IsIncomplete = true; table.IsIncomplete = true;
foreach (var column in table.Columns.Values) foreach (var column in table.Columns.Values)
{ {
if (column.Values != null && column.Values.Count > 0) if (column.Values != null && column.Values.Count > 0)
column.Values[0] = null; column.Values[0] = null;
column.IsIncomplete = true; column.IsIncomplete = true;
} }
invalidatedTables.Add(table); invalidatedTables.Add(table);
} }
@@ -253,12 +265,12 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
{ {
table.IsIncomplete = true; table.IsIncomplete = true;
foreach (var column in table.Columns.Values) foreach (var column in table.Columns.Values)
{ {
if (column.Values != null && column.Values.Count > 0) if (column.Values != null && column.Values.Count > 0)
column.Values[0] = null; column.Values[0] = null;
column.IsIncomplete = true; column.IsIncomplete = true;
} }
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -140,6 +140,9 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
{ {
var status = enumActualizeStatus.unknown; var status = enumActualizeStatus.unknown;
if (!agentUserId.HasValue && !agentDeviceId.HasValue)
return status;
try try
{ {
TimeSpan refreshDelay = TimeSpan.FromMilliseconds(500); TimeSpan refreshDelay = TimeSpan.FromMilliseconds(500);

View File

@@ -6,8 +6,7 @@ using System.Windows;
using System.Windows.Documents; using System.Windows.Documents;
using System.Linq; using System.Linq;
using System.Windows.Input; using System.Windows.Input;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Threading;
using C4IT.FASD.Base; using C4IT.FASD.Base;
using C4IT.Logging; using C4IT.Logging;
@@ -103,21 +102,19 @@ namespace FasdDesktopUi.Basics
QuickActionProtocollHelper = new cQuickActionProtocollHelper(this); QuickActionProtocollHelper = new cQuickActionProtocollHelper(this);
} }
public static async Task<cSupportCaseDataProvider> GetDataProviderForAsync(cF4sdApiSearchResultRelation selectedRelation, IRelationService relationService) public static async Task<cSupportCaseDataProvider> GetDataProviderForAsync(cF4sdApiSearchResultRelation selectedRelation, IRelationService relationService)
{ {
try try
{ {
if (selectedRelation == null) if (selectedRelation == null)
{ {
Debug.Assert(true, "The selected relation must not be null here!"); Debug.Assert(true, "The selected relation must not be null here!");
LogEntry("The selected relation must not be null here!", LogLevels.Error); LogEntry("The selected relation must not be null here!", LogLevels.Error);
return null; return null;
} }
await EnsureUserIdentityForTicketAsync(selectedRelation); // get the identities of the selected relation
var Identities = selectedRelation.Identities.Clone();
// get the identities of the selected relation
var Identities = selectedRelation.Identities.Clone();
// get the main indentities from all identites (normally this is the user, in a special case, where a computer was searched and found without any user activities, it could be the computer) // get the main indentities from all identites (normally this is the user, in a special case, where a computer was searched and found without any user activities, it could be the computer)
var MainIdentity = Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.User); var MainIdentity = Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.User);
@@ -152,17 +149,15 @@ namespace FasdDesktopUi.Basics
cSupportCaseDataProvider.CurrentProvider = null; cSupportCaseDataProvider.CurrentProvider = null;
} }
if (!DataProviders.TryGetValue(MainIdentity.Id, out var _result)) if (!DataProviders.TryGetValue(MainIdentity.Id, out var _result))
{ {
_result = new cSupportCaseDataProvider(); _result = new cSupportCaseDataProvider();
DataProviders.Add(MainIdentity.Id, _result); DataProviders.Add(MainIdentity.Id, _result);
} }
await EnsureSupportCasePagesAsync(); _result.NamedParameterEntries = new cNamedParameterList(_result);
_result.NamedParameterEntries = new cNamedParameterList(_result); _result.StartCase(MainIdentity.Id);
_result.StartCase(MainIdentity.Id);
var supportCase = SupportCaseFactory.Get(MainIdentity, relationService, _result); var supportCase = SupportCaseFactory.Get(MainIdentity, relationService, _result);
var supportCaseProcessor = SupportCaseProcessorFactory.Get(MainIdentity.Id); var supportCaseProcessor = SupportCaseProcessorFactory.Get(MainIdentity.Id);
@@ -171,14 +166,8 @@ namespace FasdDesktopUi.Basics
supportCaseProcessor.SetSupportCase(supportCase); supportCaseProcessor.SetSupportCase(supportCase);
supportCaseController.SetSupportCaseProcessor(supportCaseProcessor, Identities); supportCaseController.SetSupportCaseProcessor(supportCaseProcessor, Identities);
if (cSupportCaseDataProvider.detailsPage == null || cSupportCaseDataProvider.slimPage == null) cSupportCaseDataProvider.detailsPage.SetSupportCaseController(supportCaseController);
{ cSupportCaseDataProvider.slimPage.SetSupportCaseController(supportCaseController);
LogEntry("Support case pages are not initialized; aborting case start.", LogLevels.Error);
return null;
}
cSupportCaseDataProvider.detailsPage.SetSupportCaseController(supportCaseController);
cSupportCaseDataProvider.slimPage.SetSupportCaseController(supportCaseController);
var Status = await _result.SetViewDataAsync(requiredInformationClasses, Identities, true); var Status = await _result.SetViewDataAsync(requiredInformationClasses, Identities, true);
@@ -188,32 +177,25 @@ namespace FasdDesktopUi.Basics
if (!Status) if (!Status)
return null; return null;
var selectedHealthCard = _result.HealthCardDataHelper?.SelectedHealthCard; HashSet<string> requiredTables = cHealthCard.GetRequiredTables(_result.HealthCardDataHelper.SelectedHealthCard); // todo the healthcard is not selected at this point
if (selectedHealthCard != null) detailsPage.WidgetCollection.WidgetDataList = supportCaseController.GetWidgetData();
_ = cHealthCard.GetRequiredTables(selectedHealthCard); // todo the healthcard is not selected at this point detailsPage.DataHistoryCollectionUserControl.HistoryDataList = supportCaseController.GetHistoryData();
detailsPage.CustomizableSectionUc.ContainerCollections = supportCaseController.GetContainerData();
if (detailsPage?.WidgetCollection != null)
detailsPage.WidgetCollection.WidgetDataList = supportCaseController.GetWidgetData();
if (detailsPage?.DataHistoryCollectionUserControl != null)
detailsPage.DataHistoryCollectionUserControl.HistoryDataList = supportCaseController.GetHistoryData();
if (detailsPage?.CustomizableSectionUc != null)
detailsPage.CustomizableSectionUc.ContainerCollections = supportCaseController.GetContainerData();
CurrentProvider = _result; CurrentProvider = _result;
// start the slim or detaild page // start the slim or detaild page
bool shouldSkipSlimView = (Identities?.Any(identity => identity.Class is enumFasdInformationClass.Ticket) ?? false) bool shouldSkipSlimView = Identities.Any(identity => identity.Class is enumFasdInformationClass.Ticket) || cFasdCockpitConfig.Instance.Global.ShouldSkipSlimView;
|| (cFasdCockpitConfig.Instance?.Global?.ShouldSkipSlimView ?? false); if (shouldSkipSlimView)
if (shouldSkipSlimView) {
{ cSupportCaseDataProvider.detailsPage?.Show();
cSupportCaseDataProvider.detailsPage?.Show(); cSupportCaseDataProvider.slimPage.Hide();
cSupportCaseDataProvider.slimPage?.Hide(); }
} else
else {
{ cSupportCaseDataProvider.slimPage.Show();
cSupportCaseDataProvider.slimPage?.Show(); cSupportCaseDataProvider.detailsPage?.Hide();
cSupportCaseDataProvider.detailsPage?.Hide(); }
}
return _result; return _result;
} }
@@ -248,11 +230,11 @@ namespace FasdDesktopUi.Basics
return selectedRelation; return selectedRelation;
} }
public void StartCase(Guid userId) public void StartCase(Guid userId)
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM); LogMethodBegin(CM);
try try
{ {
lock (caseIdLockObject) lock (caseIdLockObject)
{ {
@@ -292,109 +274,11 @@ namespace FasdDesktopUi.Basics
{ {
LogException(E); LogException(E);
} }
finally finally
{ {
LogMethodEnd(CM); LogMethodEnd(CM);
} }
} }
private static async Task EnsureSupportCasePagesAsync()
{
if (detailsPage != null && slimPage != null)
return;
if (Application.Current == null)
return;
await Application.Current.Dispatcher.InvokeAsync(() =>
{
if (slimPage == null)
slimPage = new Pages.SlimPage.SlimPageView();
if (detailsPage == null)
detailsPage = new Pages.DetailsPage.DetailsPageView();
}, DispatcherPriority.Normal);
}
private static async Task EnsureUserIdentityForTicketAsync(cF4sdApiSearchResultRelation relation)
{
if (relation == null || relation.Type != enumF4sdSearchResultClass.Ticket)
return;
if (relation.Identities == null)
relation.Identities = new cF4sdIdentityList();
var existingUsers = relation.Identities
.Where(identity => identity.Class == enumFasdInformationClass.User)
.ToList();
Guid userId = Guid.Empty;
if (relation.Infos != null)
{
if (relation.Infos.TryGetValue("Sids", out var sidsValue) ||
relation.Infos.TryGetValue("UserSid", out sidsValue))
{
var sids = sidsValue?.Split(',')
.Select(v => v.Trim())
.Where(v => !string.IsNullOrWhiteSpace(v))
.ToList();
if (sids != null && sids.Count > 0)
{
var communication = cFasdCockpitCommunicationBase.Instance;
if (communication != null)
{
relation.Infos.TryGetValue("UserDisplayName", out var userDisplayName);
var result = await communication.GetUserSearchResults(userDisplayName, sids);
var user = result?.Values?.FirstOrDefault()?.FirstOrDefault();
if (user != null)
userId = user.id;
}
}
}
if (userId == Guid.Empty && relation.Infos.TryGetValue("UserAccount", out var userAccount))
{
relation.Infos.TryGetValue("UserDomain", out var userDomain);
if (!string.IsNullOrWhiteSpace(userAccount))
{
var communication = cFasdCockpitCommunicationBase.Instance;
if (communication != null)
{
userId = await communication.GetUserIdByAccount(userAccount, userDomain ?? string.Empty);
}
}
}
if (userId == Guid.Empty)
{
if (relation.Infos.TryGetValue("UserId", out var userIdString) ||
relation.Infos.TryGetValue("UserGuid", out userIdString) ||
relation.Infos.TryGetValue("UserIdentityId", out userIdString))
{
Guid.TryParse(userIdString, out userId);
}
}
}
if (userId == Guid.Empty)
return;
if (existingUsers.Count == 0 || existingUsers.Any(identity => identity.Id != userId))
{
relation.Identities.RemoveAll(identity => identity.Class == enumFasdInformationClass.User);
relation.Identities.Add(new cF4sdIdentityEntry
{
Class = enumFasdInformationClass.User,
Id = userId
});
}
if (relation.Infos == null)
relation.Infos = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
relation.Infos["UserId"] = userId.ToString();
relation.Infos["UserGuid"] = userId.ToString();
}
public async Task CloseCaseAsync() public async Task CloseCaseAsync()
{ {

View File

@@ -10,7 +10,7 @@
d:DesignWidth="40" d:DesignWidth="40"
x:Name="BadgeControl"> x:Name="BadgeControl">
<Border Background="{DynamicResource Color.F4SD}" <Border Background="{DynamicResource Color.SoftContrast}"
CornerRadius="5"> CornerRadius="5">
<StackPanel HorizontalAlignment="Center" <StackPanel HorizontalAlignment="Center"
@@ -19,7 +19,7 @@
Margin="7.5 2.5"> Margin="7.5 2.5">
<TextBlock FontSize="12" <TextBlock FontSize="12"
FontWeight="Bold" FontWeight="Bold"
Foreground="White" Foreground="{DynamicResource FontColor.DetailsPage.DataHistory.Value}"
Text="{Binding ElementName=BadgeControl, Path=Text}" /> Text="{Binding ElementName=BadgeControl, Path=Text}" />
</StackPanel> </StackPanel>

View File

@@ -1,9 +1,5 @@
using F4SD_AdaptableIcon; using System.Windows;
using FasdDesktopUi.Basics.Helper;
using System;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.UserControls namespace FasdDesktopUi.Basics.UserControls
{ {

View File

@@ -1,7 +1,7 @@
using C4IT.FASD.Base; using C4IT.FASD.Base;
using C4IT.MultiLanguage; using C4IT.MultiLanguage;
using FasdDesktopUi.Basics.Helper; using FasdDesktopUi.Basics.Helper;
using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@@ -125,25 +125,25 @@ namespace FasdDesktopUi.Basics.UserControls
} }
public static readonly DependencyProperty SearchDataChangedProperty = public static readonly DependencyProperty SearchDataChangedProperty =
DependencyProperty.Register("SearchDataChanged", typeof(EventHandler<cF4sdHealthSelectionDataRequest>), typeof(ComboBoxPageable), new PropertyMetadata(null)); DependencyProperty.Register("SearchDataChanged", typeof(EventHandler<cF4sdHealthSelectionDataRequest>), typeof(ComboBoxPageable), new PropertyMetadata(null));
#endregion #endregion
#region RestoreParentScrollFocusOnDropDownClose #region RestoreParentScrollFocusOnDropDownClose
public bool RestoreParentScrollFocusOnDropDownClose public bool RestoreParentScrollFocusOnDropDownClose
{ {
get { return (bool)GetValue(RestoreParentScrollFocusOnDropDownCloseProperty); } get { return (bool)GetValue(RestoreParentScrollFocusOnDropDownCloseProperty); }
set { SetValue(RestoreParentScrollFocusOnDropDownCloseProperty, value); } set { SetValue(RestoreParentScrollFocusOnDropDownCloseProperty, value); }
} }
public static readonly DependencyProperty RestoreParentScrollFocusOnDropDownCloseProperty = public static readonly DependencyProperty RestoreParentScrollFocusOnDropDownCloseProperty =
DependencyProperty.Register("RestoreParentScrollFocusOnDropDownClose", typeof(bool), typeof(ComboBoxPageable), new PropertyMetadata(false)); DependencyProperty.Register("RestoreParentScrollFocusOnDropDownClose", typeof(bool), typeof(ComboBoxPageable), new PropertyMetadata(false));
#endregion #endregion
#region ItemData #region ItemData
public ObservableCollection<KeyValuePair<string, object>> ItemData public ObservableCollection<KeyValuePair<string, object>> ItemData
{ {
@@ -222,6 +222,15 @@ namespace FasdDesktopUi.Basics.UserControls
return null; return null;
} }
public bool CloseDropDownIfOpen()
{
if (ComboBoxControl?.IsDropDownOpen != true)
return false;
ComboBoxControl.IsDropDownOpen = false;
return true;
}
#region Paging Events #region Paging Events
#region PageBack #region PageBack
@@ -316,33 +325,42 @@ namespace FasdDesktopUi.Basics.UserControls
} }
} }
private void ComboBoxControl_DropDownClosed(object sender, EventArgs e) private void SearchTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{ {
timer.Stop(); if (e.Key != Key.Escape)
cFocusInvoker.InvokeLostFocus(this, e); return;
if (RestoreParentScrollFocusOnDropDownClose) if (CloseDropDownIfOpen())
{ e.Handled = true;
_ = Dispatcher.BeginInvoke((Action)(() => }
{
try private void ComboBoxControl_DropDownClosed(object sender, EventArgs e)
{ {
var parentScrollViewer = cUiElementHelper.GetFirstParentOfType<ScrollViewer>(this); timer.Stop();
Keyboard.ClearFocus(); cFocusInvoker.InvokeLostFocus(this, e);
if (parentScrollViewer != null) if (RestoreParentScrollFocusOnDropDownClose)
{ {
parentScrollViewer.Focus(); _ = Dispatcher.BeginInvoke((Action)(() =>
Keyboard.Focus(parentScrollViewer); {
} try
} {
catch (Exception exception) var parentScrollViewer = cUiElementHelper.GetFirstParentOfType<ScrollViewer>(this);
{ Keyboard.ClearFocus();
LogException(exception);
} if (parentScrollViewer != null)
}), System.Windows.Threading.DispatcherPriority.Input); {
} parentScrollViewer.Focus();
} Keyboard.Focus(parentScrollViewer);
}
}
catch (Exception exception)
{
LogException(exception);
}
}), System.Windows.Threading.DispatcherPriority.Input);
}
}
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e) private void ComboBoxControl_DropDownOpened(object sender, EventArgs e)
{ {
@@ -384,6 +402,8 @@ namespace FasdDesktopUi.Basics.UserControls
TextBox searchTextBox = FindVisualChild<TextBox>(partPopup.Child, "SearchTextBox"); TextBox searchTextBox = FindVisualChild<TextBox>(partPopup.Child, "SearchTextBox");
if (searchTextBox != null) if (searchTextBox != null)
{ {
searchTextBox.PreviewKeyDown -= SearchTextBox_PreviewKeyDown;
searchTextBox.PreviewKeyDown += SearchTextBox_PreviewKeyDown;
// Setzen des Fokus auf TextBox // Setzen des Fokus auf TextBox
searchTextBox.Focus(); searchTextBox.Focus();
} }

View File

@@ -1,429 +1,451 @@
using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
namespace FasdDesktopUi.Basics.UserControls namespace FasdDesktopUi.Basics.UserControls
{ {
public partial class HierarchicalSelectionControl : UserControl public partial class HierarchicalSelectionControl : UserControl
{ {
private readonly ObservableCollection<HierarchicalSelectionItem> visibleItems = new ObservableCollection<HierarchicalSelectionItem>(); private readonly ObservableCollection<HierarchicalSelectionItem> visibleItems = new ObservableCollection<HierarchicalSelectionItem>();
private readonly Dictionary<string, HierarchicalSelectionItem> itemLookup = new Dictionary<string, HierarchicalSelectionItem>(); private readonly Dictionary<string, HierarchicalSelectionItem> itemLookup = new Dictionary<string, HierarchicalSelectionItem>();
private readonly DispatcherTimer searchDelayTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(250) }; private readonly DispatcherTimer searchDelayTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(250) };
private string lastSearchText = string.Empty; private string lastSearchText = string.Empty;
private bool suppressTreeSelectionChanged; private bool suppressTreeSelectionChanged;
private TextBox searchTextBox; private TextBox searchTextBox;
private TreeView treeViewControl; private TreeView treeViewControl;
private ScrollViewer itemsScrollViewer; private ScrollViewer itemsScrollViewer;
public ObservableCollection<HierarchicalSelectionItem> VisibleItems => visibleItems; public ObservableCollection<HierarchicalSelectionItem> VisibleItems => visibleItems;
public event EventHandler DropDownOpened; public event EventHandler DropDownOpened;
public event EventHandler DropDownClosed; public event EventHandler DropDownClosed;
public HierarchicalSelectionControl() public HierarchicalSelectionControl()
{ {
InitializeComponent(); InitializeComponent();
searchDelayTimer.Tick += SearchDelayTimer_Tick; searchDelayTimer.Tick += SearchDelayTimer_Tick;
} }
public override void OnApplyTemplate() public bool CloseDropDownIfOpen()
{ {
base.OnApplyTemplate(); if (ComboBoxControl?.IsDropDownOpen != true)
EnsureTemplateParts(); return false;
if (treeViewControl != null)
treeViewControl.ItemsSource = VisibleItems; ComboBoxControl.IsDropDownOpen = false;
} return true;
}
#region DependencyProperties
public override void OnApplyTemplate()
public ObservableCollection<HierarchicalSelectionItem> ItemsSource {
{ base.OnApplyTemplate();
get => (ObservableCollection<HierarchicalSelectionItem>)GetValue(ItemsSourceProperty); EnsureTemplateParts();
set => SetValue(ItemsSourceProperty, value); if (treeViewControl != null)
} treeViewControl.ItemsSource = VisibleItems;
}
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
nameof(ItemsSource), #region DependencyProperties
typeof(ObservableCollection<HierarchicalSelectionItem>),
typeof(HierarchicalSelectionControl), public ObservableCollection<HierarchicalSelectionItem> ItemsSource
new PropertyMetadata(null, OnItemsSourceChanged)); {
get => (ObservableCollection<HierarchicalSelectionItem>)GetValue(ItemsSourceProperty);
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) set => SetValue(ItemsSourceProperty, value);
{ }
if (d is HierarchicalSelectionControl control)
{ public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
control.RebuildLookup(); nameof(ItemsSource),
control.ApplyFilter(control.lastSearchText); typeof(ObservableCollection<HierarchicalSelectionItem>),
} typeof(HierarchicalSelectionControl),
} new PropertyMetadata(null, OnItemsSourceChanged));
public HierarchicalSelectionItem SelectedItem private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
get => (HierarchicalSelectionItem)GetValue(SelectedItemProperty); if (d is HierarchicalSelectionControl control)
set => SetValue(SelectedItemProperty, value); {
} control.RebuildLookup();
control.ApplyFilter(control.lastSearchText);
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( }
nameof(SelectedItem), }
typeof(HierarchicalSelectionItem),
typeof(HierarchicalSelectionControl), public HierarchicalSelectionItem SelectedItem
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemChanged)); {
get => (HierarchicalSelectionItem)GetValue(SelectedItemProperty);
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) set => SetValue(SelectedItemProperty, value);
{ }
if (d is HierarchicalSelectionControl control)
{ public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
control.TryExpandToSelectedItem(); nameof(SelectedItem),
control.SyncTreeSelectionWithSelectedItem(bringIntoView: false); typeof(HierarchicalSelectionItem),
} typeof(HierarchicalSelectionControl),
} new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemChanged));
public Brush ComboBoxBackground private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
get => (Brush)GetValue(ComboBoxBackgroundProperty); if (d is HierarchicalSelectionControl control)
set => SetValue(ComboBoxBackgroundProperty, value); {
} control.TryExpandToSelectedItem();
control.SyncTreeSelectionWithSelectedItem(bringIntoView: false);
public static readonly DependencyProperty ComboBoxBackgroundProperty = }
DependencyProperty.Register(nameof(ComboBoxBackground), typeof(Brush), typeof(HierarchicalSelectionControl), new PropertyMetadata(Brushes.Transparent)); }
public string SearchPlaceholderText public Brush ComboBoxBackground
{ {
get => (string)GetValue(SearchPlaceholderTextProperty); get => (Brush)GetValue(ComboBoxBackgroundProperty);
set => SetValue(SearchPlaceholderTextProperty, value); set => SetValue(ComboBoxBackgroundProperty, value);
} }
public static readonly DependencyProperty SearchPlaceholderTextProperty = public static readonly DependencyProperty ComboBoxBackgroundProperty =
DependencyProperty.Register(nameof(SearchPlaceholderText), typeof(string), typeof(HierarchicalSelectionControl), new PropertyMetadata(string.Empty)); DependencyProperty.Register(nameof(ComboBoxBackground), typeof(Brush), typeof(HierarchicalSelectionControl), new PropertyMetadata(Brushes.Transparent));
#endregion public string SearchPlaceholderText
{
#region UI Event Handling get => (string)GetValue(SearchPlaceholderTextProperty);
set => SetValue(SearchPlaceholderTextProperty, value);
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e) }
{
EnsureTemplateParts(); public static readonly DependencyProperty SearchPlaceholderTextProperty =
searchTextBox?.Focus(); DependencyProperty.Register(nameof(SearchPlaceholderText), typeof(string), typeof(HierarchicalSelectionControl), new PropertyMetadata(string.Empty));
searchTextBox?.SelectAll();
suppressTreeSelectionChanged = false; #endregion
SyncTreeSelectionWithSelectedItem(bringIntoView: true);
DropDownOpened?.Invoke(this, e); #region UI Event Handling
}
private void ComboBoxControl_DropDownOpened(object sender, EventArgs e)
private void ComboBoxControl_DropDownClosed(object sender, EventArgs e) {
{ EnsureTemplateParts();
searchDelayTimer.Stop(); searchTextBox?.Focus();
suppressTreeSelectionChanged = false; searchTextBox?.SelectAll();
DropDownClosed?.Invoke(this, e); suppressTreeSelectionChanged = false;
} SyncTreeSelectionWithSelectedItem(bringIntoView: true);
DropDownOpened?.Invoke(this, e);
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) }
{
searchDelayTimer.Stop(); private void ComboBoxControl_DropDownClosed(object sender, EventArgs e)
searchDelayTimer.Start(); {
} searchDelayTimer.Stop();
suppressTreeSelectionChanged = false;
private void SearchDelayTimer_Tick(object sender, EventArgs e) DropDownClosed?.Invoke(this, e);
{ }
searchDelayTimer.Stop();
lastSearchText = searchTextBox?.Text ?? string.Empty; private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
ApplyFilter(lastSearchText); {
} searchDelayTimer.Stop();
searchDelayTimer.Start();
private void TreeViewControl_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) }
{
if (suppressTreeSelectionChanged) private void SearchDelayTimer_Tick(object sender, EventArgs e)
return; {
searchDelayTimer.Stop();
if (e.NewValue is HierarchicalSelectionItem selected) lastSearchText = searchTextBox?.Text ?? string.Empty;
{ ApplyFilter(lastSearchText);
var original = ResolveOriginalItem(selected); }
if (original != null && !Equals(SelectedItem, original))
{ private void TreeViewControl_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
SelectedItem = original; {
} if (suppressTreeSelectionChanged)
return;
suppressTreeSelectionChanged = true;
ComboBoxControl.IsDropDownOpen = false; if (e.NewValue is HierarchicalSelectionItem selected)
} {
} var original = ResolveOriginalItem(selected);
if (original != null && !Equals(SelectedItem, original))
#endregion {
SelectedItem = original;
#region Data Preparation and Filtering }
private HierarchicalSelectionItem ResolveOriginalItem(HierarchicalSelectionItem item) suppressTreeSelectionChanged = true;
{ ComboBoxControl.IsDropDownOpen = false;
if (item == null) }
return null; }
if (!string.IsNullOrWhiteSpace(item.Id) && itemLookup.TryGetValue(item.Id, out var original)) #endregion
return original;
#region Data Preparation and Filtering
return null;
} private HierarchicalSelectionItem ResolveOriginalItem(HierarchicalSelectionItem item)
{
private void RebuildLookup() if (item == null)
{ return null;
itemLookup.Clear();
if (!string.IsNullOrWhiteSpace(item.Id) && itemLookup.TryGetValue(item.Id, out var original))
if (ItemsSource == null) return original;
return;
return null;
foreach (var entry in ItemsSource.SelectMany(item => item.SelfAndDescendants())) }
{
if (string.IsNullOrWhiteSpace(entry.Id)) private void RebuildLookup()
continue; {
itemLookup.Clear();
itemLookup[entry.Id] = entry;
} if (ItemsSource == null)
} return;
private void ApplyFilter(string searchText) foreach (var entry in ItemsSource.SelectMany(item => item.SelfAndDescendants()))
{ {
visibleItems.Clear(); if (string.IsNullOrWhiteSpace(entry.Id))
continue;
if (ItemsSource == null)
return; itemLookup[entry.Id] = entry;
}
if (string.IsNullOrWhiteSpace(searchText)) }
{
foreach (var item in ItemsSource) private void ApplyFilter(string searchText)
{ {
item.SetExpandedRecursive(false); visibleItems.Clear();
visibleItems.Add(item);
} if (ItemsSource == null)
return;
TryExpandToSelectedItem();
SyncTreeSelectionWithSelectedItem(bringIntoView: false); if (string.IsNullOrWhiteSpace(searchText))
return; {
} foreach (var item in ItemsSource)
{
var comparison = StringComparison.CurrentCultureIgnoreCase; item.SetExpandedRecursive(false);
visibleItems.Add(item);
foreach (var root in ItemsSource) }
{
var clone = root.CloneBranch(node => TryExpandToSelectedItem();
node.FullPath?.IndexOf(searchText, comparison) >= 0 || SyncTreeSelectionWithSelectedItem(bringIntoView: false);
node.DisplayName?.IndexOf(searchText, comparison) >= 0); return;
}
if (clone == null)
continue; var comparison = StringComparison.CurrentCultureIgnoreCase;
clone.SetExpandedRecursive(true); foreach (var root in ItemsSource)
visibleItems.Add(clone); {
} var clone = root.CloneBranch(node =>
node.FullPath?.IndexOf(searchText, comparison) >= 0 ||
// If the selected item is part of current results, keep it visually selected. node.DisplayName?.IndexOf(searchText, comparison) >= 0);
SyncTreeSelectionWithSelectedItem(bringIntoView: false);
} if (clone == null)
continue;
private void TryExpandToSelectedItem()
{ clone.SetExpandedRecursive(true);
if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id)) visibleItems.Add(clone);
return; }
if (!string.IsNullOrWhiteSpace(lastSearchText)) // If the selected item is part of current results, keep it visually selected.
return; SyncTreeSelectionWithSelectedItem(bringIntoView: false);
}
var chain = SelectedItem;
while (chain != null) private void TryExpandToSelectedItem()
{ {
chain.IsExpanded = true; if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id))
chain = chain.Parent; return;
}
} if (!string.IsNullOrWhiteSpace(lastSearchText))
return;
#endregion
var chain = SelectedItem;
#region Tree Selection Sync while (chain != null)
{
private void SyncTreeSelectionWithSelectedItem(bool bringIntoView) chain.IsExpanded = true;
{ chain = chain.Parent;
if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id)) }
return; }
EnsureTemplateParts(); #endregion
if (treeViewControl == null)
return; #region Tree Selection Sync
// Wait for popup/template layout to finish so item containers are generated. private void SyncTreeSelectionWithSelectedItem(bool bringIntoView)
Dispatcher.BeginInvoke(new Action(() => {
{ if (SelectedItem == null || string.IsNullOrWhiteSpace(SelectedItem.Id))
var target = FindVisibleItemById(VisibleItems, SelectedItem.Id); return;
if (target == null)
return; EnsureTemplateParts();
if (treeViewControl == null)
var ancestor = target.Parent; return;
while (ancestor != null)
{ // Wait for popup/template layout to finish so item containers are generated.
ancestor.IsExpanded = true; Dispatcher.BeginInvoke(new Action(() =>
ancestor = ancestor.Parent; {
} var target = FindVisibleItemById(VisibleItems, SelectedItem.Id);
if (target == null)
treeViewControl.UpdateLayout(); return;
var targetContainer = GetTreeViewItemContainer(treeViewControl, target);
if (targetContainer == null) var ancestor = target.Parent;
return; while (ancestor != null)
{
suppressTreeSelectionChanged = true; ancestor.IsExpanded = true;
try ancestor = ancestor.Parent;
{ }
targetContainer.IsSelected = true;
if (bringIntoView) treeViewControl.UpdateLayout();
targetContainer.BringIntoView(); var targetContainer = GetTreeViewItemContainer(treeViewControl, target);
} if (targetContainer == null)
finally return;
{
suppressTreeSelectionChanged = false; suppressTreeSelectionChanged = true;
} try
}), DispatcherPriority.Loaded); {
} targetContainer.IsSelected = true;
if (bringIntoView)
private static HierarchicalSelectionItem FindVisibleItemById(IEnumerable<HierarchicalSelectionItem> items, string id) targetContainer.BringIntoView();
{ }
if (items == null || string.IsNullOrWhiteSpace(id)) finally
return null; {
suppressTreeSelectionChanged = false;
foreach (var item in items) }
{ }), DispatcherPriority.Loaded);
if (item == null) }
continue;
private static HierarchicalSelectionItem FindVisibleItemById(IEnumerable<HierarchicalSelectionItem> items, string id)
if (string.Equals(item.Id, id, StringComparison.OrdinalIgnoreCase)) {
return item; if (items == null || string.IsNullOrWhiteSpace(id))
return null;
var childMatch = FindVisibleItemById(item.Children, id);
if (childMatch != null) foreach (var item in items)
return childMatch; {
} if (item == null)
continue;
return null;
} if (string.Equals(item.Id, id, StringComparison.OrdinalIgnoreCase))
return item;
private static TreeViewItem GetTreeViewItemContainer(ItemsControl root, object targetItem)
{ var childMatch = FindVisibleItemById(item.Children, id);
if (root == null || targetItem == null) if (childMatch != null)
return null; return childMatch;
}
var directContainer = root.ItemContainerGenerator.ContainerFromItem(targetItem) as TreeViewItem;
if (directContainer != null) return null;
return directContainer; }
foreach (var child in root.Items) private static TreeViewItem GetTreeViewItemContainer(ItemsControl root, object targetItem)
{ {
var childContainer = root.ItemContainerGenerator.ContainerFromItem(child) as TreeViewItem; if (root == null || targetItem == null)
if (childContainer == null) return null;
continue;
var directContainer = root.ItemContainerGenerator.ContainerFromItem(targetItem) as TreeViewItem;
childContainer.UpdateLayout(); if (directContainer != null)
var result = GetTreeViewItemContainer(childContainer, targetItem); return directContainer;
if (result != null)
return result; foreach (var child in root.Items)
} {
var childContainer = root.ItemContainerGenerator.ContainerFromItem(child) as TreeViewItem;
return null; if (childContainer == null)
} continue;
#endregion childContainer.UpdateLayout();
var result = GetTreeViewItemContainer(childContainer, targetItem);
#region Template and Scroll Handling if (result != null)
return result;
private void EnsureTemplateParts() }
{
if (treeViewControl == null) return null;
{ }
treeViewControl = ComboBoxControl.Template.FindName("PART_TreeView", ComboBoxControl) as TreeView;
if (treeViewControl != null) #endregion
{
treeViewControl.SelectedItemChanged += TreeViewControl_SelectedItemChanged; #region Template and Scroll Handling
treeViewControl.ItemsSource = VisibleItems;
} private void EnsureTemplateParts()
} {
if (treeViewControl == null)
if (searchTextBox == null) {
{ treeViewControl = ComboBoxControl.Template.FindName("PART_TreeView", ComboBoxControl) as TreeView;
searchTextBox = ComboBoxControl.Template.FindName("PART_SearchTextBox", ComboBoxControl) as TextBox; if (treeViewControl != null)
if (searchTextBox != null) {
searchTextBox.TextChanged += SearchTextBox_TextChanged; treeViewControl.SelectedItemChanged += TreeViewControl_SelectedItemChanged;
} treeViewControl.PreviewKeyDown += DropDownContent_PreviewKeyDown;
treeViewControl.ItemsSource = VisibleItems;
if (itemsScrollViewer == null) }
{ }
itemsScrollViewer = ComboBoxControl.Template.FindName("PART_ItemsScrollViewer", ComboBoxControl) as ScrollViewer;
} if (searchTextBox == null)
} {
searchTextBox = ComboBoxControl.Template.FindName("PART_SearchTextBox", ComboBoxControl) as TextBox;
private void ItemsScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) if (searchTextBox != null)
{ {
var scroller = itemsScrollViewer ?? sender as ScrollViewer; searchTextBox.TextChanged += SearchTextBox_TextChanged;
if (scroller == null || scroller.ScrollableHeight <= 0) searchTextBox.PreviewKeyDown += DropDownContent_PreviewKeyDown;
return; }
}
var lines = SystemParameters.WheelScrollLines;
if (lines < 0) if (itemsScrollViewer == null)
{ {
if (e.Delta < 0) itemsScrollViewer = ComboBoxControl.Template.FindName("PART_ItemsScrollViewer", ComboBoxControl) as ScrollViewer;
scroller.PageDown(); }
else }
scroller.PageUp();
e.Handled = true; private void ItemsScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
return; {
} var scroller = itemsScrollViewer ?? sender as ScrollViewer;
if (scroller == null || scroller.ScrollableHeight <= 0)
if (lines == 0) return;
{
scroller.ScrollToVerticalOffset(scroller.VerticalOffset - e.Delta); var lines = SystemParameters.WheelScrollLines;
e.Handled = true; if (lines < 0)
return; {
} if (e.Delta < 0)
scroller.PageDown();
var direction = e.Delta < 0 ? 1 : -1; else
var stepCount = Math.Max(1, Math.Abs(e.Delta) / 120) * lines; scroller.PageUp();
for (var i = 0; i < stepCount; i++) e.Handled = true;
{ return;
if (direction > 0) }
scroller.LineDown();
else if (lines == 0)
scroller.LineUp(); {
} scroller.ScrollToVerticalOffset(scroller.VerticalOffset - e.Delta);
e.Handled = true;
e.Handled = true; return;
} }
#endregion var direction = e.Delta < 0 ? 1 : -1;
var stepCount = Math.Max(1, Math.Abs(e.Delta) / 120) * lines;
#region Keyboard for (var i = 0; i < stepCount; i++)
{
protected override void OnPreviewKeyDown(KeyEventArgs e) if (direction > 0)
{ scroller.LineDown();
base.OnPreviewKeyDown(e); else
scroller.LineUp();
if (!IsEnabled) }
return;
e.Handled = true;
if (!ComboBoxControl.IsDropDownOpen && (e.Key == Key.Enter || e.Key == Key.Down || e.Key == Key.Space)) }
{
ComboBoxControl.IsDropDownOpen = true; private void DropDownContent_PreviewKeyDown(object sender, KeyEventArgs e)
e.Handled = true; {
return; if (e.Key != Key.Escape)
} return;
if (ComboBoxControl.IsDropDownOpen && e.Key == Key.Escape) if (CloseDropDownIfOpen())
{ e.Handled = true;
ComboBoxControl.IsDropDownOpen = false; }
e.Handled = true;
} #endregion
}
#region Keyboard
#endregion
} protected override void OnPreviewKeyDown(KeyEventArgs e)
} {
base.OnPreviewKeyDown(e);
if (!IsEnabled)
return;
if (!ComboBoxControl.IsDropDownOpen && (e.Key == Key.Enter || e.Key == Key.Down || e.Key == Key.Space))
{
ComboBoxControl.IsDropDownOpen = true;
e.Handled = true;
return;
}
if (ComboBoxControl.IsDropDownOpen && e.Key == Key.Escape)
{
ComboBoxControl.IsDropDownOpen = false;
e.Handled = true;
}
}
#endregion
}
}

View File

@@ -167,7 +167,9 @@
<Border Background="{DynamicResource BackgroundColor.DetailsPage.Widget.Title}" <Border Background="{DynamicResource BackgroundColor.DetailsPage.Widget.Title}"
CornerRadius="7.5" CornerRadius="7.5"
Width="{Binding ElementName=TicketSelectionBorder, Path=ActualWidth}"> Width="{Binding ElementName=TicketSelectionBorder, Path=ActualWidth}">
<StackPanel x:Name="TicketSelectionContainer" /> <StackPanel x:Name="TicketSelectionContainer"
Focusable="True"
PreviewKeyDown="TicketSelectionContainer_PreviewKeyDown" />
</Border> </Border>
</Popup> </Popup>
</StackPanel> </StackPanel>

View File

@@ -218,22 +218,22 @@
<Compile Include="Basics\SupportCaseDataProvider.cs" /> <Compile Include="Basics\SupportCaseDataProvider.cs" />
<Compile Include="Basics\Enums\enumActionDisplayType.cs" /> <Compile Include="Basics\Enums\enumActionDisplayType.cs" />
<Compile Include="Basics\Helper\DirectConnectionHelper.cs" /> <Compile Include="Basics\Helper\DirectConnectionHelper.cs" />
<Compile Include="Basics\Helper\HealthCardDataHelper.cs" /> <Compile Include="Basics\Helper\HealthCardDataHelper.cs" />
<Compile Include="Basics\Helper\TicketDeepLinkHelper.cs" /> <Compile Include="Basics\Helper\TicketDeepLinkHelper.cs" />
<Compile Include="Basics\Helper\QuickActionProtocollHelper.cs" /> <Compile Include="Basics\Helper\QuickActionProtocollHelper.cs" />
<Compile Include="Basics\Helper\RichTextBoxHelper.cs" /> <Compile Include="Basics\Helper\RichTextBoxHelper.cs" />
<Compile Include="Basics\Helper\UiElementHelper.cs" /> <Compile Include="Basics\Helper\UiElementHelper.cs" />
<Compile Include="Basics\HotKeyManager.cs" /> <Compile Include="Basics\HotKeyManager.cs" />
<Compile Include="Basics\Helper\TrayTicketNotificationManager.cs" /> <Compile Include="Basics\Helper\TrayTicketNotificationManager.cs" />
<Compile Include="Basics\Services\Models\TicketOverviewCommunicationSource.cs" /> <Compile Include="Basics\Services\Models\TicketOverviewCommunicationSource.cs" />
<Compile Include="Basics\Services\Models\TicketOverviewDispatcher.cs" /> <Compile Include="Basics\Services\Models\TicketOverviewDispatcher.cs" />
<Compile Include="Basics\Services\Models\TicketOverviewCountProcessor.cs" /> <Compile Include="Basics\Services\Models\TicketOverviewCountProcessor.cs" />
<Compile Include="Basics\Services\Models\TicketOverviewSettingsProvider.cs" /> <Compile Include="Basics\Services\Models\TicketOverviewSettingsProvider.cs" />
<Compile Include="Basics\Services\Models\TicketOverviewCountsChangedEventArgs.cs" /> <Compile Include="Basics\Services\Models\TicketOverviewCountsChangedEventArgs.cs" />
<Compile Include="Basics\Services\TicketOverviewUpdateService.cs" /> <Compile Include="Basics\Services\TicketOverviewUpdateService.cs" />
<Compile Include="Basics\Models\ConnectionStatusHelper.cs" /> <Compile Include="Basics\Models\ConnectionStatusHelper.cs" />
<Compile Include="Basics\Models\HierarchicalSelectionItem.cs" /> <Compile Include="Basics\Models\HierarchicalSelectionItem.cs" />
<Compile Include="Basics\Models\HotKeyInformation.cs" /> <Compile Include="Basics\Models\HotKeyInformation.cs" />
<Compile Include="Basics\Models\IBlurrable.cs" /> <Compile Include="Basics\Models\IBlurrable.cs" />
<Compile Include="Basics\Models\ContainerDataModels.cs" /> <Compile Include="Basics\Models\ContainerDataModels.cs" />
<Compile Include="Basics\Models\EditableValueInformation.cs" /> <Compile Include="Basics\Models\EditableValueInformation.cs" />
@@ -264,8 +264,8 @@
<Compile Include="Basics\UiActions\UiCopyAction.cs" /> <Compile Include="Basics\UiActions\UiCopyAction.cs" />
<Compile Include="Basics\UiActions\UiLocalQuickAction.cs" /> <Compile Include="Basics\UiActions\UiLocalQuickAction.cs" />
<Compile Include="Basics\UiActions\UiLocalWebRequestQuickAction.cs" /> <Compile Include="Basics\UiActions\UiLocalWebRequestQuickAction.cs" />
<Compile Include="Basics\UiActions\UiProcessSearchRelationAction.cs" /> <Compile Include="Basics\UiActions\UiProcessSearchRelationAction.cs" />
<Compile Include="Basics\UiActions\UiProcessTicketOverviewRelationAction.cs" /> <Compile Include="Basics\UiActions\UiProcessTicketOverviewRelationAction.cs" />
<Compile Include="Basics\UiActions\UiQuickAction.cs" /> <Compile Include="Basics\UiActions\UiQuickAction.cs" />
<Compile Include="Basics\UiActions\UiQuickTipAction.cs" /> <Compile Include="Basics\UiActions\UiQuickTipAction.cs" />
<Compile Include="Basics\UiActions\UiRemoteQuickAction.cs" /> <Compile Include="Basics\UiActions\UiRemoteQuickAction.cs" />
@@ -281,11 +281,13 @@
<Compile Include="Basics\UserControls\ComboBoxPageAble.xaml.cs"> <Compile Include="Basics\UserControls\ComboBoxPageAble.xaml.cs">
<DependentUpon>ComboBoxPageAble.xaml</DependentUpon> <DependentUpon>ComboBoxPageAble.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Pages\DesktopWidgetPage\DesktopWidgetPageView.xaml.cs">
<Compile Include="Basics\UserControls\HierarchicalSelectionControl.xaml.cs"> <DependentUpon>DesktopWidgetPageView.xaml</DependentUpon>
<DependentUpon>HierarchicalSelectionControl.xaml</DependentUpon> </Compile>
</Compile> <Compile Include="Basics\UserControls\HierarchicalSelectionControl.xaml.cs">
<Compile Include="Basics\UserControls\DataCanvas\DynamicChart.xaml.cs"> <DependentUpon>HierarchicalSelectionControl.xaml</DependentUpon>
</Compile>
<Compile Include="Basics\UserControls\DataCanvas\DynamicChart.xaml.cs">
<DependentUpon>DynamicChart.xaml</DependentUpon> <DependentUpon>DynamicChart.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Basics\UserControls\DontShowAgainDialog.xaml.cs"> <Compile Include="Basics\UserControls\DontShowAgainDialog.xaml.cs">
@@ -495,15 +497,19 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Include="Basics\UserControls\ComboBoxPageAble.xaml"> <Page Include="Basics\UserControls\ComboBoxPageAble.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Basics\UserControls\HierarchicalSelectionControl.xaml"> <Page Include="Pages\DesktopWidgetPage\DesktopWidgetPageView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Basics\UserControls\DataCanvas\DynamicChart.xaml"> <Page Include="Basics\UserControls\HierarchicalSelectionControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Basics\UserControls\DataCanvas\DynamicChart.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
@@ -1059,4 +1065,4 @@ taskkill -im "F4SD-Cockpit-Client.exe" -f -FI "STATUS eq RUNNING"
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.3650.58\build\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.3650.58\build\Microsoft.Web.WebView2.targets'))" /> <Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.3650.58\build\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.3650.58\build\Microsoft.Web.WebView2.targets'))" />
</Target> </Target>
</Project> </Project>

View File

@@ -399,7 +399,7 @@ namespace FasdDesktopUi.Pages.AdvancedSearchPage
{ {
await SearchBarUc.SetFixedSearchResultAsync(Class, strInfo, result); await SearchBarUc.SetFixedSearchResultAsync(Class, strInfo, result);
if (result.AutoContinue && result.Results?.Count == 1) if (result.AutoContinue && result.Results?.Count == 1)
{ {
ResultMenu.IndexOfSelectedResultItem = 0; ResultMenu.IndexOfSelectedResultItem = 0;
ResultMenu.SelectCurrentResultItem(); ResultMenu.SelectCurrentResultItem();

View File

@@ -0,0 +1,221 @@
<Window x:Class="FasdDesktopUi.Pages.DesktopWidgetPage.DesktopWidgetPageView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FasdDesktopUi.Pages.DesktopWidgetPage"
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
mc:Ignorable="d"
Title="DesktopWidgetPageView"
AllowsTransparency="True"
WindowStyle="None"
Background="Transparent"
VerticalAlignment="Bottom"
ResizeMode="NoResize"
WindowState="Maximized"
ShowInTaskbar="False"
Topmost="True"
x:Name="DesktopWidgetWindow">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
<Style x:Key="DesktopWidget.Grid"
TargetType="Grid">
<Setter Property="Visibility" Value="{Binding ElementName=DesktopWidgetWindow, Path=AreAllWidgetsVisible, Converter={StaticResource BoolToVisibility}}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=F4SDWidget}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="DesktopWidget.WidgetIcon"
TargetType="ico:AdaptableIcon">
<Setter Property="IconBackgroundColor" Value="{DynamicResource Color.AppBackground}"/>
<Setter Property="PrimaryIconColor" Value="{DynamicResource Color.Menu.Icon}"/>
<Setter Property="IconWidth" Value="50"/>
<Setter Property="IconHeight" Value="50"/>
<Setter Property="IconCornerRadius" Value="25"/>
<Setter Property="BorderPadding" Value="10"/>
<Setter Property="Margin" Value="-1"/>
<Setter Property="Cursor" Value="Hand"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="PrimaryIconColor" Value="{DynamicResource Color.Menu.Icon.Hover}" />
<Setter Property="IconBackgroundColor" Value="{DynamicResource Background.Menu.Icon.Hover}" />
</Trigger>
</Style.Triggers>
<!--<Setter Property="BorderThickness" Value="10"/>
<Setter Property="BorderBrush" Value="{DynamicResource Color.Menu.Icon}"/>-->
</Style>
<Style x:Key="DesktopWidget.F4SDIcon"
TargetType="ico:AdaptableIcon">
<Setter Property="IconBackgroundColor" Value="{DynamicResource Color.AppBackground}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Margin" Value="-1"/>
<Setter Property="IconHeight" Value="70"/>
<Setter Property="IconWidth" Value="70"/>
<Setter Property="IconCornerRadius" Value="35"/>
<Setter Property="BorderPadding" Value="15"/>
<Setter Property="PrimaryIconColor" Value="{DynamicResource Color.F4SD}"/>
<Setter Property="SecondaryIconColor" Value="{DynamicResource Color.AppBackground}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="PrimaryIconColor" Value="{DynamicResource Color.Menu.Icon.Hover}" />
<Setter Property="IconBackgroundColor" Value="{DynamicResource Background.Menu.Icon.Hover}" />
<Setter Property="SecondaryIconColor" Value="{DynamicResource Background.Menu.Icon.Hover}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Border x:Name="MainBorder"
Background="Transparent"
Padding="10"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="{Binding ElementName=DesktopWidgetWindow, Path=IsWindowVisible, Converter={StaticResource BoolToVisibility}}">
<Grid VerticalAlignment="Bottom"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid x:Name="RestartGrid"
Style="{DynamicResource DesktopWidget.Grid}"
Grid.Row="0">
<Border BorderBrush="{DynamicResource Color.Menu.Icon}"
BorderThickness="5"
CornerRadius="25"
Margin="0,10,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ico:AdaptableIcon x:Name="RestartWidget"
Style="{DynamicResource DesktopWidget.WidgetIcon}"
Grid.Row="0"
SelectedMaterialIcon="ic_power_settings_new"
MouseLeftButtonUp="RestartWidget_MouseLeftButtonUp"/>
</Border>
</Grid>
<Grid x:Name="SettingsGrid"
Style="{DynamicResource DesktopWidget.Grid}"
Grid.Row="1">
<Border BorderBrush="{DynamicResource Color.Menu.Icon}"
BorderThickness="5"
CornerRadius="25"
Margin="0,10,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ico:AdaptableIcon x:Name="SettingsWidget"
Style="{DynamicResource DesktopWidget.WidgetIcon}"
Grid.Row="0"
SelectedInternIcon="menuBar_settings"
MouseLeftButtonUp="SettingsWidget_MouseLeftButtonUp"/>
</Border>
</Grid>
<Grid x:Name="TicketNotifyGrid"
Grid.Row="2"
Style="{DynamicResource DesktopWidget.Grid}">
<Border BorderBrush="{DynamicResource Color.Menu.Icon}"
BorderThickness="5"
CornerRadius="25"
Margin="0,10,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ico:AdaptableIcon x:Name="TicketNotifyWidget"
Style="{DynamicResource DesktopWidget.WidgetIcon}"
Grid.Row="0"
SelectedInternIcon="misc_ticket"
MouseLeftButtonUp="TicketNotifyWidget_MouseLeftButtonUp"/>
</Border>
<Border Background="{DynamicResource Color.Red}"
Height="15"
Width="20"
CornerRadius="5"
Margin="0 -25 -35 0">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center">
1
</TextBlock>
</Border>
</Grid>
<Grid x:Name="SearchGrid"
Grid.Row="3"
Style="{DynamicResource DesktopWidget.Grid}">
<Border BorderBrush="{DynamicResource Color.Menu.Icon}"
BorderThickness="5"
CornerRadius="25"
Margin="0,10,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ico:AdaptableIcon x:Name="SearchWidget"
Style="{DynamicResource DesktopWidget.WidgetIcon}"
Grid.Row="1"
SelectedInternIcon="menuBar_search"
BorderPadding="5,5,12,12"
MouseLeftButtonUp="SearchWidget_MouseLeftButtonUp"/>
</Border>
</Grid>
<Grid Grid.Row="4">
<Border BorderBrush="{DynamicResource Color.Menu.Icon}"
BorderThickness="5"
CornerRadius="35"
Margin="0,10,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ico:AdaptableIcon x:Name="F4SDWidget"
Style="{DynamicResource DesktopWidget.F4SDIcon}"
SelectedInternIcon="f4sd"
MouseLeftButtonUp="F4SDWidget_MouseLeftButtonUp"/>
</Border>
<Border Background="{DynamicResource Color.Red}"
Height="15"
Width="20"
CornerRadius="5"
Margin="0 -35 -50 0"
Visibility="{Binding ElementName=DesktopWidgetWindow, Path=ShowMainNotification, Converter={StaticResource BoolToVisibility}}">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center">
1
</TextBlock>
</Border>
</Grid>
</Grid>
</Border>
</Window>

View File

@@ -0,0 +1,179 @@
using C4IT.MultiLanguage;
using FasdDesktopUi.Basics;
using FasdDesktopUi.Pages.SearchPage;
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.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ContextMenu = System.Windows.Controls.ContextMenu;
using MenuItem = System.Windows.Controls.MenuItem;
using MessageBox = System.Windows.MessageBox;
namespace FasdDesktopUi.Pages.DesktopWidgetPage
{
/// <summary>
/// Interaction logic for DesktopWidgetPageView.xaml
/// </summary>
public partial class DesktopWidgetPageView : Window
{
public bool IsWindowVisible
{
get { return (bool)GetValue(IsWindowVisibleProperty); }
set { SetValue(IsWindowVisibleProperty, value); }
}
// Using a DependencyProperty as the backing store for IsWindowVisible. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsWindowVisibleProperty =
DependencyProperty.Register(nameof(IsWindowVisible), typeof(bool), typeof(DesktopWidgetPageView), new PropertyMetadata(true));
public bool AreAllWidgetsVisible
{
get { return (bool)GetValue(AreAllWidgetsVisibleProperty); }
set { SetValue(AreAllWidgetsVisibleProperty, value); }
}
// Using a DependencyProperty as the backing store for AreAllWidgetsVisible. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AreAllWidgetsVisibleProperty =
DependencyProperty.Register(nameof(AreAllWidgetsVisible), typeof(bool), typeof(DesktopWidgetPageView), new PropertyMetadata(false));
public bool ShowMainNotification
{
get { return (bool)GetValue(ShowMainNotificationProperty); }
set { SetValue(ShowMainNotificationProperty, value); }
}
// Using a DependencyProperty as the backing store for ShowMainNotification. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowMainNotificationProperty =
DependencyProperty.Register(nameof(ShowMainNotification), typeof(bool), typeof(DesktopWidgetPageView), new PropertyMetadata(true));
public DesktopWidgetPageView()
{
InitializeComponent();
SourceInitialized += (s, e) =>
{
IntPtr handle = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(cUtility.WindowProc));
};
}
private bool IsAnyOtherVisible() => cSupportCaseDataProvider.detailsPage.IsVisible || SearchPageView.Instance.IsVisible;
protected override void OnInitialized(EventArgs e)
{
cSupportCaseDataProvider.detailsPage.IsVisibleChanged += (sender, args) =>
{
this.Visibility = IsAnyOtherVisible() ? Visibility.Collapsed : Visibility.Visible;
};
SearchPageView.Instance.IsVisibleChanged += (sender, args) =>
{
this.Visibility = IsAnyOtherVisible() ? Visibility.Collapsed : Visibility.Visible;
};
base.OnInitialized(e);
}
private void F4SDWidget_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
AreAllWidgetsVisible = !AreAllWidgetsVisible;
ShowMainNotification = !ShowMainNotification;
}
private void SearchWidget_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
SearchPageView.Instance.ActivateSearchView();
}
private void SettingsWidget_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ContextMenu menu = SetupSettingsContextMenu();
SettingsWidget.ContextMenu = menu;
SettingsWidget.ContextMenu.IsOpen = true;
}
private ContextMenu SetupSettingsContextMenu()
{
ContextMenu menu = new ContextMenu();
MenuItem languageItem = new MenuItem();
languageItem.Header = cMultiLanguageSupport.GetItem("Menu.SelectLanguage");
languageItem.Items.Add(new MenuItem { Header = "DE" });
languageItem.Items.Add(new MenuItem { Header = "EN" });
menu.Items.Add(languageItem);
MenuItem optionsItem = new MenuItem();
optionsItem.Header = cMultiLanguageSupport.GetItem("Menu.Options");
optionsItem.Click += (s, e) => MessageBox.Show(cMultiLanguageSupport.GetItem("Menu.Options"));
menu.Items.Add(optionsItem);
MenuItem m42Item = new MenuItem();
m42Item.Header = cMultiLanguageSupport.GetItem("M42Settings.SystemTray");
m42Item.Click += (s, e) => MessageBox.Show(cMultiLanguageSupport.GetItem("M42Settings.SystemTray"));
menu.Items.Add(m42Item);
MenuItem phoneItem = new MenuItem();
phoneItem.Header = cMultiLanguageSupport.GetItem("PhoneSettings.SystemTray");
phoneItem.Click += (s, e) => MessageBox.Show(cMultiLanguageSupport.GetItem("PhoneSettings.SystemTray"));
menu.Items.Add(phoneItem);
return menu;
}
private void ShowMessageBox(string message)
{
MessageBox.Show(message);
}
private void RestartWidget_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ContextMenu menu = SetupRestartContextMenu();
RestartWidget.ContextMenu = menu;
RestartWidget.ContextMenu.IsOpen = true;
}
private ContextMenu SetupRestartContextMenu()
{
ContextMenu menu = new ContextMenu();
MenuItem restartItem = new MenuItem();
restartItem.Header = cMultiLanguageSupport.GetItem("Menu.Restart");
restartItem.Click += (s, e) => MessageBox.Show(cMultiLanguageSupport.GetItem("Menu.Restart"));
menu.Items.Add(restartItem);
MenuItem quitItem = new MenuItem();
quitItem.Header = cMultiLanguageSupport.GetItem("Menu.Quit");
quitItem.Click += (s, e) => MessageBox.Show(cMultiLanguageSupport.GetItem("Menu.Quit"));
menu.Items.Add(quitItem);
return menu;
}
private void TicketNotifyWidget_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Dies wurde leider noch nicht implementiert, sollte dich das stören setze es doch gerne selber um.");
}
}
}

View File

@@ -390,6 +390,7 @@ namespace FasdDesktopUi.Pages.DetailsPage
BlurInvoker.BlurInvokerVisibilityChanged += (obj, e) => UpdateBlurStatus(obj); BlurInvoker.BlurInvokerVisibilityChanged += (obj, e) => UpdateBlurStatus(obj);
NavigationHeadingUc.HeadingIconClickedEvent += NavigationHeadingUc_HeadingIconClickedEvent; NavigationHeadingUc.HeadingIconClickedEvent += NavigationHeadingUc_HeadingIconClickedEvent;
NavigationHeadingUc.EmptySpaceClicked += (obj, e) => BlurBorder_Click();
RefreshControl.RefreshButtonClicked += RefreshButtonClickedEvent; RefreshControl.RefreshButtonClicked += RefreshButtonClickedEvent;
@@ -422,52 +423,52 @@ namespace FasdDesktopUi.Pages.DetailsPage
#region BlurBorder Click #region BlurBorder Click
private void BlurBorder_Click() private void BlurBorder_Click()
{ {
BlurBorder_Click(keepTicketCompletion: false); BlurBorder_Click(keepTicketCompletion: false);
} }
private void BlurBorder_Click(bool keepTicketCompletion) private void BlurBorder_Click(bool keepTicketCompletion)
{ {
try try
{ {
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
Panel.SetZIndex(NavigationHeadingUc, 1); Panel.SetZIndex(NavigationHeadingUc, 1);
NavigationHeadingUc.ResetSelectors(); NavigationHeadingUc.ResetSelectors();
if (cConnectionStatusHelper.Instance?.ApiConnectionStatus == cConnectionStatusHelper.enumOnlineStatus.online) if (cConnectionStatusHelper.Instance?.ApiConnectionStatus == cConnectionStatusHelper.enumOnlineStatus.online)
{ {
SearchBarUserControl.Visibility = Visibility.Collapsed; SearchBarUserControl.Visibility = Visibility.Collapsed;
SearchBarUserControl.Clear(); SearchBarUserControl.Clear();
MenuBarUserControl.Visibility = Visibility.Visible; MenuBarUserControl.Visibility = Visibility.Visible;
} }
SearchResultBorder.Visibility = Visibility.Collapsed; SearchResultBorder.Visibility = Visibility.Collapsed;
OverlayBorder.Child = null; OverlayBorder.Child = null;
OverlayBorder.Visibility = Visibility.Collapsed; OverlayBorder.Visibility = Visibility.Collapsed;
if (BlurInvokers?.Count > 0) if (BlurInvokers?.Count > 0)
{ {
foreach (var blurInvoker in BlurInvokers.ToArray()) foreach (var blurInvoker in BlurInvokers.ToArray())
{ {
if (keepTicketCompletion && blurInvoker is TicketCompletion.TicketCompletion) if (keepTicketCompletion && blurInvoker is TicketCompletion.TicketCompletion)
continue; continue;
if (blurInvoker is Window blurInvokerWindow) if (blurInvoker is Window blurInvokerWindow)
blurInvokerWindow.Hide(); blurInvokerWindow.Hide();
} }
} }
IsBlurred = BlurInvokers?.Count > 0; IsBlurred = BlurInvokers?.Count > 0;
}); });
} }
catch (Exception E) catch (Exception E)
{ {
LogException(E); LogException(E);
} }
} }
private void BlurBorder_MouseUp(object sender, MouseButtonEventArgs e) private void BlurBorder_MouseUp(object sender, MouseButtonEventArgs e)
{ {
@@ -1047,8 +1048,8 @@ namespace FasdDesktopUi.Pages.DetailsPage
Dispatcher.Invoke(UpdateHistoryWidth); Dispatcher.Invoke(UpdateHistoryWidth);
if (e is BooleanEventArgs booleanArgs && booleanArgs.BooleanArg is true) if (e is BooleanEventArgs booleanArgs && booleanArgs.BooleanArg is true)
BlurBorder_Click(keepTicketCompletion: true); BlurBorder_Click(keepTicketCompletion: true);
isDataChangedEventRunning = false; isDataChangedEventRunning = false;

View File

@@ -23,6 +23,15 @@
Handler="HeadingIcon_TouchDown" /> Handler="HeadingIcon_TouchDown" />
</Style> </Style>
<Style x:Key="DetailsPage.TitleSection.Border.NotSelected"
TargetType="Border"
BasedOn="{StaticResource DetailsPage.TitleSection.Border.NotSelected}">
<EventSetter Event="MouseLeftButtonUp"
Handler="HeadingIcon_MouseLeftButtonUp" />
<EventSetter Event="TouchDown"
Handler="HeadingIcon_TouchDown" />
</Style>
<Style x:Key="SwapIconStyleBase" <Style x:Key="SwapIconStyleBase"
x:Name="SwapIconStyleBase" x:Name="SwapIconStyleBase"
TargetType="ico:AdaptableIcon" TargetType="ico:AdaptableIcon"
@@ -35,6 +44,18 @@
Value="{x:Null}" /> Value="{x:Null}" />
<Setter Property="SelectedInternIcon" <Setter Property="SelectedInternIcon"
Value="misc_chevron_down" /> Value="misc_chevron_down" />
<Setter Property="IconWidth"
Value="40" />
<Setter Property="IconHeight"
Value="42" />
<Setter Property="BorderPadding"
Value="10 0 10 0" />
<Setter Property="BorderThickness"
Value="3 0 0 0" />
<Setter Property="Margin"
Value="0" />
<Setter Property="IconCornerRadius"
Value="10" />
<Style.Triggers> <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"> Value="True">
@@ -87,274 +108,272 @@
</UserControl.Resources> </UserControl.Resources>
<ScrollViewer x:Name="HeadingScroller" <Border x:Name="HeadingBorder"
x:FieldModifier="private" MouseLeftButtonUp="HeadingBorder_Clicked"
HorizontalScrollBarVisibility="Auto" TouchDown="HeadingBorder_Clicked">
VerticalScrollBarVisibility="Hidden" <ScrollViewer x:Name="HeadingScroller"
Padding="0 7.5"> x:FieldModifier="private"
<Grid> HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Hidden"
Padding="0 7.5">
<Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="42" /> <RowDefinition Height="42" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border Grid.Row="0" <Border Grid.Row="0"
Grid.Column="0" Grid.Column="0"
Margin="0 0 10 0" Margin="0 0 10 0"
Background="#01000000" Background="#01000000"
Padding="5 0"> Padding="5 0">
<StackPanel x:Name="UserStack" <StackPanel x:Name="UserStack"
Orientation="Horizontal"> Orientation="Horizontal">
<Border x:Name="UserStackHighlightBorder" <Border x:Name="UserStackHighlightBorder"
Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}"> Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<ico:AdaptableIcon x:Name="UserIcon" <ico:AdaptableIcon x:Name="UserIcon"
SelectedInternIcon="misc_user" /> SelectedInternIcon="misc_user" />
<TextBlock x:Name="UserTextBlock" /> <TextBlock x:Name="UserTextBlock" />
</StackPanel> </StackPanel>
</Border> </Border>
<ico:AdaptableIcon x:Name="UserCopyIcon" <ico:AdaptableIcon x:Name="UserCopyIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp" MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp"
TouchDown="CopyIcon_TouchDown" TouchDown="CopyIcon_TouchDown"
SelectedInternIcon="menuBar_copy" /> SelectedInternIcon="menuBar_copy" />
</StackPanel> </StackPanel>
</Border> </Border>
<Border Grid.Row="0" <Border Grid.Row="0"
Grid.Column="1" Grid.Column="1"
Margin="10 0" Margin="10 0"
Background="#01000000" Background="#01000000"
Padding="5 0"> Padding="5 0">
<StackPanel x:Name="ComputerStack" <StackPanel x:Name="ComputerStack"
Orientation="Horizontal"> Orientation="Horizontal">
<Border x:Name="ComputerStackHighlightBorder" <Border x:Name="ComputerStackHighlightBorder"
Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}"> Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<ico:AdaptableIcon x:Name="ComputerIcon" <ico:AdaptableIcon x:Name="ComputerIcon"
SecondaryIconColor="{DynamicResource Color.FunctionMarker}" SecondaryIconColor="{DynamicResource Color.FunctionMarker}"
SelectedInternIcon="misc_computer" SelectedInternIcon="misc_computer"
Margin="10 0 7.5 0" /> Margin="10 0 7.5 0" />
<TextBlock x:Name="ComputerTextBlock" /> <TextBlock x:Name="ComputerTextBlock" />
<ico:AdaptableIcon x:Name="ComputerSwapIcon" <ico:AdaptableIcon x:Name="ComputerSwapIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
Visibility="Visible" Visibility="Visible"
BorderBrush="{DynamicResource Color.SoftContrast}" BorderBrush="{DynamicResource Color.SoftContrast}" />
BorderThickness="2 0 0 0" </StackPanel>
Padding="5 0 0 0" /> </Border>
</StackPanel>
</Border>
<ico:AdaptableIcon x:Name="ComputerCopyIcon" <ico:AdaptableIcon x:Name="ComputerCopyIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp" MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp"
TouchDown="CopyIcon_TouchDown" TouchDown="CopyIcon_TouchDown"
SelectedInternIcon="menuBar_copy" /> SelectedInternIcon="menuBar_copy" />
</StackPanel> </StackPanel>
</Border> </Border>
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}" <Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
Padding="10" Padding="10"
Margin="10" Margin="10"
CornerRadius="10" CornerRadius="10"
Visibility="{Binding ElementName=ComputerSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}" Visibility="{Binding ElementName=ComputerSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
MaxWidth="325" MaxWidth="325"
HorizontalAlignment="Left"> HorizontalAlignment="Left">
<buc:CustomMenu x:Name="ComputerSelector" <buc:CustomMenu x:Name="ComputerSelector"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
HorizontalAlignment="Left" HorizontalAlignment="Left"
MaxWidth="325" /> MaxWidth="325" />
</Border> </Border>
<Border Grid.Row="0" <Border Grid.Row="0"
Grid.Column="2" Grid.Column="2"
Margin="10 0" Margin="10 0"
Background="#01000000" Background="#01000000"
Padding="5 0"> Padding="5 0"
<StackPanel x:Name="VirtualSessionStack" x:Name="VirtualSessionBorder">
Orientation="Horizontal"> <StackPanel x:Name="VirtualSessionStack"
<Border x:Name="VirtualSessionStackHighlightBorder" Orientation="Horizontal">
Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}"> <Border x:Name="VirtualSessionStackHighlightBorder"
<StackPanel Orientation="Horizontal"> Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}">
<ico:AdaptableIcon x:Name="VirtualSessionIcon" <StackPanel Orientation="Horizontal">
SecondaryIconColor="{DynamicResource Color.FunctionMarker}" <ico:AdaptableIcon x:Name="VirtualSessionIcon"
SelectedInternIcon="misc_computer" SecondaryIconColor="{DynamicResource Color.FunctionMarker}"
Margin="10 0 7.5 0" /> SelectedInternIcon="misc_computer"
<TextBlock x:Name="VirtualSessionTextBlock" /> Margin="10 0 7.5 0" />
<TextBlock x:Name="VirtualSessionTextBlock" />
<ico:AdaptableIcon x:Name="VirtualSessionSwapIcon" <ico:AdaptableIcon x:Name="VirtualSessionSwapIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
Visibility="Visible" Visibility="Visible"
BorderBrush="{DynamicResource Color.SoftContrast}" BorderBrush="{DynamicResource Color.SoftContrast}" />
BorderThickness="2 0 0 0" </StackPanel>
Padding="5 0 0 0" /> </Border>
</StackPanel>
</Border>
<ico:AdaptableIcon x:Name="VirtualSessionCopyIcon" <ico:AdaptableIcon x:Name="VirtualSessionCopyIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp" MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp"
TouchDown="CopyIcon_TouchDown" TouchDown="CopyIcon_TouchDown"
SelectedInternIcon="menuBar_copy" /> SelectedInternIcon="menuBar_copy" />
</StackPanel> </StackPanel>
</Border> </Border>
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}" <Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
Padding="10" Padding="10"
Margin="10" Margin="10"
CornerRadius="10" CornerRadius="10"
Visibility="{Binding ElementName=VirtualSessionSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}" Visibility="{Binding ElementName=VirtualSessionSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}"
Grid.Row="1" Grid.Row="1"
Grid.Column="2" Grid.Column="2"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
MaxWidth="325" MaxWidth="325"
HorizontalAlignment="Left"> HorizontalAlignment="Left">
<buc:CustomMenu x:Name="VirtualSessionSelector" <buc:CustomMenu x:Name="VirtualSessionSelector"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
HorizontalAlignment="Left" HorizontalAlignment="Left"
MaxWidth="325" /> MaxWidth="325" />
</Border> </Border>
<Border Grid.Row="0" <Border Grid.Row="0"
Grid.Column="3" Grid.Column="3"
Margin="10 0" Margin="10 0"
Background="#01000000" Background="#01000000"
Padding="5 0"> Padding="5 0"
<StackPanel x:Name="MobileDeviceStack" x:Name="MobileDeviceBorder">
Orientation="Horizontal"> <StackPanel x:Name="MobileDeviceStack"
<Border x:Name="MobileDeviceStackHighlightBorder" Orientation="Horizontal">
Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}"> <Border x:Name="MobileDeviceStackHighlightBorder"
<StackPanel Orientation="Horizontal"> Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}">
<ico:AdaptableIcon x:Name="MobileDeviceIcon" <StackPanel Orientation="Horizontal">
SecondaryIconColor="{DynamicResource Color.FunctionMarker}" <ico:AdaptableIcon x:Name="MobileDeviceIcon"
SelectedMaterialIcon="ic_smartphone" SecondaryIconColor="{DynamicResource Color.FunctionMarker}"
Margin="10 0 7.5 0" /> SelectedMaterialIcon="ic_smartphone"
<TextBlock x:Name="MobileDeviceTextBlock" /> Margin="10 0 7.5 0" />
<TextBlock x:Name="MobileDeviceTextBlock" />
<ico:AdaptableIcon x:Name="MobileDeviceSwapIcon" <ico:AdaptableIcon x:Name="MobileDeviceSwapIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
Visibility="Visible" Visibility="Visible"
BorderBrush="{DynamicResource Color.SoftContrast}" BorderBrush="{DynamicResource Color.SoftContrast}" />
BorderThickness="2 0 0 0" </StackPanel>
Padding="5 0 0 0" /> </Border>
</StackPanel>
</Border>
<ico:AdaptableIcon x:Name="MobileDeviceCopyIcon" <ico:AdaptableIcon x:Name="MobileDeviceCopyIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp" MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp"
TouchDown="CopyIcon_TouchDown" TouchDown="CopyIcon_TouchDown"
SelectedInternIcon="menuBar_copy" /> SelectedInternIcon="menuBar_copy" />
</StackPanel> </StackPanel>
</Border> </Border>
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}" <Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
Padding="10" Padding="10"
Margin="10" Margin="10"
CornerRadius="10" CornerRadius="10"
Visibility="{Binding ElementName=MobileDeviceSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}" Visibility="{Binding ElementName=MobileDeviceSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}"
Grid.Row="1" Grid.Row="1"
Grid.Column="3" Grid.Column="3"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
MaxWidth="325" MaxWidth="325"
HorizontalAlignment="Left"> HorizontalAlignment="Left">
<buc:CustomMenu x:Name="MobileDeviceSelector" <buc:CustomMenu x:Name="MobileDeviceSelector"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
HorizontalAlignment="Left" HorizontalAlignment="Left"
MaxWidth="325" /> MaxWidth="325" />
</Border> </Border>
<Border Grid.Row="0" <Border Grid.Row="0"
Grid.Column="4" Grid.Column="4"
Margin="10 0" Margin="10 0"
Background="#01000000" Background="#01000000"
Padding="5 0"> Padding="5 0"
<StackPanel x:Name="TicketStack" x:Name="TicketBorder">
Orientation="Horizontal"> <StackPanel x:Name="TicketStack"
<Border x:Name="TicketStackHighlightBorder" Orientation="Horizontal">
Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}"> <Border x:Name="TicketStackHighlightBorder"
<StackPanel Orientation="Horizontal"> Style="{DynamicResource DetailsPage.TitleSection.Border.NotSelected}">
<ico:AdaptableIcon x:Name="TicketIcon" <StackPanel Orientation="Horizontal">
IconHeight="25" <ico:AdaptableIcon x:Name="TicketIcon"
IconWidth="25" IconHeight="25"
SelectedMaterialIcon="ic_mail" IconWidth="25"
Margin="10 0 7.5 0" /> SelectedMaterialIcon="ic_mail"
<TextBlock x:Name="TicketTextBlock" /> Margin="10 0 7.5 0" />
<TextBlock x:Name="TicketTextBlock" />
<ico:AdaptableIcon x:Name="TicketSwapIcon" <ico:AdaptableIcon x:Name="TicketSwapIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
Visibility="Visible" Visibility="Visible"
BorderBrush="{DynamicResource Color.SoftContrast}" BorderBrush="{DynamicResource Color.SoftContrast}" />
BorderThickness="2 0 0 0" </StackPanel>
Padding="5 0 0 0" /> </Border>
</StackPanel>
</Border>
<ico:AdaptableIcon x:Name="TicketCopyIcon" <ico:AdaptableIcon x:Name="TicketCopyIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp" MouseLeftButtonUp="CopyIcon_MouseLeftButtonUp"
TouchDown="CopyIcon_TouchDown" TouchDown="CopyIcon_TouchDown"
SelectedInternIcon="menuBar_copy" /> SelectedInternIcon="menuBar_copy" />
<ico:AdaptableIcon x:Name="EditTicketIcon" <ico:AdaptableIcon x:Name="EditTicketIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
SelectedMaterialIcon="ic_edit" SelectedMaterialIcon="ic_edit"
MouseLeftButtonUp="EditTicketIcon_MouseLeftButtonUp" MouseLeftButtonUp="EditTicketIcon_MouseLeftButtonUp"
TouchDown="EditTicketIcon_TouchDown" /> TouchDown="EditTicketIcon_TouchDown" />
<ico:AdaptableIcon x:Name="SaveTicketIcon" <ico:AdaptableIcon x:Name="SaveTicketIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
SelectedMaterialIcon="ic_save" SelectedMaterialIcon="ic_save"
Visibility="Collapsed" Visibility="Collapsed"
MouseLeftButtonUp="SaveTicketIcon_MouseLeftButtonUp" MouseLeftButtonUp="SaveTicketIcon_MouseLeftButtonUp"
TouchDown="SaveTicketIcon_TouchDown" /> TouchDown="SaveTicketIcon_TouchDown" />
<ico:AdaptableIcon x:Name="UndoTicketIcon" <ico:AdaptableIcon x:Name="UndoTicketIcon"
Style="{DynamicResource SwapIconStyle}" Style="{DynamicResource SwapIconStyle}"
SelectedMaterialIcon="ic_undo" SelectedMaterialIcon="ic_undo"
Visibility="Collapsed" Visibility="Collapsed"
MouseLeftButtonUp="UndoTicketIcon_MouseLeftButtonUp" MouseLeftButtonUp="UndoTicketIcon_MouseLeftButtonUp"
TouchDown="UndoTicketIcon_TouchDown" /> TouchDown="UndoTicketIcon_TouchDown" />
</StackPanel> </StackPanel>
</Border> </Border>
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}" <Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
Padding="10" Padding="10"
Margin="10" Margin="10"
CornerRadius="10" CornerRadius="10"
Visibility="{Binding ElementName=TicketSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}" Visibility="{Binding ElementName=TicketSelector, Path=MenuDataList, Converter={StaticResource NullToVisibility}}"
Grid.Row="1" Grid.Row="1"
Grid.Column="4" Grid.Column="4"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
MaxWidth="325" MaxWidth="325"
HorizontalAlignment="Left"> HorizontalAlignment="Left">
<buc:CustomMenu x:Name="TicketSelector" <buc:CustomMenu x:Name="TicketSelector"
x:FieldModifier="private" x:FieldModifier="private"
Grid.Row="1" Grid.Row="1"
Grid.Column="2" Grid.Column="2"
Grid.ColumnSpan="999" Grid.ColumnSpan="999"
HorizontalAlignment="Left" HorizontalAlignment="Left"
MaxWidth="325" /> MaxWidth="325" />
</Border> </Border>
</Grid>
</ScrollViewer>
</Grid>
</ScrollViewer>
</Border>
</UserControl> </UserControl>

View File

@@ -37,7 +37,7 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
if (value != null) if (value != null)
{ {
UpdateHeaderHighlights(); UpdateHeaderHighlights();
SetTicketHeadingVisibility(); SetHeadingVisibility();
} }
} }
} }
@@ -100,11 +100,9 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
else if (DataProvider.HealthCardDataHelper.SelectedHealthCard.InformationClasses.Any(identity => identity is enumFasdInformationClass.User)) else if (DataProvider.HealthCardDataHelper.SelectedHealthCard.InformationClasses.Any(identity => identity is enumFasdInformationClass.User))
highlightedBorder = UserStackHighlightBorder; highlightedBorder = UserStackHighlightBorder;
if (highlightedBorder != null) highlightedBorder?.SetResourceReference(BackgroundProperty, "BackgroundColor.Menu.MainCategory");
highlightedBorder.SetResourceReference(BackgroundProperty, "BackgroundColor.Menu.MainCategory");
if (swapIcon != null) swapIcon?.SetResourceReference(AdaptableIcon.IconBackgroundColorProperty, "BackgroundColor.Menu.MainCategory");
swapIcon.SetResourceReference(AdaptableIcon.IconBackgroundColorProperty, "BackgroundColor.Menu.MainCategory");
} }
catch (Exception E) catch (Exception E)
{ {
@@ -112,16 +110,25 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
} }
} }
private void SetTicketHeadingVisibility() private async Task SetHeadingVisibility()
{ {
try try
{ {
if (DataProvider is null) if (DataProvider is null)
return; return;
cCollectorStatusInfo modules = await cFasdCockpitConfig.Instance.CheckCollectorStatusAsync();
if (modules != null)
{
TicketStack.Visibility = modules.HasM42Config ? Visibility.Visible : Visibility.Collapsed;
MobileDeviceStack.Visibility = modules.HasMobileDeviceConfig ? Visibility.Visible : Visibility.Collapsed;
VirtualSessionStack.Visibility = modules.HasCitrixConfig ? Visibility.Visible : Visibility.Collapsed;
TicketBorder.Visibility = modules.HasM42Config ? Visibility.Visible : Visibility.Collapsed;
MobileDeviceBorder.Visibility = modules.HasMobileDeviceConfig ? Visibility.Visible : Visibility.Collapsed;
VirtualSessionBorder.Visibility = modules.HasCitrixConfig ? Visibility.Visible : Visibility.Collapsed;
}
//bool isTicketIntegrationActive = cFasdCockpitCommunicationBase.CockpitUserInfo?.Roles?.Any(role => string.Equals(role, "Cockpit.TicketAgent", StringComparison.OrdinalIgnoreCase)) ?? false;
bool isTicketIntegrationActive = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.HealthCards.Values.Any(_e => _e.InformationClasses.Contains(enumFasdInformationClass.Ticket));
TicketStack.Visibility = isTicketIntegrationActive ? Visibility.Visible : Visibility.Collapsed;
} }
catch (Exception E) catch (Exception E)
{ {
@@ -144,7 +151,6 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
return; return;
_me.ResetControl(); _me.ResetControl();
_me.SetTicketHeadingVisibility();
_me.InitializeHeadings(); _me.InitializeHeadings();
_me.UpdateHeaderHighlights(); _me.UpdateHeaderHighlights();
} }
@@ -260,10 +266,11 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
VirtualSessionSwapIcon.Tag = virtualSessionDataEmpty; VirtualSessionSwapIcon.Tag = virtualSessionDataEmpty;
MobileDeviceSwapIcon.Tag = mobileDeviceDataEmpty; MobileDeviceSwapIcon.Tag = mobileDeviceDataEmpty;
ComputerStackHighlightBorder.Tag = computerDataEmpty; UserStackHighlightBorder.Tag = userDataEmpty.InformationClass;
TicketStackHighlightBorder.Tag = ticketDataEmpty; ComputerStackHighlightBorder.Tag = computerDataEmpty.InformationClass;
VirtualSessionStackHighlightBorder.Tag = virtualSessionDataEmpty; TicketStackHighlightBorder.Tag = ticketDataEmpty.InformationClass;
MobileDeviceStackHighlightBorder.Tag = mobileDeviceDataEmpty; VirtualSessionStackHighlightBorder.Tag = virtualSessionDataEmpty.InformationClass;
MobileDeviceStackHighlightBorder.Tag = mobileDeviceDataEmpty.InformationClass;
ComputerSwapIcon.Style = (Style)FindResource("SwapIconStyle"); ComputerSwapIcon.Style = (Style)FindResource("SwapIconStyle");
TicketSwapIcon.Style = (Style)FindResource("SwapIconStyle"); TicketSwapIcon.Style = (Style)FindResource("SwapIconStyle");
@@ -300,16 +307,6 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
MobileDeviceStackHighlightBorder.ClearValue(OpacityProperty); MobileDeviceStackHighlightBorder.ClearValue(OpacityProperty);
SetEditMode(false); SetEditMode(false);
if (!cFasdCockpitCommunicationBase.Instance.IsDemo())
{
if (MobileDeviceStack.Parent is UIElement mobileParent)
mobileParent.Visibility = Visibility.Collapsed;
//if (VirtualSessionStack.Parent is UIElement virtualParent)
// virtualParent.Visibility = Visibility.Collapsed;
}
ResetSelectors(); ResetSelectors();
} }
catch (Exception E) catch (Exception E)
@@ -424,6 +421,7 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
headingIcon = UserIcon; headingIcon = UserIcon;
headingTextBlock = UserTextBlock; headingTextBlock = UserTextBlock;
copyIcon = UserCopyIcon; copyIcon = UserCopyIcon;
highlightBoder = UserStackHighlightBorder;
hasValue = heading.HeadingText != cMultiLanguageSupport.GetItem("Header.Select.User"); hasValue = heading.HeadingText != cMultiLanguageSupport.GetItem("Header.Select.User");
if (!hasValue) if (!hasValue)
@@ -482,7 +480,10 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
if (highlightBoder != null) if (highlightBoder != null)
{ {
highlightBoder.Tag = new cSwapCaseInfo() { SelectedCaseInformationClass = heading.InformationClass, HeadingDatas = HeadingData }; if (hasValue)
highlightBoder.Tag = heading.Realtion;
else
highlightBoder.Tag = new cSwapCaseInfo() { SelectedCaseInformationClass = heading.InformationClass, HeadingDatas = HeadingData };
} }
if (copyIcon != null) if (copyIcon != null)
@@ -603,7 +604,7 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
#region SwapIcon Click #region SwapIcon Click
private void SwapIcon_Click(object sender) private void SwapIcon_Click(object sender, RoutedEventArgs e)
{ {
try try
@@ -639,7 +640,7 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
ShowsRelations = true; ShowsRelations = true;
cUiActionBase.RaiseEvent(new cShowHeadingSelectionMenuAction(), this, sender); cUiActionBase.RaiseEvent(new cShowHeadingSelectionMenuAction(), this, sender);
DoShowRelations(swapCaseData, location, SupportCaseController); DoShowRelations(swapCaseData, location, SupportCaseController);
//Dispatcher.Invoke(async () => await action.RunUiActionAsync(sender, location, false, DataProvider)); e.Handled = true;
} }
catch (Exception E) catch (Exception E)
{ {
@@ -710,12 +711,12 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
private void SwapIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) private void SwapIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{ {
SwapIcon_Click(sender); SwapIcon_Click(sender, e);
} }
private void SwapIcon_TouchDown(object sender, TouchEventArgs e) private void SwapIcon_TouchDown(object sender, TouchEventArgs e)
{ {
SwapIcon_Click(sender); SwapIcon_Click(sender, e);
} }
#endregion #endregion
@@ -826,10 +827,17 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
UndoTicketIcon_Click(); UndoTicketIcon_Click();
} }
#endregion #endregion
#endregion #endregion
// todo hacky solution to toggle blurr border. Think about better solution
public event EventHandler EmptySpaceClicked;
private void HeadingBorder_Clicked(object sender, EventArgs e)
{
EmptySpaceClicked?.Invoke(this, EventArgs.Empty);
}
} }
} }

View File

@@ -75,13 +75,13 @@
</Border> </Border>
<Border Grid.Row="0"> <Border Grid.Row="0">
<CheckBox x:Name="FilterCheckbox" <CheckBox x:Name="FilterCheckbox"
Style="{DynamicResource ToggleSwitch}" Style="{DynamicResource ToggleSwitch}"
Margin="0 7 50 129" Margin="0 7 50 129"
VerticalAlignment="Top" VerticalAlignment="Top"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Cursor="Hand" Cursor="Hand"
Visibility="Visible"> Visibility="Visible">
</CheckBox> </CheckBox>
</Border> </Border>
@@ -107,27 +107,28 @@
Visibility="Visible" /> Visibility="Visible" />
</Border> </Border>
<Border Grid.Row="0"> <Border Grid.Row="0">
<StackPanel Orientation="Horizontal" <StackPanel Orientation="Horizontal"
Margin="9 0 0 0" Margin="9 0 0 0"
VerticalAlignment="Top" VerticalAlignment="Top"
HorizontalAlignment="Left"> HorizontalAlignment="Left">
<Label x:Name="TicketOverviewLabel" <Label x:Name="TicketOverviewLabel"
Content="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=TicketOverview.Header}" Content="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=TicketOverview.Header}"
Style="{DynamicResource DetailsPage.DataHistory.TitleColumn.OverviewTitle}" Style="{DynamicResource DetailsPage.DataHistory.TitleColumn.OverviewTitle}"
VerticalAlignment="Top" VerticalAlignment="Top"
HorizontalAlignment="Left" HorizontalAlignment="Left"
FontWeight="Bold" FontWeight="Bold"
Visibility="Visible" /> Visibility="Visible" />
<buc:Badge Margin="6 0 0 0" <buc:Badge Margin="6 0 0 0"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="Beta"> Text="Beta">
<buc:Badge.LayoutTransform> <buc:Badge.LayoutTransform>
<ScaleTransform ScaleX="0.85" ScaleY="0.85" /> <ScaleTransform ScaleX="0.85"
</buc:Badge.LayoutTransform> ScaleY="0.85" />
</buc:Badge> </buc:Badge.LayoutTransform>
</StackPanel> </buc:Badge>
</Border> </StackPanel>
</Border>
</Grid> </Grid>
<!--Grid Row 2 SearchResult + SearchHistory--> <!--Grid Row 2 SearchResult + SearchHistory-->
@@ -166,9 +167,9 @@
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
Visibility="Collapsed"> Visibility="Collapsed">
<ScrollViewer VerticalScrollBarVisibility="Auto"> <ScrollViewer VerticalScrollBarVisibility="Auto">
<buc:CustomSearchResultCollection x:Name="ResultMenu" <buc:CustomSearchResultCollection x:Name="ResultMenu"
x:FieldModifier="private" x:FieldModifier="private"
PreviewMouseWheel="ResultMenu_PreviewMouseWheel"/> PreviewMouseWheel="ResultMenu_PreviewMouseWheel" />
</ScrollViewer> </ScrollViewer>
</Border> </Border>
</Grid> </Grid>

File diff suppressed because it is too large Load Diff

View File

@@ -210,9 +210,10 @@
<ico:AdaptableIcon x:Name="ShouldSkipSlimViewPolicy" <ico:AdaptableIcon x:Name="ShouldSkipSlimViewPolicy"
SelectedInternIcon="lock_closed" SelectedInternIcon="lock_closed"
PrimaryIconColor="{DynamicResource Color.Menu.Icon}" PrimaryIconColor="{DynamicResource Color.Menu.Icon}"
Margin="-25,-5,0,0" BorderPadding="0"
IconWidth="23" Margin="-20 0 0 0"
IconHeight="23" IconWidth="12"
IconHeight="12"
Visibility="Collapsed" /> Visibility="Collapsed" />
</StackPanel> </StackPanel>
@@ -229,9 +230,10 @@
<ico:AdaptableIcon x:Name="PositionOfSmallViewsPolicy" <ico:AdaptableIcon x:Name="PositionOfSmallViewsPolicy"
SelectedInternIcon="lock_closed" SelectedInternIcon="lock_closed"
PrimaryIconColor="{DynamicResource Color.Menu.Icon}" PrimaryIconColor="{DynamicResource Color.Menu.Icon}"
Margin="-25,-5,0,0" BorderPadding="0"
IconWidth="23" Margin="-20 0 0 0"
IconHeight="23" IconWidth="12"
IconHeight="12"
Visibility="Collapsed" /> Visibility="Collapsed" />
</StackPanel> </StackPanel>
@@ -290,9 +292,10 @@
<ico:AdaptableIcon x:Name="PositionOfFavouriteBarPolicy" <ico:AdaptableIcon x:Name="PositionOfFavouriteBarPolicy"
SelectedInternIcon="lock_closed" SelectedInternIcon="lock_closed"
PrimaryIconColor="{DynamicResource Color.Menu.Icon}" PrimaryIconColor="{DynamicResource Color.Menu.Icon}"
Margin="-25,-5,0,0" BorderPadding="0"
IconWidth="23" Margin="-20 0 0 0"
IconHeight="23" IconWidth="12"
IconHeight="12"
Visibility="Collapsed" /> Visibility="Collapsed" />
</StackPanel> </StackPanel>

View File

@@ -18,7 +18,7 @@
Background="Transparent" Background="Transparent"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
DataContext="{Binding RelativeSource={RelativeSource Self}}" DataContext="{Binding RelativeSource={RelativeSource Self}}"
PreviewKeyDown="CustomMessageBox_PreviewKeyDown" KeyDown="CustomMessageBox_KeyDown"
IsVisibleChanged="BlurInvoker_IsActiveChanged"> IsVisibleChanged="BlurInvoker_IsActiveChanged">
<WindowChrome.WindowChrome> <WindowChrome.WindowChrome>

View File

@@ -3,26 +3,26 @@ using FasdDesktopUi.Basics;
using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.Models;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using WinForms = System.Windows.Forms; using WinForms = System.Windows.Forms;
using static C4IT.Logging.cLogManager; using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Pages.TicketCompletion namespace FasdDesktopUi.Pages.TicketCompletion
{ {
public partial class TicketCompletion : Window, IBlurInvoker, INotifyPropertyChanged public partial class TicketCompletion : Window, IBlurInvoker, INotifyPropertyChanged
{ {
private const double MinWindowHeightDip = 220d; private const double MinWindowHeightDip = 220d;
private const double WindowWorkingAreaMarginDip = 12d; private const double WindowWorkingAreaMarginDip = 12d;
private const double DialogNonContentReserveDip = 180d; private const double DialogNonContentReserveDip = 180d;
private bool isUpdatingDialogBounds; private bool isUpdatingDialogBounds;
private bool isCanceled = false; private bool isCanceled = false;
private bool _WaitForClosing = false; private bool _WaitForClosing = false;
public bool WaitForClosing public bool WaitForClosing
@@ -49,31 +49,31 @@ namespace FasdDesktopUi.Pages.TicketCompletion
CloseCaseDialogUc.DataProvider = _dataProvider; CloseCaseDialogUc.DataProvider = _dataProvider;
} }
protected override void OnInitialized(EventArgs e) protected override void OnInitialized(EventArgs e)
{ {
base.OnInitialized(e); base.OnInitialized(e);
cFocusInvoker.GotFocus += ElementGotFocus; cFocusInvoker.GotFocus += ElementGotFocus;
cFocusInvoker.LostFocus += ElementLostFocus; cFocusInvoker.LostFocus += ElementLostFocus;
SizeChanged += TicketCompletion_SizeChanged; SizeChanged += TicketCompletion_SizeChanged;
Loaded += TicketCompletion_Loaded; Loaded += TicketCompletion_Loaded;
} }
protected override void OnSourceInitialized(EventArgs e) protected override void OnSourceInitialized(EventArgs e)
{ {
base.OnSourceInitialized(e); base.OnSourceInitialized(e);
UpdateDialogMaxHeightToScreen(); UpdateDialogMaxHeightToScreen();
} }
protected override void OnLocationChanged(EventArgs e) protected override void OnLocationChanged(EventArgs e)
{ {
base.OnLocationChanged(e); base.OnLocationChanged(e);
UpdateDialogMaxHeightToScreen(); UpdateDialogMaxHeightToScreen();
} }
private void TicketCompletion_Loaded(object sender, RoutedEventArgs e) => UpdateDialogMaxHeightToScreen(); private void TicketCompletion_Loaded(object sender, RoutedEventArgs e) => UpdateDialogMaxHeightToScreen();
private void TicketCompletion_SizeChanged(object sender, SizeChangedEventArgs e) => UpdateDialogMaxHeightToScreen(); private void TicketCompletion_SizeChanged(object sender, SizeChangedEventArgs e) => UpdateDialogMaxHeightToScreen();
#region ClosingBusy #region ClosingBusy
@@ -126,98 +126,98 @@ namespace FasdDesktopUi.Pages.TicketCompletion
return null; return null;
} }
#region Close_Click #region Close_Click
private void Close_Click()
{
isCanceled = true;
TrySetDialogResult(null);
Close();
}
private void CloseButton_Click(object sender, InputEventArgs e) => Close_Click(); private void Close_Click()
{
#endregion isCanceled = true;
TrySetDialogResult(null);
private void TrySetDialogResult(bool? result) Close();
{ }
try
{ private void CloseButton_Click(object sender, InputEventArgs e) => Close_Click();
DialogResult = result;
} #endregion
catch (InvalidOperationException)
{ private void TrySetDialogResult(bool? result)
// Window was not shown as dialog; ignore. {
} try
} {
DialogResult = result;
private void UpdateDialogMaxHeightToScreen() }
{ catch (InvalidOperationException)
if (isUpdatingDialogBounds) {
return; // Window was not shown as dialog; ignore.
}
isUpdatingDialogBounds = true; }
try
{ private void UpdateDialogMaxHeightToScreen()
WinForms.Screen screen = null; {
IntPtr currentHandle = new WindowInteropHelper(this).Handle; if (isUpdatingDialogBounds)
return;
if (currentHandle != IntPtr.Zero)
{ isUpdatingDialogBounds = true;
screen = WinForms.Screen.FromHandle(currentHandle); try
} {
else if (Owner != null) WinForms.Screen screen = null;
{ IntPtr currentHandle = new WindowInteropHelper(this).Handle;
IntPtr ownerHandle = new WindowInteropHelper(Owner).Handle;
if (ownerHandle != IntPtr.Zero) if (currentHandle != IntPtr.Zero)
screen = WinForms.Screen.FromHandle(ownerHandle); {
} screen = WinForms.Screen.FromHandle(currentHandle);
}
screen = screen ?? WinForms.Screen.PrimaryScreen; else if (Owner != null)
var workingArea = screen?.WorkingArea ?? WinForms.Screen.PrimaryScreen.WorkingArea; {
var dpiScaleY = VisualTreeHelper.GetDpi(this).DpiScaleY; IntPtr ownerHandle = new WindowInteropHelper(Owner).Handle;
var safeDpiScaleY = Math.Max(0.1, dpiScaleY); if (ownerHandle != IntPtr.Zero)
var workingAreaTopDip = workingArea.Top / safeDpiScaleY; screen = WinForms.Screen.FromHandle(ownerHandle);
var workingAreaBottomDip = workingArea.Bottom / safeDpiScaleY; }
var workingAreaHeightDip = workingArea.Height / safeDpiScaleY;
var availableWindowHeightDip = workingAreaHeightDip - (WindowWorkingAreaMarginDip * 2); screen = screen ?? WinForms.Screen.PrimaryScreen;
var workingArea = screen?.WorkingArea ?? WinForms.Screen.PrimaryScreen.WorkingArea;
MaxHeight = Math.Max(MinWindowHeightDip, availableWindowHeightDip); var dpiScaleY = VisualTreeHelper.GetDpi(this).DpiScaleY;
var safeDpiScaleY = Math.Max(0.1, dpiScaleY);
if (!double.IsNaN(Top)) var workingAreaTopDip = workingArea.Top / safeDpiScaleY;
{ var workingAreaBottomDip = workingArea.Bottom / safeDpiScaleY;
var minTop = workingAreaTopDip + WindowWorkingAreaMarginDip; var workingAreaHeightDip = workingArea.Height / safeDpiScaleY;
var maxBottom = workingAreaBottomDip - WindowWorkingAreaMarginDip; var availableWindowHeightDip = workingAreaHeightDip - (WindowWorkingAreaMarginDip * 2);
if (Top < minTop) MaxHeight = Math.Max(MinWindowHeightDip, availableWindowHeightDip);
Top = minTop;
if (!double.IsNaN(Top))
var currentBottom = Top + ActualHeight; {
if (currentBottom > maxBottom) var minTop = workingAreaTopDip + WindowWorkingAreaMarginDip;
Top = Math.Max(minTop, maxBottom - ActualHeight); var maxBottom = workingAreaBottomDip - WindowWorkingAreaMarginDip;
}
if (Top < minTop)
double nonDialogReserve = DialogNonContentReserveDip; Top = minTop;
if (CloseCaseDialogUc != null && CloseCaseDialogUc.IsLoaded)
{ var currentBottom = Top + ActualHeight;
var estimatedReserve = ActualHeight - CloseCaseDialogUc.ActualHeight; if (currentBottom > maxBottom)
if (estimatedReserve > 0) Top = Math.Max(minTop, maxBottom - ActualHeight);
nonDialogReserve = Math.Max(nonDialogReserve, estimatedReserve + WindowWorkingAreaMarginDip); }
}
double nonDialogReserve = DialogNonContentReserveDip;
CloseCaseDialogUc?.SetDialogContentMaxHeight(MaxHeight - nonDialogReserve); if (CloseCaseDialogUc != null && CloseCaseDialogUc.IsLoaded)
} {
catch (Exception ex) var estimatedReserve = ActualHeight - CloseCaseDialogUc.ActualHeight;
{ if (estimatedReserve > 0)
LogException(ex); nonDialogReserve = Math.Max(nonDialogReserve, estimatedReserve + WindowWorkingAreaMarginDip);
} }
finally
{ CloseCaseDialogUc?.SetDialogContentMaxHeight(MaxHeight - nonDialogReserve);
isUpdatingDialogBounds = false; }
} catch (Exception ex)
} {
LogException(ex);
#region Internal Focus Events }
finally
{
isUpdatingDialogBounds = false;
}
}
#region Internal Focus Events
private void ElementGotFocus(object sender, EventArgs e) private void ElementGotFocus(object sender, EventArgs e)
{ {
@@ -280,14 +280,15 @@ namespace FasdDesktopUi.Pages.TicketCompletion
#endregion #endregion
private void CustomMessageBox_PreviewKeyDown(object sender, KeyEventArgs e) private void CustomMessageBox_KeyDown(object sender, KeyEventArgs e)
{ {
switch (e.Key) if (e.Key != Key.Escape)
{ {
case Key.Escape: return;
Close_Click();
break;
} }
Close_Click();
e.Handled = true;
} }
private async Task DoCloseActionAsync() private async Task DoCloseActionAsync()
@@ -303,15 +304,15 @@ namespace FasdDesktopUi.Pages.TicketCompletion
bool closedSuccessfull = await CloseCaseDialogUc.CloseCaseAsync(_dataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.User).Id); bool closedSuccessfull = await CloseCaseDialogUc.CloseCaseAsync(_dataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.User).Id);
if (closedSuccessfull) if (closedSuccessfull)
{ {
SuccessPage.SuccessPage successPage = new SuccessPage.SuccessPage(); SuccessPage.SuccessPage successPage = new SuccessPage.SuccessPage();
successPage.Show(); successPage.Show();
await _dataProvider?.CloseCaseAsync(); await _dataProvider?.CloseCaseAsync();
TrySetDialogResult(true); TrySetDialogResult(true);
Close(); Close();
} }
} }
catch (Exception E) catch (Exception E)
{ {
LogException(E); LogException(E);

View File

@@ -1,8 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ToggleSwitch" <Style x:Key="ToggleSwitch"
TargetType="CheckBox"> TargetType="CheckBox">
<Setter Property="Height" <Setter Property="Height"
Value="15" /> Value="15" />
<Setter Property="ToolTipService.ShowOnDisabled" <Setter Property="ToolTipService.ShowOnDisabled"
@@ -105,5 +105,5 @@
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Style> </Style>
</ResourceDictionary> </ResourceDictionary>

View File

@@ -315,10 +315,40 @@ namespace FasdDesktopUi
return false; return false;
} }
public async Task InstantiateAnalyticsAsync(Guid SessionId) public async Task<cCollectorStatusInfo> CheckCollectorStatusAsync()
{ {
try try
{
var _res = await cFasdCockpitCommunicationBase.Instance.CheckCollectorStatusAsync();
if(_res != null)
return _res;
}
catch (Exception E)
{ {
LogException(E);
}
return null;
}
public bool HasM42Configuration()
{
try
{
return !string.IsNullOrWhiteSpace(cCockpitConfiguration.Instance?.m42ServerConfiguration?.Server);
}
catch (Exception E)
{
LogException(E);
}
return false;
}
public async Task InstantiateAnalyticsAsync(Guid SessionId)
{
try
{
IsAnalyticsActive = await cFasdCockpitCommunicationBase.Instance.IsAnalyticsModuleActive(); IsAnalyticsActive = await cFasdCockpitCommunicationBase.Instance.IsAnalyticsModuleActive();
if (IsAnalyticsActive) if (IsAnalyticsActive)
{ {

View File

@@ -4,7 +4,7 @@
<Product Id="*" <Product Id="*"
Name="First Aid Service Desk (F4SD) Cockpit Client" Name="First Aid Service Desk (F4SD) Cockpit Client"
Language="1033" Language="1033"
Version="2.6.1.2" Version="2.7.0.2"
Manufacturer="Consulting4IT GmbH, Germany" Manufacturer="Consulting4IT GmbH, Germany"
UpgradeCode="42C65B2F-5482-4A02-9A4F-07F97C8BB008"> UpgradeCode="42C65B2F-5482-4A02-9A4F-07F97C8BB008">

View File

@@ -5,7 +5,7 @@
[assembly: AssemblyCopyright("Copyright © 2026, Consulting4IT GmbH, Germany")] [assembly: AssemblyCopyright("Copyright © 2026, Consulting4IT GmbH, Germany")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.6.*")] [assembly: AssemblyVersion("2.7.*")]
[assembly: AssemblyInformationalVersion("2.6.1.2")] [assembly: AssemblyInformationalVersion("2.7.0.2")]
[assembly: AssemblyMinServerVersion("2.6.1.1")] [assembly: AssemblyMinServerVersion("2.7.0.0")]