feat: Add initial implementation of Simulation Dashboard editor and its core components.
This commit is contained in:
@@ -100,7 +100,7 @@ const DashboardEditor: React.FC = () => {
|
|||||||
setSelectedBlock(null);
|
setSelectedBlock(null);
|
||||||
setSelectedElement(null);
|
setSelectedElement(null);
|
||||||
}
|
}
|
||||||
},[editMode])
|
}, [editMode]);
|
||||||
|
|
||||||
// Helper function to send updates to backend - only sends the specific block that changed
|
// Helper function to send updates to backend - only sends the specific block that changed
|
||||||
const updateBackend = async (updatedBlock: Block) => {
|
const updateBackend = async (updatedBlock: Block) => {
|
||||||
@@ -313,6 +313,8 @@ const DashboardEditor: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseUp = async (): Promise<void> => {
|
const handleMouseUp = async (): Promise<void> => {
|
||||||
|
let blockToUpdate: Block | undefined;
|
||||||
|
|
||||||
// Update backend using peek methods, then update state from response
|
// Update backend using peek methods, then update state from response
|
||||||
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
|
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
|
||||||
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
|
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
|
// Use peek to get updated blocks and send only the affected block to backend
|
||||||
const updatedBlocks = peekUpdateElementPosition(selectedBlock, draggingElement, { x, y });
|
const updatedBlocks = peekUpdateElementPosition(selectedBlock, draggingElement, { x, y });
|
||||||
const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock);
|
blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock);
|
||||||
if (updatedBlock) {
|
|
||||||
await updateBackend(updatedBlock);
|
|
||||||
}
|
}
|
||||||
}
|
} else if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
|
||||||
}
|
|
||||||
|
|
||||||
// Update backend for block drag
|
// Update backend for block drag
|
||||||
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
|
|
||||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||||
|
|
||||||
if (blockToDrag) {
|
if (blockToDrag) {
|
||||||
@@ -343,15 +340,10 @@ const DashboardEditor: React.FC = () => {
|
|||||||
|
|
||||||
// Use peek to get updated blocks and send only the affected block to backend
|
// Use peek to get updated blocks and send only the affected block to backend
|
||||||
const updatedBlocks = peekUpdateBlockPosition(draggingBlock, { x, y });
|
const updatedBlocks = peekUpdateBlockPosition(draggingBlock, { x, y });
|
||||||
const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, draggingBlock);
|
blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, draggingBlock);
|
||||||
if (updatedBlock) {
|
|
||||||
await updateBackend(updatedBlock);
|
|
||||||
}
|
}
|
||||||
}
|
} else if (resizingElement && selectedBlock) {
|
||||||
}
|
|
||||||
|
|
||||||
// Update backend for element resize
|
// Update backend for element resize
|
||||||
if (resizingElement && selectedBlock) {
|
|
||||||
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
|
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
|
||||||
if (elementToResize) {
|
if (elementToResize) {
|
||||||
const computedStyle = window.getComputedStyle(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
|
// Use peek to get updated blocks and send only the affected block to backend
|
||||||
const updatedBlocks = peekUpdateElementSize(selectedBlock, resizingElement, { width, height });
|
const updatedBlocks = peekUpdateElementSize(selectedBlock, resizingElement, { width, height });
|
||||||
const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock);
|
blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, selectedBlock);
|
||||||
if (updatedBlock) {
|
|
||||||
await updateBackend(updatedBlock);
|
|
||||||
}
|
}
|
||||||
}
|
} else if (resizingBlock) {
|
||||||
}
|
|
||||||
|
|
||||||
// Update backend for block resize
|
// Update backend for block resize
|
||||||
if (resizingBlock) {
|
|
||||||
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
||||||
if (blockToResize) {
|
if (blockToResize) {
|
||||||
const computedStyle = window.getComputedStyle(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
|
// Use peek to get updated blocks and send only the affected block to backend
|
||||||
const updatedBlocks = peekUpdateBlockSize(resizingBlock, { width, height });
|
const updatedBlocks = peekUpdateBlockSize(resizingBlock, { width, height });
|
||||||
const updatedBlock = getBlockFromPeekedBlocks(updatedBlocks, resizingBlock);
|
blockToUpdate = getBlockFromPeekedBlocks(updatedBlocks, resizingBlock);
|
||||||
if (updatedBlock) {
|
|
||||||
await updateBackend(updatedBlock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset all dragging states
|
// Reset all dragging states IMMEDIATELY to stop cursor following
|
||||||
setDraggingElement(null);
|
setDraggingElement(null);
|
||||||
setResizingElement(null);
|
setResizingElement(null);
|
||||||
setDraggingBlock(null);
|
setDraggingBlock(null);
|
||||||
setResizingBlock(null);
|
setResizingBlock(null);
|
||||||
setResizeStart(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) {
|
if (draggingElement || draggingBlock || resizingElement || resizingBlock) {
|
||||||
|
|||||||
@@ -53,13 +53,6 @@ const BlockComponent: React.FC<BlockComponentProps> = ({
|
|||||||
const isSelected = selectedBlock === block.blockUuid;
|
const isSelected = selectedBlock === block.blockUuid;
|
||||||
const isDraggable = editMode && (block.positionType === "absolute" || block.positionType === "fixed");
|
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 (
|
return (
|
||||||
<div
|
<div
|
||||||
key={block.blockUuid}
|
key={block.blockUuid}
|
||||||
@@ -83,7 +76,7 @@ const BlockComponent: React.FC<BlockComponentProps> = ({
|
|||||||
handleBlockDragStart(block.blockUuid, e);
|
handleBlockDragStart(block.blockUuid, e);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onClick={handleMouseDown}
|
onClick={(e) => handleBlockClick(block.blockUuid, e)}
|
||||||
>
|
>
|
||||||
{/* Add Element Button */}
|
{/* Add Element Button */}
|
||||||
{editMode && isSelected && (
|
{editMode && isSelected && (
|
||||||
|
|||||||
Reference in New Issue
Block a user