ui: dashboard crit-alerts banner
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 ---------- */}}
|
||||
|
||||
@@ -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}}
|
||||
Reference in New Issue
Block a user