Merge remote-tracking branch 'origin/main-dev' into main-demo
This commit is contained in:
@@ -59,7 +59,6 @@ const DashboardEditor: React.FC = () => {
|
||||
peekUpdateCommonValue,
|
||||
peekUpdateDataValue,
|
||||
peekUpdateDataSource,
|
||||
|
||||
} = simulationDashBoardStore();
|
||||
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
@@ -209,6 +208,9 @@ const DashboardEditor: React.FC = () => {
|
||||
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
|
||||
|
||||
if (blockElement && elementToDrag) {
|
||||
// Disable transitions during drag
|
||||
elementToDrag.classList.add("no-transition");
|
||||
|
||||
const blockRect = blockElement.getBoundingClientRect();
|
||||
const elementRect = elementToDrag.getBoundingClientRect();
|
||||
const newX = e.clientX - blockRect.left - elementDragOffset.x;
|
||||
@@ -233,6 +235,9 @@ const DashboardEditor: React.FC = () => {
|
||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||
|
||||
if (editorElement && blockToDrag) {
|
||||
// Disable transitions during drag
|
||||
blockToDrag.classList.add("no-transition");
|
||||
|
||||
const editorRect = editorElement.getBoundingClientRect();
|
||||
const newX = e.clientX - editorRect.left - blockDragOffset.x;
|
||||
const newY = e.clientY - editorRect.top - blockDragOffset.y;
|
||||
@@ -248,6 +253,9 @@ const DashboardEditor: React.FC = () => {
|
||||
if (resizingElement && selectedBlock) {
|
||||
const elementToResize = document.querySelector(`[data-element-id="${resizingElement}"]`) as HTMLElement;
|
||||
if (elementToResize) {
|
||||
// Disable transitions during resize
|
||||
elementToResize.classList.add("no-transition");
|
||||
|
||||
const deltaX = e.clientX - resizeStart.x;
|
||||
const deltaY = e.clientY - resizeStart.y;
|
||||
|
||||
@@ -280,6 +288,9 @@ const DashboardEditor: React.FC = () => {
|
||||
} else if (resizingBlock) {
|
||||
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
||||
if (blockToResize) {
|
||||
// Disable transitions during resize
|
||||
blockToResize.classList.add("no-transition");
|
||||
|
||||
const deltaX = e.clientX - resizeStart.x;
|
||||
const deltaY = e.clientY - resizeStart.y;
|
||||
|
||||
@@ -328,6 +339,9 @@ const DashboardEditor: React.FC = () => {
|
||||
const elementToDrag = document.querySelector(`[data-element-id="${draggingElement}"]`) as HTMLElement;
|
||||
|
||||
if (blockElement && elementToDrag) {
|
||||
// Re-enable transitions
|
||||
elementToDrag.classList.remove("no-transition");
|
||||
|
||||
const computedStyle = window.getComputedStyle(elementToDrag);
|
||||
const x = parseFloat(computedStyle.left);
|
||||
const y = parseFloat(computedStyle.top);
|
||||
@@ -341,6 +355,9 @@ const DashboardEditor: React.FC = () => {
|
||||
const blockToDrag = document.querySelector(`[data-block-id="${draggingBlock}"]`) as HTMLElement;
|
||||
|
||||
if (blockToDrag) {
|
||||
// Re-enable transitions
|
||||
blockToDrag.classList.remove("no-transition");
|
||||
|
||||
const computedStyle = window.getComputedStyle(blockToDrag);
|
||||
const x = parseFloat(computedStyle.left);
|
||||
const y = parseFloat(computedStyle.top);
|
||||
@@ -355,6 +372,9 @@ const DashboardEditor: React.FC = () => {
|
||||
const blockElement = document.querySelector(`[data-block-id="${selectedBlock}"]`) as HTMLElement;
|
||||
|
||||
if (elementToResize && blockElement) {
|
||||
// Re-enable transitions
|
||||
elementToResize.classList.remove("no-transition");
|
||||
|
||||
const computedStyle = window.getComputedStyle(elementToResize);
|
||||
const width = parseFloat(computedStyle.width);
|
||||
const height = parseFloat(computedStyle.height);
|
||||
@@ -367,6 +387,9 @@ const DashboardEditor: React.FC = () => {
|
||||
// Update backend for block resize
|
||||
const blockToResize = document.querySelector(`[data-block-id="${resizingBlock}"]`) as HTMLElement;
|
||||
if (blockToResize) {
|
||||
// Re-enable transitions
|
||||
blockToResize.classList.remove("no-transition");
|
||||
|
||||
const computedStyle = window.getComputedStyle(blockToResize);
|
||||
const width = parseFloat(computedStyle.width);
|
||||
const height = parseFloat(computedStyle.height);
|
||||
@@ -638,7 +661,6 @@ const DashboardEditor: React.FC = () => {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,24 +14,10 @@ interface ElementComponentProps {
|
||||
handleElementResizeStart: (elementId: string, event: React.MouseEvent) => void;
|
||||
}
|
||||
|
||||
const ElementComponent: React.FC<ElementComponentProps> = ({
|
||||
element,
|
||||
blockId,
|
||||
editMode,
|
||||
selectedElement,
|
||||
handleElementClick,
|
||||
handleElementDragStart,
|
||||
handleElementResizeStart,
|
||||
}) => {
|
||||
const ElementComponent: React.FC<ElementComponentProps> = ({ 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<ElementComponentProps> = ({
|
||||
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<ElementComponentProps> = ({
|
||||
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);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ElementContent element={element} resolvedData={resolveElementValue(element)} />
|
||||
|
||||
{editMode && (
|
||||
{editMode && isSelected && (
|
||||
<>
|
||||
<div
|
||||
className="resize-handle"
|
||||
onMouseDown={(e) => handleElementResizeStart(element.elementUuid, e)}
|
||||
>
|
||||
<div className="resize-handle" onMouseDown={(e) => handleElementResizeStart(element.elementUuid, e)}>
|
||||
<ResizeIcon />
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
import React, { RefObject, useEffect, useState } from "react";
|
||||
import DataSourceSelector from "../../../ui/inputs/DataSourceSelector";
|
||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||
import {
|
||||
AlignJustifyIcon,
|
||||
AlignLeftIcon,
|
||||
AlignRightIcon,
|
||||
ArrowIcon,
|
||||
FlexColumnIcon,
|
||||
FlexRowIcon,
|
||||
FlexRowReverseIcon,
|
||||
} from "../../../icons/ExportCommonIcons";
|
||||
import { AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, ArrowIcon, FlexColumnIcon, FlexRowIcon, FlexRowReverseIcon } from "../../../icons/ExportCommonIcons";
|
||||
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||
import InputRange from "../../../ui/inputs/InputRange";
|
||||
import { getAlphaFromRgba, hexToRgba, rgbaToHex } from "../../functions/helpers/colorHandlers";
|
||||
@@ -25,35 +17,15 @@ interface ElementDesignProps {
|
||||
selectedBlock: string;
|
||||
selectedElement: string;
|
||||
updateElementStyle: (blockId: string, elementId: string, style: ExtendedCSSProperties) => void;
|
||||
updateElementSize: (
|
||||
blockId: string,
|
||||
elementId: string,
|
||||
size: { width: number; height: number }
|
||||
) => void;
|
||||
updateElementPosition: (
|
||||
blockId: string,
|
||||
elementId: string,
|
||||
position: { x: number; y: number }
|
||||
) => void;
|
||||
updateElementPositionType: (
|
||||
blockId: string,
|
||||
elementId: string,
|
||||
positionType: "relative" | "absolute" | "fixed"
|
||||
) => void;
|
||||
updateElementSize: (blockId: string, elementId: string, size: { width: number; height: number }) => void;
|
||||
updateElementPosition: (blockId: string, elementId: string, position: { x: number; y: number }) => void;
|
||||
updateElementPositionType: (blockId: string, elementId: string, positionType: "relative" | "absolute" | "fixed") => void;
|
||||
updateElementZIndex: (blockId: string, elementId: string, zIndex: number) => void;
|
||||
updateElementData: (
|
||||
blockId: string,
|
||||
elementId: string,
|
||||
updates: Partial<ElementDataBinding>
|
||||
) => void;
|
||||
updateElementData: (blockId: string, elementId: string, updates: Partial<ElementDataBinding>) => void;
|
||||
updateGraphData: (blockId: string, elementId: string, newData: GraphDataPoint[]) => void;
|
||||
updateGraphTitle: (blockId: string, elementId: string, title: string) => void;
|
||||
updateGraphType: (blockId: string, elementId: string, type: GraphTypes) => void;
|
||||
updateDataType: (
|
||||
blockId: string,
|
||||
elementId: string,
|
||||
dataType: "single-machine" | "multiple-machine"
|
||||
) => void;
|
||||
updateDataType: (blockId: string, elementId: string, dataType: "single-machine" | "multiple-machine") => void;
|
||||
updateCommonValue: (blockId: string, elementId: string, commonValue: string) => void;
|
||||
updateDataValue: (blockId: string, elementId: string, dataValue: string | string[]) => void;
|
||||
updateDataSource: (blockId: string, elementId: string, dataSource: string | string[]) => void;
|
||||
@@ -77,9 +49,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
const [color, setColor] = useState("#000000");
|
||||
|
||||
useEffect(() => {
|
||||
setColor(
|
||||
rgbaToHex(getCurrentElementStyleValue(currentElement, "backgroundColor") || "#000000")
|
||||
);
|
||||
setColor(rgbaToHex(getCurrentElementStyleValue(currentElement, "backgroundColor") || "#000000"));
|
||||
}, [currentElement]);
|
||||
|
||||
return (
|
||||
@@ -96,11 +66,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
{ id: "radar", label: "Radar Chart" },
|
||||
]}
|
||||
onSelect={(newValue) => {
|
||||
updateGraphType(
|
||||
selectedBlock,
|
||||
selectedElement,
|
||||
newValue.id as GraphTypes
|
||||
);
|
||||
updateGraphType(selectedBlock, selectedElement, newValue.id as GraphTypes);
|
||||
}}
|
||||
showEyeDropper={false}
|
||||
/>
|
||||
@@ -113,15 +79,8 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
{["relative", "absolute"].map((position) => (
|
||||
<div
|
||||
key={position}
|
||||
className={`type ${currentElement.positionType === position ? "active" : ""
|
||||
}`}
|
||||
onClick={() =>
|
||||
updateElementPositionType(
|
||||
selectedBlock,
|
||||
selectedElement,
|
||||
position as "relative" | "absolute" | "fixed"
|
||||
)
|
||||
}
|
||||
className={`type ${currentElement.positionType === position ? "active" : ""}`}
|
||||
onClick={() => updateElementPositionType(selectedBlock, selectedElement, position as "relative" | "absolute" | "fixed")}
|
||||
>
|
||||
{position.charAt(0).toUpperCase() + position.slice(1)}
|
||||
</div>
|
||||
@@ -130,48 +89,16 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<div className="position-canvas">
|
||||
<div className="canvas">
|
||||
<div className="value padding-top">
|
||||
<RenameInput
|
||||
value={
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
? String(
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
)
|
||||
: "120"
|
||||
}
|
||||
/>
|
||||
<RenameInput value={getCurrentElementStyleValue(currentElement, "padding") ? String(getCurrentElementStyleValue(currentElement, "padding")) : "120"} />
|
||||
</div>
|
||||
<div className="value padding-right">
|
||||
<RenameInput
|
||||
value={
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
? String(
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
)
|
||||
: "120"
|
||||
}
|
||||
/>
|
||||
<RenameInput value={getCurrentElementStyleValue(currentElement, "padding") ? String(getCurrentElementStyleValue(currentElement, "padding")) : "120"} />
|
||||
</div>
|
||||
<div className="value padding-bottom">
|
||||
<RenameInput
|
||||
value={
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
? String(
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
)
|
||||
: "120"
|
||||
}
|
||||
/>
|
||||
<RenameInput value={getCurrentElementStyleValue(currentElement, "padding") ? String(getCurrentElementStyleValue(currentElement, "padding")) : "120"} />
|
||||
</div>
|
||||
<div className="value padding-left">
|
||||
<RenameInput
|
||||
value={
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
? String(
|
||||
getCurrentElementStyleValue(currentElement, "padding")
|
||||
)
|
||||
: "120"
|
||||
}
|
||||
/>
|
||||
<RenameInput value={getCurrentElementStyleValue(currentElement, "padding") ? String(getCurrentElementStyleValue(currentElement, "padding")) : "120"} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -179,10 +106,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<div className="alignments-section">
|
||||
<div className="section">
|
||||
<div
|
||||
className={`icon ${getCurrentElementStyleValue(currentElement, "textAlign") === "right"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${getCurrentElementStyleValue(currentElement, "textAlign") === "right" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
textAlign: "right",
|
||||
@@ -192,11 +116,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<AlignRightIcon />
|
||||
</div>
|
||||
<div
|
||||
className={`icon ${getCurrentElementStyleValue(currentElement, "textAlign") ===
|
||||
"justify"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${getCurrentElementStyleValue(currentElement, "textAlign") === "justify" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
textAlign: "justify",
|
||||
@@ -206,10 +126,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<AlignJustifyIcon />
|
||||
</div>
|
||||
<div
|
||||
className={`icon ${getCurrentElementStyleValue(currentElement, "textAlign") === "left"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${getCurrentElementStyleValue(currentElement, "textAlign") === "left" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
textAlign: "left",
|
||||
@@ -221,10 +138,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
</div>
|
||||
<div className="section">
|
||||
<div
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") === "row"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") === "row" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
flexDirection: "row",
|
||||
@@ -234,11 +148,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<FlexRowIcon />
|
||||
</div>
|
||||
<div
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") ===
|
||||
"column"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") === "column" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
flexDirection: "column",
|
||||
@@ -248,11 +158,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<FlexColumnIcon />
|
||||
</div>
|
||||
<div
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") ===
|
||||
"row-reverse"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") === "row-reverse" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
flexDirection: "row-reverse",
|
||||
@@ -262,11 +168,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<FlexRowReverseIcon />
|
||||
</div>
|
||||
<div
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") ===
|
||||
"column-reverse"
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
className={`icon ${((currentElement.style.flexDirection as string) || "row") === "column-reverse" ? "active" : ""}`}
|
||||
onClick={() =>
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
flexDirection: "column-reverse",
|
||||
@@ -283,22 +185,12 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
label="Layer"
|
||||
value={String(currentElement.zIndex || 1)}
|
||||
placeholder={"Layer"}
|
||||
onChange={(newValue: string) =>
|
||||
updateElementZIndex(
|
||||
selectedBlock,
|
||||
selectedElement,
|
||||
Number(newValue)
|
||||
)
|
||||
}
|
||||
onChange={(newValue: string) => updateElementZIndex(selectedBlock, selectedElement, Number(newValue))}
|
||||
/>
|
||||
<button
|
||||
className="increase-z"
|
||||
onClick={() => {
|
||||
updateElementZIndex(
|
||||
selectedBlock,
|
||||
selectedElement,
|
||||
Number(currentElement.zIndex ? currentElement.zIndex + 1 : 1)
|
||||
);
|
||||
updateElementZIndex(selectedBlock, selectedElement, Number(currentElement.zIndex ? currentElement.zIndex + 1 : 1));
|
||||
}}
|
||||
>
|
||||
<ArrowIcon />
|
||||
@@ -306,11 +198,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
<button
|
||||
className="decrease-z"
|
||||
onClick={() => {
|
||||
updateElementZIndex(
|
||||
selectedBlock,
|
||||
selectedElement,
|
||||
Number(currentElement.zIndex ? currentElement.zIndex - 1 : 1)
|
||||
);
|
||||
updateElementZIndex(selectedBlock, selectedElement, Number(currentElement.zIndex ? currentElement.zIndex - 1 : 1));
|
||||
}}
|
||||
>
|
||||
<ArrowIcon />
|
||||
@@ -354,10 +242,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Width"
|
||||
value={String(
|
||||
currentElement.size?.width ??
|
||||
(currentElement.type === "graph" ? 400 : 200)
|
||||
)}
|
||||
value={String(currentElement.size?.width ?? (currentElement.type === "graph" ? 400 : 200))}
|
||||
placeholder={"Width"}
|
||||
onChange={(newValue: string) => {
|
||||
updateElementSize(selectedBlock, selectedElement, {
|
||||
@@ -368,10 +253,7 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
/>
|
||||
<InputWithDropDown
|
||||
label="Height"
|
||||
value={String(
|
||||
currentElement.size?.height ??
|
||||
(currentElement.type === "graph" ? 200 : 60)
|
||||
)}
|
||||
value={String(currentElement.size?.height ?? (currentElement.type === "graph" ? 200 : 60))}
|
||||
placeholder={"Height"}
|
||||
onChange={(newValue: string) => {
|
||||
updateElementSize(selectedBlock, selectedElement, {
|
||||
@@ -381,6 +263,17 @@ const ElementDesign: React.FC<ElementDesignProps> = ({
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<InputRange
|
||||
label={"Border Radius"}
|
||||
min={0}
|
||||
max={8}
|
||||
value={parseInt(getCurrentElementStyleValue(currentElement, "borderRadius") || "") || 8}
|
||||
onChange={(newValue: number) => {
|
||||
updateElementStyle(selectedBlock, selectedElement, {
|
||||
borderRadius: Number(newValue),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="design-section element-color">
|
||||
|
||||
@@ -187,6 +187,9 @@ function Analyzer() {
|
||||
// Track previous actions for ArmBots to detect cycle completion
|
||||
const previousArmBotActionsRef = useRef<Record<string, string | undefined>>({});
|
||||
|
||||
// Track previous actions for Machines to detect cycle completion
|
||||
const previousMachineActionsRef = useRef<Record<string, string | undefined>>({});
|
||||
|
||||
// Track previous action counts for Humans to detect completion from EventManager
|
||||
const previousHumanCountsRef = useRef<Record<string, Record<string, number>>>({});
|
||||
|
||||
@@ -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
|
||||
@@ -1722,8 +1726,8 @@ function Analyzer() {
|
||||
|
||||
// Success rates
|
||||
const liftAttempts = totalLifts + errorCount;
|
||||
const liftSuccessRate = liftAttempts > 0 ? (totalLifts / liftAttempts) * 100 : 100;
|
||||
const positioningAccuracy = liftSuccessRate * 0.98; // Slightly lower than success rate
|
||||
const liftSuccessRate = liftAttempts > 0 ? (totalLifts / liftAttempts) * 100 : 0;
|
||||
const positioningAccuracy = totalLifts > 0 ? liftSuccessRate * 1.0 : 0; // Slightly lower than success rate
|
||||
|
||||
// Load utilization
|
||||
const maxPickUpCount = crane.point?.actions?.[0]?.maxPickUpCount || 1;
|
||||
@@ -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;
|
||||
@@ -2499,22 +2530,6 @@ function Analyzer() {
|
||||
const previousPhase = previousCranePhasesRef.current[crane.modelUuid];
|
||||
const currentPhase = crane.currentPhase;
|
||||
|
||||
// Check for transition from 'pickup-drop' to 'init' (Cycle completed)
|
||||
if (previousPhase === "pickup-drop" && currentPhase === "init") {
|
||||
// Increment cycles completed
|
||||
if (!completedActionsRef.current[crane.modelUuid]) {
|
||||
completedActionsRef.current[crane.modelUuid] = 0;
|
||||
}
|
||||
completedActionsRef.current[crane.modelUuid]++;
|
||||
|
||||
// Track loads handled (number of materials carried in this cycle)
|
||||
const loadsInCycle = crane.currentMaterials?.length || 1;
|
||||
if (!completedActionsRef.current[`${crane.modelUuid}_loads`]) {
|
||||
completedActionsRef.current[`${crane.modelUuid}_loads`] = 0;
|
||||
}
|
||||
completedActionsRef.current[`${crane.modelUuid}_loads`] += loadsInCycle;
|
||||
}
|
||||
|
||||
// Track lifts (picking phase indicates a lift operation)
|
||||
if (previousPhase !== "picking" && currentPhase === "picking") {
|
||||
if (!completedActionsRef.current[`${crane.modelUuid}_lifts`]) {
|
||||
@@ -2528,6 +2543,21 @@ function Analyzer() {
|
||||
completedActionsRef.current[`${crane.modelUuid}_lift_height`] = 0;
|
||||
}
|
||||
completedActionsRef.current[`${crane.modelUuid}_lift_height`] += 5;
|
||||
|
||||
// Track loads handled when picking (each pick is a load)
|
||||
if (!completedActionsRef.current[`${crane.modelUuid}_loads`]) {
|
||||
completedActionsRef.current[`${crane.modelUuid}_loads`] = 0;
|
||||
}
|
||||
completedActionsRef.current[`${crane.modelUuid}_loads`]++;
|
||||
}
|
||||
|
||||
// Track cycles completed when dropping is done (transition from 'dropping' to any other phase)
|
||||
if (previousPhase === "dropping" && currentPhase !== "dropping") {
|
||||
// Increment cycles completed
|
||||
if (!completedActionsRef.current[crane.modelUuid]) {
|
||||
completedActionsRef.current[crane.modelUuid] = 0;
|
||||
}
|
||||
completedActionsRef.current[crane.modelUuid]++;
|
||||
}
|
||||
|
||||
previousCranePhasesRef.current[crane.modelUuid] = currentPhase;
|
||||
|
||||
@@ -25,7 +25,7 @@ function Simulation() {
|
||||
const { analysis } = analysisStore();
|
||||
|
||||
useEffect(() => {
|
||||
console.log("analysis: ", analysis);
|
||||
// console.log("analysis: ", analysis);
|
||||
}, [analysis]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
|
||||
// Utility class to disable transitions during drag/resize
|
||||
.no-transition,
|
||||
.no-transition * {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
*> {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import { useSceneContext } from "../../modules/scene/sceneContext";
|
||||
const KeyPressListener: React.FC = () => {
|
||||
const { comparisonScene, clearComparisonState } = useSimulationState();
|
||||
const { activeModule, setActiveModule } = useModuleStore();
|
||||
const { assetStore, versionStore } = useSceneContext();
|
||||
const { assetStore, versionStore, simulationDashBoardStore } = useSceneContext();
|
||||
const { selectedAssets } = assetStore();
|
||||
const { setSubModule } = useSubModuleStore();
|
||||
const { setActiveSubTool } = useActiveSubTool();
|
||||
@@ -46,6 +46,7 @@ const KeyPressListener: React.FC = () => {
|
||||
const { setSelectedComment } = useSelectedComment();
|
||||
const { setDfxUploaded } = useDfxUpload();
|
||||
const isTextInput = (element: Element | null): boolean => element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element?.getAttribute("contenteditable") === "true";
|
||||
const { setSelectedBlock, setSelectedElement } = simulationDashBoardStore();
|
||||
|
||||
const handleModuleSwitch = (keyCombination: string) => {
|
||||
const modules: Record<string, string> = {
|
||||
@@ -189,6 +190,8 @@ const KeyPressListener: React.FC = () => {
|
||||
setIsRenameMode(false);
|
||||
setDfxUploaded([]);
|
||||
setSelectedComment(null);
|
||||
setSelectedBlock(null);
|
||||
setSelectedElement(null);
|
||||
}
|
||||
|
||||
if (!keyCombination || ["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") return;
|
||||
|
||||
Reference in New Issue
Block a user