DEEP-41 Minor UI tweaks

This commit is contained in:
Andrey Shabarshov 2023-08-19 10:14:17 +01:00
parent b9f9c6fca3
commit d8783e2959
5 changed files with 69 additions and 38 deletions

View File

@ -19,20 +19,23 @@
<MudCard Class="card mb-3">
<MudCardHeader>
<CardHeaderAvatar>
<MudAvatar Color="MudBlazor.Color.Secondary">@Model?.Name[..1].ToUpper()</MudAvatar>
</CardHeaderAvatar>
<CardHeaderContent>
<MudText Typo="Typo.h6">@Model?.Name</MudText>
<MudText Typo="Typo.body1">@Model?.Name</MudText>
</CardHeaderContent>
<CardHeaderActions>
<MudSwitch @bind-Checked="IsEnabled"> @Model?.IsEnabled</MudSwitch>
<MudSwitch @bind-Checked="IsEnabled"> @(IsEnabled ? "On" : "Off")</MudSwitch>
</CardHeaderActions>
</MudCardHeader>
<MudCardContent>
<MudText>Current state: @_prediction.PredictedLabel</MudText>
<MudText>@_updated.ToString("HH:mm:ss")</MudText>
<MudText Class="@TextStyle">Current state: @_prediction.PredictedLabel</MudText>
<MudText Class="@TextStyle">@_updated.ToString("HH:mm:ss")</MudText>
</MudCardContent>
</MudCard>
@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);
}
}

View File

@ -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);

View File

@ -5,32 +5,33 @@
@inject ITrainedModelStorageService TrainedModelService
<PageTitle>Index</PageTitle>
<PageTitle>DeepTrace</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<h1>Dashboard</h1>
@if (_trainedModels != null)
{
@foreach(TrainedModelDefinition model in _trainedModels)
{
<ModelCard Model="@model"/>
}
}
else
{
<ModelCard Model="@model"/>
}
} else
{
<MudText>Nothing to display</MudText>
<MudText>Nothing to display. Train AI models first!</MudText>
}
@code{
private List<TrainedModelDefinition> _trainedModels = new();
protected override async Task OnInitializedAsync()
@code
{
base.OnInitialized();
_trainedModels = await TrainedModelService.Load();
}
private List<TrainedModelDefinition> _trainedModels = new();
protected override async Task OnInitializedAsync()
{
base.OnInitialized();
_trainedModels = await TrainedModelService.Load();
}
}

View File

@ -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<string, bool>();
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<string, bool> 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<string, bool>();
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<string, bool>();
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);

View File

@ -16,6 +16,9 @@
</MudAppBar>
<MudDrawer @bind-Open="_drawerOpen" ClipMode="DrawerClipMode.Always" Elevation="2">
<NavMenu />
<div class="d-flex justify-left align-end mud-height-full">
<MudSwitch @bind-Checked="@IsDarkMode" Color="MudBlazor.Color.Primary" Class="ma-4" T="bool" Label="Dark Mode" />
</div>
</MudDrawer>
<MudMainContent>
<CascadingValue Value="@IsDarkMode">