docs: rewrite README and reconcile plan checklist with implemented state

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ilya Ashikhmin 2026-07-02 23:47:34 +02:00
parent 94026754b7
commit 90f59f546a
2 changed files with 153 additions and 79 deletions

113
README.md
View File

@ -1,32 +1,101 @@
# React + TypeScript + Vite # Pipeline Network Diagram Editor
This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules. A desktop editor for designing pipeline networks (water, gas, power, steam …),
built with **Tauri v2 + React + TypeScript + Vite** and the **JointJS**
(`@joint/core`, MPL-2.0) diagramming engine.
Currently, two official plugins are available: ## Features
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) **Canvas & modelling**
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) - Grouped, searchable **node palette** of vector components (source, sink, pump,
valve, tank, junction, filter, meter, heat-exchanger, compressor). Drag onto
the canvas or double-click to add.
- Nodes are defined by an **SVG icon set** plus a **port configuration**
(medium + direction + side).
- Clicking a node **reveals its ports**; drag from a port to draw a connector.
Connections are **validated by relation** — mediums must be compatible
(e.g. water↔water, water↔hot-water) and directions complementary (out→in).
- **Grid (Manhattan) routing** with a configurable **arc-on-intersection**
connector (JointJS `jumpover`), plus orthogonal / straight routers.
- **Edge styles** with source/target markers: arrow, open-arrow, circle,
diamond, bar, and solid/dashed/dotted lines.
- Multiple **color schemes** (default, dark, blueprint, high-contrast) keyed by
medium.
## React Compiler **Properties**
- Right panel shows **grouped, typed properties** for the selected node/edge:
Identity, Geometry, Presentation, Physics.
- Editors for every type: `string, int, float, enum, color, catalogueItem,
catalogueItems, list`. Values are validated/coerced and written live to the
canvas. **Catalogues** (pipes, pumps, materials) back the catalogue types.
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). **Editing UX**
- Undo/redo, delete, copy/cut/paste, duplicate, select-all.
- Keyboard shortcuts (Del, Ctrl+Z/Y, Ctrl+C/X/V/D/A, Esc, Ctrl+±).
- Zoom (buttons + Ctrl-wheel toward cursor), blank-drag pan, fit-to-content,
reset. Snap-to-grid.
- Save / Open (`.json`) and export **SVG / PNG** — native file dialogs under
Tauri, browser download/upload as a fallback.
## Expanding the Oxlint configuration **Mock calculation**
- A deterministic **flow-distribution solver** computes per-edge flow from node
supplies/demands, respecting conservation and splitting at junctions by
downstream demand.
- **Run simulation** animates flow along each edge — dash direction follows the
sign, speed and width follow the volume — and the status bar reports total
supply/demand, balance and warnings (under-supplied / unbalanced).
If you are developing a production application, we recommend enabling type-aware lint rules by installing `oxlint-tsgolint` and editing `.oxlintrc.json`: ## Getting started
```json ```bash
{ npm install
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "typescript", "oxc"], # Frontend dev server (browser) — http://localhost:1420
"options": { npm run dev
"typeAware": true
}, # Full desktop app (Tauri)
"rules": { npm run tauri dev
"react/rules-of-hooks": "error",
"react/only-export-components": ["warn", { "allowConstantExport": true }]
}
}
``` ```
See the [Oxlint rules documentation](https://oxc.rs/docs/guide/usage/linter/rules) for the full list of rules and categories. > If port 1420 is already in use, stop the other process or change `server.port`
> in `vite.config.ts` and `build.devUrl` in `src-tauri/tauri.conf.json`.
## Quality gates
```bash
npm run test:run # 47 unit + integration + component tests (Vitest)
npm run test:coverage
npm run typecheck # tsc --noEmit
npm run lint # oxlint
npm run build # tsc -b && vite build
```
## Architecture
```
src/
model/ pure domain: mediums/relations, color schemes, property schema,
catalogues, node types + SVG icon set, edge styles (tested)
calc/ mock flow-distribution solver (tested)
canvas/ graphOps (paper-independent graph logic, tested) +
CanvasController (paper, selection, tools, undo, animation) + shapes
store/ Zustand editor store (config, selection, catalogues)
ui/ Toolbar, NodePalette, PropertiesPanel, ConfigPanel, StatusBar,
CanvasView, property-type editors
io/ document save/open, SVG/PNG export (Tauri + browser fallback)
src-tauri/ Tauri v2 Rust shell
docs/plan/ implementation plan & milestone checklist
```
The core logic is decoupled from the JointJS `Paper` (which needs a real DOM) so
it can be unit-tested in jsdom: `model/`, `calc/` and `canvas/graphOps.ts` are
all covered directly.
## Why JointJS
Chosen over React Flow / Rete / GoJS because it uniquely covers every hard
requirement out of the box: framework-agnostic custom **SVG node markup**, a
first-class **port model** with `validateConnection`, built-in **grid routers**,
the **`jumpover` arc connector** for the arc-on-intersection requirement, and
rich **link markers** for arrow/circle/diamond edge ends. See
[`docs/plan/README.md`](docs/plan/README.md) for the full rationale and plan.

View File

@ -44,86 +44,91 @@ src-tauri/ Tauri v2 Rust shell (file dialogs, fs plugin)
- [x] Install deps (@joint/core, zustand, vitest, testing-library, tauri plugins) - [x] Install deps (@joint/core, zustand, vitest, testing-library, tauri plugins)
- [x] Configure Vite (port 1420) + Vitest (jsdom, coverage) - [x] Configure Vite (port 1420) + Vitest (jsdom, coverage)
- [x] Write this plan - [x] Write this plan
- [ ] Base app shell layout (palette | canvas | properties, top toolbar) - [x] Base app shell layout (palette | canvas | properties, top toolbar)
- [ ] CI-style scripts: `test`, `test:run`, `lint`, `typecheck` - [x] CI-style scripts: `test`, `test:run`, `lint`, `typecheck`
### M1 — Domain model (pure, tested) ### M1 — Domain model (pure, tested)
- [ ] Port types & **relation registry** (which port types may connect) - [x] Port types & **relation registry** (which port types may connect)
- [ ] Connection validation function (`canConnect(source, target, relations)`) - [x] Connection validation function (`canConnect(source, target, relations)`)
- [ ] **Color schemes** mapping port/relation types → colors (multiple presets) - [x] **Color schemes** mapping port/relation types → colors (multiple presets)
- [ ] Property schema types: `string,int,float,enum,catalogueItem,catalogueItems,color,list` - [x] Property schema types: `string,int,float,enum,catalogueItem,catalogueItems,color,list`
- [ ] Property groups (presentation / identity / physics) - [x] Property groups (presentation / identity / physics)
- [ ] Catalogue model (named collections of catalogue items) - [x] Catalogue model (named collections of catalogue items)
- [ ] Node type definitions with SVG markup + port layout (pump, valve, tank, - [x] Node type definitions with SVG markup + port layout (pump, valve, tank,
junction, source, sink, …) junction, source, sink, …)
- [ ] Edge style definitions (line styles + source/target markers) - [x] Edge style definitions (line styles + source/target markers)
- [ ] Default property values & validation/coercion per type - [x] Default property values & validation/coercion per type
### M2 — Canvas engine (JointJS) ### M2 — Canvas engine (JointJS)
- [ ] Paper + graph init, background grid, snap-to-grid - [x] Paper + graph init, background grid, snap-to-grid
- [ ] Custom `PipelineNode` element (renders node-type SVG + ports) - [x] Custom `PipelineNode` element (renders node-type SVG + ports)
- [ ] Custom `PipelineLink` with configurable markers & line styles - [x] Custom `PipelineLink` with configurable markers & line styles
- [ ] Port rendering; show ports only when node focused/hovered - [x] Port rendering; show ports only when node focused/hovered
- [ ] Draw edge from a port; live validation highlight (valid/invalid) - [x] Draw edge from a port; live validation highlight (valid/invalid)
- [ ] Grid routing (`manhattan`) + **config toggle for `jumpover` arc connector** - [x] Grid routing (`manhattan`) + **config toggle for `jumpover` arc connector**
- [ ] Selection (single, multi, rubber-band) & focus highlighting - [x] Selection (single + multi via shift-click) & focus highlighting
- [ ] Element tools: remove, boundary, resize; link tools: vertices, arrowheads, remove - [ ] Rubber-band marquee selection (not yet implemented)
- [x] Element tools: remove, boundary; link tools: vertices, segments, arrowheads, remove
(element resize is done via the Geometry properties, not a drag handle)
### M3 — Node palette ### M3 — Node palette
- [ ] Grouped, collapsible stencil of node types (vector previews) - [x] Grouped, collapsible stencil of node types (vector previews)
- [ ] Search/filter - [x] Search/filter
- [ ] Drag-and-drop node from palette to canvas (drop at cursor, snap) - [x] Drag-and-drop node from palette to canvas (drop at cursor, snap)
### M4 — Properties panel ### M4 — Properties panel
- [ ] Reflects current selection (node or edge), empty state otherwise - [x] Reflects current selection (node or edge), empty state otherwise
- [ ] Grouped property editors, one per property type - [x] Grouped property editors, one per property type
- [ ] Editors: string, int, float, enum(select), color(picker), - [x] Editors: string, int, float, enum(select), color(picker),
catalogueItem(select), catalogueItems(multi), list(add/remove rows) catalogueItem(select), catalogueItems(multi), list(add/remove rows)
- [ ] Two-way binding: edits write back to element & update canvas presentation - [x] Two-way binding: edits write back to element & update canvas presentation
- [ ] Geometry props (position/size/rotation) & title reflected live - [x] Geometry props (position/size/rotation) & title reflected live
### M5 — Editing UX (the "typical scenarios" often missed) ### M5 — Editing UX (the "typical scenarios" often missed)
- [ ] Undo / redo (command stack) - [x] Undo / redo (command stack)
- [ ] Delete, copy / cut / paste, duplicate - [x] Delete, copy / cut / paste, duplicate
- [ ] Keyboard shortcuts (Del, Ctrl+Z/Y, Ctrl+C/V/X/D, Ctrl+A, Esc) - [x] Keyboard shortcuts (Del, Ctrl+Z/Y, Ctrl+C/V/X/D, Ctrl+A, Esc)
- [ ] Zoom (buttons + ctrl-wheel), pan (space/mmb drag), fit-to-content, reset - [x] Zoom (buttons + ctrl-wheel), pan (blank-area drag), fit-to-content, reset
- [ ] Grid + snap toggles, background config - [x] Grid + snap toggles, background config
- [ ] Context menu on nodes/edges/canvas - [ ] Context menu on nodes/edges/canvas (not yet implemented — actions available
- [ ] Rename via inline / properties title via toolbar, tools & keyboard shortcuts)
- [x] Rename via properties title (reflected live on canvas)
### M6 — Configuration ### M6 — Configuration
- [ ] Config panel: color scheme, arc-on-intersection, grid size/visibility, - [x] Config panel: color scheme, arc-on-intersection, grid size/visibility,
snap, router type, animation speed snap, router type, animation speed
- [ ] Persist config; live-apply to paper & links - [x] Persist config; live-apply to paper & links
### M7 — Persistence & export ### M7 — Persistence & export
- [ ] Serialize document (graph + metadata + config) to JSON - [x] Serialize document (graph + metadata + config) to JSON
- [ ] Save / Open via Tauri dialog + fs (graceful fallback to download/localStorage in browser) - [x] Save / Open via Tauri dialog + fs (graceful fallback to browser download / file-picker)
- [ ] New document - [x] New document
- [ ] Export canvas to SVG and PNG - [x] Export canvas to SVG and PNG
### M8 — Mock calculation & flow animation ### M8 — Mock calculation & flow animation
- [ ] Build network graph from nodes/edges (respect port direction) - [x] Build network graph from nodes/edges (respect port direction)
- [ ] Assign supplies/demands from node physics props - [x] Assign supplies/demands from node physics props
- [ ] **Flow-distribution solver** (conservation at junctions, proportional split) - [x] **Flow-distribution solver** (conservation at junctions, proportional split)
- [ ] Map per-edge flow → direction (sign) + volume (magnitude) - [x] Map per-edge flow → direction (sign) + volume (magnitude)
- [ ] Animate flow along edges (dash animation; speed ∝ volume, dir ∝ sign) - [x] Animate flow along edges (dash animation; speed ∝ volume, dir ∝ sign)
- [ ] Color/width edges by flow volume; run / stop / reset controls - [x] Color/width edges by flow volume; run / stop / reset controls
- [ ] Report unbalanced nodes / disconnected components - [x] Report unbalanced nodes / disconnected components
### M9 — Testing ### M9 — Testing
- [ ] Unit: relation validation & color schemes - [x] Unit: relation validation & color schemes
- [ ] Unit: property schema coercion/validation & catalogue resolution - [x] Unit: property schema coercion/validation & catalogue resolution
- [ ] Unit: flow-distribution solver (linear, split, merge, cycle, unbalanced) - [x] Unit: flow-distribution solver (linear, split, merge, cycle, unbalanced)
- [ ] Unit: document serialize/deserialize round-trip - [x] Unit: document serialize/deserialize round-trip
- [ ] Component: palette renders groups; properties panel renders & edits - [x] Component: palette renders/filters groups; config panel drives store;
- [ ] Component: store actions (add node, connect, select, undo/redo) properties panel empty-state + grouped/typed fields for a selection
- [ ] `npm run test:run` green; typecheck & lint clean - [x] Integration (graphOps): add node, connect w/ validation, build network,
annotate flow, JSON round-trip (port medium survives)
- [x] `npm run test:run` green (47 tests); typecheck & lint clean
### M10 — Polish & docs ### M10 — Polish & docs
- [ ] Seed demo network on first launch - [x] Seed demo network on first launch
- [ ] README with run/test instructions & feature list - [x] README with run/test instructions & feature list
- [ ] App icon / window sizing - [x] App icon / window sizing
--- ---