log panes: lines wrap under their start instead of scrolling sideways

The owner, 2026-10-16, a phone screenshot of a message's Delivery log:
"На телефоне при просмотре лога, появляются две полосы. Мы это можем
поправить?" - the horizontal scroll bars Chrome on Android drew over a
pre whose mail.log lines were wider than it. As the mockup of 216f366:
sp-log wraps (pre-wrap, overflow-wrap: anywhere) and no longer scrolls;
log_pane writes each line as a block, sp-ll, with a 4ch hanging indent and
its newline inside it, so copied text keeps one line per line. One
partial: the Delivery log of a message, System log, the outbound queue's
listing.

Tests: TestLogPaneIsAPreWithEscapedLines reads the new shape; the page
tests' substrings stand; TestPanelCSSIsTheMockupStylesheet holds panel.css
to the mockup. go vet + go test (26 packages) and make e2e on the test
server for this tree. CHANGELOG [Unreleased] § Fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-16 14:31:17 +03:00
co-authored by Claude Opus 5.5
parent 216f366dfa
commit bd21ff0f90
4 changed files with 22 additions and 8 deletions
+7 -5
View File
@@ -364,17 +364,19 @@ func TestTimelineLevels(t *testing.T) {
`<li class="sp-pending"><time>next attempt</time>Still queued</li>`)
}
// The log is a pre: its lines are separated by a newline of their own, not by
// the template's layout whitespace, and a line is escaped.
// The log is a pre of lines: each a block of its own (sp-ll), which wraps
// under its start rather than scrolling sideways, ended by a newline inside it
// so copied text keeps one line per line - and nothing of the template's
// layout whitespace between them. A line is escaped.
func TestLogPaneIsAPreWithEscapedLines(t *testing.T) {
out := partial(t, "log_pane", []LogLine{
{Time: "13:58:07", Text: "message-id=<a81f0c@alertmanager>"},
{Time: "13:58:09", Text: "status=deferred", Level: "warn"},
{Text: "no time on this one", Level: "error"},
})
want := `<pre class="sp-log"><span class="sp-d">13:58:07</span> message-id=&lt;a81f0c@alertmanager&gt;` + "\n" +
`<span class="sp-d">13:58:09</span> <span class="sp-w">status=deferred</span>` + "\n" +
`<span class="sp-e">no time on this one</span></pre>`
want := `<pre class="sp-log"><span class="sp-ll"><span class="sp-d">13:58:07</span> message-id=&lt;a81f0c@alertmanager&gt;` + "\n</span>" +
`<span class="sp-ll"><span class="sp-d">13:58:09</span> <span class="sp-w">status=deferred</span>` + "\n</span>" +
`<span class="sp-ll"><span class="sp-e">no time on this one</span>` + "\n</span></pre>"
if out != want {
t.Errorf("log_pane =\n%s\nwant\n%s", out, want)
}