From 510004cd8f4c0d64984f7afa398e4ef177ba7e27 Mon Sep 17 00:00:00 2001 From: A0 Orchestrator Date: Fri, 3 Jul 2026 21:18:13 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20history/undo/redo=20=E2=80=94=20re-init?= =?UTF-8?q?=20after=20project=20load=20+=20sync=20to=20Yjs=20CRDT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 29d3fa4..0cc4ccc 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -238,18 +238,30 @@ const CADEditor: React.FC = ({ projectId, token, onNavigateBack if (snap) { restoreSnapshot(snap); syncHistory(); + // Sync restored state to Yjs CRDT to prevent collab overwrite + if (collab.status === 'connected') { + for (const el of snap.elements) collab.setElement(el); + for (const layer of snap.layers) collab.setLayer(layer); + for (const block of snap.blocks) collab.setBlock(block); + } setCommandHistory((prev) => [...prev, { prefix: '·', text: 'Rückgängig: letzte Aktion', type: 'info' }]); } - }, [restoreSnapshot, syncHistory]); + }, [restoreSnapshot, syncHistory, collab]); const handleRedo = useCallback(() => { const snap = historyManagerRef.current.redo(); if (snap) { restoreSnapshot(snap); syncHistory(); + // Sync restored state to Yjs CRDT to prevent collab overwrite + if (collab.status === 'connected') { + for (const el of snap.elements) collab.setElement(el); + for (const layer of snap.layers) collab.setLayer(layer); + for (const block of snap.blocks) collab.setBlock(block); + } setCommandHistory((prev) => [...prev, { prefix: '·', text: 'Wiederherstellen: letzte Aktion', type: 'info' }]); } - }, [restoreSnapshot, syncHistory]); + }, [restoreSnapshot, syncHistory, collab]); const pushHistorySnapshot = useCallback((label: string) => { historyManagerRef.current.pushSnapshot({ @@ -318,6 +330,15 @@ const CADEditor: React.FC = ({ projectId, token, onNavigateBack } setSavedStatus('gespeichert'); setDataLoaded(true); + // Re-initialize HistoryManager with loaded project state so undo does not jump back to empty initial state + historyManagerRef.current.initialize({ + elements: data.elements, + layers: data.layers.length > 0 ? data.layers : initialLayers, + blocks: data.blocks, + groups: [], + bgConfig: null, + }); + syncHistory(); // Push initial data to Yjs CRDT after load // Issue #7: Only push to CRDT if backend data actually has content. // Pushing empty arrays would wipe existing CRDT data from other connected clients.