Repository navigation
Fetch fields when a settings save names one the Build tab hasn't loaded - #508
Conversation
A "Group slots by" save shows the settings the server merges, which can name a reminder field another tab or an AI assistant added after this tab loaded. The tab then had no field to put the reminder bell on, and every date field's reminder box was blocked by a field it couldn't name. Now the save fetches the field list first when that happens, inside the same settings queue so a later save's answer still lands last. A failed fetch leaves the list as it was, since the save itself succeeded. Fixes #398. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4Xf8UF6XA8WQ5rAxo5cYy
Tophat: passedI ran c3f2f2c locally with
For the owner (UX): suppose another tab or an AI assistant added a date field and moved reminders to it. On the Build tab, the next "Group slots by" change now brings that field into the Fields list with the reminder bell. The other date fields' reminder note names it. On Screenshots are in https://claude.ai/code/session_01APk7ReyToBioTg3ZrfL49L. Generated by Claude Code |
richshaw
left a comment
There was a problem hiding this comment.
Review: passed (round 1)
The PR does what #398 asks, and takes the full fix. saveSettings now runs catchUpOnFields(next) before showSettings(next). When the saved settings name a group-by or reminder ref the tab hasn't loaded, it fetches GET /api/signups/[id]/fields and shows that list. The fetch runs inside the withSave callback that is already chained on settingsSaveRef, so the next queued save can't start until this one has fetched and shown its fields. Two saves in a row still land in click order, which the issue's "Watch for" asked about. stateRef.current.fields is read after the PATCH returns, so the check sees any field this tab added while the save was in flight. If the fetch fails, the PATCH has still succeeded. The list stays as it was and the rail says "Saved", as the description says. showSettings then applies the server's settings, which are authoritative, so the tab doesn't need mirrorFieldChange here. I checked each "Done when" item. The hook test for a save that names an unloaded reminder field is there: I put main's useBuildState.ts under the new tests, and that test fails there and passes on the PR. The InlineFieldForm item applies only to the smaller fix, which wasn't taken. CI is green.
Blocking (0)
Optional (3):
src/components/build-shared/useBuildState.ts:770: the issue's outline said to share the reorder path's refetch.toBuildFields(await sendForData<SlotFieldDefinition[]>('GET', fieldsUrl))now appears twice, here and inmoveField(line 533). Aconst fetchFields = async () => …besideshowFieldswould make it one. It's a single expression, not a copied helper, so it doesn't need a round.src/components/build-shared/useBuildState.ts:770:SET_FIELDSreplaces the whole list. If a field add or edit from this same tab finishes between the GET leaving and its answer arriving, that change is overwritten until the next refetch or reload.moveField's refetch has the same window, and this one only runs when a setting names a field the tab lacks. Not worth code.- The description's "Column widths are kept by field id outside
BuildField" bullet describes nothing that exists today.BuildFieldhas no width, and nothing inbuild-sharedor the builders stores per-field column widths. Replacing the list can't lose anything, so the issue's "Keep column widths" note is met trivially.
Earlier threads: none. Copilot couldn't review because its quota is used up.
Checks: CI is green on c3f2f2c (lint-type-test, e2e, CodeQL). The tophat passed on this exact SHA, so no runtime code has changed since it ran. Locally I ran the three new tests on the PR (passed), and the same tests against main's hook (the first fails). I read the full diff, saveSettings, showSettings, mirrorFieldChange, moveField's saveMove refetch and the SET_FIELDS reducer, and went through the checklist. No service, policy, schema, public route or help article is touched, and there's a CHANGELOG entry.
Why the owner: pipeline:ux. Suppose another tab or an AI assistant has added a date field and moved reminders to it. The Build tab's next "Group slots by" change now brings that field into the Fields list with the reminder bell, and the other date fields' note names it. Before, it showed a blank until a reload. See the tophat's 508-before-after-groupby and 508-before-date-field-edit for main, and 508-after-after-groupby, 508-after-date-field-edit and 508-after-groupby-phone for the PR.
https://claude.ai/code/session_01PVfzKGxMqq8ZtxPNd3fahF
Generated by Claude Code
|
Resolve conflicts please |
Keeps both sides of the CHANGELOG "Fixed" entries and of the new test blocks at the end of useBuildState.test.ts (#398's settings-save tests and main's renameGroup tests). No runtime code conflicted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BbFpSwrE1SnxwR1UPfruWu
|
Conflicts resolved in
Locally: https://claude.ai/code/session_01BbFpSwrE1SnxwR1UPfruWu Generated by Claude Code |
|
Approved by the owner at Not merged: one gate failed.
Every other gate passed on https://claude.ai/code/session_01VzkajMzBsnuJhN9LFqAVbP Generated by Claude Code |
Resolves a CHANGELOG conflict: keeps main's new Changed entries and this PR's #398 Fixed entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VzkajMzBsnuJhN9LFqAVbP
|
Conflict resolved in
Locally, https://claude.ai/code/session_01VzkajMzBsnuJhN9LFqAVbP Generated by Claude Code |
Fixes #398.
The problem
Since #360, a settings save on the Build tab shows the settings the server returns. If another tab or an AI assistant has added a date field and moved reminders to it, the next "Group slots by" change adopts that reminder field, but the tab's field list doesn't have it. Until a reload, no field shows the reminder bell, and every date field's reminder box is disabled behind a note with a blank where the field's name should be.
The fix
saveSettingsinsrc/components/build-shared/useBuildState.tsnow calls a newcatchUpOnFieldsbeforeshowSettings. When the saved settings name a field ref (the reminder field or a group-by field) that the tab doesn't have, it fetchesGET /api/signups/[id]/fieldsand shows that list, the same refetchmoveFielduses.settingsSaveRef, so two saves in a row still show their answers in click order.BuildField, so replacing the list keeps them, as the reorder refetch does.InlineFieldFormis unchanged.Tests
useBuildState.test.tshas three new hook tests:main.I ran
pnpm lint && pnpm typecheck && pnpm knip && pnpm test(1252 passed), pluspnpm build && pnpm budgets./app/signups/[id]/buildis 150.2 kB against its 151 kB budget. I didn't runpnpm test:db, because no service, DB, MCP or OAuth code changed.Generated by Claude Code