fix: save button now fully persists canvas to DB
Root cause: handleAddNode/handleEdgeConfirm only updated Zustand store, never creating records in the DB. canvasApi.save() only updated positions of existing nodes, so nothing survived a page refresh. Fix: save now sends the full canvas state (all nodes + edges + data) and the backend does a full sync — upsert incoming, delete anything removed. This means Save is the single source of truth: no need to call individual create/update/delete APIs for every drag or edit.
This commit is contained in:
+29
-5
@@ -36,15 +36,39 @@ export default function App() {
|
||||
// Declare handleSave before the Ctrl+S effect so it is in scope
|
||||
const handleSave = useCallback(async () => {
|
||||
try {
|
||||
const nodePositions = nodes.map((n) => ({ id: n.id, x: n.position.x, y: n.position.y }))
|
||||
await canvasApi.save({ node_positions: nodePositions, viewport: {} })
|
||||
const nodesToSave = nodes.map((n) => ({
|
||||
id: n.id,
|
||||
type: n.data.type,
|
||||
label: n.data.label,
|
||||
hostname: n.data.hostname ?? null,
|
||||
ip: n.data.ip ?? null,
|
||||
mac: n.data.mac ?? null,
|
||||
os: n.data.os ?? null,
|
||||
status: n.data.status,
|
||||
check_method: n.data.check_method ?? null,
|
||||
check_target: n.data.check_target ?? null,
|
||||
services: n.data.services ?? [],
|
||||
notes: n.data.notes ?? null,
|
||||
parent_id: n.data.parent_id ?? null,
|
||||
pos_x: n.position.x,
|
||||
pos_y: n.position.y,
|
||||
}))
|
||||
const edgesToSave = edges.map((e) => ({
|
||||
id: e.id,
|
||||
source: e.source,
|
||||
target: e.target,
|
||||
type: e.data?.type ?? 'ethernet',
|
||||
label: e.data?.label ?? null,
|
||||
vlan_id: e.data?.vlan_id ?? null,
|
||||
speed: e.data?.speed ?? null,
|
||||
}))
|
||||
await canvasApi.save({ nodes: nodesToSave, edges: edgesToSave, viewport: {} })
|
||||
markSaved()
|
||||
toast.success('Canvas saved')
|
||||
} catch {
|
||||
markSaved()
|
||||
toast.success('Canvas saved (local)')
|
||||
toast.error('Save failed')
|
||||
}
|
||||
}, [nodes, markSaved])
|
||||
}, [nodes, edges, markSaved])
|
||||
|
||||
// Keep a ref so the keydown handler always calls the latest version
|
||||
const handleSaveRef = useRef(handleSave)
|
||||
|
||||
@@ -26,8 +26,11 @@ export const authApi = {
|
||||
|
||||
export const canvasApi = {
|
||||
load: () => api.get('/canvas'),
|
||||
save: (payload: { node_positions: { id: string; x: number; y: number }[]; viewport: object }) =>
|
||||
api.post('/canvas/save', payload),
|
||||
save: (payload: {
|
||||
nodes: object[]
|
||||
edges: object[]
|
||||
viewport: object
|
||||
}) => api.post('/canvas/save', payload),
|
||||
}
|
||||
|
||||
export const nodesApi = {
|
||||
|
||||
Reference in New Issue
Block a user