refactor(kpi): K13/K15 trend review fixups — per-metric isolation, disable-during-load + logging, loading-flag finally, test coverage
This commit is contained in:
@@ -31,12 +31,12 @@
|
||||
<div class="btn-group btn-group-sm" role="group" aria-label="Trend window">
|
||||
<button type="button"
|
||||
class="btn @(_windowHours == 24 ? "btn-secondary" : "btn-outline-secondary")"
|
||||
@onclick="() => SetWindowAsync(24)">
|
||||
@onclick="() => SetWindowAsync(24)" disabled="@_trendsLoading">
|
||||
24h
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn @(_windowHours == 168 ? "btn-secondary" : "btn-outline-secondary")"
|
||||
@onclick="() => SetWindowAsync(168)">
|
||||
@onclick="() => SetWindowAsync(168)" disabled="@_trendsLoading">
|
||||
7d
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Globalization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
@@ -56,6 +57,10 @@ public partial class AuditLogPage : IDisposable
|
||||
/// </summary>
|
||||
[Inject] private IKpiHistoryQueryService KpiHistory { get; set; } = null!;
|
||||
|
||||
/// <summary>Logger for the best-effort Trends panel — a degraded series fetch
|
||||
/// is logged at warning level so the silent fallback is still observable.</summary>
|
||||
[Inject] private ILogger<AuditLogPage> Logger { get; set; } = null!;
|
||||
|
||||
private AuditLogQueryFilter? _currentFilter;
|
||||
private AuditEventView? _selectedEvent;
|
||||
private bool _drawerOpen;
|
||||
@@ -271,6 +276,13 @@ public partial class AuditLogPage : IDisposable
|
||||
/// <summary>Whether the Trends panel is expanded (open by default).</summary>
|
||||
private bool _trendsOpen = true;
|
||||
|
||||
/// <summary>
|
||||
/// True while a window's series are being (re)fetched — disables the 24h/7d
|
||||
/// window toggle buttons so a mid-flight click cannot stack overlapping loads
|
||||
/// (mirrors the K13/K14 trend pages).
|
||||
/// </summary>
|
||||
private bool _trendsLoading;
|
||||
|
||||
/// <summary>Active window in hours — 24 (default) or 168 (7 days).</summary>
|
||||
private int _windowHours = 24;
|
||||
|
||||
@@ -297,25 +309,35 @@ public partial class AuditLogPage : IDisposable
|
||||
/// </summary>
|
||||
private async Task LoadTrendsAsync()
|
||||
{
|
||||
var toUtc = DateTime.UtcNow;
|
||||
var fromUtc = toUtc - TimeSpan.FromHours(_windowHours);
|
||||
|
||||
foreach (var (metric, _, _) in TrendMetrics)
|
||||
_trendsLoading = true;
|
||||
try
|
||||
{
|
||||
try
|
||||
var toUtc = DateTime.UtcNow;
|
||||
var fromUtc = toUtc - TimeSpan.FromHours(_windowHours);
|
||||
|
||||
foreach (var (metric, _, _) in TrendMetrics)
|
||||
{
|
||||
var points = await KpiHistory.GetSeriesAsync(
|
||||
KpiSources.AuditLog, metric, KpiScopes.Global, scopeKey: null,
|
||||
fromUtc, toUtc);
|
||||
_trendSeries[metric] = new TrendSeries(points, IsAvailable: true, ErrorMessage: null);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Best-effort: degrade this chart only, keep the rest of the page alive.
|
||||
_trendSeries[metric] = new TrendSeries(
|
||||
Points: null, IsAvailable: false, ErrorMessage: "Trend data unavailable.");
|
||||
try
|
||||
{
|
||||
var points = await KpiHistory.GetSeriesAsync(
|
||||
KpiSources.AuditLog, metric, KpiScopes.Global, scopeKey: null,
|
||||
fromUtc, toUtc);
|
||||
_trendSeries[metric] = new TrendSeries(points, IsAvailable: true, ErrorMessage: null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Best-effort: degrade this chart only, keep the rest of the page
|
||||
// alive — but log the failure so the silent fallback is observable.
|
||||
Logger.LogWarning(ex, "Failed to load Audit Log KPI trend series for metric {Metric}.", metric);
|
||||
_trendSeries[metric] = new TrendSeries(
|
||||
Points: null, IsAvailable: false, ErrorMessage: "Trend data unavailable.");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_trendsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns the rendered state for a metric, defaulting to available-empty.</summary>
|
||||
|
||||
Reference in New Issue
Block a user