panel: finish the monitoring rename below the URL layer

The previous two commits renamed the routes and the page titles but left
every identifier underneath still called sendlog/queue/logtail, so a
grep for "deliveries" found the route and nothing that serves it.

Renamed together, since they have to agree for a page to render at all:
the six template files, their {{define}} blocks, the pageFiles and
fragmentFiles keys, the .Active values the nav compares against, the
HTMX target ids, and the six page handlers.

Names that describe the data rather than the page keep their old form:
the send_log table and its store methods, internal/logtail, and the
sendLogData/readQueue/readLogTail helpers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 22:04:33 +03:00
parent 0ca5cba453
commit 5041f87e57
11 changed files with 51 additions and 50 deletions
+25 -24
View File
@@ -19,11 +19,12 @@ const (
logTailLines = 200
)
// handleSendLog renders the send-log monitoring page: server-side filters by
// domain/application and pagination (spec 7.3.3). The row table itself is the
// "sendlog_rows" fragment, shared verbatim with handleSendLogRows so the
// initial page and its HTMX-polled refreshes never diverge.
func (s *Server) handleSendLog(w http.ResponseWriter, r *http.Request) {
// handleDeliveries renders the Deliveries page over the send log: server-side
// filters by domain/application and pagination (spec 7.3.3). The row table
// itself is the "deliveries_rows" fragment, shared verbatim with
// handleDeliveriesRows so the initial page and its HTMX-polled refreshes never
// diverge.
func (s *Server) handleDeliveries(w http.ResponseWriter, r *http.Request) {
data, err := s.sendLogData(r)
if err != nil {
logf("panel: send log: %v", err)
@@ -32,20 +33,20 @@ func (s *Server) handleSendLog(w http.ResponseWriter, r *http.Request) {
}
data["Title"] = "SelfPost — deliveries"
data["User"] = currentUser(r)
data["Active"] = "sendlog"
s.render(w, http.StatusOK, "sendlog", data)
data["Active"] = "deliveries"
s.render(w, http.StatusOK, "deliveries", data)
}
// handleSendLogRows serves the HTMX polling fragment for the send-log table
// handleDeliveriesRows serves the HTMX polling fragment for the delivery table
// (spec 7.1: fragment endpoints return HTML, not JSON).
func (s *Server) handleSendLogRows(w http.ResponseWriter, r *http.Request) {
func (s *Server) handleDeliveriesRows(w http.ResponseWriter, r *http.Request) {
data, err := s.sendLogData(r)
if err != nil {
logf("panel: send log rows: %v", err)
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
s.renderFragment(w, http.StatusOK, "sendlog_rows", data)
s.renderFragment(w, http.StatusOK, "deliveries_rows", data)
}
// sendLogData reads the domain/app filters and page number off the query
@@ -109,22 +110,22 @@ func parsePage(v string) int {
return n
}
// handleQueue renders the mail-queue monitoring page (spec 7.2.11).
func (s *Server) handleQueue(w http.ResponseWriter, r *http.Request) {
// handleMailQueue renders the Mail queue page (spec 7.2.11).
func (s *Server) handleMailQueue(w http.ResponseWriter, r *http.Request) {
out, errText := readQueue()
s.render(w, http.StatusOK, "queue", map[string]any{
s.render(w, http.StatusOK, "mail_queue", map[string]any{
"Title": "SelfPost — mail queue",
"User": currentUser(r),
"Active": "queue",
"Active": "mail_queue",
"Output": out,
"Error": errText,
})
}
// handleQueueBody serves the HTMX polling fragment for the queue view.
func (s *Server) handleQueueBody(w http.ResponseWriter, r *http.Request) {
// handleMailQueueBody serves the HTMX polling fragment for the queue view.
func (s *Server) handleMailQueueBody(w http.ResponseWriter, r *http.Request) {
out, errText := readQueue()
s.renderFragment(w, http.StatusOK, "queue_body", map[string]any{
s.renderFragment(w, http.StatusOK, "mail_queue_body", map[string]any{
"Output": out,
"Error": errText,
})
@@ -142,22 +143,22 @@ func readQueue() (string, string) {
return out, ""
}
// handleLogTail renders the mail.log monitoring page (spec 7.2.13).
func (s *Server) handleLogTail(w http.ResponseWriter, r *http.Request) {
// handleSystemLog renders the System log page over mail.log (spec 7.2.13).
func (s *Server) handleSystemLog(w http.ResponseWriter, r *http.Request) {
lines, errText := s.readLogTail()
s.render(w, http.StatusOK, "logtail", map[string]any{
s.render(w, http.StatusOK, "system_log", map[string]any{
"Title": "SelfPost — system log",
"User": currentUser(r),
"Active": "logtail",
"Active": "system_log",
"Lines": lines,
"Error": errText,
})
}
// handleLogTailBody serves the HTMX polling fragment for the log-tail view.
func (s *Server) handleLogTailBody(w http.ResponseWriter, r *http.Request) {
// handleSystemLogBody serves the HTMX polling fragment for the log-tail view.
func (s *Server) handleSystemLogBody(w http.ResponseWriter, r *http.Request) {
lines, errText := s.readLogTail()
s.renderFragment(w, http.StatusOK, "logtail_body", map[string]any{
s.renderFragment(w, http.StatusOK, "system_log_body", map[string]any{
"Lines": lines,
"Error": errText,
})
+7 -7
View File
@@ -30,19 +30,19 @@ var pageFiles = map[string][]string{
"backup": {"templates/backup.html"},
"domain_detail": {"templates/domain_detail.html"},
"domain_delete": {"templates/domain_delete.html"},
"sendlog": {"templates/sendlog.html", "templates/sendlog_rows.html"},
"queue": {"templates/queue.html", "templates/queue_body.html"},
"logtail": {"templates/logtail.html", "templates/logtail_body.html"},
"deliveries": {"templates/deliveries.html", "templates/deliveries_rows.html"},
"mail_queue": {"templates/mail_queue.html", "templates/mail_queue_body.html"},
"system_log": {"templates/system_log.html", "templates/system_log_body.html"},
"status": {"templates/status.html", "templates/status_body.html"},
}
// fragmentFiles maps a fragment name (also its {{define}} block name) to its
// template file, for standalone rendering by the HTMX polling endpoints.
var fragmentFiles = map[string]string{
"sendlog_rows": "templates/sendlog_rows.html",
"queue_body": "templates/queue_body.html",
"logtail_body": "templates/logtail_body.html",
"status_body": "templates/status_body.html",
"deliveries_rows": "templates/deliveries_rows.html",
"mail_queue_body": "templates/mail_queue_body.html",
"system_log_body": "templates/system_log_body.html",
"status_body": "templates/status_body.html",
}
func loadTemplates() (*templates, error) {
@@ -19,6 +19,6 @@
</div>
<div class="card">
{{template "sendlog_rows" .}}
{{template "deliveries_rows" .}}
</div>
{{end}}
@@ -1,5 +1,5 @@
{{define "sendlog_rows"}}
<div id="sendlog-rows" hx-get="/deliveries/rows?domain={{.FilterDomain}}&app={{.FilterApp}}&p={{.Page}}"
{{define "deliveries_rows"}}
<div id="deliveries-rows" hx-get="/deliveries/rows?domain={{.FilterDomain}}&app={{.FilterApp}}&p={{.Page}}"
hx-trigger="every 5s" hx-swap="outerHTML">
{{if .Rows}}
<table>
+3 -3
View File
@@ -38,9 +38,9 @@
<div class="links">
{{if eq .Active "status"}}<span aria-current="page">Status</span>{{else}}<a href="/status">Status</a>{{end}}
{{if eq .Active "domains"}}<span aria-current="page">Domains</span>{{else}}<a href="/domains">Domains</a>{{end}}
{{if eq .Active "sendlog"}}<span aria-current="page">Deliveries</span>{{else}}<a href="/deliveries">Deliveries</a>{{end}}
{{if eq .Active "queue"}}<span aria-current="page">Mail queue</span>{{else}}<a href="/mail-queue">Mail queue</a>{{end}}
{{if eq .Active "logtail"}}<span aria-current="page">System log</span>{{else}}<a href="/system-log">System log</a>{{end}}
{{if eq .Active "deliveries"}}<span aria-current="page">Deliveries</span>{{else}}<a href="/deliveries">Deliveries</a>{{end}}
{{if eq .Active "mail_queue"}}<span aria-current="page">Mail queue</span>{{else}}<a href="/mail-queue">Mail queue</a>{{end}}
{{if eq .Active "system_log"}}<span aria-current="page">System log</span>{{else}}<a href="/system-log">System log</a>{{end}}
{{if eq .Active "backup"}}<span aria-current="page">Backup</span>{{else}}<a href="/backup">Backup</a>{{end}}
</div>
<div class="session">
@@ -3,6 +3,6 @@
<div class="card">
<h2>Pending messages</h2>
{{template "queue_body" .}}
{{template "mail_queue_body" .}}
</div>
{{end}}
@@ -1,5 +1,5 @@
{{define "queue_body"}}
<div id="queue-body" hx-get="/mail-queue/body" hx-trigger="every 5s" hx-swap="outerHTML">
{{define "mail_queue_body"}}
<div id="mail-queue-body" hx-get="/mail-queue/body" hx-trigger="every 5s" hx-swap="outerHTML">
{{if .Error}}<p class="error">{{.Error}}</p>{{end}}
<span class="code">{{if .Output}}{{.Output}}{{else}}Queue is empty.{{end}}</span>
</div>
@@ -3,6 +3,6 @@
<div class="card">
<h2>Recent log entries</h2>
{{template "logtail_body" .}}
{{template "system_log_body" .}}
</div>
{{end}}
@@ -1,5 +1,5 @@
{{define "logtail_body"}}
<div id="logtail-body" hx-get="/system-log/body" hx-trigger="every 5s" hx-swap="outerHTML">
{{define "system_log_body"}}
<div id="system-log-body" hx-get="/system-log/body" hx-trigger="every 5s" hx-swap="outerHTML">
{{if .Error}}<p class="error">{{.Error}}</p>{{end}}
<span class="code">{{if .Lines}}{{range .Lines}}{{.}}
{{end}}{{else}}No log lines yet.{{end}}</span>
+1 -1
View File
@@ -99,7 +99,7 @@ func TestNavMarksActivePage(t *testing.T) {
var buf bytes.Buffer
err = tmpl.pages["dashboard"].ExecuteTemplate(&buf, "nav", map[string]any{
"User": "admin",
"Active": "queue",
"Active": "mail_queue",
})
if err != nil {
t.Fatalf("execute nav: %v", err)
+6 -6
View File
@@ -185,12 +185,12 @@ func (s *Server) Handler() http.Handler {
// Monitoring screens (spec 7.2.11-13): each page and its HTMX polling
// fragment (spec 7.1 — the /rows and /body endpoints return HTML, not JSON).
authed.HandleFunc("GET /deliveries", s.handleSendLog)
authed.HandleFunc("GET /deliveries/rows", s.handleSendLogRows)
authed.HandleFunc("GET /mail-queue", s.handleQueue)
authed.HandleFunc("GET /mail-queue/body", s.handleQueueBody)
authed.HandleFunc("GET /system-log", s.handleLogTail)
authed.HandleFunc("GET /system-log/body", s.handleLogTailBody)
authed.HandleFunc("GET /deliveries", s.handleDeliveries)
authed.HandleFunc("GET /deliveries/rows", s.handleDeliveriesRows)
authed.HandleFunc("GET /mail-queue", s.handleMailQueue)
authed.HandleFunc("GET /mail-queue/body", s.handleMailQueueBody)
authed.HandleFunc("GET /system-log", s.handleSystemLog)
authed.HandleFunc("GET /system-log/body", s.handleSystemLogBody)
mux.Handle("/", s.requireAuth(authed))