feat: Add human mechanics and event handling, including UI components and action management
This commit is contained in:
@@ -8,6 +8,7 @@ import VehicleMechanics from "./mechanics/vehicleMechanics";
|
|||||||
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
|
import RoboticArmMechanics from "./mechanics/roboticArmMechanics";
|
||||||
import MachineMechanics from "./mechanics/machineMechanics";
|
import MachineMechanics from "./mechanics/machineMechanics";
|
||||||
import StorageMechanics from "./mechanics/storageMechanics";
|
import StorageMechanics from "./mechanics/storageMechanics";
|
||||||
|
import HumanMechanics from "./mechanics/humanMechanics";
|
||||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||||
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
|
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
|
||||||
import { useProductContext } from "../../../../../modules/simulation/products/productContext";
|
import { useProductContext } from "../../../../../modules/simulation/products/productContext";
|
||||||
@@ -61,6 +62,8 @@ const EventProperties: React.FC = () => {
|
|||||||
return "machine";
|
return "machine";
|
||||||
case "storageUnit":
|
case "storageUnit":
|
||||||
return "storageUnit";
|
return "storageUnit";
|
||||||
|
case "human":
|
||||||
|
return "human";
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -80,6 +83,7 @@ const EventProperties: React.FC = () => {
|
|||||||
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
||||||
{assetType === "machine" && <MachineMechanics />}
|
{assetType === "machine" && <MachineMechanics />}
|
||||||
{assetType === "storageUnit" && <StorageMechanics />}
|
{assetType === "storageUnit" && <StorageMechanics />}
|
||||||
|
{assetType === "human" && <HumanMechanics />}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!currentEventData && selectedEventSphere && (
|
{!currentEventData && selectedEventSphere && (
|
||||||
|
|||||||
@@ -0,0 +1,373 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { MathUtils } 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, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||||
|
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
|
||||||
|
import ActionsList from "../components/ActionsList";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||||
|
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { useVersionContext } from "../../../../../../modules/builder/version/versionContext";
|
||||||
|
import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
||||||
|
import InputToggle from "../../../../../ui/inputs/InputToggle";
|
||||||
|
|
||||||
|
function HumanMechanics() {
|
||||||
|
const [activeOption, setActiveOption] = useState<"animation" | "animatedTravel">("animation");
|
||||||
|
const [activeAnimationOption, setActiveAnimationOption] = useState("");
|
||||||
|
const [animationOptions, setAnimationOptions] = useState<string[]>([]);
|
||||||
|
const [speed, setSpeed] = useState("0.5");
|
||||||
|
const [currentAction, setCurrentAction] = useState<HumanAction | undefined>();
|
||||||
|
const [isLoopAnimation, setIsLoopAnimation] = useState(false);
|
||||||
|
const [selectedPointData, setSelectedPointData] = useState<HumanPointSchema | undefined>();
|
||||||
|
const { selectedEventData } = useSelectedEventData();
|
||||||
|
const { productStore, assetStore } = useSceneContext();
|
||||||
|
const { getAssetById } = assetStore();
|
||||||
|
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction, addAction, removeAction } = productStore();
|
||||||
|
const { selectedProductStore } = useProductContext();
|
||||||
|
const { selectedProduct } = selectedProductStore();
|
||||||
|
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||||
|
const { selectedVersionStore } = useVersionContext();
|
||||||
|
const { selectedVersion } = selectedVersionStore();
|
||||||
|
const { projectId } = useParams();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedEventData) {
|
||||||
|
const point = getPointByUuid(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedEventData.data.modelUuid,
|
||||||
|
selectedEventData.selectedPoint
|
||||||
|
) as HumanPointSchema | undefined;
|
||||||
|
|
||||||
|
if (point?.actions) {
|
||||||
|
setSelectedPointData(point);
|
||||||
|
if (point.actions.length > 0) {
|
||||||
|
setSelectedAction(point.actions[0].actionUuid, point.actions[0].actionName);
|
||||||
|
const asset = getAssetById(selectedEventData.data.modelUuid);
|
||||||
|
if (asset && asset.animations) {
|
||||||
|
setAnimationOptions(asset.animations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clearSelectedAction();
|
||||||
|
}
|
||||||
|
}, [selectedEventData, selectedProduct]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedEventData && selectedProduct.productUuid) {
|
||||||
|
const event = getEventByModelUuid(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedEventData.data.modelUuid
|
||||||
|
) as HumanEventSchema | undefined;
|
||||||
|
|
||||||
|
if (event?.speed !== undefined) {
|
||||||
|
setSpeed(event.speed.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
const point = getPointByUuid(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedEventData.data.modelUuid,
|
||||||
|
selectedEventData.selectedPoint
|
||||||
|
) as HumanPointSchema | undefined;
|
||||||
|
|
||||||
|
if (point?.actions) {
|
||||||
|
setSelectedPointData(point);
|
||||||
|
const action = point.actions.find((a) => a.actionUuid === selectedAction.actionId);
|
||||||
|
if (action) {
|
||||||
|
setCurrentAction(action);
|
||||||
|
setIsLoopAnimation(action.loopAnimation ?? false);
|
||||||
|
setActiveOption(action.actionType as "animation" | "animatedTravel");
|
||||||
|
setActiveAnimationOption(action.animation || '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clearSelectedAction();
|
||||||
|
setCurrentAction(undefined);
|
||||||
|
setSpeed("0.5");
|
||||||
|
}
|
||||||
|
}, [selectedEventData, selectedProduct, selectedAction]);
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productUuid: string,
|
||||||
|
projectId: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName,
|
||||||
|
productUuid,
|
||||||
|
projectId,
|
||||||
|
eventDatas: eventData,
|
||||||
|
versionId: selectedVersion?.versionId || "",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectActionType = (actionType: string) => {
|
||||||
|
if (!selectedAction.actionId) return;
|
||||||
|
setActiveOption(actionType as "animation" | "animatedTravel");
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
{ actionType: actionType as "animation" | "animatedTravel" }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (selectedPointData) {
|
||||||
|
const updatedActions = selectedPointData.actions.map((action) =>
|
||||||
|
action.actionUuid === selectedAction.actionId
|
||||||
|
? { ...action, actionType: actionType as "animation" | "animatedTravel" }
|
||||||
|
: action
|
||||||
|
);
|
||||||
|
setSelectedPointData({ ...selectedPointData, actions: updatedActions });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelectAnimation = (animationOption: string) => {
|
||||||
|
if (!selectedAction.actionId) return;
|
||||||
|
setActiveAnimationOption(animationOption);
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
{ animation: animationOption }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (selectedPointData) {
|
||||||
|
const updatedActions = selectedPointData.actions.map((action) =>
|
||||||
|
action.actionUuid === selectedAction.actionId
|
||||||
|
? { ...action, animation: animationOption }
|
||||||
|
: action
|
||||||
|
);
|
||||||
|
setSelectedPointData({ ...selectedPointData, actions: updatedActions });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLoopAnimationChange = () => {
|
||||||
|
if (!selectedAction.actionId || !currentAction) return;
|
||||||
|
|
||||||
|
const updatedValue = !isLoopAnimation;
|
||||||
|
setIsLoopAnimation(updatedValue);
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
{ loopAnimation: updatedValue }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (selectedPointData) {
|
||||||
|
const updatedActions = selectedPointData.actions.map((action) =>
|
||||||
|
action.actionUuid === selectedAction.actionId
|
||||||
|
? { ...action, loopAnimation: updatedValue }
|
||||||
|
: action
|
||||||
|
);
|
||||||
|
setSelectedPointData({ ...selectedPointData, actions: updatedActions });
|
||||||
|
setCurrentAction(updatedActions.find((a) => a.actionUuid === selectedAction.actionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRenameAction = (newName: string) => {
|
||||||
|
if (!selectedAction.actionId) return;
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
{ actionName: newName }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (selectedPointData) {
|
||||||
|
const updatedActions = selectedPointData.actions.map((action) =>
|
||||||
|
action.actionUuid === selectedAction.actionId
|
||||||
|
? { ...action, actionName: newName }
|
||||||
|
: action
|
||||||
|
);
|
||||||
|
setSelectedPointData({ ...selectedPointData, actions: updatedActions });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSpeedChange = (value: string) => {
|
||||||
|
if (!selectedEventData) return;
|
||||||
|
|
||||||
|
const event = updateEvent(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedEventData.data.modelUuid,
|
||||||
|
{ speed: parseFloat(value) }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClearPoints = () => {
|
||||||
|
if (!selectedAction.actionId || !selectedPointData) return;
|
||||||
|
|
||||||
|
const event = updateAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedAction.actionId,
|
||||||
|
{
|
||||||
|
travelPoints: {
|
||||||
|
startPoint: null,
|
||||||
|
endPoint: null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddAction = () => {
|
||||||
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
|
|
||||||
|
const newAction: HumanAction = {
|
||||||
|
actionUuid: MathUtils.generateUUID(),
|
||||||
|
actionName: `Action ${selectedPointData.actions.length + 1}`,
|
||||||
|
actionType: "animation",
|
||||||
|
animation: null,
|
||||||
|
loadCapacity: 1,
|
||||||
|
loopAnimation: true,
|
||||||
|
travelPoints: {
|
||||||
|
startPoint: null,
|
||||||
|
endPoint: null,
|
||||||
|
},
|
||||||
|
triggers: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const event = addAction(
|
||||||
|
selectedProduct.productUuid,
|
||||||
|
selectedEventData.data.modelUuid,
|
||||||
|
selectedEventData.selectedPoint,
|
||||||
|
newAction
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedPoint = { ...selectedPointData, actions: [...selectedPointData.actions, newAction] };
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
setSelectedAction(newAction.actionUuid, newAction.actionName);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteAction = (actionUuid: string) => {
|
||||||
|
if (!selectedPointData) return;
|
||||||
|
|
||||||
|
const event = removeAction(selectedProduct.productUuid, actionUuid);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(selectedProduct.productName, selectedProduct.productUuid, projectId || '', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = selectedPointData.actions.findIndex((a) => a.actionUuid === actionUuid);
|
||||||
|
const newActions = selectedPointData.actions.filter((a) => a.actionUuid !== actionUuid);
|
||||||
|
const updatedPoint = { ...selectedPointData, actions: newActions };
|
||||||
|
setSelectedPointData(updatedPoint);
|
||||||
|
|
||||||
|
if (selectedAction.actionId === actionUuid) {
|
||||||
|
const nextAction = newActions[index] || newActions[index - 1];
|
||||||
|
if (nextAction) {
|
||||||
|
setSelectedAction(nextAction.actionUuid, nextAction.actionName);
|
||||||
|
} else {
|
||||||
|
clearSelectedAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const availableActions = {
|
||||||
|
defaultOption: "animatedTravel",
|
||||||
|
options: ["animation", "animatedTravel"],
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="global-props section">
|
||||||
|
<div className="property-list-container">
|
||||||
|
<div className="property-item">
|
||||||
|
<InputWithDropDown
|
||||||
|
label="Speed"
|
||||||
|
value={speed}
|
||||||
|
min={0}
|
||||||
|
step={0.1}
|
||||||
|
defaultValue="0.5"
|
||||||
|
max={10}
|
||||||
|
activeOption="m/s"
|
||||||
|
onClick={() => { }}
|
||||||
|
onChange={handleSpeedChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section>
|
||||||
|
<ActionsList
|
||||||
|
selectedPointData={selectedPointData}
|
||||||
|
multipleAction
|
||||||
|
handleAddAction={handleAddAction}
|
||||||
|
handleDeleteAction={handleDeleteAction}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{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
|
||||||
|
label="Action Type"
|
||||||
|
defaultOption={activeOption}
|
||||||
|
options={availableActions.options}
|
||||||
|
onSelect={handleSelectActionType}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
<LabledDropdown
|
||||||
|
label="Animation"
|
||||||
|
defaultOption={activeAnimationOption}
|
||||||
|
options={animationOptions}
|
||||||
|
onSelect={handleSelectAnimation}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
<InputToggle
|
||||||
|
value={isLoopAnimation}
|
||||||
|
inputKey=""
|
||||||
|
label="Loop Animation"
|
||||||
|
onClick={handleLoopAnimationChange}
|
||||||
|
/>
|
||||||
|
{activeOption === 'animatedTravel' &&
|
||||||
|
<PickAndPlaceAction clearPoints={handleClearPoints} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="tirgger">
|
||||||
|
<Trigger
|
||||||
|
selectedPointData={selectedPointData as any}
|
||||||
|
type={"Human"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HumanMechanics;
|
||||||
@@ -13,7 +13,7 @@ import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
|
|||||||
|
|
||||||
type TriggerProps = {
|
type TriggerProps = {
|
||||||
selectedPointData?: PointsScheme | undefined;
|
selectedPointData?: PointsScheme | undefined;
|
||||||
type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit";
|
type?: "Conveyor" | "Vehicle" | "RoboticArm" | "Machine" | "StorageUnit" | "Human";
|
||||||
};
|
};
|
||||||
|
|
||||||
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||||
@@ -38,7 +38,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
|||||||
|
|
||||||
if (type === "Conveyor" || type === "Vehicle" || type === "Machine" || type === "StorageUnit") {
|
if (type === "Conveyor" || type === "Vehicle" || type === "Machine" || type === "StorageUnit") {
|
||||||
actionUuid = (selectedPointData as | ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema).action?.actionUuid;
|
actionUuid = (selectedPointData as | ConveyorPointSchema | VehiclePointSchema | MachinePointSchema | StoragePointSchema).action?.actionUuid;
|
||||||
} else if (type === "RoboticArm" && selectedAction.actionId) {
|
} else if ((type === "RoboticArm" || type === "Human") && selectedAction.actionId) {
|
||||||
actionUuid = selectedAction.actionId;
|
actionUuid = selectedAction.actionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,18 +365,16 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{triggers.length > 1 && (
|
<button
|
||||||
<button
|
id="remove-trigger-button"
|
||||||
id="remove-trigger-button"
|
className="remove-button"
|
||||||
className="remove-button"
|
onClick={(e) => {
|
||||||
onClick={(e) => {
|
e.stopPropagation();
|
||||||
e.stopPropagation();
|
handleRemoveTrigger(trigger.triggerUuid);
|
||||||
handleRemoveTrigger(trigger.triggerUuid);
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<RemoveIcon />
|
||||||
<RemoveIcon />
|
</button>
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
|||||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||||
state: "idle",
|
state: "idle",
|
||||||
type: "human",
|
type: "human",
|
||||||
|
speed: 1,
|
||||||
point: {
|
point: {
|
||||||
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
||||||
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
||||||
|
|||||||
@@ -369,6 +369,7 @@ async function handleModelLoad(
|
|||||||
rotation: newFloorItem.rotation,
|
rotation: newFloorItem.rotation,
|
||||||
state: "idle",
|
state: "idle",
|
||||||
type: "human",
|
type: "human",
|
||||||
|
speed: 1,
|
||||||
point: {
|
point: {
|
||||||
uuid: THREE.MathUtils.generateUUID(),
|
uuid: THREE.MathUtils.generateUUID(),
|
||||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const handleAddEventToProduct = ({
|
|||||||
projectId: projectId || '',
|
projectId: projectId || '',
|
||||||
eventDatas: event
|
eventDatas: event
|
||||||
}).then((data) => {
|
}).then((data) => {
|
||||||
// console.log(data);
|
console.log(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
if (clearSelectedAsset) {
|
if (clearSelectedAsset) {
|
||||||
|
|||||||
@@ -1,6 +1,27 @@
|
|||||||
import HumanInstances from './instances/humanInstances'
|
import HumanInstances from './instances/humanInstances'
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
||||||
|
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
|
import { useSceneContext } from "../../scene/sceneContext";
|
||||||
|
|
||||||
function Human() {
|
function Human() {
|
||||||
|
const { humanStore } = useSceneContext();
|
||||||
|
const { getHumanById } = humanStore();
|
||||||
|
const { selectedEventSphere } = useSelectedEventSphere();
|
||||||
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
const [isHumanSelected, setIsHumanSelected] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedEventSphere) {
|
||||||
|
const selectedVehicle = getHumanById(selectedEventSphere.userData.modelUuid);
|
||||||
|
if (selectedVehicle) {
|
||||||
|
setIsHumanSelected(true);
|
||||||
|
} else {
|
||||||
|
setIsHumanSelected(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [getHumanById, selectedEventSphere])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import HumanUi from './humanUi';
|
||||||
|
|
||||||
function HumanInstance({ human }: { human: HumanStatus }) {
|
function HumanInstance({ human }: { human: HumanStatus }) {
|
||||||
|
|
||||||
@@ -8,6 +9,9 @@ function HumanInstance({ human }: { human: HumanStatus }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
<HumanUi human={human} />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
function HumanUi({ human }: { human: HumanStatus }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HumanUi
|
||||||
@@ -1,38 +1,37 @@
|
|||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
|
||||||
export const upsertProductOrEventApi = async (body: any) => {
|
export const upsertProductOrEventApi = async (body: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${url_Backend_dwinzo}/api/V1/ProductUpsert`,
|
`${url_Backend_dwinzo}/api/V1/ProductUpsert`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer <access_token>",
|
Authorization: "Bearer <access_token>",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
token: localStorage.getItem("token") || "",
|
token: localStorage.getItem("token") || "",
|
||||||
refresh_token: localStorage.getItem("refreshToken") || "",
|
refresh_token: localStorage.getItem("refreshToken") || "",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const newAccessToken = response.headers.get("x-access-token");
|
const newAccessToken = response.headers.get("x-access-token");
|
||||||
if (newAccessToken) {
|
if (newAccessToken) {
|
||||||
//console.log("New token received:", newAccessToken);
|
localStorage.setItem("token", newAccessToken);
|
||||||
localStorage.setItem("token", newAccessToken);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error("Failed to add product or event");
|
console.error("Failed to add product or event");
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
echo.error("Failed to upsert product Or eventApi");
|
echo.error("Failed to upsert product Or eventApi");
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.log(error.message);
|
console.log(error.message);
|
||||||
} else {
|
} else {
|
||||||
console.log("An unknown error occurred");
|
console.log("An unknown error occurred");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ type ProductsStore = {
|
|||||||
productUuid: string,
|
productUuid: string,
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
pointUuid: string,
|
pointUuid: string,
|
||||||
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
|
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['actions'][0]
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
|
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
|
||||||
updateAction: (
|
updateAction: (
|
||||||
productUuid: string,
|
productUuid: string,
|
||||||
actionUuid: string,
|
actionUuid: string,
|
||||||
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
|
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action'] | HumanPointSchema['actions'][0]>
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Trigger-level actionss
|
// Trigger-level actionss
|
||||||
@@ -276,6 +276,15 @@ export const createProductStore = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (event.type === "human") {
|
||||||
|
if ('actions' in point) {
|
||||||
|
const index = point.actions.findIndex((a: any) => a.actionUuid === actionUuid);
|
||||||
|
if (index !== -1) {
|
||||||
|
point.actions.splice(index, 1);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if ('action' in point && point.action?.actionUuid === actionUuid) {
|
} else if ('action' in point && point.action?.actionUuid === actionUuid) {
|
||||||
point.action = undefined;
|
point.action = undefined;
|
||||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
|||||||
1
app/src/types/simulationTypes.d.ts
vendored
1
app/src/types/simulationTypes.d.ts
vendored
@@ -158,6 +158,7 @@ interface StorageEventSchema extends AssetEventSchema {
|
|||||||
|
|
||||||
interface HumanEventSchema extends AssetEventSchema {
|
interface HumanEventSchema extends AssetEventSchema {
|
||||||
type: "human";
|
type: "human";
|
||||||
|
speed: number;
|
||||||
point: HumanPointSchema;
|
point: HumanPointSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user