Skip to content

fix(editor): make Settings modal and toolbar trailer truly global#67

Merged
DavidBabinec merged 1 commit into
mainfrom
fix/global-settings-modal-and-header
Jun 17, 2026
Merged

fix(editor): make Settings modal and toolbar trailer truly global#67
DavidBabinec merged 1 commit into
mainfrom
fix/global-settings-modal-and-header

Conversation

@DavidBabinec

Copy link
Copy Markdown
Contributor

What changed

Two related fixes so the admin Settings modal and the toolbar settings cog behave globally on every admin route.

1. Settings General + Publishing now load on every page

GeneralSection and PublishingSection read site data straight off the heavy editor store (@site/store/store), which is only hydrated by usePersistence on the Site editor. On Content / Data / Media / Plugins / Users / Account, the editor store's site is null, so those sections rendered a permanent skeleton (see the original bug screenshots). The modal was "global" in name only.

New useSiteSettingsController (src/admin/modals/Settings/useSiteSettingsController.ts) exposes one uniform site-settings shape and picks the right source:

  • Site editor (live draft in the editor store) → delegate to the editor-store mutations, so settings edits join the unsaved draft and persist through autosave / Save alongside page-tree edits.
  • Everywhere else (no in-memory draft) → a standalone store loads the document via cmsAdapter, edits a local copy, and persists immediately with a shell-only saveSite (empty dirty sets → pages/components/layouts untouched), then refreshes the adminUi site summary and fires CMS_SITE_RELOAD_EVENT.

The controller is imported only by the lazy SettingsModal sections, so the editor-store import stays inside the settings chunk and never enters the eager graph of the lightweight layouts — the bundle-isolation contract holds.

2. Settings cog is now a consistent, global part of the header

The Toolbar shell already always rendered OpenLivePageButton + AccountMenuButton, but SettingsButton was injected per-layout — Site, Plugins/Users/Account, and Content had it; Media and Data did not.

SettingsButton is hoisted into Toolbar.tsx as part of a fixed global trailer (Settings → Open live page → Account), identical on every route the way the left nav is. Removed the per-layout/per-page injections (AdminCanvasLayout, AdminPageLayout, ContentToolbar) and the now-dead ToolbarDivider + .divider CSS. SettingsButton reads only the tiny adminUi store, so hosting it in the shell doesn't drag the editor toolchain into non-editor bundles.

User/developer impact

  • The Settings modal's General and Publishing sections work from any admin page, not just the Site editor.
  • The settings cog appears in the same place on every admin page (Media and Data gain it; no page renders a duplicate).
  • Editing site settings outside the Site editor saves immediately (those pages have no Save button).

Verification

  • bun run build (tsc -b && vite build) — clean
  • bun test — 5442 pass, 0 fail
  • bun run lint — clean on changed files

Updated toolbar.test.ts (settings cog is now asserted in the shell, not AdminCanvasLayout) and docs/editor.md (global trailer + controller).

🤖 Generated with Claude Code

The Settings modal is openable from every admin route, but its General
and Publishing sections read site data straight off the heavy editor
store, which is only hydrated on the Site editor. On Content / Data /
Media / Plugins / Users / Account those sections rendered a permanent
skeleton — the modal was "global" in name only. Separately, the settings
cog was injected per-layout: Site, Plugins/Users/Account, and Content
had it, but Media and Data did not.

Fix both:

- Hoist SettingsButton into the Toolbar shell so the trailer
  (Settings → Open live page → Account) is identical on every route,
  the same way the left nav is. Remove the per-layout/per-page
  injections (AdminCanvasLayout, AdminPageLayout, ContentToolbar) and
  the now-dead ToolbarDivider.
- Add useSiteSettingsController: one uniform site-settings source that
  delegates to the editor draft on the Site editor (joins autosave) and
  loads/saves via cmsAdapter (shell-only write + site-reload event)
  everywhere else. General and Publishing consume it instead of the
  editor store directly, so they work on every admin page without
  forcing editor-store hydration into the light layouts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@DavidBabinec DavidBabinec marked this pull request as ready for review June 17, 2026 12:35
@DavidBabinec DavidBabinec merged commit 6988c18 into main Jun 17, 2026
6 checks passed
@DavidBabinec DavidBabinec deleted the fix/global-settings-modal-and-header branch June 30, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant