UI Review Fixes - 2026-11-01¶
Index ยท builds the proposals from the UI Design Review - 2026-10-31 that Taltal picked.
Context¶
The design review scored the web UI 7.5 / 10 and left seven findings as proposals. Taltal picked five on 2026-11-01 ("do all 5"): the Cycles grid shows no result per cycle (U1), Compare hides which tests changed (U2), every run of a cycle has the same label (U4), the test page's charts were unfinished (U6), and some cards judge or sit empty (U8). The "got slower" noise (U7) and the raw artifact list (U11) stay open.
Decision¶
Two pull requests, both frontend-led, with the smallest API change that lets a page show what it needs in one request.
Cycles page shows each cycle's latest result (U1)¶
GET /api/v1/cyclesitems carrylatest_run(run_id,created_at,status,returncode,health_pct,total_tests,passed,failed,branch,commit), read with the onelatest_run_per_cycle()query the route already made. No per-cycle request from the UI.- Each card shows a status pill, the time of the run as a link ("3 h ago", full date on hover), "80% passed", "2 failing" in red,
branch @ commit, and a pass-rate bar. A cycle that never ran says "No runs recorded yet." The Run button is secondary so the result is what stands out.
Run labels say when and from where (U4)¶
formatRelativeTime("just now", "3 min ago", "5 h ago", "3 days ago", then the date) andformatProvenance("main @ 9c23517") infrontend/src/lib/format.ts.RunLabeltakesrelative; the Dashboard and Runs pages pass it. Run list items and dashboard recent runs carrycommitnext tobranch(RunListItem.commit,DashboardRecentRunItem.commit), read from the stored session.
Compare answers "which tests?" right under the summary (U2)¶
- The test-level list moves from under the four tables to right under the summary card and is open by default. The query runs when the section is open.
- "4 regressions" and "2 improvements" in the summary are buttons: they set the list's filter (regression, fix) and scroll to it. Each filter chip shows its count; each test links to its history page.
- "Test time (sum)" is dropped from the Performance table when it equals the wall duration in both runs (a single-stage run), so the table does not repeat a row.
Test page charts (U6)¶
- Duration: bars fill the card, each bar is a link to its run (tooltip and accessible name carry the time, outcome and duration), three y ticks, the run date under every bar or every nth so the axis stays readable.
- Flakiness: a line of flip rate per run, 0 to 100 %, with points and a 50 % guide, and the same sentence under it. The chart's text alternative is unchanged.
- Test outcomes use
StatusPill, which gainsbrokenandskipped, so the page says "Passed" / "Failed" like every list. Each run row carries its short id so it can be matched with the "Last failure" card.
Cards that judge, cards that are empty (U8)¶
- Test mix is shown only when at least two tiers hold tests. An ingested run has one tier (
qasight ingesttakes one--tier), so there was nothing to judge. A failed pyramid request still shows its error. - An empty Reports card folds into the Details list as a "Reports" row. A recorded-only cycle's page drops the Stages card: its one stage has nothing to configure and the header already names it.
Consequences¶
GET /api/v1/cyclesgrows one optional field;GET /api/v1/runsand the dashboard payload growcommit. The OpenAPI file andfrontend/src/lib/api-schema.tsare regenerated; nothing is removed.- The Compare page issues the case-changes request on every comparison instead of only when someone opened the section. It is the per-test diff the page exists for, and it was computed on demand before too.
- Remaining from the review: U7 (cap and sort "got slower" lists, noise floor check on real data) and U11 (group artifacts by stage, link the report ones).