inital
This commit is contained in:
538
FasdDesktopUi/Basics/UiActions/ShowDetailedDataAction.cs
Normal file
538
FasdDesktopUi/Basics/UiActions/ShowDetailedDataAction.cs
Normal file
@@ -0,0 +1,538 @@
|
||||
using C4IT.F4SD.DisplayFormatting;
|
||||
using C4IT.FASD.Base;
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using C4IT.Logging;
|
||||
using C4IT.MultiLanguage;
|
||||
using FasdDesktopUi.Basics.Models;
|
||||
using FasdDesktopUi.Basics.UserControls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
using static C4IT.FASD.Base.cF4SDHealthCardRawData;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.UiActions
|
||||
{
|
||||
public class cShowDetailedDataAction : cUiActionBase
|
||||
{
|
||||
private static readonly Dictionary<cF4sdIdentityList, Dictionary<string, cF4SDHealthCardRawData.cHealthCardDetailsTable>> CachedDetails = new Dictionary<cF4sdIdentityList, Dictionary<string, cF4SDHealthCardRawData.cHealthCardDetailsTable>>();
|
||||
|
||||
private cSupportCaseDataProvider DataProvider;
|
||||
|
||||
private readonly cHealthCardStateBase StateDefinition;
|
||||
|
||||
private int DayIndex { get; set; }
|
||||
|
||||
private string DetailsTitle { get; set; }
|
||||
|
||||
private string Recommendation { get; set; }
|
||||
|
||||
private cHealthCardDetailsTable ValuedDetailsData = null;
|
||||
|
||||
public cShowDetailedDataAction(cHealthCardStateBase StateDefinition, int DayIndex = 0, cHealthCardDetailsTable ValuedDetailsData = null)
|
||||
{
|
||||
this.StateDefinition = StateDefinition;
|
||||
this.DayIndex = DayIndex;
|
||||
this.DetailsTitle = StateDefinition.Names.GetValue();
|
||||
this.Recommendation = StateDefinition.Descriptions.GetValue();
|
||||
if (this.Recommendation == String.Empty)
|
||||
this.Recommendation = null;
|
||||
this.ValuedDetailsData = ValuedDetailsData;
|
||||
}
|
||||
|
||||
public override async Task<bool> RunUiActionAsync(object sender, UIElement UiLocation, bool isDetailedLayout, cSupportCaseDataProvider dataProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(UiLocation is Decorator decorator))
|
||||
return false;
|
||||
|
||||
DataProvider = dataProvider;
|
||||
DataProvider.HealthCardDataHelper.DataRefreshed += (s, e) => CachedDetails.Clear();
|
||||
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
|
||||
if (StateDefinition.Details is cHealthCardDetailsValued)
|
||||
{
|
||||
if (ValuedDetailsData == null)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!await LoadDetailsDataAsync())
|
||||
return false;
|
||||
}
|
||||
|
||||
cDetailedDataModel detailedData = null;
|
||||
cDetailedChartModel detailedChartData = null;
|
||||
cChartModel chartData = null;
|
||||
if (StateDefinition.Details is cHealthCardDetailsValued)
|
||||
{
|
||||
detailedData = GetValuedDataModel();
|
||||
}
|
||||
else
|
||||
{
|
||||
detailedData = GetDetailedData();
|
||||
detailedChartData = GetDetailedChartData();
|
||||
chartData = GetChartData();
|
||||
}
|
||||
cRecommendationDataModel recommendationDataModel = Recommendation != null ? new cRecommendationDataModel() { Category = DetailsTitle, Recommendation = Recommendation } : null;
|
||||
|
||||
if (decorator.Child is DataCanvas existingDataCanvas)
|
||||
{
|
||||
var tempDataCanvasData = new cDataCanvasDataModel() { QuickActionStatusMonitorData = null, DetailedData = detailedData, DetailedChartData = detailedChartData, ChartData = chartData, RecommendationData = recommendationDataModel };
|
||||
if (!(StateDefinition.Details is cHealthCardDetailsValued))
|
||||
{
|
||||
tempDataCanvasData.GetDetailedDataAsync = GetRefreshedDetailedDataAsync;
|
||||
tempDataCanvasData.GetChartDataAsync = GetRefreshedChartDataAsync;
|
||||
tempDataCanvasData.GetDatailedChartDataAsync = GetRefreshedDetailsChartDataAsync;
|
||||
}
|
||||
|
||||
existingDataCanvas.DataCanvasData = tempDataCanvasData;
|
||||
existingDataCanvas.IsDetailedLayout = isDetailedLayout;
|
||||
existingDataCanvas.DataProvider = DataProvider;
|
||||
existingDataCanvas.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataCanvas dataCanvas = new DataCanvas() { DataCanvasData = new cDataCanvasDataModel() { DetailedData = detailedData, DetailedChartData = detailedChartData, ChartData = chartData, RecommendationData = recommendationDataModel }, IsDetailedLayout = isDetailedLayout, DataProvider = DataProvider };
|
||||
if (!(StateDefinition.Details is cHealthCardDetailsValued))
|
||||
{
|
||||
dataCanvas.DataCanvasData.GetDetailedDataAsync = GetRefreshedDetailedDataAsync;
|
||||
dataCanvas.DataCanvasData.GetChartDataAsync = GetRefreshedChartDataAsync;
|
||||
dataCanvas.DataCanvasData.GetDatailedChartDataAsync = GetRefreshedDetailsChartDataAsync;
|
||||
}
|
||||
|
||||
decorator.Child = dataCanvas;
|
||||
}
|
||||
|
||||
decorator.Visibility = Visibility.Visible;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Mouse.OverrideCursor = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task<bool> LoadDetailsDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StateDefinition == null || StateDefinition.Details == null)
|
||||
return false;
|
||||
|
||||
if (!(StateDefinition.Details is cHealthCardDetails _details) || _details.Table == null)
|
||||
return false;
|
||||
|
||||
if (CachedDetails.TryGetValue(DataProvider.Identities, out var cachedDetailsForIdentities))
|
||||
{
|
||||
if (cachedDetailsForIdentities.TryGetValue(_details.Table, out _))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
cachedDetailsForIdentities = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardDetailsTable>();
|
||||
|
||||
cF4sdHealthCardRawDataRequest requestData = new cF4sdHealthCardRawDataRequest()
|
||||
{
|
||||
Identities = DataProvider.Identities,
|
||||
MaxAge = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.SearchResultAge,
|
||||
Tables = StateDefinition.GetRequiredTables()
|
||||
};
|
||||
|
||||
var detailsData = await cFasdCockpitCommunicationBase.Instance.GetDetailsData(requestData);
|
||||
|
||||
if (detailsData.Any(data => data.Name == _details.Table) || detailsData.Any(data => data.Name == StateDefinition.DetailedChartDetails?.ValueTable) || detailsData.Any(data => data.Name == StateDefinition.ChartDetails?.ValueTable))
|
||||
{
|
||||
if (StateDefinition.Details != null && detailsData.Any(data => data.Name == _details.Table))
|
||||
{
|
||||
if (!cachedDetailsForIdentities.ContainsKey(_details.Table))
|
||||
cachedDetailsForIdentities.Add(_details.Table, detailsData.First(data => data.Name == _details.Table));
|
||||
if (!CachedDetails.ContainsKey(DataProvider.Identities))
|
||||
CachedDetails.Add(DataProvider.Identities, cachedDetailsForIdentities);
|
||||
}
|
||||
if (StateDefinition.DetailedChartDetails != null && detailsData.Any(data => data.Name == StateDefinition.DetailedChartDetails.ValueTable))
|
||||
{
|
||||
if (!cachedDetailsForIdentities.ContainsKey(StateDefinition.DetailedChartDetails.ValueTable))
|
||||
cachedDetailsForIdentities.Add(StateDefinition.DetailedChartDetails.ValueTable, detailsData.First(data => data.Name == StateDefinition.DetailedChartDetails.ValueTable));
|
||||
if (!CachedDetails.ContainsKey(DataProvider.Identities))
|
||||
CachedDetails.Add(DataProvider.Identities, cachedDetailsForIdentities);
|
||||
}
|
||||
if (StateDefinition.ChartDetails != null && detailsData.Any(data => data.Name == StateDefinition.ChartDetails.ValueTable))
|
||||
{
|
||||
if (!cachedDetailsForIdentities.ContainsKey(StateDefinition.ChartDetails.ValueTable))
|
||||
cachedDetailsForIdentities.Add(StateDefinition.ChartDetails.ValueTable, detailsData.First(data => data.Name == StateDefinition.ChartDetails.ValueTable));
|
||||
if (!CachedDetails.ContainsKey(DataProvider.Identities))
|
||||
CachedDetails.Add(DataProvider.Identities, cachedDetailsForIdentities);
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateProcessorStateDefinition()
|
||||
{
|
||||
// correct an error in older definitions of table agnt-computer-event-details-processorUsage
|
||||
try
|
||||
{
|
||||
var oldFromColumn = StateDefinition.Details.FirstOrDefault(column => column.Name == "From");
|
||||
var oldToColumn = StateDefinition.Details.FirstOrDefault(column => column.Name == "To");
|
||||
|
||||
if (oldFromColumn is null || oldToColumn is null)
|
||||
return;
|
||||
|
||||
if (oldFromColumn.Column != "Duration" || oldToColumn.Column != "time")
|
||||
return;
|
||||
|
||||
oldFromColumn.Column = "time";
|
||||
oldToColumn.Column = "Duration.add";
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessDetailValue(string processintType, ref object rawValue, DateTime timeColumnValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rawValue is Int64 milliSec)
|
||||
{
|
||||
switch (processintType)
|
||||
{
|
||||
case "add":
|
||||
rawValue = timeColumnValue.AddMilliseconds(milliSec);
|
||||
break;
|
||||
case "sub":
|
||||
rawValue = timeColumnValue.AddMilliseconds(-milliSec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private cDetailedDataModel GetValuedDataModel()
|
||||
{
|
||||
if (!(StateDefinition.Details is cHealthCardDetailsValued _details) || ValuedDetailsData == null)
|
||||
return null;
|
||||
|
||||
if (ValuedDetailsData.Columns.Count > 1)
|
||||
return null;
|
||||
|
||||
var _rowHeadings = _details.Select(v => v.Names.GetValue() as object).ToList();
|
||||
cDetailedDataModel output = new cDetailedDataModel()
|
||||
{
|
||||
Heading = StateDefinition.Names.GetValue(),
|
||||
FullDetailedData = new List<object>(),
|
||||
HasColumnHeaders = _rowHeadings.Count > 1
|
||||
};
|
||||
|
||||
if (_rowHeadings.Count > 1)
|
||||
output.FullDetailedData.Add(_rowHeadings);
|
||||
|
||||
var _data = ValuedDetailsData.Values[0];
|
||||
foreach (var _row in _data)
|
||||
output.FullDetailedData.Add(new List<object>() { _row[0] });
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private cDetailedDataModel GetDetailedData()
|
||||
{
|
||||
try
|
||||
{
|
||||
const string timeColumnName = "time";
|
||||
cDetailedDataModel output = new cDetailedDataModel() { FullDetailedData = new List<object>() };
|
||||
|
||||
string dateAddtionFormat = cMultiLanguageSupport.GetItem("DetailsPage.History.Details");
|
||||
string dateAddition = string.Format(dateAddtionFormat, DateTime.Today.AddDays(-DayIndex).ToString("d", new CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage)));
|
||||
string detailedDataHeading = "Details - " + DetailsTitle + dateAddition;
|
||||
output.Heading = detailedDataHeading;
|
||||
|
||||
if (!(StateDefinition.Details is cHealthCardDetails _details) || _details.Table == null)
|
||||
return null;
|
||||
|
||||
// correct an error in older definitions of table agnt-computer-event-details-processorUsage
|
||||
if (_details.Table == "agnt-computer-event-details-processorUsage")
|
||||
UpdateProcessorStateDefinition();
|
||||
|
||||
var headerValues = StateDefinition.Details.Select(value => value.Names.GetValue());
|
||||
output.FullDetailedData.Add(headerValues.ToList<object>());
|
||||
|
||||
var detailsData = CachedDetails[DataProvider.Identities][_details.Table];
|
||||
|
||||
if (!detailsData.Values.TryGetValue(DayIndex, out var details))
|
||||
return output;
|
||||
|
||||
int columnCount = StateDefinition.Details.Count;
|
||||
List<int> rawColumnIndexes = new List<int>(columnCount);
|
||||
List<RawValueType> displayTypes = new List<RawValueType>(columnCount);
|
||||
List<string> valueProcessings = new List<string>(columnCount);
|
||||
int timeColumnIndex = detailsData.Columns.IndexOf(timeColumnName);
|
||||
int filterColumnIndex = detailsData.Columns.IndexOf(StateDefinition.Details?.Filter?.FilterColumn);
|
||||
|
||||
foreach (var columnDefinition in StateDefinition.Details)
|
||||
{
|
||||
var splitColumnName = columnDefinition.Column.Split('.');
|
||||
|
||||
var rawColumnIndex = detailsData.Columns.IndexOf(splitColumnName[0]);
|
||||
var displayType = columnDefinition.DisplayType;
|
||||
var valueProcessing = splitColumnName.Length > 1 ? splitColumnName[1] : null;
|
||||
|
||||
rawColumnIndexes.Add(rawColumnIndex);
|
||||
displayTypes.Add(cUtility.GetRawValueType(displayType));
|
||||
valueProcessings.Add(valueProcessing);
|
||||
}
|
||||
|
||||
foreach (var detailsRow in details)
|
||||
{
|
||||
var displayValuesOfRow = new List<object>(columnCount);
|
||||
|
||||
var displayTypeEnumerator = displayTypes.GetEnumerator();
|
||||
var valueProcessingsEnumerator = valueProcessings.GetEnumerator();
|
||||
bool shouldHideRow = false;
|
||||
|
||||
if (StateDefinition.Details.Filter != null && !rawColumnIndexes.Contains(filterColumnIndex))
|
||||
{
|
||||
bool columnValueMatchesFilterValue = StateDefinition.Details.Filter.FilterValues.Contains(detailsRow[filterColumnIndex]);
|
||||
if (!columnValueMatchesFilterValue)
|
||||
shouldHideRow = true;
|
||||
}
|
||||
|
||||
IRawValueFormatter rawValueFormatter = new RawValueFormatter();
|
||||
rawValueFormatter.SetDefaultCulture(new System.Globalization.CultureInfo(cFasdCockpitConfig.Instance.SelectedLanguage));
|
||||
|
||||
foreach (var index in rawColumnIndexes)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (shouldHideRow)
|
||||
continue;
|
||||
|
||||
if (detailsRow.Length < index || !displayTypeEnumerator.MoveNext() || !valueProcessingsEnumerator.MoveNext())
|
||||
continue;
|
||||
|
||||
var rawDetailValue = detailsRow[index];
|
||||
|
||||
if (index == filterColumnIndex
|
||||
&& !StateDefinition.Details.Filter.FilterValues.Contains(rawDetailValue))
|
||||
{
|
||||
shouldHideRow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (valueProcessingsEnumerator.Current != null)
|
||||
if (detailsRow[timeColumnIndex] is DateTime timeColumnValue)
|
||||
ProcessDetailValue(valueProcessingsEnumerator.Current, ref rawDetailValue, timeColumnValue);
|
||||
|
||||
var displayValue = rawValueFormatter.GetDisplayValue(rawDetailValue, displayTypeEnumerator.Current);
|
||||
displayValuesOfRow.Add(displayValue);
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldHideRow)
|
||||
continue;
|
||||
|
||||
output.FullDetailedData.Add(displayValuesOfRow);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private cDetailedChartModel GetDetailedChartData()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StateDefinition?.DetailedChartDetails is null)
|
||||
return null;
|
||||
|
||||
var detailsDataTable = CachedDetails[DataProvider.Identities][StateDefinition.DetailedChartDetails.ValueTable];
|
||||
|
||||
int valueIndex = detailsDataTable.Columns.IndexOf(StateDefinition.DetailedChartDetails.ValueColumn);
|
||||
int timeIndex = detailsDataTable.Columns.IndexOf(StateDefinition.DetailedChartDetails.TimeColumn);
|
||||
int durationIndex = detailsDataTable.Columns.IndexOf(StateDefinition.DetailedChartDetails.DurationColumn);
|
||||
string title = StateDefinition.Names.GetValue();
|
||||
bool isThresholdActive = StateDefinition is cHealthCardStateLevel;
|
||||
|
||||
var output = new cDetailedChartModel()
|
||||
{
|
||||
Data = detailsDataTable.Values[DayIndex],
|
||||
ValueIndex = valueIndex,
|
||||
TimeIndex = timeIndex,
|
||||
DurationIndex = durationIndex,
|
||||
ChartTitle = title,
|
||||
IsThresholdActive = isThresholdActive,
|
||||
};
|
||||
|
||||
if (StateDefinition is cHealthCardStateLevel stateLevelDefinition)
|
||||
{
|
||||
output.WarningThreshold = stateLevelDefinition.Warning;
|
||||
output.ErrorThreshold = stateLevelDefinition.Error;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private cChartModel GetChartData()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StateDefinition?.ChartDetails is null)
|
||||
return null;
|
||||
|
||||
var detailsDataTable = CachedDetails[DataProvider.Identities][StateDefinition.ChartDetails.ValueTable];
|
||||
|
||||
int valueIndex = detailsDataTable.Columns.IndexOf(StateDefinition.ChartDetails.ValueColumn);
|
||||
int timeIndex = detailsDataTable.Columns.IndexOf(StateDefinition.ChartDetails.TimeColumn);
|
||||
int durationIndex = detailsDataTable.Columns.IndexOf(StateDefinition.ChartDetails.DurationColumn);
|
||||
string title = StateDefinition.Names.GetValue();
|
||||
bool isThresholdActive = false;
|
||||
double warningThreshold = 0;
|
||||
double errorThreshold = 0;
|
||||
bool isDirectionUp = true;
|
||||
if (StateDefinition is cHealthCardStateLevel stateLevel)
|
||||
{
|
||||
isThresholdActive = true;
|
||||
warningThreshold = stateLevel.Warning;
|
||||
errorThreshold = stateLevel.Error;
|
||||
isDirectionUp = stateLevel.IsDirectionUp;
|
||||
}
|
||||
int stepLengthScale = StateDefinition.ChartDetails.StepLengthScale;
|
||||
int stepLengthLine = StateDefinition.ChartDetails.StepLengthLine;
|
||||
int maxValue = StateDefinition.ChartDetails.MaxValue;
|
||||
int minValue = StateDefinition.ChartDetails.MinValue;
|
||||
string unitFormat = StateDefinition.UnitFormat;
|
||||
|
||||
|
||||
var output = new cChartModel()
|
||||
{
|
||||
Data = detailsDataTable.Values[DayIndex],
|
||||
ValueIndex = valueIndex,
|
||||
TimeIndex = timeIndex,
|
||||
DurationIndex = durationIndex,
|
||||
ChartTitle = title,
|
||||
WarningThreshold = warningThreshold,
|
||||
ErrorThreshold = errorThreshold,
|
||||
IsThresholdActive = isThresholdActive,
|
||||
IsDirectionUp = isDirectionUp,
|
||||
StepLengthScale = stepLengthScale,
|
||||
StepLengthLine = stepLengthLine,
|
||||
MaxValue = maxValue,
|
||||
MinValue = minValue,
|
||||
UnitFormat = unitFormat,
|
||||
|
||||
};
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<cDetailedDataModel> GetRefreshedDetailedDataAsync()
|
||||
{
|
||||
cDetailedDataModel output = null;
|
||||
try
|
||||
{
|
||||
CachedDetails.Remove(DataProvider.Identities);
|
||||
|
||||
if (await LoadDetailsDataAsync())
|
||||
return GetDetailedData();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private async Task<cDetailedChartModel> GetRefreshedDetailsChartDataAsync()
|
||||
{
|
||||
cDetailedChartModel output = null;
|
||||
|
||||
try
|
||||
{
|
||||
CachedDetails.Remove(DataProvider.Identities);
|
||||
|
||||
if (await LoadDetailsDataAsync())
|
||||
return GetDetailedChartData();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private async Task<cChartModel> GetRefreshedChartDataAsync()
|
||||
{
|
||||
cChartModel output = null;
|
||||
|
||||
try
|
||||
{
|
||||
CachedDetails.Remove(DataProvider.Identities);
|
||||
|
||||
if (await LoadDetailsDataAsync())
|
||||
return GetChartData();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user