feat(layouts): saved layouts manager with Spotlight-style UI#4
Merged
Conversation
added 5 commits
April 20, 2026 15:40
Replace the window.prompt/alert-based save/load commands with a real
modal. Lists existing layouts, lets the user save the current canvas
(with regions, zoom and viewport), load, and delete — each with
proper input validation, error states, and a keyboard-friendly flow.
Reuses the existing main-process `layoutSave/layoutList/layoutLoad/
layoutDelete` IPC surface — no backend changes needed. Collapses the
two palette entries ("Save Layout As...", "Load Layout...") into a
single "Saved Layouts…" command that opens the manager.
…lay look Three related cleanups on the command palette: - Remove "Export Workspace Layout" and "Import Workspace Layout". The export command opened a native macOS save dialog and wrote a .json outside the app; the import command prompted via window.prompt for a path. Saving layouts now always goes through the in-app Saved Layouts manager (electron-store, named entries, modal UI), which is where the user expected to land when they hit "save layout". - Restyle the palette to match the Cmd+Shift+F search overlay: rounded-3xl with a brighter white/20 outline, backdrop-blur, wider (640px), input row with a leading magnifying-glass icon, bolder row text, type-tinted circular icon tiles, and rows inset from the container with a rounded selection highlight. The two overlays now feel like the same surface. - Fix the shortcut hint for Toggle File Explorer: was advertising ⌘⇧F, but that binding moved to Cmd+Shift+X in fix/shortcuts so globalSearch could take it. Also drops the Upload/Download icon aliases made unused by the export/ import removal.
… palette Saved Layouts modal was still wearing the old "dialog" chrome — title bar with close icon, nested input box with a separate Save button card, full-width borders. Promote it to the same look as the search overlay and command palette so the three surfaces feel like one family: - Outer container: rounded-3xl, white/20 outline, backdrop-blur, offset from top with pt-40 (not centered). - Input row: integrated into the container with a leading FloppyDisk icon; Save becomes a pill button on the right of the same row instead of a separate bordered box. - List rows: inset from the edges with a rounded selection highlight, circular violet type-tile on the left, bolder primary text. - Dropped the explicit title + X close button; Escape now closes the overlay (matches every other overlay in the app).
…gions closeAllPanels wipes every panel in the workspace, including the host 'canvas' panel that owns the dock center zone. The load flow wasn't recreating it, so the dock center came back empty — the user saw the workspace chrome but no canvas to land nodes on. Call ensureCenterCanvas() right after the reset so a fresh canvas host panel exists before node creation starts. Also grab the new canvas store via getWorkspaceCanvasStore(wsId) before calling addRegion/ zoomToFit — the useCanvasStoreApi reference captured at dialog mount pointed at the store we just disposed.
After closeAllPanels + ensureCenterCanvas the new host 'canvas' panel exists in dock state, but its store / ops only register when the React CanvasPanel mounts on the next tick. The subsequent sync calls to createTerminal / createEditor / createBrowser resolved via getActiveCanvasOps(), which at that instant still pointed at the disposed old canvas (or nothing), so nodes never made it onto the new canvas — the Welcome screen rendered instead because the new canvas had zero nodes. Find the newly-minted canvas panel id, call ensureCanvasOpsForPanel to build its store synchronously, then setActiveCanvasPanelId so placePanel resolves correctly for every node we're about to create.
0ec91d0 to
58a0709
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
window.prompt/alert-based save/load palette commands with a proper Saved Layouts modal. Lists existing layouts alphabetically, saves the current canvas arrangement (nodes + regions + zoom + viewport) under a name, loads / deletes with proper validation and error states. Reuses the existinglayoutSave/List/Load/DeleteIPC surface — no backend changes.window.prompt) palette commands — superseded by the in-app modal per user request ("save layout with name in app not external").rounded-3xl,white/20outline, backdrop blur, leading magnifying-glass icon, bolder text, type-tinted circular icon tiles on rows, inset selection highlight. Three overlays (search / palette / layouts) now share one visual language.⌘⇧F, now shows⌘⇧Xafter the collision move infeat/canvas-wide-search.Bug fixes folded into this branch
fix(layouts): restore canvas panel after load—closeAllPanelswipes every panel including the hostcanvaspanel that owns the dock center zone; load flow didn't recreate it, so the center came back empty. CallensureCenterCanvas(wsId)right after the reset and use the fresh canvas store for regions/zoomToFit.fix(layouts): register new canvas store before adding restored nodes— the ReactCanvasPanelmounts async, so its store/ops registered after our synccreateTerminal/createEditor/createBrowsercalls. Nodes landed nowhere and the Welcome screen showed. Fix: explicitlyensureCanvasOpsForPanel+setActiveCanvasPanelIdon the newly-minted canvas before creating nodes.Test plan
Cmd+K→ "Saved Layouts…" opens the modal.zoomToFitre-frames.⌘⇧Xin the palette row.Known scope limits
Depends on
feat/canvas-wide-search). Either PR can merge first; the other just picks up a trivial merge.🤖 Generated with Claude Code