ui: dashboard crit-alerts banner

This commit is contained in:
2026-05-04 20:29:49 +01:00
parent 371fe734f3
commit e0fbb8c980
4 changed files with 30 additions and 8 deletions
+15 -8
View File
@@ -122,10 +122,11 @@ func (s *Server) version() string {
// dashboardPage is the data the dashboard template renders against.
type dashboardPage struct {
Hosts []dashboardHostRow
HostCount int
Summary store.FleetSummary
PendingHosts []store.PendingHost // announce-and-approve queue (P2-18d)
Hosts []dashboardHostRow
HostCount int
Summary store.FleetSummary
PendingHosts []store.PendingHost // announce-and-approve queue (P2-18d)
CritOpenCount int
}
// dashboardHostRow carries a host plus the per-row Run-now decision
@@ -239,12 +240,18 @@ func (s *Server) handleUIDashboard(w stdhttp.ResponseWriter, r *stdhttp.Request)
slog.Warn("ui dashboard: list pending hosts", "err", perr)
}
critOpenCount := 0
if crit, err := s.deps.Store.ListAlerts(r.Context(), store.AlertFilter{Status: "open", Severity: "critical"}); err == nil {
critOpenCount = len(crit)
}
view := s.baseView(r, u)
view.Page = dashboardPage{
Hosts: rows,
HostCount: len(hosts),
Summary: summary,
PendingHosts: pending,
Hosts: rows,
HostCount: len(hosts),
Summary: summary,
PendingHosts: pending,
CritOpenCount: critOpenCount,
}
if err := s.deps.UI.Render(w, "dashboard", view); err != nil {
slog.Error("ui: render dashboard", "err", err)
+1
View File
@@ -94,6 +94,7 @@ func New() (*Renderer, error) {
"templates/partials/host_chrome.html",
"templates/partials/tree_node.html",
"templates/partials/alert_row.html",
"templates/partials/crit_banner.html",
}
pageEntries, err := fs.Glob(web.FS, "templates/pages/*.html")
+1
View File
@@ -4,6 +4,7 @@
<div class="max-w-[1280px] mx-auto px-8">
{{$page := .Page}}
{{template "crit_banner" .Page}}
{{if eq $page.HostCount 0}}
{{/* ---------- empty state ---------- */}}
+13
View File
@@ -0,0 +1,13 @@
{{define "crit_banner"}}
{{if gt .CritOpenCount 0}}
<div class="crit-banner flex items-center justify-between mb-4 px-4 py-2.5 rounded-md text-[13px]"
style="border: 1px solid color-mix(in oklch, var(--bad), transparent 60%);
background: color-mix(in oklch, var(--bad), transparent 88%);">
<div class="flex items-center gap-3">
<span class="dot dot-critical"></span>
<span><span class="text-bad font-medium">{{.CritOpenCount}} critical alert{{if ne .CritOpenCount 1}}s{{end}}</span> open across the fleet</span>
</div>
<a href="/alerts?severity=critical&status=open" class="btn btn-danger">Review →</a>
</div>
{{end}}
{{end}}