feat: Enhance EventProperties and mechanics components with new mechanics; refactor action handling and improve state management for various actions

This commit is contained in:
Jerald-Golden-B 2025-04-25 11:19:40 +05:30
parent 4310b473d0
commit bfcb67c3c8
12 changed files with 663 additions and 245 deletions

View File

@ -25,6 +25,8 @@ import { useProductStore } from "../../../../../store/simulation/useProductStore
import ConveyorMechanics from "./mechanics/conveyorMechanics"; import ConveyorMechanics from "./mechanics/conveyorMechanics";
import VehicleMechanics from "./mechanics/vehicleMechanics"; import VehicleMechanics from "./mechanics/vehicleMechanics";
import RoboticArmMechanics from "./mechanics/roboticArmMechanics"; import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
import MachineMechanics from "./mechanics/machineMechanics";
import StorageMechanics from "./mechanics/storageMechanics";
const EventProperties: React.FC = () => { const EventProperties: React.FC = () => {
const actionsContainerRef = useRef<HTMLDivElement>(null); const actionsContainerRef = useRef<HTMLDivElement>(null);
@ -170,17 +172,6 @@ const EventProperties: React.FC = () => {
return "0.5"; return "0.5";
}; };
const handleActionToggle = (actionUuid: string) => {
const selected = actions.find(action => action.uuid === actionUuid);
if (selected) {
setSelectedItem({ item: selected });
}
};
const handleDeleteAction = (actionUuid: string) => {
// Implementation for delete action
};
return ( return (
<> <>
<div className="event-proprties-wrapper"> <div className="event-proprties-wrapper">
@ -189,112 +180,11 @@ const EventProperties: React.FC = () => {
<div className="header"> <div className="header">
<div className="header-value">{selectedEventData?.data.modelName}</div> <div className="header-value">{selectedEventData?.data.modelName}</div>
</div> </div>
<div className="global-props"> {assetType === 'conveyor' && <ConveyorMechanics />}
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value="0.5"
min={0}
step={0.1}
defaultValue={speed}
max={10}
activeOption="s"
onClick={() => { }}
onChange={(value) => console.log(value)}
/>
</div>
<div className="property-item">
<InputWithDropDown
label="Delay"
value="0.5"
min={0}
step={0.1}
defaultValue="0.5"
max={10}
activeOption="s"
onClick={() => { }}
onChange={(value) => console.log(value)}
/>
</div>
</div>
</div>
{assetType === 'roboticArm' &&
<div className="actions-list-container">
<div className="actions">
<div className="header">
<div className="header-value">Actions</div>
<div className="add-button" onClick={() => { }}>
<AddIcon /> Add
</div>
</div>
<div
className="lists-main-container"
ref={actionsContainerRef}
style={{ height: "120px" }}
>
<div className="list-container">
{actions.map((action) => (
<div
key={action.uuid}
className={`list-item ${selectedItem.item?.uuid === action.uuid ? "active" : ""}`}
>
<div
className="value"
onClick={() => handleActionToggle(action.uuid)}
>
<RenameInput value={action.name} />
</div>
{actions.length > 1 && (
<div
className="remove-button"
onClick={() => handleDeleteAction(action.uuid)}
>
<RemoveIcon />
</div>
)}
</div>
))}
</div>
<div
className="resize-icon"
id="action-resize"
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
>
<ResizeHeightIcon />
</div>
</div>
</div>
</div>
}
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput value="Action Name" />
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={availableActions.defaultOption}
options={availableActions.options}
onSelect={(option) => setActiveOption(option)}
/>
{activeOption === "default" && <DefaultAction />}
{activeOption === "spawn" && <SpawnAction />}
{activeOption === "swap" && <SwapAction />}
{activeOption === "despawn" && <DespawnAction />}
{activeOption === "travel" && <TravelAction />}
{activeOption === "pickAndPlace" && <PickAndPlaceAction />}
{activeOption === "process" && <ProcessAction />}
{activeOption === "store" && <StorageAction />}
</div>
</div>
<div className="tirgger">
<Trigger />
</div>
{/* {assetType === 'conveyor' && <ConveyorMechanics />}
{assetType === 'vehicle' && <VehicleMechanics />} {assetType === 'vehicle' && <VehicleMechanics />}
{assetType === 'roboticArm' && <RoboticArmMechanics />} */} {assetType === 'roboticArm' && <RoboticArmMechanics />}
{assetType === 'machine' && <MachineMechanics />}
{assetType === 'storageUnit' && <StorageMechanics />}
</> </>
} }
</div> </div>

View File

@ -1,19 +1,27 @@
import React from "react"; import React from "react";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown"; import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
const DelayAction: React.FC = () => { interface DelayActionProps {
value: string;
defaultValue: string;
min: number;
max: number;
onChange: (value: string) => void;
}
const DelayAction: React.FC<DelayActionProps> = ({ value, defaultValue, min, max, onChange }) => {
return ( return (
<> <>
<InputWithDropDown <InputWithDropDown
label="Delay" label="Delay"
value="0.5" value={value}
min={0} min={min}
step={0.1} step={0.1}
defaultValue="0.5" defaultValue={defaultValue}
max={10} max={max}
activeOption="s" activeOption="s"
onClick={() => { }} onClick={() => { }}
onChange={(value) => console.log(value)} onChange={onChange}
/> />
</> </>
); );

View File

@ -2,23 +2,47 @@ import React from "react";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown"; import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import SwapAction from "./SwapAction"; import SwapAction from "./SwapAction";
const ProcessAction: React.FC = () => { interface ProcessActionProps {
return ( value: string;
<> min: number;
<InputWithDropDown max: number;
label="Process Time" defaultValue: string;
value="6" onChange: (value: string) => void;
min={0} swapOptions: string[];
step={1} swapDefaultOption: string;
max={10} onSwapSelect: (value: string) => void;
defaultValue="0" }
activeOption="s"
onClick={() => {}} const ProcessAction: React.FC<ProcessActionProps> = ({
onChange={(value) => console.log(value)} value,
/> min,
<SwapAction /> max,
</> defaultValue,
); onChange,
swapOptions,
swapDefaultOption,
onSwapSelect,
}) => {
return (
<>
<InputWithDropDown
label="Process Time"
value={value}
min={min}
step={1}
max={max}
defaultValue={defaultValue}
activeOption="s"
onClick={() => { }}
onChange={onChange}
/>
<SwapAction
options={swapOptions}
defaultOption={swapDefaultOption}
onSelect={onSwapSelect}
/>
</>
);
}; };
export default ProcessAction; export default ProcessAction;

View File

@ -1,35 +1,72 @@
import React from "react"; import React from "react";
import PreviewSelectionWithUpload from "../../../../../ui/inputs/PreviewSelectionWithUpload"; import PreviewSelectionWithUpload from "../../../../../ui/inputs/PreviewSelectionWithUpload";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown"; import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
const SpawnAction: React.FC = () => { interface SpawnActionProps {
return ( onChangeInterval: (value: string) => void;
<> onChangeCount: (value: string) => void;
<InputWithDropDown defaultOption: string;
label="Spawn interval" options: string[];
value="0" onSelect: (option: string) => void;
min={0} intervalValue: string;
step={1} countValue: string;
defaultValue="0" intervalMin: number;
max={10} intervalMax: number;
activeOption="s" intervalDefaultValue: string;
onClick={() => {}} countMin: number;
onChange={(value) => console.log(value)} countMax: number;
/> countDefaultValue: string;
<InputWithDropDown }
label="Spawn count"
value="0" const SpawnAction: React.FC<SpawnActionProps> = ({
min={0} onChangeInterval,
step={1} onChangeCount,
defaultValue="0" defaultOption,
max={10} options,
activeOption="s" onSelect,
onClick={() => {}} intervalValue,
onChange={(value) => console.log(value)} countValue,
/> intervalMin,
<PreviewSelectionWithUpload /> intervalMax,
</> intervalDefaultValue,
); countMin,
countMax,
countDefaultValue,
}) => {
return (
<>
<InputWithDropDown
label="Spawn interval"
value={intervalValue}
min={intervalMin}
step={1}
defaultValue={intervalDefaultValue}
max={intervalMax}
activeOption="s"
onClick={() => { }}
onChange={onChangeInterval}
/>
<InputWithDropDown
label="Spawn count"
value={countValue}
min={countMin}
step={1}
defaultValue={countDefaultValue}
max={countMax}
activeOption="s"
onClick={() => { }}
onChange={onChangeCount}
/>
{/* <PreviewSelectionWithUpload /> */}
<LabledDropdown
label="Presets"
defaultOption={defaultOption}
options={options}
onSelect={onSelect}
/>
</>
);
}; };
export default SpawnAction; export default SpawnAction;

View File

@ -1,12 +1,27 @@
import React from "react"; import React from "react";
import PreviewSelectionWithUpload from "../../../../../ui/inputs/PreviewSelectionWithUpload"; import PreviewSelectionWithUpload from "../../../../../ui/inputs/PreviewSelectionWithUpload";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
const SwapAction: React.FC = () => { interface SwapActionProps {
return ( onSelect: (option: string) => void;
<> defaultOption: string;
<PreviewSelectionWithUpload /> options: string[];
</> }
);
const SwapAction: React.FC<SwapActionProps> = ({ onSelect, defaultOption, options }) => {
return (
<>
{/* <PreviewSelectionWithUpload /> */}
<LabledDropdown
label="Presets"
defaultOption={defaultOption}
options={options}
onSelect={onSelect}
/>
</>
);
}; };
export default SwapAction; export default SwapAction;

View File

@ -2,35 +2,77 @@ import React from "react";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown"; import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import EyeDropInput from "../../../../../ui/inputs/EyeDropInput"; import EyeDropInput from "../../../../../ui/inputs/EyeDropInput";
const TravelAction: React.FC = () => { interface TravelActionProps {
return ( loadCapacity: {
<> value: string;
<InputWithDropDown min: number;
label="Load Capacity" max: number;
value="" defaultValue: string;
min={0} onChange: (value: string) => void;
step={0.1} };
max={10} unloadDuration: {
defaultValue="0" value: string;
activeOption="s" min: number;
onClick={() => {}} max: number;
onChange={(value) => console.log(value)} defaultValue: string;
/> onChange: (value: string) => void;
<InputWithDropDown };
label="Unload Duration" pickPoint?: {
value="" value: string;
min={0} onChange: (value: string) => void;
step={0.1} };
max={10} unloadPoint?: {
defaultValue="0" value: string;
activeOption="s" onChange: (value: string) => void;
onClick={() => {}} };
onChange={(value) => console.log(value)} }
/>
<EyeDropInput label="Pick Point" value="na" onChange={() => {}} /> const TravelAction: React.FC<TravelActionProps> = ({
<EyeDropInput label="Unload Point" value="na" onChange={() => {}} /> loadCapacity,
</> unloadDuration,
); pickPoint,
unloadPoint,
}) => {
return (
<>
<InputWithDropDown
label="Load Capacity"
value={loadCapacity.value}
min={loadCapacity.min}
max={loadCapacity.max}
defaultValue={loadCapacity.defaultValue}
step={0.1}
activeOption="s"
onClick={() => { }}
onChange={loadCapacity.onChange}
/>
<InputWithDropDown
label="Unload Duration"
value={unloadDuration.value}
min={unloadDuration.min}
max={unloadDuration.max}
defaultValue={unloadDuration.defaultValue}
step={0.1}
activeOption="s"
onClick={() => { }}
onChange={unloadDuration.onChange}
/>
{pickPoint && (
<EyeDropInput
label="Pick Point"
value={pickPoint.value}
onChange={pickPoint.onChange}
/>
)}
{unloadPoint && (
<EyeDropInput
label="Unload Point"
value={unloadPoint.value}
onChange={unloadPoint.onChange}
/>
)}
</>
);
}; };
export default TravelAction; export default TravelAction;

View File

@ -12,27 +12,116 @@ import { useSelectedEventData, useSelectedProduct } from "../../../../../../stor
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
function ConveyorMechanics() { function ConveyorMechanics() {
const [activeOption, setActiveOption] = useState("default"); const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default");
const [selectedPointData, setSelectedPointData] = useState<PointsScheme | undefined>(); const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid } = useProductStore(); const { getPointByUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
useEffect(() => { useEffect(() => {
if (selectedEventData) { if (selectedEventData) {
const point = getPointByUuid(selectedProduct.productId, selectedEventData?.data.modelUuid, selectedEventData?.selectedPoint); const point = getPointByUuid(
selectedProduct.productId,
selectedEventData?.data.modelUuid,
selectedEventData?.selectedPoint
) as ConveyorPointSchema | undefined;
if (point && 'action' in point) { if (point && 'action' in point) {
setSelectedPointData(point as PointsScheme & { action: { actionType: string } }); setSelectedPointData(point);
setActiveOption((point as PointsScheme & { action: { actionType: string } }).action.actionType); setActiveOption(point.action.actionType as "default" | "spawn" | "swap" | "delay" | "despawn");
} }
} }
}, [selectedProduct, selectedEventData]) }, [selectedProduct, selectedEventData])
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);
updateAction(
selectedPointData.action.actionUuid,
{ actionType: validOption }
);
};
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 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 handleDelayChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ delay: value === "inherit" ? "inherit" : parseFloat(value) }
);
};
const availableActions = { const availableActions = {
defaultOption: "default", defaultOption: "default",
options: ["default", "spawn", "swap", "delay", "despawn"], options: ["default", "spawn", "swap", "delay", "despawn"],
}; };
// 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 currentMaterial = selectedPointData
? selectedPointData.action.material
: "Default material";
const currentSpawnCount = selectedPointData
? selectedPointData.action.spawnCount?.toString() || "1"
: "1";
const currentSpawnInterval = selectedPointData
? selectedPointData.action.spawnInterval?.toString() || "1"
: "1";
const currentDelay = selectedPointData
? selectedPointData.action.delay?.toString() || "0"
: "0";
return ( return (
<> <>
{selectedEventData && {selectedEventData &&
@ -42,14 +131,14 @@ function ConveyorMechanics() {
<div className="property-item"> <div className="property-item">
<InputWithDropDown <InputWithDropDown
label="Speed" label="Speed"
value="0.5" value={currentSpeed}
min={0} min={0}
step={0.1} step={0.1}
defaultValue={"0.5"} defaultValue={"0.5"}
max={10} max={10}
activeOption="s" activeOption="m/s"
onClick={() => { }} onClick={() => { }}
onChange={(value) => console.log(value)} onChange={handleSpeedChange}
/> />
</div> </div>
</div> </div>
@ -57,21 +146,58 @@ function ConveyorMechanics() {
<div className="selected-actions-details"> <div className="selected-actions-details">
<div className="selected-actions-header"> <div className="selected-actions-header">
<RenameInput value="Action Name" /> <RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div> </div>
<div className="selected-actions-list"> <div className="selected-actions-list">
<LabledDropdown <LabledDropdown
defaultOption={selectedPointData && 'action' in selectedPointData defaultOption={selectedPointData
? (selectedPointData as PointsScheme & { action: { actionType: string } }).action.actionType ? selectedPointData.action.actionType
: "default"} : "default"}
options={availableActions.options} options={availableActions.options}
onSelect={(option) => setActiveOption(option)} onSelect={handleActionTypeChange}
/> />
{activeOption === "default" && <DefaultAction />} {activeOption === "default" &&
{activeOption === "spawn" && <SpawnAction />} <DefaultAction />
{activeOption === "swap" && <SwapAction />} }
{activeOption === "despawn" && <DespawnAction />} {activeOption === "spawn" &&
{activeOption === "delay" && <DelayAction />} <SpawnAction
onChangeCount={handleSpawnCountChange}
options={["Default material", "Material 1", "Material 2"]}
defaultOption={currentMaterial}
onSelect={handleMaterialSelect}
onChangeInterval={handleSpawnIntervalChange}
intervalValue={currentSpawnInterval}
countValue={currentSpawnCount}
intervalMin={1}
intervalMax={60}
intervalDefaultValue="1"
countMin={1}
countMax={100}
countDefaultValue="1"
/>
}
{activeOption === "swap" &&
<SwapAction
options={["Default material", "Material 1", "Material 2"]}
defaultOption={currentMaterial}
onSelect={handleMaterialSelect}
/>
}
{activeOption === "despawn" &&
<DespawnAction />
}
{activeOption === "delay" &&
<DelayAction
value={currentDelay}
defaultValue="0"
min={0}
max={60}
onChange={handleDelayChange}
/>
}
</div> </div>
</div> </div>
<div className="tirgger"> <div className="tirgger">

View File

@ -1,8 +1,122 @@
import React from 'react' 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 { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ProcessAction from '../actions/ProcessAction'
function MachineMechanics() { 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();
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])
const handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return;
const validOption = option as "process";
setActiveOption(validOption);
updateAction(
selectedPointData.action.actionUuid,
{ actionType: validOption }
);
};
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 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";
const currentProcessTime = selectedPointData
? selectedPointData.action.processTime.toString()
: "1";
const currentMaterial = selectedPointData
? selectedPointData.action.swapMaterial
: "Default material";
const availableActions = {
defaultOption: "process",
options: ["process"],
};
return ( return (
<> <>
{selectedEventData &&
<>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption="process"
options={availableActions.options}
onSelect={handleActionTypeChange}
disabled={true}
/>
{activeOption === "process" &&
<ProcessAction
value={currentProcessTime}
min={0.1}
max={60}
defaultValue="1"
onChange={handleProcessTimeChange}
swapOptions={["Default material", "Material 1", "Material 2"]}
swapDefaultOption={currentMaterial}
onSwapSelect={handleMaterialSelect}
/>
}
</div>
</div>
<div className="tirgger">
<Trigger />
</div>
</>
}
</> </>
) )
} }

View File

@ -1,8 +1,57 @@
import React from 'react' 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 { useProductStore } from "../../../../../../store/simulation/useProductStore";
import StorageAction from '../actions/StorageAction';
function StorageMechanics() { function StorageMechanics() {
const [activeOption, setActiveOption] = useState("default");
const [selectedPointData, setSelectedPointData] = useState<PointsScheme | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct();
useEffect(() => {
if (selectedEventData) {
const point = getPointByUuid(selectedProduct.productId, selectedEventData?.data.modelUuid, selectedEventData?.selectedPoint);
if (point && 'action' in point) {
setSelectedPointData(point as PointsScheme & { action: { actionType: string } });
setActiveOption((point as PointsScheme & { action: { actionType: string } }).action.actionType);
}
}
}, [selectedProduct, selectedEventData])
const availableActions = {
defaultOption: "store",
options: ["store", "spawn"],
};
return ( return (
<> <>
{selectedEventData &&
<>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput value="Action Name" />
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={selectedPointData && 'action' in selectedPointData
? (selectedPointData as PointsScheme & { action: { actionType: string } }).action.actionType
: "default"}
options={availableActions.options}
onSelect={(option) => setActiveOption(option)}
/>
{activeOption === "store" && <StorageAction />}
</div>
</div>
<div className="tirgger">
<Trigger />
</div>
</>
}
</> </>
) )
} }

View File

@ -8,22 +8,114 @@ import { useProductStore } from "../../../../../../store/simulation/useProductSt
import TravelAction from '../actions/TravelAction' import TravelAction from '../actions/TravelAction'
function VehicleMechanics() { function VehicleMechanics() {
const [activeOption, setActiveOption] = useState("default"); const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
const [selectedPointData, setSelectedPointData] = useState<PointsScheme | undefined>(); const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid } = useProductStore(); const { getPointByUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = useSelectedProduct();
useEffect(() => { useEffect(() => {
if (selectedEventData) { if (selectedEventData) {
const point = getPointByUuid(selectedProduct.productId, selectedEventData?.data.modelUuid, selectedEventData?.selectedPoint); const point = getPointByUuid(
if (point && 'action' in point) { selectedProduct.productId,
setSelectedPointData(point as PointsScheme & { action: { actionType: string } }); selectedEventData.data.modelUuid,
setActiveOption((point as PointsScheme & { action: { actionType: string } }).action.actionType); selectedEventData.selectedPoint
) as VehiclePointSchema | undefined;
if (point) {
setSelectedPointData(point);
setActiveOption(point.action.actionType as "travel");
} }
} }
}, [selectedProduct, selectedEventData]) }, [selectedProduct, selectedEventData])
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 "travel";
setActiveOption(validOption);
updateAction(
selectedPointData.action.actionUuid,
{ actionType: validOption }
);
};
const handleRenameAction = (newName: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ actionName: newName }
);
};
const handleLoadCapacityChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ loadCapacity: parseFloat(value) }
);
};
const handleUnloadDurationChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ unLoadDuration: parseFloat(value) }
);
};
const handlePickPointChange = (value: string) => {
if (!selectedPointData) return;
const [x, y, z] = value.split(',').map(Number);
updateAction(
selectedPointData.action.actionUuid,
{ pickUpPoint: { x, y, z } }
);
};
const handleUnloadPointChange = (value: string) => {
if (!selectedPointData) return;
const [x, y, z] = value.split(',').map(Number);
updateAction(
selectedPointData.action.actionUuid,
{ unLoadPoint: { x, y, z } }
);
};
// Get current values from store
const currentSpeed = selectedEventData?.data.type === "vehicle"
? selectedEventData.data.speed.toString()
: "0.5";
const currentActionName = selectedPointData
? selectedPointData.action.actionName
: "Action Name";
const currentLoadCapacity = selectedPointData
? selectedPointData.action.loadCapacity.toString()
: "1";
const currentUnloadDuration = selectedPointData
? selectedPointData.action.unLoadDuration.toString()
: "1";
const currentPickPoint = selectedPointData?.action.pickUpPoint
? `${selectedPointData.action.pickUpPoint.x},${selectedPointData.action.pickUpPoint.y},${selectedPointData.action.pickUpPoint.z}`
: "";
const currentUnloadPoint = selectedPointData?.action.unLoadPoint
? `${selectedPointData.action.unLoadPoint.x},${selectedPointData.action.unLoadPoint.y},${selectedPointData.action.unLoadPoint.z}`
: "";
const availableActions = { const availableActions = {
defaultOption: "travel", defaultOption: "travel",
options: ["travel"], options: ["travel"],
@ -38,14 +130,14 @@ function VehicleMechanics() {
<div className="property-item"> <div className="property-item">
<InputWithDropDown <InputWithDropDown
label="Speed" label="Speed"
value="0.5" value={currentSpeed}
min={0} min={0}
step={0.1} step={0.1}
defaultValue={"0.5"} defaultValue={"0.5"}
max={10} max={10}
activeOption="s" activeOption="m/s"
onClick={() => { }} onClick={() => { }}
onChange={(value) => console.log(value)} onChange={handleSpeedChange}
/> />
</div> </div>
</div> </div>
@ -53,17 +145,44 @@ function VehicleMechanics() {
<div className="selected-actions-details"> <div className="selected-actions-details">
<div className="selected-actions-header"> <div className="selected-actions-header">
<RenameInput value="Action Name" /> <RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div> </div>
<div className="selected-actions-list"> <div className="selected-actions-list">
<LabledDropdown <LabledDropdown
defaultOption={selectedPointData && 'action' in selectedPointData defaultOption="travel"
? (selectedPointData as PointsScheme & { action: { actionType: string } }).action.actionType
: "default"}
options={availableActions.options} options={availableActions.options}
onSelect={(option) => setActiveOption(option)} onSelect={handleActionTypeChange}
/> />
{activeOption === "travel" && <TravelAction />}
{activeOption === 'travel' &&
<TravelAction
loadCapacity={{
value: currentLoadCapacity,
min: 1,
max: 100,
defaultValue: "1",
onChange: handleLoadCapacityChange,
}}
unloadDuration={{
value: currentUnloadDuration,
min: 1,
max: 60,
defaultValue: "1",
onChange: handleUnloadDurationChange,
}}
// pickPoint={{
// value: currentPickPoint,
// onChange: handlePickPointChange,
// }}
// unloadPoint={{
// value: currentUnloadPoint,
// onChange: handleUnloadPointChange,
// }}
/>
}
</div> </div>
</div> </div>
<div className="tirgger"> <div className="tirgger">

View File

@ -35,12 +35,6 @@ const PreviewSelectionWithUpload: React.FC = () => {
Upload here Upload here
</label> </label>
</div> </div>
<LabledDropdown
label="Presets"
defaultOption={"Default material"}
options={["Default material", "Product 1", "Product 2"]}
onSelect={(option) => console.log(option)}
/>
</div> </div>
</div> </div>
); );

View File

@ -243,7 +243,7 @@ function processLoadedModel(
rotation: [0, 0, 0], rotation: [0, 0, 0],
action: { action: {
actionUuid: THREE.MathUtils.generateUUID(), actionUuid: THREE.MathUtils.generateUUID(),
actionName: `Action ${index}`, actionName: `Action ${index + 1}`,
actionType: 'default', actionType: 'default',
material: 'inherit', material: 'inherit',
delay: 0, delay: 0,