aktueller Stand

This commit is contained in:
Meik
2026-02-03 15:54:56 +01:00
parent ee1f54675e
commit 7192319e1e
25 changed files with 689 additions and 260 deletions

View File

@@ -1,59 +1,69 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<F4SD-CopyTemplate-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-CopyTemplate-Configuration.xsd"> <F4SD-CopyTemplate-Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F4SD-CopyTemplate-Configuration.xsd">
<CopyTemplates Default="Ticket Information" > <CopyTemplates Default="Ticket-Information-Computer">
<CopyTemplate Name="Ticket Information"> <CopyTemplate Name="Ticket-Information-Computer">
<Name Lang="DE">Ticket Information</Name> <Name Lang="DE">Ticket-Information-Computer</Name>
<Description Lang="EN">Transfers the relevant information for ticket creation to the clipboard.</Description> <Description Lang="EN">Transfers the relevant information for ticket creation to the clipboard.</Description>
<Description Lang="DE">Überträgt die relevanten Informationen für eine Ticket Erstellung in den Zwischenspeicher.</Description> <Description Lang="DE">Überträgt die relevanten Informationen für eine Ticket Erstellung in den Zwischenspeicher.</Description>
<Icon Name="misc_ticket" IconType="intern"/> <Icon Name="misc_ticket" IconType="intern"/>
<CopyContent Format="UNICODE">%DeviceName.Label% %DeviceName.Value% <CopyContent Format="UNICODE">
%DeviceName.Label% %DeviceName.Value%
%UserFullName.Label% %UserFullName.Value% %UserFullName.Label% %UserFullName.Value%
%UserAccount.Label% %UserAccount.Value% %UserAccount.Label% %UserAccount.Value%
%DeviceModel.Label% %DeviceModel.Value% %DeviceModel.Label% %DeviceModel.Value%
%OsInfo.Label% %OsInfo.Value% %OsInfo.Label% %OsInfo.Value%
%IpAddress.Label% %IpAddress.Value% %IpAddress.Label% %IpAddress.Value%
%LastSeenCalc.Label% %LastSeenCalc.Value%</CopyContent> %LastBoot.Label% %LastBoot.Value%
<CopyContent Format="HTML">&lt;table border=&quot;1&quot; cellpadding=&quot;5,1,5,1&quot;&gt;&lt;tbody&gt; %LastSeen.Label% %LastSeen.Value%
</CopyContent>
<CopyContent Format="HTML">
&lt;table border=&quot;1&quot; cellpadding=&quot;5,1,5,1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%DeviceName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td style=&quot;color: #0000ff;&quot;&gt;%DeviceName.Value%&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;em&gt;%DeviceName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td style=&quot;color: #0000ff;&quot;&gt;%DeviceName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%UserFullName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%UserFullName.Value%&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;em&gt;%UserFullName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%UserFullName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%UserAccount.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%UserAccount.Value%&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;em&gt;%UserAccount.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%UserAccount.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%OsInfo.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%OsInfo.Value%&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;em&gt;%OsInfo.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%OsInfo.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%IpAddress.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%IpAddress.Value%&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;em&gt;%IpAddress.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%IpAddress.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%LastSeenCalc.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%LastSeenCalc.Value%&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;em&gt;%LastBoot.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%LastBoot.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;</CopyContent> &lt;tr&gt;&lt;td&gt;&lt;em&gt;%LastSeen.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%LastSeen.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
</CopyContent>
</CopyTemplate>
<CopyTemplate Name="Ticket Information-VM">
<Name Lang="DE">Ticket Information-VM</Name>
<Description Lang="EN">Transfers the relevant information for ticket creation to the clipboard.</Description>
<Description Lang="DE">Überträgt die relevanten Informationen für eine Ticket Erstellung in den Zwischenspeicher.</Description>
<Icon Name="misc_ticket" IconType="intern"/>
<CopyContent Format="UNICODE">
%VirtualSessionName.Label% %VirtualSessionName.Value%
%DNSName.Label% %DNSName.Value%
%DomainName.Label% %DomainName.Value%
%HostedMachine.Label% %HostedMachine.Value%
</CopyContent>
<CopyContent Format="HTML">
&lt;table border=&quot;1&quot; cellpadding=&quot;5,1,5,1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%VirtualSessionName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td style=&quot;color: #0000ff;&quot;&gt;%VirtualSessionName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%DNSName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%DNSName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%DomainName.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%DomainName.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;%HostedMachine.Label%&lt;/em&gt;&lt;/td&gt;&lt;td&gt;%HostedMachine.Value%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
</CopyContent>
</CopyTemplate> </CopyTemplate>
<CopyTemplate Name="Computer name"> <CopyTemplate Name="Computer name">
<Name Lang="DE">Computer Name</Name> <Name Lang="DE">Computer Name</Name>
<Section>DemoActions</Section> <Section>DemoActions</Section>
<Icon Name="misc_computer" IconType="intern"/> <Icon Name="misc_computer" IconType="intern"/>
<CopyContent Format="UNICODE">%DeviceName.Value%</CopyContent> <CopyContent Format="UNICODE">%DeviceName.Label% %DeviceName.Value%</CopyContent>
</CopyTemplate> </CopyTemplate>
<CopyTemplate Name="User name"> <CopyTemplate Name="User name">
<Name Lang="DE">Anwendername</Name> <Name Lang="DE">Anwendername</Name>
<Icon Name="misc_user" IconType="intern"/> <Icon Name="misc_user" IconType="intern"/>
<CopyContent Format="UNICODE">%UserFullName.Value%</CopyContent> <CopyContent Format="UNICODE">%UserFullName.Label% %UserFullName.Value%</CopyContent>
</CopyTemplate> </CopyTemplate>
<CopyTemplate Name="User account"> <CopyTemplate Name="User account">
<Name Lang="DE">Anwender Account</Name> <Name Lang="DE">Anwender Account</Name>
<Icon Name="misc_user" IconType="intern"/> <Icon Name="misc_user" IconType="intern"/>
<CopyContent Format="UNICODE">%UserAccount.Value%</CopyContent> <CopyContent Format="UNICODE">%UserAccount.Label% %UserAccount.Value%</CopyContent>
</CopyTemplate> </CopyTemplate>
<CopyTemplate Name="Copy last Quick Action">
<Name Lang="DE">Letzte Quick Action kopieren</Name>
<Section>Ticket</Section>
<Icon Name="misc_functionBolt" IconType="intern"/>
<CopyContent Format="UNICODE">%F4SD_QuickActionProtocolLast.Value%</CopyContent>
<CopyContent Format="HTML">%F4SD_QuickActionProtocolLast.Value%</CopyContent>
</CopyTemplate>
<CopyTemplate Name="Copy Quick Action history" HiddenInTicketDialog="true">
<Name Lang="DE">Quick Action Historie kopieren</Name>
<Section>Ticket</Section>
<Icon Name="misc_copy_bolt" IconType="intern"/>
<CopyContent Format="UNICODE">%F4SD_QuickActionProtocol.Value%</CopyContent>
<CopyContent Format="HTML">%F4SD_QuickActionProtocol.Value%</CopyContent>
</CopyTemplate>
</CopyTemplates> </CopyTemplates>
</F4SD-CopyTemplate-Configuration> </F4SD-CopyTemplate-Configuration>

View File

@@ -567,7 +567,7 @@
<State-Info Name="Primary user" ValueTable="intune-deviceInfo" ValueColumn="userDisplayName"> <State-Info Name="Primary user" ValueTable="intune-deviceInfo" ValueColumn="userDisplayName">
<Name Lang="DE">Hauptbenutzer</Name> <Name Lang="DE">Hauptbenutzer</Name>
</State-Info> </State-Info>
<State-Info Name="Last Sync Date" ValueTable="intune-deviceInfo" ValueColumn="lastSyncDateTime"> <State-Info Name="Last Sync Date" ValueTable="intune-deviceInfo" ValueColumn="lastSyncDateTime" Display="DATETIME">
<Name Lang="DE">Letzte Synchronisation</Name> <Name Lang="DE">Letzte Synchronisation</Name>
</State-Info> </State-Info>
@@ -1289,10 +1289,10 @@
<State-Info Name="Session name" ParameterName="VirtualSessionName"> <State-Info Name="Session name" ParameterName="VirtualSessionName">
<Name Lang="DE">Sessionname</Name> <Name Lang="DE">Sessionname</Name>
</State-Info> </State-Info>
<State-Info Name="Start Date" ValueTable="citrix-session" ValueColumn="StartDate"> <State-Info Name="Start Date" ValueTable="citrix-session" ValueColumn="StartDate" Display="DATETIME">
<Name Lang="DE">Startdatum</Name> <Name Lang="DE">Startdatum</Name>
</State-Info> </State-Info>
<State-Info Name="End Date" ValueTable="citrix-session" ValueColumn="EndDate"> <State-Info Name="End Date" ValueTable="citrix-session" ValueColumn="EndDate" Display="DATETIME">
<Name Lang="DE">Enddatum</Name> <Name Lang="DE">Enddatum</Name>
</State-Info> </State-Info>
<State-Translation Name="Connection State" ValueTable="citrix-session" ValueColumn="ConnectionState" Translation ="citrix_connectionState" DefaultState="Ok" > <State-Translation Name="Connection State" ValueTable="citrix-session" ValueColumn="ConnectionState" Translation ="citrix_connectionState" DefaultState="Ok" >

View File

@@ -1237,7 +1237,7 @@ namespace C4IT.FASD.Cockpit.Communication
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId) public override async Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId)
{ {
cF4SDHealthCardRawData output = null; cF4SDHealthCardRawData healthcardData = null;
try try
{ {
@@ -1245,25 +1245,16 @@ namespace C4IT.FASD.Cockpit.Communication
lock (CachedHealthCardRawData) lock (CachedHealthCardRawData)
{ {
if (CachedHealthCardRawData.TryGetValue(healthCardId, out output)) if (CachedHealthCardRawData.TryGetValue(healthCardId, out healthcardData))
{ return healthcardData;
CachedHealthCardRawData.Remove(healthCardId);
return output;
} }
} }
return null;
}
catch (Exception E) catch (Exception E)
{ {
LogException(E); LogException(E);
} }
finally
{
}
await Task.CompletedTask; return healthcardData;
return output;
} }
public override async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsData(cF4sdHealthCardRawDataRequest requestData) public override async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsData(cF4sdHealthCardRawDataRequest requestData)

View File

@@ -479,7 +479,16 @@ namespace FasdDesktopUi
private async void Application_Exit(object sender, ExitEventArgs e) private async void Application_Exit(object sender, ExitEventArgs e)
{ {
var closeUserSessionTask = cFasdCockpitCommunicationBase.Instance?.CloseUserSession(cFasdCockpitConfig.SessionId).ConfigureAwait(false); cF4sdUserInfo userInfo = null;
ConfiguredTaskAwaitable? closeUserSessionTask = null;
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
{
userInfo = cFasdCockpitCommunicationBase.CockpitUserInfo;
}
if (userInfo?.Id.Equals(Guid.Empty) is false)
{
closeUserSessionTask = cFasdCockpitCommunicationBase.Instance?.CloseUserSession(cFasdCockpitConfig.SessionId).ConfigureAwait(false);
}
await cFasdCockpitCommunicationBase.Instance.TerminateAsync(); await cFasdCockpitCommunicationBase.Instance.TerminateAsync();

View File

@@ -886,8 +886,8 @@ namespace FasdDesktopUi.Basics.Helper
public string GetInformationObjectHeadingName(enumFasdInformationClass InfoClass) public string GetInformationObjectHeadingName(enumFasdInformationClass InfoClass)
{ {
if (HeadingData.TryGetValue(enumFasdInformationClass.Computer, out var computerHeadingData)) if (HeadingData.TryGetValue(InfoClass, out var infoClassHeadingData))
return computerHeadingData.HeadingText; return infoClassHeadingData.HeadingText;
return null; return null;
} }
@@ -1086,7 +1086,7 @@ namespace FasdDesktopUi.Basics.Helper
return output; return output;
} }
private void UpdateNamedParameterEntries() internal void UpdateNamedParameterEntries()
{ {
try try
{ {
@@ -1978,7 +1978,7 @@ namespace FasdDesktopUi.Basics.Helper
parent.dataProvider.Identities = identities; parent.dataProvider.Identities = identities;
if (newHealthCardRawData != null) if (newHealthCardRawData != null)
parent.HealthCardRawData = HealthCardRawData.Combine(newHealthCardRawData); parent.HealthCardRawData = newHealthCardRawData;
parent.UpdateNamedParameterEntries(); parent.UpdateNamedParameterEntries();
@@ -2021,12 +2021,12 @@ namespace FasdDesktopUi.Basics.Helper
if (oldTable.StartingIndex != newTable.StartingIndex) if (oldTable.StartingIndex != newTable.StartingIndex)
return true; return true;
foreach (var oldTableColumn in oldTable.Columns.Values) foreach (var oldTableColumn in oldTable.Columns)
{ {
if (!newTable.Columns.TryGetValue(oldTableColumn.ColumnName, out var newTableColumn)) if (!newTable.Columns.TryGetValue(oldTableColumn.Key, out var newTableColumn))
continue; continue;
if (oldTableColumn.Values.Count != newTableColumn.Values.Count) if (oldTableColumn.Value.Values.Count != newTableColumn.Values.Count)
return true; return true;
} }
} }

View File

@@ -1,11 +1,13 @@
using C4IT.F4SD.SupportCaseProtocoll.Models; using C4IT.F4SD.SupportCaseProtocoll.Models;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using C4IT.F4SD.DisplayFormatting;
using C4IT.FASD.Base; using C4IT.FASD.Base;
using C4IT.MultiLanguage; using C4IT.MultiLanguage;
using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UserControls; using FasdDesktopUi.Basics.UserControls;
using System;
using System.Collections.Generic;
using System.Globalization;
using static C4IT.Logging.cLogManager; using static C4IT.Logging.cLogManager;
using static FasdDesktopUi.Basics.UserControls.QuickActionStatusMonitor; using static FasdDesktopUi.Basics.UserControls.QuickActionStatusMonitor;
@@ -43,8 +45,8 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
quickActionCopyData.Name = quickActionDefinition.Names.GetValue(); quickActionCopyData.Name = quickActionDefinition.Names.GetValue();
quickActionCopyData.ExecutionTime = DateTime.UtcNow; quickActionCopyData.ExecutionTime = DateTime.UtcNow;
var infoClass = dataProvider.HealthCardDataHelper.SelectedHealthCard.InformationClasses.FirstOrDefault();
quickActionCopyData.AffectedDeviceName = dataProvider.HealthCardDataHelper.GetInformationObjectHeadingName(enumFasdInformationClass.Computer); quickActionCopyData.AffectedDeviceName = dataProvider.HealthCardDataHelper.GetInformationObjectHeadingName(infoClass);
quickActionCopyData.WasRunningOnAffectedDevice = wasRunningOnAffectedDevice; quickActionCopyData.WasRunningOnAffectedDevice = wasRunningOnAffectedDevice;
quickActionCopyData.QuickActionOutput = quickActionOutput; quickActionCopyData.QuickActionOutput = quickActionOutput;
@@ -91,7 +93,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
{ {
string ascii = string.Empty; string ascii = string.Empty;
ascii += GetQuickActionAsciiDescription(copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode); ascii += GetQuickActionAsciiDescription(quickActionDefinition,copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode);
ascii += GetQuickActionAsciiError(copyData.QuickActionOutput?.ErrorDescription); ascii += GetQuickActionAsciiError(copyData.QuickActionOutput?.ErrorDescription);
ascii += GetQuickActionAsciiOutput(quickActionDefinition, copyData.QuickActionOutput); ascii += GetQuickActionAsciiOutput(quickActionDefinition, copyData.QuickActionOutput);
ascii += GetQuickActionAsciiValueComparisonString(copyData.MeasureValues); ascii += GetQuickActionAsciiValueComparisonString(copyData.MeasureValues);
@@ -99,7 +101,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
return ascii; return ascii;
} }
private static string GetQuickActionAsciiDescription(string quickActionName, string deviceName, bool wasRunningOnAffectedDevice, DateTime executionTime, enumQuickActionSuccess? quickActionStatus) private static string GetQuickActionAsciiDescription(cFasdQuickAction quickActionDefinition,string quickActionName, string deviceName, bool wasRunningOnAffectedDevice, DateTime executionTime, enumQuickActionSuccess? quickActionStatus)
{ {
string asciiDescription = string.Empty; string asciiDescription = string.Empty;
try try
@@ -118,6 +120,12 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
} }
var rawDescription = wasRunningOnAffectedDevice ? cMultiLanguageSupport.GetItem("QuickAction.Remote.Copy.Description") : cMultiLanguageSupport.GetItem("QuickAction.Local.Copy.Description"); var rawDescription = wasRunningOnAffectedDevice ? cMultiLanguageSupport.GetItem("QuickAction.Remote.Copy.Description") : cMultiLanguageSupport.GetItem("QuickAction.Local.Copy.Description");
if (quickActionDefinition.Section == enumDataHistoryOrigin.Citrix.ToString())
{
rawDescription = cMultiLanguageSupport.GetItem("QuickAction.RemoteSession.Copy.Description");
}
asciiDescription = string.Format(rawDescription, quickActionName, deviceName, executionTime.ToString("g", new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)), quickActionStatusString); asciiDescription = string.Format(rawDescription, quickActionName, deviceName, executionTime.ToString("g", new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)), quickActionStatusString);
} }
catch (Exception E) catch (Exception E)
@@ -291,7 +299,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
try try
{ {
output += GetQuickActionHtmlDescription(copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode); output += GetQuickActionHtmlDescription(quickActionDefinition,copyData.Name, copyData.AffectedDeviceName, copyData.WasRunningOnAffectedDevice, copyData.ExecutionTime, copyData.QuickActionOutput?.ResultCode);
output += GetQuickActionHtmlError(copyData.QuickActionOutput?.ErrorDescription); output += GetQuickActionHtmlError(copyData.QuickActionOutput?.ErrorDescription);
output += GetQuickActionHtmlOutput(quickActionDefinition, copyData.QuickActionOutput); output += GetQuickActionHtmlOutput(quickActionDefinition, copyData.QuickActionOutput);
output += GetQuickActionHtmlValueComparison(copyData.MeasureValues); output += GetQuickActionHtmlValueComparison(copyData.MeasureValues);
@@ -304,7 +312,7 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
return output; return output;
} }
private static string GetQuickActionHtmlDescription(string quickActionName, string deviceName, bool wasRunningOnAffectedDevice, DateTime executionTime, enumQuickActionSuccess? quickActionStatus) private static string GetQuickActionHtmlDescription(cFasdQuickAction quickActionDefinition, string quickActionName, string deviceName, bool wasRunningOnAffectedDevice, DateTime executionTime, enumQuickActionSuccess? quickActionStatus)
{ {
string output = string.Empty; string output = string.Empty;
try try
@@ -323,6 +331,11 @@ namespace FasdDesktopUi.Basics.Services.ProtocollService
} }
var rawDescription = wasRunningOnAffectedDevice ? cMultiLanguageSupport.GetItem("QuickAction.Remote.Copy.Description.Html") : cMultiLanguageSupport.GetItem("QuickAction.Local.Copy.Description.Html"); var rawDescription = wasRunningOnAffectedDevice ? cMultiLanguageSupport.GetItem("QuickAction.Remote.Copy.Description.Html") : cMultiLanguageSupport.GetItem("QuickAction.Local.Copy.Description.Html");
if(quickActionDefinition.Section == enumDataHistoryOrigin.Citrix.ToString())
{
rawDescription = cMultiLanguageSupport.GetItem("QuickAction.RemoteSession.Copy.Description.Html");
}
output = string.Format(rawDescription, quickActionName, deviceName, executionTime.ToString("g", new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)), quickActionStatusString); output = string.Format(rawDescription, quickActionName, deviceName, executionTime.ToString("g", new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)), quickActionStatusString);
} }
catch (Exception E) catch (Exception E)

View File

@@ -197,6 +197,11 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
statusValue = isUserOnline ? "Online" : "Offline"; statusValue = isUserOnline ? "Online" : "Offline";
break; break;
case enumFasdInformationClass.Ticket: case enumFasdInformationClass.Ticket:
if (relationEntry.Value.Infos != null && relationEntry.Value.Infos.TryGetValue("StatusId", out var statusIdValue))
if (Enum.TryParse<enumTicketStatus>(statusIdValue, out var ticketStatus))
statusValue = ticketStatus.ToString();
break;
case enumFasdInformationClass.VirtualSession: case enumFasdInformationClass.VirtualSession:
case enumFasdInformationClass.MobileDevice: case enumFasdInformationClass.MobileDevice:
default: default:
@@ -218,8 +223,10 @@ namespace FasdDesktopUi.Basics.Services.SupportCase.Controllers
} }
} }
public async Task RefreshDataForCurrentlyFocusedRelationAsync() public async Task RefreshDataForCurrentlyFocusedRelationAsync()
{ {
SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.LastDataRequest = DateTime.Now;
await _supportCaseProcessor.UpdateLatestCaseDataFor(_focusedRelation); await _supportCaseProcessor.UpdateLatestCaseDataFor(_focusedRelation);
} }

View File

@@ -14,6 +14,7 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
{ {
private readonly Dictionary<enumFasdInformationClass, IList<cF4sdApiSearchResultRelation>> _caseRelations = new Dictionary<enumFasdInformationClass, IList<cF4sdApiSearchResultRelation>>(); private readonly Dictionary<enumFasdInformationClass, IList<cF4sdApiSearchResultRelation>> _caseRelations = new Dictionary<enumFasdInformationClass, IList<cF4sdApiSearchResultRelation>>();
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
internal readonly Guid Id; internal readonly Guid Id;
private readonly IRelationService _relationService; private readonly IRelationService _relationService;
@@ -93,11 +94,13 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
// 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
// and tables won't be loaded e.g. the QuickActionHistory // and tables won't be loaded e.g. the QuickActionHistory
bool isDataComplete = tablesToLoad.Any(t => bool isDataComplete = IsRawDataCacheComplete() && IsSupportCaseDataCacheComplete();
_supportCaseDataCache.TryGetValue(t, out var cachedTables)
&& cachedTables.TryGetValue(relation, out var table) if (isDataComplete)
&& !table.IsIncomplete && !table.Columns.Values.Any(c => c.IsIncomplete) {
); await SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.SetHealthCardRawData(_rawDataCache[relation], relation.Identities);
return;
}
var rawDataRequest = new cF4sdHealthCardRawDataRequest() var rawDataRequest = new cF4sdHealthCardRawDataRequest()
{ {
@@ -111,11 +114,13 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
if (rawData is null) if (rawData is null)
{ {
rawData = await cFasdCockpitCommunicationBase.Instance.GetHealthCardData(rawDataRequest); rawData = await cFasdCockpitCommunicationBase.Instance.GetHealthCardData(rawDataRequest);
_rawDataCache[relation] = rawData;
await SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.SetHealthCardRawData(rawData, rawDataRequest.Identities); await SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.SetHealthCardRawData(rawData, rawDataRequest.Identities);
} }
else else
{ {
rawData = await cFasdCockpitCommunicationBase.Instance.GetHealthCardData(rawData.Id); rawData = await cFasdCockpitCommunicationBase.Instance.GetHealthCardData(rawData.Id);
_rawDataCache[relation] = _rawDataCache[relation].Combine(rawData);
await SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.UpdateHealthcardRawData(rawData); await SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.UpdateHealthcardRawData(rawData);
} }
@@ -130,6 +135,24 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
{ {
LogException(ex); LogException(ex);
} }
bool IsRawDataCacheComplete()
{
return tablesToLoad.All(t =>
_rawDataCache.TryGetValue(relation, out var cachedRawData)
&& cachedRawData.Tables.TryGetValue(t, out var cachedTable)
&& !cachedTable.IsIncomplete && !cachedTable.Columns.Values.Any(c => c.IsIncomplete)
);
}
bool IsSupportCaseDataCacheComplete()
{
return tablesToLoad.Any(t =>
_supportCaseDataCache.TryGetValue(t, out var cachedTables)
&& cachedTables.TryGetValue(relation, out var table)
&& !table.IsIncomplete && !table.Columns.Values.Any(c => c.IsIncomplete)
);
}
} }
public void UpdateSupportCaseDataCache(cF4sdApiSearchResultRelation relation, IEnumerable<cF4SDHealthCardRawData.cHealthCardTable> tables) public void UpdateSupportCaseDataCache(cF4sdApiSearchResultRelation relation, IEnumerable<cF4SDHealthCardRawData.cHealthCardTable> tables)
@@ -151,7 +174,7 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
if (!_supportCaseDataCache[table.Name].ContainsKey(relation)) if (!_supportCaseDataCache[table.Name].ContainsKey(relation))
_supportCaseDataCache[table.Name][relation] = table; _supportCaseDataCache[table.Name][relation] = table;
else else if (_supportCaseDataCache[table.Name][relation].IsIncomplete)
MergeTable(_supportCaseDataCache[table.Name][relation], table); MergeTable(_supportCaseDataCache[table.Name][relation], table);
} }
@@ -164,17 +187,28 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
void MergeTable(cF4SDHealthCardRawData.cHealthCardTable existingTable, cF4SDHealthCardRawData.cHealthCardTable newTable) void MergeTable(cF4SDHealthCardRawData.cHealthCardTable existingTable, cF4SDHealthCardRawData.cHealthCardTable newTable)
{ {
try
{
existingTable.IsIncomplete = newTable.IsIncomplete;
foreach (var newColumn in newTable.Columns) foreach (var newColumn in newTable.Columns)
{ {
existingTable.Columns[newColumn.Key] = newColumn.Value; existingTable.Columns[newColumn.Key] = newColumn.Value;
} }
} }
catch (Exception ex)
{
LogException(ex);
}
}
} }
public void InvalidateCaseDataCacheFor(cF4sdApiSearchResultRelation relation) public void InvalidateCaseDataCacheFor(cF4sdApiSearchResultRelation relation)
{ {
try try
{ {
_rawDataCache.Remove(relation);
foreach (var tableCache in _supportCaseDataCache.Values) foreach (var tableCache in _supportCaseDataCache.Values)
{ {
tableCache.Remove(relation); tableCache.Remove(relation);
@@ -209,6 +243,20 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
invalidatedTables.Add(table); invalidatedTables.Add(table);
} }
if (!_rawDataCache.TryGetValue(relation, out var cachedRawData) || cachedRawData?.Tables is null)
return;
foreach (var table in cachedRawData.Tables.Values)
{
table.IsIncomplete = true;
foreach (var column in table.Columns.Values)
{
column.Values[0] = null;
column.IsIncomplete = true;
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -110,6 +110,10 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
detailsData = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync(); detailsData = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync();
_detailsPageDataCache.Add(relation, detailsData); _detailsPageDataCache.Add(relation, detailsData);
} }
else
{
_supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.UpdateNamedParameterEntries();
}
CaseDataChanged?.Invoke(this, new SupportCaseDataEventArgs()); CaseDataChanged?.Invoke(this, new SupportCaseDataEventArgs());
} }
@@ -124,7 +128,7 @@ namespace FasdDesktopUi.Basics.Services.SupportCase
await ActualizeDataAsync(agentUserId, agentDeviceId); await ActualizeDataAsync(agentUserId, agentDeviceId);
_supportCase.InvalidateLatestCaseDataCacheFor(relation, out var invalidatedTables); _supportCase.InvalidateLatestCaseDataCacheFor(relation, out var invalidatedTables);
_detailsPageDataCache.Remove(relation); _detailsPageDataCache.Remove(relation);
await _supportCase.LoadSupportCaseDataAsync(relation, invalidatedTables.Select(t => t.Name)); await _supportCase.LoadSupportCaseDataAsync(relation, invalidatedTables.Where(t => !t.Name.StartsWith("Computation_")).Select(t => t.Name));
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -114,6 +114,8 @@ namespace FasdDesktopUi.Basics
return null; return null;
} }
await EnsureUserIdentityForTicketAsync(selectedRelation);
// get the identities of the selected relation // get the identities of the selected relation
var Identities = selectedRelation.Identities.Clone(); var Identities = selectedRelation.Identities.Clone();
@@ -313,6 +315,87 @@ namespace FasdDesktopUi.Basics
}, DispatcherPriority.Normal); }, 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()
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();

View File

@@ -91,12 +91,12 @@ namespace FasdDesktopUi.Basics.UiActions
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
if (MatchPreselectedSearchRelation(_loadedRelations))
return await ProcessSearchResultRelationAsync(_searchResults.First().Name, _loadedRelations, PreSelectedSearchRelation);
if (await _isSearchUnambigous.Task) if (await _isSearchUnambigous.Task)
return await ProcessSearchResultRelationAsync(_searchResults.First().Name, _loadedRelations, _loadedRelations.FirstOrDefault()); return await ProcessSearchResultRelationAsync(_searchResults.First().Name, _loadedRelations, _loadedRelations.FirstOrDefault());
if (MatchPreselectedSearchRelation(_loadedRelations))
return await ProcessSearchResultRelationAsync(_searchResults.First().Name, _loadedRelations, PreSelectedSearchRelation);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using System.Windows;
using C4IT.FASD.Base;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.UiActions
{
public sealed class cUiProcessTicketOverviewRelationAction : cUiActionBase
{
private readonly Func<Task> _runAsync;
public cUiProcessTicketOverviewRelationAction(string name, Func<Task> runAsync)
{
Name = name;
_runAsync = runAsync;
}
public override async Task<bool> RunUiActionAsync(object sender, UIElement UiLocation, bool isDetailedLayout, cSupportCaseDataProvider dataProvider)
{
try
{
if (_runAsync != null)
await _runAsync();
}
catch (Exception ex)
{
LogException(ex);
}
return false;
}
}
}

View File

@@ -169,6 +169,18 @@ namespace FasdDesktopUi.Basics.UserControls
{ {
SearchRelationGrid.Visibility = Visibility.Visible; SearchRelationGrid.Visibility = Visibility.Visible;
if (searchRelationMenuData.LastUsed == DateTime.MinValue)
{
LessThanTextBlock.Text= string.Empty;
LessThanTextBlock.Visibility = Visibility.Collapsed;
LastSeenTextBox.Visibility = Visibility.Collapsed;
ActivityIndicator.Width = 0;
ActivityIndicator.Visibility = Visibility.Collapsed;
ActivityTextBlock.Visibility = Visibility.Collapsed;
}
else
{
var lastUsedTimeSpan = DateTime.UtcNow - searchRelationMenuData.LastUsed; var lastUsedTimeSpan = DateTime.UtcNow - searchRelationMenuData.LastUsed;
LanguageDefinitionsConverter valueConverter = new LanguageDefinitionsConverter(); LanguageDefinitionsConverter valueConverter = new LanguageDefinitionsConverter();
string lastSeenText = null; string lastSeenText = null;
@@ -181,8 +193,14 @@ namespace FasdDesktopUi.Basics.UserControls
lastSeenText = valueConverter.Convert(Math.Ceiling(lastUsedTimeSpan.TotalMinutes), null, "Searchbar.LessThan.Min", null) as string; lastSeenText = valueConverter.Convert(Math.Ceiling(lastUsedTimeSpan.TotalMinutes), null, "Searchbar.LessThan.Min", null) as string;
LessThanTextBlock.Text = lastSeenText; LessThanTextBlock.Text = lastSeenText;
LessThanTextBlock.Visibility = Visibility.Visible;
LastSeenTextBox.Visibility = Visibility.Visible;
ActivityIndicator.Width = Math.Max(ActivityIndicator.Width * relationData.UsingLevel, ActivityIndicator.Width * 0.1); ActivityIndicator.Width = Math.Max(ActivityIndicator.Width * relationData.UsingLevel, ActivityIndicator.Width * 0.1);
ActivityIndicator.Visibility = Visibility.Visible;
ActivityTextBlock.Visibility = Visibility.Visible;
}
} }
} }

View File

@@ -157,7 +157,7 @@ namespace FasdDesktopUi.Basics.UserControls
Dispatcher.Invoke(() => SearchSpinner.Visibility = visibility); Dispatcher.Invoke(() => SearchSpinner.Visibility = visibility);
} }
public async Task SetFixedSearchResultAsync(enumF4sdSearchResultClass Class, string search, cFilteredResults _result) public async Task SetFixedSearchResultAsync(enumF4sdSearchResultClass Class, string search, cFilteredResults result)
{ {
SearchStatus = eSearchStatus.fixedResult; SearchStatus = eSearchStatus.fixedResult;
SearchTextBox.IsEnabled = false; SearchTextBox.IsEnabled = false;
@@ -173,8 +173,8 @@ namespace FasdDesktopUi.Basics.UserControls
} }
SearchTextBox.Text = search; SearchTextBox.Text = search;
await ChangedSearchValue?.Invoke(_result); if (ChangedSearchValue != null)
await ChangedSearchValue.Invoke(result);
} }
public void SetApiStatus() public void SetApiStatus()

View File

@@ -894,6 +894,16 @@
<Language Lang="DE">Die Quick Action &lt;b&gt;"{0}"&lt;/b&gt; wurde durch F4SD remote auf dem Gerät &lt;b&gt;"{1}"&lt;/b&gt; am {2} &lt;b&gt;{3}&lt;/b&gt;ausgeführt.</Language> <Language Lang="DE">Die Quick Action &lt;b&gt;"{0}"&lt;/b&gt; wurde durch F4SD remote auf dem Gerät &lt;b&gt;"{1}"&lt;/b&gt; am {2} &lt;b&gt;{3}&lt;/b&gt;ausgeführt.</Language>
</UIItem> </UIItem>
<UIItem Name="QuickAction.RemoteSession.Copy.Description">
<Language Lang="EN">The Quick Action '{0}' was {3}executed remotely by F4SD for the session '{1}' at {2}.</Language>
<Language Lang="DE">Die Quick Action "{0}" wurde durch F4SD remote für die Session "{1}" am {2} {3}ausgeführt.</Language>
</UIItem>
<UIItem Name="QuickAction.RemoteSession.Copy.Description.Html">
<Language Lang="EN">The Quick Action &lt;b&gt;'{0}'&lt;/b&gt; was &lt;b&gt;{3}&lt;/b&gt;executed remotely by F4SD on the session &lt;b&gt;'{1}'&lt;/b&gt; at {2}.</Language>
<Language Lang="DE">Die Quick Action &lt;b&gt;"{0}"&lt;/b&gt; wurde durch F4SD remote für die Session &lt;b&gt;"{1}"&lt;/b&gt; am {2} &lt;b&gt;{3}&lt;/b&gt;ausgeführt.</Language>
</UIItem>
<UIItem Name="QuickAction.Local.Copy.Description"> <UIItem Name="QuickAction.Local.Copy.Description">
<Language Lang="EN">The Quick Action '{0}' was {3}executed local by F4SD for the device '{1}' at {2}.</Language> <Language Lang="EN">The Quick Action '{0}' was {3}executed local by F4SD for the device '{1}' at {2}.</Language>
<Language Lang="DE">Die Quick Action "{0}" wurde durch F4SD lokal für das Gerät "{1}" am {2} {3}ausgeführt.</Language> <Language Lang="DE">Die Quick Action "{0}" wurde durch F4SD lokal für das Gerät "{1}" am {2} {3}ausgeführt.</Language>

View File

@@ -260,6 +260,7 @@
<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\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" />

View File

@@ -55,19 +55,6 @@ namespace FasdDesktopUi.Pages.DetailsPage.ViewModels
#region Details Properties #region Details Properties
#region TimeSinceLastRefresh property
private TimeSpan timeSinceLastRefresh;
public TimeSpan TimeSinceLastRefresh
{
get { return timeSinceLastRefresh; }
set
{
timeSinceLastRefresh = value;
OnPropertyChanged();
}
}
#endregion
#region DetailsGeometry property #region DetailsGeometry property
private DetailsPageDataHistoryCollectionGeometryModel detailsGeometry; private DetailsPageDataHistoryCollectionGeometryModel detailsGeometry;

View File

@@ -31,8 +31,6 @@ namespace FasdDesktopUi.Pages.DetailsPage.Models
//Widget //Widget
public List<List<cWidgetValueModel>> WidgetData { get; set; } public List<List<cWidgetValueModel>> WidgetData { get; set; }
//Details
public TimeSpan TimeSinceLastRefresh { get; set; } = new TimeSpan(0, 1, 0);
public cDetailsPageDataHistoryDataModel DataHistoryList { get; set; } public cDetailsPageDataHistoryDataModel DataHistoryList { get; set; }
public int ShownValueColumnsCount { get; set; } public int ShownValueColumnsCount { get; set; }

View File

@@ -306,8 +306,8 @@ namespace FasdDesktopUi.Pages.DetailsPage.UserControls
if (MobileDeviceStack.Parent is UIElement mobileParent) if (MobileDeviceStack.Parent is UIElement mobileParent)
mobileParent.Visibility = Visibility.Collapsed; mobileParent.Visibility = Visibility.Collapsed;
if (VirtualSessionStack.Parent is UIElement virtualParent) //if (VirtualSessionStack.Parent is UIElement virtualParent)
virtualParent.Visibility = Visibility.Collapsed; // virtualParent.Visibility = Visibility.Collapsed;
} }
ResetSelectors(); ResetSelectors();

View File

@@ -1,21 +1,9 @@
using C4IT.Logging; using C4IT.MultiLanguage;
using C4IT.MultiLanguage;
using FasdDesktopUi.Basics; using FasdDesktopUi.Basics;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading; using System.Windows.Threading;
using static C4IT.Logging.cLogManager; using static C4IT.Logging.cLogManager;

View File

@@ -64,13 +64,15 @@ namespace FasdDesktopUi.Pages.SearchPage
// Aktueller Zustand der Checkbox // Aktueller Zustand der Checkbox
public bool IsFilterChecked => FilterCheckbox.IsChecked == true; public bool IsFilterChecked => FilterCheckbox.IsChecked == true;
public SupportCaseSearchService SearchService { get; } = new SupportCaseSearchService(new RelationService()); private readonly IRelationService _relationService = new RelationService();
public SupportCaseSearchService SearchService { get; }
private SearchPageView() private SearchPageView()
{ {
try try
{ {
InitializeComponent(); InitializeComponent();
SearchService = new SupportCaseSearchService(_relationService);
Visibility = Visibility.Visible; Visibility = Visibility.Visible;
_instance = this; _instance = this;
@@ -569,54 +571,7 @@ namespace FasdDesktopUi.Pages.SearchPage
{ {
if (!Guid.TryParse(searchInfo.ticketId, out var _ticketId)) if (!Guid.TryParse(searchInfo.ticketId, out var _ticketId))
return; return;
_ = RunTicketSearchAsync(searchInfo.ticketName, _ticketId, searchInfo.userName, searchInfo.sids);
var _h = Task.Run(async () =>
{
try
{
var lstSids = searchInfo.sids?.Split(',').Select((v) => v.Trim()).ToList();
var _result = await cFasdCockpitCommunicationBase.Instance.GetUserSearchResults(searchInfo.userName, lstSids);
if (_result is null || _result.Count == 0 || _result.First().Value.Count == 0)
{
LogEntry($"No corresponding user could be found for ticket '{searchInfo.ticketName}'", LogLevels.Warning);
return;
}
var UserId = _result.Values.First().First().id;
var _ticketRelation = new cF4sdApiSearchResultRelation()
{
Type = enumF4sdSearchResultClass.Ticket,
DisplayName = searchInfo.ticketName,
id = _ticketId,
Status = enumF4sdSearchResultStatus.Active,
Identities = new cF4sdIdentityList
{
{ new cF4sdIdentityEntry()
{
Class = enumFasdInformationClass.User,
Id = UserId
}
},
{ new cF4sdIdentityEntry()
{
Class = enumFasdInformationClass.Ticket,
Id = _ticketId
}
},
}
};
var filteredResults = new cFilteredResults(_result) { AutoContinue = true, PreSelectedRelation = _ticketRelation };
var strInfo = string.Format(cMultiLanguageSupport.GetItem("Searchbar.TicketSearch.Info"), searchInfo.ticketName);
var _t = ShowExternalSearchInfoAsync(strInfo, filteredResults, enumF4sdSearchResultClass.Ticket);
}
catch (Exception E)
{
LogException(E);
}
});
} }
catch (Exception E) catch (Exception E)
{ {
@@ -889,6 +844,12 @@ namespace FasdDesktopUi.Pages.SearchPage
new TicketOverviewSelectionRequestedEventHandler(TicketOverview_SelectionRequested), true); new TicketOverviewSelectionRequestedEventHandler(TicketOverview_SelectionRequested), true);
cFasdCockpitConfig.Instance.UiSettingsChanged += UiSettingsChanged; cFasdCockpitConfig.Instance.UiSettingsChanged += UiSettingsChanged;
SearchBarUc.ChangedSearchValue = filteredResults =>
{
UpdateSearchResults(filteredResults);
return Task.CompletedTask;
};
SearchBarUc.SearchValueChanged += HandleSearchValueChanged; SearchBarUc.SearchValueChanged += HandleSearchValueChanged;
SearchService.RelationsFound += HandleRelationsFound; SearchService.RelationsFound += HandleRelationsFound;
} }
@@ -1011,6 +972,83 @@ namespace FasdDesktopUi.Pages.SearchPage
} }
} }
private Task TicketSearchFromOverviewRelationAsync(cF4sdApiSearchResultRelation relation)
{
if (relation == null || relation.Type != enumF4sdSearchResultClass.Ticket)
return Task.CompletedTask;
var ticketName = string.IsNullOrWhiteSpace(relation.DisplayName) ? relation.Name : relation.DisplayName;
var ticketId = relation.id;
if (ticketId == Guid.Empty)
return Task.CompletedTask;
string userName = null;
string sids = null;
if (relation.Infos != null)
{
if (!relation.Infos.TryGetValue("UserDisplayName", out userName))
relation.Infos.TryGetValue("UserAccount", out userName);
if (!relation.Infos.TryGetValue("Sids", out sids))
relation.Infos.TryGetValue("UserSid", out sids);
}
return RunTicketSearchAsync(ticketName, ticketId, userName, sids);
}
private Task RunTicketSearchAsync(string ticketName, Guid ticketId, string userName, string sids)
{
if (ticketId == Guid.Empty)
return Task.CompletedTask;
return Task.Run(async () =>
{
try
{
var lstSids = sids?.Split(',').Select((v) => v.Trim()).ToList();
var _result = await cFasdCockpitCommunicationBase.Instance.GetUserSearchResults(userName, lstSids);
if (_result is null || _result.Count == 0 || _result.First().Value.Count == 0)
{
LogEntry($"No corresponding user could be found for ticket '{ticketName}'", LogLevels.Warning);
return;
}
var userId = _result.Values.First().First().id;
var _ticketRelation = new cF4sdApiSearchResultRelation()
{
Type = enumF4sdSearchResultClass.Ticket,
DisplayName = ticketName,
id = ticketId,
Status = enumF4sdSearchResultStatus.Active,
Identities = new cF4sdIdentityList
{
new cF4sdIdentityEntry()
{
Class = enumFasdInformationClass.User,
Id = userId
},
new cF4sdIdentityEntry()
{
Class = enumFasdInformationClass.Ticket,
Id = ticketId
},
}
};
var filteredResults = new cFilteredResults(_result) { AutoContinue = true, PreSelectedRelation = _ticketRelation };
var strInfo = string.Format(cMultiLanguageSupport.GetItem("Searchbar.TicketSearch.Info"), ticketName);
await ShowExternalSearchInfoAsync(strInfo, filteredResults, enumF4sdSearchResultClass.Ticket);
}
catch (Exception E)
{
LogException(E);
}
});
}
private void PrimeTicketOverviewScope(TileScope scope) private void PrimeTicketOverviewScope(TileScope scope)
{ {
if (_ticketOverviewNotificationScopesPrimed.Add(scope)) if (_ticketOverviewNotificationScopesPrimed.Add(scope))
@@ -1329,8 +1367,8 @@ namespace FasdDesktopUi.Pages.SearchPage
SetPendingInformationClasses(new HashSet<enumFasdInformationClass> { enumFasdInformationClass.Ticket }); SetPendingInformationClasses(new HashSet<enumFasdInformationClass> { enumFasdInformationClass.Ticket });
var relations = await LoadRelationsForTileAsync(e.Key, e.UseRoleScope, Math.Max(0, e.Count)); var relations = await LoadRelationsForTileAsync(e.Key, e.UseRoleScope, Math.Max(0, e.Count));
await PopulateTicketOverviewRelationUsersAsync(relations);
Debug.WriteLine($"[TicketOverview] Relations loaded: {relations?.Count ?? 0}"); Debug.WriteLine($"[TicketOverview] Relations loaded: {relations?.Count ?? 0}");
var ticketOverviewRelationService = new RelationService();
var firstRelation = relations.FirstOrDefault(); var firstRelation = relations.FirstOrDefault();
string displayText = header; string displayText = header;
if (firstRelation != null) if (firstRelation != null)
@@ -1381,7 +1419,7 @@ namespace FasdDesktopUi.Pages.SearchPage
{ {
MenuText = r.DisplayName, MenuText = r.DisplayName,
TrailingText = trailingUser, TrailingText = trailingUser,
UiAction = new cUiProcessSearchRelationAction(entry, r, ticketOverviewRelationService, this) UiAction = new cUiProcessTicketOverviewRelationAction(r.DisplayName, () => TicketSearchFromOverviewRelationAsync(r))
{ {
DisplayType = isEnabled ? enumActionDisplayType.enabled : enumActionDisplayType.disabled, DisplayType = isEnabled ? enumActionDisplayType.enabled : enumActionDisplayType.disabled,
Description = isEnabled ? string.Empty : disabledReason, Description = isEnabled ? string.Empty : disabledReason,
@@ -1517,6 +1555,106 @@ namespace FasdDesktopUi.Pages.SearchPage
} }
} }
private async Task PopulateTicketOverviewRelationUsersAsync(List<cF4sdApiSearchResultRelation> relations)
{
if (relations == null || relations.Count == 0)
return;
foreach (var relation in relations)
{
if (relation == null || relation.Type != enumF4sdSearchResultClass.Ticket)
continue;
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)
{
if (existingUsers.Count == 0)
continue;
if (relation.Infos != null)
{
if (!relation.Infos.ContainsKey("UserId"))
relation.Infos["UserId"] = existingUsers[0].Id.ToString();
if (!relation.Infos.ContainsKey("UserGuid"))
relation.Infos["UserGuid"] = existingUsers[0].Id.ToString();
}
continue;
}
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();
}
}
private void UpdateSearchResults(cFilteredResults filteredResults) private void UpdateSearchResults(cFilteredResults filteredResults)
{ {
this.Dispatcher.Invoke(new Action(() => this.Dispatcher.Invoke(new Action(() =>
@@ -1533,6 +1671,20 @@ namespace FasdDesktopUi.Pages.SearchPage
} }
string menuHeaderText = filteredResults?.PreSelectedRelation?.DisplayName; string menuHeaderText = filteredResults?.PreSelectedRelation?.DisplayName;
if (filteredResults?.PreSelectedRelation != null)
{
List<cFasdApiSearchResultEntry> selectedResult = filteredResults.Results.Values.FirstOrDefault();
var processSearchResult = new cUiProcessSearchResultAction(selectedResult.FirstOrDefault()?.DisplayName, this, selectedResult) { PreSelectedSearchRelation = filteredResults.PreSelectedRelation };
Dispatcher.Invoke(async () =>
{
bool isSearchOngoing = await processSearchResult.RunUiActionAsync(this, this, false, null);
if (!isSearchOngoing)
Hide();
});
return;
}
ResultMenu.ShowSearchResults(filteredResults, menuHeaderText, this); ResultMenu.ShowSearchResults(filteredResults, menuHeaderText, this);
preSelectedRelation = filteredResults.PreSelectedRelation; preSelectedRelation = filteredResults.PreSelectedRelation;
@@ -1546,8 +1698,6 @@ namespace FasdDesktopUi.Pages.SearchPage
})); }));
} }
private void CancledSearchAction() private void CancledSearchAction()
{ {
_renderTicketOverviewUserNames = false; _renderTicketOverviewUserNames = false;
@@ -1580,6 +1730,7 @@ namespace FasdDesktopUi.Pages.SearchPage
break; break;
case cUiProcessSearchRelationAction _: case cUiProcessSearchRelationAction _:
case cUiProcessSearchHistoryEntry _: case cUiProcessSearchHistoryEntry _:
case cUiProcessTicketOverviewRelationAction _:
break; break;
default: default:
var _t = e.UiAction?.GetType().Name; var _t = e.UiAction?.GetType().Name;
@@ -1589,7 +1740,8 @@ namespace FasdDesktopUi.Pages.SearchPage
} }
SetSearchResultVisibility(true); SetSearchResultVisibility(true);
if (!await e.UiAction.RunUiActionAsync(sender, null, false, null)) var actionResult = await e.UiAction.RunUiActionAsync(sender, null, false, null);
if (!(e.UiAction is cUiProcessTicketOverviewRelationAction) && !actionResult)
CancledSearchAction(); CancledSearchAction();
} }
catch (Exception E) catch (Exception E)

View File

@@ -887,4 +887,80 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D6F46847-581A-4FAF-90DC-52C761AAF559} SolutionGuid = {D6F46847-581A-4FAF-90DC-52C761AAF559}
EndGlobalSection EndGlobalSection
GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 14
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = https://consulting4it.visualstudio.com/
SccProjectUniqueName0 = FasdExcelToJsonConverter\\F4SD-ExcelToJson-Converter.csproj
SccProjectName0 = FasdExcelToJsonConverter
SccAuxPath0 = https://consulting4it.visualstudio.com
SccLocalPath0 = FasdExcelToJsonConverter
SccProvider0 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName1 = FasdCockpitBase\\F4SD-Cockpit-Client-Base.csproj
SccProjectName1 = FasdCockpitBase
SccAuxPath1 = https://consulting4it.visualstudio.com
SccLocalPath1 = FasdCockpitBase
SccProvider1 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName2 = FasdDesktopUi\\F4SD-Cockpit-Client.csproj
SccProjectName2 = FasdDesktopUi
SccAuxPath2 = https://consulting4it.visualstudio.com
SccLocalPath2 = FasdDesktopUi
SccProvider2 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName3 = FasdCockpitCommunicationDemo\\F4SD-Cockpit-Client-Demo.csproj
SccProjectName3 = FasdCockpitCommunicationDemo
SccAuxPath3 = https://consulting4it.visualstudio.com
SccLocalPath3 = FasdCockpitCommunicationDemo
SccProvider3 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName4 = FasdCockpitCommunication\\F4SD-Cockpit-Client-Communication.csproj
SccProjectName4 = FasdCockpitCommunication
SccAuxPath4 = https://consulting4it.visualstudio.com
SccLocalPath4 = FasdCockpitCommunication
SccProvider4 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName5 = IpRangeToConfigConverter\\F4SD-IpRangeToXml-Converter.csproj
SccProjectTopLevelParentUniqueName5 = FasdTestSolution.sln
SccProjectName5 = IpRangeToConfigConverter
SccAuxPath5 = https://consulting4it.visualstudio.com
SccLocalPath5 = IpRangeToConfigConverter
SccProvider5 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName6 = F4SD-PhoneMonitor\\F4SD-PhoneMonitor.csproj
SccProjectName6 = F4SD-PhoneMonitor
SccAuxPath6 = https://consulting4it.visualstudio.com
SccLocalPath6 = F4SD-PhoneMonitor
SccProvider6 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName7 = F4SD-Logging\\F4SD-Logging.csproj
SccProjectName7 = F4SD-Logging
SccAuxPath7 = https://consulting4it.visualstudio.com
SccLocalPath7 = F4SD-Logging
SccProvider7 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName8 = F4SD_IconPicker\\F4SDicons\\F4SD_IconPicker.csproj
SccProjectName8 = F4SD_IconPicker/F4SDicons
SccAuxPath8 = https://consulting4it.visualstudio.com
SccLocalPath8 = F4SD_IconPicker\\F4SDicons
SccProvider8 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName9 = F4SD-AdaptableIcon\\F4SD-AdaptableIcon.csproj
SccProjectName9 = F4SD-AdaptableIcon
SccAuxPath9 = https://consulting4it.visualstudio.com
SccLocalPath9 = F4SD-AdaptableIcon
SccProvider9 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName10 = F4SD-AdaptableIcon-Export\\F4SD-AdaptableIcon-Export.csproj
SccProjectName10 = F4SD-AdaptableIcon-Export
SccAuxPath10 = https://consulting4it.visualstudio.com
SccLocalPath10 = F4SD-AdaptableIcon-Export
SccProvider10 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName11 = F4SD_IconPicker\\SetupIconPicker\\Setup_IconPicker.wixproj
SccProjectName11 = F4SD_IconPicker/SetupIconPicker
SccAuxPath11 = https://consulting4it.visualstudio.com
SccLocalPath11 = F4SD_IconPicker\\SetupIconPicker
SccProvider11 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName12 = Setup_Client\\Setup_Client.wixproj
SccProjectName12 = Setup_Client
SccAuxPath12 = https://consulting4it.visualstudio.com
SccLocalPath12 = Setup_Client
SccProvider12 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccProjectUniqueName13 = Setup_IconPicker_v4\\Setup_IconPicker_v4.wixproj
SccProjectName13 = Setup_IconPicker_v4
SccAuxPath13 = https://consulting4it.visualstudio.com
SccLocalPath13 = Setup_IconPicker_v4
SccProvider13 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
EndGlobalSection
EndGlobal EndGlobal