feat(notification-outbox): add outbox KPI tiles to Health dashboard
This commit is contained in:
@@ -4,9 +4,12 @@
|
||||
@using ScadaLink.Commons.Entities.Sites
|
||||
@using ScadaLink.Commons.Interfaces.Repositories
|
||||
@using ScadaLink.HealthMonitoring
|
||||
@using ScadaLink.Commons.Messages.Notification
|
||||
@using ScadaLink.Communication
|
||||
@implements IDisposable
|
||||
@inject ICentralHealthAggregator HealthAggregator
|
||||
@inject ISiteRepository SiteRepository
|
||||
@inject CommunicationService CommunicationService
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
@@ -17,6 +20,39 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Notification Outbox headline KPIs — a central concern, shown regardless of site reports *@
|
||||
<h6 class="text-muted mb-2">Notification Outbox</h6>
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-lg-4 col-md-6 col-12">
|
||||
<div class="card h-100">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="mb-0">@OutboxTileValue(_outboxKpi.QueueDepth)</h3>
|
||||
<small class="text-muted">Queue Depth</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6 col-12">
|
||||
<div class="card h-100 @(_outboxKpiAvailable && _outboxKpi.StuckCount > 0 ? "border-warning" : "")">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="mb-0 @(_outboxKpiAvailable && _outboxKpi.StuckCount > 0 ? "text-warning" : "")">@OutboxTileValue(_outboxKpi.StuckCount)</h3>
|
||||
<small class="text-muted">Stuck</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6 col-12">
|
||||
<div class="card h-100 @(_outboxKpiAvailable && _outboxKpi.ParkedCount > 0 ? "border-danger" : "")">
|
||||
<div class="card-body text-center">
|
||||
<h3 class="mb-0 @(_outboxKpiAvailable && _outboxKpi.ParkedCount > 0 ? "text-danger" : "")">@OutboxTileValue(_outboxKpi.ParkedCount)</h3>
|
||||
<small class="text-muted">Parked</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (!_outboxKpiAvailable && _outboxKpiError != null)
|
||||
{
|
||||
<div class="text-muted small mb-3">Notification Outbox KPIs unavailable: @_outboxKpiError</div>
|
||||
}
|
||||
|
||||
@if (_siteStates.Count == 0)
|
||||
{
|
||||
<div class="alert alert-info">No site health reports received yet.</div>
|
||||
@@ -294,6 +330,12 @@
|
||||
private Timer? _refreshTimer;
|
||||
private int _autoRefreshSeconds = 10;
|
||||
|
||||
// Notification Outbox headline KPIs, refreshed alongside the site states.
|
||||
private NotificationKpiResponse _outboxKpi =
|
||||
new(string.Empty, true, null, 0, 0, 0, 0, null);
|
||||
private bool _outboxKpiAvailable;
|
||||
private string? _outboxKpiError;
|
||||
|
||||
private static bool SiteHasActiveErrors(SiteHealthState state)
|
||||
{
|
||||
var report = state.LatestReport;
|
||||
@@ -316,22 +358,53 @@
|
||||
// Non-fatal — fall back to showing siteId only
|
||||
}
|
||||
|
||||
RefreshNow();
|
||||
await RefreshNow();
|
||||
_refreshTimer = new Timer(_ =>
|
||||
{
|
||||
InvokeAsync(() =>
|
||||
InvokeAsync(async () =>
|
||||
{
|
||||
RefreshNow();
|
||||
await RefreshNow();
|
||||
StateHasChanged();
|
||||
});
|
||||
}, null, TimeSpan.FromSeconds(_autoRefreshSeconds), TimeSpan.FromSeconds(_autoRefreshSeconds));
|
||||
}
|
||||
|
||||
private void RefreshNow()
|
||||
private async Task RefreshNow()
|
||||
{
|
||||
_siteStates = HealthAggregator.GetAllSiteStates();
|
||||
await LoadOutboxKpis();
|
||||
}
|
||||
|
||||
private async Task LoadOutboxKpis()
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await CommunicationService.GetNotificationKpisAsync(
|
||||
new NotificationKpiRequest(Guid.NewGuid().ToString("N")));
|
||||
if (response.Success)
|
||||
{
|
||||
_outboxKpi = response;
|
||||
_outboxKpiAvailable = true;
|
||||
_outboxKpiError = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_outboxKpiAvailable = false;
|
||||
_outboxKpiError = response.ErrorMessage ?? "KPI query failed.";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_outboxKpiAvailable = false;
|
||||
_outboxKpiError = $"KPI query failed: {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
// Tiles show the numeric KPI when available, or an em dash when the outbox
|
||||
// KPI query failed — matching how the page renders other unavailable data.
|
||||
private string OutboxTileValue(int value) =>
|
||||
_outboxKpiAvailable ? value.ToString() : "—";
|
||||
|
||||
private string GetSiteName(string siteId)
|
||||
{
|
||||
return _siteNames.GetValueOrDefault(siteId, siteId);
|
||||
|
||||
Reference in New Issue
Block a user