Refactor mechanics components to use ActionsList for action management

- Consolidated action handling logic into a new ActionsList component for better code organization and reusability.
- Updated RoboticArmMechanics, StorageMechanics, and VehicleMechanics to utilize the new ActionsList component.
- Improved state management and action updates within the mechanics components.
- Enhanced UI responsiveness and styling in sidebar and real-time visualization pages.
This commit is contained in:
Vishnu 2025-04-28 18:08:27 +05:30
parent 5b6badaa52
commit 897633d4cc
10 changed files with 1192 additions and 948 deletions

View File

@ -1,148 +1,161 @@
import React, { useEffect } from "react";
import Header from "./Header";
import useModuleStore, {
useSubModuleStore,
useSubModuleStore,
} from "../../../store/useModuleStore";
import {
AnalysisIcon,
MechanicsIcon,
PropertiesIcon,
SimulationIcon,
AnalysisIcon,
MechanicsIcon,
PropertiesIcon,
SimulationIcon,
} from "../../icons/SimulationIcons";
import useToggleStore from "../../../store/useUIToggleStore";
import Visualization from "./visualization/Visualization";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import { useSelectedFloorItem } from "../../../store/store";
import { useSelectedEventData, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
import {
useSelectedEventData,
useSelectedEventSphere,
} from "../../../store/simulation/useSimulationStore";
import GlobalProperties from "./properties/GlobalProperties";
import AsstePropertiies from "./properties/AssetProperties";
import ZoneProperties from "./properties/ZoneProperties";
import EventProperties from "./properties/eventProperties/EventProperties";
const SideBarRight: React.FC = () => {
const { activeModule } = useModuleStore();
const { toggleUI } = useToggleStore();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { activeModule } = useModuleStore();
const { toggleUI } = useToggleStore();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
// Reset activeList whenever activeModule changes
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule]);
// Reset activeList whenever activeModule changes
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule, setSubModule]);
useEffect(() => {
if (activeModule !== "mechanics" && selectedEventData && selectedEventSphere) {
setSubModule("mechanics");
} else if (!selectedEventData && !selectedEventSphere) {
if (activeModule === 'simulation') {
setSubModule("simulations");
}
};
}, [activeModule, selectedEventData, selectedEventSphere])
useEffect(() => {
if (
activeModule !== "mechanics" &&
selectedEventData &&
selectedEventSphere
) {
setSubModule("mechanics");
} else if (!selectedEventData && !selectedEventSphere) {
if (activeModule === "simulation") {
setSubModule("simulations");
}
}
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
return (
<div className="sidebar-right-wrapper">
<Header />
{toggleUI && (
<div className="sidebar-actions-container">
<div
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""
}`}
onClick={() => setSubModule("properties")}
>
<PropertiesIcon isActive={subModule === "properties"} />
</div>
{activeModule === "simulation" && (
<>
<div
className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""
}`}
onClick={() => setSubModule("mechanics")}
>
<MechanicsIcon isActive={subModule === "mechanics"} />
</div>
<div
className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""
}`}
onClick={() => setSubModule("simulations")}
>
<SimulationIcon isActive={subModule === "simulations"} />
</div>
<div
className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""
}`}
onClick={() => setSubModule("analysis")}
>
<AnalysisIcon isActive={subModule === "analysis"} />
</div>
</>
)}
</div>
)}
{/* process builder */}
{toggleUI &&
subModule === "properties" &&
activeModule !== "visualization" &&
!selectedFloorItem && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<GlobalProperties />
</div>
</div>
)}
{toggleUI &&
subModule === "properties" &&
activeModule !== "visualization" &&
selectedFloorItem && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<AsstePropertiies />
</div>
</div>
)}
{toggleUI &&
subModule === "zoneProperties" &&
(activeModule === "builder" || activeModule === "simulation") && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<ZoneProperties />
</div>
</div>
)}
{/* simulation */}
{toggleUI && activeModule === "simulation" && (
<>
{subModule === "simulations" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Simulations />
</div>
</div>
)}
{subModule === "mechanics" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<EventProperties />
</div>
</div>
)}
{subModule === "analysis" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Analysis />
</div>
</div>
)}
</>
)}
{/* realtime visualization */}
{toggleUI && activeModule === "visualization" && <Visualization />}
return (
<div className="sidebar-right-wrapper">
<Header />
{toggleUI && (
<div className="sidebar-actions-container">
{activeModule !== "simulation" && (
<button
className={`sidebar-action-list ${
subModule === "properties" ? "active" : ""
}`}
onClick={() => setSubModule("properties")}
>
<PropertiesIcon isActive={subModule === "properties"} />
</button>
)}
{activeModule === "simulation" && (
<>
<button
className={`sidebar-action-list ${
subModule === "simulations" ? "active" : ""
}`}
onClick={() => setSubModule("simulations")}
>
<SimulationIcon isActive={subModule === "simulations"} />
</button>
<button
className={`sidebar-action-list ${
subModule === "mechanics" ? "active" : ""
}`}
onClick={() => setSubModule("mechanics")}
>
<MechanicsIcon isActive={subModule === "mechanics"} />
</button>
<button
className={`sidebar-action-list ${
subModule === "analysis" ? "active" : ""
}`}
onClick={() => setSubModule("analysis")}
>
<AnalysisIcon isActive={subModule === "analysis"} />
</button>
</>
)}
</div>
);
)}
{/* process builder */}
{toggleUI &&
subModule === "properties" &&
activeModule !== "visualization" &&
!selectedFloorItem && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<GlobalProperties />
</div>
</div>
)}
{toggleUI &&
subModule === "properties" &&
activeModule !== "visualization" &&
selectedFloorItem && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<AsstePropertiies />
</div>
</div>
)}
{toggleUI &&
subModule === "zoneProperties" &&
(activeModule === "builder" || activeModule === "simulation") && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<ZoneProperties />
</div>
</div>
)}
{/* simulation */}
{toggleUI && activeModule === "simulation" && (
<>
{subModule === "simulations" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Simulations />
</div>
</div>
)}
{subModule === "mechanics" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<EventProperties />
</div>
</div>
)}
{subModule === "analysis" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Analysis />
</div>
</div>
)}
</>
)}
{/* realtime visualization */}
{toggleUI && activeModule === "visualization" && <Visualization />}
</div>
);
};
export default SideBarRight;
export default SideBarRight;

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import {
useSelectedEventData,
useSelectedEventSphere,
useSelectedProduct,
} from "../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore";
@ -9,6 +10,7 @@ import VehicleMechanics from "./mechanics/vehicleMechanics";
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
import MachineMechanics from "./mechanics/machineMechanics";
import StorageMechanics from "./mechanics/storageMechanics";
import { AddIcon } from "../../../../icons/ExportCommonIcons";
const EventProperties: React.FC = () => {
const { selectedEventData } = useSelectedEventData();
@ -18,13 +20,15 @@ const EventProperties: React.FC = () => {
null
);
const [assetType, setAssetType] = useState<string | null>(null);
const { products } = useProductStore();
const { selectedEventSphere } = useSelectedEventSphere();
useEffect(() => {
const event = getCurrentEventData();
setCurrentEventData(event);
const type = determineAssetType(event);
setAssetType(type);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedEventData, selectedProduct]);
const getCurrentEventData = () => {
@ -72,6 +76,39 @@ const EventProperties: React.FC = () => {
{assetType === "storageUnit" && <StorageMechanics />}
</>
)}
{!currentEventData && selectedEventSphere && (
<div className="no-event-selected">
<p>
<strong>Oops!</strong> It looks like this object doesn't have an
event assigned yet. To continue, please link it to one of the
products below.
</p>
<div className="products-list">
<p>
<strong>Here are some products you can add it to:</strong>
</p>
<ul>
{products.map((product) => (
<li key={product.productId}>
<button>
<AddIcon />
{product.productName}
</button>
</li>
))}
</ul>
</div>
</div>
)}
{!selectedEventSphere && (
<div className="no-event-selected">
<p>
<strong>Oops!</strong> It looks like you haven't selected an event
point yet. Please select an event to view its properties.
</p>
</div>
)}
</div>
);
};

View File

@ -0,0 +1,197 @@
import React, { useRef } from "react";
import {
AddIcon,
RemoveIcon,
ResizeHeightIcon,
} from "../../../../../icons/ExportCommonIcons";
import RenameInput from "../../../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../../../functions/handleResizePannel";
import {
useSelectedAction,
useSelectedEventData,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore";
import { MathUtils } from "three";
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
interface ActionsListProps {
setSelectedPointData: (data: any) => void; // You can replace `any` with a more specific type if you have one
selectedPointData: any; // You can replace `any` with a more specific type if you have one
// ui control props
multipleAction?: boolean;
}
const ActionsList: React.FC<ActionsListProps> = ({
setSelectedPointData,
selectedPointData,
multipleAction = false,
}) => {
const actionsContainerRef = useRef<HTMLDivElement>(null);
// store
const { selectedEventData } = useSelectedEventData();
const { updateAction, addAction, removeAction } = useProductStore();
const { selectedProduct } = useSelectedProduct();
const { selectedAction, setSelectedAction, clearSelectedAction } =
useSelectedAction();
const handleAddAction = () => {
if (!selectedEventData || !selectedPointData) return;
const newAction = {
actionUuid: MathUtils.generateUUID(),
actionName: `Action ${selectedPointData.actions.length + 1}`,
actionType: "pickAndPlace" as const,
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: any) => 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?.actions) {
const updatedActions = selectedPointData.actions.map((action: any) =>
action.actionUuid === selectedAction.actionId
? { ...action, actionName: newName }
: action
);
setSelectedPointData({
...selectedPointData,
actions: updatedActions,
});
} else {
// write logic for single action
return;
}
};
const handleActionSelect = (actionUuid: string, actionName: string) => {
setSelectedAction(actionUuid, actionName);
};
return (
<div className="actions-list-container">
<div className="actions">
<div className="header">
<div className="header-value">Actions</div>
{multipleAction && (
<button className="add-button" onClick={() => handleAddAction()}>
<AddIcon /> Add
</button>
)}
</div>
<div
className="lists-main-container"
ref={actionsContainerRef}
style={{ height: "120px" }}
>
<div className="list-container">
{multipleAction &&
selectedPointData.actions.map((action: any) => (
<div
key={action.actionUuid}
className={`list-item ${
selectedAction.actionId === action.actionUuid
? "active"
: ""
}`}
>
<button
className="value"
onClick={() =>
handleActionSelect(action.actionUuid, action.actionName)
}
>
<RenameInput
value={action.actionName}
onRename={handleRenameAction}
/>
</button>
{selectedPointData.actions.length > 1 && (
<button
className="remove-button"
onClick={() => handleDeleteAction(action.actionUuid)}
>
<RemoveIcon />
</button>
)}
</div>
))}
{!multipleAction && selectedPointData && (
<div
key={selectedPointData.action.actionUuid}
className={`list-item active`}
>
<button
className="value"
onClick={() =>
handleActionSelect(
selectedPointData.action.actionUuid,
selectedPointData.action.actionName
)
}
>
<RenameInput
value={selectedPointData.action.actionName}
onRename={handleRenameAction}
/>
</button>
</div>
)}
</div>
<button
className="resize-icon"
id="action-resize"
onMouseDown={(e: any) => handleResize(e, actionsContainerRef)}
>
<ResizeHeightIcon />
</button>
</div>
</div>
</div>
);
};
export default ActionsList;

View File

@ -1,212 +1,224 @@
import { useEffect, useState } from 'react'
import InputWithDropDown from '../../../../../ui/inputs/InputWithDropDown'
import DelayAction from '../actions/DelayAction'
import RenameInput from '../../../../../ui/inputs/RenameInput'
import LabledDropdown from '../../../../../ui/inputs/LabledDropdown'
import DespawnAction from '../actions/DespawnAction'
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 { useEffect, useState } from "react";
import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
import DelayAction from "../actions/DelayAction";
import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import DespawnAction from "../actions/DespawnAction";
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 { 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<
ConveyorPointSchema | undefined
>();
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])
const handleSpeedChange = (value: string) => {
if (!selectedEventData) return;
updateEvent(
selectedProduct.productId,
selectedEventData.data.modelUuid,
{ speed: parseFloat(value) }
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 handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return;
const validOption = option as "default" | "spawn" | "swap" | "delay" | "despawn";
setActiveOption(validOption);
const handleSpeedChange = (value: string) => {
if (!selectedEventData) return;
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
speed: parseFloat(value),
});
};
updateAction(
selectedPointData.action.actionUuid,
{ actionType: validOption }
);
};
const handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return;
const validOption = option as
| "default"
| "spawn"
| "swap"
| "delay"
| "despawn";
setActiveOption(validOption);
const handleRenameAction = (newName: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ actionName: newName }
);
};
updateAction(selectedPointData.action.actionUuid, {
actionType: validOption,
});
};
const handleSpawnCountChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ spawnCount: value === "inherit" ? "inherit" : parseFloat(value) }
);
};
const handleRenameAction = (newName: string) => {
if (!selectedPointData) return;
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
};
const handleSpawnIntervalChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ spawnInterval: value === "inherit" ? "inherit" : parseFloat(value) }
);
};
const handleSpawnCountChange = (value: string) => {
if (!selectedPointData) return;
updateAction(selectedPointData.action.actionUuid, {
spawnCount: value === "inherit" ? "inherit" : parseFloat(value),
});
};
const handleMaterialSelect = (material: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ material }
);
};
const handleSpawnIntervalChange = (value: string) => {
if (!selectedPointData) return;
updateAction(selectedPointData.action.actionUuid, {
spawnInterval: value === "inherit" ? "inherit" : parseFloat(value),
});
};
const handleDelayChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ delay: value === "inherit" ? "inherit" : parseFloat(value) }
);
};
const handleMaterialSelect = (material: string) => {
if (!selectedPointData) return;
updateAction(selectedPointData.action.actionUuid, { material });
};
const availableActions = {
defaultOption: "default",
options: ["default", "spawn", "swap", "delay", "despawn"],
};
const handleDelayChange = (value: string) => {
if (!selectedPointData) return;
updateAction(selectedPointData.action.actionUuid, {
delay: value === "inherit" ? "inherit" : parseFloat(value),
});
};
// Get current values from store
const currentSpeed = selectedEventData?.data.type === "transfer"
? selectedEventData.data.speed.toString()
: "0.5";
const availableActions = {
defaultOption: "default",
options: ["default", "spawn", "swap", "delay", "despawn"],
};
const currentActionName = selectedPointData
? selectedPointData.action.actionName
: "Action Name";
// Get current values from store
const currentSpeed =
selectedEventData?.data.type === "transfer"
? selectedEventData.data.speed.toString()
: "0.5";
const currentMaterial = selectedPointData
? selectedPointData.action.material
: "Default material";
const currentActionName = selectedPointData
? selectedPointData.action.actionName
: "Action Name";
const currentSpawnCount = selectedPointData
? selectedPointData.action.spawnCount?.toString() || "1"
: "1";
const currentMaterial = selectedPointData
? selectedPointData.action.material
: "Default material";
const currentSpawnInterval = selectedPointData
? selectedPointData.action.spawnInterval?.toString() || "1"
: "1";
const currentSpawnCount = selectedPointData
? selectedPointData.action.spawnCount?.toString() || "1"
: "1";
const currentDelay = selectedPointData
? selectedPointData.action.delay?.toString() || "0"
: "0";
const currentSpawnInterval = selectedPointData
? selectedPointData.action.spawnInterval?.toString() || "1"
: "1";
return (
const currentDelay = selectedPointData
? selectedPointData.action.delay?.toString() || "0"
: "0";
return (
<>
{selectedEventData && (
<>
{selectedEventData &&
<>
<div key={selectedPointData?.uuid} className="global-props">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => { }}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<div key={selectedPointData?.uuid} className="global-props">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => {}}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={selectedPointData
? selectedPointData.action.actionType
: "default"}
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{activeOption === "default" &&
<DefaultAction />
}
{activeOption === "spawn" &&
<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 className="tirgger">
<Trigger />
</div>
</>
}
<ActionsList
setSelectedPointData={setSelectedPointData}
selectedPointData={selectedPointData}
/>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={
selectedPointData
? selectedPointData.action.actionType
: "default"
}
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{activeOption === "default" && <DefaultAction />}
{activeOption === "spawn" && (
<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 className="tirgger">
<Trigger />
</div>
</>
)
)}
</>
);
}
export default ConveyorMechanics
export default ConveyorMechanics;

View File

@ -1,123 +1,129 @@
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 { 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'
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<
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])
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 (
return (
<>
{selectedEventData && (
<>
{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}
/>
{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>
</>
}
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<ActionsList
setSelectedPointData={setSelectedPointData}
selectedPointData={selectedPointData}
/>
<div className="selected-actions-list">
<LabledDropdown
defaultOption="process"
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{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>
</>
)
)}
</>
);
}
export default MachineMechanics
export default MachineMechanics;

View File

@ -1,276 +1,194 @@
import { useEffect, useRef, useState } from 'react'
import * as THREE from 'three';
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 { useEffect, useState } from "react";
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 { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { AddIcon, RemoveIcon, ResizeHeightIcon } from '../../../../../icons/ExportCommonIcons'
import { handleResize } from '../../../../../../functions/handleResizePannel'
import PickAndPlaceAction from '../actions/PickAndPlaceAction'
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
import ActionsList from "../components/ActionsList";
function RoboticArmMechanics() {
const actionsContainerRef = useRef<HTMLDivElement>(null);
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default");
const [selectedPointData, setSelectedPointData] = useState<RoboticArmPointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateEvent, updateAction, addAction, removeAction } = useProductStore();
const { selectedProduct } = useSelectedProduct();
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
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();
useEffect(() => {
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();
useEffect(() => {
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
);
}
}, [selectedEventData, selectedProduct]);
}
} else {
clearSelectedAction();
}
}, [
clearSelectedAction,
getPointByUuid,
selectedAction.actionId,
selectedEventData,
selectedProduct,
setSelectedAction,
]);
const handleActionSelect = (actionUuid: string, actionName: string) => {
setSelectedAction(actionUuid, actionName);
};
const handleRenameAction = (newName: string) => {
if (!selectedAction.actionId) return;
updateAction(selectedAction.actionId, { actionName: newName });
const handleAddAction = () => {
if (!selectedEventData || !selectedPointData) return;
if (selectedPointData) {
const updatedActions = selectedPointData.actions.map((action) =>
action.actionUuid === selectedAction.actionId
? { ...action, actionName: newName }
: action
);
setSelectedPointData({
...selectedPointData,
actions: updatedActions,
});
}
};
const newAction = {
actionUuid: THREE.MathUtils.generateUUID(),
actionName: `Action ${selectedPointData.actions.length + 1}`,
actionType: "pickAndPlace" as "pickAndPlace",
process: {
startPoint: null,
endPoint: null
},
triggers: [] as TriggerSchema[]
};
const handleSpeedChange = (value: string) => {
if (!selectedEventData) return;
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
speed: parseFloat(value),
});
};
addAction(
selectedProduct.productId,
selectedEventData.data.modelUuid,
selectedEventData.selectedPoint,
newAction
);
const handlePickPointChange = (value: string) => {
if (!selectedAction.actionId || !selectedPointData) return;
const [x, y, z] = value.split(",").map(Number);
const updatedPoint = {
...selectedPointData,
actions: [...selectedPointData.actions, newAction]
};
setSelectedPointData(updatedPoint);
setSelectedAction(newAction.actionUuid, newAction.actionName);
};
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 handleDeleteAction = (actionUuid: string) => {
if (!selectedPointData) return;
const handlePlacePointChange = (value: string) => {
if (!selectedAction.actionId || !selectedPointData) return;
const [x, y, z] = value.split(",").map(Number);
removeAction(actionUuid);
const newActions = selectedPointData.actions.filter(a => a.actionUuid !== actionUuid);
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 updatedPoint = {
...selectedPointData,
actions: newActions
};
setSelectedPointData(updatedPoint);
const availableActions = {
defaultOption: "pickAndPlace",
options: ["pickAndPlace"],
};
if (selectedAction.actionId === actionUuid) {
if (newActions.length > 0) {
setSelectedAction(newActions[0].actionUuid, newActions[0].actionName);
} else {
clearSelectedAction();
}
}
};
const currentSpeed =
selectedEventData?.data.type === "roboticArm"
? selectedEventData.data.speed.toString()
: "0.5";
const handleRenameAction = (newName: string) => {
if (!selectedAction.actionId) return;
updateAction(
selectedAction.actionId,
{ actionName: newName }
);
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]}`
: "";
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 (
return (
<>
{selectedEventData && selectedPointData && (
<>
{selectedEventData && selectedPointData && (
<>
<div className="global-props">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => { }}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<div className="global-props">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => {}}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<div className="actions-list-container">
<div className="actions">
<div className="header">
<div className="header-value">Actions</div>
<div className="add-button" onClick={handleAddAction}>
<AddIcon /> Add
</div>
</div>
<div
className="lists-main-container"
ref={actionsContainerRef}
style={{ height: "120px" }}
>
<div className="list-container">
{selectedPointData.actions.map((action) => (
<div
key={action.actionUuid}
className={`list-item ${selectedAction.actionId === action.actionUuid ? "active" : ""}`}
>
<div
className="value"
onClick={() => handleActionSelect(action.actionUuid, action.actionName)}
>
<RenameInput
value={action.actionName}
onRename={handleRenameAction}
/>
</div>
{selectedPointData.actions.length > 1 && (
<div
className="remove-button"
onClick={() => handleDeleteAction(action.actionUuid)}
>
<RemoveIcon />
</div>
)}
</div>
))}
</div>
<div
className="resize-icon"
id="action-resize"
onMouseDown={(e) => handleResize(e, actionsContainerRef)}
>
<ResizeHeightIcon />
</div>
</div>
</div>
</div>
<ActionsList
setSelectedPointData={setSelectedPointData}
selectedPointData={selectedPointData}
multipleAction
/>
{selectedAction.actionId && currentAction && (
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={selectedAction.actionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={activeOption}
options={availableActions.options}
onSelect={() => { }}
disabled={true}
/>
<PickAndPlaceAction
pickPointValue={currentPickPoint}
pickPointOnChange={handlePickPointChange}
placePointValue={currentPlacePoint}
placePointOnChange={handlePlacePointChange}
/>
</div>
<div className="tirgger">
<Trigger />
</div>
</div>
)}
</>
)}
{selectedAction.actionId && currentAction && (
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={selectedAction.actionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={activeOption}
options={availableActions.options}
onSelect={() => {}}
disabled={true}
/>
<PickAndPlaceAction
pickPointValue={currentPickPoint}
pickPointOnChange={handlePickPointChange}
placePointValue={currentPlacePoint}
placePointOnChange={handlePlacePointChange}
/>
</div>
<div className="tirgger">
<Trigger />
</div>
</div>
)}
</>
)
)}
</>
);
}
export default RoboticArmMechanics
export default RoboticArmMechanics;

View File

@ -1,113 +1,120 @@
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 { 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';
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<
StoragePointSchema | 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 StoragePointSchema | undefined;
if (point && 'action' in point) {
setSelectedPointData(point);
setActiveOption(point.action.actionType as "store" | "spawn");
}
}
}, [selectedProduct, selectedEventData])
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 (
return (
<>
{selectedEventData && (
<>
{selectedEventData &&
<>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={activeOption}
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{activeOption === "store" &&
<StorageAction
value={currentCapacity}
defaultValue="0"
min={0}
max={20}
onChange={handleCapacityChange}
/>
}
{activeOption === "spawn" && (
<div className="spawn-options">
<p>Spawn configuration options would go here</p>
</div>
)}
</div>
</div>
<div className="tirgger">
<Trigger />
</div>
</>
}
<ActionsList
setSelectedPointData={setSelectedPointData}
selectedPointData={selectedPointData}
/>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption={activeOption}
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{activeOption === "store" && (
<StorageAction
value={currentCapacity}
defaultValue="0"
min={0}
max={20}
onChange={handleCapacityChange}
/>
)}
{activeOption === "spawn" && (
<div className="spawn-options">
<p>Spawn configuration options would go here</p>
</div>
)}
</div>
</div>
<div className="tirgger">
<Trigger />
</div>
</>
)
)}
</>
);
}
export default StorageMechanics
export default StorageMechanics;

View File

@ -1,197 +1,199 @@
import { useEffect, useState } from 'react'
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 { useEffect, useState } from "react";
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 { useProductStore } from "../../../../../../store/simulation/useProductStore";
import TravelAction from '../actions/TravelAction'
import TravelAction from "../actions/TravelAction";
import ActionsList from "../components/ActionsList";
function VehicleMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct();
const [activeOption, setActiveOption] = useState<"default" | "travel">(
"default"
);
const [selectedPointData, setSelectedPointData] = useState<
VehiclePointSchema | undefined
>();
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 VehiclePointSchema | undefined;
useEffect(() => {
if (selectedEventData) {
const point = getPointByUuid(
selectedProduct.productId,
selectedEventData.data.modelUuid,
selectedEventData.selectedPoint
) as VehiclePointSchema | undefined;
if (point) {
setSelectedPointData(point);
setActiveOption(point.action.actionType as "travel");
}
}
}, [selectedProduct, selectedEventData])
if (point) {
setSelectedPointData(point);
setActiveOption(point.action.actionType as "travel");
}
}
}, [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 "travel";
setActiveOption(validOption);
const handleActionTypeChange = (option: string) => {
if (!selectedEventData || !selectedPointData) return;
const validOption = option as "travel";
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 handleLoadCapacityChange = (value: string) => {
if (!selectedPointData) return;
updateAction(
selectedPointData.action.actionUuid,
{ loadCapacity: parseFloat(value) }
);
};
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 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 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 } }
);
};
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";
// 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 currentActionName = selectedPointData
? selectedPointData.action.actionName
: "Action Name";
const currentLoadCapacity = selectedPointData
? selectedPointData.action.loadCapacity.toString()
: "1";
const currentLoadCapacity = selectedPointData
? selectedPointData.action.loadCapacity.toString()
: "1";
const currentUnloadDuration = selectedPointData
? selectedPointData.action.unLoadDuration.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 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 currentUnloadPoint = selectedPointData?.action.unLoadPoint
? `${selectedPointData.action.unLoadPoint.x},${selectedPointData.action.unLoadPoint.y},${selectedPointData.action.unLoadPoint.z}`
: "";
const availableActions = {
defaultOption: "travel",
options: ["travel"],
};
const availableActions = {
defaultOption: "travel",
options: ["travel"],
};
return (
return (
<>
{selectedEventData && (
<>
{selectedEventData &&
<>
<div className="global-props">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => { }}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<div className="global-props">
<div className="property-list-container">
<div className="property-item">
<InputWithDropDown
label="Speed"
value={currentSpeed}
min={0}
step={0.1}
defaultValue={"0.5"}
max={10}
activeOption="m/s"
onClick={() => {}}
onChange={handleSpeedChange}
/>
</div>
</div>
</div>
<ActionsList
setSelectedPointData={setSelectedPointData}
selectedPointData={selectedPointData}
/>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption="travel"
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput
value={currentActionName}
onRename={handleRenameAction}
/>
</div>
<div className="selected-actions-list">
<LabledDropdown
defaultOption="travel"
options={availableActions.options}
onSelect={handleActionTypeChange}
/>
{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 className="tirgger">
<Trigger />
</div>
</>
}
{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 className="tirgger">
<Trigger />
</div>
</>
)
)}
</>
);
}
export default VehicleMechanics
export default VehicleMechanics;

View File

@ -366,15 +366,66 @@
min-height: 50vh;
padding-bottom: 12px;
position: relative;
display: flex;
flex-direction: column;
overflow: auto;
.sidebar-right-content-container {
border-bottom: 1px solid var(--border-color);
// flex: 1;
height: calc(100% - 36px);
position: relative;
overflow: auto;
width: 320px;
.no-event-selected {
color: #666;
padding: 1.8rem 1rem;
grid-column: 1 / -1;
.products-list {
padding-top: 1rem;
.products-list-title{
text-align: start;
color: var(--accent-color);
font-size: var(--font-size-regular);
}
ul {
li {
text-align: start;
margin: 8px 0;
padding: 2px 0;
text-decoration: none;
&::marker {
content: "";
}
button {
width: fit-content;
position: relative;
transition: all 0.2s ease;
@include flex-center;
gap: 4px;
&:before {
content: "";
position: absolute;
left: 0;
bottom: -4px;
background: var(--accent-color);
height: 1px;
width: 0%;
transition: all 0.3s ease;
}
}
&:hover {
button {
path {
stroke: var(--accent-color);
stroke-width: 1.5px;
}
color: var(--accent-color);
&:before {
width: 100%;
}
}
}
}
}
}
}
}
}
@ -707,7 +758,7 @@
}
.selected-actions-list {
margin-bottom: 8px;
.eye-dropper-input-container{
.eye-dropper-input-container {
padding: 6px 12px;
.regularDropdown-container {
padding: 5px 8px;
@ -798,6 +849,7 @@
@include flex-center;
padding: 4px;
cursor: grab;
width: 100%;
&:active {
cursor: grabbing;

View File

@ -776,13 +776,13 @@
border-radius: 6px;
overflow: hidden;
padding: 4px;
min-width: 150px;
.option {
padding: 4px 10px;
border-radius: #{$border-radius-small};
color: var(--text-color);
text-wrap: nowrap;
cursor: pointer;
&:hover {
@ -794,8 +794,8 @@
color: #f65648;
&:hover {
background-color: #f65648;
color: white;
background-color: #f657484d;
color: #f65648;
}
}
}