Skip to content

unify post new + edit into PostForm component

jedmund requested to merge jedmund/post-form-unify into jedmund/admin-save-ui

Created by: jedmund

Stacked on #87.

Summary

  • extracts src/lib/components/admin/forms/PostForm.svelte — single component that handles both creation and editing of posts
  • /admin/posts/new and /admin/posts/[id]/edit are now thin wrappers that mount PostForm; edit page fetches the post first, new page mounts empty
  • snapshot-based dirty tracking replaces the previous triple-tracking via post + initialValues + status — single source of truth (savedSnapshot), isDirty = currentSnapshot() !== savedSnapshot (with a "any content" rule before first save)
  • after first save on a new post, the URL silently swaps to /admin/posts/[id]/edit via replaceState and the same component continues to handle subsequent saves as PUTs — no page remount, scroll/focus preserved
  • Syndication tab is hidden until first save (since PostSyndicationForm requires a real contentId); Delete button is hidden pre-save
  • featured image, metadata, and Cmd+S all work pre-save
  • shared types extracted to forms/post-types.ts so route pages can type the loaded post without importing through a Svelte file

Net diff: 671 insertions, 1067 deletions — meaningful code reduction even with the full rewrite.

This is PR 2 of the planned admin save-flow refactor. PR 3 will swap the remaining goto-after-save patterns in Project/Garden/Album forms for replaceState.

Test plan

  • /admin/posts/new: title + content → "Save draft". URL silently swaps to /admin/posts/[id]/edit. Form stays mounted, scroll preserved. Syndication tab now appears.
  • subsequent saves on the same form → PUT (not POST). isDirty correctly resets after each save.
  • /admin/posts/[id]/edit direct load: post loads, all three tabs available immediately.
  • concurrency: edit in two tabs, save in one, then save in the other → 409 error.
  • Cmd+S works pre- and post-save.
  • Browser back from a freshly-saved new post goes to wherever the user came from (not the new-post route).
  • InlineComposerModal "open in editor" flow: drafts content via sessionStorage, lands on /new, content preserved.
  • pnpm run check net error count not increased (118 vs prior 125 — slight reduction from rewrite).

Merge request reports

Loading