From 42b106c793bfd1045db22ffe1484c402826c8d9d Mon Sep 17 00:00:00 2001 From: yaroslav k Date: Sun, 16 Aug 2026 11:57:31 +0300 Subject: [PATCH] =?UTF-8?q?roadmap:=20add=20Phase=201.5=20=E2=80=94=20undo?= =?UTF-8?q?=20&=20redo=20(snapshot-based)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - effort S (~0.5-1 day): rides on Phase 1 machinery (serde snapshots, replace_state, the store.track() autosave trigger) — no component changes needed, page-agnostic - coalesced snapshots (one per ~1 s window), capped stacks, Ctrl+Z / Ctrl+Shift+Z with focus guard for text fields - sequencing note: lands before the edit-heavy Phases 2-7 so their edits are undoable from day one; nothing depends on it - Phase 8 e2e item: drop the persistence round trip (already covered by persistence.spec.ts), add undo shortcuts - ARCHITECTURE gaps list: note the missing undo/redo --- ARCHITECTURE.md | 2 ++ ROADMAP.md | 30 +++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 8b12a47..87fecc4 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -157,6 +157,8 @@ currently mounted on any page. ## Current gaps - Quests, notes, contacts: models and mock data only +- No undo/redo (planned as Phase 1.5; snapshot-based, rides on the + persist machinery) - `Character` and `Wiki` pages render placeholders - Prepared spells list is empty; `Spell` is a name-only stub; attunements have no UI; `Settings` has only `version` diff --git a/ROADMAP.md b/ROADMAP.md index e9aee6a..a496b9c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -98,6 +98,28 @@ export/import round trip). Notes: - Version check is the migration hook: `parse_dashboard` returns `ImportError::{Parse, NewerVersion, OldVersion}` (RU messages). +## Phase 1.5 — Undo & redo (S, ~0.5-1 day) + +Snapshot-based undo rides on the Phase 1 machinery: serialize → push → +`replace_state`. It is page-agnostic: the `store.track()` trigger already +fires on any mutation, so no component changes are needed and every later +phase's edits are undoable from day one. + +- [ ] `state::undo.rs` (hydrate-gated): undo/redo stacks of serialized + `Dashboard`, capped (e.g. 100); push coalesced on the store trigger + (one snapshot per ~1 s window → one undo step = one edit burst) +- [ ] a new edit after undo clears the redo stack; Clear and import push a + snapshot first, so they are undoable too +- [ ] `undo()` / `redo()` call `replace_state`; expose stack depths as + `RwSignal` for button disabled states +- [ ] header buttons: ↩ Отменить / Вернуть (disabled when empty) +- [ ] shortcuts: Ctrl+Z, Ctrl+Shift+Z (Ctrl+Y); ignore when focus is in an + input/textarea/select, so typing never triggers undo +- [ ] unit tests for stack semantics; e2e: edit → undo → redo; reload keeps + the undone state (undo writes through autosave) +- **Acceptance:** every edit since the last window is reversible with a + keystroke; undo survives a reload. + ## Phase 2 — Character page (M, ~1-2 days) `/` currently renders the literal string "character". @@ -167,8 +189,8 @@ New route `/contacts`. Model and mock data exist; zero UI. ## Phase 8 — Polish, tests, release (L, ~2-4 days) - [ ] responsive SCSS pass (sidebar and header on mobile widths) -- [ ] Playwright e2e: persistence round-trip, add item from search, quest CRUD, - notes filter +- Playwright e2e: add item from search, quest CRUD, notes filter, undo + shortcuts (persistence round trip is covered by `persistence.spec.ts`) - [ ] rewrite README: usage, dev workflow, deploy - [ ] release build via cargo-leptos; verify SSR + hydration; pick a deploy target - **Acceptance:** fresh clone → `cargo leptos build` → app runs; e2e green. @@ -179,7 +201,9 @@ New route `/contacts`. Model and mock data exist; zero UI. - Phase 1 before Phases 2-7: every new page must persist. Building pages first against mock data and persisting later costs a data-migration pass instead. -- Phases 2 and 3 can run in parallel after Phase 1 (different components). +- Phases 2 and 3 can run in parallel after Phase 1.5 (different components). +- Phase 1.5 (undo) is page-agnostic: it must land before the edit-heavy + phases so their edits are undoable; nothing in Phases 2-7 depends on it. - Phases 4-6 are independent of each other and share one CRUD-list pattern — build the pattern once (e.g. a generic list editor) and reuse it. - Phase 7 reuses the Phase 3 add-to-inventory path; keep that path shared.