ui: F1 — populate OpenAlerts in baseView so nav badge updates everywhere

Flagged in review of 35dee98: the Alerts tab badge should show the
open count from any page, not just /alerts. baseView now takes the
request and queries store.ListAlerts(Status: "open") to fill
view.OpenAlerts on every page render. All call sites updated.
This commit is contained in:
2026-05-04 20:19:09 +01:00
parent 35dee98cf9
commit 9dbed025e0
7 changed files with 35 additions and 29 deletions
+16 -9
View File
@@ -93,12 +93,20 @@ func (s *Server) requireUIUser(w stdhttp.ResponseWriter, r *stdhttp.Request) *ui
// OpenAlerts is populated via a quick store count so the nav badge
// stays current on every page load without requiring a page-specific
// store call.
func (s *Server) baseView(u *ui.User) ui.ViewData {
return ui.ViewData{
func (s *Server) baseView(r *stdhttp.Request, u *ui.User) ui.ViewData {
view := ui.ViewData{
User: u,
Active: "dashboard",
Version: s.version(),
}
// Populate OpenAlerts from the store so the nav badge shows the
// current count on every page.
if open, err := s.deps.Store.ListAlerts(r.Context(), store.AlertFilter{Status: "open"}); err == nil {
view.OpenAlerts = len(open)
}
return view
}
// version returns the binary's build version — passed in via Deps so
@@ -231,8 +239,7 @@ func (s *Server) handleUIDashboard(w stdhttp.ResponseWriter, r *stdhttp.Request)
slog.Warn("ui dashboard: list pending hosts", "err", perr)
}
view := s.baseView(u)
view.OpenAlerts = summary.OpenAlerts
view := s.baseView(r, u)
view.Page = dashboardPage{
Hosts: rows,
HostCount: len(hosts),
@@ -299,7 +306,7 @@ func (s *Server) handleUIAddHostGet(w stdhttp.ResponseWriter, r *stdhttp.Request
if u == nil {
return
}
view := s.baseView(u)
view := s.baseView(r, u)
view.Title = "Add host · restic-manager"
view.Page = addHostPage{ServerURL: s.publicURL(r)}
if err := s.deps.UI.Render(w, "add_host", view); err != nil {
@@ -371,7 +378,7 @@ func (s *Server) handleUIAddHostPost(w stdhttp.ResponseWriter, r *stdhttp.Reques
}
}
view := s.baseView(u)
view := s.baseView(r, u)
view.Title = "Add host · restic-manager"
view.Page = page
w.WriteHeader(stdhttp.StatusUnprocessableEntity)
@@ -438,7 +445,7 @@ func (s *Server) handleUIPendingHost(w stdhttp.ResponseWriter, r *stdhttp.Reques
}
}
view := s.baseView(u)
view := s.baseView(r, u)
view.Title = "Pending host · restic-manager"
view.Page = page
if err := s.deps.UI.Render(w, "pending_host", view); err != nil {
@@ -616,7 +623,7 @@ func (s *Server) handleUIHostDetail(w stdhttp.ResponseWriter, r *stdhttp.Request
shown = shown[:cap]
}
view := s.baseView(u)
view := s.baseView(r, u)
view.Title = host.Name + " · restic-manager"
view.Page = hostDetailPage{
hostChromeData: s.loadHostChrome(r, *host, "snapshots", "snapshots"),
@@ -716,7 +723,7 @@ func (s *Server) handleUIJobDetail(w stdhttp.ResponseWriter, r *stdhttp.Request)
nextSeq = logs[n-1].Seq
}
view := s.baseView(u)
view := s.baseView(r, u)
view.Title = job.Kind + " · " + host.Name + " · restic-manager"
view.Page = jobDetailPage{
Job: *job,