diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/actions/PickAndPlaceAction.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/actions/PickAndPlaceAction.tsx index 9574669..175a824 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/actions/PickAndPlaceAction.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/actions/PickAndPlaceAction.tsx @@ -1,13 +1,25 @@ import React from "react"; import EyeDropInput from "../../../../../ui/inputs/EyeDropInput"; -const PickAndPlaceAction: React.FC = () => { - return ( - <> - {}} /> - {}} /> - - ); +interface PickAndPlaceActionProps { + pickPointValue: string; + pickPointOnChange: (value: string) => void; + placePointValue: string; + placePointOnChange: (value: string) => void; +} + +const PickAndPlaceAction: React.FC = ({ + pickPointValue, + pickPointOnChange, + placePointValue, + placePointOnChange, +}) => { + return ( + <> + + + + ); }; export default PickAndPlaceAction; 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 9a044ac..78a32f5 100644 --- a/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/roboticArmMechanics.tsx +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/mechanics/roboticArmMechanics.tsx @@ -4,7 +4,7 @@ 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 } from "../../../../../../store/simulation/useSimulationStore"; +import { useSelectedEventData, useSelectedProduct, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { AddIcon, RemoveIcon, ResizeHeightIcon } from '../../../../../icons/ExportCommonIcons' import { handleResize } from '../../../../../../functions/handleResizePannel' @@ -12,159 +12,263 @@ import PickAndPlaceAction from '../actions/PickAndPlaceAction' function RoboticArmMechanics() { const actionsContainerRef = useRef(null); - - const [activeOption, setActiveOption] = useState("pickAndPlace"); - const [selectedItem, setSelectedItem] = useState<{ item: { uuid: string; name: string } | null; }>({ item: null }); + const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default"); + const [selectedPointData, setSelectedPointData] = useState(); const { selectedEventData } = useSelectedEventData(); - const { getEventByModelUuid, addAction } = useProductStore(); + const { getPointByUuid, updateEvent, updateAction, addAction, removeAction } = useProductStore(); const { selectedProduct } = useSelectedProduct(); - - const availableActions = { - defaultOption: "pickAndPlace", - options: ["pickAndPlace"] - }; - const [actions, setActions] = useState<{ uuid: string; name: string }[]>([]); + const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction(); useEffect(() => { - const event = getCurrentEventData(); - const actionList = getActionList(event as RoboticArmEventSchema); - setActions(actionList); - - if (actionList.length > 0 && !selectedItem.item) { - setSelectedItem({ item: actionList[0] }); + if (selectedEventData) { + const point = getPointByUuid( + selectedProduct.productId, + selectedEventData.data.modelUuid, + selectedEventData.selectedPoint + ) as RoboticArmPointSchema | undefined; + if (point) { + 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(); } }, [selectedEventData, selectedProduct]); - const getCurrentEventData = () => { - if (!selectedEventData?.data || !selectedProduct) return null; - return getEventByModelUuid(selectedProduct.productId, selectedEventData.data.modelUuid) || null; - }; - - const getActionList = (event: RoboticArmEventSchema) => { - if (!event || !('point' in event)) return []; - - return event.point.actions.flatMap( - (action) => - action.triggers.map((trigger) => ({ - uuid: trigger.triggerUuid, - name: trigger.triggerName, - })) - ) || []; - }; - - const handleActionToggle = (actionUuid: string) => { - const action = actions.find(a => a.uuid === actionUuid); - if (action) { - setSelectedItem({ item: action }); - } + const handleActionSelect = (actionUuid: string, actionName: string) => { + setSelectedAction(actionUuid, actionName); }; const handleAddAction = () => { - if (selectedEventData) { - const newEvent = { - actionUuid: THREE.MathUtils.generateUUID(), - actionName: `Action ${actions.length + 1}`, - actionType: "pickAndPlace" as const, - process: { - startPoint: null as [number, number, number] | null, - endPoint: null as [number, number, number] | null - }, - triggers: [] as TriggerSchema[] - } - addAction( - selectedProduct.productId, - selectedEventData?.data.modelUuid, - selectedEventData?.selectedPoint, - newEvent - ) - } + if (!selectedEventData || !selectedPointData) return; + + const newAction = { + actionUuid: THREE.MathUtils.generateUUID(), + actionName: `Action ${selectedPointData.actions.length + 1}`, + actionType: "pickAndPlace" as "pickAndPlace", + process: { + startPoint: null, + endPoint: null + }, + triggers: [] as TriggerSchema[] + }; + + addAction( + selectedProduct.productId, + selectedEventData.data.modelUuid, + selectedEventData.selectedPoint, + newAction + ); + + const updatedPoint = { + ...selectedPointData, + actions: [...selectedPointData.actions, newAction] + }; + setSelectedPointData(updatedPoint); + setSelectedAction(newAction.actionUuid, newAction.actionName); }; const handleDeleteAction = (actionUuid: string) => { + if (!selectedPointData) return; + removeAction(actionUuid); + const newActions = selectedPointData.actions.filter(a => a.actionUuid !== actionUuid); + + const updatedPoint = { + ...selectedPointData, + actions: newActions + }; + setSelectedPointData(updatedPoint); + + if (selectedAction.actionId === actionUuid) { + if (newActions.length > 0) { + setSelectedAction(newActions[0].actionUuid, newActions[0].actionName); + } else { + clearSelectedAction(); + } + } }; + 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 + }); + } + }; + + 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); + + 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); + + 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 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]}` + : ""; + return ( <> -
-
-
- { }} - onChange={(value) => console.log(value)} - /> -
-
-
-
-
-
-
Actions
-
handleAddAction()}> - Add + {selectedEventData && selectedPointData && ( + <> +
+
+
+ { }} + onChange={handleSpeedChange} + /> +
-
-
- {actions.map((action) => ( -
-
handleActionToggle(action.uuid)} - > - -
- {actions.length > 1 && ( -
handleDeleteAction(action.uuid)} - > - -
- )} + +
+
+
+
Actions
+
+ Add
- ))} -
-
handleResize(e, actionsContainerRef)} - > - +
+
+
+ {selectedPointData.actions.map((action) => ( +
+
handleActionSelect(action.actionUuid, action.actionName)} + > + +
+ {selectedPointData.actions.length > 1 && ( +
handleDeleteAction(action.actionUuid)} + > + +
+ )} +
+ ))} +
+
handleResize(e, actionsContainerRef)} + > + +
+
-
-
-
-
- -
-
- setActiveOption(option)} - /> - {activeOption === "pickAndPlace" && } -
-
-
- -
+ + {selectedAction.actionId && currentAction && ( +
+
+ +
+
+ { }} + disabled={true} + /> + +
+
+ +
+
+ )} + + )} ) } diff --git a/app/src/components/ui/list/List.tsx b/app/src/components/ui/list/List.tsx index cac0b43..ac21c5a 100644 --- a/app/src/components/ui/list/List.tsx +++ b/app/src/components/ui/list/List.tsx @@ -142,9 +142,6 @@ const List: React.FC = ({ items = [], remove }) => { ) ); } - - console.log('newName: ', newName); - } const checkZoneNameDuplicate = (name: string) => { return zones.some( diff --git a/app/src/modules/simulation/roboticArm/roboticArm.tsx b/app/src/modules/simulation/roboticArm/roboticArm.tsx index 89f6b76..d403c6a 100644 --- a/app/src/modules/simulation/roboticArm/roboticArm.tsx +++ b/app/src/modules/simulation/roboticArm/roboticArm.tsx @@ -94,6 +94,8 @@ function RoboticArm() { + <> + ); } diff --git a/app/src/modules/simulation/simulation.tsx b/app/src/modules/simulation/simulation.tsx index 5ca0ec5..757a9ef 100644 --- a/app/src/modules/simulation/simulation.tsx +++ b/app/src/modules/simulation/simulation.tsx @@ -23,7 +23,7 @@ function Simulation() { }, [events]) useEffect(() => { - // console.log('products: ', products); + console.log('products: ', products); }, [products]) return ( diff --git a/app/src/store/simulation/useSimulationStore.ts b/app/src/store/simulation/useSimulationStore.ts index ae6ac81..5085688 100644 --- a/app/src/store/simulation/useSimulationStore.ts +++ b/app/src/store/simulation/useSimulationStore.ts @@ -90,4 +90,28 @@ export const useSelectedProduct = create()( }); }, })) +); + +interface SelectedActionState { + selectedAction: { actionId: string; actionName: string }; + setSelectedAction: (actionId: string, actionName: string) => void; + clearSelectedAction: () => void; +} + +export const useSelectedAction = create()( + immer((set) => ({ + selectedAction: { actionId: '', actionName: '' }, + setSelectedAction: (actionId, actionName) => { + set((state) => { + state.selectedAction.actionId = actionId; + state.selectedAction.actionName = actionName; + }); + }, + clearSelectedAction: () => { + set((state) => { + state.selectedAction.actionId = ''; + state.selectedAction.actionName = ''; + }); + }, + })) ); \ No newline at end of file