From 43df50c5763c0f35b2b72b6088ea471016edc30c Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Tue, 8 Apr 2025 18:31:57 +0530 Subject: [PATCH] feat: Enhance ArmBot and StaticMachine mechanics with trigger handling and reset functionality --- .../mechanics/ArmBotMechanics.tsx | 166 ++++++++++++++---- .../mechanics/StaticMachineMechanics.tsx | 114 +++++++++++- .../mechanics/VehicleMechanics.tsx | 36 ++++ .../builder/groups/floorItemsGroup.tsx | 2 + .../controls/selection/copyPasteControls.tsx | 2 +- .../selection/duplicationControls.tsx | 2 +- 6 files changed, 274 insertions(+), 48 deletions(-) diff --git a/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx index 744d555..4dffdb2 100644 --- a/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx @@ -1,65 +1,121 @@ -import React, { useRef, useMemo } from "react"; +import React, { useRef, useMemo, useCallback, useState } from "react"; import { InfoIcon } from "../../../icons/ExportCommonIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; -import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store"; +import { + useSelectedActionSphere, + useSimulationStates, + useSocketStore +} from "../../../../store/store"; import * as Types from '../../../../types/world/worldTypes'; -import PositionInput from "../customInput/PositionInputs"; -import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; +import LabeledButton from "../../../ui/inputs/LabledButton"; +import LabledDropdown from "../../../ui/inputs/LabledDropdown"; const ArmBotMechanics: React.FC = () => { const { selectedActionSphere } = useSelectedActionSphere(); const { simulationStates, setSimulationStates } = useSimulationStates(); const { socket } = useSocketStore(); + const [selectedTrigger, setSelectedTrigger] = useState(null); const propertiesContainerRef = useRef(null); - const { selectedPoint, connectedPointUuids } = useMemo(() => { - if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] }; + // Get connected models for dropdowns + const connectedModels = useMemo(() => { + if (!selectedActionSphere?.points?.uuid) return []; - const vehiclePaths = simulationStates.filter( + }, [selectedActionSphere, simulationStates]); + + // Get triggers only from connected models + const connectedTriggers = useMemo(() => { + }, [connectedModels, simulationStates]); + + const { selectedPoint } = useMemo(() => { + if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null }; + + const armBotPaths = simulationStates.filter( (path): path is Types.ArmBotEventsSchema => path.type === "ArmBot" ); - const points = vehiclePaths.find( + const points = armBotPaths.find( (path) => path.points.uuid === selectedActionSphere.points.uuid )?.points; - if (!points) return { selectedPoint: null, connectedPointUuids: [] }; - - const connectedUuids: string[] = []; - if (points.connections?.targets) { - points.connections.targets.forEach(target => { - connectedUuids.push(target.pointUUID); - }); - } - return { - selectedPoint: points, - connectedPointUuids: connectedUuids + selectedPoint: points || null }; }, [selectedActionSphere, simulationStates]); const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => { - if (!updatedPath) return; - const email = localStorage.getItem("email"); - const organization = email ? email.split("@")[1].split(".")[0] : ""; + // if (!updatedPath) return; + // const email = localStorage.getItem("email"); + // const organization = email ? email.split("@")[1].split(".")[0] : ""; - // await setEventApi( - // organization, - // updatedPath.modeluuid, - // { type: "ArmBot", points: updatedPath.points } - // ); - - const data = { - organization: organization, - modeluuid: updatedPath.modeluuid, - eventData: { type: "ArmBot", points: updatedPath.points } - } - - socket.emit('v2:model-asset:updateEventData', data); + // const data = { + // organization: organization, + // modeluuid: updatedPath.modeluuid, + // eventData: { type: "ArmBot", points: updatedPath.points } + // } + // socket.emit('v2:model-asset:updateEventData', data); } + // const handleActionUpdate = useCallback((updatedAction: Partial) => { + // if (!selectedActionSphere?.points?.uuid) return; + + // const updatedPaths = simulationStates.map((path) => { + // return path; + // }); + + // const updatedPath = updatedPaths.find( + // (path): path is Types.ArmBotEventsSchema => + // path.type === "ArmBot" && + // path.points.uuid === selectedActionSphere.points.uuid + // ); + // updateBackend(updatedPath); + + // setSimulationStates(updatedPaths); + // }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]); + + // const handleSpeedChange = useCallback((speed: number) => { + // handleActionUpdate({ speed }); + // }, [handleActionUpdate]); + + // const handleProcessChange = useCallback((processes: Types.ArmBotEventsSchema['points']['actions']['processes']) => { + // handleActionUpdate({ processes }); + // }, [handleActionUpdate]); + + // const handleTriggerSelect = useCallback((displayName: string) => { + // const selected = connectedTriggers.find(t => t.displayName === displayName); + // setSelectedTrigger(selected?.uuid || null); + // }, [connectedTriggers]); + + // const handleStartPointSelect = useCallback((pointUUID: string) => { + // if (!selectedTrigger || !selectedPoint) return; + + // const updatedProcesses = selectedPoint.actions.processes?.map(process => + // process.triggerId === selectedTrigger + // ? { ...process, startPoint: pointUUID } + // : process + // ) || []; + + // handleProcessChange(updatedProcesses); + // }, [selectedTrigger, selectedPoint, handleProcessChange]); + + // const handleEndPointSelect = useCallback((pointUUID: string) => { + // if (!selectedTrigger || !selectedPoint) return; + + // const updatedProcesses = selectedPoint.actions.processes?.map(process => + // process.triggerId === selectedTrigger + // ? { ...process, endPoint: pointUUID } + // : process + // ) || []; + + // handleProcessChange(updatedProcesses); + // }, [selectedTrigger, selectedPoint, handleProcessChange]); + + // const getCurrentProcess = useCallback(() => { + // if (!selectedTrigger || !selectedPoint) return null; + // return selectedPoint.actions.processes?.find(p => p.triggerId === selectedTrigger); + // }, [selectedTrigger, selectedPoint]); return (
@@ -71,16 +127,50 @@ const ArmBotMechanics: React.FC = () => {
ArmBot Properties
- {selectedPoint && ( + {/* {selectedPoint && ( <> + handleSpeedChange(parseInt(value))} + /> + t.uuid === selectedTrigger)?.displayName || ''} + onSelect={handleTriggerSelect} + options={connectedTriggers.map(trigger => trigger.displayName)} + /> + + {selectedTrigger && ( + <> + `${model.modelName} [${index}]`)} + /> + + `${model.modelName} [${index}]`)} + /> + + + )} - )} + )} */}
- Configure armbot properties. + Configure ArmBot properties and trigger-based processes.
diff --git a/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx index 254753e..564f221 100644 --- a/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx @@ -1,9 +1,9 @@ -import React, { useRef, useMemo } from "react"; +import React, { useRef, useMemo, useCallback } from "react"; import { InfoIcon } from "../../../icons/ExportCommonIcons"; import InputWithDropDown from "../../../ui/inputs/InputWithDropDown"; -import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store"; +import { useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store"; import * as Types from '../../../../types/world/worldTypes'; -import PositionInput from "../customInput/PositionInputs"; +import LabledDropdown from "../../../ui/inputs/LabledDropdown"; import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; const StaticMachineMechanics: React.FC = () => { @@ -16,11 +16,11 @@ const StaticMachineMechanics: React.FC = () => { const { selectedPoint, connectedPointUuids } = useMemo(() => { if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] }; - const vehiclePaths = simulationStates.filter( + const staticMachinePaths = simulationStates.filter( (path): path is Types.StaticMachineEventsSchema => path.type === "StaticMachine" ); - const points = vehiclePaths.find( + const points = staticMachinePaths.find( (path) => path.points.uuid === selectedActionSphere.points.uuid )?.points; @@ -47,7 +47,7 @@ const StaticMachineMechanics: React.FC = () => { // await setEventApi( // organization, // updatedPath.modeluuid, - // { type: "StaticMachine", points: updatedPath.points } + // { type: "Vehicle", points: updatedPath.points } // ); const data = { @@ -57,9 +57,77 @@ const StaticMachineMechanics: React.FC = () => { } socket.emit('v2:model-asset:updateEventData', data); - } + const handleActionUpdate = useCallback((updatedAction: Partial) => { + if (!selectedActionSphere?.points?.uuid) return; + + const updatedPaths = simulationStates.map((path) => { + if (path.type === "StaticMachine" && path.points.uuid === selectedActionSphere.points.uuid) { + return { + ...path, + points: { + ...path.points, + actions: { + ...path.points.actions, + ...updatedAction + } + } + }; + } + return path; + }); + + const updatedPath = updatedPaths.find( + (path): path is Types.StaticMachineEventsSchema => + path.type === "StaticMachine" && + path.points.uuid === selectedActionSphere.points.uuid + ); + updateBackend(updatedPath); + + setSimulationStates(updatedPaths); + }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]); + + const handleBufferChange = useCallback((buffer: number) => { + handleActionUpdate({ buffer }); + }, [handleActionUpdate]); + + const handleMaterialChange = useCallback((material: string) => { + handleActionUpdate({ material }); + }, [handleActionUpdate]); + + const handleTriggerChange = useCallback((updatedTrigger: Partial) => { + if (!selectedActionSphere?.points?.uuid) return; + + const updatedPaths = simulationStates.map((path) => { + if (path.type === "StaticMachine" && path.points.uuid === selectedActionSphere.points.uuid) { + return { + ...path, + points: { + ...path.points, + triggers: { + ...path.points.triggers, + ...updatedTrigger + } + } + }; + } + return path; + }); + + const updatedPath = updatedPaths.find( + (path): path is Types.StaticMachineEventsSchema => + path.type === "StaticMachine" && + path.points.uuid === selectedActionSphere.points.uuid + ); + updateBackend(updatedPath); + + setSimulationStates(updatedPaths); + }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]); + + const handleTriggerTypeChange = useCallback((type: string) => { + handleTriggerChange({ type }); + }, [handleTriggerChange]); return (
@@ -67,20 +135,50 @@ const StaticMachineMechanics: React.FC = () => { {selectedActionSphere?.path?.modelName || "Machine point not found"}
+
Machine Properties
{selectedPoint && ( <> + handleBufferChange(parseInt(value))} + /> + handleMaterialChange(value)} + options={["Inherit", "Crate", "Box"]} + /> + + handleTriggerTypeChange(value)} + options={["OnComplete", "OnStart"]} + /> + + {/* { + // Implement reset functionality if needed + }} + /> */} )}
- Configure machine properties. + Configure machine interaction properties and triggers.
diff --git a/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx index 4db77fe..67d132f 100644 --- a/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx +++ b/app/src/components/layout/sidebarRight/mechanics/VehicleMechanics.tsx @@ -5,6 +5,7 @@ import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionS import * as Types from '../../../../types/world/worldTypes'; import PositionInput from "../customInput/PositionInputs"; import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt"; +import LabeledButton from "../../../ui/inputs/LabledButton"; const VehicleMechanics: React.FC = () => { const { selectedActionSphere } = useSelectedActionSphere(); @@ -126,6 +127,33 @@ const VehicleMechanics: React.FC = () => { setSimulationStates(updatedPaths); }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]); + + const ResetVehicleState = React.useCallback(() => { + if (!selectedActionSphere?.points?.uuid) return; + + const updatedPaths = simulationStates.map((state) => { + if (state.type === "Vehicle" && state.points.uuid === selectedActionSphere.points.uuid) { + return { + ...state, + points: { + ...state.points, + actions: { ...state.points.actions, start: {}, end: {} } + } + }; + } + return state; + }); + + const updatedPath = updatedPaths.find( + (path): path is Types.VehicleEventsSchema => + path.type === "Vehicle" && + path.points.uuid === selectedActionSphere.points.uuid + ); + updateBackend(updatedPath); + + setSimulationStates(updatedPaths); + }, [selectedActionSphere?.points?.uuid, simulationStates, setSimulationStates]); + const handleStartEyeDropClick = () => { setEditingPoint('start'); setEyeDropMode(true); @@ -193,6 +221,14 @@ const VehicleMechanics: React.FC = () => { handleEyeDropClick={handleEndEyeDropClick} /> + { + ResetVehicleState(); + }} + /> +