From 6b8658602d7be741681ba8f06c432a4146112c23 Mon Sep 17 00:00:00 2001 From: Mikhail Yenuchenko Date: Tue, 11 Aug 2026 23:24:24 +0300 Subject: [PATCH] panel: place mail queue and TLS cert side by side on Status Widen the status page and wrap the short queue/certificate cards in .split so the stack is shorter; other checks stay full width. Co-authored-by: Cursor --- CHANGELOG.md | 7 ++++ internal/web/view/templates/status.html | 4 +++ internal/web/view/templates/status_body.html | 38 ++++++++++---------- internal/web/view/templates_test.go | 5 ++- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd3eaaf..b640fb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version ## [Unreleased] +### Changed + +- panel: **Status** places Mail queue and TLS certificate side by side (the + same `.split` / wide layout as Settings and a delivery), so the shorter + checks take less vertical space; Processes, Machine, sockets, hostname, and + Configuration stay full width. + ### Fixed - panel: on the user create/edit form, **Assigned domains** checkboxes stacked diff --git a/internal/web/view/templates/status.html b/internal/web/view/templates/status.html index e0f020d..d0b4e9e 100644 --- a/internal/web/view/templates/status.html +++ b/internal/web/view/templates/status.html @@ -1,3 +1,7 @@ +{{/* Wide enough for mail queue and TLS certificate side by side (see .split + in panel.css, as on account and delivery). */}} +{{define "wide"}}wide{{end}} + {{define "content"}}

Server status

diff --git a/internal/web/view/templates/status_body.html b/internal/web/view/templates/status_body.html index 22f551b..f29bb08 100644 --- a/internal/web/view/templates/status_body.html +++ b/internal/web/view/templates/status_body.html @@ -72,25 +72,27 @@ -
-

Mail queue {{.QueueStatus}}

- {{if .QueueError}} -

{{.QueueError}}

- {{else}} -

{{if .QueueSummary}}{{.QueueSummary}}{{else}}Mail queue is empty.{{end}}

- Full queue - {{end}} -
+
+
+

Mail queue {{.QueueStatus}}

+ {{if .QueueError}} +

{{.QueueError}}

+ {{else}} +

{{if .QueueSummary}}{{.QueueSummary}}{{else}}Mail queue is empty.{{end}}

+ Full queue + {{end}} +
-
-

TLS certificate {{.Cert.Status}}

-

The certificate Postfix serves on port 465{{if .Cert.Subject}} ({{.Cert.Subject}}){{end}}. - It is supplied by the reverse proxy through a read-only mount; SelfPost only reads it.

- {{if not .Cert.NotAfter.IsZero}} - - {{.Cert.NotAfter.UTC.Format "2006-01-02 15:04 UTC"}} - {{end}} -

{{.Cert.Detail}}

+
+

TLS certificate {{.Cert.Status}}

+

The certificate Postfix serves on port 465{{if .Cert.Subject}} ({{.Cert.Subject}}){{end}}. + It is supplied by the reverse proxy through a read-only mount; SelfPost only reads it.

+ {{if not .Cert.NotAfter.IsZero}} + + {{.Cert.NotAfter.UTC.Format "2006-01-02 15:04 UTC"}} + {{end}} +

{{.Cert.Detail}}

+
diff --git a/internal/web/view/templates_test.go b/internal/web/view/templates_test.go index d45821d..6847893 100644 --- a/internal/web/view/templates_test.go +++ b/internal/web/view/templates_test.go @@ -263,7 +263,7 @@ func TestOnlyThePagesMadeOfDataDeclareThemselvesWide(t *testing.T) { if err != nil { t.Fatalf("New: %v", err) } - wide := map[string]bool{"account": true, "deliveries": true, "delivery": true, "mail_queue": true, "system_log": true} + wide := map[string]bool{"account": true, "deliveries": true, "delivery": true, "mail_queue": true, "status": true, "system_log": true} for name, page := range engine.Pages() { var buf bytes.Buffer if err := page.ExecuteTemplate(&buf, "wide", nil); err != nil { @@ -379,6 +379,9 @@ func TestStatusPageRendersEveryCheck(t *testing.T) { "opendkim", "FATAL", "Mail queue is empty", "mail.example.com", "203.0.113.10 → no PTR record", `action="/reload"`, `hx-get="/status/fragment"`, `class="st st-error"`, + // Queue and certificate sit abreast inside the polled fragment; their + // ids stay on the cards so the section index and scroll highlights hold. + `class="split"`, `id="queue"`, `id="certificate"`, `id="sockets"`, // The machine card: the bars carry their reading in an attribute // (the CSP rules out sizing them with a style), and the figures are // printed beside them for anything that does not render a meter.