feat: implement DashboardEditor component for managing simulation dashboards and add block size calculation utility.

This commit is contained in:
2025-12-20 14:49:23 +05:30
parent 8a5c78bc6d
commit 005e17c7b5
2 changed files with 46 additions and 7 deletions

View File

@@ -252,12 +252,20 @@ const DashboardEditor: React.FC = () => {
if (blockElement && elementToDrag) { if (blockElement && elementToDrag) {
const blockRect = blockElement.getBoundingClientRect(); const blockRect = blockElement.getBoundingClientRect();
const elementRect = elementToDrag.getBoundingClientRect();
const newX = e.clientX - blockRect.left - elementDragOffset.x; const newX = e.clientX - blockRect.left - elementDragOffset.x;
const newY = e.clientY - blockRect.top - elementDragOffset.y; const newY = e.clientY - blockRect.top - elementDragOffset.y;
// Direct DOM manipulation // Constrain element to stay within block bounds using actual element dimensions
elementToDrag.style.left = `${Math.max(0, Math.min(blockRect.width - 50, newX))}px`; // Add 20px padding on all sides to match the padding used in calculateMinBlockSize
elementToDrag.style.top = `${Math.max(0, Math.min(blockRect.height - 30, newY))}px`; const minX = 20; // Left padding
const minY = 20; // Top padding
const maxX = blockRect.width - elementRect.width - 20; // Right padding
const maxY = blockRect.height - elementRect.height - 20; // Bottom padding
// Direct DOM manipulation with padding on all sides
elementToDrag.style.left = `${Math.max(minX, Math.min(maxX, newX))}px`;
elementToDrag.style.top = `${Math.max(minY, Math.min(maxY, newY))}px`;
} }
} }
@@ -318,10 +326,32 @@ const DashboardEditor: React.FC = () => {
const deltaY = e.clientY - resizeStart.y; const deltaY = e.clientY - resizeStart.y;
const currentBlock = blocks.find((b) => b.blockUuid === resizingBlock); 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); // Calculate minimum size based on ALL elements in the block
const newHeight = Math.max(minSize.height, resizeStart.height + deltaY); const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 100, height: 50 };
const minWidth = minSize.width;
const minHeight = minSize.height;
let newWidth = Math.max(minWidth, resizeStart.width + deltaX);
let newHeight = Math.max(minHeight, resizeStart.height + deltaY);
// Constrain block to editor bounds if it has absolute or fixed positioning
if (currentBlock && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) {
const editorElement = editorRef.current;
if (editorElement) {
const editorRect = editorElement.getBoundingClientRect();
const blockX = currentBlock.position?.x || 0;
const blockY = currentBlock.position?.y || 0;
// Calculate max allowed dimensions based on position
const maxAllowedWidth = editorRect.width - blockX;
const maxAllowedHeight = editorRect.height - blockY;
// Constrain width and height to editor bounds, but not below minimum
newWidth = Math.max(minWidth, Math.min(newWidth, maxAllowedWidth));
newHeight = Math.max(minHeight, Math.min(newHeight, maxAllowedHeight));
}
}
// Direct DOM manipulation // Direct DOM manipulation
blockToResize.style.width = `${newWidth}px`; blockToResize.style.width = `${newWidth}px`;

View File

@@ -3,6 +3,7 @@ import type { Block } from "../../../../types/exportedTypes";
export const calculateMinBlockSize = (block: Block): Size => { export const calculateMinBlockSize = (block: Block): Size => {
let minWidth = 100; let minWidth = 100;
let minHeight = 50; let minHeight = 50;
let stackedHeight = 0; // Track cumulative height for stacked elements
block.elements.forEach((element) => { block.elements.forEach((element) => {
if (element.positionType === "absolute") { if (element.positionType === "absolute") {
@@ -11,10 +12,18 @@ export const calculateMinBlockSize = (block: Block): Size => {
minWidth = Math.max(minWidth, elementRight + 20); minWidth = Math.max(minWidth, elementRight + 20);
minHeight = Math.max(minHeight, elementBottom + 20); minHeight = Math.max(minHeight, elementBottom + 20);
} else { } else {
// For relative/static elements, they stack vertically
// Width: take the maximum
minWidth = Math.max(minWidth, (element.size?.width || 200) + 40); minWidth = Math.max(minWidth, (element.size?.width || 200) + 40);
minHeight = Math.max(minHeight, (element.size?.height || 60) + 40); // Height: sum them up since they stack
stackedHeight += element.size?.height || 60;
} }
}); });
// Add padding to stacked height and compare with minHeight from absolute elements
if (stackedHeight > 0) {
minHeight = Math.max(minHeight, stackedHeight + 40);
}
return { width: minWidth, height: minHeight }; return { width: minWidth, height: minHeight };
}; };