Files
Dwinzo_Demo/app/src/components/SimulationDashboard/components/block/BlockComponent.tsx

147 lines
5.7 KiB
TypeScript

import { useRef, type RefObject } from "react";
import { Block } from "../../../../types/exportedTypes";
import ElementComponent from "../element/ElementComponent";
import { ResizeIcon } from "../../../icons/ExportToolsIcons";
import ElementDropdown from "../element/ElementDropdown";
interface BlockComponentProps {
block: Block;
handleAddElement: (blockId: string, type: UIType, graphType?: GraphTypes) => void;
editMode: boolean;
selectedBlock: string | null;
selectedElement: string | null;
calculateMinBlockSize: (block: Block) => { width: number; height: number };
handleBlockClick: (blockId: string, event: React.MouseEvent) => void;
handleElementClick: (blockId: string, elementId: string, event: React.MouseEvent) => void;
handleElementDragStart: (elementId: string, event: React.MouseEvent) => void;
handleElementResizeStart: (elementId: string, event: React.MouseEvent) => void;
handleBlockResizeStart: (blockId: string, event: React.MouseEvent) => void;
setShowElementDropdown: (blockId: string | null) => void;
showElementDropdown: string | null;
blockRef: RefObject<HTMLDivElement>;
handleBlockDragStart: (blockId: string, event: React.MouseEvent) => void;
}
const BlockComponent: React.FC<BlockComponentProps> = ({
block,
handleAddElement,
editMode,
selectedBlock,
selectedElement,
calculateMinBlockSize,
handleBlockClick,
handleElementClick,
handleElementDragStart,
handleElementResizeStart,
handleBlockResizeStart,
setShowElementDropdown,
showElementDropdown,
blockRef,
handleBlockDragStart,
}) => {
const dropdownRef = useRef<HTMLDivElement>(null);
const minSize = calculateMinBlockSize(block);
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 (
<div
key={block.blockUuid}
data-block-id={block.blockUuid}
ref={isSelected ? blockRef : null}
className={`block ${isSelected ? "selected" : ""} ${editMode ? "edit-mode" : ""} ${isDraggable ? "draggable" : ""}`}
style={{
...block.style,
position: block.positionType || "relative",
left: block.positionType === "absolute" || block.positionType === "fixed" ? `${block.position?.x || 0}px` : "auto",
top: block.positionType === "absolute" || block.positionType === "fixed" ? `${block.position?.y || 0}px` : "auto",
width: block.size?.width || 400,
height: block.size?.height || 300,
minWidth: minSize.width,
minHeight: minSize.height,
zIndex: block.zIndex || 1,
cursor: isDraggable ? "move" : "pointer",
}}
onClick={handleMouseDown}
>
{/* Add Element Button */}
{editMode && isSelected && (
<div className="element-container">
<button
onClick={(e) => {
e.stopPropagation();
setShowElementDropdown(showElementDropdown === block.blockUuid ? null : block.blockUuid);
}}
className="add-element-button"
>
+ Add Element
</button>
<ElementDropdown
showElementDropdown={showElementDropdown}
handleAddElement={(blockId, type, graphType) => handleAddElement(blockId, type as UIType, graphType as GraphTypes)}
dropdownRef={dropdownRef}
/>
</div>
)}
{/* Elements */}
{block.elements.map((el) => (
<ElementComponent
key={el.elementUuid}
element={el}
blockId={block.blockUuid}
editMode={editMode}
selectedElement={selectedElement}
handleElementClick={handleElementClick}
handleElementDragStart={handleElementDragStart}
handleElementResizeStart={handleElementResizeStart}
/>
))}
{/* Block resize handle */}
{editMode && isSelected && (
<div className="resize-handle" onMouseDown={(e) => handleBlockResizeStart(block.blockUuid, e)}>
<ResizeIcon />
</div>
)}
{/* Drag handle indicator for absolute/fixed blocks */}
{isDraggable && editMode && (
<div
className="drag-handle"
style={{
position: "absolute",
top: "5px",
left: "5px",
width: "20px",
height: "20px",
backgroundColor: "rgba(33, 150, 243, 0.8)",
borderRadius: "4px",
cursor: "move",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white",
fontSize: "12px",
zIndex: 10,
}}
title="Drag to move"
>
</div>
)}
</div>
);
};
export default BlockComponent;