sqlinsight-pro/src/SQLInsight.Web/Components/Pages/Home.razor
Søren Eggert Lundsteen Olsen 8e1b877fda Review 1.3: overview leaves out removed instances and marks paused ones
The overview kept listing removed and paused instances with their last data and
counted them in the totals and alerts. Removed instances now disappear from the
overview, Alle fund, /api/v1/instances and /metrics (their history stays for
reports and the instance page); paused ones are shown as "Sat på pause" and
are left out of the totals, the urgent findings and the alerts (Prometheus gets
sqlinsight_instance_paused instead of instance_up = 0).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 13:22:42 +02:00

97 lines
5.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@page "/"
@inject InsightRepository Repository
@inject Display Display
<PageTitle>SQLInsight Pro</PageTitle>
<h1>Overblik</h1>
<p class="lead">Status for alle overvågede SQL Server-instanser.</p>
@if (_instances.Count == 0)
{
<div class="empty">
<p>Der er endnu ingen data. Tilføj en server under <a href="/opsaetning/instanser">Servere og databaser</a>, og tjek, at SQLInsight Agent kører.</p>
</div>
}
else
{
<PrivilegeAlert Findings="_active" ShowInstance="true" />
<div class="kpis">
<div class="kpi"><span class="kpi-icon"><Icon Name="servers" /></span><div><strong>@_monitored.Count</strong><span>instanser@(_paused > 0 ? $" (+{_paused} på pause)" : string.Empty)</span></div></div>
<div class="kpi sev-critical"><span class="kpi-icon"><Icon Name="alert" /></span><div><strong>@_monitored.Sum(i => i.Critical)</strong><span>kritiske fund</span></div></div>
<div class="kpi sev-high"><span class="kpi-icon"><Icon Name="alert" /></span><div><strong>@_monitored.Sum(i => i.High)</strong><span>høje fund</span></div></div>
<div class="kpi sev-info"><span class="kpi-icon"><Icon Name="unplug" /></span><div><strong>@_monitored.Count(i => i.IsFailing)</strong><span>kan ikke nås</span></div></div>
<div class="kpi sev-info"><span class="kpi-icon"><Icon Name="gauge" /></span><div><strong>@_monitored.Sum(i => i.NotMeasurable)</strong><span>regler ikke målbare</span></div></div>
<div class="kpi sev-info"><span class="kpi-icon"><Icon Name="list" /></span><div><strong>@_monitored.Sum(i => i.ManualChecks)</strong><span>skal tjekkes manuelt</span></div></div>
</div>
<section class="card">
<div class="card-head"><h2>Instanser</h2><span class="muted">sorteret efter alvor</span></div>
<table class="instances">
<thead>
<tr><th>Status</th><th>Instans</th><th>Version</th><th>Fund</th><th>Ikke målbar</th><th>Sidst set</th></tr>
</thead>
<tbody>
@foreach (var i in _instances.OrderBy(i => i.Paused).ThenByDescending(i => i.IsFailing).ThenByDescending(i => i.WorstSeverity ?? (Severity)(-1)).ThenBy(i => i.Name))
{
<tr class="@(i.Paused ? "paused" : string.Empty)">
<td>
@if (i.Paused)
{
<span class="badge sev-info" title="Overvågningen er sat på pause under Servere og databaser. Der kommer ingen nye fund eller alarmer, og tallene tæller ikke med i overblikket.">Sat på pause</span>
}
else if (i.IsFailing)
{
<span class="badge sev-critical" title="@i.LastError">Fejler</span>
}
else
{
<SeverityBadge Severity="i.WorstSeverity" />
}
</td>
<td><a href="/instanser/@Uri.EscapeDataString(i.Name)"><strong>@i.Name</strong></a><div class="muted">@i.ServerName</div></td>
<td>@(i.ProductVersion is null ? "–" : Display.Release(i.ProductVersion, i.EngineEdition))<div class="muted">@i.ProductVersion @i.ProductLevel @i.ProductUpdateLevel</div></td>
<td><div class="counts">
@if (i.Paused)
{
<span class="muted">sidste data før pausen</span>
}
@if (i.Critical > 0) { <SeverityBadge Severity="Severity.Critical" Count="i.Critical" /> }
@if (i.High > 0) { <SeverityBadge Severity="Severity.High" Count="i.High" /> }
@if (i.Medium > 0) { <SeverityBadge Severity="Severity.Medium" Count="i.Medium" /> }
@if (i.Low > 0) { <SeverityBadge Severity="Severity.Low" Count="i.Low" /> }
</div></td>
<td>@i.NotMeasurable</td>
<td title="@Display.Time(i.LastSeenAt)">@Display.Ago(i.LastSeenAt)</td>
</tr>
}
</tbody>
</table>
</section>
<section class="card">
<div class="card-head"><h2>Kritiske og høje fund</h2><a href="/fund">Se alle fund</a></div>
<FindingList Findings="_urgent" ShowInstance="true" Empty="Ingen kritiske eller høje fund." />
</section>
}
@code {
private IReadOnlyList<InstanceOverview> _instances = [];
private IReadOnlyList<InstanceOverview> _monitored = [];
private int _paused;
private IReadOnlyList<StoredFinding> _active = [];
private IReadOnlyList<StoredFinding> _urgent = [];
protected override async Task OnInitializedAsync()
{
// Removed instances are left out (their history stays for reports); paused ones are shown, marked, but do not
// count in the totals, the urgent findings or the privilege alert.
_instances = (await Repository.GetInstancesAsync()).Where(i => !i.Removed).ToList();
_monitored = _instances.Where(i => i.IsMonitored).ToList();
_paused = _instances.Count(i => i.Paused);
var monitoredIds = _monitored.Select(i => i.InstanceId).ToHashSet();
_active = (await Repository.GetActiveFindingsAsync()).Where(f => monitoredIds.Contains(f.InstanceId)).ToList();
_urgent = _active.Where(f => f.Severity >= Severity.High).ToList();
}
}