diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/EventProperties.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/EventProperties.tsx index 87d3bf6..4fa9105 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/EventProperties.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/EventProperties.tsx @@ -1,9 +1,8 @@ import React, { useEffect, useState } from "react"; import { - useSelectedAsset, - useSelectedEventData, - useSelectedEventSphere, - useSelectedProduct, + useSelectedEventData, + useSelectedEventSphere, + useSelectedProduct, } from "../../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore"; import ConveyorMechanics from "./mechanics/conveyorMechanics"; @@ -13,120 +12,117 @@ import MachineMechanics from "./mechanics/machineMechanics"; import StorageMechanics from "./mechanics/storageMechanics"; import { AddIcon } from "../../../../icons/ExportCommonIcons"; import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct"; +import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; const EventProperties: React.FC = () => { - const { selectedEventData } = useSelectedEventData(); - const { getEventByModelUuid } = useProductStore(); - const { selectedProduct } = useSelectedProduct(); - const [currentEventData, setCurrentEventData] = useState( - null - ); - const [assetType, setAssetType] = useState(null); - const { products, addEvent } = useProductStore(); - const { selectedEventSphere } = useSelectedEventSphere(); + const { selectedEventData } = useSelectedEventData(); + const { getEventByModelUuid } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); + const [currentEventData, setCurrentEventData] = useState(null); + const [assetType, setAssetType] = useState(null); + const { products, addEvent } = useProductStore(); + const { selectedEventSphere } = useSelectedEventSphere(); - const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); - useEffect(() => { - const event = getCurrentEventData(); - setCurrentEventData(event); + useEffect(() => { + const event = getCurrentEventData(); + setCurrentEventData(event); - const type = determineAssetType(event); - setAssetType(type); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedEventData, selectedProduct]); + const type = determineAssetType(event); + setAssetType(type); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedEventData, selectedProduct]); + + const getCurrentEventData = () => { + if (!selectedEventData?.data || !selectedProduct) return null; + return ( + getEventByModelUuid( + selectedProduct.productId, + selectedEventData.data.modelUuid + ) ?? null + ); + }; + + const determineAssetType = (event: EventsSchema | null) => { + if (!event) return null; + + switch (event.type) { + case "transfer": + return "conveyor"; + case "vehicle": + return "vehicle"; + case "roboticArm": + return "roboticArm"; + case "machine": + return "machine"; + case "storageUnit": + return "storageUnit"; + default: + return null; + } + }; - const getCurrentEventData = () => { - if (!selectedEventData?.data || !selectedProduct) return null; return ( - getEventByModelUuid( - selectedProduct.productId, - selectedEventData.data.modelUuid - ) ?? null +
+ {currentEventData && ( + <> +
+
+ {selectedEventData?.data.modelName} +
+
+ {assetType === "conveyor" && } + {assetType === "vehicle" && } + {assetType === "roboticArm" && } + {assetType === "machine" && } + {assetType === "storageUnit" && } + + )} + {!currentEventData && selectedEventSphere && ( +
+

+ Oops! It looks like this object doesn't have an + event assigned yet. To continue, please link it to one of the + products below. +

+ +
+

+ Here are some products you can add it to: +

+
    + {products.map((product) => ( +
  • + +
  • + ))} +
+
+
+ ) + } + {!selectedEventSphere && ( +
+

+ Oops! It looks like you haven't selected an event + point yet. Please select an event to view its properties. +

+
+ )} +
); - }; - - const determineAssetType = (event: EventsSchema | null) => { - if (!event) return null; - - switch (event.type) { - case "transfer": - return "conveyor"; - case "vehicle": - return "vehicle"; - case "roboticArm": - return "roboticArm"; - case "machine": - return "machine"; - case "storageUnit": - return "storageUnit"; - default: - return null; - } - }; - - return ( -
- {currentEventData && ( - <> -
-
- {selectedEventData?.data.modelName} -
-
- {assetType === "conveyor" && } - {assetType === "vehicle" && } - {assetType === "roboticArm" && } - {assetType === "machine" && } - {assetType === "storageUnit" && } - - )} - {!currentEventData && selectedEventSphere && ( -
-

- Oops! It looks like this object doesn't have an - event assigned yet. To continue, please link it to one of the - products below. -

- -
-

- Here are some products you can add it to: -

-
    - {products.map((product) => ( -
  • - -
  • - ))} -
-
-
- )} - {!selectedEventSphere && ( -
-

- Oops! It looks like you haven't selected an event - point yet. Please select an event to view its properties. -

-
- )} -
- ); }; export default EventProperties; diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/conveyorMechanics.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/conveyorMechanics.tsx index b370b3e..61c9c6c 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/conveyorMechanics.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/conveyorMechanics.tsx @@ -8,217 +8,193 @@ import SwapAction from "../actions/SwapAction"; import SpawnAction from "../actions/SpawnAction"; import DefaultAction from "../actions/DefaultAction"; import Trigger from "../trigger/Trigger"; -import { - useSelectedEventData, - useSelectedProduct, -} from "../../../../../../store/simulation/useSimulationStore"; +import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import ActionsList from "../components/ActionsList"; function ConveyorMechanics() { - const [activeOption, setActiveOption] = useState< - "default" | "spawn" | "swap" | "delay" | "despawn" - >("default"); - const [selectedPointData, setSelectedPointData] = useState< - ConveyorPointSchema | undefined - >(); - const { selectedEventData } = useSelectedEventData(); - const { getPointByUuid, updateEvent, updateAction } = useProductStore(); - const { selectedProduct } = useSelectedProduct(); + const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default"); + const [selectedPointData, setSelectedPointData] = useState(); + const { selectedEventData } = useSelectedEventData(); + const { getPointByUuid, updateEvent, updateAction } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); - useEffect(() => { - if (selectedEventData) { - const point = getPointByUuid( - selectedProduct.productId, - selectedEventData?.data.modelUuid, - selectedEventData?.selectedPoint - ) as ConveyorPointSchema | undefined; - if (point && "action" in point) { - setSelectedPointData(point); - setActiveOption( - point.action.actionType as - | "default" - | "spawn" - | "swap" - | "delay" - | "despawn" - ); - } - } - }, [selectedProduct, selectedEventData, getPointByUuid]); + useEffect(() => { + if (selectedEventData) { + const point = getPointByUuid( + selectedProduct.productId, + selectedEventData?.data.modelUuid, + selectedEventData?.selectedPoint + ) as ConveyorPointSchema | undefined; + if (point && "action" in point) { + setSelectedPointData(point); + setActiveOption(point.action.actionType as | "default" | "spawn" | "swap" | "delay" | "despawn"); + } + } + }, [selectedProduct, selectedEventData, getPointByUuid]); - const handleSpeedChange = (value: string) => { - if (!selectedEventData) return; - updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, { - speed: parseFloat(value), - }); - }; + const handleSpeedChange = (value: string) => { + if (!selectedEventData) return; + updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, { + speed: parseFloat(value), + }); + }; - const handleActionTypeChange = (option: string) => { - if (!selectedEventData || !selectedPointData) return; - const validOption = option as - | "default" - | "spawn" - | "swap" - | "delay" - | "despawn"; - setActiveOption(validOption); + const handleActionTypeChange = (option: string) => { + if (!selectedEventData || !selectedPointData) return; + const validOption = option as | "default" | "spawn" | "swap" | "delay" | "despawn"; + setActiveOption(validOption); - updateAction(selectedPointData.action.actionUuid, { - actionType: validOption, - }); - }; + updateAction(selectedPointData.action.actionUuid, { + actionType: validOption, + }); + }; - const handleRenameAction = (newName: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { actionName: newName }); - }; + const handleRenameAction = (newName: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { actionName: newName }); + }; - const handleSpawnCountChange = (value: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { - spawnCount: value === "inherit" ? "inherit" : parseFloat(value), - }); - }; + const handleSpawnCountChange = (value: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { + spawnCount: value === "inherit" ? "inherit" : parseFloat(value), + }); + }; - const handleSpawnIntervalChange = (value: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { - spawnInterval: value === "inherit" ? "inherit" : parseFloat(value), - }); - }; + const handleSpawnIntervalChange = (value: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { + spawnInterval: value === "inherit" ? "inherit" : parseFloat(value), + }); + }; - const handleMaterialSelect = (material: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { material }); - }; + const handleMaterialSelect = (material: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { material }); + }; - const handleDelayChange = (value: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { - delay: value === "inherit" ? "inherit" : parseFloat(value), - }); - }; + const handleDelayChange = (value: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { + delay: value === "inherit" ? "inherit" : parseFloat(value), + }); + }; - const availableActions = { - defaultOption: "default", - options: ["default", "spawn", "swap", "delay", "despawn"], - }; + const availableActions = { + defaultOption: "default", + options: ["default", "spawn", "swap", "delay", "despawn"], + }; - // Get current values from store - const currentSpeed = - selectedEventData?.data.type === "transfer" - ? selectedEventData.data.speed.toString() - : "0.5"; + // Get current values from store + const currentSpeed = selectedEventData?.data.type === "transfer" + ? selectedEventData.data.speed.toString() + : "0.5"; - const currentActionName = selectedPointData - ? selectedPointData.action.actionName - : "Action Name"; + const currentActionName = selectedPointData + ? selectedPointData.action.actionName + : "Action Name"; - const currentMaterial = selectedPointData - ? selectedPointData.action.material - : "Default material"; + const currentMaterial = selectedPointData + ? selectedPointData.action.material + : "Default material"; - const currentSpawnCount = selectedPointData - ? selectedPointData.action.spawnCount?.toString() || "1" - : "1"; + const currentSpawnCount = selectedPointData + ? selectedPointData.action.spawnCount?.toString() || "1" + : "1"; - const currentSpawnInterval = selectedPointData - ? selectedPointData.action.spawnInterval?.toString() || "1" - : "1"; + const currentSpawnInterval = selectedPointData + ? selectedPointData.action.spawnInterval?.toString() || "1" + : "1"; - const currentDelay = selectedPointData - ? selectedPointData.action.delay?.toString() || "0" - : "0"; + const currentDelay = selectedPointData + ? selectedPointData.action.delay?.toString() || "0" + : "0"; - return ( - <> - {selectedEventData && ( + return ( <> -
-
-
- {}} - onChange={handleSpeedChange} - /> -
-
-
+ {selectedEventData && ( + <> +
+
+
+ { }} + onChange={handleSpeedChange} + /> +
+
+
- + -
-
- -
-
- - {activeOption === "default" && } - {activeOption === "spawn" && ( - - )} - {activeOption === "swap" && ( - - )} - {activeOption === "despawn" && } - {activeOption === "delay" && ( - - )} -
-
-
- -
+
+
+ +
+
+ + {activeOption === "default" && } + {activeOption === "spawn" && ( + + )} + {activeOption === "swap" && ( + + )} + {activeOption === "despawn" && } + {activeOption === "delay" && ( + + )} +
+
+
+ +
+ + )} - )} - - ); + ); } export default ConveyorMechanics; diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/machineMechanics.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/machineMechanics.tsx index fa2cfdf..8d128af 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/machineMechanics.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/machineMechanics.tsx @@ -2,128 +2,121 @@ import { useEffect, useState } from "react"; import RenameInput from "../../../../../ui/inputs/RenameInput"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import Trigger from "../trigger/Trigger"; -import { - useSelectedEventData, - useSelectedProduct, -} from "../../../../../../store/simulation/useSimulationStore"; +import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import ProcessAction from "../actions/ProcessAction"; import ActionsList from "../components/ActionsList"; function MachineMechanics() { - const [activeOption, setActiveOption] = useState<"default" | "process">( - "default" - ); - const [selectedPointData, setSelectedPointData] = useState< - MachinePointSchema | undefined - >(); - const { selectedEventData } = useSelectedEventData(); - const { getPointByUuid, updateAction } = useProductStore(); - const { selectedProduct } = useSelectedProduct(); + const [activeOption, setActiveOption] = useState<"default" | "process">("default"); + const [selectedPointData, setSelectedPointData] = useState(); + const { selectedEventData } = useSelectedEventData(); + const { getPointByUuid, updateAction } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); - useEffect(() => { - if (selectedEventData) { - const point = getPointByUuid( - selectedProduct.productId, - selectedEventData?.data.modelUuid, - selectedEventData?.selectedPoint - ) as MachinePointSchema | undefined; - if (point && "action" in point) { - setSelectedPointData(point); - setActiveOption(point.action.actionType as "process"); - } - } - }, [selectedProduct, selectedEventData, getPointByUuid]); + useEffect(() => { + if (selectedEventData) { + const point = getPointByUuid( + selectedProduct.productId, + selectedEventData?.data.modelUuid, + selectedEventData?.selectedPoint + ) as MachinePointSchema | undefined; + if (point && "action" in point) { + setSelectedPointData(point); + setActiveOption(point.action.actionType as "process"); + } + } + }, [selectedProduct, selectedEventData, getPointByUuid]); - const handleActionTypeChange = (option: string) => { - if (!selectedEventData || !selectedPointData) return; - const validOption = option as "process"; - setActiveOption(validOption); + const handleActionTypeChange = (option: string) => { + if (!selectedEventData || !selectedPointData) return; + const validOption = option as "process"; + setActiveOption(validOption); - updateAction(selectedPointData.action.actionUuid, { - actionType: validOption, - }); - }; + updateAction(selectedPointData.action.actionUuid, { + actionType: validOption, + }); + }; - const handleRenameAction = (newName: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { actionName: newName }); - }; + const handleRenameAction = (newName: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { actionName: newName }); + }; - const handleProcessTimeChange = (value: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { - processTime: parseFloat(value), - }); - }; + const handleProcessTimeChange = (value: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { + processTime: parseFloat(value), + }); + }; - const handleMaterialSelect = (material: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { - swapMaterial: material, - }); - }; + const handleMaterialSelect = (material: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { + swapMaterial: material, + }); + }; - // Get current values from store - const currentActionName = selectedPointData - ? selectedPointData.action.actionName - : "Action Name"; + // Get current values from store + const currentActionName = selectedPointData + ? selectedPointData.action.actionName + : "Action Name"; - const currentProcessTime = selectedPointData - ? selectedPointData.action.processTime.toString() - : "1"; + const currentProcessTime = selectedPointData + ? selectedPointData.action.processTime.toString() + : "1"; - const currentMaterial = selectedPointData - ? selectedPointData.action.swapMaterial - : "Default material"; + const currentMaterial = selectedPointData + ? selectedPointData.action.swapMaterial + : "Default material"; - const availableActions = { - defaultOption: "process", - options: ["process"], - }; + const availableActions = { + defaultOption: "process", + options: ["process"], + }; - return ( - <> - {selectedEventData && ( + return ( <> -
-
- -
- -
- - {activeOption === "process" && ( - - )} -
-
-
- -
+ {selectedEventData && ( + <> +
+
+ +
+ +
+ + {activeOption === "process" && ( + + )} +
+
+
+ +
+ + )} - )} - - ); + ); } export default MachineMechanics; diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/roboticArmMechanics.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/roboticArmMechanics.tsx index 7c20ce5..811a676 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/roboticArmMechanics.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/roboticArmMechanics.tsx @@ -3,192 +3,164 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown"; import RenameInput from "../../../../../ui/inputs/RenameInput"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import Trigger from "../trigger/Trigger"; -import { - useSelectedEventData, - useSelectedProduct, - useSelectedAction, -} from "../../../../../../store/simulation/useSimulationStore"; +import { useSelectedEventData, useSelectedProduct, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import PickAndPlaceAction from "../actions/PickAndPlaceAction"; import ActionsList from "../components/ActionsList"; function RoboticArmMechanics() { - const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">( - "default" - ); - const [selectedPointData, setSelectedPointData] = useState< - RoboticArmPointSchema | undefined - >(); - const { selectedEventData } = useSelectedEventData(); - const { getPointByUuid, updateEvent, updateAction } = useProductStore(); - const { selectedProduct } = useSelectedProduct(); - const { selectedAction, setSelectedAction, clearSelectedAction } = - useSelectedAction(); + const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default"); + const [selectedPointData, setSelectedPointData] = useState(); + const { selectedEventData } = useSelectedEventData(); + const { getPointByUuid, updateEvent, updateAction } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); + const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction(); - useEffect(() => { - if (selectedEventData) { - const point = getPointByUuid( - selectedProduct.productId, - selectedEventData.data.modelUuid, - selectedEventData.selectedPoint - ) as RoboticArmPointSchema | undefined; - if (point?.actions) { - setSelectedPointData(point); - setActiveOption( - point.actions[0].actionType as "default" | "pickAndPlace" - ); - if (point.actions.length > 0 && !selectedAction.actionId) { - setSelectedAction( - point.actions[0].actionUuid, - point.actions[0].actionName - ); + useEffect(() => { + if (selectedEventData) { + const point = getPointByUuid( + selectedProduct.productId, + selectedEventData.data.modelUuid, + selectedEventData.selectedPoint + ) as RoboticArmPointSchema | undefined; + if (point?.actions) { + setSelectedPointData(point); + setActiveOption(point.actions[0].actionType as "default" | "pickAndPlace"); + if (point.actions.length > 0 && !selectedAction.actionId) { + setSelectedAction( + point.actions[0].actionUuid, + point.actions[0].actionName + ); + } + } + } else { + clearSelectedAction(); } - } - } else { - clearSelectedAction(); - } - }, [ - clearSelectedAction, - getPointByUuid, - selectedAction.actionId, - selectedEventData, - selectedProduct, - setSelectedAction, - ]); + }, [clearSelectedAction, getPointByUuid, selectedAction.actionId, selectedEventData, selectedProduct, setSelectedAction,]); - const handleRenameAction = (newName: string) => { - if (!selectedAction.actionId) return; - updateAction(selectedAction.actionId, { actionName: newName }); + const handleRenameAction = (newName: string) => { + if (!selectedAction.actionId) return; + updateAction(selectedAction.actionId, { actionName: newName }); - if (selectedPointData) { - const updatedActions = selectedPointData.actions.map((action) => - action.actionUuid === selectedAction.actionId - ? { ...action, actionName: newName } - : action - ); - setSelectedPointData({ - ...selectedPointData, - actions: updatedActions, - }); - } - }; + if (selectedPointData) { + const updatedActions = selectedPointData.actions.map((action) => + action.actionUuid === selectedAction.actionId ? { ...action, actionName: newName } : action + ); + setSelectedPointData({ + ...selectedPointData, + actions: updatedActions, + }); + } + }; - const handleSpeedChange = (value: string) => { - if (!selectedEventData) return; - updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, { - speed: parseFloat(value), - }); - }; + const handleSpeedChange = (value: string) => { + if (!selectedEventData) return; + updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, { + speed: parseFloat(value), + }); + }; - const handlePickPointChange = (value: string) => { - if (!selectedAction.actionId || !selectedPointData) return; - const [x, y, z] = value.split(",").map(Number); + const handlePickPointChange = (value: string) => { + if (!selectedAction.actionId || !selectedPointData) return; + const [x, y, z] = value.split(",").map(Number); - updateAction(selectedAction.actionId, { - process: { - startPoint: [x, y, z] as [number, number, number], - endPoint: - selectedPointData.actions.find( - (a) => a.actionUuid === selectedAction.actionId - )?.process.endPoint || null, - }, - }); - }; + updateAction(selectedAction.actionId, { + process: { + startPoint: [x, y, z] as [number, number, number], + endPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.endPoint || null, + }, + }); + }; - const handlePlacePointChange = (value: string) => { - if (!selectedAction.actionId || !selectedPointData) return; - const [x, y, z] = value.split(",").map(Number); + const handlePlacePointChange = (value: string) => { + if (!selectedAction.actionId || !selectedPointData) return; + const [x, y, z] = value.split(",").map(Number); - updateAction(selectedAction.actionId, { - process: { - startPoint: - selectedPointData.actions.find( - (a) => a.actionUuid === selectedAction.actionId - )?.process.startPoint || null, - endPoint: [x, y, z] as [number, number, number], - }, - }); - }; + updateAction(selectedAction.actionId, { + process: { + startPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.startPoint || null, + endPoint: [x, y, z] as [number, number, number], + }, + }); + }; - const availableActions = { - defaultOption: "pickAndPlace", - options: ["pickAndPlace"], - }; + const availableActions = { + defaultOption: "pickAndPlace", + options: ["pickAndPlace"], + }; - const currentSpeed = - selectedEventData?.data.type === "roboticArm" - ? selectedEventData.data.speed.toString() - : "0.5"; + const currentSpeed = selectedEventData?.data.type === "roboticArm" + ? selectedEventData.data.speed.toString() + : "0.5"; - const currentAction = selectedPointData?.actions.find( - (a) => a.actionUuid === selectedAction.actionId - ); - const currentPickPoint = currentAction?.process.startPoint - ? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}` - : ""; - const currentPlacePoint = currentAction?.process.endPoint - ? `${currentAction.process.endPoint[0]},${currentAction.process.endPoint[1]},${currentAction.process.endPoint[2]}` - : ""; + const currentAction = selectedPointData?.actions.find((a) => a.actionUuid === selectedAction.actionId); - return ( - <> - {selectedEventData && selectedPointData && ( + const currentPickPoint = currentAction?.process.startPoint + ? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}` + : ""; + const currentPlacePoint = currentAction?.process.endPoint + ? `${currentAction.process.endPoint[0]},${currentAction.process.endPoint[1]},${currentAction.process.endPoint[2]}` + : ""; + + return ( <> -
-
-
- {}} - onChange={handleSpeedChange} - /> -
-
-
+ {selectedEventData && selectedPointData && ( + <> +
+
+
+ { }} + onChange={handleSpeedChange} + /> +
+
+
- + - {selectedAction.actionId && currentAction && ( -
-
- -
-
- {}} - disabled={true} - /> - -
-
- -
-
- )} + {selectedAction.actionId && currentAction && ( +
+
+ +
+
+ { }} + disabled={true} + /> + +
+
+ +
+
+ )} + + )} - )} - - ); + ); } export default RoboticArmMechanics; diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/storageMechanics.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/storageMechanics.tsx index d92ed80..b295519 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/storageMechanics.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/storageMechanics.tsx @@ -2,119 +2,112 @@ import { useEffect, useState } from "react"; import RenameInput from "../../../../../ui/inputs/RenameInput"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import Trigger from "../trigger/Trigger"; -import { - useSelectedEventData, - useSelectedProduct, -} from "../../../../../../store/simulation/useSimulationStore"; +import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import StorageAction from "../actions/StorageAction"; import ActionsList from "../components/ActionsList"; function StorageMechanics() { - const [activeOption, setActiveOption] = useState< - "default" | "store" | "spawn" - >("default"); - const [selectedPointData, setSelectedPointData] = useState< - StoragePointSchema | undefined - >(); - const { selectedEventData } = useSelectedEventData(); - const { getPointByUuid, updateAction } = useProductStore(); - const { selectedProduct } = useSelectedProduct(); + const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default"); + const [selectedPointData, setSelectedPointData] = useState(); + const { selectedEventData } = useSelectedEventData(); + const { getPointByUuid, updateAction } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); - useEffect(() => { - if (selectedEventData) { - const point = getPointByUuid( - selectedProduct.productId, - selectedEventData?.data.modelUuid, - selectedEventData?.selectedPoint - ) as StoragePointSchema | undefined; - if (point && "action" in point) { - setSelectedPointData(point); - setActiveOption(point.action.actionType as "store" | "spawn"); - } - } - }, [selectedProduct, selectedEventData, getPointByUuid]); + useEffect(() => { + if (selectedEventData) { + const point = getPointByUuid( + selectedProduct.productId, + selectedEventData?.data.modelUuid, + selectedEventData?.selectedPoint + ) as StoragePointSchema | undefined; + if (point && "action" in point) { + setSelectedPointData(point); + setActiveOption(point.action.actionType as "store" | "spawn"); + } + } + }, [selectedProduct, selectedEventData, getPointByUuid]); - const handleActionTypeChange = (option: string) => { - if (!selectedEventData || !selectedPointData) return; - const validOption = option as "store" | "spawn"; - setActiveOption(validOption); + const handleActionTypeChange = (option: string) => { + if (!selectedEventData || !selectedPointData) return; + const validOption = option as "store" | "spawn"; + setActiveOption(validOption); - updateAction(selectedPointData.action.actionUuid, { - actionType: validOption, - }); - }; + updateAction(selectedPointData.action.actionUuid, { + actionType: validOption, + }); + }; - const handleRenameAction = (newName: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { actionName: newName }); - }; + const handleRenameAction = (newName: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { actionName: newName }); + }; - const handleCapacityChange = (value: string) => { - if (!selectedPointData) return; - updateAction(selectedPointData.action.actionUuid, { - storageCapacity: parseInt(value), - }); - }; + const handleCapacityChange = (value: string) => { + if (!selectedPointData) return; + updateAction(selectedPointData.action.actionUuid, { + storageCapacity: parseInt(value), + }); + }; - // Get current values from store - const currentActionName = selectedPointData - ? selectedPointData.action.actionName - : "Action Name"; + // Get current values from store + const currentActionName = selectedPointData + ? selectedPointData.action.actionName + : "Action Name"; - const currentCapacity = selectedPointData - ? selectedPointData.action.storageCapacity.toString() - : "0"; + const currentCapacity = selectedPointData + ? selectedPointData.action.storageCapacity.toString() + : "0"; - const availableActions = { - defaultOption: "store", - options: ["store", "spawn"], - }; + const availableActions = { + defaultOption: "store", + options: ["store", "spawn"], + }; - return ( - <> - {selectedEventData && ( + return ( <> - -
-
- -
-
- - {activeOption === "store" && ( - - )} - {activeOption === "spawn" && ( -
-

Spawn configuration options would go here

-
- )} -
-
-
- -
+ {selectedEventData && ( + <> + +
+
+ +
+
+ + {activeOption === "store" && ( + + )} + {activeOption === "spawn" && ( +
+

Spawn configuration options would go here

+
+ )} +
+
+
+ +
+ + )} - )} - - ); + ); } export default StorageMechanics; diff --git a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx index b037098..ca29087 100644 --- a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx +++ b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx @@ -1,216 +1,216 @@ -import React, { useEffect, useRef } from "react"; +import React, { useRef } from "react"; import { - AddIcon, - ArrowIcon, - RemoveIcon, - ResizeHeightIcon, + AddIcon, + ArrowIcon, + RemoveIcon, + ResizeHeightIcon, } from "../../../icons/ExportCommonIcons"; import RenameInput from "../../../ui/inputs/RenameInput"; import { handleResize } from "../../../../functions/handleResizePannel"; import { - useSelectedAsset, - useSelectedProduct, + useSelectedAsset, + useSelectedProduct, } from "../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../store/simulation/useProductStore"; import { generateUUID } from "three/src/math/MathUtils"; import RenderOverlay from "../../../templates/Overlay"; import EditWidgetOption from "../../../ui/menu/EditWidgetOption"; -import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi"; import { handleAddEventToProduct } from "../../../../modules/simulation/events/points/functions/handleAddEventToProduct"; +import { useEventsStore } from "../../../../store/simulation/useEventsStore"; +import { deleteEventDataApi } from "../../../../services/simulation/deleteEventDataApi"; interface Event { - pathName: string; + pathName: string; } interface ListProps { - val: Event; + val: Event; } const List: React.FC = ({ val }) => { - return ( -
-
{val.pathName}
-
- ); + return ( +
+
{val.pathName}
+
+ ); }; const Simulations: React.FC = () => { - const productsContainerRef = useRef(null); - const { - products, - addProduct, - removeProduct, - renameProduct, - addEvent, - removeEvent, - } = useProductStore(); - const { selectedProduct, setSelectedProduct } = useSelectedProduct(); - const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); + const productsContainerRef = useRef(null); + const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, } = useProductStore(); + const { selectedProduct, setSelectedProduct } = useSelectedProduct(); + const { getEventByModelUuid } = useEventsStore(); + const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); - const handleAddProduct = () => { - addProduct(`Product ${products.length + 1}`, generateUUID()); - }; + const handleAddProduct = () => { + addProduct(`Product ${products.length + 1}`, generateUUID()); + }; - const handleRemoveProduct = (productId: string) => { - const currentIndex = products.findIndex((p) => p.productId === productId); - const isSelected = selectedProduct.productId === productId; + const handleRemoveProduct = (productId: string) => { + const currentIndex = products.findIndex((p) => p.productId === productId); + const isSelected = selectedProduct.productId === productId; - const updatedProducts = products.filter((p) => p.productId !== productId); + const updatedProducts = products.filter((p) => p.productId !== productId); - if (isSelected) { - if (updatedProducts.length > 0) { - let newSelectedIndex = currentIndex; - if (currentIndex >= updatedProducts.length) { - newSelectedIndex = updatedProducts.length - 1; + if (isSelected) { + if (updatedProducts.length > 0) { + let newSelectedIndex = currentIndex; + if (currentIndex >= updatedProducts.length) { + newSelectedIndex = updatedProducts.length - 1; + } + setSelectedProduct( + updatedProducts[newSelectedIndex].productId, + updatedProducts[newSelectedIndex].productName + ); + } else { + setSelectedProduct("", ""); + } } - setSelectedProduct( - updatedProducts[newSelectedIndex].productId, - updatedProducts[newSelectedIndex].productName - ); - } else { - setSelectedProduct("", ""); - } - } - removeProduct(productId); - }; + removeProduct(productId); + }; - const handleRenameProduct = (productId: string, newName: string) => { - renameProduct(productId, newName); - if (selectedProduct.productId === productId) { - setSelectedProduct(productId, newName); - } - }; + const handleRenameProduct = (productId: string, newName: string) => { + renameProduct(productId, newName); + if (selectedProduct.productId === productId) { + setSelectedProduct(productId, newName); + } + }; - const handleRemoveEventFromProduct = () => { - if (selectedAsset) { - removeEvent(selectedProduct.productId, selectedAsset.modelUuid); - clearSelectedAsset(); - } - }; + const handleRemoveEventFromProduct = () => { + if (selectedAsset) { + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + deleteEventDataApi({ + productId: selectedProduct.productId, + modelUuid: selectedAsset.modelUuid, + organization: organization + }); + removeEvent(selectedProduct.productId, selectedAsset.modelUuid); + clearSelectedAsset(); + } + }; - const selectedProductData = products.find( - (product) => product.productId === selectedProduct.productId - ); + const selectedProductData = products.find( + (product) => product.productId === selectedProduct.productId + ); - const events: Event[] = - selectedProductData?.eventDatas.map((event) => ({ - pathName: event.modelName, + const events: Event[] = selectedProductData?.eventDatas.map((event) => ({ + pathName: event.modelName, })) || []; - return ( -
-
Simulations
-
-
-
-
Products
-
- Add -
-
-
-
- {products.map((product, index) => ( -
-
- setSelectedProduct(product.productId, product.productName) - } - > - - - handleRenameProduct(product.productId, newName) - } - /> -
- {products.length > 1 && ( -
handleRemoveProduct(product.productId)} - > - + return ( +
+
Simulations
+
+
+
+
Products
+
+ Add +
+
+
+
+ {products.map((product, index) => ( +
+
+ setSelectedProduct(product.productId, product.productName) + } + > + + + handleRenameProduct(product.productId, newName) + } + /> +
+ {products.length > 1 && ( +
handleRemoveProduct(product.productId)} + > + +
+ )} +
+ ))} +
+
handleResize(e, productsContainerRef)} + > + +
- )}
- ))} -
-
handleResize(e, productsContainerRef)} - > - -
-
-
-
-
-
Events
-
- +
+
+
Events
+
+ +
+
+ {events.map((event, index) => ( + + ))} +
+ +
+
+ Need to Compare Layout? +
+
+ Click 'Compare' to review and analyze the layout + differences between them. +
+
+ +
+
-
- {events.map((event, index) => ( - - ))} -
-
-
- Need to Compare Layout? -
-
- Click 'Compare' to review and analyze the layout - differences between them. -
-
- -
+ {selectedAsset && ( + + { + if (option === "Add to Product") { + handleAddEventToProduct({ + event: getEventByModelUuid(selectedAsset.modelUuid), + addEvent, + selectedProduct, + clearSelectedAsset + }); + } else { + handleRemoveEventFromProduct(); + } + }} + /> + + )}
-
- - {selectedAsset && ( - - { - if (option === "Add to Product") { - handleAddEventToProduct({ - selectedAsset, - addEvent, - selectedProduct, - clearSelectedAsset, - }); - } else { - handleRemoveEventFromProduct(); - } - }} - /> - - )} -
- ); + ); }; export default Simulations; diff --git a/app/src/modules/builder/IntialLoad/loadInitialFloorItems.ts b/app/src/modules/builder/IntialLoad/loadInitialFloorItems.ts index c46c0e7..f09f130 100644 --- a/app/src/modules/builder/IntialLoad/loadInitialFloorItems.ts +++ b/app/src/modules/builder/IntialLoad/loadInitialFloorItems.ts @@ -156,7 +156,7 @@ function processLoadedModel( const model = gltf.clone(); model.uuid = item.modeluuid; model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap); - model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid }; + model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid, eventData: item.eventData }; model.position.set(...item.position); model.rotation.set(item.rotation.x, item.rotation.y, item.rotation.z); @@ -170,256 +170,141 @@ function processLoadedModel( } }); - itemsGroup?.current?.add(model); - setFloorItems((prevItems) => [ - ...(prevItems || []), - { - modeluuid: item.modeluuid, - modelname: item.modelname, - position: item.position, - rotation: item.rotation, - modelfileID: item.modelfileID, - isLocked: item.isLocked, - isVisible: item.isVisible, - }, - ]); + if (item.eventData) { + setFloorItems((prevItems) => [ + ...(prevItems || []), + { + modeluuid: item.modeluuid, + modelname: item.modelname, + position: item.position, + rotation: item.rotation, + modelfileID: item.modelfileID, + isLocked: item.isLocked, + isVisible: item.isVisible, + eventData: item.eventData, + }, + ]); - if (item.modelfileID === "a1ee92554935007b10b3eb05") { - const data = PointsCalculator( - 'Vehicle', - gltf.clone(), - new THREE.Vector3(...model.rotation) - ); - - if (!data || !data.points) return; - - const vehicleEvent: VehicleEventSchema = { - modelUuid: item.modeluuid, - modelName: item.modelname, - position: item.position, - rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - state: "idle", - type: "vehicle", - speed: 1, - point: { - uuid: THREE.MathUtils.generateUUID(), - position: [data.points[0].x, data.points[0].y, data.points[0].z], - rotation: [0, 0, 0], - action: { - actionUuid: THREE.MathUtils.generateUUID(), - actionName: "Vehicle Action", - actionType: "travel", - unLoadDuration: 5, - loadCapacity: 10, - pickUpPoint: null, - unLoadPoint: null, - triggers: [] - } - } - }; - addEvent(vehicleEvent); - } else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") { - const data = PointsCalculator( - 'Conveyor', - gltf.clone(), - new THREE.Vector3(...model.rotation) - ); - - if (!data || !data.points) return; - - const ConveyorEvent: ConveyorEventSchema = { - modelUuid: item.modeluuid, - modelName: item.modelname, - position: item.position, - rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - state: "idle", - type: "transfer", - speed: 1, - points: data.points.map((point: THREE.Vector3, index: number) => ({ - uuid: THREE.MathUtils.generateUUID(), - position: [point.x, point.y, point.z], - rotation: [0, 0, 0], - action: { - actionUuid: THREE.MathUtils.generateUUID(), - actionName: `Action ${index + 1}`, - actionType: 'default', - material: 'Default material', - delay: 0, - spawnInterval: 5, - spawnCount: 1, - triggers: [] - } - })) - }; - addEvent(ConveyorEvent); - } else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") { - // const data = PointsCalculator( - // 'Conveyor', - // gltf.clone(), - // new THREE.Vector3(...model.rotation) - // ); - - // if (!data || !data.points) return; - - // const points: ConveyorPointSchema[] = data.points.map((point: THREE.Vector3, index: number) => { - // const actionUuid = THREE.MathUtils.generateUUID(); - // return { - // uuid: THREE.MathUtils.generateUUID(), - // position: [point.x, point.y, point.z], - // rotation: [0, 0, 0], - // action: { - // actionUuid, - // actionName: `Action ${index}`, - // actionType: 'default', - // material: 'inherit', - // delay: 0, - // spawnInterval: 5, - // spawnCount: 1, - // triggers: [] - // } - // }; - // }); - - // points.forEach((point, index) => { - // if (index < points.length - 1) { - // const nextPoint = points[index + 1]; - // point.action.triggers.push({ - // triggerUuid: THREE.MathUtils.generateUUID(), - // triggerName: `Trigger 1`, - // triggerType: "onComplete", - // delay: 0, - // triggeredAsset: { - // triggeredModel: { - // modelName: item.modelname, - // modelUuid: item.modeluuid - // }, - // triggeredPoint: { - // pointName: `Point ${index + 1}`, - // pointUuid: nextPoint.uuid - // }, - // triggeredAction: { - // actionName: nextPoint.action.actionName, - // actionUuid: nextPoint.action.actionUuid - // } - // } - // }); - // } - // }); - - // const ConveyorEvent: ConveyorEventSchema = { - // modelUuid: item.modeluuid, - // modelName: item.modelname, - // position: item.position, - // rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - // state: "idle", - // type: "transfer", - // speed: 1, - // points - // }; - // addEvent(ConveyorEvent); - } else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") { - const data = PointsCalculator( - 'Conveyor', - gltf.clone(), - new THREE.Vector3(...model.rotation) - ); - - if (!data || !data.points) return; - - const ConveyorEvent: ConveyorEventSchema = { - modelUuid: item.modeluuid, - modelName: item.modelname, - position: item.position, - rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - state: "idle", - type: "transfer", - speed: 1, - points: data.points.map((point: THREE.Vector3, index: number) => ({ - uuid: THREE.MathUtils.generateUUID(), - position: [point.x, point.y, point.z], - rotation: [0, 0, 0], - action: { - actionUuid: THREE.MathUtils.generateUUID(), - actionName: `Action ${index}`, - actionType: 'default', - material: 'inherit', - delay: 0, - spawnInterval: 5, - spawnCount: 1, - triggers: [] - } - })) - }; - addEvent(ConveyorEvent); - } else if (item.modelfileID === "29dee78715ad5b853f5c346d") { - const data = PointsCalculator( - 'StaticMachine', - gltf.clone(), - new THREE.Vector3(...model.rotation) - ); - - if (!data || !data.points) return; - - const machineEvent: MachineEventSchema = { - modelUuid: item.modeluuid, - modelName: item.modelname, - position: item.position, - rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - state: "idle", - type: "machine", - point: { - uuid: THREE.MathUtils.generateUUID(), - position: [data.points[0].x, data.points[0].y, data.points[0].z], - rotation: [0, 0, 0], - action: { - actionUuid: THREE.MathUtils.generateUUID(), - actionName: "Process Action", - actionType: "process", - processTime: 10, - swapMaterial: "material-id", - triggers: [] - } - } - }; - addEvent(machineEvent); - } else if (item.modelfileID === "52e6681fbb743a890d96c914") { - const data = PointsCalculator( - 'ArmBot', - gltf.clone(), - new THREE.Vector3(...model.rotation) - ); - - if (!data || !data.points) return; - - const roboticArmEvent: RoboticArmEventSchema = { - modelUuid: item.modeluuid, - modelName: item.modelname, - position: item.position, - rotation: [item.rotation.x, item.rotation.y, item.rotation.z], - state: "idle", - type: "roboticArm", - speed: 1, - point: { - uuid: THREE.MathUtils.generateUUID(), - position: [data.points[0].x, data.points[0].y, data.points[0].z], - rotation: [0, 0, 0], - actions: [ - { + if (item.eventData.type === "vehicle") { + const vehicleEvent: VehicleEventSchema = { + modelUuid: item.modeluuid, + modelName: item.modelname, + position: item.position, + rotation: [item.rotation.x, item.rotation.y, item.rotation.z], + state: "idle", + type: "vehicle", + speed: 1, + point: { + uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(), + position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0], + rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0], + action: { actionUuid: THREE.MathUtils.generateUUID(), - actionName: "Pick and Place", - actionType: "pickAndPlace", - process: { - startPoint: [0, 0, 0], - endPoint: [0, 0, 0] - }, + actionName: "Vehicle Action", + actionType: "travel", + unLoadDuration: 5, + loadCapacity: 10, + pickUpPoint: null, + unLoadPoint: null, triggers: [] } - ] - } - }; - addEvent(roboticArmEvent); + } + }; + addEvent(vehicleEvent); + } else if (item.eventData.type === "Conveyor") { + const ConveyorEvent: ConveyorEventSchema = { + modelUuid: item.modeluuid, + modelName: item.modelname, + position: item.position, + rotation: [item.rotation.x, item.rotation.y, item.rotation.z], + state: "idle", + type: "transfer", + speed: 1, + points: item.eventData.points?.map((point: any, index: number) => ({ + uuid: point.uuid || THREE.MathUtils.generateUUID(), + position: [point.position[0], point.position[1], point.position[2]], + rotation: [point.rotation[0], point.rotation[1], point.rotation[2]], + action: { + actionUuid: THREE.MathUtils.generateUUID(), + actionName: `Action ${index + 1}`, + actionType: 'default', + material: 'Default material', + delay: 0, + spawnInterval: 5, + spawnCount: 1, + triggers: [] + } + })) || [], + }; + addEvent(ConveyorEvent); + } else if (item.eventData.type === "StaticMachine") { + const machineEvent: MachineEventSchema = { + modelUuid: item.modeluuid, + modelName: item.modelname, + position: item.position, + rotation: [item.rotation.x, item.rotation.y, item.rotation.z], + state: "idle", + type: "machine", + point: { + uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(), + position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0], + rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0], + action: { + actionUuid: THREE.MathUtils.generateUUID(), + actionName: "Process Action", + actionType: "process", + processTime: 10, + swapMaterial: "material-id", + triggers: [] + } + } + }; + addEvent(machineEvent); + } else if (item.eventData.type === "ArmBot") { + const roboticArmEvent: RoboticArmEventSchema = { + modelUuid: item.modeluuid, + modelName: item.modelname, + position: item.position, + rotation: [item.rotation.x, item.rotation.y, item.rotation.z], + state: "idle", + type: "roboticArm", + speed: 1, + point: { + uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(), + position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0], + rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0], + actions: [ + { + actionUuid: THREE.MathUtils.generateUUID(), + actionName: "Pick and Place", + actionType: "pickAndPlace", + process: { + startPoint: [0, 0, 0], + endPoint: [0, 0, 0] + }, + triggers: [] + } + ] + } + }; + addEvent(roboticArmEvent); + + } + } else { + setFloorItems((prevItems) => [ + ...(prevItems || []), + { + modeluuid: item.modeluuid, + modelname: item.modelname, + position: item.position, + rotation: item.rotation, + modelfileID: item.modelfileID, + isLocked: item.isLocked, + isVisible: item.isVisible, + }, + ]); } gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: 'power2.out' }); diff --git a/app/src/modules/builder/geomentries/assets/addAssetModel.ts b/app/src/modules/builder/geomentries/assets/addAssetModel.ts index d7c278c..ab9d90d 100644 --- a/app/src/modules/builder/geomentries/assets/addAssetModel.ts +++ b/app/src/modules/builder/geomentries/assets/addAssetModel.ts @@ -164,18 +164,6 @@ async function handleModelLoad( // SOCKET - const data = { - organization, - modeluuid: newFloorItem.modeluuid, - modelname: newFloorItem.modelname, - modelfileID: newFloorItem.modelfileID, - position: newFloorItem.position, - rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z }, - isLocked: false, - isVisible: true, - socketId: socket.id - }; - if (selectedItem.type) { const data = PointsCalculator( selectedItem.type, @@ -185,6 +173,10 @@ async function handleModelLoad( if (!data || !data.points) return; + const eventData: any = { + type: selectedItem.type, + }; + if (selectedItem.type === "Conveyor") { const ConveyorEvent: ConveyorEventSchema = { modelUuid: newFloorItem.modeluuid, @@ -209,8 +201,14 @@ async function handleModelLoad( triggers: [] } })) - } + }; addEvent(ConveyorEvent); + eventData.points = ConveyorEvent.points.map(point => ({ + uuid: point.uuid, + position: point.position, + rotation: point.rotation + })); + } else if (selectedItem.type === "Vehicle") { const vehicleEvent: VehicleEventSchema = { modelUuid: newFloorItem.modeluuid, @@ -237,6 +235,12 @@ async function handleModelLoad( } }; addEvent(vehicleEvent); + eventData.point = { + uuid: vehicleEvent.point.uuid, + position: vehicleEvent.point.position, + rotation: vehicleEvent.point.rotation + }; + } else if (selectedItem.type === "ArmBot") { const roboticArmEvent: RoboticArmEventSchema = { modelUuid: newFloorItem.modeluuid, @@ -265,6 +269,13 @@ async function handleModelLoad( } }; addEvent(roboticArmEvent); + console.log('roboticArmEvent: ', roboticArmEvent); + eventData.point = { + uuid: roboticArmEvent.point.uuid, + position: roboticArmEvent.point.position, + rotation: roboticArmEvent.point.rotation + }; + } else if (selectedItem.type === "StaticMachine") { const machineEvent: MachineEventSchema = { modelUuid: newFloorItem.modeluuid, @@ -288,19 +299,65 @@ async function handleModelLoad( } }; addEvent(machineEvent); + eventData.point = { + uuid: machineEvent.point.uuid, + position: machineEvent.point.position, + rotation: machineEvent.point.rotation + }; } + + const completeData = { + organization, + modeluuid: newFloorItem.modeluuid, + modelname: newFloorItem.modelname, + modelfileID: newFloorItem.modelfileID, + position: newFloorItem.position, + rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id, + eventData: eventData + }; + + model.userData.eventData = eventData; + + newFloorItem.eventData = eventData; + + setFloorItems((prevItems) => { + const updatedItems = [...(prevItems || []), newFloorItem]; + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + + socket.emit("v2:model-asset:add", completeData); + + gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" }); + gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } }); + } else { + + const data = { + organization, + modeluuid: newFloorItem.modeluuid, + modelname: newFloorItem.modelname, + modelfileID: newFloorItem.modelfileID, + position: newFloorItem.position, + rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z }, + isLocked: false, + isVisible: true, + socketId: socket.id + }; + + setFloorItems((prevItems) => { + const updatedItems = [...(prevItems || []), newFloorItem]; + localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); + return updatedItems; + }); + + socket.emit("v2:model-asset:add", data); + + gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" }); + gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } }); } - - setFloorItems((prevItems) => { - const updatedItems = [...(prevItems || []), newFloorItem]; - localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); - return updatedItems; - }); - - socket.emit("v2:model-asset:add", data); - - gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" }); - gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } }); } export default addAssetModel; diff --git a/app/src/modules/builder/groups/floorItemsGroup.tsx b/app/src/modules/builder/groups/floorItemsGroup.tsx index f3f5050..f1da0a4 100644 --- a/app/src/modules/builder/groups/floorItemsGroup.tsx +++ b/app/src/modules/builder/groups/floorItemsGroup.tsx @@ -65,6 +65,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject }; getFloorAssets(organization).then((data) => { + console.log('data: ', data); if (data.length > 0) { const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID)); totalAssets = uniqueItems.length; diff --git a/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx b/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx index 9ca4dd0..c92c98f 100644 --- a/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/copyPasteControls.tsx @@ -137,6 +137,38 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas if (itemsGroupRef.current) { + let updatedEventData = null; + if (obj.userData.eventData) { + updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData)); + + updatedEventData.modelUuid = THREE.MathUtils.generateUUID(); + + if (updatedEventData.type === "Conveyor" && updatedEventData.points) { + updatedEventData.points = updatedEventData.points.map((point: any) => ({ + ...point, + uuid: THREE.MathUtils.generateUUID() + })); + } + else if (updatedEventData.type === "Vehicle" && updatedEventData.point) { + updatedEventData.point = { + ...updatedEventData.point, + uuid: THREE.MathUtils.generateUUID() + }; + } + else if (updatedEventData.type === "ArmBot" && updatedEventData.point) { + updatedEventData.point = { + ...updatedEventData.point, + uuid: THREE.MathUtils.generateUUID() + }; + } + else if (updatedEventData.type === "StaticMachine" && updatedEventData.point) { + updatedEventData.point = { + ...updatedEventData.point, + uuid: THREE.MathUtils.generateUUID() + }; + } + } + const newFloorItem: Types.FloorItemType = { modeluuid: obj.uuid, modelname: obj.userData.name, @@ -144,7 +176,8 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas position: [worldPosition.x, worldPosition.y, worldPosition.z], rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, }, isLocked: false, - isVisible: true + isVisible: true, + eventData: updatedEventData }; setFloorItems((prevItems: Types.FloorItems) => { @@ -181,11 +214,18 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas isLocked: false, isVisible: true, socketId: socket.id, + eventData: updatedEventData }; socket.emit("v2:model-asset:add", data); - obj.userData.modeluuid = newFloorItem.modeluuid; + obj.userData = { + name: newFloorItem.modelname, + modelId: newFloorItem.modelfileID, + modeluuid: newFloorItem.modeluuid, + eventData: updatedEventData + }; + itemsGroupRef.current.add(obj); } }); @@ -205,7 +245,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas setSelectedAssets([]); } - return null; // No visible output, but the component handles copy-paste functionality + return null; }; export default CopyPasteControls; \ No newline at end of file diff --git a/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx b/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx index 39c3e49..c1f4a74 100644 --- a/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/duplicationControls.tsx @@ -115,6 +115,38 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb if (itemsGroupRef.current) { + let updatedEventData = null; + if (obj.userData.eventData) { + updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData)); + + updatedEventData.modelUuid = THREE.MathUtils.generateUUID(); + + if (updatedEventData.type === "Conveyor" && updatedEventData.points) { + updatedEventData.points = updatedEventData.points.map((point: any) => ({ + ...point, + uuid: THREE.MathUtils.generateUUID() + })); + } + else if (updatedEventData.type === "Vehicle" && updatedEventData.point) { + updatedEventData.point = { + ...updatedEventData.point, + uuid: THREE.MathUtils.generateUUID() + }; + } + else if (updatedEventData.type === "ArmBot" && updatedEventData.point) { + updatedEventData.point = { + ...updatedEventData.point, + uuid: THREE.MathUtils.generateUUID() + }; + } + else if (updatedEventData.type === "StaticMachine" && updatedEventData.point) { + updatedEventData.point = { + ...updatedEventData.point, + uuid: THREE.MathUtils.generateUUID() + }; + } + } + const newFloorItem: Types.FloorItemType = { modeluuid: obj.uuid, modelname: obj.userData.name, @@ -122,7 +154,8 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb position: [worldPosition.x, worldPosition.y, worldPosition.z], rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, }, isLocked: false, - isVisible: true + isVisible: true, + eventData: updatedEventData }; setFloorItems((prevItems: Types.FloorItems) => { @@ -159,11 +192,18 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb isLocked: false, isVisible: true, socketId: socket.id, + eventData: updatedEventData }; socket.emit("v2:model-asset:add", data); - obj.userData.modeluuid = newFloorItem.modeluuid; + obj.userData = { + name: newFloorItem.modelname, + modelId: newFloorItem.modelfileID, + modeluuid: newFloorItem.modeluuid, + eventData: updatedEventData + }; + itemsGroupRef.current.add(obj); } }); @@ -183,7 +223,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb setSelectedAssets([]); } - return null; // This component does not render any UI + return null; }; export default DuplicationControls; \ No newline at end of file diff --git a/app/src/modules/scene/controls/selectionControls/moveControls.tsx b/app/src/modules/scene/controls/selectionControls/moveControls.tsx index 2cde3e4..f422d6e 100644 --- a/app/src/modules/scene/controls/selectionControls/moveControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/moveControls.tsx @@ -1,11 +1,14 @@ import * as THREE from "three"; -import { useEffect, useMemo, useRef, useState } from "react"; +import { useEffect, useMemo, useRef } from "react"; import { useFrame, useThree } from "@react-three/fiber"; import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import { toast } from "react-toastify"; import * as Types from "../../../../types/world/worldTypes"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; +import { useEventsStore } from "../../../../store/simulation/useEventsStore"; +import { useProductStore } from "../../../../store/simulation/useProductStore"; +import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore"; function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) { const { camera, controls, gl, scene, pointer, raycaster } = useThree(); @@ -176,6 +179,24 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje isVisible: true }; + if (obj.userData.eventData) { + const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modeluuid); + const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid); + + if (eventData) { + useEventsStore.getState().updateEvent(obj.userData.modeluuid, { + position: [worldPosition.x, worldPosition.y, worldPosition.z], + rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z], + }) + } + if (productData) { + useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid, { + position: [worldPosition.x, worldPosition.y, worldPosition.z], + rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z], + }) + } + } + setFloorItems((prevItems: Types.FloorItems) => { const updatedItems = [...(prevItems || []), newFloorItem]; localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); @@ -234,7 +255,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje setSelectedAssets([]); } - return null; // No need to return anything, as this component is used for its side effects + return null; } export default MoveControls \ No newline at end of file diff --git a/app/src/modules/scene/controls/selectionControls/rotateControls.tsx b/app/src/modules/scene/controls/selectionControls/rotateControls.tsx index 5dfaf08..cf66772 100644 --- a/app/src/modules/scene/controls/selectionControls/rotateControls.tsx +++ b/app/src/modules/scene/controls/selectionControls/rotateControls.tsx @@ -1,11 +1,13 @@ import * as THREE from "three"; -import { useEffect, useMemo, useRef, useState } from "react"; +import { useEffect, useMemo, useRef } from "react"; import { useFrame, useThree } from "@react-three/fiber"; import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store"; // import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi'; import { toast } from "react-toastify"; import * as Types from "../../../../types/world/worldTypes"; -import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; +import { useEventsStore } from "../../../../store/simulation/useEventsStore"; +import { useProductStore } from "../../../../store/simulation/useProductStore"; +import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore"; function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) { const { camera, controls, gl, scene, pointer, raycaster } = useThree(); @@ -177,6 +179,24 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo isVisible: true }; + if (obj.userData.eventData) { + const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modeluuid); + const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid); + + if (eventData) { + useEventsStore.getState().updateEvent(obj.userData.modeluuid, { + position: [worldPosition.x, worldPosition.y, worldPosition.z], + rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z], + }) + } + if (productData) { + useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid, { + position: [worldPosition.x, worldPosition.y, worldPosition.z], + rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z], + }) + } + } + setFloorItems((prevItems: Types.FloorItems) => { const updatedItems = [...(prevItems || []), newFloorItem]; localStorage.setItem("FloorItems", JSON.stringify(updatedItems)); @@ -235,7 +255,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo setSelectedAssets([]); } - return null; // No need to return anything, as this component is used for its side effects + return null; } export default RotateControls \ No newline at end of file diff --git a/app/src/modules/simulation/events/points/creator/pointsCreator.tsx b/app/src/modules/simulation/events/points/creator/pointsCreator.tsx index c5025dd..8e476d0 100644 --- a/app/src/modules/simulation/events/points/creator/pointsCreator.tsx +++ b/app/src/modules/simulation/events/points/creator/pointsCreator.tsx @@ -62,7 +62,7 @@ function PointsCreator() { {events.map((event, i) => { if (event.type === 'transfer') { return ( - + {event.points.map((point, j) => ( @@ -88,7 +89,7 @@ function PointsCreator() { ); } else if (event.type === 'vehicle') { return ( - + @@ -111,7 +113,7 @@ function PointsCreator() { ); } else if (event.type === 'roboticArm') { return ( - + @@ -134,7 +137,7 @@ function PointsCreator() { ); } else if (event.type === 'machine') { return ( - + diff --git a/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts b/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts index 7943c1c..9928578 100644 --- a/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts +++ b/app/src/modules/simulation/events/points/functions/handleAddEventToProduct.ts @@ -1,28 +1,38 @@ +import { upsertProductOrEventApi } from "../../../../../services/simulation/UpsertProductOrEventApi"; + interface HandleAddEventToProductParams { - selectedAsset: any; // Replace `any` with specific type if you have it - addEvent: (productId: string, asset: any) => void; + event: EventsSchema | undefined; + addEvent: (productId: string, event: EventsSchema) => void; selectedProduct: { productId: string; productName: string; - // Add other fields if needed - }; - clearSelectedAsset: () => void; + } + clearSelectedAsset?: () => void; } export const handleAddEventToProduct = ({ - selectedAsset, + event, addEvent, selectedProduct, - clearSelectedAsset, + clearSelectedAsset }: HandleAddEventToProductParams) => { - console.log('selectedProduct: ', selectedProduct); - if (selectedAsset) { - addEvent(selectedProduct.productId, selectedAsset); - // upsertProductOrEventApi({ - // productName: selectedProduct.productName, - // productId: selectedProduct.productId, - // eventDatas: selectedAsset - // }); - clearSelectedAsset(); + if (event && selectedProduct.productId) { + addEvent(selectedProduct.productId, event); + + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + + upsertProductOrEventApi({ + productName: selectedProduct.productName, + productId: selectedProduct.productId, + organization: organization, + eventDatas: event + }).then((data) => { + // console.log(data); + }) + + if (clearSelectedAsset) { + clearSelectedAsset(); + } } }; diff --git a/app/src/modules/simulation/products/products.tsx b/app/src/modules/simulation/products/products.tsx index 38175e2..ee1ac42 100644 --- a/app/src/modules/simulation/products/products.tsx +++ b/app/src/modules/simulation/products/products.tsx @@ -7,28 +7,27 @@ import { upsertProductOrEventApi } from '../../../services/simulation/UpsertProd import { getAllProductsApi } from '../../../services/simulation/getallProductsApi'; function Products() { - const { products, addProduct } = useProductStore(); + const { products, addProduct, setProducts } = useProductStore(); const { setSelectedProduct } = useSelectedProduct(); useEffect(() => { - if (products.length === 0) { - const id = THREE.MathUtils.generateUUID(); - const name = 'Product 1'; - addProduct(name, id); - // upsertProductOrEventApi({ productName: name, productId: id }).then((data) => { - // console.log('data: ', data); - // }); - setSelectedProduct(id, name); - } - }, [products]) + const email = localStorage.getItem('email') + const organization = (email!.split("@")[1]).split(".")[0]; + getAllProductsApi(organization).then((data) => { + if (data.length === 0) { + const id = THREE.MathUtils.generateUUID(); + const name = 'Product 1'; + addProduct(name, id); + upsertProductOrEventApi({ productName: name, productId: id, organization: organization }) + setSelectedProduct(id, name); + } else { + setProducts(data); + setSelectedProduct(data[0].productId, data[0].productName); + } + }) + }, []) useEffect(() => { - // const email = localStorage.getItem('email') - // const organization = (email!.split("@")[1]).split(".")[0]; - // console.log(organization); - // getAllProductsApi(organization).then((data) => { - // console.log('data: ', data); - // }) }, []) return ( diff --git a/app/src/modules/simulation/simulation.tsx b/app/src/modules/simulation/simulation.tsx index 5ca0ec5..f2d208d 100644 --- a/app/src/modules/simulation/simulation.tsx +++ b/app/src/modules/simulation/simulation.tsx @@ -19,11 +19,11 @@ function Simulation() { const { products } = useProductStore(); useEffect(() => { - // console.log('events: ', events); + console.log('events: ', events); }, [events]) useEffect(() => { - // console.log('products: ', products); + console.log('products: ', products); }, [products]) return ( diff --git a/app/src/modules/simulation/triggers/connector/triggerConnector.tsx b/app/src/modules/simulation/triggers/connector/triggerConnector.tsx index f836ea4..efefa0c 100644 --- a/app/src/modules/simulation/triggers/connector/triggerConnector.tsx +++ b/app/src/modules/simulation/triggers/connector/triggerConnector.tsx @@ -1,19 +1,85 @@ -import { useEffect } from "react"; +import { useEffect, useRef, useState } from "react"; import { useThree } from "@react-three/fiber"; +import * as THREE from "three"; import { useSubModuleStore } from "../../../../store/useModuleStore"; import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../store/simulation/useProductStore"; +import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore"; +import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct"; + +interface ConnectionLine { + id: string; + start: THREE.Vector3; + end: THREE.Vector3; + mid: THREE.Vector3; + trigger: TriggerSchema; +} function TriggerConnector() { const { gl, raycaster, scene } = useThree(); const { subModule } = useSubModuleStore(); - const { getPointByUuid, getIsEventInProduct } = useProductStore(); + const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid } = useProductStore(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { selectedProduct } = useSelectedProduct(); - useEffect(() => { + const [firstSelectedPoint, setFirstSelectedPoint] = useState<{ + productId: string; + modelUuid: string; + pointUuid: string; + actionUuid?: string; + } | null>(null); + const [connections, setConnections] = useState([]); + + useEffect(() => { + const newConnections: ConnectionLine[] = []; + + products.forEach(product => { + product.eventDatas.forEach(event => { + if ('points' in event) { + event.points.forEach(point => { + if ('action' in point && point.action?.triggers) { + point.action.triggers.forEach(trigger => { + if (trigger.triggeredAsset) { + const targetPoint = getPointByUuid( + product.productId, + trigger.triggeredAsset.triggeredModel.modelUuid, + trigger.triggeredAsset.triggeredPoint.pointUuid + ); + + if (targetPoint) { + const startPos = new THREE.Vector3(...point.position); + const endPos = new THREE.Vector3(...targetPoint.position); + const midPos = new THREE.Vector3() + .addVectors(startPos, endPos) + .multiplyScalar(0.5) + .add(new THREE.Vector3(0, 2, 0)); + + newConnections.push({ + id: `${point.uuid}-${targetPoint.uuid}-${trigger.triggerUuid}`, + start: startPos, + end: endPos, + mid: midPos, + trigger + }); + } + } + }); + } + }); + } + }); + }); + + setConnections(newConnections); + }, [products]); + + useEffect(() => { + console.log('connections: ', connections); + }, connections) + + useEffect(() => { const canvasElement = gl.domElement; let drag = false; @@ -44,37 +110,114 @@ function TriggerConnector() { const handleRightClick = (evt: MouseEvent) => { if (drag) return; evt.preventDefault(); - const canvasElement = gl.domElement; - if (!canvasElement) return; - let intersects = raycaster.intersectObjects(scene.children, true); - if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) { - let currentObject = intersects[0].object; + const intersects = raycaster.intersectObjects(scene.children, true); + if (intersects.length === 0) return; - if (currentObject && currentObject.name === 'Event-Sphere') { + const currentObject = intersects[0].object; + if (!currentObject || currentObject.name !== 'Event-Sphere') return; - const isInProduct = getIsEventInProduct( - selectedProduct.productId, - currentObject.userData.modelUuid - ); + const modelUuid = currentObject.userData.modelUuid; + const pointUuid = currentObject.userData.pointUuid; - // You left Here + if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) { - if (isInProduct) { + const point = getPointByUuid( + selectedProduct.productId, + modelUuid, + pointUuid + ); - const event = getPointByUuid( - selectedProduct.productId, - currentObject.userData.modelUuid, - currentObject.userData.pointUuid - ); - console.log('event: ', event); - } else { + if (!point) return; - } + let actionUuid: string | undefined; + if ('action' in point && point.action) { + actionUuid = point.action.actionUuid; + } else if ('actions' in point && point.actions.length === 1) { + actionUuid = point.actions[0].actionUuid; } - } else { + if (!firstSelectedPoint) { + setFirstSelectedPoint({ + productId: selectedProduct.productId, + modelUuid, + pointUuid, + actionUuid + }); + } else { + const trigger: TriggerSchema = { + triggerUuid: THREE.MathUtils.generateUUID(), + triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)} → ${pointUuid.slice(0, 4)}`, + triggerType: "onComplete", + delay: 0, + triggeredAsset: { + triggeredModel: { + modelName: currentObject.parent?.parent?.name || 'Unknown', + modelUuid: modelUuid + }, + triggeredPoint: { + pointName: currentObject.name, + pointUuid: pointUuid + }, + triggeredAction: actionUuid ? { + actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action', + actionUuid: actionUuid + } : null + } + }; + if (firstSelectedPoint.actionUuid) { + addTrigger(firstSelectedPoint.actionUuid, trigger); + } + setFirstSelectedPoint(null); + } + } else if (!getIsEventInProduct(selectedProduct.productId, modelUuid) && firstSelectedPoint) { + handleAddEventToProduct({ + event: useEventsStore.getState().getEventByModelUuid(modelUuid), + addEvent, + selectedProduct, + }) + + const point = getPointByUuid( + selectedProduct.productId, + modelUuid, + pointUuid + ); + + if (!point) return; + + let actionUuid: string | undefined; + if ('action' in point && point.action) { + actionUuid = point.action.actionUuid; + } else if ('actions' in point && point.actions.length === 1) { + actionUuid = point.actions[0].actionUuid; + } + + const trigger: TriggerSchema = { + triggerUuid: THREE.MathUtils.generateUUID(), + triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)} → ${pointUuid.slice(0, 4)}`, + triggerType: "onComplete", + delay: 0, + triggeredAsset: { + triggeredModel: { + modelName: currentObject.parent?.parent?.name || 'Unknown', + modelUuid: modelUuid + }, + triggeredPoint: { + pointName: currentObject.name, + pointUuid: pointUuid + }, + triggeredAction: actionUuid ? { + actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action', + actionUuid: actionUuid + } : null + } + }; + + if (firstSelectedPoint.actionUuid) { + addTrigger(firstSelectedPoint.actionUuid, trigger); + } + setFirstSelectedPoint(null); } }; @@ -92,12 +235,12 @@ function TriggerConnector() { canvasElement.removeEventListener('contextmenu', handleRightClick); }; - }, [gl, subModule]); + }, [gl, subModule, selectedProduct, firstSelectedPoint]); return ( <> - ) + ); } -export default TriggerConnector \ No newline at end of file +export default TriggerConnector; \ No newline at end of file diff --git a/app/src/store/simulation/useProductStore.ts b/app/src/store/simulation/useProductStore.ts index 8ec74cf..de02551 100644 --- a/app/src/store/simulation/useProductStore.ts +++ b/app/src/store/simulation/useProductStore.ts @@ -6,6 +6,7 @@ type ProductsStore = { // Product-level actions addProduct: (productName: string, productId: string) => void; + setProducts: (products: productsSchema) => void; removeProduct: (productId: string) => void; updateProduct: (productId: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void; @@ -78,6 +79,12 @@ export const useProductStore = create()( }); }, + setProducts: (products) => { + set((state) => { + state.products = products; + }); + }, + removeProduct: (productId) => { set((state) => { state.products = state.products.filter(p => p.productId !== productId); diff --git a/app/src/types/simulationTypes.d.ts b/app/src/types/simulationTypes.d.ts index 811812d..46093d6 100644 --- a/app/src/types/simulationTypes.d.ts +++ b/app/src/types/simulationTypes.d.ts @@ -14,7 +14,7 @@ interface TriggerSchema { triggeredAsset: { triggeredModel: { modelName: string, modelUuid: string }; triggeredPoint: { pointName: string, pointUuid: string }; - triggeredAction: { actionName: string, actionUuid: string }; + triggeredAction: { actionName: string, actionUuid: string } | null; } | null; } diff --git a/app/src/types/world/worldTypes.d.ts b/app/src/types/world/worldTypes.d.ts index fa6c129..20c44da 100644 --- a/app/src/types/world/worldTypes.d.ts +++ b/app/src/types/world/worldTypes.d.ts @@ -196,6 +196,19 @@ export type FloorItemType = { modelfileID: string; isLocked: boolean; isVisible: boolean; + eventData?: { + type: string; + point?: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + } + points?: { + uuid: string; + position: [number, number, number]; + rotation: [number, number, number]; + }[]; + } }; // Array of floor items for managing multiple objects on the floor diff --git a/app/src/utils/indexDB/idbUtils.ts b/app/src/utils/indexDB/idbUtils.ts index c9228d3..24b1448 100644 --- a/app/src/utils/indexDB/idbUtils.ts +++ b/app/src/utils/indexDB/idbUtils.ts @@ -3,43 +3,43 @@ const STORE_NAME = 'models'; const DB_VERSION = 1; export function initializeDB(): Promise { - return new Promise((resolve, reject) => { - const request = indexedDB.open(DB_NAME, DB_VERSION); + return new Promise((resolve, reject) => { + const request = indexedDB.open(DB_NAME, DB_VERSION); - request.onupgradeneeded = () => { - const db = request.result; - if (!db.objectStoreNames.contains(STORE_NAME)) { - db.createObjectStore(STORE_NAME); - } - }; + request.onupgradeneeded = () => { + const db = request.result; + if (!db.objectStoreNames.contains(STORE_NAME)) { + db.createObjectStore(STORE_NAME); + } + }; - request.onsuccess = () => resolve(request.result); - request.onerror = () => reject(request.error); - }); + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + }); } export async function storeGLTF(key: string, file: Blob): Promise { - const db = await initializeDB(); + const db = await initializeDB(); - return new Promise((resolve, reject) => { - const transaction = db.transaction(STORE_NAME, 'readwrite'); - const store = transaction.objectStore(STORE_NAME); - const request = store.put(file, key); + return new Promise((resolve, reject) => { + const transaction = db.transaction(STORE_NAME, 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + const request = store.put(file, key); - request.onsuccess = () => resolve(); - request.onerror = () => reject(request.error); - }); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + }); } export async function retrieveGLTF(key: string): Promise { - const db = await initializeDB(); + const db = await initializeDB(); - return new Promise((resolve, reject) => { - const transaction = db.transaction(STORE_NAME, 'readonly'); - const store = transaction.objectStore(STORE_NAME); - const request = store.get(key); + return new Promise((resolve, reject) => { + const transaction = db.transaction(STORE_NAME, 'readonly'); + const store = transaction.objectStore(STORE_NAME); + const request = store.get(key); - request.onsuccess = () => resolve(request.result as Blob | undefined); - request.onerror = () => reject(request.error); - }); + request.onsuccess = () => resolve(request.result as Blob | undefined); + request.onerror = () => reject(request.error); + }); } \ No newline at end of file