Add formboard harness layout designer
Separate read-only canvas for physically laying out wire harnesses.
Syncs connectors from the main diagram (one-way), no changes flow back.
Backend:
- FormboardLayout, FormboardNode, FormboardSegment models
- /api/formboard/ router: get/create layout, sync connectors from diagram,
full CRUD for nodes and segments
Frontend (formboard.js):
- Konva canvas: drag nodes, click-to-connect segments, zoom/pan
- Node types: Connector (blue rect, synced from diagram), Branch (green
circle, manual), Splice/joint (orange diamond, manual)
- Segments scale thickness by wire count; fitting overlays for open,
split loom, conduit, heat shrink, tape wrap
- Right-click context menu for delete on nodes/segments
App integration:
- "⊞ Formboard" tab in view-tab-bar (distinct color, independent of views)
- Sub-toolbar: Select / Branch / Splice / Connect / Sync / Fit / Delete
- Right panel swaps to formboard props when active:
- Node: label, notes, linked device info
- Segment: fitting type, fitting color, label, length, wire checklist
(checkboxes for every wire in the main diagram)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -60,6 +60,16 @@ const api = {
|
||||
jsonUrl: (id) => `${API_BASE}/export/${id}/json`,
|
||||
formboardUrl: (id) => `${API_BASE}/export/${id}/formboard`,
|
||||
},
|
||||
formboard: {
|
||||
get: (diagramId) => apiFetch(`/formboard/${diagramId}`),
|
||||
sync: (diagramId) => apiFetch(`/formboard/${diagramId}/sync`, { method: "POST" }),
|
||||
createNode: (diagramId, data) => apiFetch(`/formboard/${diagramId}/nodes`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
updateNode: (nodeId, data) => apiFetch(`/formboard/nodes/${nodeId}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
deleteNode: (nodeId) => apiFetch(`/formboard/nodes/${nodeId}`, { method: "DELETE" }),
|
||||
createSegment: (diagramId, data) => apiFetch(`/formboard/${diagramId}/segments`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
updateSegment: (segId, data) => apiFetch(`/formboard/segments/${segId}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }),
|
||||
deleteSegment: (segId) => apiFetch(`/formboard/segments/${segId}`, { method: "DELETE" }),
|
||||
},
|
||||
git: {
|
||||
status: () => apiFetch("/git/status"),
|
||||
log: (diagram_id) => apiFetch(diagram_id != null ? `/git/log?diagram_id=${diagram_id}` : "/git/log"),
|
||||
|
||||
Reference in New Issue
Block a user