diff --git a/app/src/components/layout/scenes/ComparisonScene.tsx b/app/src/components/layout/scenes/ComparisonScene.tsx index 06c74be..cd3e398 100644 --- a/app/src/components/layout/scenes/ComparisonScene.tsx +++ b/app/src/components/layout/scenes/ComparisonScene.tsx @@ -124,6 +124,7 @@ function ComparisonScene() { const { activeModule } = useModuleStore(); const { mainScene, comparisonScene, setComparisonState } = useSimulationState(); const { loadingProgress } = useLoadingProgress(); + const { simulationRecords } = useSimulationManager(); const { projectId } = useParams(); const { setCompareProductsData } = useCompareProductDataStore(); const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false); @@ -165,9 +166,11 @@ function ComparisonScene() { useEffect(() => { // const selectedProductData = getProductById(selectedProduct.productUuid); if (mainScene && comparisonScene && selectedVersion) { - const product1 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, mainScene.product.productUuid); + const product1 = useSimulationManager.getState().getProductById(projectId, mainScene.version.versionUuid, mainScene.product.productUuid); + console.log("product1: ", product1); - const product2 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, comparisonScene.product.productUuid); + const product2 = useSimulationManager.getState().getProductById(projectId, comparisonScene.version.versionUuid, comparisonScene.product.productUuid); + console.log("product2: ", product2); const compareProduct1 = createCompareProduct(product1?.productId ?? "", mainScene.product.productName, product1?.simulateData || []); const compareProduct2 = createCompareProduct(product2?.productId ?? "", comparisonScene.product.productName, product2?.simulateData || []); diff --git a/app/src/components/layout/scenes/functions/simulationStorage.ts b/app/src/components/layout/scenes/functions/simulationStorage.ts deleted file mode 100644 index 9537ea4..0000000 --- a/app/src/components/layout/scenes/functions/simulationStorage.ts +++ /dev/null @@ -1,135 +0,0 @@ -let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; - -interface SimulationData { - key: string; - data?: object | any; -} -interface SimulationUsageRecord { - activeTime: number; - isActive: boolean; - idleTime: number; - type: "roboticArm" | "vehicle" | "transfer" | "storageUnit" | "crane" | "human" | "machine"; - assetId: string; -} - -// Product → holds multiple usage records -interface ProductSimulation { - productId: string; - simulateData: SimulationUsageRecord[]; -} - -// Version → holds multiple products -interface VersionSimulation { - versionId: string; - products: ProductSimulation[]; -} - -// Project → holds multiple versions -interface ProjectSimulation { - projectId: string | undefined; - versions: VersionSimulation[]; -} - -export const saveSimulationData = async (data: any) => { - try { - const response = await fetch(`${url_Backend_dwinzo}/api/V1/SimulatedUpsert`, { - method: "POST", - headers: { - Authorization: "Bearer ", - "Content-Type": "application/json", - token: localStorage.getItem("token") || "", - refresh_token: localStorage.getItem("refreshToken") || "", - }, - body: JSON.stringify(data), - }); - const newAccessToken = response.headers.get("x-access-token"); - if (newAccessToken) { - localStorage.setItem("token", newAccessToken); - } - if (!response.ok) { - console.error("Failed to add project"); - } - - const result = await response.json(); - - return result; - } catch (error) { - if (error instanceof Error) { - console.log(error.message); - } else { - console.log("An unknown error occurred"); - } - } -}; - -export const updateSimulateData = async (data: any) => { - // console.log("data: update", data); - try { - const response = await fetch(`${url_Backend_dwinzo}/api/V1/ValidateSimulated`, { - method: "POST", - headers: { - Authorization: "Bearer ", - "Content-Type": "application/json", - token: localStorage.getItem("token") || "", - refresh_token: localStorage.getItem("refreshToken") || "", - }, - body: JSON.stringify(data), - }); - const newAccessToken = response.headers.get("x-access-token"); - if (newAccessToken) { - localStorage.setItem("token", newAccessToken); - } - if (!response.ok) { - console.error("Failed to update "); - } - - const result = await response.json(); - - return result; - } catch (error) { - if (error instanceof Error) { - console.log(error.message); - } else { - console.log("An unknown error occurred"); - } - } -}; -export const getSimulationData = async ( - projectId: string, - versionId: string, - productUuid: string -) => { - // console.log("called"); - try { - const response = await fetch( - `${url_Backend_dwinzo}/api/V1/SimulatedDatas/${projectId}/${versionId}?productUuid=${productUuid}`, - { - method: "GET", - headers: { - Authorization: "Bearer ", - "Content-Type": "application/json", - token: localStorage.getItem("token") || "", - refresh_token: localStorage.getItem("refreshToken") || "", - }, - } - ); - - console.log("response: ", response); - - const newAccessToken = response.headers.get("x-access-token"); - if (newAccessToken) { - localStorage.setItem("token", newAccessToken); - } - - if (!response.ok) { - throw new Error("Failed to fetch simulateData"); - } - - return await response.json(); - } catch (error: any) { - console.error("Failed to get simulation data"); - console.log(error.message); - } -}; - -// export const clearSimulationData = ({ key, data }: SimulationData) => {}; diff --git a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx index 90b04ee..e275341 100644 --- a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx +++ b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx @@ -13,11 +13,12 @@ import { deleteProductApi } from "../../../../services/simulation/products/delet import { renameProductApi } from "../../../../services/simulation/products/renameProductApi"; import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences"; import ComparePopUp from "../../../ui/compareVersion/Compare"; -import { useCompareStore, useIsComparing, useSimulateId } from "../../../../store/builder/store"; +import { useCompareStore, useIsComparing } from "../../../../store/builder/store"; import { useToggleStore } from "../../../../store/ui/useUIToggleStore"; import { useParams } from "react-router-dom"; import { useSceneContext } from "../../../../modules/scene/sceneContext"; -import { updateSimulateData } from "../../scenes/functions/simulationStorage"; +import { useSimulationManager } from "../../../../store/rough/useSimulationManagerStore"; +import { validateSimulationDataApi } from "../../../../services/simulation/comparison/validateSimulationDataApi"; interface Event { modelName: string; @@ -38,9 +39,9 @@ const Simulations: React.FC = () => { const { selectedVersion } = versionStore(); const { comparePopUp, setComparePopUp } = useCompareStore(); const { setIsComparing } = useIsComparing(); - const { simulateId } = useSimulateId(); + const { addSimulationRecord } = useSimulationManager(); - const handleSaveVersion = async () => { + const handleSaveVersion = () => { setIsComparing(true); setComparePopUp(false); setToggleUI(false, false); @@ -48,10 +49,13 @@ const Simulations: React.FC = () => { projectId: projectId, versionId: selectedVersion?.versionId || "", productUuid: selectedProduct?.productUuid || "", - simulatedId: simulateId, }; - const getData = await updateSimulateData(singleData); - echo.log(getData.message); + validateSimulationDataApi(singleData).then((getData) => { + echo.log(getData.message); + const getSimulate = getData?.data; + if (!selectedVersion?.versionId && !projectId && getSimulate === undefined && !selectedProduct.productUuid) return; + addSimulationRecord(projectId, selectedVersion?.versionId || "", selectedProduct.productUuid || "", getSimulate.data); + }); }; const handleAddProduct = () => { @@ -152,18 +156,6 @@ const Simulations: React.FC = () => { } }, [comparePopUp]); - const getSimulate = async () => { - // const singleData = { - // projectId: projectId, - // versionId: selectedVersion?.versionId || "", - // productUuid: selectedProduct?.productUuid || "", - // }; - // console.log("singleData: ", singleData); - // const getData = await getSimulationData(singleData); - // console.log("getData: ", getData); - setComparePopUp(true); - }; - return (
Simulations
@@ -236,13 +228,7 @@ const Simulations: React.FC = () => {
Click 'Compare' to review and analyze the layout differences between them.
-
diff --git a/app/src/components/ui/compareVersion/CompareLayOut.tsx b/app/src/components/ui/compareVersion/CompareLayOut.tsx index 27f1447..c86cc66 100644 --- a/app/src/components/ui/compareVersion/CompareLayOut.tsx +++ b/app/src/components/ui/compareVersion/CompareLayOut.tsx @@ -12,10 +12,12 @@ import Scene from "../../../modules/scene/scene"; import useRestStates from "../../../hooks/useResetStates"; import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi"; +import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore"; +import { validateSimulationDataApi } from "../../../services/simulation/comparison/validateSimulationDataApi"; const CompareLayOut = () => { const { clearComparisonState, comparisonScene, setComparisonState } = useSimulationState(); - const { versionStore } = useSceneContext(); + const { versionStore, productStore } = useSceneContext(); const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion, setVersions } = versionStore(); const { setLoadingProgress } = useLoadingProgress(); const [width, setWidth] = useState("50vw"); @@ -29,7 +31,8 @@ const CompareLayOut = () => { const { setIsPlaying } = usePlayButtonStore(); const { projectId } = useParams(); const { resetStates } = useRestStates(); - + const { products } = productStore(); + const { addSimulationRecord } = useSimulationManager(); useEffect(() => { return () => { resetStates(); @@ -65,6 +68,7 @@ const CompareLayOut = () => { if (!comparisonScene) { clearSelectedVersion(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [comparisonScene]); OuterClick({ @@ -161,13 +165,24 @@ const CompareLayOut = () => { }; setComparisonState(comparisonData); setLoadingProgress(1); + const singleData = { + projectId: projectId, + versionId: version.versionId, // use version directly, not selectedVersion + productUuid: data[0].productUuid, // productUuid is already a string + }; + console.log("products", products); + validateSimulationDataApi(singleData).then((getData) => { + echo.log(getData.message); + const getSimulate = getData?.data; + addSimulationRecord(projectId, selectedVersion?.versionId || "", data[0].productUuid || "", getSimulate.data); + }); } }); }; return (
- {loadingProgress == 0 && selectedVersion?.versionId && ( + {loadingProgress === 0 && selectedVersion?.versionId && ( diff --git a/app/src/components/ui/simulation/simulationPlayer.tsx b/app/src/components/ui/simulation/simulationPlayer.tsx index cb3ce1d..b512ad6 100644 --- a/app/src/components/ui/simulation/simulationPlayer.tsx +++ b/app/src/components/ui/simulation/simulationPlayer.tsx @@ -42,8 +42,6 @@ const SimulationPlayer: React.FC = () => { useEffect(() => { if (materialData.length === 0) return; - // console.log("materialData: ", materialData); - // saveSimulationData({ key: selectedProduct.productUuid, data: materialData }); }, [materialData]); // Button functions @@ -333,7 +331,12 @@ const SimulationPlayer: React.FC = () => {
- diff --git a/app/src/modules/simulation/analysis/ROI/roiData.tsx b/app/src/modules/simulation/analysis/ROI/roiData.tsx index 27807ae..fe4862b 100644 --- a/app/src/modules/simulation/analysis/ROI/roiData.tsx +++ b/app/src/modules/simulation/analysis/ROI/roiData.tsx @@ -1,9 +1,18 @@ -import React, { useEffect } from 'react' -import { CompareProduct, comparsionMaterialData, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store'; -import { useSceneContext } from '../../../scene/sceneContext'; -import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage'; -import { set } from 'immer/dist/internal'; -import { usePlayButtonStore } from '../../../../store/ui/usePlayButtonStore'; +import React, { useEffect } from "react"; +import { + CompareProduct, + comparsionMaterialData, + useCompareProductDataStore, + useInputValues, + useMachineDowntime, + useMachineUptime, + useProductionCapacityData, + useROISummaryData, + useThroughPutData, +} from "../../../../store/builder/store"; +import { useSceneContext } from "../../../scene/sceneContext"; + +import { usePlayButtonStore } from "../../../../store/ui/usePlayButtonStore"; export default function ROIData() { const { inputValues } = useInputValues(); @@ -15,8 +24,8 @@ export default function ROIData() { const { compareProductsData, setCompareProductsData } = useCompareProductDataStore(); const { machineActiveTime } = useMachineUptime(); const { machineIdleTime } = useMachineDowntime(); - const { throughputData } = useThroughPutData() - const { materialData, setMaterialData } = comparsionMaterialData() + const { throughputData } = useThroughPutData(); + const { setMaterialData } = comparsionMaterialData(); useEffect(() => { if (isPlaying) return; @@ -29,6 +38,7 @@ export default function ROIData() { netProfit: 0, netLoss: 0, }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isPlaying]); useEffect(() => { @@ -47,7 +57,20 @@ export default function ROIData() { const shiftsPerDay = parseFloat(inputValues["Shifts / day"]); const workingDaysPerYear = parseFloat(inputValues["Working days / year"]); - if (!isNaN(electricityCost) && !isNaN(fixedCost) && !isNaN(laborCost) && !isNaN(maintenanceCost) && !isNaN(materialCost) && !isNaN(productionPeriod) && !isNaN(salvageValue) && !isNaN(sellingPrice) && !isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && productionCapacityData > 0) { + if ( + !isNaN(electricityCost) && + !isNaN(fixedCost) && + !isNaN(laborCost) && + !isNaN(maintenanceCost) && + !isNaN(materialCost) && + !isNaN(productionPeriod) && + !isNaN(salvageValue) && + !isNaN(sellingPrice) && + !isNaN(shiftLength) && + !isNaN(shiftsPerDay) && + !isNaN(workingDaysPerYear) && + productionCapacityData > 0 + ) { // const totalHoursPerYear = shiftLength * shiftsPerDay * workingDaysPerYear; // const annualProductionUnits = productionCapacityData * totalHoursPerYear; // const annualRevenue = annualProductionUnits * sellingPrice; @@ -130,7 +153,8 @@ export default function ROIData() { const ROI = (Net_profit / initialInvestment) * 100; - 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 data = { productName: selectedProduct.productName, @@ -139,14 +163,13 @@ export default function ROIData() { 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 }); + netLoss: Net_profit < 0 ? -Net_profit : 0, + }; + console.log("selectedProduct.productUuid: ", selectedProduct.productUuid); + const datas = { - roi: data - } + roi: data, + }; setMaterialData(datas); setRoiSummaryData({ @@ -193,6 +216,7 @@ export default function ROIData() { setCompareProductsData([...prev, newData]); } } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [inputValues, productionCapacityData, throughputData, isPlaying]); useEffect(() => {}, [compareProductsData]); diff --git a/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx b/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx index e38baa1..32e4274 100644 --- a/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx +++ b/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx @@ -1,21 +1,20 @@ -import { useEffect } from 'react' -import { comparsionMaterialData, useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store' +import { useEffect } from "react"; +import { comparsionMaterialData, useInputValues, useProductionCapacityData, useThroughPutData } from "../../../../store/builder/store"; -import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage'; -import { usePlayButtonStore } from '../../../../store/ui/usePlayButtonStore'; +import { usePlayButtonStore } from "../../../../store/ui/usePlayButtonStore"; export default function ProductionCapacityData() { const { throughputData } = useThroughPutData(); const { setProductionCapacityData } = useProductionCapacityData(); const { inputValues } = useInputValues(); const { isPlaying } = usePlayButtonStore(); - const { materialData, setMaterialData } = comparsionMaterialData() - + const { materialData, setMaterialData } = comparsionMaterialData(); useEffect(() => { if (!isPlaying) { setProductionCapacityData(0); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isPlaying]); useEffect(() => { @@ -26,7 +25,6 @@ export default function ProductionCapacityData() { 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))); } diff --git a/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx b/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx index a875de3..fd898c3 100644 --- a/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx +++ b/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx @@ -1,9 +1,8 @@ -import { useEffect } from 'react'; -import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences'; -import { comparsionMaterialData, useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store'; -import { useSceneContext } from '../../../scene/sceneContext'; -import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage'; -import { usePlayButtonStore } from '../../../../store/ui/usePlayButtonStore'; +import { useEffect } from "react"; +import { determineExecutionMachineSequences } from "../../simulator/functions/determineExecutionMachineSequences"; +import { comparsionMaterialData, useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from "../../../../store/builder/store"; +import { useSceneContext } from "../../../scene/sceneContext"; +import { usePlayButtonStore } from "../../../../store/ui/usePlayButtonStore"; export default function ThroughPutData() { const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore } = useSceneContext(); @@ -22,7 +21,7 @@ export default function ThroughPutData() { const { setThroughputData } = useThroughPutData(); const { isPlaying } = usePlayButtonStore(); const { inputValues } = useInputValues(); - const { materialData, setMaterialData } = comparsionMaterialData() + const { materialData, setMaterialData } = comparsionMaterialData(); // Setting machine count let totalItems = 0; @@ -209,6 +208,7 @@ export default function ThroughPutData() { return () => { if (timeoutId) clearTimeout(timeoutId); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid]); useEffect(() => { @@ -220,13 +220,11 @@ 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)) - console.log('data: ', data); - // saveSimulationData({ key: selectedProduct.productUuid, data: data }); - + const data = Number(Throughput_per_day.toFixed(2)); setMaterialData({ ...materialData, throughput: data }); setThroughputData(Number(Throughput_per_day.toFixed(2))); // Keep as number } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [materialCycleTime, machineCount, isPlaying, inputValues, materialData]); return <>; diff --git a/app/src/modules/simulation/simulator/SimulationHandler.tsx b/app/src/modules/simulation/simulator/SimulationHandler1.tsx similarity index 68% rename from app/src/modules/simulation/simulator/SimulationHandler.tsx rename to app/src/modules/simulation/simulator/SimulationHandler1.tsx index dfa230f..f105f77 100644 --- a/app/src/modules/simulation/simulator/SimulationHandler.tsx +++ b/app/src/modules/simulation/simulator/SimulationHandler1.tsx @@ -1,10 +1,10 @@ -import React, { useEffect, useState } from 'react'; -import { useSceneContext } from '../../scene/sceneContext'; -import { determineExecutionMachineSequences } from './functions/determineExecutionMachineSequences'; -import { usePlayButtonStore } from '../../../store/ui/usePlayButtonStore'; -import { useSimulationManager } from '../../../store/rough/useSimulationManagerStore'; -import { useParams } from 'react-router-dom'; -import { useSimulateId } from '../../../store/builder/store'; +import React, { useEffect, useState } from "react"; +import { useSceneContext } from "../../scene/sceneContext"; +import { determineExecutionMachineSequences } from "./functions/determineExecutionMachineSequences"; +import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore"; +import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore"; +import { useParams } from "react-router-dom"; +import { saveSimulationDataApi } from "../../../services/simulation/comparison/saveSimulationDataApi"; interface SimulationUsageRecord { activeTime: number; @@ -26,11 +26,6 @@ interface VersionSimulation { 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, versionStore } = useSceneContext(); const { armBots, getArmBotById } = armBotStore(); @@ -43,10 +38,8 @@ const SimulationHandler = () => { const { getCraneById } = craneStore(); const { getStorageUnitById } = storageUnitStore(); const { isPlaying, setIsPlaying } = usePlayButtonStore(); - const { simulationRecords, addSimulationRecord } = useSimulationManager(); + const { resetProductRecords, addSimulationRecord } = useSimulationManager(); const { projectId } = useParams(); - const [simulationEntry, setSimulationEntry] = useState(); - const { setSimulateId } = useSimulateId(); const COST_RATES: Record = { roboticArm: 5, vehicle: 2, @@ -117,76 +110,6 @@ const SimulationHandler = () => { }); } - // useEffect(() => { - // const runSimulation = async () => { - // console.log("simulationRecords: ", simulationRecords); - // if (!projectId || !selectedVersion || !selectedProduct.productUuid || simulationRecords.length === 0) return; - - // const project = simulationRecords[0]; - - // if (project) { - // // const scores = calculateEfficiencyScores(project.versions); - // // console.log("Version Comparisons:", scores); - // } - // console.log("simulationEntry: ", simulationEntry); - // console.log("simulationEntrysaddasd: ", useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, selectedProduct.productUuid)?.simulateData); - - // const data = { - // projectId: projectId, - // versionId: selectedVersion.versionId, - // productUuid: selectedProduct.productUuid, - // simulateData: useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, selectedProduct.productUuid)?.simulateData, - // }; - - // const simulations = await saveSimulationData(data); - // console.log("simulations: ", simulations); - // const simulateId = localStorage.getItem("simulateId"); - // console.log("simulateId: ", simulateId); - // if (simulations.message === "SimulatedData created Successfully") { - // console.log("simulations.data: ", simulations.data); - // setSimulationEntry(simulations.data); - // localStorage.setItem("simulateId", simulations.data); - // setSimulateId(simulations.data); - // } - - // // else { - // // console.log("djh"); - // // const data = { - // // projectId: projectId, - // // versionId: selectedVersion.versionId, - // // productUuid: selectedProduct.productUuid, - // // simulateId: simulateId, - // // simulateData: useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, selectedProduct.productUuid)?.simulateData, - // // }; - // // const update = await updateSimulateData(data); - // // console.log("update: ", update); - // // } - // }; - - // runSimulation(); - // }, [simulationRecords, projectId, selectedVersion, selectedProduct]); - - // useEffect(() => { - // console.log('simulationRecords: ', simulationRecords); - // if (!projectId || !selectedVersion || !selectedProduct.productUuid || simulationRecords.length === 0) return; - - // const project = simulationRecords[0]; - - // if (project) { - // const scores = calculateEfficiencyScores(project.versions); - // console.log("Version Comparisons:", scores); - // } - - // saveSimulationData({ - // key: selectedProduct.productUuid, - // data: simulationRecords, - // }); - // // saveSimulationData({ - // // key: selectedProduct.productUuid, - // // data: simulationRecords, - // // }); - // }, [simulationRecords]); - useEffect(() => { let checkTimer: ReturnType; if (!projectId) return; @@ -246,6 +169,8 @@ const SimulationHandler = () => { } if (materials.length === 0 && materialHistory.length >= 0 && !hasActiveEntity) { + if (!selectedVersion) return; + resetProductRecords(projectId, selectedVersion?.versionId, selectedProduct?.productUuid); if (executionSequences?.length > 0) { executionSequences.forEach((sequence) => { sequence.forEach((entity) => { @@ -275,6 +200,15 @@ const SimulationHandler = () => { }); }); } + const data = { + projectId: projectId, + versionId: selectedVersion?.versionId, + productUuid: selectedProduct.productUuid, + simulateData: useSimulationManager.getState().getProductById(projectId || "", selectedVersion?.versionId || "", selectedProduct?.productUuid || "")?.simulateData, + }; + const simulations = await saveSimulationDataApi(data); + + echo.log("Simulation data saved successfully"); setIsPlaying(false); } } @@ -289,6 +223,7 @@ const SimulationHandler = () => { return () => { if (checkTimer) clearTimeout(checkTimer); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [materials, materialHistory, selectedVersion, selectedProduct?.productUuid, isPlaying, armBots, vehicles, machines]); return null; diff --git a/app/src/modules/simulation/simulator/simulator.tsx b/app/src/modules/simulation/simulator/simulator.tsx index f64d2b1..f44dc4c 100644 --- a/app/src/modules/simulation/simulator/simulator.tsx +++ b/app/src/modules/simulation/simulator/simulator.tsx @@ -3,14 +3,10 @@ import { useActionHandler } from "../actions/useActionHandler"; import { usePlayButtonStore, useResetButtonStore } from "../../../store/ui/usePlayButtonStore"; import { determineExecutionOrder } from "./functions/determineExecutionOrder"; import { useSceneContext } from "../../scene/sceneContext"; -import SimulationHandler from "./SimulationHandler"; +import SimulationHandler from "./SimulationHandler1"; import { useParams } from "react-router-dom"; -import { - getSimulationData, - saveSimulationData, -} from "../../../components/layout/scenes/functions/simulationStorage"; import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore"; -import { useSimulateId } from "../../../store/builder/store"; +import { getSimulationDataApi } from "../../../services/simulation/comparison/getSimulationDataApi"; function Simulator() { const { productStore, versionStore } = useSceneContext(); @@ -20,8 +16,7 @@ function Simulator() { const { isReset } = useResetButtonStore(); const { projectId } = useParams(); const { selectedVersion } = versionStore(); - const { setSimulateId } = useSimulateId(); - const { addSimulationRecords } = useSimulationManager(); + const { addSimulationRecord } = useSimulationManager(); useEffect(() => { if (!isPlaying || isReset || !selectedProduct.productUuid) return; @@ -34,52 +29,28 @@ function Simulator() { executionOrder.forEach((action) => { handleAction(action); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [products, isPlaying, isReset, selectedProduct]); useEffect(() => { if (!projectId || !selectedVersion || !selectedProduct?.productUuid) return; const fetchSimulateData = async () => { - const getData = await getSimulationData( - projectId, - selectedVersion.versionId, - selectedProduct?.productUuid - ); + const getData = await getSimulationDataApi(projectId, selectedVersion.versionId, selectedProduct?.productUuid); + const product = getProductById(selectedProduct.productUuid); if (!product) return; const products: ProductsSchema = [product]; const getSimulate = getData?.data; - // console.log("getSimulate: ", getSimulate); - if (getData && getSimulate && getSimulate.productTimestamp === products[0]?.timestamp) { - setSimulateId(getSimulate._id); - // console.log(" getSimulate.data: ", getSimulate.data); - addSimulationRecords( - projectId, - selectedVersion?.versionId || "", - selectedProduct?.productUuid || "", - getSimulate.data // ✅ this is already an array - ); + + if (getData.message !== "Simulated data not found" && getSimulate && getSimulate.productTimestamp === products[0]?.timestamp) { + addSimulationRecord(projectId, selectedVersion?.versionId || "", selectedProduct?.productUuid || "", getSimulate.data); echo.log("Simulation data is up to date"); return; } else { - //call create API - const data = { - projectId: projectId, - versionId: selectedVersion.versionId, - productUuid: selectedProduct.productUuid, - simulateData: useSimulationManager - .getState() - .getProductById( - projectId, - selectedVersion?.versionId, - selectedProduct.productUuid - )?.simulateData, - }; - const simulations = await saveSimulationData(data); - // console.log("simulations: ", simulations); - echo.log("Simulation data saved successfully"); } }; fetchSimulateData(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/app/src/services/simulation/comparison/getSimulationDataApi.ts b/app/src/services/simulation/comparison/getSimulationDataApi.ts new file mode 100644 index 0000000..62cc56f --- /dev/null +++ b/app/src/services/simulation/comparison/getSimulationDataApi.ts @@ -0,0 +1,31 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const getSimulationDataApi = async (projectId: string, versionId: string, productUuid: string) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/V1/SimulatedDatas/${projectId}/${versionId}?productUuid=${productUuid}`, { + method: "GET", + headers: { + Authorization: "Bearer ", + "Content-Type": "application/json", + token: localStorage.getItem("token") || "", + refresh_token: localStorage.getItem("refreshToken") || "", + }, + }); + + console.log("response: ", response); + + const newAccessToken = response.headers.get("x-access-token"); + if (newAccessToken) { + localStorage.setItem("token", newAccessToken); + } + + if (!response.ok) { + throw new Error("Failed to fetch simulateData"); + } + + return await response.json(); + } catch (error: any) { + console.error("Failed to get simulation data"); + console.log(error.message); + } +}; diff --git a/app/src/services/simulation/comparison/saveSimulationDataApi.ts b/app/src/services/simulation/comparison/saveSimulationDataApi.ts new file mode 100644 index 0000000..c708bf3 --- /dev/null +++ b/app/src/services/simulation/comparison/saveSimulationDataApi.ts @@ -0,0 +1,33 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; + +export const saveSimulationDataApi = async (data: any) => { + try { + const response = await fetch(`${url_Backend_dwinzo}/api/V1/SimulatedUpsert`, { + method: "POST", + headers: { + Authorization: "Bearer ", + "Content-Type": "application/json", + token: localStorage.getItem("token") || "", + refresh_token: localStorage.getItem("refreshToken") || "", + }, + body: JSON.stringify(data), + }); + const newAccessToken = response.headers.get("x-access-token"); + if (newAccessToken) { + localStorage.setItem("token", newAccessToken); + } + if (!response.ok) { + console.error("Failed to add project"); + } + + const result = await response.json(); + + return result; + } catch (error) { + if (error instanceof Error) { + console.log(error.message); + } else { + console.log("An unknown error occurred"); + } + } +}; diff --git a/app/src/services/simulation/comparison/validateSimulationDataApi.ts b/app/src/services/simulation/comparison/validateSimulationDataApi.ts new file mode 100644 index 0000000..77ee433 --- /dev/null +++ b/app/src/services/simulation/comparison/validateSimulationDataApi.ts @@ -0,0 +1,34 @@ +let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; +export const validateSimulationDataApi = async (data: any) => { + console.log("data: validate", data); + try { + const response = await fetch(`${url_Backend_dwinzo}/api/V1/ValidateSimulated`, { + method: "POST", + headers: { + Authorization: "Bearer ", + "Content-Type": "application/json", + token: localStorage.getItem("token") || "", + refresh_token: localStorage.getItem("refreshToken") || "", + }, + body: JSON.stringify(data), + }); + const newAccessToken = response.headers.get("x-access-token"); + if (newAccessToken) { + localStorage.setItem("token", newAccessToken); + } + if (!response.ok) { + console.error("Failed to update "); + } + + const result = await response.json(); + console.log("result:Valid ", result); + + return result; + } catch (error) { + if (error instanceof Error) { + console.log(error.message); + } else { + console.log("An unknown error occurred"); + } + } +}; diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index 560a141..d2e107a 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -538,6 +538,7 @@ export interface CompareProduct { netProfit: number; productionCapacity: number; paybackPeriod: number; + // netLoss: number; machineIdleTime: number; machineActiveTime: number; throughputData: number; @@ -589,7 +590,3 @@ export const comparsionMaterialData = create((set: any) => ({ materialData: [], setMaterialData: (x: any) => set({ materialData: x }), })); -export const useSimulateId = create((set: any) => ({ - simulateId: "", - setSimulateId: (x: any) => set({ simulateId: x }), -})); diff --git a/app/src/store/rough/useSimulationManagerStore.ts b/app/src/store/rough/useSimulationManagerStore.ts index 3be1ca9..fc72630 100644 --- a/app/src/store/rough/useSimulationManagerStore.ts +++ b/app/src/store/rough/useSimulationManagerStore.ts @@ -32,7 +32,7 @@ interface SimulationManagerStore { setSimulationRecords: (simulateData: ProjectSimulation[]) => void; addSimulationRecord: (projectId: string | undefined, versionId: string, productId: string, record: SimulationUsageRecord) => void; addSimulationRecords: (projectId: string | undefined, versionId: string, productId: string, records: SimulationUsageRecord[]) => void; - resetProductRecords: (projectId: string, versionId: string, productId: string) => void; + resetProductRecords: (projectId: string | undefined, versionId: string | null, productId: string) => void; getProjectById: (projectId: string | undefined) => ProjectSimulation | undefined; getVersionById: (projectId: string | undefined, versionId: string) => VersionSimulation | undefined; getProductById: (projectId: string | undefined, versionId: string, productId: string) => ProductSimulation | undefined; @@ -41,6 +41,52 @@ interface SimulationManagerStore { export const useSimulationManager = create((set, get) => ({ simulationRecords: [], + // addSimulationRecord: (projectId, versionId, productId, record) => + // set((state) => { + // const projects = state.simulationRecords.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, simulateData: [...product.simulateData, record] } : product)), + // }; + // }), + // }; + // }); + + // // If project doesn't exist, create it + // if (!state.simulationRecords.find((p) => p.projectId === projectId)) { + // projects.push({ + // projectId, + // versions: [ + // { + // versionId, + // products: [{ productId, simulateData: [record] }], + // }, + // ], + // }); + // } else { + // const project = projects.find((p) => p.projectId === projectId)!; + // if (!project.versions.find((v) => v.versionId === versionId)) { + // project.versions.push({ + // versionId, + // products: [{ productId, simulateData: [record] }], + // }); + // } else { + // const version = project.versions.find((v) => v.versionId === versionId)!; + // if (!version.products.find((p) => p.productId === productId)) { + // version.products.push({ productId, simulateData: [record] }); + // } + // } + // } + + // return { simulationRecords: projects }; + // }), addSimulationRecord: (projectId, versionId, productId, record) => set((state) => { const projects = state.simulationRecords.map((project) => { @@ -53,14 +99,25 @@ export const useSimulationManager = create((set, get) => return { ...version, - products: version.products.map((product) => (product.productId === productId ? { ...product, simulateData: [...product.simulateData, record] } : product)), + products: version.products.map((product) => { + if (product.productId !== productId) return product; + + const exists = product.simulateData.some((r) => r.assetId === record.assetId); + + return { + ...product, + simulateData: exists + ? product.simulateData.map((r) => (r.assetId === record.assetId ? record : r)) // update + : [...product.simulateData, record], // insert + }; + }), }; }), }; }); - // If project doesn't exist, create it - if (!state.simulationRecords.find((p) => p.projectId === projectId)) { + // If project/version/product doesn’t exist, create it + if (!projects.find((p) => p.projectId === projectId)) { projects.push({ projectId, versions: [ @@ -72,14 +129,15 @@ export const useSimulationManager = create((set, get) => }); } else { const project = projects.find((p) => p.projectId === projectId)!; - if (!project.versions.find((v) => v.versionId === versionId)) { + let version = project.versions.find((v) => v.versionId === versionId); + if (!version) { project.versions.push({ versionId, products: [{ productId, simulateData: [record] }], }); } else { - const version = project.versions.find((v) => v.versionId === versionId)!; - if (!version.products.find((p) => p.productId === productId)) { + let product = version.products.find((p) => p.productId === productId); + if (!product) { version.products.push({ productId, simulateData: [record] }); } }