add simulations data
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
interface SimulationData {
|
||||||
|
key: string;
|
||||||
|
data?: object | any;
|
||||||
|
}
|
||||||
|
export const saveSimulationData = ({ key, data }: SimulationData) => {
|
||||||
|
console.log("key: ", key);
|
||||||
|
localStorage.setItem(key, JSON.stringify(data));
|
||||||
|
};
|
||||||
|
export const getSimulationData = ({ key }: SimulationData) => {
|
||||||
|
const data = localStorage.getItem(key);
|
||||||
|
console.log("data: ", JSON.parse(data || "{}"));
|
||||||
|
};
|
||||||
|
export const clearSimulationData = ({ key, data }: SimulationData) => {};
|
||||||
@@ -19,6 +19,7 @@ import { useProductContext } from "../../../../modules/simulation/products/produ
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
||||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||||
|
import { getSimulationData } from "../../scenes/functions/simulationStorage";
|
||||||
|
|
||||||
interface Event {
|
interface Event {
|
||||||
modelName: string;
|
modelName: string;
|
||||||
@@ -137,6 +138,7 @@ const Simulations: React.FC = () => {
|
|||||||
if (selectedProductData) {
|
if (selectedProductData) {
|
||||||
determineExecutionMachineSequences([selectedProductData]).then(
|
determineExecutionMachineSequences([selectedProductData]).then(
|
||||||
(sequences) => {
|
(sequences) => {
|
||||||
|
console.log('selectedProductData: ', selectedProductData);
|
||||||
sequences.forEach((sequence) => {
|
sequences.forEach((sequence) => {
|
||||||
const events: Event[] =
|
const events: Event[] =
|
||||||
sequence.map((event) => ({
|
sequence.map((event) => ({
|
||||||
@@ -151,6 +153,12 @@ const Simulations: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}, [selectedProduct.productUuid, products]);
|
}, [selectedProduct.productUuid, products]);
|
||||||
|
//call when comparePopup is true
|
||||||
|
useEffect(() => {
|
||||||
|
if (comparePopUp || selectedProduct.productUuid) {
|
||||||
|
getSimulationData({ key: selectedProduct.productUuid });
|
||||||
|
}
|
||||||
|
}, [comparePopUp])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="simulations-container">
|
<div className="simulations-container">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
import { ExitIcon, PlayStopIcon, ResetIcon } from "../../icons/SimulationIcons";
|
import { ExitIcon, PlayStopIcon, ResetIcon } from "../../icons/SimulationIcons";
|
||||||
import {
|
import {
|
||||||
|
comparsionMaterialData,
|
||||||
useActiveTool,
|
useActiveTool,
|
||||||
useProcessBar,
|
useProcessBar,
|
||||||
useViewSceneStore,
|
useViewSceneStore,
|
||||||
@@ -32,6 +33,8 @@ import ROISummary from "../analysis/ROISummary";
|
|||||||
import { usePlayerStore } from "../../../store/useUIToggleStore";
|
import { usePlayerStore } from "../../../store/useUIToggleStore";
|
||||||
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
||||||
import InputToggle from "../inputs/InputToggle";
|
import InputToggle from "../inputs/InputToggle";
|
||||||
|
import { saveSimulationData } from "../../layout/scenes/functions/simulationStorage";
|
||||||
|
import { useProductContext } from "../../../modules/simulation/products/productContext";
|
||||||
|
|
||||||
const SimulationPlayer: React.FC = () => {
|
const SimulationPlayer: React.FC = () => {
|
||||||
const MAX_SPEED = 8; // Maximum speed
|
const MAX_SPEED = 8; // Maximum speed
|
||||||
@@ -49,9 +52,11 @@ const SimulationPlayer: React.FC = () => {
|
|||||||
const { subModule } = useSubModuleStore();
|
const { subModule } = useSubModuleStore();
|
||||||
const { clearComparisonProduct } = useComparisonProduct();
|
const { clearComparisonProduct } = useComparisonProduct();
|
||||||
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
|
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
|
||||||
|
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
const { selectedProductStore } = useProductContext();
|
||||||
|
const { selectedProduct, setSelectedProduct } = selectedProductStore();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isReset) {
|
if (isReset) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -60,6 +65,12 @@ const SimulationPlayer: React.FC = () => {
|
|||||||
}
|
}
|
||||||
}, [isReset, setReset]);
|
}, [isReset, setReset]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (materialData.length === 0) return;
|
||||||
|
console.log('materialData: ', materialData);
|
||||||
|
saveSimulationData({ key: selectedProduct.productUuid, data: materialData });
|
||||||
|
}, [materialData])
|
||||||
|
|
||||||
// Button functions
|
// Button functions
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
setReset(true);
|
setReset(true);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { DepthOfField, Bloom, EffectComposer, N8AO } from "@react-three/postprocessing";
|
import { DepthOfField, Bloom, EffectComposer, N8AO } from "@react-three/postprocessing";
|
||||||
|
// import OutlineInstances from "./outlineInstances/outlineInstances";
|
||||||
import OutlineInstances from "./outlineInstances/outlineInstances";
|
import OutlineInstances from "./outlineInstances/outlineInstances";
|
||||||
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { CompareProduct, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store';
|
import { CompareProduct, comparsionMaterialData, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store';
|
||||||
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
||||||
import { useProductContext } from '../../products/productContext';
|
import { useProductContext } from '../../products/productContext';
|
||||||
import { useSceneContext } from '../../../scene/sceneContext';
|
import { useSceneContext } from '../../../scene/sceneContext';
|
||||||
|
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
|
||||||
|
import { set } from 'immer/dist/internal';
|
||||||
|
|
||||||
export default function ROIData() {
|
export default function ROIData() {
|
||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
@@ -17,6 +19,7 @@ export default function ROIData() {
|
|||||||
const { machineActiveTime } = useMachineUptime();
|
const { machineActiveTime } = useMachineUptime();
|
||||||
const { machineIdleTime } = useMachineDowntime();
|
const { machineIdleTime } = useMachineDowntime();
|
||||||
const { throughputData } = useThroughPutData()
|
const { throughputData } = useThroughPutData()
|
||||||
|
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isPlaying) return;
|
if (isPlaying) return;
|
||||||
@@ -136,6 +139,22 @@ export default function ROIData() {
|
|||||||
|
|
||||||
const Annual_net_profit = (Annual_units * (sellingPrice - materialCost - laborCost)) - (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear + (salvageValue * workingDaysPerYear)
|
const Annual_net_profit = (Annual_units * (sellingPrice - materialCost - laborCost)) - (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear + (salvageValue * workingDaysPerYear)
|
||||||
const Payback_period_years = initialInvestment / Annual_net_profit;
|
const Payback_period_years = initialInvestment / Annual_net_profit;
|
||||||
|
const data = {
|
||||||
|
productName: selectedProduct.productName,
|
||||||
|
roiPercentage: ROI,
|
||||||
|
paybackPeriod: Payback_period_years,
|
||||||
|
totalCost: Total_cost,
|
||||||
|
revenueGenerated: Total_revenue,
|
||||||
|
netProfit: Net_profit > 0 ? Net_profit : 0,
|
||||||
|
netLoss: Net_profit < 0 ? -Net_profit : 0
|
||||||
|
}
|
||||||
|
console.log('selectedProduct.productUuid: ', selectedProduct.productUuid);
|
||||||
|
|
||||||
|
saveSimulationData({ key: selectedProduct.productUuid, data: data });
|
||||||
|
const datas = {
|
||||||
|
roi: data
|
||||||
|
}
|
||||||
|
setMaterialData(datas);
|
||||||
|
|
||||||
setRoiSummaryData({
|
setRoiSummaryData({
|
||||||
productName: selectedProduct.productName,
|
productName: selectedProduct.productName,
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
|
import { comparsionMaterialData, useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
|
||||||
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
||||||
|
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
|
||||||
|
|
||||||
export default function ProductionCapacityData() {
|
export default function ProductionCapacityData() {
|
||||||
const { throughputData } = useThroughPutData()
|
const { throughputData } = useThroughPutData()
|
||||||
const { setProductionCapacityData } = useProductionCapacityData()
|
const { setProductionCapacityData } = useProductionCapacityData()
|
||||||
const { inputValues } = useInputValues();
|
const { inputValues } = useInputValues();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isPlaying) {
|
if (!isPlaying) {
|
||||||
@@ -21,10 +24,12 @@ export default function ProductionCapacityData() {
|
|||||||
if (!isNaN(workingDaysPerYear) && throughputData > 0) {
|
if (!isNaN(workingDaysPerYear) && throughputData > 0) {
|
||||||
const Monthly_working_days = workingDaysPerYear / 12;
|
const Monthly_working_days = workingDaysPerYear / 12;
|
||||||
const Production_capacity_per_month = throughputData * Monthly_working_days;
|
const Production_capacity_per_month = throughputData * Monthly_working_days;
|
||||||
|
const data = Number(Production_capacity_per_month.toFixed(2));
|
||||||
|
saveSimulationData({ key: 'productionCapacity', data: data });
|
||||||
|
setMaterialData({ ...materialData, productionCapacity: data });
|
||||||
setProductionCapacityData(Number(Production_capacity_per_month.toFixed(2)));
|
setProductionCapacityData(Number(Production_capacity_per_month.toFixed(2)));
|
||||||
}
|
}
|
||||||
}, [throughputData, inputValues, isPlaying]);
|
}, [throughputData, inputValues, isPlaying, materialData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<></>
|
<></>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences';
|
import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences';
|
||||||
import { useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
|
import { comparsionMaterialData, useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
|
||||||
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
||||||
import { useSceneContext } from '../../../scene/sceneContext';
|
import { useSceneContext } from '../../../scene/sceneContext';
|
||||||
import { useProductContext } from '../../products/productContext';
|
import { useProductContext } from '../../products/productContext';
|
||||||
|
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
|
||||||
|
|
||||||
export default function ThroughPutData() {
|
export default function ThroughPutData() {
|
||||||
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore } = useSceneContext();
|
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore } = useSceneContext();
|
||||||
@@ -24,6 +25,7 @@ export default function ThroughPutData() {
|
|||||||
const { setThroughputData } = useThroughPutData()
|
const { setThroughputData } = useThroughPutData()
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { inputValues } = useInputValues();
|
const { inputValues } = useInputValues();
|
||||||
|
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||||
|
|
||||||
// Setting machine count
|
// Setting machine count
|
||||||
let totalItems = 0;
|
let totalItems = 0;
|
||||||
@@ -219,9 +221,13 @@ export default function ThroughPutData() {
|
|||||||
const Units_per_shift = (shiftLength * 60) / (materialCycleTime / 60);
|
const Units_per_shift = (shiftLength * 60) / (materialCycleTime / 60);
|
||||||
|
|
||||||
const Throughput_per_day = Units_per_shift * shiftsPerDay * (yieldRate / 100);
|
const Throughput_per_day = Units_per_shift * shiftsPerDay * (yieldRate / 100);
|
||||||
|
const data = Number(Throughput_per_day.toFixed(2))
|
||||||
|
saveSimulationData({ key: selectedProduct.productUuid, data: data });
|
||||||
|
|
||||||
|
setMaterialData({ ...materialData, throughput: data });
|
||||||
setThroughputData(Number(Throughput_per_day.toFixed(2))); // Keep as number
|
setThroughputData(Number(Throughput_per_day.toFixed(2))); // Keep as number
|
||||||
}
|
}
|
||||||
}, [materialCycleTime, machineCount, isPlaying, inputValues]);
|
}, [materialCycleTime, machineCount, isPlaying, inputValues, materialData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
181
app/src/modules/simulation/simulator/SimulationHandler.tsx
Normal file
181
app/src/modules/simulation/simulator/SimulationHandler.tsx
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { useSceneContext } from '../../scene/sceneContext';
|
||||||
|
import { useProductContext } from '../products/productContext';
|
||||||
|
import { determineExecutionMachineSequences } from './functions/determineExecutionMachineSequences';
|
||||||
|
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
|
||||||
|
import { useSimulationManager } from '../../../store/rough/useSimulationManagerStore';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useVersionContext } from '../../builder/version/versionContext';
|
||||||
|
interface SimulationUsageRecord {
|
||||||
|
activeTime: number;
|
||||||
|
isActive: boolean;
|
||||||
|
idleTime: number;
|
||||||
|
type:
|
||||||
|
| "roboticArm"
|
||||||
|
| "vehicle"
|
||||||
|
| "transfer"
|
||||||
|
| "storageUnit"
|
||||||
|
| "crane"
|
||||||
|
| "human"
|
||||||
|
| "machine";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product → holds multiple usage records
|
||||||
|
interface ProductSimulation {
|
||||||
|
productId: string;
|
||||||
|
data: SimulationUsageRecord[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version → holds multiple products
|
||||||
|
interface VersionSimulation {
|
||||||
|
versionId: string;
|
||||||
|
products: ProductSimulation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project → holds multiple versions
|
||||||
|
interface ProjectSimulation {
|
||||||
|
projectId: string | undefined;
|
||||||
|
versions: VersionSimulation[];
|
||||||
|
}
|
||||||
|
const SimulationHandler = () => {
|
||||||
|
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore, craneStore, humanStore } = useSceneContext();
|
||||||
|
const { armBots, getArmBotById } = armBotStore();
|
||||||
|
const { vehicles, getVehicleById } = vehicleStore();
|
||||||
|
const { getConveyorById } = conveyorStore();
|
||||||
|
const { materialHistory, materials } = materialStore();
|
||||||
|
const { getProductById } = productStore();
|
||||||
|
const { selectedProductStore } = useProductContext();
|
||||||
|
const { selectedProduct } = selectedProductStore();
|
||||||
|
const { machines, getMachineById } = machineStore();
|
||||||
|
const { getHumanById } = humanStore();
|
||||||
|
const { getCraneById, } = craneStore();
|
||||||
|
const { getStorageUnitById } = storageUnitStore();
|
||||||
|
const { isPlaying, setIsPlaying } = usePlayButtonStore();
|
||||||
|
const { simulationData, addData } = useSimulationManager();
|
||||||
|
const { projectId } = useParams();
|
||||||
|
const { selectedVersionStore } = useVersionContext();
|
||||||
|
const { selectedVersion } = selectedVersionStore();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let checkTimer: ReturnType<typeof setTimeout>;
|
||||||
|
if (!projectId) return;
|
||||||
|
async function checkActiveMachines() {
|
||||||
|
const currentProduct = getProductById(selectedProduct.productUuid);
|
||||||
|
let hasActiveEntity = false;
|
||||||
|
|
||||||
|
if (currentProduct) {
|
||||||
|
const executionSequences = await determineExecutionMachineSequences([currentProduct]);
|
||||||
|
if (executionSequences?.length > 0) {
|
||||||
|
executionSequences.forEach(sequence => {
|
||||||
|
sequence.forEach(entity => {
|
||||||
|
if (entity.type === 'roboticArm') {
|
||||||
|
const roboticArm = getArmBotById(entity.modelUuid);
|
||||||
|
if (roboticArm?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.type === 'vehicle') {
|
||||||
|
const vehicle = getVehicleById(entity.modelUuid);
|
||||||
|
if (vehicle?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.type === 'machine') {
|
||||||
|
const machine = getMachineById(entity.modelUuid);
|
||||||
|
if (machine?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.type === 'human') {
|
||||||
|
const human = getHumanById(entity.modelUuid);
|
||||||
|
if (human?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.type === 'crane') {
|
||||||
|
const crane = getCraneById(entity.modelUuid);
|
||||||
|
if (crane?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.type === 'storageUnit') {
|
||||||
|
const storageUnit = getStorageUnitById(entity.modelUuid);
|
||||||
|
if (storageUnit?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entity.type === "transfer") {
|
||||||
|
const storageUnit = getConveyorById(entity.modelUuid);
|
||||||
|
if (storageUnit?.isActive) {
|
||||||
|
hasActiveEntity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materials.length === 0 && materialHistory.length >= 0 && !hasActiveEntity) {
|
||||||
|
|
||||||
|
if (executionSequences?.length > 0) {
|
||||||
|
executionSequences.forEach((sequence) => {
|
||||||
|
sequence.forEach((entity) => {
|
||||||
|
const typeToGetter: Record<string, (id: string) => any> = {
|
||||||
|
roboticArm: getArmBotById,
|
||||||
|
vehicle: getVehicleById,
|
||||||
|
machine: getMachineById,
|
||||||
|
human: getHumanById,
|
||||||
|
crane: getCraneById,
|
||||||
|
storageUnit: getStorageUnitById,
|
||||||
|
transfer: getConveyorById,
|
||||||
|
};
|
||||||
|
|
||||||
|
const getter = typeToGetter[entity.type];
|
||||||
|
if (!getter) return; // skip unknown entity types
|
||||||
|
|
||||||
|
const obj = getter(entity.modelUuid);
|
||||||
|
if (!obj) return; // skip if not found
|
||||||
|
|
||||||
|
addData(
|
||||||
|
projectId,
|
||||||
|
selectedVersion?.versionId || "",
|
||||||
|
selectedProduct?.productUuid,
|
||||||
|
{
|
||||||
|
activeTime: obj.activeTime ?? 0,
|
||||||
|
isActive: obj.isActive ?? false,
|
||||||
|
idleTime: obj.idleTime ?? 0,
|
||||||
|
type: entity.type as
|
||||||
|
| "roboticArm"
|
||||||
|
| "vehicle"
|
||||||
|
| "machine"
|
||||||
|
| "human"
|
||||||
|
| "crane"
|
||||||
|
| "storageUnit"
|
||||||
|
| "transfer",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setIsPlaying(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPlaying) {
|
||||||
|
checkTimer = setTimeout(() => {
|
||||||
|
checkActiveMachines();
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (checkTimer) clearTimeout(checkTimer);
|
||||||
|
};
|
||||||
|
}, [materials, materialHistory, selectedVersion, selectedProduct?.productUuid, isPlaying, armBots, vehicles, machines]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SimulationHandler;
|
||||||
@@ -4,6 +4,7 @@ import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayB
|
|||||||
import { determineExecutionOrder } from './functions/determineExecutionOrder';
|
import { determineExecutionOrder } from './functions/determineExecutionOrder';
|
||||||
import { useProductContext } from '../products/productContext';
|
import { useProductContext } from '../products/productContext';
|
||||||
import { useSceneContext } from '../../scene/sceneContext';
|
import { useSceneContext } from '../../scene/sceneContext';
|
||||||
|
import SimulationHandler from './SimulationHandler';
|
||||||
|
|
||||||
function Simulator() {
|
function Simulator() {
|
||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
@@ -32,6 +33,9 @@ function Simulator() {
|
|||||||
|
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
{/* <simulationHandler/> */}
|
||||||
|
<SimulationHandler />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,601 +4,607 @@ import { io } from "socket.io-client";
|
|||||||
import * as CONSTANTS from "../../types/world/worldConstants";
|
import * as CONSTANTS from "../../types/world/worldConstants";
|
||||||
|
|
||||||
export const useSocketStore = create<any>((set: any, get: any) => ({
|
export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||||
socket: null,
|
socket: null,
|
||||||
initializeSocket: (
|
initializeSocket: (
|
||||||
email?: string,
|
email?: string,
|
||||||
organization?: string,
|
organization?: string,
|
||||||
token?: string,
|
token?: string,
|
||||||
refreshToken?: string
|
refreshToken?: string
|
||||||
) => {
|
) => {
|
||||||
const existingSocket = get().socket;
|
const existingSocket = get().socket;
|
||||||
if (existingSocket) {
|
if (existingSocket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const socket = io(
|
const socket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const visualizationSocket = io(
|
const visualizationSocket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const dashBoardSocket = io(
|
const dashBoardSocket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const projectSocket = io(
|
const projectSocket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const threadSocket = io(
|
const threadSocket = io(
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
||||||
{
|
{
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
set({
|
set({
|
||||||
socket,
|
socket,
|
||||||
visualizationSocket,
|
visualizationSocket,
|
||||||
dashBoardSocket,
|
dashBoardSocket,
|
||||||
projectSocket,
|
projectSocket,
|
||||||
threadSocket,
|
threadSocket,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
disconnectSocket: () => {
|
disconnectSocket: () => {
|
||||||
set((state: any) => {
|
set((state: any) => {
|
||||||
state.socket?.disconnect();
|
state.socket?.disconnect();
|
||||||
state.visualizationSocket?.disconnect();
|
state.visualizationSocket?.disconnect();
|
||||||
state.dashBoardSocket?.disconnect();
|
state.dashBoardSocket?.disconnect();
|
||||||
state.projectSocket?.disconnect();
|
state.projectSocket?.disconnect();
|
||||||
state.threadSocket?.disconnect();
|
state.threadSocket?.disconnect();
|
||||||
return { socket: null };
|
return { socket: null };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useLoadingProgress = create<{
|
export const useLoadingProgress = create<{
|
||||||
loadingProgress: number;
|
loadingProgress: number;
|
||||||
setLoadingProgress: (x: number) => void;
|
setLoadingProgress: (x: number) => void;
|
||||||
}>((set) => ({
|
}>((set) => ({
|
||||||
loadingProgress: 1,
|
loadingProgress: 1,
|
||||||
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useOrganization = create<any>((set: any) => ({
|
export const useOrganization = create<any>((set: any) => ({
|
||||||
organization: "",
|
organization: "",
|
||||||
setOrganization: (x: any) => set(() => ({ organization: x })),
|
setOrganization: (x: any) => set(() => ({ organization: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useToggleView = create<any>((set: any) => ({
|
export const useToggleView = create<any>((set: any) => ({
|
||||||
toggleView: false,
|
toggleView: false,
|
||||||
setToggleView: (x: any) => set(() => ({ toggleView: x })),
|
setToggleView: (x: any) => set(() => ({ toggleView: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useRoomsState = create<any>((set: any) => ({
|
export const useRoomsState = create<any>((set: any) => ({
|
||||||
roomsState: [],
|
roomsState: [],
|
||||||
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
|
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useSelectedItem = create<any>((set: any) => ({
|
export const useSelectedItem = create<any>((set: any) => ({
|
||||||
selectedItem: {
|
selectedItem: {
|
||||||
name: "",
|
name: "",
|
||||||
id: "",
|
id: "",
|
||||||
type: undefined,
|
type: undefined,
|
||||||
category: "",
|
category: "",
|
||||||
subType: "",
|
subType: "",
|
||||||
},
|
},
|
||||||
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
type DroppedDecalType = {
|
type DroppedDecalType = {
|
||||||
category: string;
|
category: string;
|
||||||
decalName: string;
|
decalName: string;
|
||||||
decalImage: string;
|
decalImage: string;
|
||||||
decalId: string;
|
decalId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDroppedDecal = create<{
|
export const useDroppedDecal = create<{
|
||||||
droppedDecal: DroppedDecalType | null;
|
droppedDecal: DroppedDecalType | null;
|
||||||
setDroppedDecal: (x: DroppedDecalType | null) => void;
|
setDroppedDecal: (x: DroppedDecalType | null) => void;
|
||||||
}>((set) => ({
|
}>((set) => ({
|
||||||
droppedDecal: null,
|
droppedDecal: null,
|
||||||
setDroppedDecal: (x) => set({ droppedDecal: x }),
|
setDroppedDecal: (x) => set({ droppedDecal: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useNavMesh = create<any>((set: any) => ({
|
export const useNavMesh = create<any>((set: any) => ({
|
||||||
navMesh: null,
|
navMesh: null,
|
||||||
setNavMesh: (x: any) => set({ navMesh: x }),
|
setNavMesh: (x: any) => set({ navMesh: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useLayers = create<any>((set: any) => ({
|
export const useLayers = create<any>((set: any) => ({
|
||||||
Layers: 1,
|
Layers: 1,
|
||||||
setLayers: (x: any) => set(() => ({ Layers: x })),
|
setLayers: (x: any) => set(() => ({ Layers: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useCamPosition = create<any>((set: any) => ({
|
export const useCamPosition = create<any>((set: any) => ({
|
||||||
camPosition: { x: undefined, y: undefined, z: undefined },
|
camPosition: { x: undefined, y: undefined, z: undefined },
|
||||||
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
|
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useMenuVisible = create<any>((set: any) => ({
|
export const useMenuVisible = create<any>((set: any) => ({
|
||||||
menuVisible: false,
|
menuVisible: false,
|
||||||
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
|
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useToolMode = create<any>((set: any) => ({
|
export const useToolMode = create<any>((set: any) => ({
|
||||||
toolMode: null,
|
toolMode: null,
|
||||||
setToolMode: (x: any) => set(() => ({ toolMode: x })),
|
setToolMode: (x: any) => set(() => ({ toolMode: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useSetScale = create<any>((set: any) => ({
|
export const useSetScale = create<any>((set: any) => ({
|
||||||
scale: null,
|
scale: null,
|
||||||
setScale: (x: any) => set(() => ({ scale: x })),
|
setScale: (x: any) => set(() => ({ scale: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useRoofVisibility = create<any>((set: any) => ({
|
export const useRoofVisibility = create<any>((set: any) => ({
|
||||||
roofVisibility: false,
|
roofVisibility: false,
|
||||||
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
|
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useWallVisibility = create<any>((set: any) => ({
|
export const useWallVisibility = create<any>((set: any) => ({
|
||||||
wallVisibility: false,
|
wallVisibility: false,
|
||||||
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
|
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useShadows = create<any>((set: any) => ({
|
export const useShadows = create<any>((set: any) => ({
|
||||||
shadows: false,
|
shadows: false,
|
||||||
setShadows: (x: any) => set(() => ({ shadows: x })),
|
setShadows: (x: any) => set(() => ({ shadows: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useSunPosition = create<any>((set: any) => ({
|
export const useSunPosition = create<any>((set: any) => ({
|
||||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||||
setSunPosition: (newSuntPosition: any) =>
|
setSunPosition: (newSuntPosition: any) =>
|
||||||
set({ sunPosition: newSuntPosition }),
|
set({ sunPosition: newSuntPosition }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useRemoveLayer = create<any>((set: any) => ({
|
export const useRemoveLayer = create<any>((set: any) => ({
|
||||||
removeLayer: false,
|
removeLayer: false,
|
||||||
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
|
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useRemovedLayer = create<any>((set: any) => ({
|
export const useRemovedLayer = create<any>((set: any) => ({
|
||||||
removedLayer: null,
|
removedLayer: null,
|
||||||
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
|
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useProjectName = create<any>((set: any) => ({
|
export const useProjectName = create<any>((set: any) => ({
|
||||||
projectName: "Creating Your Project",
|
projectName: "Creating Your Project",
|
||||||
setProjectName: (x: any) => set({ projectName: x }),
|
setProjectName: (x: any) => set({ projectName: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useActiveLayer = create<any>((set: any) => ({
|
export const useActiveLayer = create<any>((set: any) => ({
|
||||||
activeLayer: 1,
|
activeLayer: 1,
|
||||||
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useResetCamera = create<any>((set: any) => ({
|
export const useResetCamera = create<any>((set: any) => ({
|
||||||
resetCamera: false,
|
resetCamera: false,
|
||||||
setResetCamera: (x: any) => set({ resetCamera: x }),
|
setResetCamera: (x: any) => set({ resetCamera: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useAddAction = create<any>((set: any) => ({
|
export const useAddAction = create<any>((set: any) => ({
|
||||||
addAction: null,
|
addAction: null,
|
||||||
setAddAction: (x: any) => set({ addAction: x }),
|
setAddAction: (x: any) => set({ addAction: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useActiveTool = create<any>((set: any) => ({
|
export const useActiveTool = create<any>((set: any) => ({
|
||||||
activeTool: "cursor",
|
activeTool: "cursor",
|
||||||
setActiveTool: (x: any) => set({ activeTool: x }),
|
setActiveTool: (x: any) => set({ activeTool: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useActiveSubTool = create<any>((set: any) => ({
|
export const useActiveSubTool = create<any>((set: any) => ({
|
||||||
activeSubTool: "cursor",
|
activeSubTool: "cursor",
|
||||||
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
|
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useElevation = create<any>((set: any) => ({
|
export const useElevation = create<any>((set: any) => ({
|
||||||
elevation: 45,
|
elevation: 45,
|
||||||
setElevation: (x: any) => set({ elevation: x }),
|
setElevation: (x: any) => set({ elevation: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useAzimuth = create<any>((set: any) => ({
|
export const useAzimuth = create<any>((set: any) => ({
|
||||||
azimuth: -160,
|
azimuth: -160,
|
||||||
setAzimuth: (x: any) => set({ azimuth: x }),
|
setAzimuth: (x: any) => set({ azimuth: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useRenderDistance = create<any>((set: any) => ({
|
export const useRenderDistance = create<any>((set: any) => ({
|
||||||
renderDistance: 40,
|
renderDistance: 40,
|
||||||
setRenderDistance: (x: any) => set({ renderDistance: x }),
|
setRenderDistance: (x: any) => set({ renderDistance: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useCamMode = create<any>((set: any) => ({
|
export const useCamMode = create<any>((set: any) => ({
|
||||||
camMode: "ThirdPerson",
|
camMode: "ThirdPerson",
|
||||||
setCamMode: (x: any) => set({ camMode: x }),
|
setCamMode: (x: any) => set({ camMode: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useUserName = create<any>((set: any) => ({
|
export const useUserName = create<any>((set: any) => ({
|
||||||
userName: "",
|
userName: "",
|
||||||
setUserName: (x: any) => set({ userName: x }),
|
setUserName: (x: any) => set({ userName: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useRenameModeStore = create<any>((set: any) => ({
|
export const useRenameModeStore = create<any>((set: any) => ({
|
||||||
isRenameMode: false,
|
isRenameMode: false,
|
||||||
setIsRenameMode: (state: boolean) => set({ isRenameMode: state }),
|
setIsRenameMode: (state: boolean) => set({ isRenameMode: state }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useObjectPosition = create<any>((set: any) => ({
|
export const useObjectPosition = create<any>((set: any) => ({
|
||||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||||
setObjectPosition: (newObjectPosition: any) =>
|
setObjectPosition: (newObjectPosition: any) =>
|
||||||
set({ objectPosition: newObjectPosition }),
|
set({ objectPosition: newObjectPosition }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useObjectRotation = create<any>((set: any) => ({
|
export const useObjectRotation = create<any>((set: any) => ({
|
||||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||||
setObjectRotation: (newObjectRotation: any) =>
|
setObjectRotation: (newObjectRotation: any) =>
|
||||||
set({ objectRotation: newObjectRotation }),
|
set({ objectRotation: newObjectRotation }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useDrieTemp = create<any>((set: any) => ({
|
export const useDrieTemp = create<any>((set: any) => ({
|
||||||
drieTemp: undefined,
|
drieTemp: undefined,
|
||||||
setDrieTemp: (x: any) => set({ drieTemp: x }),
|
setDrieTemp: (x: any) => set({ drieTemp: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useActiveUsers = create<any>((set: any) => ({
|
export const useActiveUsers = create<any>((set: any) => ({
|
||||||
activeUsers: [],
|
activeUsers: [],
|
||||||
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
||||||
set((state: { activeUsers: any[] }) => ({
|
set((state: { activeUsers: any[] }) => ({
|
||||||
activeUsers:
|
activeUsers:
|
||||||
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useDrieUIValue = create<any>((set: any) => ({
|
export const useDrieUIValue = create<any>((set: any) => ({
|
||||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||||
|
|
||||||
setDrieUIValue: (x: any) =>
|
setDrieUIValue: (x: any) =>
|
||||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||||
|
|
||||||
setTouch: (value: any) =>
|
setTouch: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
drieUIValue: { ...state.drieUIValue, touch: value },
|
drieUIValue: { ...state.drieUIValue, touch: value },
|
||||||
})),
|
})),
|
||||||
setTemperature: (value: any) =>
|
setTemperature: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
drieUIValue: { ...state.drieUIValue, temperature: value },
|
drieUIValue: { ...state.drieUIValue, temperature: value },
|
||||||
})),
|
})),
|
||||||
setHumidity: (value: any) =>
|
setHumidity: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
drieUIValue: { ...state.drieUIValue, humidity: value },
|
drieUIValue: { ...state.drieUIValue, humidity: value },
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const usezoneTarget = create<any>((set: any) => ({
|
export const usezoneTarget = create<any>((set: any) => ({
|
||||||
zoneTarget: [],
|
zoneTarget: [],
|
||||||
setZoneTarget: (x: any) => set({ zoneTarget: x }),
|
setZoneTarget: (x: any) => set({ zoneTarget: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const usezonePosition = create<any>((set: any) => ({
|
export const usezonePosition = create<any>((set: any) => ({
|
||||||
zonePosition: [],
|
zonePosition: [],
|
||||||
setZonePosition: (x: any) => set({ zonePosition: x }),
|
setZonePosition: (x: any) => set({ zonePosition: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface EditPositionState {
|
interface EditPositionState {
|
||||||
Edit: boolean;
|
Edit: boolean;
|
||||||
setEdit: (value: boolean) => void;
|
setEdit: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useEditPosition = create<EditPositionState>((set) => ({
|
export const useEditPosition = create<EditPositionState>((set) => ({
|
||||||
Edit: false,
|
Edit: false,
|
||||||
setEdit: (value) => set({ Edit: value }),
|
setEdit: (value) => set({ Edit: value }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useAsset3dWidget = create<any>((set: any) => ({
|
export const useAsset3dWidget = create<any>((set: any) => ({
|
||||||
widgetSelect: "",
|
widgetSelect: "",
|
||||||
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useWidgetSubOption = create<any>((set: any) => ({
|
export const useWidgetSubOption = create<any>((set: any) => ({
|
||||||
widgetSubOption: "2D",
|
widgetSubOption: "2D",
|
||||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useLimitDistance = create<any>((set: any) => ({
|
export const useLimitDistance = create<any>((set: any) => ({
|
||||||
limitDistance: true,
|
limitDistance: true,
|
||||||
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useTileDistance = create<any>((set: any) => ({
|
export const useTileDistance = create<any>((set: any) => ({
|
||||||
gridValue: {
|
gridValue: {
|
||||||
size: CONSTANTS.gridConfig.size,
|
size: CONSTANTS.gridConfig.size,
|
||||||
divisions: CONSTANTS.gridConfig.divisions,
|
divisions: CONSTANTS.gridConfig.divisions,
|
||||||
},
|
},
|
||||||
planeValue: {
|
planeValue: {
|
||||||
height: CONSTANTS.planeConfig.height,
|
height: CONSTANTS.planeConfig.height,
|
||||||
width: CONSTANTS.planeConfig.width,
|
width: CONSTANTS.planeConfig.width,
|
||||||
},
|
},
|
||||||
|
|
||||||
setGridValue: (value: any) =>
|
setGridValue: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
gridValue: { ...state.gridValue, ...value },
|
gridValue: { ...state.gridValue, ...value },
|
||||||
})),
|
})),
|
||||||
|
|
||||||
setPlaneValue: (value: any) =>
|
setPlaneValue: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
planeValue: { ...state.planeValue, ...value },
|
planeValue: { ...state.planeValue, ...value },
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const usePlayAgv = create<any>((set, get) => ({
|
export const usePlayAgv = create<any>((set, get) => ({
|
||||||
PlayAgv: [],
|
PlayAgv: [],
|
||||||
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
|
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
|
||||||
set({ PlayAgv: updateFn(get().PlayAgv) }),
|
set({ PlayAgv: updateFn(get().PlayAgv) }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Define the Asset type
|
// Define the Asset type
|
||||||
type Asset = {
|
type Asset = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
position?: [number, number, number]; // Optional: 3D position
|
position?: [number, number, number]; // Optional: 3D position
|
||||||
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
|
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
|
||||||
};
|
};
|
||||||
|
|
||||||
// Zustand store type
|
// Zustand store type
|
||||||
type ZoneAssetState = {
|
type ZoneAssetState = {
|
||||||
zoneAssetId: Asset | null;
|
zoneAssetId: Asset | null;
|
||||||
setZoneAssetId: (asset: Asset | null) => void;
|
setZoneAssetId: (asset: Asset | null) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Zustand store
|
// Zustand store
|
||||||
export const useZoneAssetId = create<ZoneAssetState>((set) => ({
|
export const useZoneAssetId = create<ZoneAssetState>((set) => ({
|
||||||
zoneAssetId: null,
|
zoneAssetId: null,
|
||||||
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
|
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface ResourceManagementState {
|
interface ResourceManagementState {
|
||||||
resourceManagementId: string;
|
resourceManagementId: string;
|
||||||
setResourceManagementId: (id: string) => void;
|
setResourceManagementId: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useResourceManagementId = create<ResourceManagementState>((set) => ({
|
export const useResourceManagementId = create<ResourceManagementState>(
|
||||||
|
(set) => ({
|
||||||
resourceManagementId: "", // default value
|
resourceManagementId: "", // default value
|
||||||
setResourceManagementId: (id: string) => set({ resourceManagementId: id }),
|
setResourceManagementId: (id: string) => set({ resourceManagementId: id }),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// version visible hidden
|
// version visible hidden
|
||||||
interface VersionHistoryState {
|
interface VersionHistoryState {
|
||||||
viewVersionHistory: boolean;
|
viewVersionHistory: boolean;
|
||||||
setVersionHistoryVisible: (value: boolean) => void;
|
setVersionHistoryVisible: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useVersionHistoryVisibleStore = create<VersionHistoryState>((set) => ({
|
const useVersionHistoryVisibleStore = create<VersionHistoryState>((set) => ({
|
||||||
viewVersionHistory: false,
|
viewVersionHistory: false,
|
||||||
setVersionHistoryVisible: (value) => set({ viewVersionHistory: value }),
|
setVersionHistoryVisible: (value) => set({ viewVersionHistory: value }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useVersionHistoryVisibleStore;
|
export default useVersionHistoryVisibleStore;
|
||||||
|
|
||||||
interface ShortcutStore {
|
interface ShortcutStore {
|
||||||
showShortcuts: boolean;
|
showShortcuts: boolean;
|
||||||
setShowShortcuts: (value: boolean) => void;
|
setShowShortcuts: (value: boolean) => void;
|
||||||
toggleShortcuts: () => void;
|
toggleShortcuts: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useShortcutStore = create<ShortcutStore>((set) => ({
|
export const useShortcutStore = create<ShortcutStore>((set) => ({
|
||||||
showShortcuts: false,
|
showShortcuts: false,
|
||||||
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
||||||
toggleShortcuts: () =>
|
toggleShortcuts: () =>
|
||||||
set((state) => ({ showShortcuts: !state.showShortcuts })),
|
set((state) => ({ showShortcuts: !state.showShortcuts })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useMachineCount = create<any>((set: any) => ({
|
export const useMachineCount = create<any>((set: any) => ({
|
||||||
machineCount: 0,
|
machineCount: 0,
|
||||||
setMachineCount: (x: any) => set({ machineCount: x }),
|
setMachineCount: (x: any) => set({ machineCount: x }),
|
||||||
}));
|
}));
|
||||||
export const useMachineUptime = create<any>((set: any) => ({
|
export const useMachineUptime = create<any>((set: any) => ({
|
||||||
machineActiveTime: 0,
|
machineActiveTime: 0,
|
||||||
setMachineActiveTime: (x: any) => set({ machineActiveTime: x }),
|
setMachineActiveTime: (x: any) => set({ machineActiveTime: x }),
|
||||||
}));
|
}));
|
||||||
export const useMachineDowntime = create<any>((set: any) => ({
|
export const useMachineDowntime = create<any>((set: any) => ({
|
||||||
machineIdleTime: 0,
|
machineIdleTime: 0,
|
||||||
setMachineIdleTime: (x: any) => set({ machineIdleTime: x }),
|
setMachineIdleTime: (x: any) => set({ machineIdleTime: x }),
|
||||||
}));
|
}));
|
||||||
export const useMaterialCycle = create<any>((set: any) => ({
|
export const useMaterialCycle = create<any>((set: any) => ({
|
||||||
materialCycleTime: 0,
|
materialCycleTime: 0,
|
||||||
setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }),
|
setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useThroughPutData = create<any>((set: any) => ({
|
export const useThroughPutData = create<any>((set: any) => ({
|
||||||
throughputData: 0,
|
throughputData: 0,
|
||||||
setThroughputData: (x: any) => set({ throughputData: x }),
|
setThroughputData: (x: any) => set({ throughputData: x }),
|
||||||
}));
|
}));
|
||||||
export const useProductionCapacityData = create<any>((set: any) => ({
|
export const useProductionCapacityData = create<any>((set: any) => ({
|
||||||
productionCapacityData: 0,
|
productionCapacityData: 0,
|
||||||
setProductionCapacityData: (x: any) => set({ productionCapacityData: x }),
|
setProductionCapacityData: (x: any) => set({ productionCapacityData: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useProcessBar = create<any>((set: any) => ({
|
export const useProcessBar = create<any>((set: any) => ({
|
||||||
processBar: [],
|
processBar: [],
|
||||||
setProcessBar: (x: any) => set({ processBar: x }),
|
setProcessBar: (x: any) => set({ processBar: x }),
|
||||||
}));
|
}));
|
||||||
export const useDfxUpload = create<any>((set: any) => ({
|
export const useDfxUpload = create<any>((set: any) => ({
|
||||||
dfxuploaded: [],
|
dfxuploaded: [],
|
||||||
dfxWallGenerate: [],
|
dfxWallGenerate: [],
|
||||||
objValue: { x: 0, y: 0, z: 0 },
|
objValue: { x: 0, y: 0, z: 0 },
|
||||||
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
|
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
|
||||||
setDxfWallGenerate: (x: any) => set({ dfxWallGenerate: x }),
|
setDxfWallGenerate: (x: any) => set({ dfxWallGenerate: x }),
|
||||||
setObjValue: (x: any) => set({ objValue: x }),
|
setObjValue: (x: any) => set({ objValue: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
type InputValuesStore = {
|
type InputValuesStore = {
|
||||||
inputValues: Record<string, string>;
|
inputValues: Record<string, string>;
|
||||||
setInputValues: (values: Record<string, string>) => void;
|
setInputValues: (values: Record<string, string>) => void;
|
||||||
updateInputValue: (label: string, value: string) => void; // <- New
|
updateInputValue: (label: string, value: string) => void; // <- New
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useInputValues = create<InputValuesStore>((set) => ({
|
export const useInputValues = create<InputValuesStore>((set) => ({
|
||||||
inputValues: {},
|
inputValues: {},
|
||||||
setInputValues: (values) => set({ inputValues: values }),
|
setInputValues: (values) => set({ inputValues: values }),
|
||||||
updateInputValue: (label, value) =>
|
updateInputValue: (label, value) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
inputValues: {
|
inputValues: {
|
||||||
...state.inputValues,
|
...state.inputValues,
|
||||||
[label]: value,
|
[label]: value,
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export interface ROISummaryData {
|
export interface ROISummaryData {
|
||||||
productName: string;
|
productName: string;
|
||||||
roiPercentage: number;
|
roiPercentage: number;
|
||||||
paybackPeriod: number;
|
paybackPeriod: number;
|
||||||
totalCost: number;
|
totalCost: number;
|
||||||
revenueGenerated: number;
|
revenueGenerated: number;
|
||||||
netProfit: number;
|
netProfit: number;
|
||||||
netLoss: number;
|
netLoss: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ROISummaryStore {
|
interface ROISummaryStore {
|
||||||
roiSummary: ROISummaryData;
|
roiSummary: ROISummaryData;
|
||||||
setRoiSummaryData: (values: ROISummaryData) => void;
|
setRoiSummaryData: (values: ROISummaryData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useROISummaryData = create<ROISummaryStore>((set) => ({
|
export const useROISummaryData = create<ROISummaryStore>((set) => ({
|
||||||
roiSummary: {
|
roiSummary: {
|
||||||
productName: "",
|
productName: "",
|
||||||
roiPercentage: 0,
|
roiPercentage: 0,
|
||||||
paybackPeriod: 0,
|
paybackPeriod: 0,
|
||||||
totalCost: 0,
|
totalCost: 0,
|
||||||
revenueGenerated: 0,
|
revenueGenerated: 0,
|
||||||
netProfit: 0,
|
netProfit: 0,
|
||||||
netLoss: 0,
|
netLoss: 0,
|
||||||
},
|
},
|
||||||
setRoiSummaryData: (values) => set({ roiSummary: values }),
|
setRoiSummaryData: (values) => set({ roiSummary: values }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface CompareStore {
|
interface CompareStore {
|
||||||
comparePopUp: boolean;
|
comparePopUp: boolean;
|
||||||
setComparePopUp: (value: boolean) => void;
|
setComparePopUp: (value: boolean) => void;
|
||||||
toggleComparePopUp: () => void;
|
toggleComparePopUp: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useCompareStore = create<CompareStore>((set) => ({
|
export const useCompareStore = create<CompareStore>((set) => ({
|
||||||
comparePopUp: false,
|
comparePopUp: false,
|
||||||
setComparePopUp: (value) => set({ comparePopUp: value }),
|
setComparePopUp: (value) => set({ comparePopUp: value }),
|
||||||
toggleComparePopUp: () =>
|
toggleComparePopUp: () =>
|
||||||
set((state) => ({ comparePopUp: !state.comparePopUp })),
|
set((state) => ({ comparePopUp: !state.comparePopUp })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Save state store
|
// Save state store
|
||||||
interface SaveVersionStore {
|
interface SaveVersionStore {
|
||||||
isVersionSaved: boolean;
|
isVersionSaved: boolean;
|
||||||
setIsVersionSaved: (value: boolean) => void;
|
setIsVersionSaved: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSaveVersion = create<SaveVersionStore>((set) => ({
|
export const useSaveVersion = create<SaveVersionStore>((set) => ({
|
||||||
isVersionSaved: false,
|
isVersionSaved: false,
|
||||||
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
|
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface ViewSceneState {
|
interface ViewSceneState {
|
||||||
viewSceneLabels: boolean;
|
viewSceneLabels: boolean;
|
||||||
setViewSceneLabels: (value: boolean | ((prev: boolean) => boolean)) => void;
|
setViewSceneLabels: (value: boolean | ((prev: boolean) => boolean)) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useViewSceneStore = create<ViewSceneState>((set) => ({
|
export const useViewSceneStore = create<ViewSceneState>((set) => ({
|
||||||
viewSceneLabels: getInitialViewSceneLabels(),
|
viewSceneLabels: getInitialViewSceneLabels(),
|
||||||
setViewSceneLabels: (value) => {
|
setViewSceneLabels: (value) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const newValue =
|
const newValue =
|
||||||
typeof value === "function" ? value(state.viewSceneLabels) : value;
|
typeof value === "function" ? value(state.viewSceneLabels) : value;
|
||||||
|
|
||||||
// Store in localStorage manually
|
// Store in localStorage manually
|
||||||
localStorage.setItem("viewSceneLabels", JSON.stringify(newValue));
|
localStorage.setItem("viewSceneLabels", JSON.stringify(newValue));
|
||||||
|
|
||||||
return { viewSceneLabels: newValue };
|
return { viewSceneLabels: newValue };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function getInitialViewSceneLabels(): boolean {
|
function getInitialViewSceneLabels(): boolean {
|
||||||
if (typeof window === "undefined") return false; // SSR safety
|
if (typeof window === "undefined") return false; // SSR safety
|
||||||
const saved = localStorage.getItem("viewSceneLabels");
|
const saved = localStorage.getItem("viewSceneLabels");
|
||||||
return saved ? JSON.parse(saved) : false;
|
return saved ? JSON.parse(saved) : false;
|
||||||
}
|
}
|
||||||
export interface CompareProduct {
|
export interface CompareProduct {
|
||||||
productUuid: string;
|
productUuid: string;
|
||||||
productName: string;
|
productName: string;
|
||||||
simulationData: {
|
simulationData: {
|
||||||
// costPerUnit: number;
|
// costPerUnit: number;
|
||||||
// workingDaysPerYear: number;
|
// workingDaysPerYear: number;
|
||||||
// shiftLength: number;
|
// shiftLength: number;
|
||||||
// shiftsPerDay: number;
|
// shiftsPerDay: number;
|
||||||
roiPercentage: number;
|
roiPercentage: number;
|
||||||
// paybackPeriod: number;
|
// paybackPeriod: number;
|
||||||
// totalCost: number;
|
// totalCost: number;
|
||||||
// revenueGenerated: number;
|
// revenueGenerated: number;
|
||||||
netProfit: number;
|
netProfit: number;
|
||||||
productionCapacity: number;
|
productionCapacity: number;
|
||||||
paybackPeriod: number;
|
paybackPeriod: number;
|
||||||
// netLoss: number;
|
// netLoss: number;
|
||||||
machineIdleTime: number;
|
machineIdleTime: number;
|
||||||
machineActiveTime: number;
|
machineActiveTime: number;
|
||||||
throughputData: number;
|
throughputData: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useCompareProductDataStore = create<{
|
export const useCompareProductDataStore = create<{
|
||||||
compareProductsData: CompareProduct[];
|
compareProductsData: CompareProduct[];
|
||||||
setCompareProductsData: (x: CompareProduct[]) => void;
|
setCompareProductsData: (x: CompareProduct[]) => void;
|
||||||
}>((set) => ({
|
}>((set) => ({
|
||||||
compareProductsData: [],
|
compareProductsData: [],
|
||||||
setCompareProductsData: (x) => set({ compareProductsData: x }),
|
setCompareProductsData: (x) => set({ compareProductsData: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useSelectedComment = create<any>((set: any) => ({
|
export const useSelectedComment = create<any>((set: any) => ({
|
||||||
selectedComment: null,
|
selectedComment: null,
|
||||||
setSelectedComment: (x: any) => set({ selectedComment: x }),
|
setSelectedComment: (x: any) => set({ selectedComment: x }),
|
||||||
position2Dstate: {},
|
position2Dstate: {},
|
||||||
setPosition2Dstate: (x: any) => set({ position2Dstate: x }),
|
setPosition2Dstate: (x: any) => set({ position2Dstate: x }),
|
||||||
commentPositionState: null,
|
commentPositionState: null,
|
||||||
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
||||||
}));
|
}));
|
||||||
export const useSelectedPath = create<any>((set: any) => ({
|
export const useSelectedPath = create<any>((set: any) => ({
|
||||||
selectedPath: "auto",
|
selectedPath: "auto",
|
||||||
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useContextActionStore = create<any>((set: any) => ({
|
export const useContextActionStore = create<any>((set: any) => ({
|
||||||
contextAction: null,
|
contextAction: null,
|
||||||
setContextAction: (x: any) => set({ contextAction: x }),
|
setContextAction: (x: any) => set({ contextAction: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
// Define the store's state and actions type
|
// Define the store's state and actions type
|
||||||
interface DecalStore {
|
interface DecalStore {
|
||||||
selectedSubCategory: string | null;
|
selectedSubCategory: string | null;
|
||||||
setSelectedSubCategory: (subCategory: string | null) => void;
|
setSelectedSubCategory: (subCategory: string | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Zustand store with types
|
// Create the Zustand store with types
|
||||||
export const useDecalStore = create<DecalStore>((set) => ({
|
export const useDecalStore = create<DecalStore>((set) => ({
|
||||||
selectedSubCategory: 'Safety',
|
selectedSubCategory: "Safety",
|
||||||
setSelectedSubCategory: (subCategory: string | null) => set({ selectedSubCategory: subCategory }),
|
setSelectedSubCategory: (subCategory: string | null) =>
|
||||||
|
set({ selectedSubCategory: subCategory }),
|
||||||
|
}));
|
||||||
|
export const comparsionMaterialData = create<any>((set: any) => ({
|
||||||
|
materialData: [],
|
||||||
|
setMaterialData: (x: any) => set({ materialData: x }),
|
||||||
}));
|
}));
|
||||||
|
|||||||
136
app/src/store/rough/useSimulationManagerStore.ts
Normal file
136
app/src/store/rough/useSimulationManagerStore.ts
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
|
||||||
|
import { create } from "zustand";
|
||||||
|
|
||||||
|
|
||||||
|
interface SimulationUsageRecord {
|
||||||
|
activeTime: number;
|
||||||
|
isActive: boolean;
|
||||||
|
idleTime: number;
|
||||||
|
type:
|
||||||
|
| "roboticArm"
|
||||||
|
| "vehicle"
|
||||||
|
| "transfer"
|
||||||
|
| "storageUnit"
|
||||||
|
| "crane"
|
||||||
|
| "human"
|
||||||
|
| "machine";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product → holds multiple usage records
|
||||||
|
interface ProductSimulation {
|
||||||
|
productId: string;
|
||||||
|
data: SimulationUsageRecord[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version → holds multiple products
|
||||||
|
interface VersionSimulation {
|
||||||
|
versionId: string;
|
||||||
|
products: ProductSimulation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project → holds multiple versions
|
||||||
|
interface ProjectSimulation {
|
||||||
|
projectId: string | undefined;
|
||||||
|
versions: VersionSimulation[];
|
||||||
|
}
|
||||||
|
// or same file
|
||||||
|
|
||||||
|
interface SimulationManagerStore {
|
||||||
|
simulationData: ProjectSimulation[];
|
||||||
|
|
||||||
|
addData: (
|
||||||
|
projectId: string | undefined,
|
||||||
|
versionId: string,
|
||||||
|
productId: string,
|
||||||
|
record: SimulationUsageRecord
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
resetProductData: (
|
||||||
|
projectId: string,
|
||||||
|
versionId: string,
|
||||||
|
productId: string
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSimulationManager = create<SimulationManagerStore>((set) => ({
|
||||||
|
simulationData: [],
|
||||||
|
|
||||||
|
addData: (projectId, versionId, productId, record) =>
|
||||||
|
set((state) => {
|
||||||
|
const projects = state.simulationData.map((project) => {
|
||||||
|
if (project.projectId !== projectId) return project;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...project,
|
||||||
|
versions: project.versions.map((version) => {
|
||||||
|
if (version.versionId !== versionId) return version;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...version,
|
||||||
|
products: version.products.map((product) =>
|
||||||
|
product.productId === productId
|
||||||
|
? { ...product, data: [...product.data, record] }
|
||||||
|
: product
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// If project doesn't exist, create it
|
||||||
|
if (!state.simulationData.find((p) => p.projectId === projectId)) {
|
||||||
|
projects.push({
|
||||||
|
projectId,
|
||||||
|
versions: [
|
||||||
|
{
|
||||||
|
versionId,
|
||||||
|
products: [{ productId, data: [record] }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const project = projects.find((p) => p.projectId === projectId)!;
|
||||||
|
if (!project.versions.find((v) => v.versionId === versionId)) {
|
||||||
|
project.versions.push({
|
||||||
|
versionId,
|
||||||
|
products: [{ productId, data: [record] }],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const version = project.versions.find(
|
||||||
|
(v) => v.versionId === versionId
|
||||||
|
)!;
|
||||||
|
if (!version.products.find((p) => p.productId === productId)) {
|
||||||
|
version.products.push({ productId, data: [record] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { simulationData: projects };
|
||||||
|
}),
|
||||||
|
|
||||||
|
resetProductData: (projectId, versionId, productId) =>
|
||||||
|
set((state) => {
|
||||||
|
const projects = state.simulationData.map((project) => {
|
||||||
|
if (project.projectId !== projectId) return project;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...project,
|
||||||
|
versions: project.versions.map((version) => {
|
||||||
|
if (version.versionId !== versionId) return version;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...version,
|
||||||
|
products: version.products.map((product) =>
|
||||||
|
product.productId === productId
|
||||||
|
? { ...product, data: [] }
|
||||||
|
: product
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return { simulationData: projects };
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
///////////////////////////
|
||||||
Reference in New Issue
Block a user