docs: mark Phase 1 done; sync architecture, modernize, readme
- ROADMAP: all Phase 1 boxes checked, done-notes added - MODERNIZE: serde item marked APPLIED (persistence uses the derives) - ARCHITECTURE: persist module + modal in the component tree, gaps list updated (persistence no longer a gap) - README: header buttons + autosave in 'What works today', tests section describes both specs, playwright command pins the chromium project
This commit is contained in:
parent
cc11700621
commit
9c4d95220d
@ -99,9 +99,10 @@ JSON as-is.
|
|||||||
|
|
||||||
## Component tree
|
## Component tree
|
||||||
|
|
||||||
```
|
|
||||||
App
|
App
|
||||||
├─ Header name, image, date steppers, session steppers, Save/Load/Clear (dead)
|
├─ Header name, image, date steppers, session steppers,
|
||||||
|
│ Save (download)/Load (file import)/Clear (wipe)
|
||||||
|
├─ Modal overlay dialog: confirm (action) or error (close)
|
||||||
├─ Sidebar
|
├─ Sidebar
|
||||||
│ ├─ Image portrait
|
│ ├─ Image portrait
|
||||||
│ ├─ Names first / alias «» / last
|
│ ├─ Names first / alias «» / last
|
||||||
@ -125,6 +126,13 @@ closures by index; "move" transfers a row between the personal and common
|
|||||||
inventories, "remove" deletes it. The "…" (details) button and the search
|
inventories, "remove" deletes it. The "…" (details) button and the search
|
||||||
"+" button are unwired.
|
"+" button are unwired.
|
||||||
|
|
||||||
|
Persistence lives in `state::persist`: on hydration a deferred timer loads
|
||||||
|
the saved dashboard from localStorage (SSR markup stays authoritative),
|
||||||
|
then a debounced (500 ms) effect writes on any store change via
|
||||||
|
`store.track()`. `parse_dashboard` version-checks the JSON against
|
||||||
|
`Settings::VERSION` (the migration hook). `ModalState` holds title/message/
|
||||||
|
action as signals; the confirm button reads the action at click time.
|
||||||
|
|
||||||
`Numput` is the shared numeric input: `+n`/`-n` adjust relative to the
|
`Numput` is the shared numeric input: `+n`/`-n` adjust relative to the
|
||||||
current value, a plain number sets absolutely, invalid input is reverted,
|
current value, a plain number sets absolutely, invalid input is reverted,
|
||||||
and the value renders with thousands separators. `NumputChange` is the same
|
and the value renders with thousands separators. `NumputChange` is the same
|
||||||
@ -148,12 +156,11 @@ currently mounted on any page.
|
|||||||
|
|
||||||
## Current gaps
|
## Current gaps
|
||||||
|
|
||||||
- No persistence; state is recreated from `mock()` each load
|
|
||||||
- `Character` and `Wiki` pages render placeholders
|
|
||||||
- Quests, notes, contacts: models and mock data only
|
- Quests, notes, contacts: models and mock data only
|
||||||
|
- `Character` and `Wiki` pages render placeholders
|
||||||
- Prepared spells list is empty; `Spell` is a name-only stub; attunements
|
- Prepared spells list is empty; `Spell` is a name-only stub; attunements
|
||||||
have no UI; `Settings` is empty
|
have no UI; `Settings` has only `version`
|
||||||
- Save/Load/Clear buttons and the item "+"/"…" buttons are dead
|
- The item "+"/"…" buttons are dead
|
||||||
- `foundry.json` was loaded twice (fixed); ~3.9 MB of JSON is bundled
|
- `foundry.json` was loaded twice (fixed); ~3.9 MB of JSON is bundled
|
||||||
into the WASM and parsed on startup
|
into the WASM and parsed on startup
|
||||||
- Several unused dependencies (see `MODERNIZE.md`); kept for now by
|
- Several unused dependencies (see `MODERNIZE.md`); kept for now by
|
||||||
|
|||||||
@ -71,9 +71,11 @@ under consideration.
|
|||||||
`usize`. `Numput` keeps its generics.
|
`usize`. `Numput` keeps its generics.
|
||||||
|
|
||||||
4. **`serde` (direct) → remove now, re-add in ROADMAP phase 1.**
|
4. **`serde` (direct) → remove now, re-add in ROADMAP phase 1.**
|
||||||
No derives exist today; `serde_json::Value` works without naming `serde`
|
No derives existed at the time; `serde_json::Value` works without naming
|
||||||
in `Cargo.toml`. Phase 1 (persistence) re-adds
|
`serde` in `Cargo.toml`. Phase 1 (persistence) re-added
|
||||||
`serde = { version = "1", features = ["derive"] }`.
|
`serde = { version = "1", features = ["derive"] }`.
|
||||||
|
**APPLIED 2026-08-16:** persistence is in; `serde` is used by every entity
|
||||||
|
derive — keep it.
|
||||||
|
|
||||||
Result: dropping the under-consideration items takes `[dependencies]` from
|
Result: dropping the under-consideration items takes `[dependencies]` from
|
||||||
27 entries to about 18. If the five kept deps are dropped later too, it goes
|
27 entries to about 18. If the five kept deps are dropped later too, it goes
|
||||||
|
|||||||
16
README.md
16
README.md
@ -5,7 +5,9 @@ game. The UI is in Russian.
|
|||||||
|
|
||||||
## What works today
|
## What works today
|
||||||
|
|
||||||
- Campaign header: name, in-game date steppers, session counter
|
- Campaign header: name, in-game date steppers, session counter, and
|
||||||
|
Save / Load / Clear: download `dashboard.json`, import a file back,
|
||||||
|
wipe to a blank campaign
|
||||||
- Character sidebar: portrait, names, class, level, XP, hit points with
|
- Character sidebar: portrait, names, class, level, XP, hit points with
|
||||||
temp HP bar, hit dice, death saves, spell slots
|
temp HP bar, hit dice, death saves, spell slots
|
||||||
- Inventories page (`/inv`): personal and party-common inventories,
|
- Inventories page (`/inv`): personal and party-common inventories,
|
||||||
@ -14,8 +16,9 @@ game. The UI is in Russian.
|
|||||||
- Bundled 5e.tools item data (~5k items) with fuzzy search components
|
- Bundled 5e.tools item data (~5k items) with fuzzy search components
|
||||||
(search is not mounted on a page yet)
|
(search is not mounted on a page yet)
|
||||||
|
|
||||||
State is mock data: nothing is persisted, and several buttons and pages are
|
State autosaves to localStorage (debounced) and survives reloads; export/
|
||||||
stubs. The phased plan to fix that is in [ROADMAP.md](./ROADMAP.md).
|
import round-trips through a JSON file. The phased plan is in
|
||||||
|
[ROADMAP.md](./ROADMAP.md).
|
||||||
|
|
||||||
## Tech stack
|
## Tech stack
|
||||||
|
|
||||||
@ -48,13 +51,14 @@ cargo check --target wasm32-unknown-unknown --no-default-features --features hyd
|
|||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
End-to-end smoke tests live in `end2end/` (Playwright). With the dev server
|
End-to-end tests live in `end2end/` (Playwright): a smoke spec and a
|
||||||
running on port 3000:
|
persistence spec (reload keeps state; export/import round trip). With the
|
||||||
|
dev server running:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd end2end
|
cd end2end
|
||||||
npm install
|
npm install
|
||||||
npx playwright test
|
npx playwright test --project=chromium
|
||||||
```
|
```
|
||||||
|
|
||||||
or let cargo-leptos manage the server: `cargo leptos end2end`.
|
or let cargo-leptos manage the server: `cargo leptos end2end`.
|
||||||
|
|||||||
28
ROADMAP.md
28
ROADMAP.md
@ -72,24 +72,32 @@ Cheap, unblocks the rest. Can happen any time; do it first.
|
|||||||
|
|
||||||
The foundation. Every later phase depends on it.
|
The foundation. Every later phase depends on it.
|
||||||
|
|
||||||
- [ ] derive `serde::Serialize` / `Deserialize` on all entities in `src/entities/mod.rs`
|
- [x] derive `serde::Serialize` / `Deserialize` on all entities in `src/entities/mod.rs`
|
||||||
(Dashboard, PlayerData, Balance, Inventory, InventoryEntry, InventoryItem,
|
(Dashboard, PlayerData, Balance, Inventory, InventoryEntry, InventoryItem,
|
||||||
QuestBook, Quest, NoteBook, Note, ContactBook, Contact, SpellSlots, Attunements,
|
QuestBook, Quest, NoteBook, Note, ContactBook, Contact, SpellSlots, Attunements,
|
||||||
PreparedSpells, Spell, HitDice, DeathSaveThrows, Name, Settings; enums:
|
PreparedSpells, Spell, HitDice, DeathSaveThrows, Name, Settings; enums:
|
||||||
InventoryKind, ContactStatus, PreparedSpell)
|
InventoryKind, ContactStatus, PreparedSpell)
|
||||||
- [ ] verify `Store` derive and `serde` derive coexist on the same structs (prototype first)
|
- [x] verify `Store` derive and `serde` derive coexist on the same structs (prototype first)
|
||||||
- [ ] add a `version` field to `Settings`; add a migration hook for future format changes
|
- [x] add a `version` field to `Settings`; add a migration hook for future format changes
|
||||||
- [ ] serialize Dashboard to JSON; save to localStorage via `web_sys::Storage`
|
- [x] serialize Dashboard to JSON; save to localStorage via `web_sys::Storage`
|
||||||
(feature-gate to `hydrate`/`csr`; SSR renders mock/empty)
|
(feature-gate to `hydrate`/`csr`; SSR renders mock/empty)
|
||||||
- [ ] auto-save on change — debounced effect over the `Store` — plus manual Save button
|
- [x] auto-save on change — debounced effect over the `Store` — plus manual Save button
|
||||||
- [ ] Load button: restore from localStorage with an overwrite confirm
|
- [x] Load button: restore from localStorage with an overwrite confirm
|
||||||
- [ ] Clear button: wipe localStorage with a confirm
|
- [x] Clear button: wipe localStorage with a confirm
|
||||||
- [ ] export: download `dashboard.json` as a blob
|
- [x] export: download `dashboard.json` as a blob
|
||||||
- [ ] import: file input → parse → validate version → replace state
|
- [x] import: file input → parse → validate version → replace state
|
||||||
- [ ] on startup, hydrate from localStorage; keep `mock()` as the fallback / "New dashboard"
|
- [x] on startup, hydrate from localStorage; keep `mock()` as the fallback / "New dashboard"
|
||||||
- **Acceptance:** close the tab, reopen — state is intact. Export → import into a
|
- **Acceptance:** close the tab, reopen — state is intact. Export → import into a
|
||||||
fresh browser — identical state.
|
fresh browser — identical state.
|
||||||
|
|
||||||
|
**Done (2026-08-16):** implementation in `src/state/persist.rs` + header buttons +
|
||||||
|
`components/modal.rs`; e2e-verified in chromium (reload persistence and
|
||||||
|
export/import round trip). Notes:
|
||||||
|
- Save = download; Load = file import; Clear = wipe (merged per user decision).
|
||||||
|
- Clear writes the blank dashboard back to storage; mock stays the first-visit fallback.
|
||||||
|
- Version check is the migration hook: `parse_dashboard` returns
|
||||||
|
`ImportError::{Parse, NewerVersion, OldVersion}` (RU messages).
|
||||||
|
|
||||||
## Phase 2 — Character page (M, ~1-2 days)
|
## Phase 2 — Character page (M, ~1-2 days)
|
||||||
|
|
||||||
`/` currently renders the literal string "character".
|
`/` currently renders the literal string "character".
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user