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 { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||
import { getSimulationData } from "../../scenes/functions/simulationStorage";
|
||||
|
||||
interface Event {
|
||||
modelName: string;
|
||||
@@ -137,6 +138,7 @@ const Simulations: React.FC = () => {
|
||||
if (selectedProductData) {
|
||||
determineExecutionMachineSequences([selectedProductData]).then(
|
||||
(sequences) => {
|
||||
console.log('selectedProductData: ', selectedProductData);
|
||||
sequences.forEach((sequence) => {
|
||||
const events: Event[] =
|
||||
sequence.map((event) => ({
|
||||
@@ -151,6 +153,12 @@ const Simulations: React.FC = () => {
|
||||
}
|
||||
|
||||
}, [selectedProduct.productUuid, products]);
|
||||
//call when comparePopup is true
|
||||
useEffect(() => {
|
||||
if (comparePopUp || selectedProduct.productUuid) {
|
||||
getSimulationData({ key: selectedProduct.productUuid });
|
||||
}
|
||||
}, [comparePopUp])
|
||||
|
||||
return (
|
||||
<div className="simulations-container">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { ExitIcon, PlayStopIcon, ResetIcon } from "../../icons/SimulationIcons";
|
||||
import {
|
||||
comparsionMaterialData,
|
||||
useActiveTool,
|
||||
useProcessBar,
|
||||
useViewSceneStore,
|
||||
@@ -32,6 +33,8 @@ import ROISummary from "../analysis/ROISummary";
|
||||
import { usePlayerStore } from "../../../store/useUIToggleStore";
|
||||
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
||||
import InputToggle from "../inputs/InputToggle";
|
||||
import { saveSimulationData } from "../../layout/scenes/functions/simulationStorage";
|
||||
import { useProductContext } from "../../../modules/simulation/products/productContext";
|
||||
|
||||
const SimulationPlayer: React.FC = () => {
|
||||
const MAX_SPEED = 8; // Maximum speed
|
||||
@@ -49,9 +52,11 @@ const SimulationPlayer: React.FC = () => {
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { clearComparisonProduct } = useComparisonProduct();
|
||||
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
|
||||
|
||||
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct, setSelectedProduct } = selectedProductStore();
|
||||
useEffect(() => {
|
||||
if (isReset) {
|
||||
setTimeout(() => {
|
||||
@@ -60,6 +65,12 @@ const SimulationPlayer: React.FC = () => {
|
||||
}
|
||||
}, [isReset, setReset]);
|
||||
|
||||
useEffect(() => {
|
||||
if (materialData.length === 0) return;
|
||||
console.log('materialData: ', materialData);
|
||||
saveSimulationData({ key: selectedProduct.productUuid, data: materialData });
|
||||
}, [materialData])
|
||||
|
||||
// Button functions
|
||||
const handleReset = () => {
|
||||
setReset(true);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DepthOfField, Bloom, EffectComposer, N8AO } from "@react-three/postprocessing";
|
||||
// import OutlineInstances from "./outlineInstances/outlineInstances";
|
||||
import OutlineInstances from "./outlineInstances/outlineInstances";
|
||||
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
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 { useProductContext } from '../../products/productContext';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
|
||||
import { set } from 'immer/dist/internal';
|
||||
|
||||
export default function ROIData() {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
@@ -17,6 +19,7 @@ export default function ROIData() {
|
||||
const { machineActiveTime } = useMachineUptime();
|
||||
const { machineIdleTime } = useMachineDowntime();
|
||||
const { throughputData } = useThroughPutData()
|
||||
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||
|
||||
useEffect(() => {
|
||||
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 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({
|
||||
productName: selectedProduct.productName,
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
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 { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
|
||||
|
||||
export default function ProductionCapacityData() {
|
||||
const { throughputData } = useThroughPutData()
|
||||
const { setProductionCapacityData } = useProductionCapacityData()
|
||||
const { inputValues } = useInputValues();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
@@ -21,10 +24,12 @@ export default function ProductionCapacityData() {
|
||||
if (!isNaN(workingDaysPerYear) && throughputData > 0) {
|
||||
const Monthly_working_days = workingDaysPerYear / 12;
|
||||
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)));
|
||||
}
|
||||
}, [throughputData, inputValues, isPlaying]);
|
||||
}, [throughputData, inputValues, isPlaying, materialData]);
|
||||
|
||||
return (
|
||||
<></>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useEffect } from 'react';
|
||||
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 { useSceneContext } from '../../../scene/sceneContext';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
|
||||
|
||||
export default function ThroughPutData() {
|
||||
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore } = useSceneContext();
|
||||
@@ -24,6 +25,7 @@ export default function ThroughPutData() {
|
||||
const { setThroughputData } = useThroughPutData()
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { inputValues } = useInputValues();
|
||||
const { materialData, setMaterialData } = comparsionMaterialData()
|
||||
|
||||
// Setting machine count
|
||||
let totalItems = 0;
|
||||
@@ -219,9 +221,13 @@ export default function ThroughPutData() {
|
||||
const Units_per_shift = (shiftLength * 60) / (materialCycleTime / 60);
|
||||
|
||||
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
|
||||
}
|
||||
}, [materialCycleTime, machineCount, isPlaying, inputValues]);
|
||||
}, [materialCycleTime, machineCount, isPlaying, inputValues, materialData]);
|
||||
|
||||
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 { useProductContext } from '../products/productContext';
|
||||
import { useSceneContext } from '../../scene/sceneContext';
|
||||
import SimulationHandler from './SimulationHandler';
|
||||
|
||||
function Simulator() {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
@@ -32,6 +33,9 @@ function Simulator() {
|
||||
|
||||
<>
|
||||
|
||||
{/* <simulationHandler/> */}
|
||||
<SimulationHandler />
|
||||
|
||||
</>
|
||||
|
||||
);
|
||||
|
||||
@@ -377,10 +377,12 @@ interface ResourceManagementState {
|
||||
setResourceManagementId: (id: string) => void;
|
||||
}
|
||||
|
||||
export const useResourceManagementId = create<ResourceManagementState>((set) => ({
|
||||
export const useResourceManagementId = create<ResourceManagementState>(
|
||||
(set) => ({
|
||||
resourceManagementId: "", // default value
|
||||
setResourceManagementId: (id: string) => set({ resourceManagementId: id }),
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
// version visible hidden
|
||||
interface VersionHistoryState {
|
||||
@@ -590,7 +592,6 @@ export const useContextActionStore = create<any>((set: any) => ({
|
||||
setContextAction: (x: any) => set({ contextAction: x }),
|
||||
}));
|
||||
|
||||
|
||||
// Define the store's state and actions type
|
||||
interface DecalStore {
|
||||
selectedSubCategory: string | null;
|
||||
@@ -599,6 +600,11 @@ interface DecalStore {
|
||||
|
||||
// Create the Zustand store with types
|
||||
export const useDecalStore = create<DecalStore>((set) => ({
|
||||
selectedSubCategory: 'Safety',
|
||||
setSelectedSubCategory: (subCategory: string | null) => set({ selectedSubCategory: subCategory }),
|
||||
selectedSubCategory: "Safety",
|
||||
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