feat: Add assembly action handling and UI components

- Implemented `useAssemblyHandler` to manage assembly actions for humans.
- Enhanced `useHumanActions` to include assembly action handling.
- Updated `HumanInstance` to support assembly processes and animations.
- Modified `HumanUi` to allow for assembly point configuration and rotation.
- Created `AssemblyAction` component for setting process time and material swap options.
- Updated simulation types to include assembly action properties.
- Adjusted existing action handlers to accommodate assembly actions alongside worker actions.
- Refactored `MaterialAnimator` and `VehicleAnimator` to manage attachment states and visibility based on load.
- Updated product store types to include human point actions.
This commit is contained in:
2025-07-07 15:00:16 +05:30
parent b7f29bf5db
commit 74094aee9f
20 changed files with 592 additions and 859 deletions

View File

@@ -0,0 +1,44 @@
import React from "react";
import InputRange from "../../../../../ui/inputs/InputRange";
import SwapAction from "./SwapAction";
interface AssemblyActionProps {
processTime: {
value: number;
min: number;
max: number;
disabled?: boolean,
onChange: (value: number) => void;
};
swapOptions: string[];
swapDefaultOption: string;
onSwapSelect: (value: string) => void;
}
const AssemblyAction: React.FC<AssemblyActionProps> = ({
processTime,
swapOptions,
swapDefaultOption,
onSwapSelect,
}) => {
return (
<>
<InputRange
label="Process Time"
value={processTime.value}
min={processTime.min}
max={processTime.max}
disabled={processTime.disabled}
onClick={() => { }}
onChange={processTime.onChange}
/>
<SwapAction
options={swapOptions}
defaultOption={swapDefaultOption}
onSelect={onSwapSelect}
/>
</>
);
};
export default AssemblyAction;

View File

@@ -5,18 +5,21 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger";
import ActionsList from "../components/ActionsList";
import { useSelectedEventData, useSelectedAction, useSelectedAnimation } from "../../../../../../store/simulation/useSimulationStore";
import { useSelectedEventData, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
import { useParams } from "react-router-dom";
import WorkerAction from "../actions/workerAction";
import AssemblyAction from "../actions/assemblyAction";
function HumanMechanics() {
const [activeOption, setActiveOption] = useState<"worker">("worker");
const [activeOption, setActiveOption] = useState<"worker" | "assembly">("worker");
const [speed, setSpeed] = useState("0.5");
const [loadCapacity, setLoadCapacity] = useState("1");
const [processTime, setProcessTime] = useState(10);
const [swappedMaterial, setSwappedMaterial] = useState("Default material");
const [currentAction, setCurrentAction] = useState<HumanAction | undefined>();
const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
const { selectedEventData } = useSelectedEventData();
@@ -48,6 +51,8 @@ function HumanMechanics() {
) as HumanEventSchema | undefined
)?.speed?.toString() || "1");
setLoadCapacity(point.action.loadCapacity.toString());
setProcessTime(point.action.processTime || 10);
setSwappedMaterial(point.action.swapMaterial || "Default material");
}
} else {
clearSelectedAction();
@@ -158,6 +163,52 @@ function HumanMechanics() {
setLoadCapacity(value);
};
const handleProcessTimeChange = (value: number) => {
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
const updatedAction = { ...currentAction };
updatedAction.processTime = value
const updatedPoint = { ...selectedPointData, action: updatedAction };
const event = updateAction(
selectedProduct.productUuid,
selectedAction.actionId,
updatedAction
);
if (event) {
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
}
setCurrentAction(updatedAction);
setSelectedPointData(updatedPoint);
setProcessTime(value);
};
const handleMaterialChange = (value: string) => {
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
const updatedAction = { ...currentAction };
updatedAction.swapMaterial = value
const updatedPoint = { ...selectedPointData, action: updatedAction };
const event = updateAction(
selectedProduct.productUuid,
selectedAction.actionId,
updatedAction
);
if (event) {
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
}
setCurrentAction(updatedAction);
setSelectedPointData(updatedPoint);
setSwappedMaterial(value);
};
const handleClearPoints = () => {
if (!currentAction || !selectedPointData || !selectedAction.actionId) return;
@@ -262,23 +313,38 @@ function HumanMechanics() {
<LabledDropdown
label="Action Type"
defaultOption={activeOption}
options={["worker"]}
options={["worker", "assembly"]}
onSelect={handleSelectActionType}
disabled={true}
/>
</div>
<WorkerAction
loadCapacity={{
value: loadCapacity,
min: 1,
max: 5,
step: 1,
defaultValue: "1",
disabled: true,
onChange: handleLoadCapacityChange,
}}
clearPoints={handleClearPoints}
/>
{currentAction.actionType === 'worker' &&
<WorkerAction
loadCapacity={{
value: loadCapacity,
min: 1,
max: 5,
step: 1,
defaultValue: "10",
disabled: true,
onChange: handleLoadCapacityChange,
}}
clearPoints={handleClearPoints}
/>
}
{currentAction.actionType === 'assembly' &&
<AssemblyAction
processTime={{
value: processTime,
min: 1,
max: 60,
onChange: handleProcessTimeChange,
}}
swapOptions={["Default material", "Material 1", "Material 2", "Material 3"]}
swapDefaultOption={swappedMaterial}
onSwapSelect={handleMaterialChange}
/>
}
<div className="tirgger">
<Trigger selectedPointData={selectedPointData as any} type="Human" />
</div>