From 8e711d9016a0cba7a250190fc0e9ee4b115b67ea Mon Sep 17 00:00:00 2001 From: Pouzor Date: Sun, 8 Mar 2026 11:48:02 +0100 Subject: [PATCH] fix: cluster edge type and label now persisted on connect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - canvasStore.onConnect was hardcoding type=ethernet and ignoring edgeData fields (type, label, color, etc.) - EdgeModal had no key, so useState was not reset between connections — initial prop ignored - Added key based on source/target/handles so modal re-mounts for each new connection --- frontend/src/App.tsx | 1 + .../src/stores/__tests__/canvasStore.test.ts | 13 ++++++++++++- frontend/src/stores/canvasStore.ts | 16 ++++++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a7ccaf2..f11d439 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -261,6 +261,7 @@ export default function App() { /> setPendingConnection(null)} onSubmit={handleEdgeConfirm} diff --git a/frontend/src/stores/__tests__/canvasStore.test.ts b/frontend/src/stores/__tests__/canvasStore.test.ts index 70b53a0..bb61bef 100644 --- a/frontend/src/stores/__tests__/canvasStore.test.ts +++ b/frontend/src/stores/__tests__/canvasStore.test.ts @@ -117,12 +117,23 @@ describe('canvasStore', () => { expect(hasUnsavedChanges).toBe(true) }) + it('onConnect preserves type and label from edge data', () => { + const conn = Object.assign({ source: 'n1', target: 'n2', sourceHandle: null, targetHandle: null }, { type: 'wifi', label: 'uplink' }) + useCanvasStore.getState().onConnect(conn) + const { edges } = useCanvasStore.getState() + expect(edges[0].type).toBe('wifi') + expect(edges[0].data?.type).toBe('wifi') + expect(edges[0].data?.label).toBe('uplink') + }) + it('onConnect preserves sourceHandle and targetHandle for cluster edges', () => { - useCanvasStore.getState().onConnect({ source: 'n1', target: 'n2', sourceHandle: 'cluster-right', targetHandle: 'cluster-left' }) + const conn = Object.assign({ source: 'n1', target: 'n2', sourceHandle: 'cluster-right', targetHandle: 'cluster-left' }, { type: 'cluster' }) + useCanvasStore.getState().onConnect(conn) const { edges } = useCanvasStore.getState() expect(edges).toHaveLength(1) expect(edges[0].sourceHandle).toBe('cluster-right') expect(edges[0].targetHandle).toBe('cluster-left') + expect(edges[0].type).toBe('cluster') }) it('addNode with parent_id sets parentId and extent', () => { diff --git a/frontend/src/stores/canvasStore.ts b/frontend/src/stores/canvasStore.ts index 61e229c..5a8288a 100644 --- a/frontend/src/stores/canvasStore.ts +++ b/frontend/src/stores/canvasStore.ts @@ -53,10 +53,18 @@ export const useCanvasStore = create((set) => ({ })), onConnect: (connection) => - set((state) => ({ - edges: addEdge({ ...connection, type: 'ethernet', data: { type: 'ethernet' } }, state.edges), - hasUnsavedChanges: true, - })), + set((state) => { + const extra = connection as Connection & Partial + const edgeType = extra.type ?? 'ethernet' + return { + edges: addEdge({ + ...connection, + type: edgeType, + data: { type: edgeType, label: extra.label, vlan_id: extra.vlan_id, custom_color: extra.custom_color, path_style: extra.path_style }, + }, state.edges), + hasUnsavedChanges: true, + } + }), setSelectedNode: (id) => set({ selectedNodeId: id }),