Commit Graph

13 Commits

Author SHA1 Message Date
Pouzor 485d2f2b04 feat: configurable edge line style + width per type and per edge
Edge render (solid/dashed/dotted) and stroke width were hardcoded per
edge type. Expose both as user settings.

- Custom Style modal (Edges): line-style buttons, 1-4x width slider,
  live preview; left-list swatch renders the actual line.
- Per-edge EdgeModal: same controls; line style follows the type preset
  live until overridden.
- Renderer applies line_style/width_mult over BASE_STYLES (width scales
  markers + animation overlays); unset keeps the type default look.
- Persist line_style/width_mult through serializer, canvas save, and the
  edges API (new nullable columns, idempotent migration).

ha-relevant: yes
2026-07-05 14:11:01 +02:00
Pouzor c95d104245 feat: selectable marker shapes per edge endpoint
Replace the on/off arrowhead toggle with a per-end shape picker. Each end
(start/end) independently selects: none, arrow, arrow-open, circle, diamond,
or square. Markers still recolor live from the resolved stroke color.

Frontend:
- MarkerShape type + edgeMarkers util (normalizeMarker, MARKER_GEOMETRY);
  legacy boolean coerces to 'arrow' on read.
- Per-shape <marker> inner geometry; symmetric shapes use fixed orient.
- MarkerShapePicker reused in EdgeModal and CustomStyleModal.
- Serializer normalizes to shape strings.

Backend:
- Edge marker columns Boolean -> String (default 'none'); TEXT migration.
- normalize_marker() + validators coerce legacy bool / unknown values.

ha-relevant: yes
2026-07-05 11:30:49 +02:00
Pouzor 1cf525844b feat: arrowhead endpoints for edges + fix parallel edges not rendering
Add optional filled-triangle arrowheads at either end of an edge,
independently toggleable per edge (EdgeModal) and as per-edge-type
defaults (CustomStyleModal). Arrowheads are custom inline <marker> defs
filled with the live stroke colour so they recolour reactively with
custom_color / vlan / selected state. Persisted frontend (serializer)
and backend (edge columns + schemas + runtime migration).

Also fix two dedupe layers that silently dropped legitimate parallel
links between the same two devices:
- store: React Flow addEdge() connectionExists dropped a second edge
  with matching source+target when handles were null/equal. Build the
  edge with a unique id and append directly.
- render: rewireEdgesForCollapse deduped ALL edges by src->tgt key even
  when nothing was collapsed, filtering real parallel edges out of the
  visible set. Restrict the anti-mesh dedupe to rewired collapse stubs.

Tests: marker render, per-edge/per-type UI, store apply, serializer
round-trip, backend edge/canvas persistence, parallel-edge regressions.

ha-relevant: yes
2026-07-05 01:16:26 +02:00
Pouzor cbc2bc03c2 fix: attach MCP-created nodes/edges to a design (#225)
create_node/create_edge persisted rows with design_id=null when the
client omitted it (the MCP write tools), so they existed in the DB but
never rendered on the canvas until a container restart reconciled them.
Both routes now fall back to the first design, matching bulk-approve.

Also fix MCP resource reads (homelable://canvas, homelable://edges):
the framework passes a pydantic AnyUrl, not a str, which raised
"'AnyUrl' object has no attribute 'startswith'". Coerce to str.

EdgeResponse now exposes design_id for symmetry with NodeResponse.

ha-relevant: no
2026-06-28 14:00:59 +02:00
Pranjal Joshi 3a57d809a4 fix: compatibility with multi-design schema for scan/zigbee/liveview/CustomStyleModal
- liveview.py: replace hardcoded CanvasState PK lookup (get(1)) with
  design_id-aware query; filter nodes/edges by design_id
- scan.py: add design_id to bulk approve, single approve, and edge
  resolution Node/Edge constructors (fallback to first design)
- zigbee.py: add design_id to coordinator auto-approval Node constructor
- schemas/nodes.py: add design_id to NodeCreate and NodeResponse
- schemas/edges.py: add design_id to EdgeCreate
- CustomStyleModal.tsx: add 'electrical' to EDITABLE_EDGE_TYPES
2026-05-31 14:44:17 +05:30
Pouzor 94c6ac7fa7 fix: add type parameters to bare list annotations for mypy compliance 2026-04-09 14:23:13 +02:00
Pouzor 3afc8ed3d8 fix: persist edge waypoints in backend
Add waypoints JSON column to edges table, include it in all edge
schemas (EdgeBase, EdgeUpdate, canvas CanvasEdge) and add the
idempotent ALTER TABLE migration so existing databases are upgraded
on next startup.
2026-04-08 23:31:53 +02:00
Pouzor 32b60a201b fix: persist edge animation mode (None/Snake/Flow) end-to-end
- canvasStore.onConnect: include animated in edge data object (was silently dropped)
- Backend schemas: normalize animated bool/int to string ('none'/'snake'/'flow') via field_validator
- ORM model: change animated column from Boolean to String
- DB migration: convert existing 0/1 boolean rows to 'none'/'snake' strings
2026-03-29 14:41:18 +02:00
Pouzor 41cfccbd37 feat: add edge flow animation (dot traveling source→target)
- Add animated toggle per edge in EdgeModal (cyan switch, "Flow Animation")
- SVG-native <animate> element for reliable cross-browser dot animation
- Persist animated field: backend model, schemas (EdgeBase/EdgeUpdate/EdgeSave), DB migration
- Include animated in App.tsx edgesToSave serialization so it survives save/reload
- Add animated: bool to EdgeData TypeScript type
2026-03-12 10:23:18 +01:00
Pouzor f43a94a403 fix: persist sourceHandle/targetHandle so cluster edges survive reload 2026-03-08 11:32:38 +01:00
Pouzor 07d8c4e58b feat: per-link path style toggle (bezier / smooth step) 2026-03-07 14:46:55 +01:00
Pouzor 8437f5ef49 feat: customizable link color per edge
- Add custom_color field to EdgeData type, Edge DB model and all schemas
- HomelableEdge applies custom_color as stroke override (before selected highlight)
- EDGE_DEFAULT_COLORS extracted to utils/edgeColors.ts (react-refresh compliant)
- EdgeModal: color picker row showing effective color (custom or type default)
  with hex value, Reset button when custom color is active
- Auto-migration adds custom_color column to edges table
2026-03-07 14:42:34 +01:00
Pouzor 4310a5cc2d feat: Phase 1 scaffold — frontend canvas + backend skeleton
Frontend:
- Vite + React 18 + TypeScript + Tailwind v4 + Shadcn/ui
- React Flow v12 canvas with all 11 node types and 5 edge types
- Dark theme with project design system (cyan, green, orange, purple accents)
- Collapsible sidebar, toolbar, detail panel
- Zustand store for canvas state
- Demo data with 10 nodes and 10 edges

Backend:
- FastAPI + SQLAlchemy async + SQLite (Python 3.13)
- DB models: Node, Edge, CanvasState, PendingDevice, ScanRun
- REST API routes: auth, nodes, edges, canvas, scan, status (WebSocket)
- JWT auth + bcrypt via config.yml
- Pydantic v2 schemas

Infra:
- GitHub Actions quality + security workflows
- .gitignore, .env.example, verify-tooling.sh, security-check.sh
2026-03-06 23:14:34 +01:00