[Game Systems] System selector UI + free-text coexistence + suggested-match nudge (frontend) #135
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation/Context
With the
GameSystemregistry andcampaigns.game_system_idFK in place (#133), GMsneed a way to actually pick a registry system from the UI — while free-text campaigns
keep working exactly as before. Most existing campaigns already have a free-text value
that names a known system (
"D&D 5e","PF2e","5e", …); a cheap, safe suggestionnudge covers the 90% case without any silent/automatic linking.
Approach
Selector UI. Add a registry dropdown to the campaign create form
(
webapp/frontend/src/pages/Dashboard.jsx:107-111,138-142, input at:244-245) and thecampaign settings edit form (
webapp/frontend/src/pages/CampaignDetail.jsx:340,387,1427-1428).The existing free-text input is retained and presented as a "Free text / Other" option —
never removed, never gated behind the new selector. Campaign cards
(
Dashboard.jsx:83-84) and the campaign header (CampaignDetail.jsx:965-966) continueto render the resolved display string from the backend's resolution helper (#133), so no
client-side resolution logic is needed — just wire the new
game_system_reffieldthrough if a distinct linked-system badge/icon is wanted.
Suggested-match nudge. On campaign settings load (GM only): if
game_system_id IS NULLandlower(trim(game_system))matches any registryaliasesentry, show aone-line banner — "This campaign's system looks like Pathfinder 2e — link it? (You
can undo this at any time.)" Accepting sets
game_system_idvia the existing campaignPATCH; the free-text column is left untouched. Declining is remembered (a
game_system_prompt_dismissedflag or localStorage) so the banner doesn't nag everyvisit. This alias-matching check can run client-side against the registry list already
fetched for the dropdown, or server-side as a computed field on the campaign response —
implementer's call, but it must not write anything until the GM explicitly accepts.
Scope discipline. This is UI wiring only — the registry, the FK, the resolution
helper, and the
game_system_refschema field all come from #133 and are notre-implemented here.
Dependencies
game_system_idon create/update, andgame_system_refon read.Out of scope
explicit GM opt-in.
Acceptance criteria
"Free text / Other" option that reveals the existing free-text input.
between a linked system and free text at any time.
name for both linked and free-form campaigns, sourced from the backend.
suggests linking; accepting sets
game_system_idwithout altering the free-textcolumn; declining persists across the session/page reloads.
accepts the nudge or picks a system manually.
accepting the nudge issues the expected PATCH payload.
Done and verified — merged into the integration branch via PR #207.
Verification (Node 20 via
node:20-alpine):Dashboard.test.jsx/CampaignDetail.test.jsxfor both selector modes, the create/save payload shape, and nudge show/hide/dismiss/accept.npm run build, Vite + PWA).Delivered: a shared
GameSystemSelect(registry dropdown + always-available free-text fallback, "Linked" badge),fetchGameSystems()client, selector wired into the create and settings forms (game_system_idthreaded through), and a GM-only suggested-match nudge that links a campaign whose free text matches a registryshort_name/name/alias— accept sends a partial{game_system_id}PATCH (free text untouched), dismiss persists tolocalStorage. Never writes until the GM accepts; the free-text input is never removed.Closing; ships to
mainwith the v3.9.0 release.