Refactor DashboardEditor to improve block and element handling, including backend updates and drag-and-drop functionality. Adjust minimum block size constraints and enhance asset visibility checks in the asset group store. Update socket initialization to streamline project connections. Modify styles for element dropdown transitions.

This commit is contained in:
2025-10-17 15:19:12 +05:30
parent ba615cefed
commit 68899162b2
11 changed files with 452 additions and 232 deletions

View File

@@ -3,6 +3,7 @@ import React, { useState, useRef, useEffect } from "react";
import { dataModelManager } from "./data/dataModel";
import ControlPanel from "./ControlPanel";
import SwapModal from "./SwapModal";
import { Block } from "../../types/exportedTypes";
import DataModelPanel from "./components/models/DataModelPanel";
import { useSceneContext } from "../../modules/scene/sceneContext";
@@ -77,23 +78,35 @@ const DashboardEditor: React.FC = () => {
const currentBlock = blocks.find((b) => b.blockUuid === selectedBlock);
const currentElement = currentBlock?.elements.find((el) => el.elementUuid === selectedElement);
useEffect(() => {
console.log("blocks: ", blocks);
}, [blocks]);
useEffect(() => {
if (!projectId || !selectedVersion) return;
// getDashBoardBlocksApi(projectId, selectedVersion.versionId).then((data) => {
// if (data.data && data.data.blocks) {
// console.log("data: ", data);
// setBlocks(data.data.blocks);
// }
// });
getDashBoardBlocksApi(projectId, selectedVersion.versionId).then((data) => {
if (data.data?.blocks) {
console.log("data.data.blocks: ", data.data.blocks);
setBlocks(data.data.blocks);
}
});
}, [projectId, selectedVersion]);
const updateBackend = (blocks: Block[]) => {
if (!projectId || !selectedVersion) return;
upsetDashBoardBlocksApi({ projectId, versionId: selectedVersion.versionId, blocks }).then((data) => {
if (data.data?.blocks) {
console.log("data.data.blocks: ", data.data.blocks);
setBlocks(data.data.blocks);
}
});
};
useEffect(() => {
const unsubscribe = subscribe(() => {
if (!projectId || !selectedVersion) return;
// upsetDashBoardBlocksApi({ projectId, versionId: selectedVersion.versionId, blocks }).then((data) => {
// console.log("data: ", data);
// });
updateBackend(blocks);
});
return () => {
@@ -103,10 +116,11 @@ const DashboardEditor: React.FC = () => {
useCallBackOnKey(
() => {
console.log(blocks);
if (!projectId || !selectedVersion) return;
updateBackend(blocks);
},
"Ctrl+S",
{ dependencies: [blocks], noRepeat: true, allowOnInput: true }
{ dependencies: [blocks, projectId, selectedVersion], noRepeat: true, allowOnInput: true }
);
// Subscribe to data model changes
@@ -118,27 +132,27 @@ const DashboardEditor: React.FC = () => {
const keys = dataModelManager.getAvailableKeys();
const subscriptions: Array<[string, () => void]> = [];
keys.forEach((key) => {
for (const key of keys) {
const callback = () => handleDataChange();
dataModelManager.subscribe(key, callback);
subscriptions.push([key, callback]);
});
}
const interval = setInterval(() => {
const currentKeys = dataModelManager.getAvailableKeys();
const newKeys = currentKeys.filter((key) => !keys.includes(key));
newKeys.forEach((key) => {
for (const key of newKeys) {
const callback = () => handleDataChange();
dataModelManager.subscribe(key, callback);
subscriptions.push([key, callback]);
});
}
}, 1000);
return () => {
subscriptions.forEach(([key, callback]) => {
for (const [key, callback] of subscriptions) {
dataModelManager.unsubscribe(key, callback);
});
}
clearInterval(interval);
};
}, []);
@@ -183,144 +197,144 @@ const DashboardEditor: React.FC = () => {
}, [selectedBlock, selectedElement]);
// Drag and drop handler
useEffect(() => {
const handleMouseMove = (e: MouseEvent): void => {
// Element dragging - direct DOM manipulation
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
if (blockElement && elementToDrag) {
const blockRect = blockElement.getBoundingClientRect();
const newX = e.clientX - blockRect.left - elementDragOffset.x;
const newY = e.clientY - blockRect.top - elementDragOffset.y;
useEffect(() => {
const handleMouseMove = (e: MouseEvent): void => {
// Element dragging - direct DOM manipulation
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
// Direct DOM manipulation
elementToDrag.style.left = `${Math.max(0, Math.min(blockRect.width - 50, newX))}px`;
elementToDrag.style.top = `${Math.max(0, Math.min(blockRect.height - 30, newY))}px`;
if (blockElement && elementToDrag) {
const blockRect = blockElement.getBoundingClientRect();
const newX = e.clientX - blockRect.left - elementDragOffset.x;
const newY = e.clientY - blockRect.top - elementDragOffset.y;
// Direct DOM manipulation
elementToDrag.style.left = `${Math.max(0, Math.min(blockRect.width - 50, newX))}px`;
elementToDrag.style.top = `${Math.max(0, Math.min(blockRect.height - 30, newY))}px`;
}
}
}
// Block dragging - direct DOM manipulation
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
const editorElement = editorRef.current;
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
if (editorElement && blockToDrag) {
const editorRect = editorElement.getBoundingClientRect();
const newX = e.clientX - editorRect.left - blockDragOffset.x;
const newY = e.clientY - editorRect.top - blockDragOffset.y;
// Block dragging - direct DOM manipulation
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
const editorElement = editorRef.current;
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
// Direct DOM manipulation
blockToDrag.style.left = `${Math.max(0, Math.min(editorRect.width - (currentBlock.size?.width || 400), newX))}px`;
blockToDrag.style.top = `${Math.max(0, Math.min(editorRect.height - (currentBlock.size?.height || 300), newY))}px`;
if (editorElement && blockToDrag) {
const editorRect = editorElement.getBoundingClientRect();
const newX = e.clientX - editorRect.left - blockDragOffset.x;
const newY = e.clientY - editorRect.top - blockDragOffset.y;
// Direct DOM manipulation
blockToDrag.style.left = `${Math.max(0, Math.min(editorRect.width - (currentBlock.size?.width || 400), newX))}px`;
blockToDrag.style.top = `${Math.max(0, Math.min(editorRect.height - (currentBlock.size?.height || 300), newY))}px`;
}
}
}
// Resizing - direct DOM manipulation
if ((resizingElement || resizingBlock) && resizeStart) {
// Resizing - direct DOM manipulation
if ((resizingElement || resizingBlock) && resizeStart) {
if (resizingElement && selectedBlock) {
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
if (elementToResize) {
const deltaX = e.clientX - resizeStart.x;
const deltaY = e.clientY - resizeStart.y;
const newWidth = Math.max(100, resizeStart.width + deltaX);
const newHeight = Math.max(50, resizeStart.height + deltaY);
// Direct DOM manipulation
elementToResize.style.width = `${newWidth}px`;
elementToResize.style.height = `${newHeight}px`;
}
} else if (resizingBlock) {
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
if (blockToResize) {
const deltaX = e.clientX - resizeStart.x;
const deltaY = e.clientY - resizeStart.y;
const currentBlock = blocks.find((b) => b.blockUuid === resizingBlock);
const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 100, height: 50 };
const newWidth = Math.max(minSize.width, resizeStart.width + deltaX);
const newHeight = Math.max(minSize.height, resizeStart.height + deltaY);
// Direct DOM manipulation
blockToResize.style.width = `${newWidth}px`;
blockToResize.style.height = `${newHeight}px`;
}
}
}
};
const handleMouseUp = (): void => {
// Update state only on mouse up for elements
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
if (blockElement && elementToDrag) {
const computedStyle = window.getComputedStyle(elementToDrag);
const x = parseFloat(computedStyle.left);
const y = parseFloat(computedStyle.top);
updateElementPosition(selectedBlock, draggingElement, { x, y });
}
}
// Update state only on mouse up for blocks
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
if (blockToDrag) {
const computedStyle = window.getComputedStyle(blockToDrag);
const x = parseFloat(computedStyle.left);
const y = parseFloat(computedStyle.top);
updateBlockPosition(draggingBlock, { x, y });
}
}
// Update state only on mouse up for resizing
if (resizingElement && selectedBlock) {
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
if (elementToResize) {
const deltaX = e.clientX - resizeStart.x;
const deltaY = e.clientY - resizeStart.y;
const computedStyle = window.getComputedStyle(elementToResize);
const width = parseFloat(computedStyle.width);
const height = parseFloat(computedStyle.height);
const newWidth = Math.max(100, resizeStart.width + deltaX);
const newHeight = Math.max(50, resizeStart.height + deltaY);
// Direct DOM manipulation
elementToResize.style.width = `${newWidth}px`;
elementToResize.style.height = `${newHeight}px`;
updateElementSize(selectedBlock, resizingElement, { width, height });
}
} else if (resizingBlock) {
}
if (resizingBlock) {
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
if (blockToResize) {
const deltaX = e.clientX - resizeStart.x;
const deltaY = e.clientY - resizeStart.y;
const computedStyle = window.getComputedStyle(blockToResize);
const width = parseFloat(computedStyle.width);
const height = parseFloat(computedStyle.height);
const currentBlock = blocks.find((b) => b.blockUuid === resizingBlock);
const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 300, height: 200 };
const newWidth = Math.max(minSize.width, resizeStart.width + deltaX);
const newHeight = Math.max(minSize.height, resizeStart.height + deltaY);
// Direct DOM manipulation
blockToResize.style.width = `${newWidth}px`;
blockToResize.style.height = `${newHeight}px`;
updateBlockSize(resizingBlock, { width, height });
}
}
}
};
const handleMouseUp = (): void => {
// Update state only on mouse up for elements
if (draggingElement && selectedBlock && currentElement?.positionType === "absolute") {
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
if (blockElement && elementToDrag) {
const computedStyle = window.getComputedStyle(elementToDrag);
const x = parseFloat(computedStyle.left);
const y = parseFloat(computedStyle.top);
updateElementPosition(selectedBlock, draggingElement, { x, y });
}
// Reset all dragging states
setDraggingElement(null);
setResizingElement(null);
setDraggingBlock(null);
setResizingBlock(null);
setResizeStart(null);
};
if (draggingElement || draggingBlock || resizingElement || resizingBlock) {
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
}
// Update state only on mouse up for blocks
if (draggingBlock && currentBlock?.positionType && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
if (blockToDrag) {
const computedStyle = window.getComputedStyle(blockToDrag);
const x = parseFloat(computedStyle.left);
const y = parseFloat(computedStyle.top);
updateBlockPosition(draggingBlock, { x, y });
}
}
// Update state only on mouse up for resizing
if (resizingElement && selectedBlock) {
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
if (elementToResize) {
const computedStyle = window.getComputedStyle(elementToResize);
const width = parseFloat(computedStyle.width);
const height = parseFloat(computedStyle.height);
updateElementSize(selectedBlock, resizingElement, { width, height });
}
}
if (resizingBlock) {
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
if (blockToResize) {
const computedStyle = window.getComputedStyle(blockToResize);
const width = parseFloat(computedStyle.width);
const height = parseFloat(computedStyle.height);
updateBlockSize(resizingBlock, { width, height });
}
}
// Reset all dragging states
setDraggingElement(null);
setResizingElement(null);
setDraggingBlock(null);
setResizingBlock(null);
setResizeStart(null);
};
if (draggingElement || draggingBlock || resizingElement || resizingBlock) {
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
}
return () => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
};
}, [draggingElement, resizingElement, draggingBlock, resizingBlock, elementDragOffset, blockDragOffset, selectedBlock, currentElement, resizeStart, currentBlock, blocks]);
return () => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
};
}, [draggingElement, resizingElement, draggingBlock, resizingBlock, elementDragOffset, blockDragOffset, selectedBlock, currentElement, resizeStart, currentBlock, blocks]);
// Update dropdown position when showElementDropdown changes
useEffect(() => {