aktueller Stand

This commit is contained in:
Meik
2026-01-28 12:08:39 +01:00
parent 1283750829
commit ee1f54675e
104 changed files with 6797 additions and 1867 deletions

View File

@@ -0,0 +1,274 @@
using C4IT.FASD.Base;
using C4IT.FASD.Cockpit.Communication;
using C4IT.Logging;
using FasdDesktopUi.Basics.CustomEvents;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Pages.DetailsPage.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Services.SupportCase
{
/// <summary>
/// Used for processing raw data of a <see cref="ISupportCase"/> for the UI in a certain way.
/// </summary>
internal class SupportCaseProcessor
{
private ISupportCase _supportCase;
public cSupportCaseDataProvider SupportCaseDataProviderArtifact { get => _supportCase?.SupportCaseDataProviderArtifact; }
private readonly Dictionary<cF4sdApiSearchResultRelation, cDetailsPageData> _detailsPageDataCache = new Dictionary<cF4sdApiSearchResultRelation, cDetailsPageData>();
private readonly Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, object>> _namedParameterCache = new Dictionary<cF4sdApiSearchResultRelation, Dictionary<string, object>>();
internal void SetSupportCase(ISupportCase supportCase)
{
if (_supportCase != null)
{
_supportCase.CaseRelationsAdded -= HandleSupportCaseRelationsAdded;
_supportCase.SupportCaseDataCacheHasChanged -= HandleSupportCaseDataCacheHasChanged;
}
_supportCase = supportCase;
_supportCase.CaseRelationsAdded += HandleSupportCaseRelationsAdded;
_supportCase.SupportCaseDataCacheHasChanged += HandleSupportCaseDataCacheHasChanged;
}
private void HandleSupportCaseRelationsAdded(object sender, RelationEventArgs e)
=> AvailableCaseRelationsAdded?.Invoke(this, e);
private async void HandleSupportCaseDataCacheHasChanged(object sender, SupportCaseDataEventArgs e)
{
bool isArtifactShowingCorrectHealthCard
= SupportCaseDataProviderArtifact.HealthCardDataHelper.SelectedHealthCard == GetHealthcardFor(e.Relation);
if (!isArtifactShowingCorrectHealthCard)
{
// todo this can probably be removed, as soon as the last dependency of the SupportCaseDataProviderArtifact is gone.
// till then the detailspageData gets overriden with the detailspageData of the new relation.
// However, the removal shouldn't be much of a problem, due to the fact the Artifact also stores the raw data
_detailsPageDataCache.Remove(e.Relation);
return;
}
if (_detailsPageDataCache.TryGetValue(e.Relation, out var cachedData))
{
cDetailsPageData detailData = _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataWithoutHeading();
cachedData.WidgetData = detailData.WidgetData;
cachedData.DataHistoryList = detailData.DataHistoryList;
cachedData.MenuBarData = detailData.MenuBarData;
cachedData.DataContainerCollectionList = detailData.DataContainerCollectionList;
}
else
{
_detailsPageDataCache[e.Relation] = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync();
}
UpdateNamedParameters(e.Relation, e.DataTables);
CaseDataChanged?.Invoke(this, e);
}
private void UpdateNamedParameters(cF4sdApiSearchResultRelation relation, IEnumerable<cF4SDHealthCardRawData.cHealthCardTable> dataTables)
{
try
{
if (!_namedParameterCache.ContainsKey(relation))
_namedParameterCache.Add(relation, new Dictionary<string, object>());
var healthcard = GetHealthcardFor(relation);
foreach (var namedParameter in cHealthCardPrerequisites.GetNamedParameters(healthcard).Values)
{
var table = dataTables.FirstOrDefault(t => t.Name == namedParameter.DatabaseInfo.ValueTable);
if (table is null)
continue;
if (!table.Columns.TryGetValue(namedParameter.DatabaseInfo.ValueColumn, out var column))
continue;
string value = cUtility.RawValueFormatter.GetDisplayValue(column.Values.FirstOrDefault(), namedParameter.Display);
_namedParameterCache[relation][namedParameter.ParameterName] = value;
}
}
catch (Exception ex)
{
LogException(ex);
}
}
public async Task LoadSupportCaseDataAsync(cF4sdApiSearchResultRelation relation, IEnumerable<string> tablesToLoad)
{
_ = Task.Run(async () => await _supportCase.LoadSupportCaseDataAsync(relation, tablesToLoad.Where(t => !t.Contains("-details-"))));
if (!_detailsPageDataCache.TryGetValue(relation, out var detailsData))
{
detailsData = await _supportCase.SupportCaseDataProviderArtifact.HealthCardDataHelper.DetailPage.GetDataAsync();
_detailsPageDataCache.Add(relation, detailsData);
}
CaseDataChanged?.Invoke(this, new SupportCaseDataEventArgs());
}
public async Task UpdateLatestCaseDataFor(cF4sdApiSearchResultRelation relation)
{
try
{
int? agentUserId = relation.Identities.FirstOrDefault(i => i.Class == enumFasdInformationClass.User)?.agentId;
int? agentDeviceId = relation.Identities.FirstOrDefault(i => i.Class == enumFasdInformationClass.Computer)?.agentId;
await ActualizeDataAsync(agentUserId, agentDeviceId);
_supportCase.InvalidateLatestCaseDataCacheFor(relation, out var invalidatedTables);
_detailsPageDataCache.Remove(relation);
await _supportCase.LoadSupportCaseDataAsync(relation, invalidatedTables.Select(t => t.Name));
}
catch (Exception ex)
{
LogException(ex);
}
}
private async Task<enumActualizeStatus> ActualizeDataAsync(int? agentUserId, int? agentDeviceId)
{
var status = enumActualizeStatus.unknown;
try
{
TimeSpan refreshDelay = TimeSpan.FromMilliseconds(500);
const int maxPollCount = 20;
if (!agentDeviceId.HasValue)
{
LogEntry("Coudldn't acutalize data. There was no valid AgentDeviceId found.", LogLevels.Error);
return status;
}
var taskId = await cFasdCockpitCommunicationBase.Instance.ActualizeAgentData(agentDeviceId.Value, agentUserId);
if (taskId == Guid.Empty)
return enumActualizeStatus.failed;
enumFasdInformationClass informationClass = agentUserId != null ? enumFasdInformationClass.User : enumFasdInformationClass.Computer;
int pollCount = 0;
do
{
status = await cFasdCockpitCommunicationBase.Instance.GetActualizeAgentDataStatus(taskId, informationClass);
if (status == enumActualizeStatus.unknown)
{
pollCount++;
if (pollCount >= maxPollCount)
return status;
await Task.Delay(refreshDelay);
}
} while (status == enumActualizeStatus.unknown);
}
catch (Exception E)
{
LogException(E);
}
return status;
}
internal ILookup<enumFasdInformationClass, cF4sdApiSearchResultRelation> GetCaseRelations()
=> _supportCase.GetCaseRelations();
internal cHealthCard GetHealthcardFor(cF4sdApiSearchResultRelation relation)
{
var availableHealthCards = cF4SDCockpitXmlConfig.Instance?.HealthCardConfig?.HealthCards?.Values;
if (availableHealthCards is null || availableHealthCards.Count == 0)
return null;
return availableHealthCards
.FirstOrDefault(hc =>
hc.InformationClasses.All(i => i == cF4sdIdentityEntry.GetFromSearchResult(relation.Type))
&& HasCockpitUserRequiredRoles(hc.RequiredRoles));
}
private static bool HasCockpitUserRequiredRoles(List<string> requiredRoles)
{
try
{
if (requiredRoles is null || requiredRoles.Count == 0)
return true;
List<string> roles = null;
lock (cFasdCockpitCommunicationBase.CockpitUserInfoLock)
{
roles = cFasdCockpitCommunicationBase.CockpitUserInfo?.Roles;
}
if (roles is null || roles.Count == 0)
return false;
foreach (var requiredRole in requiredRoles)
{
if (roles.Contains(requiredRole, StringComparer.InvariantCultureIgnoreCase))
return true;
}
}
catch (Exception E)
{
LogException(E);
}
return false;
}
public List<List<cWidgetValueModel>> GetWidgetData(cF4sdApiSearchResultRelation relation)
{
List<List<cWidgetValueModel>> widgetData = null;
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
widgetData = detailsData?.WidgetData;
return widgetData ?? new List<List<cWidgetValueModel>>();
}
public cDetailsPageDataHistoryDataModel GetHistoryData(cF4sdApiSearchResultRelation relation)
{
cDetailsPageDataHistoryDataModel historyData = null;
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
historyData = detailsData?.DataHistoryList;
return historyData ?? new cDetailsPageDataHistoryDataModel();
}
public List<cContainerCollectionData> GetContainerData(cF4sdApiSearchResultRelation relation)
{
List<cContainerCollectionData> containerData = null;
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
containerData = detailsData?.DataContainerCollectionList;
return containerData ?? new List<cContainerCollectionData>();
}
public List<cMenuDataBase> GetMenuBarData(cF4sdApiSearchResultRelation relation)
{
List<cMenuDataBase> menuData = null;
if (_detailsPageDataCache.TryGetValue(relation, out var detailsData))
menuData = detailsData?.MenuBarData;
return menuData ?? new List<cMenuDataBase>();
}
/// <summary>
/// Raised when newly available relations for a support case were added.
/// </summary>
public event EventHandler<RelationEventArgs> AvailableCaseRelationsAdded;
/// <summary>
/// Raised when the data set of a support case has changed.
/// </summary>
public event EventHandler<SupportCaseDataEventArgs> CaseDataChanged;
}
}