Refactor asset model handling and event data management
- Removed redundant data structure in handleModelLoad function. - Introduced eventData object to encapsulate event-related information for different asset types (Conveyor, Vehicle, ArmBot, StaticMachine). - Updated socket emission to include complete data with eventData. - Enhanced copy-paste and duplication controls to maintain eventData integrity during object duplication. - Integrated event data updates in move and rotate controls to reflect changes in the simulation state. - Improved PointsCreator component to handle rotation for event groups. - Updated handleAddEventToProduct function to support event data management. - Enhanced product management to fetch existing products from the server and handle new product creation. - Added new types for eventData in worldTypes and simulationTypes for better type safety. - Refactored IndexedDB utility functions for cleaner code.
This commit is contained in:
parent
ea53af62c4
commit
882c81a385
|
@ -1,9 +1,8 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
useSelectedAsset,
|
||||
useSelectedEventData,
|
||||
useSelectedEventSphere,
|
||||
useSelectedProduct,
|
||||
useSelectedEventData,
|
||||
useSelectedEventSphere,
|
||||
useSelectedProduct,
|
||||
} from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../store/simulation/useProductStore";
|
||||
import ConveyorMechanics from "./mechanics/conveyorMechanics";
|
||||
|
@ -13,120 +12,117 @@ import MachineMechanics from "./mechanics/machineMechanics";
|
|||
import StorageMechanics from "./mechanics/storageMechanics";
|
||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
|
||||
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
||||
|
||||
const EventProperties: React.FC = () => {
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getEventByModelUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(
|
||||
null
|
||||
);
|
||||
const [assetType, setAssetType] = useState<string | null>(null);
|
||||
const { products, addEvent } = useProductStore();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getEventByModelUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(null);
|
||||
const [assetType, setAssetType] = useState<string | null>(null);
|
||||
const { products, addEvent } = useProductStore();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
useEffect(() => {
|
||||
const event = getCurrentEventData();
|
||||
setCurrentEventData(event);
|
||||
useEffect(() => {
|
||||
const event = getCurrentEventData();
|
||||
setCurrentEventData(event);
|
||||
|
||||
const type = determineAssetType(event);
|
||||
setAssetType(type);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
const type = determineAssetType(event);
|
||||
setAssetType(type);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const getCurrentEventData = () => {
|
||||
if (!selectedEventData?.data || !selectedProduct) return null;
|
||||
return (
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid
|
||||
) ?? null
|
||||
);
|
||||
};
|
||||
|
||||
const determineAssetType = (event: EventsSchema | null) => {
|
||||
if (!event) return null;
|
||||
|
||||
switch (event.type) {
|
||||
case "transfer":
|
||||
return "conveyor";
|
||||
case "vehicle":
|
||||
return "vehicle";
|
||||
case "roboticArm":
|
||||
return "roboticArm";
|
||||
case "machine":
|
||||
return "machine";
|
||||
case "storageUnit":
|
||||
return "storageUnit";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const getCurrentEventData = () => {
|
||||
if (!selectedEventData?.data || !selectedProduct) return null;
|
||||
return (
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid
|
||||
) ?? null
|
||||
<div className="event-proprties-wrapper">
|
||||
{currentEventData && (
|
||||
<>
|
||||
<div className="header">
|
||||
<div className="header-value">
|
||||
{selectedEventData?.data.modelName}
|
||||
</div>
|
||||
</div>
|
||||
{assetType === "conveyor" && <ConveyorMechanics />}
|
||||
{assetType === "vehicle" && <VehicleMechanics />}
|
||||
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
||||
{assetType === "machine" && <MachineMechanics />}
|
||||
{assetType === "storageUnit" && <StorageMechanics />}
|
||||
</>
|
||||
)}
|
||||
{!currentEventData && selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like this object doesn't have an
|
||||
event assigned yet. To continue, please link it to one of the
|
||||
products below.
|
||||
</p>
|
||||
|
||||
<div className="products-list">
|
||||
<p>
|
||||
<strong>Here are some products you can add it to:</strong>
|
||||
</p>
|
||||
<ul>
|
||||
{products.map((product) => (
|
||||
<li key={product.productId}>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (selectedEventData) {
|
||||
handleAddEventToProduct({
|
||||
event: useEventsStore.getState().getEventByModelUuid(selectedEventData?.data.modelUuid),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AddIcon />
|
||||
{product.productName}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like you haven't selected an event
|
||||
point yet. Please select an event to view its properties.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
const determineAssetType = (event: EventsSchema | null) => {
|
||||
if (!event) return null;
|
||||
|
||||
switch (event.type) {
|
||||
case "transfer":
|
||||
return "conveyor";
|
||||
case "vehicle":
|
||||
return "vehicle";
|
||||
case "roboticArm":
|
||||
return "roboticArm";
|
||||
case "machine":
|
||||
return "machine";
|
||||
case "storageUnit":
|
||||
return "storageUnit";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="event-proprties-wrapper">
|
||||
{currentEventData && (
|
||||
<>
|
||||
<div className="header">
|
||||
<div className="header-value">
|
||||
{selectedEventData?.data.modelName}
|
||||
</div>
|
||||
</div>
|
||||
{assetType === "conveyor" && <ConveyorMechanics />}
|
||||
{assetType === "vehicle" && <VehicleMechanics />}
|
||||
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
||||
{assetType === "machine" && <MachineMechanics />}
|
||||
{assetType === "storageUnit" && <StorageMechanics />}
|
||||
</>
|
||||
)}
|
||||
{!currentEventData && selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like this object doesn't have an
|
||||
event assigned yet. To continue, please link it to one of the
|
||||
products below.
|
||||
</p>
|
||||
|
||||
<div className="products-list">
|
||||
<p>
|
||||
<strong>Here are some products you can add it to:</strong>
|
||||
</p>
|
||||
<ul>
|
||||
{products.map((product) => (
|
||||
<li key={product.productId}>
|
||||
<button
|
||||
onClick={() =>
|
||||
handleAddEventToProduct({
|
||||
selectedAsset,
|
||||
addEvent,
|
||||
selectedProduct: {
|
||||
productId: product.productId,
|
||||
productName: product.productName,
|
||||
},
|
||||
clearSelectedAsset,
|
||||
})
|
||||
}
|
||||
>
|
||||
<AddIcon />
|
||||
{product.productName}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like you haven't selected an event
|
||||
point yet. Please select an event to view its properties.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EventProperties;
|
||||
|
|
|
@ -8,217 +8,193 @@ import SwapAction from "../actions/SwapAction";
|
|||
import SpawnAction from "../actions/SpawnAction";
|
||||
import DefaultAction from "../actions/DefaultAction";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
import {
|
||||
useSelectedEventData,
|
||||
useSelectedProduct,
|
||||
} from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
|
||||
function ConveyorMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<
|
||||
"default" | "spawn" | "swap" | "delay" | "despawn"
|
||||
>("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<
|
||||
ConveyorPointSchema | undefined
|
||||
>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as ConveyorPointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(
|
||||
point.action.actionType as
|
||||
| "default"
|
||||
| "spawn"
|
||||
| "swap"
|
||||
| "delay"
|
||||
| "despawn"
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as ConveyorPointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as | "default" | "spawn" | "swap" | "delay" | "despawn");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
|
||||
speed: parseFloat(value),
|
||||
});
|
||||
};
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
|
||||
speed: parseFloat(value),
|
||||
});
|
||||
};
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as
|
||||
| "default"
|
||||
| "spawn"
|
||||
| "swap"
|
||||
| "delay"
|
||||
| "despawn";
|
||||
setActiveOption(validOption);
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as | "default" | "spawn" | "swap" | "delay" | "despawn";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
actionType: validOption,
|
||||
});
|
||||
};
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
actionType: validOption,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
||||
};
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
||||
};
|
||||
|
||||
const handleSpawnCountChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
spawnCount: value === "inherit" ? "inherit" : parseFloat(value),
|
||||
});
|
||||
};
|
||||
const handleSpawnCountChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
spawnCount: value === "inherit" ? "inherit" : parseFloat(value),
|
||||
});
|
||||
};
|
||||
|
||||
const handleSpawnIntervalChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
spawnInterval: value === "inherit" ? "inherit" : parseFloat(value),
|
||||
});
|
||||
};
|
||||
const handleSpawnIntervalChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
spawnInterval: value === "inherit" ? "inherit" : parseFloat(value),
|
||||
});
|
||||
};
|
||||
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { material });
|
||||
};
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { material });
|
||||
};
|
||||
|
||||
const handleDelayChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
delay: value === "inherit" ? "inherit" : parseFloat(value),
|
||||
});
|
||||
};
|
||||
const handleDelayChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
delay: value === "inherit" ? "inherit" : parseFloat(value),
|
||||
});
|
||||
};
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "default",
|
||||
options: ["default", "spawn", "swap", "delay", "despawn"],
|
||||
};
|
||||
const availableActions = {
|
||||
defaultOption: "default",
|
||||
options: ["default", "spawn", "swap", "delay", "despawn"],
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentSpeed =
|
||||
selectedEventData?.data.type === "transfer"
|
||||
? selectedEventData.data.speed.toString()
|
||||
: "0.5";
|
||||
// Get current values from store
|
||||
const currentSpeed = selectedEventData?.data.type === "transfer"
|
||||
? selectedEventData.data.speed.toString()
|
||||
: "0.5";
|
||||
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
|
||||
const currentMaterial = selectedPointData
|
||||
? selectedPointData.action.material
|
||||
: "Default material";
|
||||
const currentMaterial = selectedPointData
|
||||
? selectedPointData.action.material
|
||||
: "Default material";
|
||||
|
||||
const currentSpawnCount = selectedPointData
|
||||
? selectedPointData.action.spawnCount?.toString() || "1"
|
||||
: "1";
|
||||
const currentSpawnCount = selectedPointData
|
||||
? selectedPointData.action.spawnCount?.toString() || "1"
|
||||
: "1";
|
||||
|
||||
const currentSpawnInterval = selectedPointData
|
||||
? selectedPointData.action.spawnInterval?.toString() || "1"
|
||||
: "1";
|
||||
const currentSpawnInterval = selectedPointData
|
||||
? selectedPointData.action.spawnInterval?.toString() || "1"
|
||||
: "1";
|
||||
|
||||
const currentDelay = selectedPointData
|
||||
? selectedPointData.action.delay?.toString() || "0"
|
||||
: "0";
|
||||
const currentDelay = selectedPointData
|
||||
? selectedPointData.action.delay?.toString() || "0"
|
||||
: "0";
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData && (
|
||||
return (
|
||||
<>
|
||||
<div key={selectedPointData?.uuid} className="global-props">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={currentSpeed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue={"0.5"}
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => {}}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{selectedEventData && (
|
||||
<>
|
||||
<div key={selectedPointData?.uuid} className="global-props">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={currentSpeed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue={"0.5"}
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={
|
||||
selectedPointData
|
||||
? selectedPointData.action.actionType
|
||||
: "default"
|
||||
}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "default" && <DefaultAction />}
|
||||
{activeOption === "spawn" && (
|
||||
<SpawnAction
|
||||
onChangeCount={handleSpawnCountChange}
|
||||
options={["Default material", "Material 1", "Material 2"]}
|
||||
defaultOption={currentMaterial}
|
||||
onSelect={handleMaterialSelect}
|
||||
onChangeInterval={handleSpawnIntervalChange}
|
||||
intervalValue={currentSpawnInterval}
|
||||
countValue={currentSpawnCount}
|
||||
intervalMin={1}
|
||||
intervalMax={60}
|
||||
intervalDefaultValue="1"
|
||||
countMin={1}
|
||||
countMax={100}
|
||||
countDefaultValue="1"
|
||||
/>
|
||||
)}
|
||||
{activeOption === "swap" && (
|
||||
<SwapAction
|
||||
options={["Default material", "Material 1", "Material 2"]}
|
||||
defaultOption={currentMaterial}
|
||||
onSelect={handleMaterialSelect}
|
||||
/>
|
||||
)}
|
||||
{activeOption === "despawn" && <DespawnAction />}
|
||||
{activeOption === "delay" && (
|
||||
<DelayAction
|
||||
value={currentDelay}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={60}
|
||||
onChange={handleDelayChange}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={selectedPointData ? selectedPointData.action.actionType : "default"}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "default" && <DefaultAction />}
|
||||
{activeOption === "spawn" && (
|
||||
<SpawnAction
|
||||
onChangeCount={handleSpawnCountChange}
|
||||
options={["Default material", "Material 1", "Material 2"]}
|
||||
defaultOption={currentMaterial}
|
||||
onSelect={handleMaterialSelect}
|
||||
onChangeInterval={handleSpawnIntervalChange}
|
||||
intervalValue={currentSpawnInterval}
|
||||
countValue={currentSpawnCount}
|
||||
intervalMin={1}
|
||||
intervalMax={60}
|
||||
intervalDefaultValue="1"
|
||||
countMin={1}
|
||||
countMax={100}
|
||||
countDefaultValue="1"
|
||||
/>
|
||||
)}
|
||||
{activeOption === "swap" && (
|
||||
<SwapAction
|
||||
options={["Default material", "Material 1", "Material 2"]}
|
||||
defaultOption={currentMaterial}
|
||||
onSelect={handleMaterialSelect}
|
||||
/>
|
||||
)}
|
||||
{activeOption === "despawn" && <DespawnAction />}
|
||||
{activeOption === "delay" && (
|
||||
<DelayAction
|
||||
value={currentDelay}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={60}
|
||||
onChange={handleDelayChange}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default ConveyorMechanics;
|
||||
|
|
|
@ -2,128 +2,121 @@ import { useEffect, useState } from "react";
|
|||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
import {
|
||||
useSelectedEventData,
|
||||
useSelectedProduct,
|
||||
} from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import ProcessAction from "../actions/ProcessAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
|
||||
function MachineMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "process">(
|
||||
"default"
|
||||
);
|
||||
const [selectedPointData, setSelectedPointData] = useState<
|
||||
MachinePointSchema | undefined
|
||||
>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [activeOption, setActiveOption] = useState<"default" | "process">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<MachinePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as MachinePointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "process");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as MachinePointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "process");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "process";
|
||||
setActiveOption(validOption);
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "process";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
actionType: validOption,
|
||||
});
|
||||
};
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
actionType: validOption,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
||||
};
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
||||
};
|
||||
|
||||
const handleProcessTimeChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
processTime: parseFloat(value),
|
||||
});
|
||||
};
|
||||
const handleProcessTimeChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
processTime: parseFloat(value),
|
||||
});
|
||||
};
|
||||
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
swapMaterial: material,
|
||||
});
|
||||
};
|
||||
const handleMaterialSelect = (material: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
swapMaterial: material,
|
||||
});
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
// Get current values from store
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
|
||||
const currentProcessTime = selectedPointData
|
||||
? selectedPointData.action.processTime.toString()
|
||||
: "1";
|
||||
const currentProcessTime = selectedPointData
|
||||
? selectedPointData.action.processTime.toString()
|
||||
: "1";
|
||||
|
||||
const currentMaterial = selectedPointData
|
||||
? selectedPointData.action.swapMaterial
|
||||
: "Default material";
|
||||
const currentMaterial = selectedPointData
|
||||
? selectedPointData.action.swapMaterial
|
||||
: "Default material";
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "process",
|
||||
options: ["process"],
|
||||
};
|
||||
const availableActions = {
|
||||
defaultOption: "process",
|
||||
options: ["process"],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData && (
|
||||
return (
|
||||
<>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption="process"
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "process" && (
|
||||
<ProcessAction
|
||||
value={currentProcessTime}
|
||||
min={0.1}
|
||||
max={60}
|
||||
defaultValue="1"
|
||||
onChange={handleProcessTimeChange}
|
||||
swapOptions={["Default material", "Material 1", "Material 2"]}
|
||||
swapDefaultOption={currentMaterial}
|
||||
onSwapSelect={handleMaterialSelect}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
{selectedEventData && (
|
||||
<>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption="process"
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "process" && (
|
||||
<ProcessAction
|
||||
value={currentProcessTime}
|
||||
min={0.1}
|
||||
max={60}
|
||||
defaultValue="1"
|
||||
onChange={handleProcessTimeChange}
|
||||
swapOptions={["Default material", "Material 1", "Material 2"]}
|
||||
swapDefaultOption={currentMaterial}
|
||||
onSwapSelect={handleMaterialSelect}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default MachineMechanics;
|
||||
|
|
|
@ -3,192 +3,164 @@ import InputWithDropDown from "../../../../../ui/inputs/InputWithDropDown";
|
|||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
import {
|
||||
useSelectedEventData,
|
||||
useSelectedProduct,
|
||||
useSelectedAction,
|
||||
} from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedEventData, useSelectedProduct, useSelectedAction } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import PickAndPlaceAction from "../actions/PickAndPlaceAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
|
||||
function RoboticArmMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">(
|
||||
"default"
|
||||
);
|
||||
const [selectedPointData, setSelectedPointData] = useState<
|
||||
RoboticArmPointSchema | undefined
|
||||
>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } =
|
||||
useSelectedAction();
|
||||
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<RoboticArmPointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateEvent, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const { selectedAction, setSelectedAction, clearSelectedAction } = useSelectedAction();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as RoboticArmPointSchema | undefined;
|
||||
if (point?.actions) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(
|
||||
point.actions[0].actionType as "default" | "pickAndPlace"
|
||||
);
|
||||
if (point.actions.length > 0 && !selectedAction.actionId) {
|
||||
setSelectedAction(
|
||||
point.actions[0].actionUuid,
|
||||
point.actions[0].actionName
|
||||
);
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid,
|
||||
selectedEventData.selectedPoint
|
||||
) as RoboticArmPointSchema | undefined;
|
||||
if (point?.actions) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.actions[0].actionType as "default" | "pickAndPlace");
|
||||
if (point.actions.length > 0 && !selectedAction.actionId) {
|
||||
setSelectedAction(
|
||||
point.actions[0].actionUuid,
|
||||
point.actions[0].actionName
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clearSelectedAction();
|
||||
}
|
||||
}, [
|
||||
clearSelectedAction,
|
||||
getPointByUuid,
|
||||
selectedAction.actionId,
|
||||
selectedEventData,
|
||||
selectedProduct,
|
||||
setSelectedAction,
|
||||
]);
|
||||
}, [clearSelectedAction, getPointByUuid, selectedAction.actionId, selectedEventData, selectedProduct, setSelectedAction,]);
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedAction.actionId) return;
|
||||
updateAction(selectedAction.actionId, { actionName: newName });
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedAction.actionId) return;
|
||||
updateAction(selectedAction.actionId, { actionName: newName });
|
||||
|
||||
if (selectedPointData) {
|
||||
const updatedActions = selectedPointData.actions.map((action) =>
|
||||
action.actionUuid === selectedAction.actionId
|
||||
? { ...action, actionName: newName }
|
||||
: action
|
||||
);
|
||||
setSelectedPointData({
|
||||
...selectedPointData,
|
||||
actions: updatedActions,
|
||||
});
|
||||
}
|
||||
};
|
||||
if (selectedPointData) {
|
||||
const updatedActions = selectedPointData.actions.map((action) =>
|
||||
action.actionUuid === selectedAction.actionId ? { ...action, actionName: newName } : action
|
||||
);
|
||||
setSelectedPointData({
|
||||
...selectedPointData,
|
||||
actions: updatedActions,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
|
||||
speed: parseFloat(value),
|
||||
});
|
||||
};
|
||||
const handleSpeedChange = (value: string) => {
|
||||
if (!selectedEventData) return;
|
||||
updateEvent(selectedProduct.productId, selectedEventData.data.modelUuid, {
|
||||
speed: parseFloat(value),
|
||||
});
|
||||
};
|
||||
|
||||
const handlePickPointChange = (value: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
const [x, y, z] = value.split(",").map(Number);
|
||||
const handlePickPointChange = (value: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
const [x, y, z] = value.split(",").map(Number);
|
||||
|
||||
updateAction(selectedAction.actionId, {
|
||||
process: {
|
||||
startPoint: [x, y, z] as [number, number, number],
|
||||
endPoint:
|
||||
selectedPointData.actions.find(
|
||||
(a) => a.actionUuid === selectedAction.actionId
|
||||
)?.process.endPoint || null,
|
||||
},
|
||||
});
|
||||
};
|
||||
updateAction(selectedAction.actionId, {
|
||||
process: {
|
||||
startPoint: [x, y, z] as [number, number, number],
|
||||
endPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.endPoint || null,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handlePlacePointChange = (value: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
const [x, y, z] = value.split(",").map(Number);
|
||||
const handlePlacePointChange = (value: string) => {
|
||||
if (!selectedAction.actionId || !selectedPointData) return;
|
||||
const [x, y, z] = value.split(",").map(Number);
|
||||
|
||||
updateAction(selectedAction.actionId, {
|
||||
process: {
|
||||
startPoint:
|
||||
selectedPointData.actions.find(
|
||||
(a) => a.actionUuid === selectedAction.actionId
|
||||
)?.process.startPoint || null,
|
||||
endPoint: [x, y, z] as [number, number, number],
|
||||
},
|
||||
});
|
||||
};
|
||||
updateAction(selectedAction.actionId, {
|
||||
process: {
|
||||
startPoint: selectedPointData.actions.find((a) => a.actionUuid === selectedAction.actionId)?.process.startPoint || null,
|
||||
endPoint: [x, y, z] as [number, number, number],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "pickAndPlace",
|
||||
options: ["pickAndPlace"],
|
||||
};
|
||||
const availableActions = {
|
||||
defaultOption: "pickAndPlace",
|
||||
options: ["pickAndPlace"],
|
||||
};
|
||||
|
||||
const currentSpeed =
|
||||
selectedEventData?.data.type === "roboticArm"
|
||||
? selectedEventData.data.speed.toString()
|
||||
: "0.5";
|
||||
const currentSpeed = selectedEventData?.data.type === "roboticArm"
|
||||
? selectedEventData.data.speed.toString()
|
||||
: "0.5";
|
||||
|
||||
const currentAction = selectedPointData?.actions.find(
|
||||
(a) => a.actionUuid === selectedAction.actionId
|
||||
);
|
||||
const currentPickPoint = currentAction?.process.startPoint
|
||||
? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}`
|
||||
: "";
|
||||
const currentPlacePoint = currentAction?.process.endPoint
|
||||
? `${currentAction.process.endPoint[0]},${currentAction.process.endPoint[1]},${currentAction.process.endPoint[2]}`
|
||||
: "";
|
||||
const currentAction = selectedPointData?.actions.find((a) => a.actionUuid === selectedAction.actionId);
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData && selectedPointData && (
|
||||
const currentPickPoint = currentAction?.process.startPoint
|
||||
? `${currentAction.process.startPoint[0]},${currentAction.process.startPoint[1]},${currentAction.process.startPoint[2]}`
|
||||
: "";
|
||||
const currentPlacePoint = currentAction?.process.endPoint
|
||||
? `${currentAction.process.endPoint[0]},${currentAction.process.endPoint[1]},${currentAction.process.endPoint[2]}`
|
||||
: "";
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="global-props">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={currentSpeed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue={"0.5"}
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => {}}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{selectedEventData && selectedPointData && (
|
||||
<>
|
||||
<div className="global-props">
|
||||
<div className="property-list-container">
|
||||
<div className="property-item">
|
||||
<InputWithDropDown
|
||||
label="Speed"
|
||||
value={currentSpeed}
|
||||
min={0}
|
||||
step={0.1}
|
||||
defaultValue={"0.5"}
|
||||
max={10}
|
||||
activeOption="m/s"
|
||||
onClick={() => { }}
|
||||
onChange={handleSpeedChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction
|
||||
/>
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
multipleAction
|
||||
/>
|
||||
|
||||
{selectedAction.actionId && currentAction && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={selectedAction.actionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={() => {}}
|
||||
disabled={true}
|
||||
/>
|
||||
<PickAndPlaceAction
|
||||
pickPointValue={currentPickPoint}
|
||||
pickPointOnChange={handlePickPointChange}
|
||||
placePointValue={currentPlacePoint}
|
||||
placePointOnChange={handlePlacePointChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{selectedAction.actionId && currentAction && (
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={selectedAction.actionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={() => { }}
|
||||
disabled={true}
|
||||
/>
|
||||
<PickAndPlaceAction
|
||||
pickPointValue={currentPickPoint}
|
||||
pickPointOnChange={handlePickPointChange}
|
||||
placePointValue={currentPlacePoint}
|
||||
placePointOnChange={handlePlacePointChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default RoboticArmMechanics;
|
||||
|
|
|
@ -2,119 +2,112 @@ import { useEffect, useState } from "react";
|
|||
import RenameInput from "../../../../../ui/inputs/RenameInput";
|
||||
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
|
||||
import Trigger from "../trigger/Trigger";
|
||||
import {
|
||||
useSelectedEventData,
|
||||
useSelectedProduct,
|
||||
} from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../../store/simulation/useProductStore";
|
||||
import StorageAction from "../actions/StorageAction";
|
||||
import ActionsList from "../components/ActionsList";
|
||||
|
||||
function StorageMechanics() {
|
||||
const [activeOption, setActiveOption] = useState<
|
||||
"default" | "store" | "spawn"
|
||||
>("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<
|
||||
StoragePointSchema | undefined
|
||||
>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [activeOption, setActiveOption] = useState<"default" | "store" | "spawn">("default");
|
||||
const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getPointByUuid, updateAction } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "store" | "spawn");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||
useEffect(() => {
|
||||
if (selectedEventData) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData?.data.modelUuid,
|
||||
selectedEventData?.selectedPoint
|
||||
) as StoragePointSchema | undefined;
|
||||
if (point && "action" in point) {
|
||||
setSelectedPointData(point);
|
||||
setActiveOption(point.action.actionType as "store" | "spawn");
|
||||
}
|
||||
}
|
||||
}, [selectedProduct, selectedEventData, getPointByUuid]);
|
||||
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "store" | "spawn";
|
||||
setActiveOption(validOption);
|
||||
const handleActionTypeChange = (option: string) => {
|
||||
if (!selectedEventData || !selectedPointData) return;
|
||||
const validOption = option as "store" | "spawn";
|
||||
setActiveOption(validOption);
|
||||
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
actionType: validOption,
|
||||
});
|
||||
};
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
actionType: validOption,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
||||
};
|
||||
const handleRenameAction = (newName: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, { actionName: newName });
|
||||
};
|
||||
|
||||
const handleCapacityChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
storageCapacity: parseInt(value),
|
||||
});
|
||||
};
|
||||
const handleCapacityChange = (value: string) => {
|
||||
if (!selectedPointData) return;
|
||||
updateAction(selectedPointData.action.actionUuid, {
|
||||
storageCapacity: parseInt(value),
|
||||
});
|
||||
};
|
||||
|
||||
// Get current values from store
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
// Get current values from store
|
||||
const currentActionName = selectedPointData
|
||||
? selectedPointData.action.actionName
|
||||
: "Action Name";
|
||||
|
||||
const currentCapacity = selectedPointData
|
||||
? selectedPointData.action.storageCapacity.toString()
|
||||
: "0";
|
||||
const currentCapacity = selectedPointData
|
||||
? selectedPointData.action.storageCapacity.toString()
|
||||
: "0";
|
||||
|
||||
const availableActions = {
|
||||
defaultOption: "store",
|
||||
options: ["store", "spawn"],
|
||||
};
|
||||
const availableActions = {
|
||||
defaultOption: "store",
|
||||
options: ["store", "spawn"],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedEventData && (
|
||||
return (
|
||||
<>
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "store" && (
|
||||
<StorageAction
|
||||
value={currentCapacity}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={20}
|
||||
onChange={handleCapacityChange}
|
||||
/>
|
||||
)}
|
||||
{activeOption === "spawn" && (
|
||||
<div className="spawn-options">
|
||||
<p>Spawn configuration options would go here</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
{selectedEventData && (
|
||||
<>
|
||||
<ActionsList
|
||||
setSelectedPointData={setSelectedPointData}
|
||||
selectedPointData={selectedPointData}
|
||||
/>
|
||||
<div className="selected-actions-details">
|
||||
<div className="selected-actions-header">
|
||||
<RenameInput
|
||||
value={currentActionName}
|
||||
onRename={handleRenameAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="selected-actions-list">
|
||||
<LabledDropdown
|
||||
defaultOption={activeOption}
|
||||
options={availableActions.options}
|
||||
onSelect={handleActionTypeChange}
|
||||
/>
|
||||
{activeOption === "store" && (
|
||||
<StorageAction
|
||||
value={currentCapacity}
|
||||
defaultValue="0"
|
||||
min={0}
|
||||
max={20}
|
||||
onChange={handleCapacityChange}
|
||||
/>
|
||||
)}
|
||||
{activeOption === "spawn" && (
|
||||
<div className="spawn-options">
|
||||
<p>Spawn configuration options would go here</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tirgger">
|
||||
<Trigger />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
export default StorageMechanics;
|
||||
|
|
|
@ -1,216 +1,216 @@
|
|||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useRef } from "react";
|
||||
import {
|
||||
AddIcon,
|
||||
ArrowIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
AddIcon,
|
||||
ArrowIcon,
|
||||
RemoveIcon,
|
||||
ResizeHeightIcon,
|
||||
} from "../../../icons/ExportCommonIcons";
|
||||
import RenameInput from "../../../ui/inputs/RenameInput";
|
||||
import { handleResize } from "../../../../functions/handleResizePannel";
|
||||
import {
|
||||
useSelectedAsset,
|
||||
useSelectedProduct,
|
||||
useSelectedAsset,
|
||||
useSelectedProduct,
|
||||
} from "../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||
import { generateUUID } from "three/src/math/MathUtils";
|
||||
import RenderOverlay from "../../../templates/Overlay";
|
||||
import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
|
||||
import { upsertProductOrEventApi } from "../../../../services/simulation/UpsertProductOrEventApi";
|
||||
import { handleAddEventToProduct } from "../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
|
||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||
import { deleteEventDataApi } from "../../../../services/simulation/deleteEventDataApi";
|
||||
|
||||
interface Event {
|
||||
pathName: string;
|
||||
pathName: string;
|
||||
}
|
||||
|
||||
interface ListProps {
|
||||
val: Event;
|
||||
val: Event;
|
||||
}
|
||||
|
||||
const List: React.FC<ListProps> = ({ val }) => {
|
||||
return (
|
||||
<div className="process-container">
|
||||
<div className="value">{val.pathName}</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="process-container">
|
||||
<div className="value">{val.pathName}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Simulations: React.FC = () => {
|
||||
const productsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
products,
|
||||
addProduct,
|
||||
removeProduct,
|
||||
renameProduct,
|
||||
addEvent,
|
||||
removeEvent,
|
||||
} = useProductStore();
|
||||
const { selectedProduct, setSelectedProduct } = useSelectedProduct();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
const productsContainerRef = useRef<HTMLDivElement>(null);
|
||||
const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent, } = useProductStore();
|
||||
const { selectedProduct, setSelectedProduct } = useSelectedProduct();
|
||||
const { getEventByModelUuid } = useEventsStore();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
|
||||
const handleAddProduct = () => {
|
||||
addProduct(`Product ${products.length + 1}`, generateUUID());
|
||||
};
|
||||
const handleAddProduct = () => {
|
||||
addProduct(`Product ${products.length + 1}`, generateUUID());
|
||||
};
|
||||
|
||||
const handleRemoveProduct = (productId: string) => {
|
||||
const currentIndex = products.findIndex((p) => p.productId === productId);
|
||||
const isSelected = selectedProduct.productId === productId;
|
||||
const handleRemoveProduct = (productId: string) => {
|
||||
const currentIndex = products.findIndex((p) => p.productId === productId);
|
||||
const isSelected = selectedProduct.productId === productId;
|
||||
|
||||
const updatedProducts = products.filter((p) => p.productId !== productId);
|
||||
const updatedProducts = products.filter((p) => p.productId !== productId);
|
||||
|
||||
if (isSelected) {
|
||||
if (updatedProducts.length > 0) {
|
||||
let newSelectedIndex = currentIndex;
|
||||
if (currentIndex >= updatedProducts.length) {
|
||||
newSelectedIndex = updatedProducts.length - 1;
|
||||
if (isSelected) {
|
||||
if (updatedProducts.length > 0) {
|
||||
let newSelectedIndex = currentIndex;
|
||||
if (currentIndex >= updatedProducts.length) {
|
||||
newSelectedIndex = updatedProducts.length - 1;
|
||||
}
|
||||
setSelectedProduct(
|
||||
updatedProducts[newSelectedIndex].productId,
|
||||
updatedProducts[newSelectedIndex].productName
|
||||
);
|
||||
} else {
|
||||
setSelectedProduct("", "");
|
||||
}
|
||||
}
|
||||
setSelectedProduct(
|
||||
updatedProducts[newSelectedIndex].productId,
|
||||
updatedProducts[newSelectedIndex].productName
|
||||
);
|
||||
} else {
|
||||
setSelectedProduct("", "");
|
||||
}
|
||||
}
|
||||
|
||||
removeProduct(productId);
|
||||
};
|
||||
removeProduct(productId);
|
||||
};
|
||||
|
||||
const handleRenameProduct = (productId: string, newName: string) => {
|
||||
renameProduct(productId, newName);
|
||||
if (selectedProduct.productId === productId) {
|
||||
setSelectedProduct(productId, newName);
|
||||
}
|
||||
};
|
||||
const handleRenameProduct = (productId: string, newName: string) => {
|
||||
renameProduct(productId, newName);
|
||||
if (selectedProduct.productId === productId) {
|
||||
setSelectedProduct(productId, newName);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveEventFromProduct = () => {
|
||||
if (selectedAsset) {
|
||||
removeEvent(selectedProduct.productId, selectedAsset.modelUuid);
|
||||
clearSelectedAsset();
|
||||
}
|
||||
};
|
||||
const handleRemoveEventFromProduct = () => {
|
||||
if (selectedAsset) {
|
||||
const email = localStorage.getItem('email')
|
||||
const organization = (email!.split("@")[1]).split(".")[0];
|
||||
deleteEventDataApi({
|
||||
productId: selectedProduct.productId,
|
||||
modelUuid: selectedAsset.modelUuid,
|
||||
organization: organization
|
||||
});
|
||||
removeEvent(selectedProduct.productId, selectedAsset.modelUuid);
|
||||
clearSelectedAsset();
|
||||
}
|
||||
};
|
||||
|
||||
const selectedProductData = products.find(
|
||||
(product) => product.productId === selectedProduct.productId
|
||||
);
|
||||
const selectedProductData = products.find(
|
||||
(product) => product.productId === selectedProduct.productId
|
||||
);
|
||||
|
||||
const events: Event[] =
|
||||
selectedProductData?.eventDatas.map((event) => ({
|
||||
pathName: event.modelName,
|
||||
const events: Event[] = selectedProductData?.eventDatas.map((event) => ({
|
||||
pathName: event.modelName,
|
||||
})) || [];
|
||||
|
||||
return (
|
||||
<div className="simulations-container">
|
||||
<div className="header">Simulations</div>
|
||||
<div className="add-product-container">
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Products</div>
|
||||
<div className="add-button" onClick={handleAddProduct}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={productsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{products.map((product, index) => (
|
||||
<div
|
||||
key={product.productId}
|
||||
className={`list-item ${
|
||||
selectedProduct.productId === product.productId
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() =>
|
||||
setSelectedProduct(product.productId, product.productName)
|
||||
}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="products"
|
||||
checked={selectedProduct.productId === product.productId}
|
||||
readOnly
|
||||
/>
|
||||
<RenameInput
|
||||
value={product.productName}
|
||||
onRename={(newName) =>
|
||||
handleRenameProduct(product.productId, newName)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{products.length > 1 && (
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleRemoveProduct(product.productId)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
return (
|
||||
<div className="simulations-container">
|
||||
<div className="header">Simulations</div>
|
||||
<div className="add-product-container">
|
||||
<div className="actions">
|
||||
<div className="header">
|
||||
<div className="header-value">Products</div>
|
||||
<div className="add-button" onClick={handleAddProduct}>
|
||||
<AddIcon /> Add
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="lists-main-container"
|
||||
ref={productsContainerRef}
|
||||
style={{ height: "120px" }}
|
||||
>
|
||||
<div className="list-container">
|
||||
{products.map((product, index) => (
|
||||
<div
|
||||
key={product.productId}
|
||||
className={`list-item ${selectedProduct.productId === product.productId
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="value"
|
||||
onClick={() =>
|
||||
setSelectedProduct(product.productId, product.productName)
|
||||
}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="products"
|
||||
checked={selectedProduct.productId === product.productId}
|
||||
readOnly
|
||||
/>
|
||||
<RenameInput
|
||||
value={product.productName}
|
||||
onRename={(newName) =>
|
||||
handleRenameProduct(product.productId, newName)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{products.length > 1 && (
|
||||
<div
|
||||
className="remove-button"
|
||||
onClick={() => handleRemoveProduct(product.productId)}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, productsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="resize-icon"
|
||||
id="action-resize"
|
||||
onMouseDown={(e) => handleResize(e, productsContainerRef)}
|
||||
>
|
||||
<ResizeHeightIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="simulation-process">
|
||||
<div className="collapse-header-container">
|
||||
<div className="header">Events</div>
|
||||
<div className="arrow-container">
|
||||
<ArrowIcon />
|
||||
<div className="simulation-process">
|
||||
<div className="collapse-header-container">
|
||||
<div className="header">Events</div>
|
||||
<div className="arrow-container">
|
||||
<ArrowIcon />
|
||||
</div>
|
||||
</div>
|
||||
{events.map((event, index) => (
|
||||
<List key={index} val={event} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="compare-simulations-container">
|
||||
<div className="compare-simulations-header">
|
||||
Need to Compare Layout?
|
||||
</div>
|
||||
<div className="content">
|
||||
Click <span>'Compare'</span> to review and analyze the layout
|
||||
differences between them.
|
||||
</div>
|
||||
<div className="input">
|
||||
<input type="button" value={"Compare"} className="submit" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{events.map((event, index) => (
|
||||
<List key={index} val={event} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="compare-simulations-container">
|
||||
<div className="compare-simulations-header">
|
||||
Need to Compare Layout?
|
||||
</div>
|
||||
<div className="content">
|
||||
Click <span>'Compare'</span> to review and analyze the layout
|
||||
differences between them.
|
||||
</div>
|
||||
<div className="input">
|
||||
<input type="button" value={"Compare"} className="submit" />
|
||||
</div>
|
||||
{selectedAsset && (
|
||||
<RenderOverlay>
|
||||
<EditWidgetOption
|
||||
options={["Add to Product", "Remove from Product"]}
|
||||
onClick={(option) => {
|
||||
if (option === "Add to Product") {
|
||||
handleAddEventToProduct({
|
||||
event: getEventByModelUuid(selectedAsset.modelUuid),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
clearSelectedAsset
|
||||
});
|
||||
} else {
|
||||
handleRemoveEventFromProduct();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</RenderOverlay>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedAsset && (
|
||||
<RenderOverlay>
|
||||
<EditWidgetOption
|
||||
options={["Add to Product", "Remove from Product"]}
|
||||
onClick={(option) => {
|
||||
if (option === "Add to Product") {
|
||||
handleAddEventToProduct({
|
||||
selectedAsset,
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
clearSelectedAsset,
|
||||
});
|
||||
} else {
|
||||
handleRemoveEventFromProduct();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</RenderOverlay>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default Simulations;
|
||||
|
|
|
@ -156,7 +156,7 @@ function processLoadedModel(
|
|||
const model = gltf.clone();
|
||||
model.uuid = item.modeluuid;
|
||||
model.scale.set(...CONSTANTS.assetConfig.defaultScaleBeforeGsap);
|
||||
model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid };
|
||||
model.userData = { name: item.modelname, modelId: item.modelfileID, modeluuid: item.modeluuid, eventData: item.eventData };
|
||||
model.position.set(...item.position);
|
||||
model.rotation.set(item.rotation.x, item.rotation.y, item.rotation.z);
|
||||
|
||||
|
@ -170,256 +170,141 @@ function processLoadedModel(
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
itemsGroup?.current?.add(model);
|
||||
|
||||
setFloorItems((prevItems) => [
|
||||
...(prevItems || []),
|
||||
{
|
||||
modeluuid: item.modeluuid,
|
||||
modelname: item.modelname,
|
||||
position: item.position,
|
||||
rotation: item.rotation,
|
||||
modelfileID: item.modelfileID,
|
||||
isLocked: item.isLocked,
|
||||
isVisible: item.isVisible,
|
||||
},
|
||||
]);
|
||||
if (item.eventData) {
|
||||
setFloorItems((prevItems) => [
|
||||
...(prevItems || []),
|
||||
{
|
||||
modeluuid: item.modeluuid,
|
||||
modelname: item.modelname,
|
||||
position: item.position,
|
||||
rotation: item.rotation,
|
||||
modelfileID: item.modelfileID,
|
||||
isLocked: item.isLocked,
|
||||
isVisible: item.isVisible,
|
||||
eventData: item.eventData,
|
||||
},
|
||||
]);
|
||||
|
||||
if (item.modelfileID === "a1ee92554935007b10b3eb05") {
|
||||
const data = PointsCalculator(
|
||||
'Vehicle',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const vehicleEvent: VehicleEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "vehicle",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Vehicle Action",
|
||||
actionType: "travel",
|
||||
unLoadDuration: 5,
|
||||
loadCapacity: 10,
|
||||
pickUpPoint: null,
|
||||
unLoadPoint: null,
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(vehicleEvent);
|
||||
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") {
|
||||
const data = PointsCalculator(
|
||||
'Conveyor',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "transfer",
|
||||
speed: 1,
|
||||
points: data.points.map((point: THREE.Vector3, index: number) => ({
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [point.x, point.y, point.z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action ${index + 1}`,
|
||||
actionType: 'default',
|
||||
material: 'Default material',
|
||||
delay: 0,
|
||||
spawnInterval: 5,
|
||||
spawnCount: 1,
|
||||
triggers: []
|
||||
}
|
||||
}))
|
||||
};
|
||||
addEvent(ConveyorEvent);
|
||||
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") {
|
||||
// const data = PointsCalculator(
|
||||
// 'Conveyor',
|
||||
// gltf.clone(),
|
||||
// new THREE.Vector3(...model.rotation)
|
||||
// );
|
||||
|
||||
// if (!data || !data.points) return;
|
||||
|
||||
// const points: ConveyorPointSchema[] = data.points.map((point: THREE.Vector3, index: number) => {
|
||||
// const actionUuid = THREE.MathUtils.generateUUID();
|
||||
// return {
|
||||
// uuid: THREE.MathUtils.generateUUID(),
|
||||
// position: [point.x, point.y, point.z],
|
||||
// rotation: [0, 0, 0],
|
||||
// action: {
|
||||
// actionUuid,
|
||||
// actionName: `Action ${index}`,
|
||||
// actionType: 'default',
|
||||
// material: 'inherit',
|
||||
// delay: 0,
|
||||
// spawnInterval: 5,
|
||||
// spawnCount: 1,
|
||||
// triggers: []
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
|
||||
// points.forEach((point, index) => {
|
||||
// if (index < points.length - 1) {
|
||||
// const nextPoint = points[index + 1];
|
||||
// point.action.triggers.push({
|
||||
// triggerUuid: THREE.MathUtils.generateUUID(),
|
||||
// triggerName: `Trigger 1`,
|
||||
// triggerType: "onComplete",
|
||||
// delay: 0,
|
||||
// triggeredAsset: {
|
||||
// triggeredModel: {
|
||||
// modelName: item.modelname,
|
||||
// modelUuid: item.modeluuid
|
||||
// },
|
||||
// triggeredPoint: {
|
||||
// pointName: `Point ${index + 1}`,
|
||||
// pointUuid: nextPoint.uuid
|
||||
// },
|
||||
// triggeredAction: {
|
||||
// actionName: nextPoint.action.actionName,
|
||||
// actionUuid: nextPoint.action.actionUuid
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// const ConveyorEvent: ConveyorEventSchema = {
|
||||
// modelUuid: item.modeluuid,
|
||||
// modelName: item.modelname,
|
||||
// position: item.position,
|
||||
// rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
// state: "idle",
|
||||
// type: "transfer",
|
||||
// speed: 1,
|
||||
// points
|
||||
// };
|
||||
// addEvent(ConveyorEvent);
|
||||
} else if (item.modelfileID === "7dc04e36882e4debbc1a8e3d") {
|
||||
const data = PointsCalculator(
|
||||
'Conveyor',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "transfer",
|
||||
speed: 1,
|
||||
points: data.points.map((point: THREE.Vector3, index: number) => ({
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [point.x, point.y, point.z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action ${index}`,
|
||||
actionType: 'default',
|
||||
material: 'inherit',
|
||||
delay: 0,
|
||||
spawnInterval: 5,
|
||||
spawnCount: 1,
|
||||
triggers: []
|
||||
}
|
||||
}))
|
||||
};
|
||||
addEvent(ConveyorEvent);
|
||||
} else if (item.modelfileID === "29dee78715ad5b853f5c346d") {
|
||||
const data = PointsCalculator(
|
||||
'StaticMachine',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const machineEvent: MachineEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "machine",
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Process Action",
|
||||
actionType: "process",
|
||||
processTime: 10,
|
||||
swapMaterial: "material-id",
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(machineEvent);
|
||||
} else if (item.modelfileID === "52e6681fbb743a890d96c914") {
|
||||
const data = PointsCalculator(
|
||||
'ArmBot',
|
||||
gltf.clone(),
|
||||
new THREE.Vector3(...model.rotation)
|
||||
);
|
||||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const roboticArmEvent: RoboticArmEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "roboticArm",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: THREE.MathUtils.generateUUID(),
|
||||
position: [data.points[0].x, data.points[0].y, data.points[0].z],
|
||||
rotation: [0, 0, 0],
|
||||
actions: [
|
||||
{
|
||||
if (item.eventData.type === "vehicle") {
|
||||
const vehicleEvent: VehicleEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "vehicle",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
||||
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Pick and Place",
|
||||
actionType: "pickAndPlace",
|
||||
process: {
|
||||
startPoint: [0, 0, 0],
|
||||
endPoint: [0, 0, 0]
|
||||
},
|
||||
actionName: "Vehicle Action",
|
||||
actionType: "travel",
|
||||
unLoadDuration: 5,
|
||||
loadCapacity: 10,
|
||||
pickUpPoint: null,
|
||||
unLoadPoint: null,
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
addEvent(roboticArmEvent);
|
||||
}
|
||||
};
|
||||
addEvent(vehicleEvent);
|
||||
} else if (item.eventData.type === "Conveyor") {
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "transfer",
|
||||
speed: 1,
|
||||
points: item.eventData.points?.map((point: any, index: number) => ({
|
||||
uuid: point.uuid || THREE.MathUtils.generateUUID(),
|
||||
position: [point.position[0], point.position[1], point.position[2]],
|
||||
rotation: [point.rotation[0], point.rotation[1], point.rotation[2]],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: `Action ${index + 1}`,
|
||||
actionType: 'default',
|
||||
material: 'Default material',
|
||||
delay: 0,
|
||||
spawnInterval: 5,
|
||||
spawnCount: 1,
|
||||
triggers: []
|
||||
}
|
||||
})) || [],
|
||||
};
|
||||
addEvent(ConveyorEvent);
|
||||
} else if (item.eventData.type === "StaticMachine") {
|
||||
const machineEvent: MachineEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "machine",
|
||||
point: {
|
||||
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
||||
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||
action: {
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Process Action",
|
||||
actionType: "process",
|
||||
processTime: 10,
|
||||
swapMaterial: "material-id",
|
||||
triggers: []
|
||||
}
|
||||
}
|
||||
};
|
||||
addEvent(machineEvent);
|
||||
} else if (item.eventData.type === "ArmBot") {
|
||||
const roboticArmEvent: RoboticArmEventSchema = {
|
||||
modelUuid: item.modeluuid,
|
||||
modelName: item.modelname,
|
||||
position: item.position,
|
||||
rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
|
||||
state: "idle",
|
||||
type: "roboticArm",
|
||||
speed: 1,
|
||||
point: {
|
||||
uuid: item.eventData.point?.uuid || THREE.MathUtils.generateUUID(),
|
||||
position: [item.eventData.point?.position[0] || 0, item.eventData.point?.position[1] || 0, item.eventData.point?.position[2] || 0],
|
||||
rotation: [item.eventData.point?.rotation[0] || 0, item.eventData.point?.rotation[1] || 0, item.eventData.point?.rotation[2] || 0],
|
||||
actions: [
|
||||
{
|
||||
actionUuid: THREE.MathUtils.generateUUID(),
|
||||
actionName: "Pick and Place",
|
||||
actionType: "pickAndPlace",
|
||||
process: {
|
||||
startPoint: [0, 0, 0],
|
||||
endPoint: [0, 0, 0]
|
||||
},
|
||||
triggers: []
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
addEvent(roboticArmEvent);
|
||||
|
||||
}
|
||||
} else {
|
||||
setFloorItems((prevItems) => [
|
||||
...(prevItems || []),
|
||||
{
|
||||
modeluuid: item.modeluuid,
|
||||
modelname: item.modelname,
|
||||
position: item.position,
|
||||
rotation: item.rotation,
|
||||
modelfileID: item.modelfileID,
|
||||
isLocked: item.isLocked,
|
||||
isVisible: item.isVisible,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
gsap.to(model.position, { y: item.position[1], duration: 1.5, ease: 'power2.out' });
|
||||
|
|
|
@ -164,18 +164,6 @@ async function handleModelLoad(
|
|||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
organization,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
modelname: newFloorItem.modelname,
|
||||
modelfileID: newFloorItem.modelfileID,
|
||||
position: newFloorItem.position,
|
||||
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket.id
|
||||
};
|
||||
|
||||
if (selectedItem.type) {
|
||||
const data = PointsCalculator(
|
||||
selectedItem.type,
|
||||
|
@ -185,6 +173,10 @@ async function handleModelLoad(
|
|||
|
||||
if (!data || !data.points) return;
|
||||
|
||||
const eventData: any = {
|
||||
type: selectedItem.type,
|
||||
};
|
||||
|
||||
if (selectedItem.type === "Conveyor") {
|
||||
const ConveyorEvent: ConveyorEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
|
@ -209,8 +201,14 @@ async function handleModelLoad(
|
|||
triggers: []
|
||||
}
|
||||
}))
|
||||
}
|
||||
};
|
||||
addEvent(ConveyorEvent);
|
||||
eventData.points = ConveyorEvent.points.map(point => ({
|
||||
uuid: point.uuid,
|
||||
position: point.position,
|
||||
rotation: point.rotation
|
||||
}));
|
||||
|
||||
} else if (selectedItem.type === "Vehicle") {
|
||||
const vehicleEvent: VehicleEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
|
@ -237,6 +235,12 @@ async function handleModelLoad(
|
|||
}
|
||||
};
|
||||
addEvent(vehicleEvent);
|
||||
eventData.point = {
|
||||
uuid: vehicleEvent.point.uuid,
|
||||
position: vehicleEvent.point.position,
|
||||
rotation: vehicleEvent.point.rotation
|
||||
};
|
||||
|
||||
} else if (selectedItem.type === "ArmBot") {
|
||||
const roboticArmEvent: RoboticArmEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
|
@ -265,6 +269,13 @@ async function handleModelLoad(
|
|||
}
|
||||
};
|
||||
addEvent(roboticArmEvent);
|
||||
console.log('roboticArmEvent: ', roboticArmEvent);
|
||||
eventData.point = {
|
||||
uuid: roboticArmEvent.point.uuid,
|
||||
position: roboticArmEvent.point.position,
|
||||
rotation: roboticArmEvent.point.rotation
|
||||
};
|
||||
|
||||
} else if (selectedItem.type === "StaticMachine") {
|
||||
const machineEvent: MachineEventSchema = {
|
||||
modelUuid: newFloorItem.modeluuid,
|
||||
|
@ -288,19 +299,65 @@ async function handleModelLoad(
|
|||
}
|
||||
};
|
||||
addEvent(machineEvent);
|
||||
eventData.point = {
|
||||
uuid: machineEvent.point.uuid,
|
||||
position: machineEvent.point.position,
|
||||
rotation: machineEvent.point.rotation
|
||||
};
|
||||
}
|
||||
|
||||
const completeData = {
|
||||
organization,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
modelname: newFloorItem.modelname,
|
||||
modelfileID: newFloorItem.modelfileID,
|
||||
position: newFloorItem.position,
|
||||
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket.id,
|
||||
eventData: eventData
|
||||
};
|
||||
|
||||
model.userData.eventData = eventData;
|
||||
|
||||
newFloorItem.eventData = eventData;
|
||||
|
||||
setFloorItems((prevItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
socket.emit("v2:model-asset:add", completeData);
|
||||
|
||||
gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" });
|
||||
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } });
|
||||
} else {
|
||||
|
||||
const data = {
|
||||
organization,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
modelname: newFloorItem.modelname,
|
||||
modelfileID: newFloorItem.modelfileID,
|
||||
position: newFloorItem.position,
|
||||
rotation: { x: model.rotation.x, y: model.rotation.y, z: model.rotation.z },
|
||||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket.id
|
||||
};
|
||||
|
||||
setFloorItems((prevItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" });
|
||||
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } });
|
||||
}
|
||||
|
||||
setFloorItems((prevItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
return updatedItems;
|
||||
});
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
gsap.to(model.position, { y: newFloorItem.position[1], duration: 1.5, ease: "power2.out" });
|
||||
gsap.to(model.scale, { x: 1, y: 1, z: 1, duration: 1.5, ease: "power2.out", onComplete: () => { toast.success("Model Added!"); } });
|
||||
}
|
||||
|
||||
export default addAssetModel;
|
||||
|
|
|
@ -65,6 +65,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
|
|||
};
|
||||
|
||||
getFloorAssets(organization).then((data) => {
|
||||
console.log('data: ', data);
|
||||
if (data.length > 0) {
|
||||
const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
|
||||
totalAssets = uniqueItems.length;
|
||||
|
|
|
@ -137,6 +137,38 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
|||
|
||||
if (itemsGroupRef.current) {
|
||||
|
||||
let updatedEventData = null;
|
||||
if (obj.userData.eventData) {
|
||||
updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData));
|
||||
|
||||
updatedEventData.modelUuid = THREE.MathUtils.generateUUID();
|
||||
|
||||
if (updatedEventData.type === "Conveyor" && updatedEventData.points) {
|
||||
updatedEventData.points = updatedEventData.points.map((point: any) => ({
|
||||
...point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
}));
|
||||
}
|
||||
else if (updatedEventData.type === "Vehicle" && updatedEventData.point) {
|
||||
updatedEventData.point = {
|
||||
...updatedEventData.point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
};
|
||||
}
|
||||
else if (updatedEventData.type === "ArmBot" && updatedEventData.point) {
|
||||
updatedEventData.point = {
|
||||
...updatedEventData.point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
};
|
||||
}
|
||||
else if (updatedEventData.type === "StaticMachine" && updatedEventData.point) {
|
||||
updatedEventData.point = {
|
||||
...updatedEventData.point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const newFloorItem: Types.FloorItemType = {
|
||||
modeluuid: obj.uuid,
|
||||
modelname: obj.userData.name,
|
||||
|
@ -144,7 +176,8 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
|||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, },
|
||||
isLocked: false,
|
||||
isVisible: true
|
||||
isVisible: true,
|
||||
eventData: updatedEventData
|
||||
};
|
||||
|
||||
setFloorItems((prevItems: Types.FloorItems) => {
|
||||
|
@ -181,11 +214,18 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
|||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket.id,
|
||||
eventData: updatedEventData
|
||||
};
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
obj.userData.modeluuid = newFloorItem.modeluuid;
|
||||
obj.userData = {
|
||||
name: newFloorItem.modelname,
|
||||
modelId: newFloorItem.modelfileID,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
eventData: updatedEventData
|
||||
};
|
||||
|
||||
itemsGroupRef.current.add(obj);
|
||||
}
|
||||
});
|
||||
|
@ -205,7 +245,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
|
|||
setSelectedAssets([]);
|
||||
}
|
||||
|
||||
return null; // No visible output, but the component handles copy-paste functionality
|
||||
return null;
|
||||
};
|
||||
|
||||
export default CopyPasteControls;
|
|
@ -115,6 +115,38 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
|||
|
||||
if (itemsGroupRef.current) {
|
||||
|
||||
let updatedEventData = null;
|
||||
if (obj.userData.eventData) {
|
||||
updatedEventData = JSON.parse(JSON.stringify(obj.userData.eventData));
|
||||
|
||||
updatedEventData.modelUuid = THREE.MathUtils.generateUUID();
|
||||
|
||||
if (updatedEventData.type === "Conveyor" && updatedEventData.points) {
|
||||
updatedEventData.points = updatedEventData.points.map((point: any) => ({
|
||||
...point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
}));
|
||||
}
|
||||
else if (updatedEventData.type === "Vehicle" && updatedEventData.point) {
|
||||
updatedEventData.point = {
|
||||
...updatedEventData.point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
};
|
||||
}
|
||||
else if (updatedEventData.type === "ArmBot" && updatedEventData.point) {
|
||||
updatedEventData.point = {
|
||||
...updatedEventData.point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
};
|
||||
}
|
||||
else if (updatedEventData.type === "StaticMachine" && updatedEventData.point) {
|
||||
updatedEventData.point = {
|
||||
...updatedEventData.point,
|
||||
uuid: THREE.MathUtils.generateUUID()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const newFloorItem: Types.FloorItemType = {
|
||||
modeluuid: obj.uuid,
|
||||
modelname: obj.userData.name,
|
||||
|
@ -122,7 +154,8 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
|||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z, },
|
||||
isLocked: false,
|
||||
isVisible: true
|
||||
isVisible: true,
|
||||
eventData: updatedEventData
|
||||
};
|
||||
|
||||
setFloorItems((prevItems: Types.FloorItems) => {
|
||||
|
@ -159,11 +192,18 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
|||
isLocked: false,
|
||||
isVisible: true,
|
||||
socketId: socket.id,
|
||||
eventData: updatedEventData
|
||||
};
|
||||
|
||||
socket.emit("v2:model-asset:add", data);
|
||||
|
||||
obj.userData.modeluuid = newFloorItem.modeluuid;
|
||||
obj.userData = {
|
||||
name: newFloorItem.modelname,
|
||||
modelId: newFloorItem.modelfileID,
|
||||
modeluuid: newFloorItem.modeluuid,
|
||||
eventData: updatedEventData
|
||||
};
|
||||
|
||||
itemsGroupRef.current.add(obj);
|
||||
}
|
||||
});
|
||||
|
@ -183,7 +223,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
|
|||
setSelectedAssets([]);
|
||||
}
|
||||
|
||||
return null; // This component does not render any UI
|
||||
return null;
|
||||
};
|
||||
|
||||
export default DuplicationControls;
|
|
@ -1,11 +1,14 @@
|
|||
import * as THREE from "three";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store";
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import { toast } from "react-toastify";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||
|
||||
function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) {
|
||||
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
||||
|
@ -176,6 +179,24 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
|||
isVisible: true
|
||||
};
|
||||
|
||||
if (obj.userData.eventData) {
|
||||
const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modeluuid);
|
||||
const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid);
|
||||
|
||||
if (eventData) {
|
||||
useEventsStore.getState().updateEvent(obj.userData.modeluuid, {
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
})
|
||||
}
|
||||
if (productData) {
|
||||
useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid, {
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setFloorItems((prevItems: Types.FloorItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
|
@ -234,7 +255,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
|
|||
setSelectedAssets([]);
|
||||
}
|
||||
|
||||
return null; // No need to return anything, as this component is used for its side effects
|
||||
return null;
|
||||
}
|
||||
|
||||
export default MoveControls
|
|
@ -1,11 +1,13 @@
|
|||
import * as THREE from "three";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useFloorItems, useSelectedAssets, useSocketStore, useToggleView } from "../../../../store/store";
|
||||
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
|
||||
import { toast } from "react-toastify";
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||
|
||||
function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, boundingBoxRef }: any) {
|
||||
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
|
||||
|
@ -177,6 +179,24 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
|||
isVisible: true
|
||||
};
|
||||
|
||||
if (obj.userData.eventData) {
|
||||
const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modeluuid);
|
||||
const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid);
|
||||
|
||||
if (eventData) {
|
||||
useEventsStore.getState().updateEvent(obj.userData.modeluuid, {
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
})
|
||||
}
|
||||
if (productData) {
|
||||
useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modeluuid, {
|
||||
position: [worldPosition.x, worldPosition.y, worldPosition.z],
|
||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setFloorItems((prevItems: Types.FloorItems) => {
|
||||
const updatedItems = [...(prevItems || []), newFloorItem];
|
||||
localStorage.setItem("FloorItems", JSON.stringify(updatedItems));
|
||||
|
@ -235,7 +255,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
|||
setSelectedAssets([]);
|
||||
}
|
||||
|
||||
return null; // No need to return anything, as this component is used for its side effects
|
||||
return null;
|
||||
}
|
||||
|
||||
export default RotateControls
|
|
@ -62,7 +62,7 @@ function PointsCreator() {
|
|||
{events.map((event, i) => {
|
||||
if (event.type === 'transfer') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
{event.points.map((point, j) => (
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
|
@ -78,6 +78,7 @@ function PointsCreator() {
|
|||
}}
|
||||
key={`${i}-${j}`}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
// rotation={new THREE.Euler(...point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
|
@ -88,7 +89,7 @@ function PointsCreator() {
|
|||
);
|
||||
} else if (event.type === 'vehicle') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
uuid={event.point.uuid}
|
||||
|
@ -102,6 +103,7 @@ function PointsCreator() {
|
|||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
|
@ -111,7 +113,7 @@ function PointsCreator() {
|
|||
);
|
||||
} else if (event.type === 'roboticArm') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
uuid={event.point.uuid}
|
||||
|
@ -125,6 +127,7 @@ function PointsCreator() {
|
|||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
|
@ -134,7 +137,7 @@ function PointsCreator() {
|
|||
);
|
||||
} else if (event.type === 'machine') {
|
||||
return (
|
||||
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||
<group key={i} position={[...event.position]} rotation={[...event.rotation]} >
|
||||
<mesh
|
||||
name='Event-Sphere'
|
||||
uuid={event.point.uuid}
|
||||
|
@ -148,6 +151,7 @@ function PointsCreator() {
|
|||
setTransformMode(null);
|
||||
}}
|
||||
position={new THREE.Vector3(...event.point.position)}
|
||||
// rotation={new THREE.Euler(...event.point.rotation)}
|
||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
|
|
|
@ -1,28 +1,38 @@
|
|||
import { upsertProductOrEventApi } from "../../../../../services/simulation/UpsertProductOrEventApi";
|
||||
|
||||
interface HandleAddEventToProductParams {
|
||||
selectedAsset: any; // Replace `any` with specific type if you have it
|
||||
addEvent: (productId: string, asset: any) => void;
|
||||
event: EventsSchema | undefined;
|
||||
addEvent: (productId: string, event: EventsSchema) => void;
|
||||
selectedProduct: {
|
||||
productId: string;
|
||||
productName: string;
|
||||
// Add other fields if needed
|
||||
};
|
||||
clearSelectedAsset: () => void;
|
||||
}
|
||||
clearSelectedAsset?: () => void;
|
||||
}
|
||||
|
||||
export const handleAddEventToProduct = ({
|
||||
selectedAsset,
|
||||
event,
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
clearSelectedAsset,
|
||||
clearSelectedAsset
|
||||
}: HandleAddEventToProductParams) => {
|
||||
console.log('selectedProduct: ', selectedProduct);
|
||||
if (selectedAsset) {
|
||||
addEvent(selectedProduct.productId, selectedAsset);
|
||||
// upsertProductOrEventApi({
|
||||
// productName: selectedProduct.productName,
|
||||
// productId: selectedProduct.productId,
|
||||
// eventDatas: selectedAsset
|
||||
// });
|
||||
clearSelectedAsset();
|
||||
if (event && selectedProduct.productId) {
|
||||
addEvent(selectedProduct.productId, event);
|
||||
|
||||
const email = localStorage.getItem('email')
|
||||
const organization = (email!.split("@")[1]).split(".")[0];
|
||||
|
||||
upsertProductOrEventApi({
|
||||
productName: selectedProduct.productName,
|
||||
productId: selectedProduct.productId,
|
||||
organization: organization,
|
||||
eventDatas: event
|
||||
}).then((data) => {
|
||||
// console.log(data);
|
||||
})
|
||||
|
||||
if (clearSelectedAsset) {
|
||||
clearSelectedAsset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -7,28 +7,27 @@ import { upsertProductOrEventApi } from '../../../services/simulation/UpsertProd
|
|||
import { getAllProductsApi } from '../../../services/simulation/getallProductsApi';
|
||||
|
||||
function Products() {
|
||||
const { products, addProduct } = useProductStore();
|
||||
const { products, addProduct, setProducts } = useProductStore();
|
||||
const { setSelectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
if (products.length === 0) {
|
||||
const id = THREE.MathUtils.generateUUID();
|
||||
const name = 'Product 1';
|
||||
addProduct(name, id);
|
||||
// upsertProductOrEventApi({ productName: name, productId: id }).then((data) => {
|
||||
// console.log('data: ', data);
|
||||
// });
|
||||
setSelectedProduct(id, name);
|
||||
}
|
||||
}, [products])
|
||||
const email = localStorage.getItem('email')
|
||||
const organization = (email!.split("@")[1]).split(".")[0];
|
||||
getAllProductsApi(organization).then((data) => {
|
||||
if (data.length === 0) {
|
||||
const id = THREE.MathUtils.generateUUID();
|
||||
const name = 'Product 1';
|
||||
addProduct(name, id);
|
||||
upsertProductOrEventApi({ productName: name, productId: id, organization: organization })
|
||||
setSelectedProduct(id, name);
|
||||
} else {
|
||||
setProducts(data);
|
||||
setSelectedProduct(data[0].productId, data[0].productName);
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
// const email = localStorage.getItem('email')
|
||||
// const organization = (email!.split("@")[1]).split(".")[0];
|
||||
// console.log(organization);
|
||||
// getAllProductsApi(organization).then((data) => {
|
||||
// console.log('data: ', data);
|
||||
// })
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
|
|
@ -19,11 +19,11 @@ function Simulation() {
|
|||
const { products } = useProductStore();
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('events: ', events);
|
||||
console.log('events: ', events);
|
||||
}, [events])
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('products: ', products);
|
||||
console.log('products: ', products);
|
||||
}, [products])
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,19 +1,85 @@
|
|||
import { useEffect } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
import { useSubModuleStore } from "../../../../store/useModuleStore";
|
||||
import { useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../store/simulation/useProductStore";
|
||||
import { useEventsStore } from "../../../../store/simulation/useEventsStore";
|
||||
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
|
||||
import { handleAddEventToProduct } from "../../events/points/functions/handleAddEventToProduct";
|
||||
|
||||
interface ConnectionLine {
|
||||
id: string;
|
||||
start: THREE.Vector3;
|
||||
end: THREE.Vector3;
|
||||
mid: THREE.Vector3;
|
||||
trigger: TriggerSchema;
|
||||
}
|
||||
|
||||
function TriggerConnector() {
|
||||
const { gl, raycaster, scene } = useThree();
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { getPointByUuid, getIsEventInProduct } = useProductStore();
|
||||
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, addEvent, getEventByModelUuid } = useProductStore();
|
||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
|
||||
useEffect(() => {
|
||||
const [firstSelectedPoint, setFirstSelectedPoint] = useState<{
|
||||
productId: string;
|
||||
modelUuid: string;
|
||||
pointUuid: string;
|
||||
actionUuid?: string;
|
||||
} | null>(null);
|
||||
|
||||
const [connections, setConnections] = useState<ConnectionLine[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const newConnections: ConnectionLine[] = [];
|
||||
|
||||
products.forEach(product => {
|
||||
product.eventDatas.forEach(event => {
|
||||
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) {
|
||||
const startPos = new THREE.Vector3(...point.position);
|
||||
const endPos = new THREE.Vector3(...targetPoint.position);
|
||||
const midPos = new THREE.Vector3()
|
||||
.addVectors(startPos, endPos)
|
||||
.multiplyScalar(0.5)
|
||||
.add(new THREE.Vector3(0, 2, 0));
|
||||
|
||||
newConnections.push({
|
||||
id: `${point.uuid}-${targetPoint.uuid}-${trigger.triggerUuid}`,
|
||||
start: startPos,
|
||||
end: endPos,
|
||||
mid: midPos,
|
||||
trigger
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
setConnections(newConnections);
|
||||
}, [products]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('connections: ', connections);
|
||||
}, connections)
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = gl.domElement;
|
||||
|
||||
let drag = false;
|
||||
|
@ -44,37 +110,114 @@ function TriggerConnector() {
|
|||
const handleRightClick = (evt: MouseEvent) => {
|
||||
if (drag) return;
|
||||
evt.preventDefault();
|
||||
const canvasElement = gl.domElement;
|
||||
if (!canvasElement) return;
|
||||
|
||||
let intersects = raycaster.intersectObjects(scene.children, true);
|
||||
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;
|
||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||
if (intersects.length === 0) return;
|
||||
|
||||
if (currentObject && currentObject.name === 'Event-Sphere') {
|
||||
const currentObject = intersects[0].object;
|
||||
if (!currentObject || currentObject.name !== 'Event-Sphere') return;
|
||||
|
||||
const isInProduct = getIsEventInProduct(
|
||||
selectedProduct.productId,
|
||||
currentObject.userData.modelUuid
|
||||
);
|
||||
const modelUuid = currentObject.userData.modelUuid;
|
||||
const pointUuid = currentObject.userData.pointUuid;
|
||||
|
||||
// You left Here
|
||||
if (selectedProduct && getIsEventInProduct(selectedProduct.productId, modelUuid)) {
|
||||
|
||||
if (isInProduct) {
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
modelUuid,
|
||||
pointUuid
|
||||
);
|
||||
|
||||
const event = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
currentObject.userData.modelUuid,
|
||||
currentObject.userData.pointUuid
|
||||
);
|
||||
console.log('event: ', event);
|
||||
} else {
|
||||
if (!point) return;
|
||||
|
||||
}
|
||||
let actionUuid: string | undefined;
|
||||
if ('action' in point && point.action) {
|
||||
actionUuid = point.action.actionUuid;
|
||||
} else if ('actions' in point && point.actions.length === 1) {
|
||||
actionUuid = point.actions[0].actionUuid;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!firstSelectedPoint) {
|
||||
setFirstSelectedPoint({
|
||||
productId: selectedProduct.productId,
|
||||
modelUuid,
|
||||
pointUuid,
|
||||
actionUuid
|
||||
});
|
||||
} else {
|
||||
const trigger: TriggerSchema = {
|
||||
triggerUuid: THREE.MathUtils.generateUUID(),
|
||||
triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)} → ${pointUuid.slice(0, 4)}`,
|
||||
triggerType: "onComplete",
|
||||
delay: 0,
|
||||
triggeredAsset: {
|
||||
triggeredModel: {
|
||||
modelName: currentObject.parent?.parent?.name || 'Unknown',
|
||||
modelUuid: modelUuid
|
||||
},
|
||||
triggeredPoint: {
|
||||
pointName: currentObject.name,
|
||||
pointUuid: pointUuid
|
||||
},
|
||||
triggeredAction: actionUuid ? {
|
||||
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
||||
actionUuid: actionUuid
|
||||
} : null
|
||||
}
|
||||
};
|
||||
|
||||
if (firstSelectedPoint.actionUuid) {
|
||||
addTrigger(firstSelectedPoint.actionUuid, trigger);
|
||||
}
|
||||
setFirstSelectedPoint(null);
|
||||
}
|
||||
} else if (!getIsEventInProduct(selectedProduct.productId, modelUuid) && firstSelectedPoint) {
|
||||
handleAddEventToProduct({
|
||||
event: useEventsStore.getState().getEventByModelUuid(modelUuid),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
})
|
||||
|
||||
const point = getPointByUuid(
|
||||
selectedProduct.productId,
|
||||
modelUuid,
|
||||
pointUuid
|
||||
);
|
||||
|
||||
if (!point) return;
|
||||
|
||||
let actionUuid: string | undefined;
|
||||
if ('action' in point && point.action) {
|
||||
actionUuid = point.action.actionUuid;
|
||||
} else if ('actions' in point && point.actions.length === 1) {
|
||||
actionUuid = point.actions[0].actionUuid;
|
||||
}
|
||||
|
||||
const trigger: TriggerSchema = {
|
||||
triggerUuid: THREE.MathUtils.generateUUID(),
|
||||
triggerName: `Trigger ${firstSelectedPoint.pointUuid.slice(0, 4)} → ${pointUuid.slice(0, 4)}`,
|
||||
triggerType: "onComplete",
|
||||
delay: 0,
|
||||
triggeredAsset: {
|
||||
triggeredModel: {
|
||||
modelName: currentObject.parent?.parent?.name || 'Unknown',
|
||||
modelUuid: modelUuid
|
||||
},
|
||||
triggeredPoint: {
|
||||
pointName: currentObject.name,
|
||||
pointUuid: pointUuid
|
||||
},
|
||||
triggeredAction: actionUuid ? {
|
||||
actionName: getActionByUuid(selectedProduct.productId, actionUuid)?.actionName || 'Action',
|
||||
actionUuid: actionUuid
|
||||
} : null
|
||||
}
|
||||
};
|
||||
|
||||
if (firstSelectedPoint.actionUuid) {
|
||||
addTrigger(firstSelectedPoint.actionUuid, trigger);
|
||||
}
|
||||
setFirstSelectedPoint(null);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -92,12 +235,12 @@ function TriggerConnector() {
|
|||
canvasElement.removeEventListener('contextmenu', handleRightClick);
|
||||
};
|
||||
|
||||
}, [gl, subModule]);
|
||||
}, [gl, subModule, selectedProduct, firstSelectedPoint]);
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default TriggerConnector
|
||||
export default TriggerConnector;
|
|
@ -6,6 +6,7 @@ type ProductsStore = {
|
|||
|
||||
// Product-level actions
|
||||
addProduct: (productName: string, productId: string) => void;
|
||||
setProducts: (products: productsSchema) => void;
|
||||
removeProduct: (productId: string) => void;
|
||||
updateProduct: (productId: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void;
|
||||
|
||||
|
@ -78,6 +79,12 @@ export const useProductStore = create<ProductsStore>()(
|
|||
});
|
||||
},
|
||||
|
||||
setProducts: (products) => {
|
||||
set((state) => {
|
||||
state.products = products;
|
||||
});
|
||||
},
|
||||
|
||||
removeProduct: (productId) => {
|
||||
set((state) => {
|
||||
state.products = state.products.filter(p => p.productId !== productId);
|
||||
|
|
|
@ -14,7 +14,7 @@ interface TriggerSchema {
|
|||
triggeredAsset: {
|
||||
triggeredModel: { modelName: string, modelUuid: string };
|
||||
triggeredPoint: { pointName: string, pointUuid: string };
|
||||
triggeredAction: { actionName: string, actionUuid: string };
|
||||
triggeredAction: { actionName: string, actionUuid: string } | null;
|
||||
} | null;
|
||||
}
|
||||
|
||||
|
|
|
@ -196,6 +196,19 @@ export type FloorItemType = {
|
|||
modelfileID: string;
|
||||
isLocked: boolean;
|
||||
isVisible: boolean;
|
||||
eventData?: {
|
||||
type: string;
|
||||
point?: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
}
|
||||
points?: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
}[];
|
||||
}
|
||||
};
|
||||
|
||||
// Array of floor items for managing multiple objects on the floor
|
||||
|
|
|
@ -3,43 +3,43 @@ const STORE_NAME = 'models';
|
|||
const DB_VERSION = 1;
|
||||
|
||||
export function initializeDB(): Promise<IDBDatabase> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
|
||||
request.onupgradeneeded = () => {
|
||||
const db = request.result;
|
||||
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
||||
db.createObjectStore(STORE_NAME);
|
||||
}
|
||||
};
|
||||
request.onupgradeneeded = () => {
|
||||
const db = request.result;
|
||||
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
||||
db.createObjectStore(STORE_NAME);
|
||||
}
|
||||
};
|
||||
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
export async function storeGLTF(key: string, file: Blob): Promise<void> {
|
||||
const db = await initializeDB();
|
||||
const db = await initializeDB();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(STORE_NAME, 'readwrite');
|
||||
const store = transaction.objectStore(STORE_NAME);
|
||||
const request = store.put(file, key);
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(STORE_NAME, 'readwrite');
|
||||
const store = transaction.objectStore(STORE_NAME);
|
||||
const request = store.put(file, key);
|
||||
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
request.onsuccess = () => resolve();
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
|
||||
export async function retrieveGLTF(key: string): Promise<Blob | undefined> {
|
||||
const db = await initializeDB();
|
||||
const db = await initializeDB();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(STORE_NAME, 'readonly');
|
||||
const store = transaction.objectStore(STORE_NAME);
|
||||
const request = store.get(key);
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction(STORE_NAME, 'readonly');
|
||||
const store = transaction.objectStore(STORE_NAME);
|
||||
const request = store.get(key);
|
||||
|
||||
request.onsuccess = () => resolve(request.result as Blob | undefined);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
request.onsuccess = () => resolve(request.result as Blob | undefined);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue