From a7b8319974136c363adb0e7dd03d894718eea981 Mon Sep 17 00:00:00 2001 From: Mitchell-Johnson Date: Mon, 21 Sep 2026 21:09:43 -0700 Subject: [PATCH] Disks: the SMART table stays inside its card Co-Authored-By: Claude Opus 5 --- BUGS.md | 24 ++++++++++++++++++++++++ web/src/Disks.tsx | 6 ++++-- web/src/styles.css | 14 ++++++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/BUGS.md b/BUGS.md index 2d5a7dd..6e173b1 100644 --- a/BUGS.md +++ b/BUGS.md @@ -520,3 +520,27 @@ table is re-read under it; terminate, on a throwaway `sleep`, asks by name and p and the footer stops offering a process that is gone. Sampler values outside 100 ms–60 s are refused, and a rate slower than the collector's 10 s samples at 10 s. All 14 pages at his window size and on a phone, in both browsers: no errors, no overflow. + + +# Bug bash 4, later — 2026-09-21: the SMART table outside its card + +Mitchell, from the Disks page of `hamtv` with SMART open: the attribute table's rows ran out +through the right-hand side of the card they belong to, the rules and the Thresh column +drawn over the page behind. + +12. ✅ **A table cannot be narrower than its widest unbreakable cell, and one of `hamtv`'s + was 130px wide.** `.num` sets `white-space: nowrap`, and a SMART raw value is not always a + number — the temperature attribute reads `34 (Min/Max 28/39)`. That one cell set the + table's minimum width above the card's, so it spilled. Three changes, in this order, + because the first two each looked worse than the bug in their own way: + - the raw column wraps — but `overflow-wrap: anywhere` broke `4295163906` across two + lines as "429516 / 3906", which reads as two numbers. It wraps at spaces only now; + - a disk card is given room for six columns of SMART (`minmax(420px, 1fr)` rather than + the shared 320px), and the cells' side padding goes 6px → 4px, which together is the + ~40px it was short by; + - if some drive ever reports a raw value long enough to still not fit, the table scrolls + inside its card rather than out of it. + Verified on all four machines at six widths from 1721px down to a phone, in Chromium and + Firefox: nothing leaves its card, no number is broken across lines, and the fallback + scrollbar is never reached. The same measurement was run over every other page's cards + and boxes — Dashboard, Top, Docker, Alerts, Machines and the rest — and found nothing. diff --git a/web/src/Disks.tsx b/web/src/Disks.tsx index 00229b2..35cc163 100644 --- a/web/src/Disks.tsx +++ b/web/src/Disks.tsx @@ -58,17 +58,19 @@ function SmartPanel({ dev, rotational }: { dev: string; rotational: boolean }) { )} {s.attrs.length > 0 && ( +
{s.attrs.map((a) => ( - + ))}
IDAttributeRawValueWorstThresh
{a.id}{a.name.replace(/_/g, ' ')}{a.failed && {a.failed}}{a.raw}{a.value}{a.worst}{a.thresh}{a.raw}{a.value}{a.worst}{a.thresh}
+
)} {!s.self_test_supported &&
Self-tests: {s.self_test_note || 'not available on this drive'}.
} {s.self_test_supported &&
@@ -231,7 +233,7 @@ export default function Disks() {
{!hasSmart &&
SMART health needs smartmontools on this host. Install it with the button, then reload.
} {task && { toast(`${t.title}: ${t.exit_code === 0 ? 'finished' : `exited ${t.exit_code}`}`, t.exit_code === 0 ? 'ok' : 'err'); load() }} />} -
+
{devs.map((d) => )}
diff --git a/web/src/styles.css b/web/src/styles.css index 627979d..7c82d2e 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -262,9 +262,19 @@ h2.section { margin: 0; font-size: 13px; font-weight: 600; color: var(--muted); .good { color: var(--ok); } .warn-text { color: var(--s2); } .smart { display: flex; flex-direction: column; gap: 8px; padding-top: 8px; border-top: 1px solid var(--border); } .attrs { width: 100%; border-collapse: collapse; font-size: 12px; } -.attrs th { text-align: left; color: var(--muted); font-weight: 500; padding: 4px 6px; border-bottom: 1px solid var(--border); } -.attrs td { padding: 3px 6px; border-bottom: 1px solid var(--border); } .attrs td.num, .attrs th:not(:nth-child(2)) { text-align: right; } +.attrs th { text-align: left; color: var(--muted); font-weight: 500; padding: 4px 4px; border-bottom: 1px solid var(--border); } +.attrs td { padding: 3px 4px; border-bottom: 1px solid var(--border); } .attrs td.num, .attrs th:not(:nth-child(2)) { text-align: right; } .attrs tr.warn td { color: var(--s2); } +/* A SMART raw value is not always a number — a temperature reads "36 (Min/Max 28/39)" — and a + table cannot be narrower than its widest unbreakable cell, so one of those pushed the whole + table out through the side of its card. The raw column wraps, but only where there is a + space: a number broken across two lines reads as two numbers. If some drive ever reports + one long enough to still not fit, the table scrolls inside its card rather than out of it. */ +.attrs td.raw { white-space: normal; } +.attrs-wrap { overflow-x: auto; scrollbar-width: thin; } +/* Six columns of SMART want about 350px between them; a disk card is given room for that, so + the fallback above stays a fallback. */ +.disk-cards { grid-template-columns: repeat(auto-fill, minmax(min(420px, 100%), 1fr)); } .datasets { padding: 0; overflow-x: auto; } .ds-row { display: grid; grid-template-columns: minmax(160px, 1fr) 80px 80px 80px 50px 50px minmax(120px, 1fr); gap: 8px; align-items: center; padding: 6px 12px; border-bottom: 1px solid var(--border); font-size: 13px; min-width: 700px; } /* the columns and gaps add up to 692: at 640 the row ended before its own cells did */ .ds-row.head { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }