From e0fbb8c9801e848dbf59c28495f1fbec9eab989b Mon Sep 17 00:00:00 2001 From: Steve Cliff Date: Mon, 4 May 2026 20:29:49 +0100 Subject: [PATCH] ui: dashboard crit-alerts banner --- internal/server/http/ui_handlers.go | 23 +++++++++++++++-------- internal/server/ui/ui.go | 1 + web/templates/pages/dashboard.html | 1 + web/templates/partials/crit_banner.html | 13 +++++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 web/templates/partials/crit_banner.html diff --git a/internal/server/http/ui_handlers.go b/internal/server/http/ui_handlers.go index c5293d7..8bf9f8c 100644 --- a/internal/server/http/ui_handlers.go +++ b/internal/server/http/ui_handlers.go @@ -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) diff --git a/internal/server/ui/ui.go b/internal/server/ui/ui.go index 3df58e4..d970b74 100644 --- a/internal/server/ui/ui.go +++ b/internal/server/ui/ui.go @@ -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") diff --git a/web/templates/pages/dashboard.html b/web/templates/pages/dashboard.html index fdcd487..b3a379a 100644 --- a/web/templates/pages/dashboard.html +++ b/web/templates/pages/dashboard.html @@ -4,6 +4,7 @@
{{$page := .Page}} + {{template "crit_banner" .Page}} {{if eq $page.HostCount 0}} {{/* ---------- empty state ---------- */}} diff --git a/web/templates/partials/crit_banner.html b/web/templates/partials/crit_banner.html new file mode 100644 index 0000000..c2c31d2 --- /dev/null +++ b/web/templates/partials/crit_banner.html @@ -0,0 +1,13 @@ +{{define "crit_banner"}} +{{if gt .CritOpenCount 0}} +
+
+ + {{.CritOpenCount}} critical alert{{if ne .CritOpenCount 1}}s{{end}} open across the fleet +
+ Review → +
+{{end}} +{{end}}