diff --git a/app/src/components/SimulationDashboard/components/element/ElementComponent.tsx b/app/src/components/SimulationDashboard/components/element/ElementComponent.tsx index 28ec04d..ccd0f9e 100644 --- a/app/src/components/SimulationDashboard/components/element/ElementComponent.tsx +++ b/app/src/components/SimulationDashboard/components/element/ElementComponent.tsx @@ -14,24 +14,10 @@ interface ElementComponentProps { handleElementResizeStart: (elementId: string, event: React.MouseEvent) => void; } -const ElementComponent: React.FC = ({ - element, - blockId, - editMode, - selectedElement, - handleElementClick, - handleElementDragStart, - handleElementResizeStart, -}) => { +const ElementComponent: React.FC = ({ element, blockId, editMode, selectedElement, handleElementClick, handleElementDragStart, handleElementResizeStart }) => { const isSelected = selectedElement === element.elementUuid; - const elementClasses = [ - "element", - element.positionType === "absolute" ? "absolute" : "", - element.type === "graph" ? "graph" : "", - editMode ? "edit-mode" : "", - isSelected ? "selected" : "", - ] + const elementClasses = ["element", element.positionType === "absolute" ? "absolute" : "", element.type === "graph" ? "graph" : "", editMode ? "edit-mode" : "", isSelected ? "selected" : ""] .filter(Boolean) .join(" "); @@ -43,8 +29,7 @@ const ElementComponent: React.FC = ({ style={{ ...element.style, position: element.positionType || "relative", - left: - element.positionType === "absolute" ? `${element.position?.x || 0}px` : "auto", + left: element.positionType === "absolute" ? `${element.position?.x || 0}px` : "auto", top: element.positionType === "absolute" ? `${element.position?.y || 0}px` : "auto", width: element.size?.width || "auto", height: element.size?.height || "auto", @@ -55,16 +40,18 @@ const ElementComponent: React.FC = ({ e.stopPropagation(); handleElementClick(blockId, element.elementUuid, e); }} - onMouseDown={(e) => handleElementDragStart(element.elementUuid, e)} + onMouseDown={(e) => { + // Only allow dragging for absolute positioned elements + if (element.positionType === "absolute") { + handleElementDragStart(element.elementUuid, e); + } + }} > {editMode && ( <> -
handleElementResizeStart(element.elementUuid, e)} - > +
handleElementResizeStart(element.elementUuid, e)}>
diff --git a/app/src/modules/simulation/analyzer/analyzer.tsx b/app/src/modules/simulation/analyzer/analyzer.tsx index 744bac2..bf41928 100644 --- a/app/src/modules/simulation/analyzer/analyzer.tsx +++ b/app/src/modules/simulation/analyzer/analyzer.tsx @@ -187,6 +187,9 @@ function Analyzer() { // Track previous actions for ArmBots to detect cycle completion const previousArmBotActionsRef = useRef>({}); + // Track previous actions for Machines to detect cycle completion + const previousMachineActionsRef = useRef>({}); + // Track previous action counts for Humans to detect completion from EventManager const previousHumanCountsRef = useRef>>({}); @@ -228,6 +231,7 @@ function Analyzer() { bottleneckEventsRef.current = {}; previousAssetStatesRef.current = {}; previousArmBotActionsRef.current = {}; + previousMachineActionsRef.current = {}; previousHumanCountsRef.current = {}; previousVehiclePhasesRef.current = {}; previousCranePhasesRef.current = {}; @@ -278,7 +282,7 @@ function Analyzer() { const calculateQualityMetrics = (assetId: string, totalOperations: number, defects: number, historicalData: any[] = []) => { const errorCount = errorCountsRef.current[assetId] || 0; - const firstPassYield = totalOperations > 0 ? ((totalOperations - defects) / totalOperations) * 100 : 100; + const firstPassYield = totalOperations > 0 ? ((totalOperations - defects) / totalOperations) * 100 : 0; const defectRate = totalOperations > 0 ? (defects / totalOperations) * 100 : 0; const scrapRate = defects > 0 ? defects * 0.1 : 0; // Assuming 10% scrap rate const reworkRate = defects > 0 ? defects * 0.9 : 0; // Assuming 90% rework @@ -2395,6 +2399,33 @@ function Analyzer() { }); }, [armBots, isPlaying]); + // Monitor Machine action changes to track cycles + useEffect(() => { + if (!isPlaying) return; + + machines.forEach((machine) => { + const previousActionUuid = previousMachineActionsRef.current[machine.modelUuid]; + const currentActionUuid = machine.currentAction?.actionUuid; + + // Check if action completed (transition from an action to no action or different action) + if (previousActionUuid && previousActionUuid !== currentActionUuid) { + // Action completed - increment cycles + if (!completedActionsRef.current[machine.modelUuid]) { + completedActionsRef.current[machine.modelUuid] = 0; + } + completedActionsRef.current[machine.modelUuid]++; + + // Also update parts processed (assume 1 part per cycle) + if (!completedActionsRef.current[`${machine.modelUuid}_parts`]) { + completedActionsRef.current[`${machine.modelUuid}_parts`] = 0; + } + completedActionsRef.current[`${machine.modelUuid}_parts`]++; + } + + previousMachineActionsRef.current[machine.modelUuid] = currentActionUuid; + }); + }, [machines, isPlaying]); + // Monitor Human action changes from EventManager useEffect(() => { if (!isPlaying || !humanEventManagerRef.current) return;