Merge remote-tracking branch 'origin/v2' into v2-ui
This commit is contained in:
commit
fb0da32504
|
@ -35,7 +35,7 @@ const ActionsList: React.FC<ActionsListProps> = ({
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleRenameAction = (newName: string) => {
|
||||||
if (!selectedAction.actionId) return;
|
if (!selectedAction.actionId) return;
|
||||||
const event = renameAction(selectedAction.actionId, newName);
|
const event = renameAction(selectedProduct.productId, selectedAction.actionId, newName);
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
upsertProductOrEventApi({
|
upsertProductOrEventApi({
|
||||||
|
|
|
@ -72,7 +72,7 @@ function ConveyorMechanics() {
|
||||||
const validOption = option as | "default" | "spawn" | "swap" | "delay" | "despawn";
|
const validOption = option as | "default" | "spawn" | "swap" | "delay" | "despawn";
|
||||||
setActiveOption(validOption);
|
setActiveOption(validOption);
|
||||||
|
|
||||||
const event = updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
actionType: validOption,
|
actionType: validOption,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ function ConveyorMechanics() {
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleRenameAction = (newName: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const event = updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { actionName: newName });
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(
|
updateBackend(
|
||||||
|
@ -102,7 +102,7 @@ function ConveyorMechanics() {
|
||||||
|
|
||||||
const handleSpawnCountChange = (value: string) => {
|
const handleSpawnCountChange = (value: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const event = updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
spawnCount: value === "inherit" ? "inherit" : parseFloat(value),
|
spawnCount: value === "inherit" ? "inherit" : parseFloat(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ function ConveyorMechanics() {
|
||||||
|
|
||||||
const handleSpawnIntervalChange = (value: string) => {
|
const handleSpawnIntervalChange = (value: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const event = updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
spawnInterval: value === "inherit" ? "inherit" : parseFloat(value),
|
spawnInterval: value === "inherit" ? "inherit" : parseFloat(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ function ConveyorMechanics() {
|
||||||
|
|
||||||
const handleMaterialSelect = (material: string) => {
|
const handleMaterialSelect = (material: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const event = updateAction(selectedPointData.action.actionUuid, { material });
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { material });
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(
|
updateBackend(
|
||||||
|
@ -148,7 +148,7 @@ function ConveyorMechanics() {
|
||||||
|
|
||||||
const handleDelayChange = (value: string) => {
|
const handleDelayChange = (value: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const event = updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
delay: value === "inherit" ? "inherit" : parseFloat(value),
|
delay: value === "inherit" ? "inherit" : parseFloat(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ function ConveyorMechanics() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="tirgger">
|
<div className="tirgger">
|
||||||
<Trigger />
|
<Trigger selectedPointData={selectedPointData as any} type= {'Conveyor'}/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useSelectedEventData, useSelectedProduct } from "../../../../../../stor
|
||||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||||
import ProcessAction from "../actions/ProcessAction";
|
import ProcessAction from "../actions/ProcessAction";
|
||||||
import ActionsList from "../components/ActionsList";
|
import ActionsList from "../components/ActionsList";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
|
||||||
function MachineMechanics() {
|
function MachineMechanics() {
|
||||||
const [activeOption, setActiveOption] = useState<"default" | "process">("default");
|
const [activeOption, setActiveOption] = useState<"default" | "process">("default");
|
||||||
|
@ -14,6 +15,9 @@ function MachineMechanics() {
|
||||||
const { getPointByUuid, updateAction } = useProductStore();
|
const { getPointByUuid, updateAction } = useProductStore();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventData) {
|
if (selectedEventData) {
|
||||||
const point = getPointByUuid(
|
const point = getPointByUuid(
|
||||||
|
@ -28,31 +32,54 @@ function MachineMechanics() {
|
||||||
}
|
}
|
||||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const handleActionTypeChange = (option: string) => {
|
const handleActionTypeChange = (option: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const validOption = option as "process";
|
const validOption = option as "process";
|
||||||
setActiveOption(validOption);
|
setActiveOption(validOption);
|
||||||
|
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
actionType: validOption,
|
actionType: validOption,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleRenameAction = (newName: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { actionName: newName });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleProcessTimeChange = (value: string) => {
|
const handleProcessTimeChange = (value: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
processTime: parseFloat(value),
|
processTime: parseFloat(value),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMaterialSelect = (material: string) => {
|
const handleMaterialSelect = (material: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
swapMaterial: material,
|
swapMaterial: material,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,7 @@ function RoboticArmMechanics() {
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleRenameAction = (newName: string) => {
|
||||||
if (!selectedAction.actionId) return;
|
if (!selectedAction.actionId) return;
|
||||||
const event = updateAction(selectedAction.actionId, { actionName: newName });
|
const event = updateAction(selectedProduct.productId, selectedAction.actionId, { actionName: newName });
|
||||||
|
|
||||||
if (selectedPointData) {
|
if (selectedPointData) {
|
||||||
const updatedActions = selectedPointData.actions.map((action) =>
|
const updatedActions = selectedPointData.actions.map((action) =>
|
||||||
|
@ -101,7 +101,7 @@ function RoboticArmMechanics() {
|
||||||
if (!selectedAction.actionId || !selectedPointData) return;
|
if (!selectedAction.actionId || !selectedPointData) return;
|
||||||
const [x, y, z] = value.split(",").map(Number);
|
const [x, y, z] = value.split(",").map(Number);
|
||||||
|
|
||||||
const event = updateAction(selectedAction.actionId, {
|
const event = updateAction(selectedProduct.productId, selectedAction.actionId, {
|
||||||
process: {
|
process: {
|
||||||
startPoint: [x, y, z] as [number, number, number],
|
startPoint: [x, y, z] as [number, number, number],
|
||||||
endPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.endPoint || null,
|
endPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.endPoint || null,
|
||||||
|
@ -122,7 +122,7 @@ function RoboticArmMechanics() {
|
||||||
if (!selectedAction.actionId || !selectedPointData) return;
|
if (!selectedAction.actionId || !selectedPointData) return;
|
||||||
const [x, y, z] = value.split(",").map(Number);
|
const [x, y, z] = value.split(",").map(Number);
|
||||||
|
|
||||||
const event = updateAction(selectedAction.actionId, {
|
const event = updateAction(selectedProduct.productId, selectedAction.actionId, {
|
||||||
process: {
|
process: {
|
||||||
startPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.startPoint || null,
|
startPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.startPoint || null,
|
||||||
endPoint: [x, y, z] as [number, number, number],
|
endPoint: [x, y, z] as [number, number, number],
|
||||||
|
@ -181,7 +181,7 @@ function RoboticArmMechanics() {
|
||||||
const handleDeleteAction = (actionUuid: string) => {
|
const handleDeleteAction = (actionUuid: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
|
|
||||||
const event = removeAction(actionUuid);
|
const event = removeAction(selectedProduct.productId, actionUuid);
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
updateBackend(
|
updateBackend(
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useSelectedEventData, useSelectedProduct } from "../../../../../../stor
|
||||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||||
import StorageAction from "../actions/StorageAction";
|
import StorageAction from "../actions/StorageAction";
|
||||||
import ActionsList from "../components/ActionsList";
|
import ActionsList from "../components/ActionsList";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
|
||||||
function StorageMechanics() {
|
function StorageMechanics() {
|
||||||
const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
|
const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
|
||||||
|
@ -14,6 +15,9 @@ function StorageMechanics() {
|
||||||
const { getPointByUuid, updateAction } = useProductStore();
|
const { getPointByUuid, updateAction } = useProductStore();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventData) {
|
if (selectedEventData) {
|
||||||
const point = getPointByUuid(
|
const point = getPointByUuid(
|
||||||
|
@ -28,26 +32,67 @@ function StorageMechanics() {
|
||||||
}
|
}
|
||||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const handleActionTypeChange = (option: string) => {
|
const handleActionTypeChange = (option: string) => {
|
||||||
if (!selectedEventData || !selectedPointData) return;
|
if (!selectedEventData || !selectedPointData) return;
|
||||||
const validOption = option as "store" | "spawn";
|
const validOption = option as "store" | "spawn";
|
||||||
setActiveOption(validOption);
|
setActiveOption(validOption);
|
||||||
|
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
actionType: validOption,
|
actionType: validOption,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleRenameAction = (newName: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { actionName: newName });
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCapacityChange = (value: string) => {
|
const handleCapacityChange = (value: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
storageCapacity: parseInt(value),
|
storageCapacity: parseInt(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get current values from store
|
// Get current values from store
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||||
import TravelAction from "../actions/TravelAction";
|
import TravelAction from "../actions/TravelAction";
|
||||||
import ActionsList from "../components/ActionsList";
|
import ActionsList from "../components/ActionsList";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
|
||||||
function VehicleMechanics() {
|
function VehicleMechanics() {
|
||||||
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
|
const [activeOption, setActiveOption] = useState<"default" | "travel">("default");
|
||||||
|
@ -18,8 +19,11 @@ function VehicleMechanics() {
|
||||||
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore();
|
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventData) {
|
if (selectedEventData && selectedEventData.data.type === 'vehicle') {
|
||||||
const point = getPointByUuid(
|
const point = getPointByUuid(
|
||||||
selectedProduct.productId,
|
selectedProduct.productId,
|
||||||
selectedEventData.data.modelUuid,
|
selectedEventData.data.modelUuid,
|
||||||
|
@ -33,11 +37,34 @@ function VehicleMechanics() {
|
||||||
}
|
}
|
||||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const handleSpeedChange = (value: string) => {
|
const handleSpeedChange = (value: string) => {
|
||||||
if (!selectedEventData) return;
|
if (!selectedEventData) return;
|
||||||
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
|
const event = updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
|
||||||
speed: parseFloat(value),
|
speed: parseFloat(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleActionTypeChange = (option: string) => {
|
const handleActionTypeChange = (option: string) => {
|
||||||
|
@ -45,28 +72,64 @@ function VehicleMechanics() {
|
||||||
const validOption = option as "travel";
|
const validOption = option as "travel";
|
||||||
setActiveOption(validOption);
|
setActiveOption(validOption);
|
||||||
|
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
actionType: validOption,
|
actionType: validOption,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRenameAction = (newName: string) => {
|
const handleRenameAction = (newName: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, { actionName: newName });
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLoadCapacityChange = (value: string) => {
|
const handleLoadCapacityChange = (value: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
loadCapacity: parseFloat(value),
|
loadCapacity: parseFloat(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUnloadDurationChange = (value: string) => {
|
const handleUnloadDurationChange = (value: string) => {
|
||||||
if (!selectedPointData) return;
|
if (!selectedPointData) return;
|
||||||
updateAction(selectedPointData.action.actionUuid, {
|
const event = updateAction(selectedProduct.productId, selectedPointData.action.actionUuid, {
|
||||||
unLoadDuration: parseFloat(value),
|
unLoadDuration: parseFloat(value),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePickPointChange = (value: string) => {
|
const handlePickPointChange = (value: string) => {
|
||||||
|
|
|
@ -1,137 +1,132 @@
|
||||||
import React, { useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import {
|
import {
|
||||||
AddIcon,
|
AddIcon,
|
||||||
RemoveIcon,
|
RemoveIcon,
|
||||||
ResizeHeightIcon,
|
ResizeHeightIcon,
|
||||||
} from "../../../../../icons/ExportCommonIcons";
|
} from "../../../../../icons/ExportCommonIcons";
|
||||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||||
import { handleResize } from "../../../../../../functions/handleResizePannel";
|
import { handleResize } from "../../../../../../functions/handleResizePannel";
|
||||||
|
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||||
|
import { useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||||
|
|
||||||
const Trigger: React.FC = () => {
|
type TriggerProps = {
|
||||||
// State to hold the list of triggers
|
selectedPointData?: PointsScheme | undefined;
|
||||||
const [triggers, setTriggers] = useState<string[]>(["Trigger 1"]);
|
type?: 'Conveyor' | 'Vehicle' | 'RoboticArm' | 'Machine' | 'StorageUnit';
|
||||||
const [selectedTrigger, setSelectedTrigger] = useState<string>("Trigger 1");
|
};
|
||||||
const [activeOption, setActiveOption] = useState("onComplete");
|
|
||||||
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
// States for dropdowns
|
const Trigger = ({ selectedPointData, type }: TriggerProps) => {
|
||||||
const [triggeredModel, setTriggeredModel] = useState<string[]>([]);
|
const [currentAction, setCurrentAction] = useState<string | undefined>();
|
||||||
const [triggeredPoint, setTriggeredPoint] = useState<string[]>([]);
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const [triggeredAction, setTriggeredAction] = useState<string[]>([]);
|
const { getActionByUuid } = useProductStore();
|
||||||
|
const [triggers, setTriggers] = useState<TriggerSchema[]>([]);
|
||||||
|
const [selectedTrigger, setSelectedTrigger] = useState<TriggerSchema | undefined>();
|
||||||
|
const [activeOption, setActiveOption] = useState("onComplete");
|
||||||
|
const triggersContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
// Function to handle adding a new trigger
|
useEffect(() => {
|
||||||
const addTrigger = (): void => {
|
if (!selectedPointData) return;
|
||||||
const newTrigger = `Trigger ${triggers.length + 1}`;
|
if (type === 'Conveyor' || type === 'Vehicle' || type === 'Machine' || type === 'StorageUnit') {
|
||||||
setTriggers([...triggers, newTrigger]); // Add new trigger to the state
|
setCurrentAction((selectedPointData as ConveyorPointSchema).action.actionUuid);
|
||||||
|
}
|
||||||
|
}, [selectedPointData]);
|
||||||
|
|
||||||
// Initialize the states for the new trigger
|
useEffect(() => {
|
||||||
setTriggeredModel([...triggeredModel, ""]);
|
if (!currentAction || !selectedProduct) return;
|
||||||
setTriggeredPoint([...triggeredPoint, ""]);
|
const action = getActionByUuid(selectedProduct.productId, currentAction);
|
||||||
setTriggeredAction([...triggeredAction, ""]);
|
setTriggers(action?.triggers || []);
|
||||||
};
|
setSelectedTrigger(action?.triggers[0] || undefined);
|
||||||
|
}, [currentAction, selectedProduct]);
|
||||||
|
|
||||||
// Function to handle removing a trigger
|
const addTrigger = (): void => {
|
||||||
const removeTrigger = (index: number): void => {
|
};
|
||||||
setTriggers(triggers.filter((_, i) => i !== index)); // Remove trigger by index
|
|
||||||
setTriggeredModel(triggeredModel.filter((_, i) => i !== index));
|
|
||||||
setTriggeredPoint(triggeredPoint.filter((_, i) => i !== index));
|
|
||||||
setTriggeredAction(triggeredAction.filter((_, i) => i !== index));
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
const removeTrigger = (triggerUuid: string): void => {
|
||||||
<div className="trigger-wrapper">
|
};
|
||||||
<div className="header">
|
|
||||||
<div className="title">Trigger</div>
|
const triggeredModel = selectedTrigger?.triggeredAsset?.triggeredModel || { modelName: "Select Model", modelUuid: "" };
|
||||||
<button
|
const triggeredPoint = selectedTrigger?.triggeredAsset?.triggeredPoint || { pointName: "Select Point", pointUuid: "" };
|
||||||
className="add-button"
|
const triggeredAction = selectedTrigger?.triggeredAsset?.triggeredAction || { actionName: "Select Action", actionUuid: "" };
|
||||||
onClick={addTrigger}
|
|
||||||
style={{ cursor: "pointer" }}
|
return (
|
||||||
>
|
<div className="trigger-wrapper">
|
||||||
<AddIcon /> Add
|
<div className="header">
|
||||||
</button>
|
<div className="title">Trigger</div>
|
||||||
</div>
|
<button
|
||||||
<div className="trigger-list">
|
className="add-button"
|
||||||
<div
|
onClick={addTrigger}
|
||||||
className="lists-main-container"
|
style={{ cursor: "pointer" }}
|
||||||
ref={triggersContainerRef}
|
>
|
||||||
style={{ height: "120px" }}
|
<AddIcon /> Add
|
||||||
>
|
|
||||||
<div className="list-container">
|
|
||||||
{triggers.map((trigger: any, index: number) => (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className={`list-item ${
|
|
||||||
selectedTrigger === trigger ? "active" : ""
|
|
||||||
}`}
|
|
||||||
onClick={() => setSelectedTrigger(trigger)}
|
|
||||||
>
|
|
||||||
<button className="value" onClick={() => {}}>
|
|
||||||
<RenameInput value={trigger} onRename={() => {}} />
|
|
||||||
</button>
|
</button>
|
||||||
{triggers.length > 1 && (
|
</div>
|
||||||
<button
|
<div className="trigger-list">
|
||||||
className="remove-button"
|
<div
|
||||||
onClick={() => removeTrigger(index)}
|
className="lists-main-container"
|
||||||
>
|
ref={triggersContainerRef}
|
||||||
<RemoveIcon />
|
style={{ height: "120px" }}
|
||||||
</button>
|
>
|
||||||
)}
|
<div className="list-container">
|
||||||
</div>
|
{triggers.map((trigger) => (
|
||||||
))}
|
<div
|
||||||
</div>
|
key={trigger.triggerUuid}
|
||||||
<button
|
className={`list-item ${selectedTrigger?.triggerUuid === trigger.triggerUuid ? "active" : ""}`}
|
||||||
className="resize-icon"
|
onClick={() => setSelectedTrigger(trigger)}
|
||||||
id="action-resize"
|
>
|
||||||
onMouseDown={(e: any) => handleResize(e, triggersContainerRef)}
|
<button className="value" onClick={() => { }}>
|
||||||
>
|
<RenameInput value={trigger.triggerName} onRename={() => { }} />
|
||||||
<ResizeHeightIcon />
|
</button>
|
||||||
</button>
|
{triggers.length > 1 && (
|
||||||
|
<button
|
||||||
|
className="remove-button"
|
||||||
|
onClick={() => removeTrigger(trigger.triggerUuid)}
|
||||||
|
>
|
||||||
|
<RemoveIcon />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="resize-icon"
|
||||||
|
id="action-resize"
|
||||||
|
onMouseDown={(e: any) => handleResize(e, triggersContainerRef)}
|
||||||
|
>
|
||||||
|
<ResizeHeightIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="trigger-item">
|
||||||
|
<div className="trigger-name">{selectedTrigger?.triggerName}</div>
|
||||||
|
<LabledDropdown
|
||||||
|
label="Trigger Type"
|
||||||
|
defaultOption={activeOption}
|
||||||
|
options={["onComplete", "onStart", "onStop", "delay"]}
|
||||||
|
onSelect={(option) => setActiveOption(option)}
|
||||||
|
/>
|
||||||
|
<div className="trigger-options">
|
||||||
|
<LabledDropdown
|
||||||
|
label="Triggered Object"
|
||||||
|
defaultOption={triggeredModel.modelName}
|
||||||
|
options={[]}
|
||||||
|
onSelect={(option) => { }}
|
||||||
|
/>
|
||||||
|
<LabledDropdown
|
||||||
|
label="Triggered Point"
|
||||||
|
defaultOption={triggeredPoint.pointName}
|
||||||
|
options={[]}
|
||||||
|
onSelect={(option) => { }}
|
||||||
|
/>
|
||||||
|
<LabledDropdown
|
||||||
|
label="Triggered Action"
|
||||||
|
defaultOption={triggeredAction.actionName}
|
||||||
|
options={[]}
|
||||||
|
onSelect={(option) => { }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="trigger-item">
|
);
|
||||||
<div className="trigger-name">{selectedTrigger}</div>
|
|
||||||
<LabledDropdown
|
|
||||||
label="Trigger on"
|
|
||||||
defaultOption={activeOption}
|
|
||||||
options={["onComplete", "onStart", "onStop", "delay"]}
|
|
||||||
onSelect={(option) => setActiveOption(option)}
|
|
||||||
/>
|
|
||||||
<div className="trigger-options">
|
|
||||||
<LabledDropdown
|
|
||||||
label="Triggered Object"
|
|
||||||
defaultOption={triggeredModel[0] || "Select Model"}
|
|
||||||
options={["Model 1", "Model 2", "Model 3"]}
|
|
||||||
onSelect={(option) => {
|
|
||||||
const newModel = [...triggeredModel];
|
|
||||||
newModel[0] = option;
|
|
||||||
setTriggeredModel(newModel);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<LabledDropdown
|
|
||||||
label="Triggered Point"
|
|
||||||
defaultOption={triggeredPoint[0] || "Select Point"}
|
|
||||||
options={["Point 1", "Point 2", "Point 3"]}
|
|
||||||
onSelect={(option) => {
|
|
||||||
const newPoint = [...triggeredPoint];
|
|
||||||
newPoint[0] = option;
|
|
||||||
setTriggeredPoint(newPoint);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<LabledDropdown
|
|
||||||
label="Triggered Action"
|
|
||||||
defaultOption={triggeredAction[0] || "Select Action"}
|
|
||||||
options={["Action 1", "Action 2", "Action 3"]}
|
|
||||||
onSelect={(option) => {
|
|
||||||
const newAction = [...triggeredAction];
|
|
||||||
newAction[0] = option;
|
|
||||||
setTriggeredAction(newAction);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Trigger;
|
export default Trigger;
|
||||||
|
|
|
@ -187,7 +187,7 @@ function processLoadedModel(
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (item.eventData.type === "vehicle") {
|
if (item.eventData.type === "Vehicle") {
|
||||||
const vehicleEvent: VehicleEventSchema = {
|
const vehicleEvent: VehicleEventSchema = {
|
||||||
modelUuid: item.modelUuid,
|
modelUuid: item.modelUuid,
|
||||||
modelName: item.modelName,
|
modelName: item.modelName,
|
||||||
|
@ -202,11 +202,11 @@ function processLoadedModel(
|
||||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||||
action: {
|
action: {
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionName: "Vehicle Action",
|
actionName: "Action 1",
|
||||||
actionType: "travel",
|
actionType: "travel",
|
||||||
unLoadDuration: 5,
|
unLoadDuration: 5,
|
||||||
loadCapacity: 10,
|
loadCapacity: 10,
|
||||||
steeringAngle:0,
|
steeringAngle: 0,
|
||||||
pickUpPoint: null,
|
pickUpPoint: null,
|
||||||
unLoadPoint: null,
|
unLoadPoint: null,
|
||||||
triggers: []
|
triggers: []
|
||||||
|
@ -254,7 +254,7 @@ function processLoadedModel(
|
||||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||||
action: {
|
action: {
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionName: "Process Action",
|
actionName: "Action 1",
|
||||||
actionType: "process",
|
actionType: "process",
|
||||||
processTime: 10,
|
processTime: 10,
|
||||||
swapMaterial: "material-id",
|
swapMaterial: "material-id",
|
||||||
|
@ -279,7 +279,7 @@ function processLoadedModel(
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionName: "Pick and Place",
|
actionName: "Action 1",
|
||||||
actionType: "pickAndPlace",
|
actionType: "pickAndPlace",
|
||||||
process: {
|
process: {
|
||||||
startPoint: [0, 0, 0],
|
startPoint: [0, 0, 0],
|
||||||
|
|
|
@ -186,22 +186,59 @@ async function handleModelLoad(
|
||||||
state: "idle",
|
state: "idle",
|
||||||
type: 'transfer',
|
type: 'transfer',
|
||||||
speed: 1,
|
speed: 1,
|
||||||
points: data.points.map((point: THREE.Vector3, index: number) => ({
|
points: data.points.map((point: THREE.Vector3, index: number) => {
|
||||||
uuid: THREE.MathUtils.generateUUID(),
|
const triggers: TriggerSchema[] = [];
|
||||||
position: [point.x, point.y, point.z],
|
|
||||||
rotation: [0, 0, 0],
|
if (data.points && index < data.points.length - 1) {
|
||||||
action: {
|
triggers.push({
|
||||||
actionUuid: THREE.MathUtils.generateUUID(),
|
triggerUuid: THREE.MathUtils.generateUUID(),
|
||||||
actionName: `Action ${index}`,
|
triggerName: `Trigger 1`,
|
||||||
actionType: 'default',
|
triggerType: "onComplete",
|
||||||
material: 'Default Material',
|
delay: 0,
|
||||||
delay: 0,
|
triggeredAsset: {
|
||||||
spawnInterval: 5,
|
triggeredModel: {
|
||||||
spawnCount: 1,
|
modelName: newFloorItem.modelName,
|
||||||
triggers: []
|
modelUuid: newFloorItem.modelUuid
|
||||||
|
},
|
||||||
|
triggeredPoint: {
|
||||||
|
pointName: `Point`,
|
||||||
|
pointUuid: ""
|
||||||
|
},
|
||||||
|
triggeredAction: {
|
||||||
|
actionName: `Action 1`,
|
||||||
|
actionUuid: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}))
|
|
||||||
|
return {
|
||||||
|
uuid: THREE.MathUtils.generateUUID(),
|
||||||
|
position: [point.x, point.y, point.z],
|
||||||
|
rotation: [0, 0, 0],
|
||||||
|
action: {
|
||||||
|
actionUuid: THREE.MathUtils.generateUUID(),
|
||||||
|
actionName: `Action 1`,
|
||||||
|
actionType: 'default',
|
||||||
|
material: 'Default Material',
|
||||||
|
delay: 0,
|
||||||
|
spawnInterval: 5,
|
||||||
|
spawnCount: 1,
|
||||||
|
triggers: triggers
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < ConveyorEvent.points.length - 1; i++) {
|
||||||
|
const currentPoint = ConveyorEvent.points[i];
|
||||||
|
const nextPoint = ConveyorEvent.points[i + 1];
|
||||||
|
|
||||||
|
if (currentPoint.action.triggers.length > 0) {
|
||||||
|
currentPoint.action.triggers[0].triggeredAsset!.triggeredPoint.pointUuid = nextPoint.uuid;
|
||||||
|
currentPoint.action.triggers[0].triggeredAsset!.triggeredAction!.actionUuid = nextPoint.action.actionUuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
addEvent(ConveyorEvent);
|
addEvent(ConveyorEvent);
|
||||||
eventData.points = ConveyorEvent.points.map(point => ({
|
eventData.points = ConveyorEvent.points.map(point => ({
|
||||||
uuid: point.uuid,
|
uuid: point.uuid,
|
||||||
|
@ -228,7 +265,7 @@ async function handleModelLoad(
|
||||||
actionType: "travel",
|
actionType: "travel",
|
||||||
unLoadDuration: 5,
|
unLoadDuration: 5,
|
||||||
loadCapacity: 10,
|
loadCapacity: 10,
|
||||||
steeringAngle:0,
|
steeringAngle: 0,
|
||||||
pickUpPoint: null,
|
pickUpPoint: null,
|
||||||
unLoadPoint: null,
|
unLoadPoint: null,
|
||||||
triggers: []
|
triggers: []
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifie
|
||||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
|
||||||
function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) {
|
function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) {
|
||||||
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
||||||
|
@ -16,10 +17,28 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
|
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const itemsData = useRef<Types.FloorItems>([]);
|
const itemsData = useRef<Types.FloorItems>([]);
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!camera || !scene || toggleView || !itemsGroupRef.current) return;
|
if (!camera || !scene || toggleView || !itemsGroupRef.current) return;
|
||||||
|
|
||||||
|
@ -190,10 +209,19 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (productData) {
|
if (productData) {
|
||||||
useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modelUuid, {
|
const event = useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modelUuid, {
|
||||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,9 +231,6 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
|
||||||
|
|
||||||
//REST
|
//REST
|
||||||
|
|
||||||
// await setFloorItemApi(
|
// await setFloorItemApi(
|
||||||
|
|
|
@ -8,6 +8,7 @@ import * as Types from "../../../../types/world/worldTypes";
|
||||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
|
||||||
function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) {
|
function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) {
|
||||||
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
||||||
|
@ -15,10 +16,28 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
|
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
const { selectedAssets, setSelectedAssets } = useSelectedAssets();
|
||||||
|
const { selectedProduct } = useSelectedProduct();
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { floorItems, setFloorItems } = useFloorItems();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const itemsData = useRef<Types.FloorItems>([]);
|
const itemsData = useRef<Types.FloorItems>([]);
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const prevPointerPosition = useRef<THREE.Vector2 | null>(null);
|
const prevPointerPosition = useRef<THREE.Vector2 | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -190,10 +209,19 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (productData) {
|
if (productData) {
|
||||||
useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modelUuid, {
|
const event = useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modelUuid, {
|
||||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,9 +231,6 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
||||||
return updatedItems;
|
return updatedItems;
|
||||||
});
|
});
|
||||||
|
|
||||||
const email = localStorage.getItem("email");
|
|
||||||
const organization = email ? email.split("@")[1].split(".")[0] : "default";
|
|
||||||
|
|
||||||
//REST
|
//REST
|
||||||
|
|
||||||
// await setFloorItemApi(
|
// await setFloorItemApi(
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
||||||
import useModuleStore from "../../../../../store/useModuleStore";
|
import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore";
|
||||||
import { TransformControls } from "@react-three/drei";
|
import { TransformControls } from "@react-three/drei";
|
||||||
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
||||||
import {
|
import {
|
||||||
useSelectedEventSphere,
|
useSelectedEventSphere,
|
||||||
useSelectedEventData,
|
useSelectedEventData,
|
||||||
|
useIsDragging,
|
||||||
|
useIsRotating,
|
||||||
} from "../../../../../store/simulation/useSimulationStore";
|
} from "../../../../../store/simulation/useSimulationStore";
|
||||||
|
import { useThree } from "@react-three/fiber";
|
||||||
|
|
||||||
function PointsCreator() {
|
function PointsCreator() {
|
||||||
|
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||||
|
const { subModule } = useSubModuleStore();
|
||||||
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
|
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const transformRef = useRef<any>(null);
|
const transformRef = useRef<any>(null);
|
||||||
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
||||||
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
|
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
|
||||||
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere();
|
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere();
|
||||||
const { selectedEventData, setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
||||||
|
const { isDragging } = useIsDragging();
|
||||||
|
const { isRotating } = useIsRotating();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEventSphere) {
|
if (selectedEventSphere) {
|
||||||
|
@ -72,6 +79,53 @@ function PointsCreator() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const canvasElement = gl.domElement;
|
||||||
|
|
||||||
|
let drag = false;
|
||||||
|
let isMouseDown = false;
|
||||||
|
|
||||||
|
const onMouseDown = () => {
|
||||||
|
isMouseDown = true;
|
||||||
|
drag = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
if (selectedEventSphere && !drag) {
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
const intersects = raycaster
|
||||||
|
.intersectObjects(scene.children, true)
|
||||||
|
.filter(
|
||||||
|
(intersect) =>
|
||||||
|
intersect.object.name === ('Event-Sphere')
|
||||||
|
);
|
||||||
|
if (intersects.length === 0) {
|
||||||
|
clearSelectedEventSphere();
|
||||||
|
setTransformMode(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onMouseMove = () => {
|
||||||
|
if (isMouseDown) {
|
||||||
|
drag = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (subModule === 'mechanics') {
|
||||||
|
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||||
|
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||||
|
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||||
|
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||||
|
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||||
|
};
|
||||||
|
|
||||||
|
}, [gl, subModule, selectedEventSphere]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{activeModule === "simulation" && (
|
{activeModule === "simulation" && (
|
||||||
|
@ -92,12 +146,6 @@ function PointsCreator() {
|
||||||
sphereRefs.current[point.uuid]
|
sphereRefs.current[point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onPointerMissed={() => {
|
|
||||||
if (selectedEventData?.data.type !== 'vehicle') {
|
|
||||||
clearSelectedEventSphere();
|
|
||||||
}
|
|
||||||
setTransformMode(null);
|
|
||||||
}}
|
|
||||||
key={`${i}-${j}`}
|
key={`${i}-${j}`}
|
||||||
position={new THREE.Vector3(...point.position)}
|
position={new THREE.Vector3(...point.position)}
|
||||||
// rotation={new THREE.Euler(...point.rotation)}
|
// rotation={new THREE.Euler(...point.rotation)}
|
||||||
|
@ -122,10 +170,6 @@ function PointsCreator() {
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[event.point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onPointerMissed={() => {
|
|
||||||
clearSelectedEventSphere();
|
|
||||||
setTransformMode(null);
|
|
||||||
}}
|
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...event.point.position)}
|
||||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||||
|
@ -148,10 +192,6 @@ function PointsCreator() {
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[event.point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onPointerMissed={() => {
|
|
||||||
clearSelectedEventSphere();
|
|
||||||
setTransformMode(null);
|
|
||||||
}}
|
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...event.point.position)}
|
||||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||||
|
@ -174,10 +214,6 @@ function PointsCreator() {
|
||||||
sphereRefs.current[event.point.uuid]
|
sphereRefs.current[event.point.uuid]
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onPointerMissed={() => {
|
|
||||||
clearSelectedEventSphere();
|
|
||||||
setTransformMode(null);
|
|
||||||
}}
|
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
position={new THREE.Vector3(...event.point.position)}
|
||||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||||
|
|
|
@ -1,7 +1,43 @@
|
||||||
import React from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import MachineInstances from './instances/machineInstances'
|
import MachineInstances from './instances/machineInstances'
|
||||||
|
import { useMachineStore } from '../../../store/simulation/useMachineStore'
|
||||||
|
import { useSelectedProduct } from '../../../store/simulation/useSimulationStore';
|
||||||
|
|
||||||
function Machine() {
|
function Machine() {
|
||||||
|
const { addMachine, addCurrentAction, removeMachine } = useMachineStore();
|
||||||
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
|
||||||
|
const machineSample: MachineEventSchema[] = [
|
||||||
|
{
|
||||||
|
modelUuid: "machine-1234-5678-9012",
|
||||||
|
modelName: "CNC Milling Machine",
|
||||||
|
position: [10, 0, 5],
|
||||||
|
rotation: [0, 0, 0],
|
||||||
|
state: "idle",
|
||||||
|
type: "machine",
|
||||||
|
point: {
|
||||||
|
uuid: "machine-point-9876-5432-1098",
|
||||||
|
position: [10, 0.5, 5.2],
|
||||||
|
rotation: [0, 0, 0],
|
||||||
|
action: {
|
||||||
|
actionUuid: "machine-action-2468-1357-8024",
|
||||||
|
actionName: "Metal Processing",
|
||||||
|
actionType: "process",
|
||||||
|
processTime: 10,
|
||||||
|
swapMaterial: "steel",
|
||||||
|
triggers: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
removeMachine(machineSample[0].modelUuid);
|
||||||
|
addMachine(selectedProduct.productId, machineSample[0]);
|
||||||
|
|
||||||
|
// addCurrentAction(machineSample[0].modelUuid, machineSample[0].point.action.actionUuid);
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,17 @@ function AddOrRemoveEventsInProducts() {
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
if (!canvasElement) return;
|
if (!canvasElement) return;
|
||||||
|
|
||||||
let intersects = raycaster.intersectObjects(scene.children, true);
|
const intersects = raycaster
|
||||||
|
.intersectObjects(scene.children, true)
|
||||||
|
.filter(
|
||||||
|
(intersect) =>
|
||||||
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
|
!(intersect.object.type === "GridHelper") &&
|
||||||
|
!(intersect.object?.parent?.name.includes('zones')) &&
|
||||||
|
!(intersect.object?.parent?.name.includes('Zone'))
|
||||||
|
);
|
||||||
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
|
||||||
let currentObject = intersects[0].object;
|
let currentObject = intersects[0].object;
|
||||||
|
|
||||||
|
@ -116,6 +126,7 @@ function AddOrRemoveEventsInProducts() {
|
||||||
};
|
};
|
||||||
|
|
||||||
}, [gl, subModule, selectedProduct, selectedAsset]);
|
}, [gl, subModule, selectedProduct, selectedAsset]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<></>
|
<></>
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { upsertProductOrEventApi } from '../../../services/simulation/UpsertProd
|
||||||
import { getAllProductsApi } from '../../../services/simulation/getallProductsApi';
|
import { getAllProductsApi } from '../../../services/simulation/getallProductsApi';
|
||||||
|
|
||||||
function Products() {
|
function Products() {
|
||||||
const { products, addProduct, setProducts } = useProductStore();
|
const { addProduct, setProducts } = useProductStore();
|
||||||
const { setSelectedProduct } = useSelectedProduct();
|
const { setSelectedProduct } = useSelectedProduct();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -27,9 +27,6 @@ function Products() {
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
|
|
@ -170,8 +170,8 @@ function RoboticArmInstance({ robot }: { robot: ArmBotStatus }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const logStatus = (id: string, status: string) => {
|
const logStatus = (id: string, status: string) => {
|
||||||
// console.log(id + "," + status);
|
//
|
||||||
console.log( status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -23,7 +23,7 @@ function Simulation() {
|
||||||
}, [events])
|
}, [events])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log('products: ', products);
|
console.log('products: ', products);
|
||||||
}, [products])
|
}, [products])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useSubModuleStore } from "../../../../store/useModuleStore";
|
import { useSubModuleStore } from "../../../../store/useModuleStore";
|
||||||
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
||||||
|
@ -7,21 +7,28 @@ import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||||
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
||||||
|
import { QuadraticBezierLine } from "@react-three/drei";
|
||||||
|
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||||
|
import { useDeleteTool } from "../../../../store/store";
|
||||||
|
|
||||||
interface ConnectionLine {
|
interface ConnectionLine {
|
||||||
id: string;
|
id: string;
|
||||||
start: THREE.Vector3;
|
startPointUuid: string;
|
||||||
end: THREE.Vector3;
|
endPointUuid: string;
|
||||||
mid: THREE.Vector3;
|
|
||||||
trigger: TriggerSchema;
|
trigger: TriggerSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TriggerConnector() {
|
function TriggerConnector() {
|
||||||
const { gl, raycaster, scene } = useThree();
|
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||||
const { subModule } = useSubModuleStore();
|
const { subModule } = useSubModuleStore();
|
||||||
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid } = useProductStore();
|
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getProductById } = useProductStore();
|
||||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||||
const { selectedProduct } = useSelectedProduct();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
|
||||||
|
const groupRefs = useRef<Record<string, any>>({});
|
||||||
|
const [helperlineColor, setHelperLineColor] = useState<string>("red");
|
||||||
|
const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3; end: THREE.Vector3; mid: THREE.Vector3; } | null>(null);
|
||||||
|
const { deleteTool } = useDeleteTool();
|
||||||
|
|
||||||
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
|
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
|
||||||
productId: string;
|
productId: string;
|
||||||
|
@ -32,52 +39,99 @@ function TriggerConnector() {
|
||||||
|
|
||||||
const [connections, setConnections] = useState<ConnectionLine[]>([]);
|
const [connections, setConnections] = useState<ConnectionLine[]>([]);
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newConnections: ConnectionLine[] = [];
|
const newConnections: ConnectionLine[] = [];
|
||||||
|
|
||||||
products.forEach(product => {
|
const product = getProductById(selectedProduct.productId);
|
||||||
product.eventDatas.forEach(event => {
|
if (!product || products.length === 0) return;
|
||||||
if ('points' in event) {
|
|
||||||
event.points.forEach(point => {
|
|
||||||
if ('action' in point && point.action?.triggers) {
|
|
||||||
point.action.triggers.forEach(trigger => {
|
|
||||||
if (trigger.triggeredAsset) {
|
|
||||||
const targetPoint = getPointByUuid(
|
|
||||||
product.productId,
|
|
||||||
trigger.triggeredAsset.triggeredModel.modelUuid,
|
|
||||||
trigger.triggeredAsset.triggeredPoint.pointUuid
|
|
||||||
);
|
|
||||||
|
|
||||||
if (targetPoint) {
|
product.eventDatas.forEach(event => {
|
||||||
const startPos = new THREE.Vector3(...point.position);
|
// Handle Conveyor points
|
||||||
const endPos = new THREE.Vector3(...targetPoint.position);
|
if (event.type === "transfer" && 'points' in event) {
|
||||||
const midPos = new THREE.Vector3()
|
event.points.forEach(point => {
|
||||||
.addVectors(startPos, endPos)
|
if (point.action?.triggers) {
|
||||||
.multiplyScalar(0.5)
|
point.action.triggers.forEach(trigger => {
|
||||||
.add(new THREE.Vector3(0, 2, 0));
|
if (trigger.triggeredAsset) {
|
||||||
|
newConnections.push({
|
||||||
newConnections.push({
|
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
||||||
id: `${point.uuid}-${targetPoint.uuid}-${trigger.triggerUuid}`,
|
startPointUuid: point.uuid,
|
||||||
start: startPos,
|
endPointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid,
|
||||||
end: endPos,
|
trigger
|
||||||
mid: midPos,
|
});
|
||||||
trigger
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
// Handle Vehicle point
|
||||||
|
else if (event.type === "vehicle" && 'point' in event) {
|
||||||
|
const point = event.point;
|
||||||
|
if (point.action?.triggers) {
|
||||||
|
point.action.triggers.forEach(trigger => {
|
||||||
|
if (trigger.triggeredAsset) {
|
||||||
|
newConnections.push({
|
||||||
|
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
||||||
|
startPointUuid: point.uuid,
|
||||||
|
endPointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid,
|
||||||
|
trigger
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
// Handle Robotic Arm points
|
||||||
|
else if (event.type === "roboticArm" && 'point' in event) {
|
||||||
|
const point = event.point;
|
||||||
|
point.actions?.forEach(action => {
|
||||||
|
action.triggers?.forEach(trigger => {
|
||||||
|
if (trigger.triggeredAsset) {
|
||||||
|
newConnections.push({
|
||||||
|
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
||||||
|
startPointUuid: point.uuid,
|
||||||
|
endPointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid,
|
||||||
|
trigger
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Handle Machine point
|
||||||
|
else if (event.type === "machine" && 'point' in event) {
|
||||||
|
const point = event.point;
|
||||||
|
if (point.action?.triggers) {
|
||||||
|
point.action.triggers.forEach(trigger => {
|
||||||
|
if (trigger.triggeredAsset) {
|
||||||
|
newConnections.push({
|
||||||
|
id: `${point.uuid}-${trigger.triggeredAsset.triggeredPoint.pointUuid}-${trigger.triggerUuid}`,
|
||||||
|
startPointUuid: point.uuid,
|
||||||
|
endPointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid,
|
||||||
|
trigger
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setConnections(newConnections);
|
setConnections(newConnections);
|
||||||
}, [products]);
|
}, [products, selectedProduct.productId]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('connections: ', connections);
|
|
||||||
}, connections)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
|
@ -111,15 +165,31 @@ function TriggerConnector() {
|
||||||
if (drag) return;
|
if (drag) return;
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
const intersects = raycaster
|
||||||
if (intersects.length === 0) return;
|
.intersectObjects(scene.children, true)
|
||||||
|
.filter(
|
||||||
|
(intersect) =>
|
||||||
|
intersect.object.name === ('Event-Sphere')
|
||||||
|
);
|
||||||
|
if (intersects.length === 0) {
|
||||||
|
setFirstSelectedPoint(null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
const currentObject = intersects[0].object;
|
const currentObject = intersects[0].object;
|
||||||
if (!currentObject || currentObject.name !== 'Event-Sphere') return;
|
if (!currentObject || currentObject.name !== 'Event-Sphere') {
|
||||||
|
setFirstSelectedPoint(null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
const modelUuid = currentObject.userData.modelUuid;
|
const modelUuid = currentObject.userData.modelUuid;
|
||||||
const pointUuid = currentObject.userData.pointUuid;
|
const pointUuid = currentObject.userData.pointUuid;
|
||||||
|
|
||||||
|
if (firstSelectedPoint && firstSelectedPoint.pointUuid === pointUuid) {
|
||||||
|
setFirstSelectedPoint(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) {
|
if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) {
|
||||||
|
|
||||||
const point = getPointByUuid(
|
const point = getPointByUuid(
|
||||||
|
@ -128,7 +198,12 @@ function TriggerConnector() {
|
||||||
pointUuid
|
pointUuid
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!point) return;
|
const event = getEventByModelUuid(selectedProduct.productId, modelUuid);
|
||||||
|
|
||||||
|
if (!point || !event) {
|
||||||
|
setFirstSelectedPoint(null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let actionUuid: string | undefined;
|
let actionUuid: string | undefined;
|
||||||
if ('action' in point && point.action) {
|
if ('action' in point && point.action) {
|
||||||
|
@ -152,12 +227,12 @@ function TriggerConnector() {
|
||||||
delay: 0,
|
delay: 0,
|
||||||
triggeredAsset: {
|
triggeredAsset: {
|
||||||
triggeredModel: {
|
triggeredModel: {
|
||||||
modelName: currentObject.parent?.parent?.name || 'Unknown',
|
modelName: event.modelName || 'Unknown',
|
||||||
modelUuid: modelUuid
|
modelUuid: modelUuid
|
||||||
},
|
},
|
||||||
triggeredPoint: {
|
triggeredPoint: {
|
||||||
pointName: currentObject.name,
|
pointName: 'Point',
|
||||||
pointUuid: pointUuid
|
pointUuid: point.uuid
|
||||||
},
|
},
|
||||||
triggeredAction: actionUuid ? {
|
triggeredAction: actionUuid ? {
|
||||||
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
||||||
|
@ -167,7 +242,16 @@ function TriggerConnector() {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (firstSelectedPoint.actionUuid) {
|
if (firstSelectedPoint.actionUuid) {
|
||||||
addTrigger(firstSelectedPoint.actionUuid, trigger);
|
const event = addTrigger(selectedProduct.productId, firstSelectedPoint.actionUuid, trigger);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setFirstSelectedPoint(null);
|
setFirstSelectedPoint(null);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +268,12 @@ function TriggerConnector() {
|
||||||
pointUuid
|
pointUuid
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!point) return;
|
const event = getEventByModelUuid(selectedProduct.productId, modelUuid);
|
||||||
|
|
||||||
|
if (!point || !event) {
|
||||||
|
setFirstSelectedPoint(null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let actionUuid: string | undefined;
|
let actionUuid: string | undefined;
|
||||||
if ('action' in point && point.action) {
|
if ('action' in point && point.action) {
|
||||||
|
@ -200,12 +289,12 @@ function TriggerConnector() {
|
||||||
delay: 0,
|
delay: 0,
|
||||||
triggeredAsset: {
|
triggeredAsset: {
|
||||||
triggeredModel: {
|
triggeredModel: {
|
||||||
modelName: currentObject.parent?.parent?.name || 'Unknown',
|
modelName: event.modelName || 'Unknown',
|
||||||
modelUuid: modelUuid
|
modelUuid: modelUuid
|
||||||
},
|
},
|
||||||
triggeredPoint: {
|
triggeredPoint: {
|
||||||
pointName: currentObject.name,
|
pointName: 'Point',
|
||||||
pointUuid: pointUuid
|
pointUuid: point.uuid
|
||||||
},
|
},
|
||||||
triggeredAction: actionUuid ? {
|
triggeredAction: actionUuid ? {
|
||||||
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
||||||
|
@ -215,13 +304,24 @@ function TriggerConnector() {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (firstSelectedPoint.actionUuid) {
|
if (firstSelectedPoint.actionUuid) {
|
||||||
addTrigger(firstSelectedPoint.actionUuid, trigger);
|
const event = addTrigger(selectedProduct.productId, firstSelectedPoint.actionUuid, trigger);
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setFirstSelectedPoint(null);
|
setFirstSelectedPoint(null);
|
||||||
|
} else if (firstSelectedPoint) {
|
||||||
|
setFirstSelectedPoint(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (subModule === 'simulations') {
|
if (subModule === 'simulations' && !deleteTool) {
|
||||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||||
|
@ -235,11 +335,149 @@ function TriggerConnector() {
|
||||||
canvasElement.removeEventListener('contextmenu', handleRightClick);
|
canvasElement.removeEventListener('contextmenu', handleRightClick);
|
||||||
};
|
};
|
||||||
|
|
||||||
}, [gl, subModule, selectedProduct, firstSelectedPoint]);
|
}, [gl, subModule, selectedProduct, firstSelectedPoint, deleteTool]);
|
||||||
|
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (firstSelectedPoint) {
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
const intersects = raycaster.intersectObjects(scene.children, true).filter(
|
||||||
|
(intersect) =>
|
||||||
|
!intersect.object.name.includes("Roof") &&
|
||||||
|
!intersect.object.name.includes("agv-collider") &&
|
||||||
|
!intersect.object.name.includes("MeasurementReference") &&
|
||||||
|
!intersect.object.parent?.name.includes("Zone") &&
|
||||||
|
!(intersect.object.type === "GridHelper") &&
|
||||||
|
!(intersect.object.type === "Line2")
|
||||||
|
);
|
||||||
|
|
||||||
|
let point: THREE.Vector3 | null = null;
|
||||||
|
|
||||||
|
if (intersects.length > 0) {
|
||||||
|
point = intersects[0].point;
|
||||||
|
if (point.y < 0.05) {
|
||||||
|
point = new THREE.Vector3(point.x, 0.05, point.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sphereIntersects = raycaster.intersectObjects(scene.children, true).filter((intersect) => intersect.object.name === ('Event-Sphere'));
|
||||||
|
|
||||||
|
if (sphereIntersects.length > 0 && sphereIntersects[0].object.uuid === firstSelectedPoint.pointUuid) {
|
||||||
|
setHelperLineColor('red');
|
||||||
|
setCurrentLine(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPoint = getWorldPositionFromScene(firstSelectedPoint.pointUuid);
|
||||||
|
|
||||||
|
if (point && startPoint) {
|
||||||
|
if (sphereIntersects.length > 0) {
|
||||||
|
point = sphereIntersects[0].object.getWorldPosition(new THREE.Vector3());
|
||||||
|
}
|
||||||
|
const distance = startPoint.distanceTo(point);
|
||||||
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
const midPoint = new THREE.Vector3(
|
||||||
|
(startPoint.x + point.x) / 2,
|
||||||
|
Math.max(startPoint.y, point.y) + heightFactor,
|
||||||
|
(startPoint.z + point.z) / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
const endPoint = point;
|
||||||
|
|
||||||
|
setCurrentLine({
|
||||||
|
start: startPoint,
|
||||||
|
mid: midPoint,
|
||||||
|
end: endPoint,
|
||||||
|
});
|
||||||
|
|
||||||
|
setHelperLineColor(sphereIntersects.length > 0 ? "#6cf542" : "red");
|
||||||
|
} else {
|
||||||
|
setCurrentLine(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCurrentLine(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const getWorldPositionFromScene = (pointUuid: string): THREE.Vector3 | null => {
|
||||||
|
const pointObj = scene.getObjectByProperty("uuid", pointUuid);
|
||||||
|
if (!pointObj) return null;
|
||||||
|
|
||||||
|
const worldPosition = new THREE.Vector3();
|
||||||
|
pointObj.getWorldPosition(worldPosition);
|
||||||
|
return worldPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeConnection = (connection: ConnectionLine) => {
|
||||||
|
if (connection.trigger.triggerUuid) {
|
||||||
|
const event = removeTrigger(selectedProduct.productId, connection.trigger.triggerUuid);
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<group name="simulationConnectionGroup" >
|
||||||
</>
|
{connections.map((connection) => {
|
||||||
|
const startPoint = getWorldPositionFromScene(connection.startPointUuid);
|
||||||
|
const endPoint = getWorldPositionFromScene(connection.endPointUuid);
|
||||||
|
|
||||||
|
if (!startPoint || !endPoint) return null;
|
||||||
|
|
||||||
|
const distance = startPoint.distanceTo(endPoint);
|
||||||
|
const heightFactor = Math.max(0.5, distance * 0.2);
|
||||||
|
const midPoint = new THREE.Vector3(
|
||||||
|
(startPoint.x + endPoint.x) / 2,
|
||||||
|
Math.max(startPoint.y, endPoint.y) + heightFactor,
|
||||||
|
(startPoint.z + endPoint.z) / 2
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<QuadraticBezierLine
|
||||||
|
key={connection.id}
|
||||||
|
ref={(el) => (groupRefs.current[connection.id] = el!)}
|
||||||
|
start={startPoint.toArray()}
|
||||||
|
end={endPoint.toArray()}
|
||||||
|
mid={midPoint.toArray()}
|
||||||
|
color={deleteTool && hoveredLineKey === connection.id ? "red" : "#42a5f5"}
|
||||||
|
lineWidth={4}
|
||||||
|
dashed={deleteTool && hoveredLineKey === connection.id ? false : true}
|
||||||
|
dashSize={0.75}
|
||||||
|
dashScale={20}
|
||||||
|
onPointerOver={() => setHoveredLineKey(connection.id)}
|
||||||
|
onPointerOut={() => setHoveredLineKey(null)}
|
||||||
|
onClick={() => {
|
||||||
|
if (deleteTool) {
|
||||||
|
setHoveredLineKey(null);
|
||||||
|
setCurrentLine(null);
|
||||||
|
removeConnection(connection);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
userData={connection.trigger}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{currentLine && (
|
||||||
|
<QuadraticBezierLine
|
||||||
|
start={currentLine.start.toArray()}
|
||||||
|
end={currentLine.end.toArray()}
|
||||||
|
mid={currentLine.mid.toArray()}
|
||||||
|
color={helperlineColor}
|
||||||
|
lineWidth={4}
|
||||||
|
dashed
|
||||||
|
dashSize={1}
|
||||||
|
dashScale={20}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import * as Types from "../../../../types/world/worldTypes";
|
||||||
import startPoint from "../../../../assets/gltf-glb/arrow_green.glb";
|
import startPoint from "../../../../assets/gltf-glb/arrow_green.glb";
|
||||||
import startEnd from "../../../../assets/gltf-glb/arrow_red.glb";
|
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
import startEnd from "../../../../assets/gltf-glb/arrow_red.glb";
|
||||||
import { useGLTF } from '@react-three/drei';
|
import { useGLTF } from '@react-three/drei';
|
||||||
import { useFrame, useThree } from '@react-three/fiber';
|
import { useFrame, useThree } from '@react-three/fiber';
|
||||||
import { useSelectedEventSphere } from '../../../../store/simulation/useSimulationStore';
|
import { useSelectedEventSphere, useIsDragging, useIsRotating } from '../../../../store/simulation/useSimulationStore';
|
||||||
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
|
import { useVehicleStore } from '../../../../store/simulation/useVehicleStore';
|
||||||
import * as Types from "../../../../types/world/worldTypes";
|
import { useProductStore } from '../../../../store/simulation/useProductStore';
|
||||||
|
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
|
||||||
|
import { upsertProductOrEventApi } from '../../../../services/simulation/UpsertProductOrEventApi';
|
||||||
|
|
||||||
const VehicleUI = () => {
|
const VehicleUI = () => {
|
||||||
const { scene: startScene } = useGLTF(startPoint) as any;
|
const { scene: startScene } = useGLTF(startPoint) as any;
|
||||||
const { scene: endScene } = useGLTF(startEnd) as any;
|
const { scene: endScene } = useGLTF(startEnd) as any;
|
||||||
|
@ -14,67 +18,60 @@ const VehicleUI = () => {
|
||||||
const endMarker = useRef<THREE.Group>(null);
|
const endMarker = useRef<THREE.Group>(null);
|
||||||
const prevMousePos = useRef({ x: 0, y: 0 });
|
const prevMousePos = useRef({ x: 0, y: 0 });
|
||||||
const { selectedEventSphere } = useSelectedEventSphere();
|
const { selectedEventSphere } = useSelectedEventSphere();
|
||||||
const { vehicles, updateVehicle } = useVehicleStore();
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
const { getVehicleById } = useVehicleStore();
|
||||||
|
const { updateEvent } = useProductStore();
|
||||||
const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 0, 0]);
|
const [startPosition, setStartPosition] = useState<[number, number, number]>([0, 0, 0]);
|
||||||
const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 0, 0]);
|
const [endPosition, setEndPosition] = useState<[number, number, number]>([0, 0, 0]);
|
||||||
const [startRotation, setStartRotation] = useState<[number, number, number]>([0, 0, 0]);
|
const [startRotation, setStartRotation] = useState<[number, number, number]>([0, 0, 0]);
|
||||||
const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]);
|
const [endRotation, setEndRotation] = useState<[number, number, number]>([0, 0, 0]);
|
||||||
const [isDragging, setIsDragging] = useState<"start" | "end" | null>(null);
|
const { isDragging, setIsDragging } = useIsDragging();
|
||||||
const [isRotating, setIsRotating] = useState<"start" | "end" | null>(null);
|
const { isRotating, setIsRotating } = useIsRotating();
|
||||||
const { raycaster } = useThree();
|
const { raycaster } = useThree();
|
||||||
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0));
|
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0));
|
||||||
const state: Types.ThreeState = useThree();
|
const state: Types.ThreeState = useThree();
|
||||||
const controls: any = state.controls;
|
const controls: any = state.controls;
|
||||||
|
|
||||||
|
const email = localStorage.getItem('email')
|
||||||
|
const organization = (email!.split("@")[1]).split(".")[0];
|
||||||
|
|
||||||
|
const updateBackend = (
|
||||||
|
productName: string,
|
||||||
|
productId: string,
|
||||||
|
organization: string,
|
||||||
|
eventData: EventsSchema
|
||||||
|
) => {
|
||||||
|
upsertProductOrEventApi({
|
||||||
|
productName: productName,
|
||||||
|
productId: productId,
|
||||||
|
organization: organization,
|
||||||
|
eventDatas: eventData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedEventSphere) return;
|
if (!selectedEventSphere) return;
|
||||||
const selectedVehicle = vehicles.find(
|
const selectedVehicle = getVehicleById(selectedEventSphere.userData.modelUuid);
|
||||||
(vehicle: any) => vehicle.modelUuid === selectedEventSphere.userData.modelUuid
|
|
||||||
);
|
|
||||||
|
|
||||||
if (selectedVehicle?.point?.action) {
|
if (selectedVehicle?.point?.action) {
|
||||||
const { pickUpPoint, unLoadPoint } = selectedVehicle.point.action;
|
const { pickUpPoint, unLoadPoint } = selectedVehicle.point.action;
|
||||||
|
|
||||||
if (pickUpPoint) {
|
if (pickUpPoint) {
|
||||||
const pickupPosition = new THREE.Vector3(
|
setStartPosition([pickUpPoint.position.x, 0, pickUpPoint.position.z]);
|
||||||
pickUpPoint.position.x,
|
setStartRotation([pickUpPoint.rotation.x, pickUpPoint.rotation.y, pickUpPoint.rotation.z]);
|
||||||
pickUpPoint.position.y,
|
|
||||||
pickUpPoint.position.z
|
|
||||||
);
|
|
||||||
const pickupRotation = new THREE.Vector3(
|
|
||||||
pickUpPoint.rotation.x,
|
|
||||||
pickUpPoint.rotation.y,
|
|
||||||
pickUpPoint.rotation.z
|
|
||||||
);
|
|
||||||
pickupPosition.y = 0;
|
|
||||||
setStartPosition([pickupPosition.x, 0, pickupPosition.z]);
|
|
||||||
setStartRotation([pickupRotation.x, pickupRotation.y, pickupRotation.z]);
|
|
||||||
} else {
|
} else {
|
||||||
const defaultLocal = new THREE.Vector3(0, 0, 1.5);
|
const defaultLocal = new THREE.Vector3(0, 0, 1.5);
|
||||||
const defaultWorld = selectedEventSphere.localToWorld(defaultLocal);
|
const defaultWorld = selectedEventSphere.localToWorld(defaultLocal);
|
||||||
defaultWorld.y = 0;
|
|
||||||
setStartPosition([defaultWorld.x, 0, defaultWorld.z]);
|
setStartPosition([defaultWorld.x, 0, defaultWorld.z]);
|
||||||
setStartRotation([0, 0, 0]);
|
setStartRotation([0, 0, 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unLoadPoint) {
|
if (unLoadPoint) {
|
||||||
const unLoadPosition = new THREE.Vector3(
|
setEndPosition([unLoadPoint.position.x, 0, unLoadPoint.position.z]);
|
||||||
unLoadPoint.position.x,
|
setEndRotation([unLoadPoint.rotation.x, unLoadPoint.rotation.y, unLoadPoint.rotation.z]);
|
||||||
unLoadPoint.position.y,
|
|
||||||
unLoadPoint.position.z
|
|
||||||
);
|
|
||||||
const unLoadRotation = new THREE.Vector3(
|
|
||||||
unLoadPoint.rotation.x,
|
|
||||||
unLoadPoint.rotation.y,
|
|
||||||
unLoadPoint.position.z
|
|
||||||
);
|
|
||||||
unLoadPosition.y = 0; // Force y to 0
|
|
||||||
setEndPosition([unLoadPosition.x, 0, unLoadPosition.z]);
|
|
||||||
setEndRotation([unLoadRotation.x, unLoadRotation.y, unLoadRotation.z]);
|
|
||||||
} else {
|
} else {
|
||||||
const defaultLocal = new THREE.Vector3(0, 0, -1.5);
|
const defaultLocal = new THREE.Vector3(0, 0, -1.5);
|
||||||
const defaultWorld = selectedEventSphere.localToWorld(defaultLocal);
|
const defaultWorld = selectedEventSphere.localToWorld(defaultLocal);
|
||||||
defaultWorld.y = 0; // Force y to 0
|
|
||||||
setEndPosition([defaultWorld.x, 0, defaultWorld.z]);
|
setEndPosition([defaultWorld.x, 0, defaultWorld.z]);
|
||||||
setEndRotation([0, 0, 0]);
|
setEndRotation([0, 0, 0]);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +84,6 @@ const VehicleUI = () => {
|
||||||
const intersects = raycaster.ray.intersectPlane(plane.current, intersectPoint);
|
const intersects = raycaster.ray.intersectPlane(plane.current, intersectPoint);
|
||||||
|
|
||||||
if (intersects) {
|
if (intersects) {
|
||||||
intersectPoint.y = 0; // Force y to 0
|
|
||||||
if (isDragging === "start") {
|
if (isDragging === "start") {
|
||||||
setStartPosition([intersectPoint.x, 0, intersectPoint.z]);
|
setStartPosition([intersectPoint.x, 0, intersectPoint.z]);
|
||||||
}
|
}
|
||||||
|
@ -108,12 +104,12 @@ const VehicleUI = () => {
|
||||||
|
|
||||||
if (marker) {
|
if (marker) {
|
||||||
const rotationSpeed = 10;
|
const rotationSpeed = 10;
|
||||||
marker.rotation.y += deltaX * rotationSpeed;
|
|
||||||
if (isRotating === 'start') {
|
if (isRotating === 'start') {
|
||||||
setStartRotation([marker.rotation.x, marker.rotation.y, marker.rotation.z])
|
const y = startRotation[1] + deltaX * rotationSpeed;
|
||||||
|
setStartRotation([0, y, 0]);
|
||||||
} else {
|
} else {
|
||||||
|
const y = endRotation[1] + deltaX * rotationSpeed;
|
||||||
setEndRotation([marker.rotation.x, marker.rotation.y, marker.rotation.z])
|
setEndRotation([0, y, 0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -142,43 +138,34 @@ const VehicleUI = () => {
|
||||||
setIsRotating(null);
|
setIsRotating(null);
|
||||||
|
|
||||||
if (selectedEventSphere?.userData.modelUuid) {
|
if (selectedEventSphere?.userData.modelUuid) {
|
||||||
const updatedVehicle = vehicles.find(
|
const updatedVehicle = getVehicleById(selectedEventSphere.userData.modelUuid);
|
||||||
(vehicle) => vehicle.modelUuid === selectedEventSphere.userData.modelUuid
|
|
||||||
);
|
|
||||||
|
|
||||||
if (updatedVehicle) {
|
if (updatedVehicle) {
|
||||||
updateVehicle(selectedEventSphere.userData.modelUuid, {
|
const event = updateEvent(selectedProduct.productId, selectedEventSphere.userData.modelUuid, {
|
||||||
point: {
|
point: {
|
||||||
...updatedVehicle.point,
|
...updatedVehicle.point,
|
||||||
action: {
|
action: {
|
||||||
...updatedVehicle.point?.action,
|
...updatedVehicle.point?.action,
|
||||||
pickUpPoint: {
|
pickUpPoint: {
|
||||||
position: {
|
position: { x: startPosition[0], y: startPosition[1], z: startPosition[2], },
|
||||||
x: startPosition[0],
|
rotation: { x: 0, y: startRotation[1], z: 0, },
|
||||||
y: startPosition[1],
|
|
||||||
z: startPosition[2],
|
|
||||||
},
|
|
||||||
rotation: {
|
|
||||||
x: startRotation[0],
|
|
||||||
y: startRotation[1],
|
|
||||||
z: startRotation[2],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
unLoadPoint: {
|
unLoadPoint: {
|
||||||
position: {
|
position: { x: endPosition[0], y: endPosition[1], z: endPosition[2], },
|
||||||
x: endPosition[0],
|
rotation: { x: 0, y: endRotation[1], z: 0, },
|
||||||
y: endPosition[1],
|
|
||||||
z: endPosition[2],
|
|
||||||
},
|
|
||||||
rotation: {
|
|
||||||
x: endRotation[0],
|
|
||||||
y: endRotation[1],
|
|
||||||
z: endRotation[2],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
updateBackend(
|
||||||
|
selectedProduct.productName,
|
||||||
|
selectedProduct.productId,
|
||||||
|
organization,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -208,6 +195,7 @@ const VehicleUI = () => {
|
||||||
object={startScene}
|
object={startScene}
|
||||||
ref={startMarker}
|
ref={startMarker}
|
||||||
position={startPosition}
|
position={startPosition}
|
||||||
|
rotation={startRotation}
|
||||||
onPointerDown={(e: any) => {
|
onPointerDown={(e: any) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handlePointerDown(e, "start", "start");
|
handlePointerDown(e, "start", "start");
|
||||||
|
@ -224,6 +212,7 @@ const VehicleUI = () => {
|
||||||
object={endScene}
|
object={endScene}
|
||||||
ref={endMarker}
|
ref={endMarker}
|
||||||
position={endPosition}
|
position={endPosition}
|
||||||
|
rotation={endRotation}
|
||||||
onPointerDown={(e: any) => {
|
onPointerDown={(e: any) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handlePointerDown(e, "end", "end");
|
handlePointerDown(e, "end", "end");
|
||||||
|
|
|
@ -11,7 +11,7 @@ interface VehicleAnimatorProps {
|
||||||
reset: () => void;
|
reset: () => void;
|
||||||
currentPhase: string;
|
currentPhase: string;
|
||||||
agvUuid: number;
|
agvUuid: number;
|
||||||
agvDetail: any;
|
agvDetail: VehicleStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset }: VehicleAnimatorProps) {
|
function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset }: VehicleAnimatorProps) {
|
||||||
|
@ -32,7 +32,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
||||||
let startTime: number;
|
let startTime: number;
|
||||||
let fixedInterval: number;
|
let fixedInterval: number;
|
||||||
let coveredDistance = progressRef.current;
|
let coveredDistance = progressRef.current;
|
||||||
let objectRotation = (agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) as { x: number; y: number; z: number };
|
let objectRotation = (agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) as { x: number; y: number; z: number } | undefined;
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -67,10 +67,9 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
||||||
setRestingRotation(true);
|
setRestingRotation(true);
|
||||||
decrementVehicleLoad(agvDetail.modelUuid, 0);
|
decrementVehicleLoad(agvDetail.modelUuid, 0);
|
||||||
const object = scene.getObjectByProperty('uuid', agvUuid);
|
const object = scene.getObjectByProperty('uuid', agvUuid);
|
||||||
console.log('currentPhase: ', currentPhase);
|
|
||||||
if (object) {
|
if (object) {
|
||||||
object.position.set(agvDetail.position[0], agvDetail.position[1], agvDetail.position[2]);
|
object.position.set(agvDetail.position[0], agvDetail.position[1], agvDetail.position[2]);
|
||||||
object.rotation.set(objectRotation.x, objectRotation.y, objectRotation.z);
|
object.rotation.set(agvDetail.rotation[0], agvDetail.rotation[1], agvDetail.rotation[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isReset, isPlaying])
|
}, [isReset, isPlaying])
|
||||||
|
@ -132,7 +131,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progressRef.current >= totalDistance) {
|
if (progressRef.current >= totalDistance) {
|
||||||
if (restRotation) {
|
if (restRotation && objectRotation) {
|
||||||
const targetQuaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(objectRotation.x, objectRotation.y, objectRotation.z));
|
const targetQuaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(objectRotation.x, objectRotation.y, objectRotation.z));
|
||||||
object.quaternion.slerp(targetQuaternion, delta * 2);
|
object.quaternion.slerp(targetQuaternion, delta * 2);
|
||||||
const angleDiff = object.quaternion.angleTo(targetQuaternion);
|
const angleDiff = object.quaternion.angleTo(targetQuaternion);
|
||||||
|
|
|
@ -30,7 +30,8 @@ function VehicleInstance({ agvDetail }: any) {
|
||||||
);
|
);
|
||||||
|
|
||||||
function vehicleStatus(modelId: string, status: string) {
|
function vehicleStatus(modelId: string, status: string) {
|
||||||
// console.log(`${modelId} , ${status});
|
// console.log(`${modelId} , ${status}`);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to reset everything
|
// Function to reset everything
|
||||||
|
@ -44,7 +45,7 @@ function VehicleInstance({ agvDetail }: any) {
|
||||||
const increment = () => {
|
const increment = () => {
|
||||||
if (isIncrememtable.current) {
|
if (isIncrememtable.current) {
|
||||||
|
|
||||||
incrementVehicleLoad(agvDetail.modelUuid, 2);
|
incrementVehicleLoad(agvDetail.modelUuid, 10);
|
||||||
isIncrememtable.current = false;
|
isIncrememtable.current = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +70,7 @@ function VehicleInstance({ agvDetail }: any) {
|
||||||
increment();
|
increment();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
|
|
||||||
if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity) {
|
if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity) {
|
||||||
const toDrop = computePath(
|
const toDrop = computePath(
|
||||||
agvDetail.point.action.pickUpPoint.position,
|
agvDetail.point.action.pickUpPoint.position,
|
||||||
|
|
|
@ -1,220 +1,48 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect } from "react";
|
||||||
import VehicleInstances from "./instances/vehicleInstances";
|
import VehicleInstances from "./instances/vehicleInstances";
|
||||||
import { useVehicleStore } from "../../../store/simulation/useVehicleStore";
|
import { useVehicleStore } from "../../../store/simulation/useVehicleStore";
|
||||||
import { useFloorItems } from "../../../store/store";
|
import { useSelectedEventData, useSelectedEventSphere, useSelectedProduct } from "../../../store/simulation/useSimulationStore";
|
||||||
import { useSelectedEventData, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
|
||||||
import VehicleUI from "../ui/vehicle/vehicleUI";
|
import VehicleUI from "../ui/vehicle/vehicleUI";
|
||||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
function Vehicles() {
|
import { useProductStore } from "../../../store/simulation/useProductStore";
|
||||||
|
|
||||||
const { vehicles, addVehicle } = useVehicleStore();
|
function Vehicles() {
|
||||||
|
const { products, getProductById } = useProductStore();
|
||||||
|
const { selectedProduct } = useSelectedProduct();
|
||||||
|
const { vehicles, addVehicle, clearvehicles } = useVehicleStore();
|
||||||
const { selectedEventSphere } = useSelectedEventSphere();
|
const { selectedEventSphere } = useSelectedEventSphere();
|
||||||
const { selectedEventData } = useSelectedEventData();
|
const { selectedEventData } = useSelectedEventData();
|
||||||
const { floorItems } = useFloorItems();
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
|
||||||
const [vehicleStatusSample, setVehicleStatusSample] = useState<
|
useEffect(() => {
|
||||||
VehicleEventSchema[]
|
if (selectedProduct.productId) {
|
||||||
>([
|
const product = getProductById(selectedProduct.productId);
|
||||||
{
|
if (product) {
|
||||||
modelUuid: "9356f710-4727-4b50-bdb2-9c1e747ecc74",
|
clearvehicles();
|
||||||
modelName: "AGV",
|
product.eventDatas.forEach(events => {
|
||||||
position: [97.9252965204558, 0, 37.96138815638661],
|
if (events.type === 'vehicle') {
|
||||||
rotation: [0, 0, 0],
|
addVehicle(selectedProduct.productId, events);
|
||||||
state: "idle",
|
}
|
||||||
type: "vehicle",
|
});
|
||||||
speed: 2.5,
|
|
||||||
point: {
|
|
||||||
uuid: "point-789",
|
|
||||||
position: [0, 1, 0],
|
|
||||||
rotation: [0, 0, 0],
|
|
||||||
action: {
|
|
||||||
actionUuid: "action-456",
|
|
||||||
actionName: "Deliver to Zone A",
|
|
||||||
actionType: "travel",
|
|
||||||
unLoadDuration: 10,
|
|
||||||
loadCapacity: 2,
|
|
||||||
steeringAngle:0,
|
|
||||||
pickUpPoint: { position: { x: 98.71483985219794, y: 0, z: 28.66321267938962 }, rotation: { x: 0, y: 0, z: 0 } },
|
|
||||||
unLoadPoint: { position: { x: 105.71483985219794, y: 0, z: 28.66321267938962 }, rotation: { x: 0, y: 0, z: 0 } },
|
|
||||||
triggers: [
|
|
||||||
{
|
|
||||||
triggerUuid: "trig-001",
|
|
||||||
triggerName: "Start Travel",
|
|
||||||
triggerType: "onComplete",
|
|
||||||
delay: 0,
|
|
||||||
triggeredAsset: {
|
|
||||||
triggeredModel: { modelName: "ArmBot-X", modelUuid: "arm-001" },
|
|
||||||
triggeredPoint: { pointName: "Pickup Arm Point", pointUuid: "arm-point-01" },
|
|
||||||
triggeredAction: { actionName: "Grab Widget", actionUuid: "grab-001" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
triggerUuid: "trig-002",
|
|
||||||
triggerName: "Complete Travel",
|
|
||||||
triggerType: "onComplete",
|
|
||||||
delay: 2,
|
|
||||||
triggeredAsset: null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
{
|
}, [selectedProduct, products]);
|
||||||
modelUuid: "b06960bb-3d2e-41f7-a646-335f389c68b4",
|
|
||||||
modelName: "AGV",
|
|
||||||
position: [89.61609306554463, 0, 33.634136622267356],
|
|
||||||
rotation: [0, 0, 0],
|
|
||||||
state: "idle",
|
|
||||||
type: "vehicle",
|
|
||||||
speed: 2.5,
|
|
||||||
point: {
|
|
||||||
uuid: "point-789",
|
|
||||||
position: [0, 1, 0],
|
|
||||||
rotation: [0, 0, 0],
|
|
||||||
action: {
|
|
||||||
actionUuid: "action-456",
|
|
||||||
actionName: "Deliver to Zone A",
|
|
||||||
actionType: "travel",
|
|
||||||
unLoadDuration: 10,
|
|
||||||
loadCapacity: 2,
|
|
||||||
steeringAngle:0,
|
|
||||||
pickUpPoint: null,
|
|
||||||
unLoadPoint: null,
|
|
||||||
triggers: [
|
|
||||||
{
|
|
||||||
triggerUuid: "trig-001",
|
|
||||||
triggerName: "Start Travel",
|
|
||||||
triggerType: "onStart",
|
|
||||||
delay: 0,
|
|
||||||
triggeredAsset: {
|
|
||||||
triggeredModel: { modelName: "ArmBot-X", modelUuid: "arm-001" },
|
|
||||||
triggeredPoint: { pointName: "Pickup Arm Point", pointUuid: "arm-point-01" },
|
|
||||||
triggeredAction: { actionName: "Grab Widget", actionUuid: "grab-001" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
triggerUuid: "trig-002",
|
|
||||||
triggerName: "Complete Travel",
|
|
||||||
triggerType: "onComplete",
|
|
||||||
delay: 2,
|
|
||||||
triggeredAsset: null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// modelUuid: "cd7d0584-0684-42b4-b051-9e882c1914aa",
|
|
||||||
// modelName: "AGV",
|
|
||||||
// position: [105.90938758014703, 0, 31.584209911095215],
|
|
||||||
// rotation: [0, 0, 0],
|
|
||||||
// state: "idle",
|
|
||||||
// type: "vehicle",
|
|
||||||
// speed: 2.5,
|
|
||||||
// point: {
|
|
||||||
// uuid: "point-789",
|
|
||||||
// position: [0, 1, 0],
|
|
||||||
// rotation: [0, 0, 0],
|
|
||||||
// action: {
|
|
||||||
// actionUuid: "action-456",
|
|
||||||
// actionName: "Deliver to Zone A",
|
|
||||||
// actionType: "travel",
|
|
||||||
// unLoadDuration: 10,
|
|
||||||
// loadCapacity: 2,
|
|
||||||
// steeringAngle:0,
|
|
||||||
// pickUpPoint: null,
|
|
||||||
// unLoadPoint: null,
|
|
||||||
// triggers: [
|
|
||||||
// {
|
|
||||||
// triggerUuid: "trig-001",
|
|
||||||
// triggerName: "Start Travel",
|
|
||||||
// triggerType: "onStart",
|
|
||||||
// delay: 0,
|
|
||||||
// triggeredAsset: {
|
|
||||||
// triggeredModel: { modelName: "ArmBot-X", modelUuid: "arm-001" },
|
|
||||||
// triggeredPoint: { pointName: "Pickup Arm Point", pointUuid: "arm-point-01" },
|
|
||||||
// triggeredAction: { actionName: "Grab Widget", actionUuid: "grab-001" }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// triggerUuid: "trig-002",
|
|
||||||
// triggerName: "Complete Travel",
|
|
||||||
// triggerType: "onComplete",
|
|
||||||
// delay: 2,
|
|
||||||
// triggeredAsset: null
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// modelUuid: "e729a4f1-11d2-4778-8d6a-468f1b4f6b79",
|
|
||||||
// modelName: "forklift",
|
|
||||||
// position: [98.85729337188162, 0, 38.36616546567653],
|
|
||||||
// rotation: [0, 0, 0],
|
|
||||||
// state: "idle",
|
|
||||||
// type: "vehicle",
|
|
||||||
// speed: 2.5,
|
|
||||||
// point: {
|
|
||||||
// uuid: "point-789",
|
|
||||||
// position: [0, 1, 0],
|
|
||||||
// rotation: [0, 0, 0],
|
|
||||||
// action: {
|
|
||||||
// actionUuid: "action-456",
|
|
||||||
// actionName: "Deliver to Zone A",
|
|
||||||
// actionType: "travel",
|
|
||||||
// unLoadDuration: 15,
|
|
||||||
// loadCapacity: 5,
|
|
||||||
// steeringAngle:0,
|
|
||||||
// pickUpPoint: null,
|
|
||||||
// unLoadPoint: null,
|
|
||||||
// triggers: [
|
|
||||||
// {
|
|
||||||
// triggerUuid: "trig-001",
|
|
||||||
// triggerName: "Start Travel",
|
|
||||||
// triggerType: "onStart",
|
|
||||||
// delay: 0,
|
|
||||||
// triggeredAsset: {
|
|
||||||
// triggeredModel: { modelName: "ArmBot-X", modelUuid: "arm-001" },
|
|
||||||
// triggeredPoint: { pointName: "Pickup Arm Point", pointUuid: "arm-point-01" },
|
|
||||||
// triggeredAction: { actionName: "Grab Widget", actionUuid: "grab-001" }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// triggerUuid: "trig-002",
|
|
||||||
// triggerName: "Complete Travel",
|
|
||||||
// triggerType: "onComplete",
|
|
||||||
// delay: 2,
|
|
||||||
// triggeredAsset: null
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
]);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log('vehicles: ', vehicles);
|
// console.log('vehicles: ', vehicles);
|
||||||
}, [vehicles])
|
}, [vehicles])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
addVehicle("123", vehicleStatusSample[0]);
|
|
||||||
addVehicle('123', vehicleStatusSample[1]);
|
|
||||||
// addVehicle('123', vehicleStatusSample[2]);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<VehicleInstances />
|
<VehicleInstances />
|
||||||
|
|
||||||
{selectedEventSphere && selectedEventData?.data.type === "vehicle" && !isPlaying &&
|
{selectedEventSphere && selectedEventData?.data.type === "vehicle" && !isPlaying &&
|
||||||
< VehicleUI />
|
< VehicleUI />
|
||||||
}
|
}
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Vehicles;
|
export default Vehicles;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
|
|
||||||
const { setRightSelect } = useRightSelected();
|
const { setRightSelect } = useRightSelected();
|
||||||
const { editWidgetOptions, setEditWidgetOptions } =
|
const { editWidgetOptions, setEditWidgetOptions } = useEditWidgetOptionsStore();
|
||||||
useEditWidgetOptionsStore();
|
|
||||||
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
||||||
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
||||||
const { setFloatingWidget } = useFloatingWidget();
|
const { setFloatingWidget } = useFloatingWidget();
|
||||||
|
|
|
@ -10,6 +10,7 @@ interface ArmBotStore {
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
updates: Partial<Omit<ArmBotStatus, 'modelUuid' | 'productId'>>
|
updates: Partial<Omit<ArmBotStatus, 'modelUuid' | 'productId'>>
|
||||||
) => void;
|
) => void;
|
||||||
|
clearArmBots: () => void;
|
||||||
|
|
||||||
addCurrentAction: (modelUuid: string, actionUuid: string) => void;
|
addCurrentAction: (modelUuid: string, actionUuid: string) => void;
|
||||||
removeCurrentAction: (modelUuid: string) => void;
|
removeCurrentAction: (modelUuid: string) => void;
|
||||||
|
@ -39,14 +40,17 @@ export const useArmBotStore = create<ArmBotStore>()(
|
||||||
|
|
||||||
addArmBot: (productId, event) => {
|
addArmBot: (productId, event) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.armBots.push({
|
const exists = state.armBots.some(a => a.modelUuid === event.modelUuid);
|
||||||
...event,
|
if (!exists) {
|
||||||
productId,
|
state.armBots.push({
|
||||||
isActive: false,
|
...event,
|
||||||
idleTime: 0,
|
productId,
|
||||||
activeTime: 0,
|
isActive: false,
|
||||||
state: 'idle',
|
idleTime: 0,
|
||||||
});
|
activeTime: 0,
|
||||||
|
state: 'idle',
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -65,6 +69,12 @@ export const useArmBotStore = create<ArmBotStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearArmBots: () => {
|
||||||
|
set((state) => {
|
||||||
|
state.armBots = [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
addCurrentAction: (modelUuid, actionUuid) => {
|
addCurrentAction: (modelUuid, actionUuid) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
|
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
|
||||||
|
|
|
@ -10,6 +10,7 @@ interface ConveyorStore {
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
updates: Partial<Omit<ConveyorStatus, 'modelUuid' | 'productId'>>
|
updates: Partial<Omit<ConveyorStatus, 'modelUuid' | 'productId'>>
|
||||||
) => void;
|
) => void;
|
||||||
|
clearConveyors: () => void;
|
||||||
|
|
||||||
setConveyorActive: (modelUuid: string, isActive: boolean) => void;
|
setConveyorActive: (modelUuid: string, isActive: boolean) => void;
|
||||||
setConveyorState: (modelUuid: string, newState: ConveyorStatus['state']) => void;
|
setConveyorState: (modelUuid: string, newState: ConveyorStatus['state']) => void;
|
||||||
|
@ -30,14 +31,17 @@ export const useConveyorStore = create<ConveyorStore>()(
|
||||||
|
|
||||||
addConveyor: (productId, event) => {
|
addConveyor: (productId, event) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.conveyors.push({
|
const exists = state.conveyors.some(c => c.modelUuid === event.modelUuid);
|
||||||
...event,
|
if (!exists) {
|
||||||
productId,
|
state.conveyors.push({
|
||||||
isActive: false,
|
...event,
|
||||||
idleTime: 0,
|
productId,
|
||||||
activeTime: 0,
|
isActive: false,
|
||||||
state: 'idle',
|
idleTime: 0,
|
||||||
});
|
activeTime: 0,
|
||||||
|
state: 'idle',
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -56,6 +60,12 @@ export const useConveyorStore = create<ConveyorStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearConveyors: () => {
|
||||||
|
set((state) => {
|
||||||
|
state.conveyors = [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setConveyorActive: (modelUuid, isActive) => {
|
setConveyorActive: (modelUuid, isActive) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
|
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
|
||||||
|
|
|
@ -7,7 +7,7 @@ type EventsStore = {
|
||||||
// Event-level actions
|
// Event-level actions
|
||||||
addEvent: (event: EventsSchema) => void;
|
addEvent: (event: EventsSchema) => void;
|
||||||
removeEvent: (modelUuid: string) => void;
|
removeEvent: (modelUuid: string) => void;
|
||||||
updateEvent: (modelUuid: string, updates: Partial<EventsSchema>) => void;
|
updateEvent: (modelUuid: string, updates: Partial<EventsSchema>) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Point-level actions
|
// Point-level actions
|
||||||
addPoint: (modelUuid: string, point: ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
|
addPoint: (modelUuid: string, point: ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
|
||||||
|
@ -49,7 +49,9 @@ export const useEventsStore = create<EventsStore>()(
|
||||||
// Event-level actions
|
// Event-level actions
|
||||||
addEvent: (event) => {
|
addEvent: (event) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.events.push(event);
|
if (!state.events.some(e => 'modelUuid' in e && e.modelUuid === event.modelUuid)) {
|
||||||
|
state.events.push(event);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -60,12 +62,15 @@ export const useEventsStore = create<EventsStore>()(
|
||||||
},
|
},
|
||||||
|
|
||||||
updateEvent: (modelUuid, updates) => {
|
updateEvent: (modelUuid, updates) => {
|
||||||
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||||
if (event) {
|
if (event) {
|
||||||
Object.assign(event, updates);
|
Object.assign(event, updates);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Point-level actions
|
// Point-level actions
|
||||||
|
@ -73,9 +78,14 @@ export const useEventsStore = create<EventsStore>()(
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||||
if (event && 'points' in event) {
|
if (event && 'points' in event) {
|
||||||
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
|
const existingPoint = (event as ConveyorEventSchema).points.find(p => p.uuid === point.uuid);
|
||||||
|
if (!existingPoint) {
|
||||||
|
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
|
||||||
|
}
|
||||||
} else if (event && 'point' in event) {
|
} else if (event && 'point' in event) {
|
||||||
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
|
if (!(event as any).point || (event as any).point.uuid !== point.uuid) {
|
||||||
|
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -110,14 +120,15 @@ export const useEventsStore = create<EventsStore>()(
|
||||||
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||||
if (event && 'points' in event) {
|
if (event && 'points' in event) {
|
||||||
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||||
if (point) {
|
if (point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
|
||||||
point.action = action as any;
|
point.action = action as any;
|
||||||
}
|
}
|
||||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||||
if ('action' in (event as any).point) {
|
const point = (event as any).point;
|
||||||
(event as any).point.action = action;
|
if ('action' in point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
|
||||||
} else if ('actions' in (event as any).point) {
|
point.action = action;
|
||||||
(event as any).point.actions.push(action);
|
} else if ('actions' in point && !point.actions.some((a: any) => a.actionUuid === action.actionUuid)) {
|
||||||
|
point.actions.push(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -180,18 +191,22 @@ export const useEventsStore = create<EventsStore>()(
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
if (point.action && point.action.actionUuid === actionUuid) {
|
if (point.action && point.action.actionUuid === actionUuid) {
|
||||||
point.action.triggers.push(trigger);
|
if (!point.action.triggers.some(t => t.triggerUuid === trigger.triggerUuid)) {
|
||||||
|
point.action.triggers.push(trigger);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ('point' in event) {
|
} else if ('point' in event) {
|
||||||
const point = (event as any).point;
|
const point: MachinePointSchema | VehiclePointSchema = (event as any).point;
|
||||||
if ('action' in point && point.action.actionUuid === actionUuid) {
|
if ('action' in point && point.action.actionUuid === actionUuid) {
|
||||||
point.action.triggers.push(trigger);
|
if (!point.action.triggers.some(t => t.triggerUuid === trigger.triggerUuid)) {
|
||||||
|
point.action.triggers.push(trigger);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else if ('actions' in point) {
|
} else if ('actions' in point) {
|
||||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
const action = (point as RoboticArmPointSchema).actions.find((a) => a.actionUuid === actionUuid);
|
||||||
if (action) {
|
if (action && !action.triggers.some(t => t.triggerUuid === trigger.triggerUuid)) {
|
||||||
action.triggers.push(trigger);
|
action.triggers.push(trigger);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,23 +4,23 @@ import { immer } from 'zustand/middleware/immer';
|
||||||
interface MachineStore {
|
interface MachineStore {
|
||||||
machines: MachineStatus[];
|
machines: MachineStatus[];
|
||||||
|
|
||||||
// Actions
|
|
||||||
addMachine: (productId: string, machine: MachineEventSchema) => void;
|
addMachine: (productId: string, machine: MachineEventSchema) => void;
|
||||||
removeMachine: (modelUuid: string) => void;
|
removeMachine: (modelUuid: string) => void;
|
||||||
updateMachine: (
|
updateMachine: (
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
updates: Partial<Omit<MachineStatus, 'modelUuid' | 'productId'>>
|
updates: Partial<Omit<MachineStatus, 'modelUuid' | 'productId'>>
|
||||||
) => void;
|
) => void;
|
||||||
|
clearMachines: () => void;
|
||||||
|
|
||||||
|
addCurrentAction: (modelUuid: string, actionUuid: string) => void;
|
||||||
|
removeCurrentAction: (modelUuid: string) => void;
|
||||||
|
|
||||||
// Status updates
|
|
||||||
setMachineActive: (modelUuid: string, isActive: boolean) => void;
|
setMachineActive: (modelUuid: string, isActive: boolean) => void;
|
||||||
setMachineState: (modelUuid: string, newState: MachineStatus['state']) => void;
|
setMachineState: (modelUuid: string, newState: MachineStatus['state']) => void;
|
||||||
|
|
||||||
// Time tracking
|
|
||||||
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
|
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
|
||||||
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
|
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
|
||||||
|
|
||||||
// Helpers
|
|
||||||
getMachineById: (modelUuid: string) => MachineStatus | undefined;
|
getMachineById: (modelUuid: string) => MachineStatus | undefined;
|
||||||
getMachinesByProduct: (productId: string) => MachineStatus[];
|
getMachinesByProduct: (productId: string) => MachineStatus[];
|
||||||
getMachinesBystate: (state: string) => MachineStatus[];
|
getMachinesBystate: (state: string) => MachineStatus[];
|
||||||
|
@ -32,17 +32,19 @@ export const useMachineStore = create<MachineStore>()(
|
||||||
immer((set, get) => ({
|
immer((set, get) => ({
|
||||||
machines: [],
|
machines: [],
|
||||||
|
|
||||||
// Actions
|
|
||||||
addMachine: (productId, machine) => {
|
addMachine: (productId, machine) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.machines.push({
|
const exists = state.machines.some(m => m.modelUuid === machine.modelUuid);
|
||||||
...machine,
|
if (!exists) {
|
||||||
productId,
|
state.machines.push({
|
||||||
isActive: false,
|
...machine,
|
||||||
idleTime: 0,
|
productId,
|
||||||
activeTime: 0,
|
isActive: false,
|
||||||
state: 'idle',
|
idleTime: 0,
|
||||||
});
|
activeTime: 0,
|
||||||
|
state: 'idle',
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -61,7 +63,36 @@ export const useMachineStore = create<MachineStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Status updates
|
clearMachines: () => {
|
||||||
|
set((state) => {
|
||||||
|
state.machines = [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
addCurrentAction: (modelUuid) => {
|
||||||
|
set((state) => {
|
||||||
|
const armBot = state.machines.find(a => a.modelUuid === modelUuid);
|
||||||
|
if (armBot) {
|
||||||
|
const action = armBot.point.action;
|
||||||
|
if (action) {
|
||||||
|
armBot.currentAction = {
|
||||||
|
actionUuid: action.actionUuid,
|
||||||
|
actionName: action.actionName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
removeCurrentAction: (modelUuid) => {
|
||||||
|
set((state) => {
|
||||||
|
const armBot = state.machines.find(a => a.modelUuid === modelUuid);
|
||||||
|
if (armBot) {
|
||||||
|
armBot.currentAction = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setMachineActive: (modelUuid, isActive) => {
|
setMachineActive: (modelUuid, isActive) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const machine = state.machines.find(m => m.modelUuid === modelUuid);
|
const machine = state.machines.find(m => m.modelUuid === modelUuid);
|
||||||
|
@ -80,7 +111,6 @@ export const useMachineStore = create<MachineStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Time tracking
|
|
||||||
incrementActiveTime: (modelUuid, incrementBy) => {
|
incrementActiveTime: (modelUuid, incrementBy) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const machine = state.machines.find(m => m.modelUuid === modelUuid);
|
const machine = state.machines.find(m => m.modelUuid === modelUuid);
|
||||||
|
@ -99,7 +129,6 @@ export const useMachineStore = create<MachineStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Helpers
|
|
||||||
getMachineById: (modelUuid) => {
|
getMachineById: (modelUuid) => {
|
||||||
return get().machines.find(m => m.modelUuid === modelUuid);
|
return get().machines.find(m => m.modelUuid === modelUuid);
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,27 +33,30 @@ type ProductsStore = {
|
||||||
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']
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
removeAction: (actionUuid: string) => EventsSchema | undefined;
|
removeAction: (productId: string, actionUuid: string) => EventsSchema | undefined;
|
||||||
updateAction: (
|
updateAction: (
|
||||||
|
productId: 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']>
|
||||||
) => EventsSchema | undefined;
|
) => EventsSchema | undefined;
|
||||||
|
|
||||||
// Trigger-level actions
|
// Trigger-level actions
|
||||||
addTrigger: (
|
addTrigger: (
|
||||||
|
productId: string,
|
||||||
actionUuid: string,
|
actionUuid: string,
|
||||||
trigger: TriggerSchema
|
trigger: TriggerSchema
|
||||||
) => void;
|
) => EventsSchema | undefined;
|
||||||
removeTrigger: (triggerUuid: string) => void;
|
removeTrigger: (productId: string, triggerUuid: string) => EventsSchema | undefined;
|
||||||
updateTrigger: (
|
updateTrigger: (
|
||||||
|
productId: string,
|
||||||
triggerUuid: string,
|
triggerUuid: string,
|
||||||
updates: Partial<TriggerSchema>
|
updates: Partial<TriggerSchema>
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
// Renaming functions
|
// Renaming functions
|
||||||
renameProduct: (productId: string, newName: string) => void;
|
renameProduct: (productId: string, newName: string) => void;
|
||||||
renameAction: (actionUuid: string, newName: string) => EventsSchema | undefined;
|
renameAction: (productId: string, actionUuid: string, newName: string) => EventsSchema | undefined;
|
||||||
renameTrigger: (triggerUuid: string, newName: string) => void;
|
renameTrigger: (productId: string, triggerUuid: string, newName: string) => void;
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
getProductById: (productId: string) => { productName: string; productId: string; eventDatas: EventsSchema[] } | undefined;
|
getProductById: (productId: string) => { productName: string; productId: string; eventDatas: EventsSchema[] } | undefined;
|
||||||
|
@ -71,12 +74,15 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
// Product-level actions
|
// Product-level actions
|
||||||
addProduct: (productName, productId) => {
|
addProduct: (productName, productId) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const newProduct = {
|
const existingProduct = state.products.find(p => p.productId === productId);
|
||||||
productName,
|
if (!existingProduct) {
|
||||||
productId: productId,
|
const newProduct = {
|
||||||
eventDatas: []
|
productName,
|
||||||
};
|
productId: productId,
|
||||||
state.products.push(newProduct);
|
eventDatas: []
|
||||||
|
};
|
||||||
|
state.products.push(newProduct);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -106,7 +112,10 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const product = state.products.find(p => p.productId === productId);
|
const product = state.products.find(p => p.productId === productId);
|
||||||
if (product) {
|
if (product) {
|
||||||
product.eventDatas.push(event);
|
const existingEvent = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === event.modelUuid);
|
||||||
|
if (!existingEvent) {
|
||||||
|
product.eventDatas.push(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -120,7 +129,7 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteEvent: (modelUuid: string) => {
|
deleteEvent: (modelUuid) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
for (const product of state.products) {
|
||||||
product.eventDatas = product.eventDatas.filter(e => 'modelUuid' in e && e.modelUuid !== modelUuid);
|
product.eventDatas = product.eventDatas.filter(e => 'modelUuid' in e && e.modelUuid !== modelUuid);
|
||||||
|
@ -150,9 +159,15 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
if (product) {
|
if (product) {
|
||||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||||
if (event && 'points' in event) {
|
if (event && 'points' in event) {
|
||||||
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
|
const existingPoint = (event as ConveyorEventSchema).points.find(p => p.uuid === point.uuid);
|
||||||
|
if (!existingPoint) {
|
||||||
|
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
|
||||||
|
}
|
||||||
} else if (event && 'point' in event) {
|
} else if (event && 'point' in event) {
|
||||||
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
|
const existingPoint = (event as any).point?.uuid === point.uuid;
|
||||||
|
if (!existingPoint) {
|
||||||
|
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -198,17 +213,22 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
|
||||||
if (event && 'points' in event) {
|
if (event && 'points' in event) {
|
||||||
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
|
||||||
if (point) {
|
if (point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
|
||||||
point.action = action as any;
|
point.action = action as any;
|
||||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
}
|
}
|
||||||
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
|
||||||
if ('action' in (event as any).point) {
|
if ('action' in (event as any).point) {
|
||||||
(event as any).point.action = action;
|
if (!(event as any).point.action || (event as any).point.action.actionUuid !== action.actionUuid) {
|
||||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
(event as any).point.action = action;
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
} else if ('actions' in (event as any).point) {
|
} else if ('actions' in (event as any).point) {
|
||||||
(event as any).point.actions.push(action);
|
const existingAction = (event as any).point.actions.find((a: any) => a.actionUuid === action.actionUuid);
|
||||||
updatedEvent = JSON.parse(JSON.stringify(event));
|
if (!existingAction) {
|
||||||
|
(event as any).point.actions.push(action);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,10 +236,11 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
return updatedEvent;
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeAction: (actionUuid: string) => {
|
removeAction: (productId, actionUuid) => {
|
||||||
let updatedEvent: EventsSchema | undefined;
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
// Handle ConveyorEventSchema
|
// Handle ConveyorEventSchema
|
||||||
|
@ -248,10 +269,11 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
return updatedEvent;
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateAction: (actionUuid, updates) => {
|
updateAction: (productId, actionUuid, updates) => {
|
||||||
let updatedEvent: EventsSchema | undefined;
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
|
@ -283,26 +305,40 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
},
|
},
|
||||||
|
|
||||||
// Trigger-level actions
|
// Trigger-level actions
|
||||||
addTrigger: (actionUuid, trigger) => {
|
addTrigger: (productId, actionUuid, trigger) => {
|
||||||
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
if (point.action && point.action.actionUuid === actionUuid) {
|
if (point.action && point.action.actionUuid === actionUuid) {
|
||||||
point.action.triggers.push(trigger);
|
const existingTrigger = point.action.triggers.find(t => t.triggerUuid === trigger.triggerUuid);
|
||||||
|
if (!existingTrigger) {
|
||||||
|
point.action.triggers.push(trigger);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ('point' in event) {
|
} else if ('point' in event) {
|
||||||
const point = (event as any).point;
|
const point = (event as any).point;
|
||||||
if ('action' in point && point.action.actionUuid === actionUuid) {
|
if ('action' in point && point.action.actionUuid === actionUuid) {
|
||||||
point.action.triggers.push(trigger);
|
const existingTrigger = point.action.triggers.find((t: any) => t.triggerUuid === trigger.triggerUuid);
|
||||||
|
if (!existingTrigger) {
|
||||||
|
point.action.triggers.push(trigger);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else if ('actions' in point) {
|
} else if ('actions' in point) {
|
||||||
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
|
||||||
if (action) {
|
if (action) {
|
||||||
action.triggers.push(trigger);
|
const existingTrigger = action.triggers.find((t: any) => t.triggerUuid === trigger.triggerUuid);
|
||||||
|
if (!existingTrigger) {
|
||||||
|
action.triggers.push(trigger);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,26 +346,41 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeTrigger: (triggerUuid) => {
|
removeTrigger: (productId, triggerUuid) => {
|
||||||
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
if (point.action && 'triggers' in point.action) {
|
if (point.action && 'triggers' in point.action) {
|
||||||
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
|
const Trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
|
||||||
|
if (Trigger) {
|
||||||
|
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ('point' in event) {
|
} else if ('point' in event) {
|
||||||
const point = (event as any).point;
|
const point = (event as any).point;
|
||||||
if ('action' in point && 'triggers' in point.action) {
|
if ('action' in point && 'triggers' in point.action) {
|
||||||
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
const Trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||||
|
if (Trigger) {
|
||||||
|
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
} else if ('actions' in point) {
|
} else if ('actions' in point) {
|
||||||
for (const action of point.actions) {
|
for (const action of point.actions) {
|
||||||
if ('triggers' in action) {
|
if ('triggers' in action) {
|
||||||
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
const Trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
|
||||||
|
if (Trigger) {
|
||||||
|
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
|
||||||
|
updatedEvent = JSON.parse(JSON.stringify(event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,11 +388,13 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTrigger: (triggerUuid, updates) => {
|
updateTrigger: (productId, triggerUuid, updates) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
|
@ -388,10 +441,11 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renameAction: (actionUuid, newName) => {
|
renameAction: (productId, actionUuid, newName) => {
|
||||||
let updatedEvent: EventsSchema | undefined;
|
let updatedEvent: EventsSchema | undefined;
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
|
@ -422,9 +476,10 @@ export const useProductStore = create<ProductsStore>()(
|
||||||
return updatedEvent;
|
return updatedEvent;
|
||||||
},
|
},
|
||||||
|
|
||||||
renameTrigger: (triggerUuid, newName) => {
|
renameTrigger: (productId, triggerUuid, newName) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
for (const product of state.products) {
|
const product = state.products.find(p => p.productId === productId);
|
||||||
|
if (product) {
|
||||||
for (const event of product.eventDatas) {
|
for (const event of product.eventDatas) {
|
||||||
if ('points' in event) {
|
if ('points' in event) {
|
||||||
for (const point of (event as ConveyorEventSchema).points) {
|
for (const point of (event as ConveyorEventSchema).points) {
|
||||||
|
|
|
@ -114,4 +114,36 @@ export const useSelectedAction = create<SelectedActionState>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
interface IsDraggingState {
|
||||||
|
isDragging: "start" | "end" | null;
|
||||||
|
setIsDragging: (state: "start" | "end" | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useIsDragging = create<IsDraggingState>()(
|
||||||
|
immer((set) => ({
|
||||||
|
isDragging: null,
|
||||||
|
setIsDragging: (state) => {
|
||||||
|
set((s) => {
|
||||||
|
s.isDragging = state;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
interface IsRotatingState {
|
||||||
|
isRotating: "start" | "end" | null;
|
||||||
|
setIsRotating: (state: "start" | "end" | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useIsRotating = create<IsRotatingState>()(
|
||||||
|
immer((set) => ({
|
||||||
|
isRotating: null,
|
||||||
|
setIsRotating: (state) => {
|
||||||
|
set((s) => {
|
||||||
|
s.isRotating = state;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}))
|
||||||
);
|
);
|
|
@ -4,26 +4,22 @@ import { immer } from 'zustand/middleware/immer';
|
||||||
interface StorageUnitStore {
|
interface StorageUnitStore {
|
||||||
storageUnits: StorageUnitStatus[];
|
storageUnits: StorageUnitStatus[];
|
||||||
|
|
||||||
// Actions
|
|
||||||
addStorageUnit: (productId: string, storageUnit: StorageEventSchema) => void;
|
addStorageUnit: (productId: string, storageUnit: StorageEventSchema) => void;
|
||||||
removeStorageUnit: (modelUuid: string) => void;
|
removeStorageUnit: (modelUuid: string) => void;
|
||||||
updateStorageUnit: (
|
updateStorageUnit: (
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
updates: Partial<Omit<StorageUnitStatus, 'modelUuid' | 'productId'>>
|
updates: Partial<Omit<StorageUnitStatus, 'modelUuid' | 'productId'>>
|
||||||
) => void;
|
) => void;
|
||||||
|
clearStorageUnits: () => void;
|
||||||
|
|
||||||
// Status updates
|
|
||||||
setStorageUnitActive: (modelUuid: string, isActive: boolean) => void;
|
setStorageUnitActive: (modelUuid: string, isActive: boolean) => void;
|
||||||
setStorageUnitState: (modelUuid: string, newState: StorageUnitStatus['state']) => void;
|
setStorageUnitState: (modelUuid: string, newState: StorageUnitStatus['state']) => void;
|
||||||
|
|
||||||
// Load updates
|
|
||||||
updateStorageUnitLoad: (modelUuid: string, incrementBy: number) => void;
|
updateStorageUnitLoad: (modelUuid: string, incrementBy: number) => void;
|
||||||
|
|
||||||
// Time tracking
|
|
||||||
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
|
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
|
||||||
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
|
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
|
||||||
|
|
||||||
// Helpers
|
|
||||||
getStorageUnitById: (modelUuid: string) => StorageUnitStatus | undefined;
|
getStorageUnitById: (modelUuid: string) => StorageUnitStatus | undefined;
|
||||||
getStorageUnitsByProduct: (productId: string) => StorageUnitStatus[];
|
getStorageUnitsByProduct: (productId: string) => StorageUnitStatus[];
|
||||||
getStorageUnitsBystate: (state: string) => StorageUnitStatus[];
|
getStorageUnitsBystate: (state: string) => StorageUnitStatus[];
|
||||||
|
@ -37,18 +33,20 @@ export const useStorageUnitStore = create<StorageUnitStore>()(
|
||||||
immer((set, get) => ({
|
immer((set, get) => ({
|
||||||
storageUnits: [],
|
storageUnits: [],
|
||||||
|
|
||||||
// Actions
|
|
||||||
addStorageUnit: (productId, storageUnit) => {
|
addStorageUnit: (productId, storageUnit) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.storageUnits.push({
|
const exists = state.storageUnits.some(s => s.modelUuid === storageUnit.modelUuid);
|
||||||
...storageUnit,
|
if (!exists) {
|
||||||
productId,
|
state.storageUnits.push({
|
||||||
isActive: false,
|
...storageUnit,
|
||||||
idleTime: 0,
|
productId,
|
||||||
activeTime: 0,
|
isActive: false,
|
||||||
currentLoad: 0,
|
idleTime: 0,
|
||||||
state: 'idle',
|
activeTime: 0,
|
||||||
});
|
currentLoad: 0,
|
||||||
|
state: 'idle',
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -67,7 +65,12 @@ export const useStorageUnitStore = create<StorageUnitStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Status updates
|
clearStorageUnits: () => {
|
||||||
|
set(() => ({
|
||||||
|
storageUnits: [],
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
setStorageUnitActive: (modelUuid, isActive) => {
|
setStorageUnitActive: (modelUuid, isActive) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
|
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
|
||||||
|
@ -86,7 +89,6 @@ export const useStorageUnitStore = create<StorageUnitStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Load updates
|
|
||||||
updateStorageUnitLoad: (modelUuid, incrementBy) => {
|
updateStorageUnitLoad: (modelUuid, incrementBy) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
|
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
|
||||||
|
@ -96,7 +98,6 @@ export const useStorageUnitStore = create<StorageUnitStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Time tracking
|
|
||||||
incrementActiveTime: (modelUuid, incrementBy) => {
|
incrementActiveTime: (modelUuid, incrementBy) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
|
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
|
||||||
|
@ -115,7 +116,6 @@ export const useStorageUnitStore = create<StorageUnitStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Helpers
|
|
||||||
getStorageUnitById: (modelUuid) => {
|
getStorageUnitById: (modelUuid) => {
|
||||||
return get().storageUnits.find(s => s.modelUuid === modelUuid);
|
return get().storageUnits.find(s => s.modelUuid === modelUuid);
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,6 +20,7 @@ interface VehiclesStore {
|
||||||
modelUuid: string,
|
modelUuid: string,
|
||||||
updates: Partial<Omit<VehicleStatus, 'modelUuid' | 'productId'>>
|
updates: Partial<Omit<VehicleStatus, 'modelUuid' | 'productId'>>
|
||||||
) => void;
|
) => void;
|
||||||
|
clearvehicles: () => void;
|
||||||
|
|
||||||
setVehicleActive: (modelUuid: string, isActive: boolean) => void;
|
setVehicleActive: (modelUuid: string, isActive: boolean) => void;
|
||||||
updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void;
|
updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void;
|
||||||
|
@ -41,15 +42,18 @@ export const useVehicleStore = create<VehiclesStore>()(
|
||||||
|
|
||||||
addVehicle: (productId, event) => {
|
addVehicle: (productId, event) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.vehicles.push({
|
const exists = state.vehicles.some(v => v.modelUuid === event.modelUuid);
|
||||||
...event,
|
if (!exists) {
|
||||||
productId,
|
state.vehicles.push({
|
||||||
isActive: false,
|
...event,
|
||||||
idleTime: 0,
|
productId,
|
||||||
activeTime: 0,
|
isActive: false,
|
||||||
currentLoad: 0,
|
idleTime: 0,
|
||||||
distanceTraveled: 0,
|
activeTime: 0,
|
||||||
});
|
currentLoad: 0,
|
||||||
|
distanceTraveled: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -68,6 +72,12 @@ export const useVehicleStore = create<VehiclesStore>()(
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearvehicles: () => {
|
||||||
|
set((state) => {
|
||||||
|
state.vehicles = [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setVehicleActive: (modelUuid, isActive) => {
|
setVehicleActive: (modelUuid, isActive) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid);
|
const vehicle = state.vehicles.find(v => v.modelUuid === modelUuid);
|
||||||
|
|
|
@ -88,6 +88,7 @@ interface StoragePointSchema {
|
||||||
actionType: "store";
|
actionType: "store";
|
||||||
materials: { materialName: string; materialId: string; }[];
|
materials: { materialName: string; materialId: string; }[];
|
||||||
storageCapacity: number;
|
storageCapacity: number;
|
||||||
|
triggers: TriggerSchema[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +144,10 @@ interface MachineStatus extends MachineEventSchema {
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
idleTime: number;
|
idleTime: number;
|
||||||
activeTime: number;
|
activeTime: number;
|
||||||
|
currentAction?: {
|
||||||
|
actionUuid: string;
|
||||||
|
actionName: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ArmBotStatus extends RoboticArmEventSchema {
|
interface ArmBotStatus extends RoboticArmEventSchema {
|
||||||
|
|
Loading…
Reference in New Issue