From d8783e2959da9d48cc466b96d6a49bb26e95e401 Mon Sep 17 00:00:00 2001 From: Andrey Shabarshov Date: Sat, 19 Aug 2023 10:14:17 +0100 Subject: [PATCH] DEEP-41 Minor UI tweaks --- DeepTrace/Controls/ModelCard.razor | 16 +++++++---- DeepTrace/Controls/TimeSeriesChart.razor | 21 +++++++++------ DeepTrace/Pages/Index.razor | 33 ++++++++++++----------- DeepTrace/Pages/Training.razor | 34 +++++++++++++++++------- DeepTrace/Shared/MainLayout.razor | 3 +++ 5 files changed, 69 insertions(+), 38 deletions(-) diff --git a/DeepTrace/Controls/ModelCard.razor b/DeepTrace/Controls/ModelCard.razor index 5457f41..8283618 100644 --- a/DeepTrace/Controls/ModelCard.razor +++ b/DeepTrace/Controls/ModelCard.razor @@ -19,20 +19,23 @@ + + @Model?.Name[..1].ToUpper() + - @Model?.Name + @Model?.Name - @Model?.IsEnabled + @(IsEnabled ? "On" : "Off") - Current state: @_prediction.PredictedLabel - @_updated.ToString("HH:mm:ss") + Current state: @_prediction.PredictedLabel + @_updated.ToString("HH:mm:ss") -@code{ + @code{ [Parameter] public TrainedModelDefinition? Model { get; set; } @@ -41,6 +44,8 @@ private IMLProcessor? _mlProcessor; private DateTime _updated = DateTime.MinValue; + private string TextStyle => IsEnabled ? "mud-secondary-text" : ""; + protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender || Model?.Id == null) @@ -66,6 +71,7 @@ } Model.IsEnabled = value; InvokeAsync(SaveIsEnabled); + InvokeAsync(StateHasChanged); } } diff --git a/DeepTrace/Controls/TimeSeriesChart.razor b/DeepTrace/Controls/TimeSeriesChart.razor index 55d5386..d466805 100644 --- a/DeepTrace/Controls/TimeSeriesChart.razor +++ b/DeepTrace/Controls/TimeSeriesChart.razor @@ -44,12 +44,17 @@ await base.OnInitializedAsync(); } - //protected override async Task OnAfterRenderAsync(bool firstRender) - //{ - // if (firstRender) - // await UpdateChart(); - // base.OnAfterRender(firstRender); - //} + private bool _rendered = false; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + _rendered = true; + await UpdateChart(); + } + base.OnAfterRender(firstRender); + } protected override async Task OnParametersSetAsync() { @@ -73,9 +78,9 @@ return; //await InvokeAsync(StateHasChanged); - if (_currentData.Series.Count > 0) + if (_currentData.Series.Count > 0 && _rendered) { - await _chart.UpdateSeriesAsync(); + await InvokeAsync( async () => await _chart.UpdateSeriesAsync() ); await _chart.UpdateOptionsAsync(true, true, true); } await InvokeAsync(StateHasChanged); diff --git a/DeepTrace/Pages/Index.razor b/DeepTrace/Pages/Index.razor index 942d6c9..ba96631 100644 --- a/DeepTrace/Pages/Index.razor +++ b/DeepTrace/Pages/Index.razor @@ -5,32 +5,33 @@ @inject ITrainedModelStorageService TrainedModelService -Index +DeepTrace -

Hello, world!

- -Welcome to your new app. +

Dashboard

@if (_trainedModels != null) { @foreach(TrainedModelDefinition model in _trainedModels) + { + + } +} +else { - -} -} else -{ - Nothing to display + Nothing to display. Train AI models first! } -@code{ -private List _trainedModels = new(); - -protected override async Task OnInitializedAsync() +@code { - base.OnInitialized(); - _trainedModels = await TrainedModelService.Load(); -} + private List _trainedModels = new(); + + protected override async Task OnInitializedAsync() + { + base.OnInitialized(); + _trainedModels = await TrainedModelService.Load(); + + } } \ No newline at end of file diff --git a/DeepTrace/Pages/Training.razor b/DeepTrace/Pages/Training.razor index 3c3166c..2b9e28e 100644 --- a/DeepTrace/Pages/Training.razor +++ b/DeepTrace/Pages/Training.razor @@ -9,6 +9,7 @@ @using PrometheusAPI; @using System.Text; @using System.Globalization; +@using System.Collections.Concurrent; @inject PrometheusClient Prometheus @inject IDialogService DialogService @@ -271,13 +272,17 @@ var startDate = MinDate ?? (DateTime.UtcNow - TimeSpan.FromDays(30)); var endDate = MaxDate ?? DateTime.UtcNow; - - await UpdateDisplayData(startDate, endDate); + var reported = new ConcurrentDictionary(); + await UpdateDisplayData(startDate, endDate, reported); await InvokeAsync(StateHasChanged); } - private async Task UpdateDisplayData(DateTime startDate, DateTime endDate) + private async Task UpdateDisplayData( + DateTime startDate, + DateTime endDate, + ConcurrentDictionary reported + ) { // use automatic step value to always request 500 elements @@ -306,20 +311,26 @@ { if (res.Status != StatusType.Success) { - await ShowError(res.Error ?? "Error"); + var msg = res.Error ?? "Error"; + if ( reported.TryAdd(msg, true)) + await ShowError(msg); return; } if (res.ResultType != ResultTypeType.Matrix) { - await ShowError($"Got {res.ResultType}, but Matrix expected for {def.Query}"); + var msg = $"Got {res.ResultType}, but Matrix expected for {def.Query}"; + if (reported.TryAdd(msg, true)) + await ShowError(msg); return; } var m = res.AsMatrix().Result; if (m == null || m.Length != 1) { - await ShowError($"No data returned for {def.Query}"); + var msg = $"No data returned for {def.Query}"; + if (reported.TryAdd(msg, true)) + await ShowError(msg); return; } @@ -391,8 +402,13 @@ if(element is IntervalDefinition interval) { _nameBackUp = interval.Name; + var reported = new ConcurrentDictionary(); + InvokeAsync( async () => + { + await UpdateDisplayData(interval.From, interval.To, reported); + await InvokeAsync(StateHasChanged); + }); } - } private void ResetItemToOriginalValues(object element) @@ -414,10 +430,10 @@ return; var previousIntervals = _modelForm!.CurrentModel.IntervalDefinitionList; - + var reported = new ConcurrentDictionary(); foreach(var currentInterval in previousIntervals) { - await UpdateDisplayData(currentInterval.From,currentInterval.To); + await UpdateDisplayData(currentInterval.From,currentInterval.To, reported); currentInterval.Data = DisplayData!.Series; } await ModelService.Store(_modelForm!.CurrentModel); diff --git a/DeepTrace/Shared/MainLayout.razor b/DeepTrace/Shared/MainLayout.razor index b3ba4aa..03dd7f7 100644 --- a/DeepTrace/Shared/MainLayout.razor +++ b/DeepTrace/Shared/MainLayout.razor @@ -16,6 +16,9 @@ +
+ +