diff --git a/internal/server/http/ui_alerts.go b/internal/server/http/ui_alerts.go index 06c82fb..8fc76ac 100644 --- a/internal/server/http/ui_alerts.go +++ b/internal/server/http/ui_alerts.go @@ -14,10 +14,11 @@ import ( ) type alertsPage struct { - Filter store.AlertFilter - Alerts []store.Alert - Counts alertCounts - HostNames map[string]string // host_id → name for table rendering + Filter store.AlertFilter + Alerts []store.Alert + Counts alertCounts + HostNames map[string]string // host_id → name for table rendering + RefreshURL string // self-URL for the live-refresh poll } type alertCounts struct { @@ -51,7 +52,12 @@ func (s *Server) handleUIAlerts(w stdhttp.ResponseWriter, r *stdhttp.Request) { return } - page := alertsPage{Filter: f, Alerts: alerts, HostNames: map[string]string{}} + page := alertsPage{ + Filter: f, + Alerts: alerts, + HostNames: map[string]string{}, + RefreshURL: r.URL.RequestURI(), + } if hosts, err := s.deps.Store.ListHosts(r.Context()); err == nil { for _, h := range hosts { page.HostNames[h.ID] = h.Name diff --git a/web/templates/pages/alerts.html b/web/templates/pages/alerts.html index c059e24..7b3fd26 100644 --- a/web/templates/pages/alerts.html +++ b/web/templates/pages/alerts.html @@ -90,8 +90,18 @@ - {{/* alerts table */}} -
+ {{/* alerts table — polled every 15s while the tab is visible. + hx-get re-fetches the same URL (so filter querystring is preserved) + and hx-select pulls just this element out of the full response, + replacing the live one. Pauses automatically when the tab is + backgrounded so we're not burning CPU on inactive tabs. + The polling lives here (not on the page root) so the filter strip + and header don't flash on each tick. */}} +
{{/* header row */}}
@@ -101,7 +111,9 @@
Message
Raised
Last seen
-
+
+ live ● +
{{if eq (len $page.Alerts) 0}}