Editor has no Save button — user can edit a design but must navigate back to Workspace and click 'Save to Gallery' to persist; the Editor offers no save affordance #150

Closed
opened 2026-10-03 05:45:14 +00:00 by Mark · 1 comment
Owner

Finding

The Editor (src/pages/Editor.tsx) has no "Save" or "Save to Gallery" button. The Editor header (src/components/editor/EditorHeader.tsx) exposes:

  • Back to Workspace (link)
  • Export (button, opens the export dialog)
  • Undo / Redo

A user who opens a saved design from the Gallery, edits it in the Editor, then clicks "Back to Workspace" has no way to persist the edits from inside the Editor. They must:

  1. Click "Back to Workspace" (navigates to /workspace)
  2. Click the Workspace's "Save to Gallery" button (separate from the Editor)
  3. Confirm any overwrite dialog

The Editor writes its changes to sessionStorage on every modification (via the existing useEffect in Editor.tsx:188-210). The Workspace re-hydrates from that sessionStorage on mount. So the data IS carried across the route change. But the user has to know to click "Save to Gallery" in the Workspace, and the Editor offers no way to trigger it directly.

This is a real UX gap: the user is in a context (the Editor) where they expect to be able to save their work, and they can't. They have to navigate to a different context (the Workspace) to do it.

Where

  • Editor header: src/components/editor/EditorHeader.tsx — buttons at line 84-110 (Export), 118-134 (Undo), 137-153 (Redo), 76-89 (Back to Workspace). No Save.
  • Editor's sessionStorage write: src/pages/Editor.tsx:188-210 (carries edits across navigation)
  • Workspace's Save to Gallery: src/components/workspace/useWorkspace.ts (the handleSave callback, exact line not relevant here)

Suggested fix shape

Add a Save button to the Editor header, between Undo/Redo and the right edge of the actions group. The button:

  1. Reads the current paths from Editor state
  2. Calls the Workspace's save handler via a shared mechanism (lift the save callback to a context, or refactor the save logic into a hook that both Editor and Workspace can call)
  3. Shows a success toast on save, an error toast on failure
  4. Is disabled when there are no unsaved changes (compare the current paths against the most-recently-saved paths; if equal, disable)

The simplest implementation: move the handleSave logic out of useWorkspace into a shared useSaveDesign hook that both the Workspace and the Editor can call. The hook takes the design state, the snapshot, and the current stitchObjects/threadStops/designSettings and writes to localStorage.

The Save button could also be a "Save & Close" variant that saves then navigates to /gallery, giving the user a clear end-state.

Severity

High. Editing in the Editor and returning to the Workspace without manually clicking "Save to Gallery" loses the work. A user expectation broken.

Discovered by

Gap analysis (2026-10-02) of Editor/Gallery integration.

  • The Editor-Workspace round-trip was fixed in #110 (Editor writes to sessionStorage, Workspace re-hydrates). The save-from-Editor side is the missing piece.
## Finding The Editor (`src/pages/Editor.tsx`) has no "Save" or "Save to Gallery" button. The Editor header (`src/components/editor/EditorHeader.tsx`) exposes: - Back to Workspace (link) - Export (button, opens the export dialog) - Undo / Redo A user who opens a saved design from the Gallery, edits it in the Editor, then clicks "Back to Workspace" has no way to persist the edits from inside the Editor. They must: 1. Click "Back to Workspace" (navigates to /workspace) 2. Click the Workspace's "Save to Gallery" button (separate from the Editor) 3. Confirm any overwrite dialog The Editor writes its changes to `sessionStorage` on every modification (via the existing useEffect in `Editor.tsx:188-210`). The Workspace re-hydrates from that sessionStorage on mount. So the data IS carried across the route change. But the user has to know to click "Save to Gallery" in the Workspace, and the Editor offers no way to trigger it directly. This is a real UX gap: the user is in a context (the Editor) where they expect to be able to save their work, and they can't. They have to navigate to a different context (the Workspace) to do it. ## Where - Editor header: `src/components/editor/EditorHeader.tsx` — buttons at line 84-110 (Export), 118-134 (Undo), 137-153 (Redo), 76-89 (Back to Workspace). No Save. - Editor's sessionStorage write: `src/pages/Editor.tsx:188-210` (carries edits across navigation) - Workspace's Save to Gallery: `src/components/workspace/useWorkspace.ts` (the `handleSave` callback, exact line not relevant here) ## Suggested fix shape Add a Save button to the Editor header, between Undo/Redo and the right edge of the actions group. The button: 1. Reads the current paths from Editor state 2. Calls the Workspace's save handler via a shared mechanism (lift the save callback to a context, or refactor the save logic into a hook that both Editor and Workspace can call) 3. Shows a success toast on save, an error toast on failure 4. Is disabled when there are no unsaved changes (compare the current paths against the most-recently-saved paths; if equal, disable) The simplest implementation: move the `handleSave` logic out of `useWorkspace` into a shared `useSaveDesign` hook that both the Workspace and the Editor can call. The hook takes the design state, the snapshot, and the current stitchObjects/threadStops/designSettings and writes to localStorage. The Save button could also be a "Save & Close" variant that saves then navigates to /gallery, giving the user a clear end-state. ## Severity High. Editing in the Editor and returning to the Workspace without manually clicking "Save to Gallery" loses the work. A user expectation broken. ## Discovered by Gap analysis (2026-10-02) of Editor/Gallery integration. ## Related - The Editor-Workspace round-trip was fixed in #110 (Editor writes to sessionStorage, Workspace re-hydrates). The save-from-Editor side is the missing piece.
Author
Owner

Fixed in commit 7de1e29 on origin/main.

Implementation:

  • Added a Save button to the Editor header (between Back to Workspace and Export), styled with the gold accent to match the rest of the editor chrome.
  • Extracted the Workspace Save-to-Gallery persistence into a shared src/components/gallery/saveDesign.ts helper (saveDesignToGallery) that both the Workspace header and the Editor call. Returns a structured {ok, design} / {ok: false, error} result so callers surface toasts consistently.
  • Refactored useWorkspace.saveCurrentDesign to delegate to the helper — Workspace behavior is unchanged byte-for-byte (same id shape, same tc_design_snapshots/<id> sidecar, same source/folder defaults, same quota fallback).
  • Editor handleSave reuses the existing pathsToStitchObjects / pathsToThreadStops converters that already feed the ExportDialog — single source of truth for what gets persisted.
  • Save button is disabled when the design has no visible paths.

Verification: 622/622 tests pass, lint+typecheck clean. Added 9 new tests (4 for the helper, 5 for the Editor Save flow including filename round-trip and sessionStorage-snapshot-intact-after-save).

Fixed in commit 7de1e29 on origin/main. Implementation: - Added a Save button to the Editor header (between Back to Workspace and Export), styled with the gold accent to match the rest of the editor chrome. - Extracted the Workspace Save-to-Gallery persistence into a shared `src/components/gallery/saveDesign.ts` helper (`saveDesignToGallery`) that both the Workspace header and the Editor call. Returns a structured `{ok, design}` / `{ok: false, error}` result so callers surface toasts consistently. - Refactored `useWorkspace.saveCurrentDesign` to delegate to the helper — Workspace behavior is unchanged byte-for-byte (same id shape, same `tc_design_snapshots/<id>` sidecar, same source/folder defaults, same quota fallback). - Editor `handleSave` reuses the existing `pathsToStitchObjects` / `pathsToThreadStops` converters that already feed the ExportDialog — single source of truth for what gets persisted. - Save button is disabled when the design has no visible paths. Verification: 622/622 tests pass, lint+typecheck clean. Added 9 new tests (4 for the helper, 5 for the Editor Save flow including filename round-trip and sessionStorage-snapshot-intact-after-save).
Mark closed this issue 2026-10-03 06:54:55 +00:00
Sign in to join this conversation.
No description provided.