From deb9472073c2308065dafc948772726b7fa24ada Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Sat, 20 Dec 2025 14:12:10 +0530 Subject: [PATCH] feat: Add initial implementation of Simulation Dashboard editor and its core components. --- .../SimulationDashboard/DashboardEditor.tsx | 55 ++++++++----------- .../components/block/BlockComponent.tsx | 9 +-- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/app/src/components/SimulationDashboard/DashboardEditor.tsx b/app/src/components/SimulationDashboard/DashboardEditor.tsx index b20296f..ccf732a 100644 --- a/app/src/components/SimulationDashboard/DashboardEditor.tsx +++ b/app/src/components/SimulationDashboard/DashboardEditor.tsx @@ -95,12 +95,12 @@ const DashboardEditor: React.FC = () => { const currentBlock = blocks.find((b) => b.blockUuid === selectedBlock); const currentElement = currentBlock?.elements.find((el) => el.elementUuid === selectedElement); - useEffect(()=>{ + useEffect(() => { if (!editMode) { setSelectedBlock(null); setSelectedElement(null); } - },[editMode]) + }, [editMode]); // Helper function to send updates to backend - only sends the specific block that changed const updateBackend = async (updatedBlock: Block) => { @@ -313,6 +313,8 @@ const DashboardEditor: React.FC = () => { }; const handleMouseUp = async (): Promise => { + let blockToUpdate: Block | undefined; + // Update backend using peek methods, then update state from response if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") { const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement; @@ -325,15 +327,10 @@ const DashboardEditor: React.FC = () => { // Use peek to get updated blocks and send only the affected block to backend const updatedBlocks = peekUpdateElementPosition(selectedBlock, draggingElement, { x, y }); - const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock); - if (updatedBlock) { - await updateBackend(updatedBlock); - } + blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock); } - } - - // Update backend for block drag - if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) { + } else if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) { + // Update backend for block drag const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement; if (blockToDrag) { @@ -343,15 +340,10 @@ const DashboardEditor: React.FC = () => { // Use peek to get updated blocks and send only the affected block to backend const updatedBlocks = peekUpdateBlockPosition(draggingBlock, { x, y }); - const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, draggingBlock); - if (updatedBlock) { - await updateBackend(updatedBlock); - } + blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, draggingBlock); } - } - - // Update backend for element resize - if (resizingElement && selectedBlock) { + } else if (resizingElement && selectedBlock) { + // Update backend for element resize const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement; if (elementToResize) { const computedStyle = window.getComputedStyle(elementToResize); @@ -360,15 +352,10 @@ const DashboardEditor: React.FC = () => { // Use peek to get updated blocks and send only the affected block to backend const updatedBlocks = peekUpdateElementSize(selectedBlock, resizingElement, { width, height }); - const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock); - if (updatedBlock) { - await updateBackend(updatedBlock); - } + blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock); } - } - - // Update backend for block resize - if (resizingBlock) { + } else if (resizingBlock) { + // Update backend for block resize const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement; if (blockToResize) { const computedStyle = window.getComputedStyle(blockToResize); @@ -377,19 +364,25 @@ const DashboardEditor: React.FC = () => { // Use peek to get updated blocks and send only the affected block to backend const updatedBlocks = peekUpdateBlockSize(resizingBlock, { width, height }); - const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, resizingBlock); - if (updatedBlock) { - await updateBackend(updatedBlock); - } + blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, resizingBlock); } } - // Reset all dragging states + // Reset all dragging states IMMEDIATELY to stop cursor following setDraggingElement(null); setResizingElement(null); setDraggingBlock(null); setResizingBlock(null); setResizeStart(null); + + // Perform updates if needed + if (blockToUpdate) { + // Optimistic update to prevent snap-back + updateBlock(blockToUpdate.blockUuid, blockToUpdate); + + // Send to backend + await updateBackend(blockToUpdate); + } }; if (draggingElement || draggingBlock || resizingElement || resizingBlock) { diff --git a/app/src/components/SimulationDashboard/components/block/BlockComponent.tsx b/app/src/components/SimulationDashboard/components/block/BlockComponent.tsx index 75e89c5..ae21157 100644 --- a/app/src/components/SimulationDashboard/components/block/BlockComponent.tsx +++ b/app/src/components/SimulationDashboard/components/block/BlockComponent.tsx @@ -53,13 +53,6 @@ const BlockComponent: React.FC = ({ const isSelected = selectedBlock === block.blockUuid; const isDraggable = editMode && (block.positionType === "absolute" || block.positionType === "fixed"); - const handleMouseDown = (event: React.MouseEvent) => { - if (isDraggable) { - handleBlockDragStart(block.blockUuid, event); - } - handleBlockClick(block.blockUuid, event); - }; - return (
= ({ handleBlockDragStart(block.blockUuid, e); } }} - onClick={handleMouseDown} + onClick={(e) => handleBlockClick(block.blockUuid, e)} > {/* Add Element Button */} {editMode && isSelected && (