From b697e26170da95dcb427ff6907b6f663c98ba59f Mon Sep 17 00:00:00 2001 From: Guy Ben-Aharon Date: Mon, 18 Aug 2025 20:56:32 +0300 Subject: [PATCH] fix(canvas): delete table + area together bug (#859) --- src/pages/editor-page/canvas/canvas.tsx | 134 ++++++++++++++---------- 1 file changed, 77 insertions(+), 57 deletions(-) diff --git a/src/pages/editor-page/canvas/canvas.tsx b/src/pages/editor-page/canvas/canvas.tsx index 4d2038c0..8bab0b8d 100644 --- a/src/pages/editor-page/canvas/canvas.tsx +++ b/src/pages/editor-page/canvas/canvas.tsx @@ -848,26 +848,87 @@ export const Canvas: React.FC = ({ initialTables }) => { changesToApply = [...changesToApply, ...additionalChanges]; } - // Handle table changes - only update storage when NOT dragging + // First, detect area changes + const { + positionChanges: areaPositionChanges, + removeChanges: areaRemoveChanges, + sizeChanges: areaSizeChanges, + } = findRelevantNodesChanges(changesToApply, 'area'); + + // Then, detect table changes const { positionChanges, removeChanges, sizeChanges } = findRelevantNodesChanges(changesToApply, 'table'); + // Calculate child table movements from area position changes + const childTableMovements: Map< + string, + { deltaX: number; deltaY: number } + > = new Map(); + if ( + areaPositionChanges.length > 0 && + areaSizeChanges.length === 0 + ) { + areaPositionChanges.forEach((change) => { + if (change.type === 'position' && change.position) { + const currentArea = areas.find( + (a) => a.id === change.id + ); + if (currentArea) { + const deltaX = change.position.x - currentArea.x; + const deltaY = change.position.y - currentArea.y; + + const childTables = getTablesInArea( + change.id, + tables + ); + childTables.forEach((table) => { + childTableMovements.set(table.id, { + deltaX, + deltaY, + }); + }); + } + } + }); + } + + // Apply all table updates in a single call if ( positionChanges.length > 0 || removeChanges.length > 0 || - sizeChanges.length > 0 + sizeChanges.length > 0 || + childTableMovements.size > 0 || + areaRemoveChanges.length > 0 ) { updateTablesState((currentTables) => { - // First update positions const updatedTables = currentTables .map((currentTable) => { + // Handle area removal - clear parentAreaId + const removedArea = areaRemoveChanges.find( + (change) => + change.id === currentTable.parentAreaId + ); + if (removedArea) { + return { + ...currentTable, + parentAreaId: null, + }; + } + + // Handle direct table changes const positionChange = positionChanges.find( (change) => change.id === currentTable.id ); const sizeChange = sizeChanges.find( (change) => change.id === currentTable.id ); - if (positionChange || sizeChange) { + + // Handle child table movement from area drag + const areaMovement = childTableMovements.get( + currentTable.id + ); + + if (positionChange || sizeChange || areaMovement) { const x = positionChange?.position?.x; const y = positionChange?.position?.y; @@ -883,6 +944,16 @@ export const Canvas: React.FC = ({ initialTables }) => { y, } : {}), + ...(areaMovement && !positionChange + ? { + x: + currentTable.x + + areaMovement.deltaX, + y: + currentTable.y + + areaMovement.deltaY, + } + : {}), ...(sizeChange ? { width: @@ -911,20 +982,13 @@ export const Canvas: React.FC = ({ initialTables }) => { sizeChanges, }); - // Handle area changes - const { - positionChanges: areaPositionChanges, - removeChanges: areaRemoveChanges, - sizeChanges: areaSizeChanges, - } = findRelevantNodesChanges(changesToApply, 'area'); - if ( areaPositionChanges.length > 0 || areaRemoveChanges.length > 0 || areaSizeChanges.length > 0 ) { const areasUpdates: Record> = {}; - // Handle area position changes and move child tables (only when drag ends) + // Handle area position changes (child tables already moved above) areaPositionChanges.forEach((change) => { if (change.type === 'position' && change.position) { areasUpdates[change.id] = { @@ -932,39 +996,6 @@ export const Canvas: React.FC = ({ initialTables }) => { x: change.position.x, y: change.position.y, }; - - if (areaSizeChanges.length !== 0) { - // If there are size changes, we don't need to move child tables - return; - } - const currentArea = areas.find( - (a) => a.id === change.id - ); - if (currentArea) { - const deltaX = change.position.x - currentArea.x; - const deltaY = change.position.y - currentArea.y; - - const childTables = getTablesInArea( - change.id, - tables - ); - - // Update child table positions in storage - if (childTables.length > 0) { - updateTablesState((currentTables) => - currentTables.map((table) => { - if (table.parentAreaId === change.id) { - return { - id: table.id, - x: table.x + deltaX, - y: table.y + deltaY, - }; - } - return table; - }) - ); - } - } } }); @@ -979,20 +1010,9 @@ export const Canvas: React.FC = ({ initialTables }) => { } }); + // Handle area removal (child tables parentAreaId already cleared above) areaRemoveChanges.forEach((change) => { - updateTablesState((currentTables) => - currentTables.map((table) => { - if (table.parentAreaId === change.id) { - return { - ...table, - parentAreaId: null, - }; - } - return table; - }) - ); removeArea(change.id); - delete areasUpdates[change.id]; });