Compare commits
3
Commits
8ed20b0c98
...
7cc499d57c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cc499d57c | ||
|
|
aeba3f8db1 | ||
|
|
d6e67ceb61 |
+7
-1
@@ -28,7 +28,13 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
|
||||
whose only card is the narrow one now takes its heading and footer down to the
|
||||
card's width instead of splitting them across the wider measure, and the send
|
||||
log stops breaking `Details` and `deferred` across two lines when a row is
|
||||
tight. The three
|
||||
tight.
|
||||
- panel: the send log's **status is a badge**, in the same ok/warn/error/unknown
|
||||
colours the status page and the DNS checks use, instead of the one place in
|
||||
the panel where a status was bare text. The mapping is the one the delivery
|
||||
page already applied — `sent` is ok, `deferred` a warning, `bounced` and
|
||||
`rejected` errors, `queued` unknown because nothing has gone wrong yet.
|
||||
The three
|
||||
WOFF2 files add ~76 KB to the image and are served from the panel's own origin,
|
||||
so the Content-Security-Policy is unchanged (`default-src 'self'`).
|
||||
|
||||
|
||||
@@ -145,6 +145,17 @@ func deliveryLevel(status string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// sendLogRow is a row of the send log as the table draws it: the stored row
|
||||
// plus the badge level its status maps onto. The level is carried rather than
|
||||
// derived in the template because deliveryLevel is the one place that decides
|
||||
// what a status means — the delivery page already reads it, and a second
|
||||
// mapping written in the template or the stylesheet would be free to drift
|
||||
// from it.
|
||||
type sendLogRow struct {
|
||||
store.SendLogRow
|
||||
Level string // ok / warn / error / unknown, as deliveryLevel returns
|
||||
}
|
||||
|
||||
// deliveryEvent is one step of a message's history, as the timeline on the
|
||||
// delivery page draws it. At is zero for the step that has not happened yet —
|
||||
// the delivery report a queued message is still waiting for.
|
||||
@@ -324,8 +335,10 @@ func (h *Handlers) sendLogData(r *http.Request) (map[string]any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
view := make([]sendLogRow, len(rows))
|
||||
for i := range rows {
|
||||
rows[i].Subject = mailhdr.DecodeSubject(rows[i].Subject)
|
||||
view[i] = sendLogRow{SendLogRow: rows[i], Level: deliveryLevel(rows[i].Status)}
|
||||
}
|
||||
|
||||
domainNames := make([]string, 0, len(assigned))
|
||||
@@ -358,7 +371,7 @@ func (h *Handlers) sendLogData(r *http.Request) (map[string]any, error) {
|
||||
lastPage = int((total + sendLogPageSize - 1) / sendLogPageSize)
|
||||
}
|
||||
return map[string]any{
|
||||
"Rows": rows,
|
||||
"Rows": view,
|
||||
"FilterDomains": domainNames,
|
||||
"FilterApps": logins,
|
||||
"FilterDomain": filter.Domain,
|
||||
|
||||
@@ -194,17 +194,19 @@ a { color: var(--accent-text); }
|
||||
/* form.inline only exists so a POST can sit next to other content without a
|
||||
form's block layout; its button is styled like any other. */
|
||||
form.inline { display: inline; margin: 0; }
|
||||
/* A page whose card is the narrow one takes the column down with it. .card.narrow
|
||||
centres itself inside whatever holds it, so at the panel's usual width the
|
||||
/* The signed-out pages are a single card and nothing else, and .card.narrow
|
||||
centres itself inside whatever holds it — so at the panel's usual width the
|
||||
card floated in the middle while the mark and the heading stayed at the far
|
||||
left — three alignments on a page with four elements. Narrowing the column to
|
||||
the card's own width lines the three up and puts the block as a whole in the
|
||||
middle of the page.
|
||||
Named by what the page holds rather than by which page it is: it was written
|
||||
for login and setup, and Settings and the user form have the same single
|
||||
narrow card and had the same split heading — a list of page names would have
|
||||
had to be remembered and extended by every page added since. */
|
||||
main:has(> .card.narrow) { max-width: 24rem; }
|
||||
left, three alignments on a page with four elements. Narrowing the column to
|
||||
the card's own width makes the three line up and puts the block as a whole in
|
||||
the middle of the page.
|
||||
By page name and not by "the page holds a narrow card", which is what this
|
||||
briefly was. Settings and the user form hold one too, and narrowing their
|
||||
column moves the navigation sideways with it — the shell centres the column
|
||||
and the page as a pair, so 296px of it, measured. Their heading and card are
|
||||
still not aligned with each other; that is worth fixing on its own terms and
|
||||
not by making every page's chrome move. */
|
||||
main.page-login, main.page-setup { max-width: 24rem; }
|
||||
.card + .card { margin-top: 1.2rem; }
|
||||
.flash { background: var(--flash-bg); border: 1px solid var(--flash-border); color: var(--flash-fg); padding: 0.7rem 1rem; border-radius: 6px; margin-bottom: 1.2rem; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
@@ -261,9 +263,9 @@ h2 { font-size: 1.05rem; font-weight: 600; margin: 0 0 0.4rem; }
|
||||
.version { margin-top: 1.6rem; text-align: right; font-size: 0.8rem; color: var(--muted); line-height: 1.45; }
|
||||
.version a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
|
||||
.version a:hover { color: var(--fg); }
|
||||
/* The narrow column is 24rem; a right-aligned multi-link notice wraps into a
|
||||
ragged edge, so centre it there. */
|
||||
main:has(> .card.narrow) .version { text-align: center; }
|
||||
/* The signed-out column is 24rem; a right-aligned multi-link notice wraps
|
||||
into a ragged edge, so centre it there. */
|
||||
main.page-login .version, main.page-setup .version { text-align: center; }
|
||||
select, textarea {
|
||||
width: 100%; padding: 0.55rem 0.7rem; font-size: 1rem;
|
||||
border: 1px solid var(--control-border); border-radius: 5px; background: var(--input-bg); color: inherit;
|
||||
@@ -391,8 +393,9 @@ button.danger:hover, a.danger:hover { background: var(--danger-fill-hover); }
|
||||
font-weight: 600; color: var(--accent-text); background: var(--nav-active-bg);
|
||||
box-shadow: inset 2px 0 0 var(--accent-fill);
|
||||
}
|
||||
/* Sign out carries an icon too, so it needs the same row layout; its padding
|
||||
and colours come from the compact button rule further down. */
|
||||
/* Sign out carries an icon too, so it needs the same row layout; its colours
|
||||
come from the compact button rule further down, and its type is put back to
|
||||
the column's beside it (see the rule after that one). */
|
||||
.nav button { display: flex; align-items: center; gap: 0.5rem; }
|
||||
/* The icons draw in the entry's own colour, so the active entry's darker text,
|
||||
a link's blue and Sign out's red all carry through without a rule apiece. */
|
||||
@@ -460,9 +463,19 @@ button.danger:hover, a.danger:hover { background: var(--danger-fill-hover); }
|
||||
is where the panel puts machine output everywhere else. Uppercasing it was
|
||||
the pill's own emphasis — dropped with the pill, since the colour already
|
||||
says how loud the badge is. */
|
||||
/* line-height 1 and the padding doing the centring, rather than the 1.5 the
|
||||
badge would inherit from the body. In a tall line box a word of lowercase
|
||||
with no descender — ok, warn, unknown — sits above the optical centre of the
|
||||
space around it, and inside a bordered box that reads as text stuck to the
|
||||
top. With the box hugging the line, the padding is what centres the word, and
|
||||
it is uneven on purpose: the extra tenth at the top pays for the descender
|
||||
space every line box reserves below the baseline and these words rarely use.
|
||||
The one that does use it, queued, keeps the same box — the tail hangs into
|
||||
the bottom padding rather than growing the badge. */
|
||||
.st {
|
||||
display: inline-block; padding: 0.1rem 0.45rem; border-radius: 4px;
|
||||
font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500; letter-spacing: 0.02em;
|
||||
display: inline-block; padding: 0.28rem 0.45rem 0.2rem; border-radius: 4px;
|
||||
font-family: var(--font-mono); font-size: 0.78rem; font-weight: 500; line-height: 1;
|
||||
letter-spacing: 0.02em;
|
||||
vertical-align: middle; border: 1px solid transparent;
|
||||
}
|
||||
.st-ok { background: var(--st-ok-bg); color: var(--st-ok-fg); border-color: var(--st-ok-border); }
|
||||
@@ -600,6 +613,17 @@ button.copy { flex: none; margin-top: 0.3rem; }
|
||||
color: var(--danger-fg); background: var(--danger-bg); border-color: var(--danger-border);
|
||||
}
|
||||
.actions button.danger:hover, .actions a.danger:hover, .nav button.danger:hover { background: var(--danger-bg-hover); }
|
||||
/* Sign out takes the compact button's colours but not its type. The rule above
|
||||
is written for controls that cluster — a row of them beside a value or in a
|
||||
table cell — where 0.8rem/600 is what keeps four of them from shouting. In
|
||||
the navigation column it has no cluster to belong to: it stands under
|
||||
Settings, among entries set 0.95rem/400, and being smaller and heavier than
|
||||
every word around it made it read as a different kind of object rather than
|
||||
as the last item of the list. Type and padding go back to the entries';
|
||||
the red, the border and the background stay, and are what say it acts. */
|
||||
.nav button {
|
||||
padding: 0.35rem 0.6rem; font-size: 0.95rem; font-weight: 400;
|
||||
}
|
||||
|
||||
/* The optional "encrypt this download" block on the backup and export forms.
|
||||
Its label is the one checkbox in the panel, so it opts out of the
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<td>{{.From}}</td>
|
||||
<td>{{.To}}</td>
|
||||
<td class="subject"><span title="{{.Subject}}">{{.Subject}}</span></td>
|
||||
<td class="status">{{.Status}}</td>
|
||||
<td class="status"><span class="st st-{{.Level}}">{{.Status}}</span></td>
|
||||
<td class="actions"><a href="/deliveries/{{.ID}}?domain={{$.FilterDomain}}&app={{$.FilterApp}}&p={{$.Page}}">Details</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user