Skip to content

feat(surveys): edit survey settings after creation (Issue 1459) - #1473

Merged
leahpeker merged 3 commits into
mainfrom
feat-survey-settings-edit
Sep 14, 2026
Merged

leahpeker merged 3 commits into
mainfrom
feat-survey-settings-edit

Conversation

@leahpeker

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a "settings" dialog on the survey builder screen to edit title, description, slug, visibility, one-response-per-user, and linked event via the existing PATCH /surveys/{id}/ endpoint (useUpdateSurvey).
  • Extracts the shared field layout from CreateSurveyDialog into a new SurveyFields component so create and edit stay in sync; the linked-event picker reuses the existing useEvents hook and keeps a past/cancelled linked event selectable even once it drops off the active list.
  • Slug collisions from the backend (Code.Survey.SlugAlreadyExists) now surface as a field-level error via a new getFieldError helper in apiErrors.ts, instead of the generic form alert.

Closes #1459

Test plan

  • make agent-frontend-lint — passes
  • make agent-frontend-typecheck — passes
  • make agent-frontend-test — passes (1286 passed, 1 skipped)
  • make agent-ci — backend ruff, manage.py check, ty typecheck, cognitive-complexity, and check-codes all pass clean. The backend pytest run has 7 pre-existing failures unrelated to this change (this branch is frontend-only): 5 test_sse.py auth tests that need Postgres pg_notify (SSE is documented in CLAUDE.md as returning 503 on SQLite), and 2 concurrency race tests (test_poll_finalize_race.py, test_rsvp_capacity_race.py) that hit SQLite's lack of real row-level locking under select_for_update.
  • added SurveySettingsDialog.test.tsx covering: seeding fields from the survey and saving edits, keeping a non-active linked event selectable, surfacing a slug collision as a field error, and blocking save on a blank title.

@leahpeker

Copy link
Copy Markdown
Collaborator Author

Merge conflicts with main need manual resolution.

Rebasing feat-survey-settings-edit onto main surfaced conflicts in two commits:

Auto-resolvable (mechanical):

Needs human judgment (blocker):

  • frontend/src/screens/admin/SurveyAdminListScreen.test.tsx — add/add conflict. main (via feat(surveys): add copyable participant link (Issue 1458) #1469) and this PR each added a different test file at this path, with incompatible module-level setup:

    • main: mocks sonner, seeds useAdminSurveys with two surveys, tests the copy-link button.
    • this PR: mocks react-router-dom (useNavigate) and @/api/events, seeds useAdminSurveys with [], tests create-dialog reset + field-error routing.

    The two suites can't be concatenated — the vi.mock factories for @/api/surveyAdmin conflict, and the copy-link test depends on a non-empty survey list while the create tests assume an empty one. Merging them means picking one mock set and reconciling both suites against it.

Auto-resolution was skipped to avoid a risky merge; the branch was left untouched (rebase aborted).

leahpeker and others added 3 commits September 14, 2026 20:40
Add a settings dialog on the survey builder to edit title, description,
slug, visibility, one-response-per-user, and linked event via the
existing PATCH endpoint. Extracts the shared field layout from
CreateSurveyDialog into SurveyFields so create and edit stay in sync.
Slug collisions surface as a field-level error via a new getFieldError
helper in apiErrors.
- clear the slug field error as soon as the slug changes, in both the
  settings and create dialogs
- remount CreateSurveyDialog on open so values don't survive close/reopen
- show slug collisions inline on create, matching the edit path
- route linked_event_id backend errors to the linked event dropdown
…hook

Drop two comments that restated the code they sat above and tighten the
getFieldError docblock to the part that isn't in the signature.

Move useSurveyFieldErrors into its own module so SurveyFields.tsx exports
only components — it was tripping react-refresh/only-export-components,
which the config disables only for src/router.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@leahpeker
leahpeker force-pushed the feat-survey-settings-edit branch from 8176a02 to fbacaa0 Compare September 14, 2026 17:45
@leahpeker

Copy link
Copy Markdown
Collaborator Author

Resolved — conflicts are gone, branch rebased onto main and force-pushed (fbacaa03).

Test file (the blocker): hand-merged into one file with a unified mock set — useAdminSurveys now seeds the two-survey fixture from main (the create-dialog tests don't depend on an empty list), useCreateSurvey uses the shared createMutateAsync spy, and the sonner, @/api/events, and react-router-dom mocks all coexist (the router mock spreads ...actual, so MemoryRouter/Link still work). Both suites kept as separate describe blocks sharing the renderScreen helper. All 6 tests pass.

Screen file: import-only union, as expected.

Two extra things while in here:

  • Trimmed the verbose comments this PR added — dropped the two that restated the code below them, tightened the getFieldError docblock, kept the remount note and the linked-event constraint (both are real hidden constraints).
  • SurveyFields.tsx was failing react-refresh/only-export-components by exporting useSurveyFieldErrors alongside the component (the config disables that rule only for src/router). Moved the hook to useSurveyFieldErrors.ts.

Verified: frontend lint, typecheck, and the full 1322-test suite pass; backend lint/typecheck/complexity pass. The 7 backend failures locally (SSE + the two race tests) are pre-existing SQLite-environment limits — identical on main.

@leahpeker
leahpeker merged commit dc5b1b7 into main Sep 14, 2026
3 checks passed
@leahpeker
leahpeker deleted the feat-survey-settings-edit branch September 14, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow editing survey settings after creation

1 participant