From c8e963305057dcadcd0c7c9d76fe44be4eeec9e8 Mon Sep 17 00:00:00 2001 From: Poovizhi99 Date: Sat, 6 Sep 2025 18:19:02 +0530 Subject: [PATCH] merged and added the layout --- .../layout/scenes/ComparisonScene.tsx | 145 +++++++++++++++++- .../sidebarRight/simulation/Simulations.tsx | 15 +- .../simulation/simulator/simulator.tsx | 15 +- app/src/store/builder/store.ts | 134 ++++++++-------- .../store/rough/useSimulationManagerStore.ts | 48 +++++- 5 files changed, 281 insertions(+), 76 deletions(-) diff --git a/app/src/components/layout/scenes/ComparisonScene.tsx b/app/src/components/layout/scenes/ComparisonScene.tsx index 00b757d..41201ad 100644 --- a/app/src/components/layout/scenes/ComparisonScene.tsx +++ b/app/src/components/layout/scenes/ComparisonScene.tsx @@ -7,7 +7,110 @@ import useModuleStore from "../../../store/ui/useModuleStore"; import CompareLayOut from "../../ui/compareVersion/CompareLayOut"; import ComparisonResult from "../../ui/compareVersion/ComparisonResult"; import RegularDropDown from "../../ui/inputs/RegularDropDown"; +import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore"; +import { useParams } from "react-router-dom"; +type AssetData = { + activeTime: number; + idleTime: number; + type: string; + assetId: string; +}; +export interface CompareProduct { + productUuid: string; + productName: string; + // simulationData: { + // // costPerUnit: number; + // // workingDaysPerYear: number; + // // shiftLength: number; + // // shiftsPerDay: number; + // roiPercentage: number; + // // paybackPeriod: number; + // // totalCost: number; + // // revenueGenerated: number; + // netProfit: number; + // productionCapacity: number; + // paybackPeriod: number; + // // netLoss: number; + // machineIdleTime: number; + // machineActiveTime: number; + // throughputData: number; + // }; + simulationData: { + roiPercentage: number; + netProfit: number; + productionCapacity: number; + paybackPeriod: number; + machineIdleTime: number; + machineActiveTime: number; + throughputData: number; + simulationTime?: number; + simulationCost?: number; + efficiencyScore?: number; + }; +} +const calculateSimulationData = (assets: AssetData[]) => { + let totalActiveTime = 0; + let totalIdleTime = 0; + let throughput = 0; + let productionCapacity = 0; + let simulationCost = 0; + // Cost weight per type (example values, adjust as needed) + const costWeight: Record = { + roboticArm: 50, + machine: 100, + human: 30, + transfer: 20, + storageUnit: 10, + }; + const energyUsage = assets.filter((a) => a.type === "human").reduce((sum, a) => sum + a.activeTime * 1, 0); + + assets.forEach((asset) => { + totalActiveTime += asset.activeTime; + totalIdleTime += asset.idleTime; + + if (asset.activeTime > 0) throughput += 1; + + productionCapacity += asset.activeTime; + simulationCost += asset.activeTime * (costWeight[asset.type] || 10); + }); + + const machineActiveTime = assets.filter((a) => a.type === "machine").reduce((acc, a) => acc + a.activeTime, 0); + + const machineIdleTime = assets.filter((a) => a.type === "machine").reduce((acc, a) => acc + a.idleTime, 0); + + const simulationTime = totalActiveTime + totalIdleTime; + + // --- Efficiency Score --- + // Weighted formula: lower cost + lower time => higher score + // Example formula (normalize to 0–100): + const efficiencyScore = Math.max( + 0, + 100 - + (simulationTime / 1000) * 0.5 - // weight 0.5 for time + (simulationCost / 1000) * 0.5 // weight 0.5 for cost + ); + + return { + throughputData: throughput, + machineActiveTime, + machineIdleTime, + productionCapacity, + netProfit: 0, // placeholder + roiPercentage: 0, // placeholder + paybackPeriod: 0, // placeholder + simulationTime, + simulationCost, + efficiencyScore, + energyUsage, + }; +}; + +export const createCompareProduct = (productUuid: string, productName: string, assets: AssetData[]): CompareProduct => ({ + productUuid, + productName, + simulationData: calculateSimulationData(assets), +}); function ComparisonScene() { const { isPlaying } = usePlayButtonStore(); const { productStore, versionStore } = useSceneContext(); @@ -18,8 +121,10 @@ function ComparisonScene() { const { comparisonProduct, setComparisonProduct } = useComparisonProduct(); const { mainProduct } = useMainProduct(); const { loadingProgress } = useLoadingProgress(); - const { compareProductsData } = useCompareProductDataStore(); + const { projectId } = useParams(); + const { compareProductsData, setCompareProductsData } = useCompareProductDataStore(); const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false); + console.log("shouldShowComparisonResult: ", shouldShowComparisonResult); const handleSelectVersion = (option: string) => { const version = versionHistory.find((version) => version.versionName === option); @@ -35,19 +140,43 @@ function ComparisonScene() { } }; + // useEffect(() => { + // if (mainProduct && comparisonProduct && compareProductsData.length > 1) { + // const hasMain = compareProductsData.some((val) => val.productUuid === mainProduct.productUuid); + // const hasComparison = compareProductsData.some((val) => val.productUuid === comparisonProduct.productUuid); + // if (hasMain && hasComparison && mainProduct.productUuid !== comparisonProduct.productUuid) { + // setShouldShowComparisonResult(true); + // } else { + // setShouldShowComparisonResult(false); + // } + // } else { + // setShouldShowComparisonResult(false); + // } + // }, [compareProductsData, mainProduct, comparisonProduct]); + useEffect(() => { - if (mainProduct && comparisonProduct && compareProductsData.length > 1) { - const hasMain = compareProductsData.some((val) => val.productUuid === mainProduct.productUuid); - const hasComparison = compareProductsData.some((val) => val.productUuid === comparisonProduct.productUuid); - if (hasMain && hasComparison && mainProduct.productUuid !== comparisonProduct.productUuid) { - setShouldShowComparisonResult(true); - } else { + // const selectedProductData = getProductById(selectedProduct.productUuid); + if (mainProduct && comparisonProduct && selectedVersion) { + const product1 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, mainProduct.productUuid); + + const product2 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, comparisonProduct.productUuid); + + const compareProduct1 = createCompareProduct(product1?.productId ?? "", mainProduct.productName, product1?.simulateData || []); + const compareProduct2 = createCompareProduct(product2?.productId ?? "", comparisonProduct.productName, product2?.simulateData || []); + + const comparedArray = [compareProduct1, compareProduct2]; + console.log("comparedArray: ", comparedArray); + + if (product1 === undefined || product2 === undefined) { setShouldShowComparisonResult(false); + } else if (comparedArray.length === 2) { + setCompareProductsData(comparedArray); + setShouldShowComparisonResult(true); } } else { setShouldShowComparisonResult(false); } - }, [compareProductsData, mainProduct, comparisonProduct]); + }, [mainProduct, comparisonProduct, selectedVersion, projectId, setCompareProductsData]); return ( <> diff --git a/app/src/components/layout/sidebarRight/simulation/Simulations.tsx b/app/src/components/layout/sidebarRight/simulation/Simulations.tsx index 55869be..8b82ff3 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 } from "../../../../store/builder/store"; +import { useCompareStore, useIsComparing, useSimulateId } from "../../../../store/builder/store"; import { useToggleStore } from "../../../../store/ui/useUIToggleStore"; import { useParams } from "react-router-dom"; import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { getSimulationData, updateSimulateData } from "../../scenes/functions/simulationStorage"; +import { get } from "http"; interface Event { modelName: string; @@ -38,11 +39,21 @@ const Simulations: React.FC = () => { const { selectedVersion } = versionStore(); const { comparePopUp, setComparePopUp } = useCompareStore(); const { setIsComparing } = useIsComparing(); + const { simulateId } = useSimulateId(); - const handleSaveVersion = () => { + const handleSaveVersion = async () => { setIsComparing(true); setComparePopUp(false); setToggleUI(false, false); + const singleData = { + projectId: projectId, + versionId: selectedVersion?.versionId || "", + productUuid: selectedProduct?.productUuid || "", + simulatedId: simulateId, + }; + console.log("singleData: ", singleData); + const getData = await updateSimulateData(singleData); + echo.log(getData.message); }; const handleAddProduct = () => { diff --git a/app/src/modules/simulation/simulator/simulator.tsx b/app/src/modules/simulation/simulator/simulator.tsx index 0683e08..56d640c 100644 --- a/app/src/modules/simulation/simulator/simulator.tsx +++ b/app/src/modules/simulation/simulator/simulator.tsx @@ -7,15 +7,18 @@ import SimulationHandler from "./SimulationHandler"; 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"; function Simulator() { - const { productStore,versionStore } = useSceneContext(); + const { productStore, versionStore } = useSceneContext(); const { products, getProductById, selectedProduct } = productStore(); const { handleAction } = useActionHandler(); const { isPlaying } = usePlayButtonStore(); const { isReset } = useResetButtonStore(); const { projectId } = useParams(); const { selectedVersion } = versionStore(); + const { setSimulateId } = useSimulateId(); + const { addSimulationRecords } = useSimulationManager(); useEffect(() => { if (!isPlaying || isReset || !selectedProduct.productUuid) return; @@ -37,7 +40,17 @@ function Simulator() { 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 + ); + echo.log("Simulation data is up to date"); return; } else { //call create API diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index e0cce35..560a141 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -3,17 +3,12 @@ import { io } from "socket.io-client"; import * as CONSTANTS from "../../types/world/worldConstants"; export const useSocketStore = create((set: any, get: any) => ({ - socket: null, - initializeSocket: ( - email?: string, - organization?: string, - token?: string, - refreshToken?: string - ) => { - const existingSocket = get().socket; - if (existingSocket) { - return; - } + socket: null, + initializeSocket: (email?: string, organization?: string, token?: string, refreshToken?: string) => { + const existingSocket = get().socket; + if (existingSocket) { + return; + } const socket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`, { reconnection: true, @@ -38,24 +33,24 @@ export const useSocketStore = create((set: any, get: any) => ({ auth: { token, refreshToken }, }); - set({ - socket, - visualizationSocket, - dashBoardSocket, - projectSocket, - threadSocket, - }); - }, - disconnectSocket: () => { - set((state: any) => { - state.socket?.disconnect(); - state.visualizationSocket?.disconnect(); - state.dashBoardSocket?.disconnect(); - state.projectSocket?.disconnect(); - state.threadSocket?.disconnect(); - return { socket: null }; - }); - }, + set({ + socket, + visualizationSocket, + dashBoardSocket, + projectSocket, + threadSocket, + }); + }, + disconnectSocket: () => { + set((state: any) => { + state.socket?.disconnect(); + state.visualizationSocket?.disconnect(); + state.dashBoardSocket?.disconnect(); + state.projectSocket?.disconnect(); + state.threadSocket?.disconnect(); + return { socket: null }; + }); + }, })); export const useLoadingProgress = create<{ @@ -67,8 +62,8 @@ export const useLoadingProgress = create<{ })); export const useOrganization = create((set: any) => ({ - organization: "", - setOrganization: (x: any) => set(() => ({ organization: x })), + organization: "", + setOrganization: (x: any) => set(() => ({ organization: x })), })); export const useToggleView = create((set: any) => ({ @@ -93,18 +88,18 @@ export const useSelectedItem = create((set: any) => ({ })); type DroppedDecalType = { - category: string; - decalName: string; - decalImage: string; - decalId: string; + category: string; + decalName: string; + decalImage: string; + decalId: string; }; export const useDroppedDecal = create<{ - droppedDecal: DroppedDecalType | null; - setDroppedDecal: (x: DroppedDecalType | null) => void; + droppedDecal: DroppedDecalType | null; + setDroppedDecal: (x: DroppedDecalType | null) => void; }>((set) => ({ - droppedDecal: null, - setDroppedDecal: (x) => set({ droppedDecal: x }), + droppedDecal: null, + setDroppedDecal: (x) => set({ droppedDecal: x }), })); export const useNavMesh = create((set: any) => ({ @@ -113,18 +108,18 @@ export const useNavMesh = create((set: any) => ({ })); export const useLayers = create((set: any) => ({ - Layers: 1, - setLayers: (x: any) => set(() => ({ Layers: x })), + Layers: 1, + setLayers: (x: any) => set(() => ({ Layers: x })), })); export const useCamPosition = create((set: any) => ({ - camPosition: { x: undefined, y: undefined, z: undefined }, - setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), + camPosition: { x: undefined, y: undefined, z: undefined }, + setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }), })); export const useMenuVisible = create((set: any) => ({ - menuVisible: false, - setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), + menuVisible: false, + setMenuVisible: (x: any) => set(() => ({ menuVisible: x })), })); export const useToolMode = create((set: any) => ({ @@ -133,8 +128,8 @@ export const useToolMode = create((set: any) => ({ })); export const useSetScale = create((set: any) => ({ - scale: null, - setScale: (x: any) => set(() => ({ scale: x })), + scale: null, + setScale: (x: any) => set(() => ({ scale: x })), })); export const useRoofVisibility = create((set: any) => ({ @@ -158,13 +153,13 @@ export const useSunPosition = create((set: any) => ({ })); export const useRemoveLayer = create((set: any) => ({ - removeLayer: false, - setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), + removeLayer: false, + setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })), })); export const useRemovedLayer = create((set: any) => ({ - removedLayer: null, - setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), + removedLayer: null, + setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })), })); export const useProjectName = create((set: any) => ({ @@ -321,9 +316,8 @@ export const useTileDistance = create((set: any) => ({ })); export const usePlayAgv = create((set, get) => ({ - PlayAgv: [], - setPlayAgv: (updateFn: (prev: any[]) => any[]) => - set({ PlayAgv: updateFn(get().PlayAgv) }), + PlayAgv: [], + setPlayAgv: (updateFn: (prev: any[]) => any[]) => set({ PlayAgv: updateFn(get().PlayAgv) }), })); // Define the Asset type @@ -522,22 +516,34 @@ function getInitialViewSceneLabels(): boolean { export interface CompareProduct { productUuid: string; productName: string; + // simulationData: { + // // costPerUnit: number; + // // workingDaysPerYear: number; + // // shiftLength: number; + // // shiftsPerDay: number; + // roiPercentage: number; + // // paybackPeriod: number; + // // totalCost: number; + // // revenueGenerated: number; + // netProfit: number; + // productionCapacity: number; + // paybackPeriod: number; + // // netLoss: number; + // machineIdleTime: number; + // machineActiveTime: number; + // throughputData: number; + // }; simulationData: { - // costPerUnit: number; - // workingDaysPerYear: number; - // shiftLength: number; - // shiftsPerDay: number; roiPercentage: number; - // paybackPeriod: number; - // totalCost: number; - // revenueGenerated: number; netProfit: number; productionCapacity: number; paybackPeriod: number; - // netLoss: number; machineIdleTime: number; machineActiveTime: number; throughputData: number; + simulationTime?: number; + simulationCost?: number; + efficiencyScore?: number; }; } @@ -564,8 +570,8 @@ export const useSelectedPath = create((set: any) => ({ })); export const useContextActionStore = create((set: any) => ({ - contextAction: null, - setContextAction: (x: any) => set({ contextAction: x }), + contextAction: null, + setContextAction: (x: any) => set({ contextAction: x }), })); // Define the store's state and actions type diff --git a/app/src/store/rough/useSimulationManagerStore.ts b/app/src/store/rough/useSimulationManagerStore.ts index 77b6d5a..3be1ca9 100644 --- a/app/src/store/rough/useSimulationManagerStore.ts +++ b/app/src/store/rough/useSimulationManagerStore.ts @@ -31,7 +31,7 @@ interface SimulationManagerStore { simulationRecords: ProjectSimulation[]; 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; getProjectById: (projectId: string | undefined) => ProjectSimulation | undefined; getVersionById: (projectId: string | undefined, versionId: string) => VersionSimulation | undefined; @@ -85,6 +85,52 @@ export const useSimulationManager = create((set, get) => } } + return { simulationRecords: projects }; + }), + addSimulationRecords: (projectId, versionId, productId, records) => + 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, ...records] } : product)), + }; + }), + }; + }); + + // same creation logic for new project/version/product + if (!state.simulationRecords.find((p) => p.projectId === projectId)) { + projects.push({ + projectId, + versions: [ + { + versionId, + products: [{ productId, simulateData: [...records] }], + }, + ], + }); + } else { + const project = projects.find((p) => p.projectId === projectId)!; + if (!project.versions.find((v) => v.versionId === versionId)) { + project.versions.push({ + versionId, + products: [{ productId, simulateData: [...records] }], + }); + } else { + const version = project.versions.find((v) => v.versionId === versionId)!; + if (!version.products.find((p) => p.productId === productId)) { + version.products.push({ productId, simulateData: [...records] }); + } + } + } + return { simulationRecords: projects }; }),