Add distributed settings and workspace import/export (M5)

This commit is contained in:
2026-06-07 15:51:00 +03:00
parent 80bedd2a8d
commit 548aa199d9
38 changed files with 3150 additions and 101 deletions
+11 -2
View File
@@ -179,8 +179,13 @@ Each cohesive feature owns a store holding its durable domain state.
- **`useSnippetStore`** — the snippet library: `snippets`, `activeSnippetId`, the
working `draftSpec`, and its actions.
- **`useDatasetStore`** — loaded datasets, the active dataset, inferred fields.
- **`useSettingsStore`** — user preferences (editor options, render debounce,
date format, theme); mirrors what gets persisted to `localStorage`.
- **`useUserSettingsStore`** — the **managed** user preferences applied _live_ as
`saved` (editor options, render debounce, date format). Its per-cluster setters
are called by the per-pane settings popovers; the editor/preview/library read
`saved.*`. There is **no draft/Apply** — settings are distributed and commit on
change (spec §07). **UI theme and preview fit mode are NOT here** — they're
cross-cutting and live in `useAppStore` (header toggle, Fit control); all three
persist to the one `astrolabe:settings` record via slice writers (arch 02 §5).
### Global overlay stores (imperative trigger)
@@ -189,6 +194,10 @@ ephemeral request state, not durable data:
- **`useConfirmStore`** — the blocking confirm dialog (the `window.confirm` replacement).
- **`useNotificationStore`** — non-blocking toasts (failed saves, etc.).
- **`useSettingsPopoverStore`** — which per-pane settings disclosure is open (one
at a time); its imperative `openSettingsPopover(id)` lets the Cmd/Ctrl+, shortcut
open the editor cluster. The disclosure widget contract (gear + non-modal popover,
not an ARIA menu; Esc/focus rules) is [10 · Interaction & Feedback](10-interaction-and-feedback.md) §5.
Each pairs its store with a thin **imperative trigger** exported alongside the hook —
`confirm(opts): Promise<boolean>` and `notify(opts): string` — so orchestration/services can