Repository navigation
Commit 5fbddf8
Draw each site's server dot before its name in the sites list (#652)
## Why
The prototype draws each site's server dot at the left of its name in
the sites list, so which sites are running can be seen without opening
each. The app had the dot only in the open site's header: a contributor
with three sites had to open each one to learn which server was up. The
dot also sat 1.5px above the lowercase letters beside it, in the header
as in the list.
## What changes
Every entry in the sites list now wears the header's own dot before its
name: grey while the server is stopped, green running, amber starting,
red for a server that went by itself or could not start, with the reason
as the dot's tooltip. The attention dot for a stale or half-updated site
(#94) stays, drawn after it.
A server lives in its site's view, open or not, so the view is the one
thing that knows. Each `SiteRow` reports its server's state to the
window as it changes and takes the report back when it unmounts; the
window keeps the reports by path and hands them to `sitesListRows`. What
a report says, what it does to the reports and what the dot shows are
all decided in `src/renderer/sites-list.cjs`, where the suite can reach
them.
For a screen reader the dot's words follow the name, as the attention
dot's do, and only when the dot is not the grey every site starts with:
said after every name, "Server stopped" would be the thing heard most
and needed least. So an entry is named `my-site` while stopped and
`my-site (Server running)` while running.
Both dots, and the header's, are now centred on the text's x-height with
`vertical-align: middle`, which centres an inline box on the parent
font's x-height by definition and so holds on Windows with a different
font. A flex item, which the dots were, is centred on the line box
instead, 1.5px higher.
Deliberately not in it: a dot for the build watch in the list, and any
control on the list's dot. The dot reports; the header and the details
act.
## How to test this
Platforms: any. The x-height alignment is worth a look on Windows too,
where the font differs: the rule is font-agnostic, but only a look
confirms it.
The first journey in `tests/e2e/journeys/dev-server.spec.js` walks the
reported path and reads the list's dot at each turn: starting, running,
stopped and crashed, with the entry's name. It is red without the
change. From the repository root:
```bash
npx playwright test --project=journeys tests/e2e/journeys/dev-server.spec.js
```
What the journey cannot reach is a real server, since journeys stub the
handler that starts one, and what the dots look like beside real text:
**Starting state:** two sites, both set up, neither server running. The
Buildkite artifact for the head commit, on macOS or Windows.
1. Look at the sites list. Expected: every entry has a grey dot at the
left of its name, on the same line as the lowercase letters, and a stale
site has its amber dot after it.
2. On the open site, open the server's menu in the page header and
choose **Start development server**. Expected: the entry's dot turns
amber while the server starts and green once the site opens in the
browser. The header's dot sits on its words' x-height, as the list's
does.
3. Click the other site in the list. Expected: its own dot is still
grey, and the first site's dot is still green while you look at the
second.
4. Go back to the first site and choose **Stop development server**.
Expected: its dot is grey again.
5. Narrow the window until the header's menus show only their dots.
Expected: one gap between a dot and its chevron, not two.
**What must not have happened:** no site's entry has lost its name or
project line; a long name still ends in an ellipsis; the attention dot
of a stale site is still there, after the server dot; nothing else in
the header moved.
## Risks and limitations
- A running stale site shows two dots side by side, a green and an
amber. The prototype has no attention dot to reconcile with, so this
keeps both rather than folding two meanings into one dot.
- A crashed server's words are the whole sentence from the details, so
that entry's accessible name is long. It says what the red dot means,
which "Server stopped" would not.
- The guide's sidebar screenshots were not retaken.
- Pre-PR review: 2 [fix here] · 0 [follow-up], both fixed in `6229fb6`.
## Related
Follow-up to #590 (the sites list) and #595 (the server and the watch in
the header).
---
<details>
<summary>Design decisions and alternatives considered</summary>
- **The view reports up, rather than the main process broadcasting.**
"Starting" is a renderer state: it covers the wait for the build watch
before the server is even asked for. Only the view knows it, so a
main-process list of running servers would have drawn the wrong colour
for the longest phase.
- **One effect, with a cleanup that takes the report back.** Two
effects, one to report and one to clean up on unmount, would have lost
the entry if the callback's identity ever changed; one effect's cleanup
and re-run land in the same commit, so the list sees a single change and
no grey dot in between.
- **No words for a stopped server.** The prototype announces "Server
stopped" before every name. Here the grey dot is the default and says
nothing, as the attention dot says nothing when there is nothing to
report.
- **`vertical-align: middle` over a pixel offset.** The dot was measured
1.5px high against the ink of the letters, in a screenshot of the
running app. A `margin-top` would have fixed that for this font and this
size; `vertical-align: middle` is the CSS definition of "centred on the
x-height", so it follows the font.
</details>
<details>
<summary>Review outcome (required — see AGENTS.md)</summary>
2 [fix here] · 0 [follow-up] — both fixed.
- 🟡 Architecture, `[fix here]`: the words a view reports of its server,
and what a report does to the window's reports, were decided inline in
`index.jsx`, where the suite cannot reach them. Fixed: `serverReport`
and `withServerReport` in `src/renderer/sites-list.cjs`, with unit
tests.
- 🔵 Layout, `[fix here]`: the space between a process's dot and its
words was the dot's margin, which stayed when the words gave way to the
dot in a short header and doubled the gap before the chevron. Fixed: the
margin is the words' own and goes with them.
- **Review:** completed — a separate agent context running
`.github/instructions/code-review.instructions.md`; reviewed head
`aad1b72` / base `0cd70e4` (origin/trunk); `npm test` 2047 pass, `eslint
src tests scripts` and Stylelint clean (a repo-wide `eslint .` fails
only on stale checkouts under `.claude/worktrees`, which are not part of
the branch); outcome above.
- **Since review:** `aad1b72 → 6229fb6` checked; the one commit applies
the two findings and nothing else. `npm test` 2049 pass, lint clean, and
the dev-server, site-header, auto-start and logs journeys pass on the
new head.
- **CodeRabbit:** not yet requested.
</details>
<details>
<summary>Implementation notes</summary>
- `src/renderer/sites-list.cjs`: `serverDot` (what the row draws;
unknown or missing reports are offline), `serverReport` (what a view
reports from `serverProcess`), `withServerReport` (the reducer).
`sitesListRows` takes `servers` by path.
- `src/renderer/index.jsx`: `serverReports` state and the
`onServerStatus` callback in `App`; the reporting effect in `SiteRow`.
- `src/renderer/components/sites-sidebar.jsx`: draws `ProcessStatus`
before the name and the hidden words after it. `ProcessStatus` in
`site-header-actions.jsx` gained an optional `title`.
- `src/renderer/shell.css`: the name span is one nowrap line with the
ellipsis, the dots inline boxes; the header's dot and words are one
inline span inside the button.
- Journeys: `dev-server.spec.js` reads the list's dot at each state;
`logs.spec.js` and `auto-start.spec.js` name a running site's entry with
its dot's words, since the accessible name carries them.
- Measured alignment, in the ink of a window screenshot at 1x: list dot
centre 93.5 against the letters' 95.5 before, 95.5 against 95.5 after;
header dot 32.5 against 34 before, 33.5 against 34 after.
</details>
<details>
<summary>Screenshots or recording</summary>
The list before the alignment fix (dots centred on the line box) and
after (dots on the x-height), and the header's menu, are to be attached
from the measuring run; `gh` cannot upload images, so they go in from
the web UI.
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>1 parent 0cd70e4 commit 5fbddf8
11 files changed
Lines changed: 245 additions & 39 deletions
File tree
- docs/guide
- src/renderer
- components
- tests
- e2e/journeys
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
| 45 | + | |
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
| 39 | + | |
39 | 40 | | |
40 | | - | |
41 | | - | |
| 41 | + | |
| 42 | + | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| |||
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
58 | 63 | | |
59 | 64 | | |
60 | 65 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
15 | 19 | | |
16 | 20 | | |
17 | 21 | | |
| |||
20 | 24 | | |
21 | 25 | | |
22 | 26 | | |
| 27 | + | |
23 | 28 | | |
24 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
25 | 38 | | |
26 | 39 | | |
27 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| |||
476 | 476 | | |
477 | 477 | | |
478 | 478 | | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
479 | 490 | | |
480 | 491 | | |
481 | 492 | | |
| |||
531 | 542 | | |
532 | 543 | | |
533 | 544 | | |
534 | | - | |
535 | | - | |
| 545 | + | |
| 546 | + | |
536 | 547 | | |
537 | 548 | | |
538 | 549 | | |
| |||
705 | 716 | | |
706 | 717 | | |
707 | 718 | | |
| 719 | + | |
708 | 720 | | |
709 | 721 | | |
710 | 722 | | |
| |||
758 | 770 | | |
759 | 771 | | |
760 | 772 | | |
761 | | - | |
| 773 | + | |
762 | 774 | | |
763 | 775 | | |
764 | 776 | | |
| |||
1300 | 1312 | | |
1301 | 1313 | | |
1302 | 1314 | | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
1303 | 1327 | | |
1304 | 1328 | | |
1305 | 1329 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
155 | 161 | | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
| 162 | + | |
163 | 163 | | |
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
167 | 167 | | |
168 | 168 | | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
169 | 176 | | |
170 | 177 | | |
171 | 178 | | |
172 | 179 | | |
173 | 180 | | |
174 | 181 | | |
175 | 182 | | |
176 | | - | |
177 | 183 | | |
178 | 184 | | |
179 | 185 | | |
| |||
359 | 365 | | |
360 | 366 | | |
361 | 367 | | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
362 | 386 | | |
363 | 387 | | |
364 | 388 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
38 | 39 | | |
39 | 40 | | |
40 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
41 | 101 | | |
42 | 102 | | |
43 | 103 | | |
| |||
62 | 122 | | |
63 | 123 | | |
64 | 124 | | |
| 125 | + | |
65 | 126 | | |
66 | | - | |
| 127 | + | |
67 | 128 | | |
68 | | - | |
| 129 | + | |
69 | 130 | | |
70 | 131 | | |
71 | 132 | | |
| |||
77 | 138 | | |
78 | 139 | | |
79 | 140 | | |
80 | | - | |
| 141 | + | |
| 142 | + | |
81 | 143 | | |
82 | 144 | | |
83 | 145 | | |
| |||
104 | 166 | | |
105 | 167 | | |
106 | 168 | | |
107 | | - | |
| 169 | + | |
0 commit comments