Repository navigation
Commit 022ea60
Move the rename dialog out of SiteRow into a component of its own (#568)
## Why
`SiteRow` is about 5,000 lines and holds the state of everything a
site's view can do. The redesign in #542 needs its dialogs as components
it can restyle one at a time, and #553 asks for them to leave
`index.jsx` one per pull request. This is the first: the rename dialog,
chosen because nothing else in `SiteRow` reads its state.
## What changes
`src/renderer/components/rename-site-modal.jsx` is new. It holds what
was inline in `SiteRow`: the value being typed, the refusal, the busy
flag, two effects, the handlers and the markup. `SiteRow` keeps the one
thing that is its business, whether the dialog is open.
One thing is different in structure. **The component is mounted while
the dialog is open and not otherwise.** Opening used to reset the value
to the site's name and clear the last refusal by hand; a fresh mount
does both, so those two lines are gone rather than moved. Everything
else is the code that was there, with `onClose()` where it set
`SiteRow`'s flag.
**No journey drove this dialog**, so one does now. `rename-site.spec.js`
was written against the inline version first and passes on both: the
dialog opens on the site's name with it selected, refuses an empty one,
writes nothing when cancelled, and puts the saved name in the sidebar
and the heading. `siteHeading` joins the shared locators in `ui.cjs`,
now that two files use it.
Deliberately not in this PR: the other four dialogs, and the two things
listed under Risks that would change what the dialog does.
## How to test this
Platforms: any. Use the Buildkite build for the current head of this
branch.
The journey carries this: `npx playwright test --project=journeys -g
"rename dialog"`, from the repository root. It passes on `trunk`'s
inline dialog and on the component, and it is red when Save does not
rename, when an empty name is accepted, when Cancel saves what was
typed, and when the name is not selected on opening.
What it does not reach is the dialog while a rename is pending, which is
too brief to stage against a local store:
**Starting state:** the app open on any site.
1. Click the pencil beside the site's name. The "Rename site" dialog
opens with the name selected.
2. Type a new name and press Enter. The dialog closes and the name
changes in the sidebar and in the heading.
3. Open it again, clear the field, and click "Save". "Site name cannot
be empty." appears under the field and the dialog stays open.
4. Press Escape. The dialog closes and the name is unchanged.
**What must not have happened:**
- The name typed and then abandoned in step 4's dialog is not in the
field the next time it opens.
- No other site's name changed.
## Risks and limitations
- **A failed rename still closes the dialog.** `App`'s rename handler
catches every error, shows it in a native alert and resolves, so the
dialog's own place for a refusal can never be reached and what was typed
is lost. This is how `trunk` behaves; the move keeps it, and fixing it
changes behaviour.
- **The empty-name check is still in a `.jsx` file**, where the unit
suite cannot reach it. It was moved, not added. The rule in the review
standard says it belongs in a `.cjs` module with a test; the journey
covers it at layer 4 until then.
- **The journey costs one app launch** on every pull request, on both
platforms: about a second and a half locally on macOS.
- **Two of its assertions could not be shown to be load-bearing on their
own.** The saved name's surrounding spaces are removed by the main
process as well as the dialog, and what was typed is forgotten both by
the fresh mount and by an effect; breaking one of each pair leaves the
test green.
- **Checked on macOS only.** Windows is covered by CI.
- Review: 1 [fix here], fixed; 2 [follow-up], the first two items above.
## Related
Part of #553, which has four more dialogs. Part of #542. Follows #567.
---
<details>
<summary>Design decisions and alternatives considered</summary>
**Mounted while open, rather than always mounted with an `isOpen`
prop.** An always-mounted component would have to reset its own state
each time it opens, from an effect, which is the code this removes.
Mounting it fresh is the reset.
**`SiteRow` still owns the open flag.** The button that opens the dialog
is in the site's header, which `SiteRow` renders, so the flag has to
live where both can reach it.
**The state keeps its names**, `renameValue`, `renameError`, `renaming`,
although inside a component called `RenameSiteModal` the prefix says
nothing. Keeping them makes the diff readable as a move.
**A journey of its own rather than a step in `engine.spec.js`.** That
file's restart test renames through the handler directly, deliberately,
because what it proves is the write reaching disk. The dialog is a
different claim.
</details>
<details>
<summary>Review outcome (required — see AGENTS.md)</summary>
**1 [fix here] · 2 [follow-up]** — the one fixed, the two recorded under
Risks.
- Tests, low, [fix here], fixed: TESTING.md and the helper's header
listed what `ui.cjs` holds as the shared controls and four locators, and
`siteHeading` is neither. Both say five.
- Architecture, low, [follow-up], deferred: the empty-name check and its
sentence are in JSX. Moved, not added; extracting it to a module changes
nothing a contributor sees but is a change to the code's shape beyond a
move.
- Architecture, low, [follow-up], deferred: `App.onRename` swallows a
failed write, so the dialog closes on failure. It predates this change,
and fixing it is a behaviour change.
The review went through every piece of state, effect, handler and prop
against `trunk` and found the behaviour the same, including a state
update after unmount on success, closing while a rename is pending, and
focus and selection on opening.
- **Review:** completed — fresh agent context, local, before the PR
existed, read-only; head b6c996d / base
2b6a69a; committed work only, working
tree clean; outcome above. CodeRabbit: not run yet.
- **Since review:** `b6c996d → 655a5ed` checked. The difference is the
fix and one comment in the component. It was not reviewed again by a
fresh context.
Checks, macOS, local:
| Check | On | Result |
|---|---|---|
| `eslint . --max-warnings=0` | 655a5ed | clean |
| unit suite on Node | b6c996d | 1691 pass, 2 skipped, 0 fail |
| unit suite on Electron's Node | b6c996d | 1693 pass, 0 fail |
| `npm run test:e2e` | b6c996d | 35 of 35 pass |
| the two journeys that use what the second commit touched | 655a5ed | 2
of 2 pass |
| `npm run test:e2e:packaged` | b6c996d | 15 of 15 pass |
Lint and the unit suites were run on this checkout's files only: a
worktree left by another local session sits under `.claude/worktrees/`,
and the bare commands collect it.
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>1 parent 2b6a69a commit 022ea60
6 files changed
Lines changed: 208 additions & 89 deletions
File tree
- src/renderer
- components
- tests/e2e
- helpers
- journeys
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
221 | 221 | | |
222 | 222 | | |
223 | 223 | | |
224 | | - | |
| 224 | + | |
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
| 75 | + | |
75 | 76 | | |
76 | 77 | | |
77 | 78 | | |
| |||
133 | 134 | | |
134 | 135 | | |
135 | 136 | | |
136 | | - | |
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| |||
1343 | 1343 | | |
1344 | 1344 | | |
1345 | 1345 | | |
| 1346 | + | |
| 1347 | + | |
1346 | 1348 | | |
1347 | | - | |
1348 | | - | |
1349 | | - | |
1350 | | - | |
1351 | | - | |
1352 | | - | |
1353 | | - | |
1354 | | - | |
1355 | | - | |
1356 | | - | |
1357 | | - | |
1358 | | - | |
1359 | | - | |
1360 | | - | |
1361 | | - | |
1362 | | - | |
1363 | | - | |
1364 | | - | |
1365 | | - | |
1366 | | - | |
1367 | | - | |
1368 | | - | |
1369 | | - | |
1370 | | - | |
1371 | | - | |
1372 | | - | |
1373 | | - | |
1374 | | - | |
1375 | | - | |
1376 | | - | |
1377 | | - | |
1378 | | - | |
1379 | | - | |
1380 | | - | |
1381 | | - | |
1382 | | - | |
1383 | | - | |
1384 | | - | |
1385 | | - | |
1386 | | - | |
1387 | | - | |
1388 | | - | |
1389 | | - | |
1390 | | - | |
1391 | | - | |
1392 | | - | |
1393 | | - | |
1394 | | - | |
1395 | | - | |
1396 | | - | |
1397 | | - | |
1398 | | - | |
1399 | | - | |
1400 | | - | |
| 1349 | + | |
| 1350 | + | |
1401 | 1351 | | |
1402 | 1352 | | |
1403 | 1353 | | |
| |||
5712 | 5662 | | |
5713 | 5663 | | |
5714 | 5664 | | |
5715 | | - | |
5716 | | - | |
5717 | | - | |
5718 | | - | |
5719 | | - | |
5720 | | - | |
5721 | | - | |
5722 | | - | |
5723 | | - | |
5724 | | - | |
5725 | | - | |
5726 | | - | |
5727 | | - | |
5728 | | - | |
5729 | | - | |
5730 | | - | |
5731 | | - | |
5732 | | - | |
5733 | | - | |
5734 | | - | |
5735 | | - | |
5736 | | - | |
5737 | | - | |
5738 | | - | |
5739 | | - | |
5740 | | - | |
5741 | | - | |
| 5665 | + | |
5742 | 5666 | | |
5743 | 5667 | | |
5744 | 5668 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | | - | |
15 | | - | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| |||
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
68 | 78 | | |
69 | 79 | | |
70 | 80 | | |
| |||
206 | 216 | | |
207 | 217 | | |
208 | 218 | | |
| 219 | + | |
209 | 220 | | |
210 | 221 | | |
211 | 222 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
28 | | - | |
| 27 | + | |
| 28 | + | |
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| |||
160 | 160 | | |
161 | 161 | | |
162 | 162 | | |
163 | | - | |
| 163 | + | |
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 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 | + | |
0 commit comments