Refactor simulation product handling and state management

- Replaced `useComparisonProduct` with `useSimulationState` in multiple components to streamline state management.
- Updated `SyncCam` to use `comparisonScene` instead of `comparisonProduct`.
- Modified `Products` component to utilize `mainScene` and `comparisonScene` for product selection.
- Adjusted various simulation functions to accept `ProductsSchema` instead of `productsSchema`.
- Enhanced `Simulator` component to fetch simulation data using the updated state structure.
- Refined Zustand store to manage `mainScene` and `comparisonScene` states, including their respective setters and clearers.
- Updated type definitions for products to ensure consistency across the application.
- Cleaned up shortcut key handling to reflect changes in state management.
This commit is contained in:
2025-09-08 11:40:27 +05:30
parent c8e9633050
commit 80a672adf0
20 changed files with 637 additions and 640 deletions

View File

@@ -1,5 +1,5 @@
import { useCompareProductDataStore, useLoadingProgress, useIsComparing } from "../../../store/builder/store"; import { useCompareProductDataStore, useLoadingProgress, useIsComparing } from "../../../store/builder/store";
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore"; import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useSceneContext } from "../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../modules/scene/sceneContext";
@@ -9,12 +9,14 @@ import ComparisonResult from "../../ui/compareVersion/ComparisonResult";
import RegularDropDown from "../../ui/inputs/RegularDropDown"; import RegularDropDown from "../../ui/inputs/RegularDropDown";
import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore"; import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
type AssetData = { type AssetData = {
activeTime: number; activeTime: number;
idleTime: number; idleTime: number;
type: string; type: string;
assetId: string; assetId: string;
}; };
export interface CompareProduct { export interface CompareProduct {
productUuid: string; productUuid: string;
productName: string; productName: string;
@@ -48,6 +50,7 @@ export interface CompareProduct {
efficiencyScore?: number; efficiencyScore?: number;
}; };
} }
const calculateSimulationData = (assets: AssetData[]) => { const calculateSimulationData = (assets: AssetData[]) => {
let totalActiveTime = 0; let totalActiveTime = 0;
let totalIdleTime = 0; let totalIdleTime = 0;
@@ -111,6 +114,7 @@ export const createCompareProduct = (productUuid: string, productName: string, a
productName, productName,
simulationData: calculateSimulationData(assets), simulationData: calculateSimulationData(assets),
}); });
function ComparisonScene() { function ComparisonScene() {
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { productStore, versionStore } = useSceneContext(); const { productStore, versionStore } = useSceneContext();
@@ -118,13 +122,11 @@ function ComparisonScene() {
const { products, selectedProduct } = productStore(); const { products, selectedProduct } = productStore();
const { isComparing } = useIsComparing(); const { isComparing } = useIsComparing();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { comparisonProduct, setComparisonProduct } = useComparisonProduct(); const { mainScene, comparisonScene, setComparisonState } = useSimulationState();
const { mainProduct } = useMainProduct();
const { loadingProgress } = useLoadingProgress(); const { loadingProgress } = useLoadingProgress();
const { projectId } = useParams(); const { projectId } = useParams();
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore(); const { setCompareProductsData } = useCompareProductDataStore();
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false); const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
console.log("shouldShowComparisonResult: ", shouldShowComparisonResult);
const handleSelectVersion = (option: string) => { const handleSelectVersion = (option: string) => {
const version = versionHistory.find((version) => version.versionName === option); const version = versionHistory.find((version) => version.versionName === option);
@@ -135,8 +137,14 @@ function ComparisonScene() {
const handleSelectProduct = (option: string) => { const handleSelectProduct = (option: string) => {
const product = products.find((product) => product.productName === option); const product = products.find((product) => product.productName === option);
if (product) { if (product && selectedVersion) {
setComparisonProduct(product.productUuid, product.productName); const data = {
productUuid: product.productUuid,
productName: product.productName,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setComparisonState(data);
} }
}; };
@@ -156,16 +164,15 @@ function ComparisonScene() {
useEffect(() => { useEffect(() => {
// const selectedProductData = getProductById(selectedProduct.productUuid); // const selectedProductData = getProductById(selectedProduct.productUuid);
if (mainProduct && comparisonProduct && selectedVersion) { if (mainScene && comparisonScene && selectedVersion) {
const product1 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, mainProduct.productUuid); const product1 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, mainScene.product.productUuid);
const product2 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, comparisonProduct.productUuid); const product2 = useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, comparisonScene.product.productUuid);
const compareProduct1 = createCompareProduct(product1?.productId ?? "", mainProduct.productName, product1?.simulateData || []); const compareProduct1 = createCompareProduct(product1?.productId ?? "", mainScene.product.productName, product1?.simulateData || []);
const compareProduct2 = createCompareProduct(product2?.productId ?? "", comparisonProduct.productName, product2?.simulateData || []); const compareProduct2 = createCompareProduct(product2?.productId ?? "", comparisonScene.product.productName, product2?.simulateData || []);
const comparedArray = [compareProduct1, compareProduct2]; const comparedArray = [compareProduct1, compareProduct2];
console.log("comparedArray: ", comparedArray);
if (product1 === undefined || product2 === undefined) { if (product1 === undefined || product2 === undefined) {
setShouldShowComparisonResult(false); setShouldShowComparisonResult(false);
@@ -176,7 +183,7 @@ function ComparisonScene() {
} else { } else {
setShouldShowComparisonResult(false); setShouldShowComparisonResult(false);
} }
}, [mainProduct, comparisonProduct, selectedVersion, projectId, setCompareProductsData]); }, [mainScene, comparisonScene, selectedVersion, projectId, setCompareProductsData]);
return ( return (
<> <>

View File

@@ -7,7 +7,7 @@ import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore"
import { useFloatingWidget } from "../../../store/visualization/useDroppedObjectsStore"; import { useFloatingWidget } from "../../../store/visualization/useDroppedObjectsStore";
import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore"; import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore";
import { createHandleDrop } from "../../../modules/visualization/functions/handleUiDrop"; import { createHandleDrop } from "../../../modules/visualization/functions/handleUiDrop";
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import { useSceneContext } from "../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../modules/scene/sceneContext";
import { useBuilderStore } from "../../../store/builder/useBuilderStore"; import { useBuilderStore } from "../../../store/builder/useBuilderStore";
import useRestStates from "../../../hooks/useResetStates"; import useRestStates from "../../../hooks/useResetStates";
@@ -35,7 +35,7 @@ import { setAssetsApi } from "../../../services/factoryBuilder/asset/floorAsset/
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi"; import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
function MainScene() { function MainScene() {
const { setMainProduct } = useMainProduct(); const { setMainState, clearComparisonState } = useSimulationState();
const { isComparing, setIsComparing } = useIsComparing(); const { isComparing, setIsComparing } = useIsComparing();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { selectedUser } = useSelectedUserStore(); const { selectedUser } = useSelectedUserStore();
@@ -46,7 +46,6 @@ function MainScene() {
const { visualizationSocket } = useSocketStore(); const { visualizationSocket } = useSocketStore();
const { selectedZone } = useSelectedZoneStore(); const { selectedZone } = useSelectedZoneStore();
const { setFloatingWidget } = useFloatingWidget(); const { setFloatingWidget } = useFloatingWidget();
const { clearComparisonProduct } = useComparisonProduct();
const { selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore(); const { selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore();
const { assetStore, productStore, versionStore } = useSceneContext(); const { assetStore, productStore, versionStore } = useSceneContext();
const { products, selectedProduct } = productStore(); const { products, selectedProduct } = productStore();
@@ -62,14 +61,15 @@ function MainScene() {
return () => { return () => {
resetStates(); resetStates();
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
useEffect(() => { useEffect(() => {
if (activeModule !== "simulation") { if (activeModule !== "simulation") {
clearComparisonProduct(); clearComparisonState();
setIsComparing(false); setIsComparing(false);
} }
}, [activeModule, clearComparisonProduct, setIsComparing]); }, [activeModule, clearComparisonState, setIsComparing]);
useEffect(() => { useEffect(() => {
if (!projectId) return; if (!projectId) return;
@@ -120,8 +120,14 @@ function MainScene() {
const handleSelectProduct = (option: string) => { const handleSelectProduct = (option: string) => {
const product = products.find((product) => product.productName === option); const product = products.find((product) => product.productName === option);
if (product) { if (product && selectedVersion) {
setMainProduct(product.productUuid, product.productName); const data = {
productUuid: product.productUuid,
productName: product.productName,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setMainState(data);
} }
}; };

View File

@@ -1,4 +1,5 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`; let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
interface SimulationData { interface SimulationData {
key: string; key: string;
data?: object | any; data?: object | any;
@@ -28,6 +29,7 @@ interface ProjectSimulation {
projectId: string | undefined; projectId: string | undefined;
versions: VersionSimulation[]; versions: VersionSimulation[];
} }
export const saveSimulationData = async (data: any) => { export const saveSimulationData = async (data: any) => {
try { try {
const response = await fetch(`${url_Backend_dwinzo}/api/V1/SimulatedUpsert`, { const response = await fetch(`${url_Backend_dwinzo}/api/V1/SimulatedUpsert`, {
@@ -59,8 +61,9 @@ export const saveSimulationData = async (data: any) => {
} }
} }
}; };
export const updateSimulateData = async (data: any) => { export const updateSimulateData = async (data: any) => {
console.log("data: update", data); // console.log("data: update", data);
try { try {
const response = await fetch(`${url_Backend_dwinzo}/api/V1/ValidateSimulated`, { const response = await fetch(`${url_Backend_dwinzo}/api/V1/ValidateSimulated`, {
method: "POST", method: "POST",
@@ -91,10 +94,16 @@ export const updateSimulateData = async (data: any) => {
} }
} }
}; };
export const getSimulationData = async (projectId: string, versionId: string, productUuid: string) => { export const getSimulationData = async (
console.log("called"); projectId: string,
versionId: string,
productUuid: string
) => {
// console.log("called");
try { try {
const response = await fetch(`${url_Backend_dwinzo}/api/V1/SimulatedDatas/${projectId}/${versionId}?productUuid=${productUuid}`, { const response = await fetch(
`${url_Backend_dwinzo}/api/V1/SimulatedDatas/${projectId}/${versionId}?productUuid=${productUuid}`,
{
method: "GET", method: "GET",
headers: { headers: {
Authorization: "Bearer <access_token>", Authorization: "Bearer <access_token>",
@@ -102,7 +111,8 @@ export const getSimulationData = async (projectId: string, versionId: string, pr
token: localStorage.getItem("token") || "", token: localStorage.getItem("token") || "",
refresh_token: localStorage.getItem("refreshToken") || "", refresh_token: localStorage.getItem("refreshToken") || "",
}, },
}); }
);
console.log("response: ", response); console.log("response: ", response);

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
import { AddIcon, ArrowIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons"; import { AddIcon, ArrowIcon, RemoveIcon, ResizeHeightIcon } from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput"; import RenameInput from "../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../functions/handleResizePannel"; import { handleResize } from "../../../../functions/handleResizePannel";
import { useMainProduct, useSelectedAsset } from "../../../../store/simulation/useSimulationStore"; import { useSimulationState, useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
import { generateUUID } from "three/src/math/MathUtils"; import { generateUUID } from "three/src/math/MathUtils";
import RenderOverlay from "../../../templates/Overlay"; import RenderOverlay from "../../../templates/Overlay";
import EditWidgetOption from "../../../ui/menu/EditWidgetOption"; import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
@@ -17,8 +17,7 @@ import { useCompareStore, useIsComparing, useSimulateId } from "../../../../stor
import { useToggleStore } from "../../../../store/ui/useUIToggleStore"; import { useToggleStore } from "../../../../store/ui/useUIToggleStore";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useSceneContext } from "../../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../../modules/scene/sceneContext";
import { getSimulationData, updateSimulateData } from "../../scenes/functions/simulationStorage"; import { updateSimulateData } from "../../scenes/functions/simulationStorage";
import { get } from "http";
interface Event { interface Event {
modelName: string; modelName: string;
@@ -35,7 +34,7 @@ const Simulations: React.FC = () => {
const [processes, setProcesses] = useState<Event[][]>(); const [processes, setProcesses] = useState<Event[][]>();
const { setToggleUI } = useToggleStore(); const { setToggleUI } = useToggleStore();
const { projectId } = useParams(); const { projectId } = useParams();
const { setMainProduct } = useMainProduct(); const { setMainState, clearMainState } = useSimulationState();
const { selectedVersion } = versionStore(); const { selectedVersion } = versionStore();
const { comparePopUp, setComparePopUp } = useCompareStore(); const { comparePopUp, setComparePopUp } = useCompareStore();
const { setIsComparing } = useIsComparing(); const { setIsComparing } = useIsComparing();
@@ -51,7 +50,6 @@ const Simulations: React.FC = () => {
productUuid: selectedProduct?.productUuid || "", productUuid: selectedProduct?.productUuid || "",
simulatedId: simulateId, simulatedId: simulateId,
}; };
console.log("singleData: ", singleData);
const getData = await updateSimulateData(singleData); const getData = await updateSimulateData(singleData);
echo.log(getData.message); echo.log(getData.message);
}; };
@@ -74,17 +72,23 @@ const Simulations: React.FC = () => {
const updatedProducts = products.filter((p) => p.productUuid !== productUuid); const updatedProducts = products.filter((p) => p.productUuid !== productUuid);
if (isSelected) { if (isSelected && selectedVersion) {
if (updatedProducts.length > 0) { if (updatedProducts.length > 0) {
let newSelectedIndex = currentIndex; let newSelectedIndex = currentIndex;
if (currentIndex >= updatedProducts.length) { if (currentIndex >= updatedProducts.length) {
newSelectedIndex = updatedProducts.length - 1; newSelectedIndex = updatedProducts.length - 1;
} }
setSelectedProduct(updatedProducts[newSelectedIndex].productUuid, updatedProducts[newSelectedIndex].productName); setSelectedProduct(updatedProducts[newSelectedIndex].productUuid, updatedProducts[newSelectedIndex].productName);
setMainProduct(updatedProducts[newSelectedIndex].productUuid, updatedProducts[newSelectedIndex].productName); const data = {
productUuid: updatedProducts[newSelectedIndex].productUuid,
productName: updatedProducts[newSelectedIndex].productName,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setMainState(data);
} else { } else {
setSelectedProduct("", ""); setSelectedProduct("", "");
setMainProduct("", ""); clearMainState();
} }
} }
@@ -99,9 +103,15 @@ const Simulations: React.FC = () => {
const handleRenameProduct = (productUuid: string, newName: string) => { const handleRenameProduct = (productUuid: string, newName: string) => {
renameProduct(productUuid, newName); renameProduct(productUuid, newName);
renameProductApi({ productName: newName, productUuid, projectId: projectId || "", versionId: selectedVersion?.versionId || "" }); renameProductApi({ productName: newName, productUuid, projectId: projectId || "", versionId: selectedVersion?.versionId || "" });
if (selectedProduct.productUuid === productUuid) { if (selectedProduct.productUuid === productUuid && selectedVersion) {
setSelectedProduct(productUuid, newName); setSelectedProduct(productUuid, newName);
setMainProduct(productUuid, newName); const data = {
productUuid: productUuid,
productName: newName,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setMainState(data);
} }
}; };
@@ -136,7 +146,7 @@ const Simulations: React.FC = () => {
}); });
} }
}, [selectedProduct.productUuid, products]); }, [selectedProduct.productUuid, products]);
//call when comparePopup is true
useEffect(() => { useEffect(() => {
if (comparePopUp || selectedProduct.productUuid) { if (comparePopUp || selectedProduct.productUuid) {
} }
@@ -173,8 +183,16 @@ const Simulations: React.FC = () => {
<div <div
className="value" className="value"
onClick={() => { onClick={() => {
if (selectedVersion) {
setSelectedProduct(product.productUuid, product.productName); setSelectedProduct(product.productUuid, product.productName);
setMainProduct(product.productUuid, product.productName); const data = {
productUuid: product.productUuid,
productName: product.productName,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setMainState(data);
}
}} }}
> >
<input type="radio" name="products" checked={selectedProduct.productUuid === product.productUuid} readOnly /> <input type="radio" name="products" checked={selectedProduct.productUuid === product.productUuid} readOnly />

View File

@@ -4,7 +4,7 @@ import { LogoIconLarge } from "../icons/Logo";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useProjectName } from "../../store/builder/store"; import { useProjectName } from "../../store/builder/store";
import { getAllProjects } from "../../services/dashboard/getAllProjects"; import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { useComparisonProduct } from "../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../store/simulation/useSimulationStore";
import { getUserData } from "../../functions/getUserData"; import { getUserData } from "../../functions/getUserData";
import { sharedWithMeProjects } from "../../services/dashboard/sharedWithMeProject"; import { sharedWithMeProjects } from "../../services/dashboard/sharedWithMeProject";
@@ -15,10 +15,11 @@ interface LoadingPageProps {
const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => { const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const { projectName, setProjectName } = useProjectName(); const { projectName, setProjectName } = useProjectName();
const { projectId } = useParams(); const { projectId } = useParams();
const { comparisonProduct } = useComparisonProduct(); const { comparisonScene } = useSimulationState();
const { userId, organization } = getUserData(); const { userId, organization } = getUserData();
const validatedProgress = Math.min(100, Math.max(0, progress)); const validatedProgress = Math.min(100, Math.max(0, progress));
useEffect(() => { useEffect(() => {
if (!userId) { if (!userId) {
console.error("User data not found in localStorage"); console.error("User data not found in localStorage");
@@ -32,13 +33,10 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const allProjects = [...(projects?.Projects || []), ...(shared || [])]; const allProjects = [...(projects?.Projects || []), ...(shared || [])];
const matchedProject = allProjects.find( const matchedProject = allProjects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
(val: any) => val.projectUuid === projectId || val._id === projectId
);
if (matchedProject) { if (matchedProject) {
setProjectName(matchedProject.projectName); setProjectName(matchedProject.projectName);
} else { } else {
console.warn("Project not found with given ID:", projectId); console.warn("Project not found with given ID:", projectId);
} }
@@ -48,14 +46,12 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
}; };
fetchProjects(); fetchProjects();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
return ( return (
<RenderOverlay> <RenderOverlay>
<div <div className={`loading-wrapper ${comparisonScene != null ? "comparisionLoading" : ""}`}>
className={`loading-wrapper ${comparisonProduct != null ? "comparisionLoading" : ""
}`}
>
<div className="loading-container"> <div className="loading-container">
<div className="project-name">{projectName}</div> <div className="project-name">{projectName}</div>
<div className="loading-hero-container"> <div className="loading-hero-container">

View File

@@ -2,7 +2,7 @@ import { useParams } from "react-router-dom";
import React, { useState, useRef, useEffect, Suspense } from "react"; import React, { useState, useRef, useEffect, Suspense } from "react";
import { CompareLayoutIcon, LayoutIcon, ResizerIcon } from "../../icons/SimulationIcons"; import { CompareLayoutIcon, LayoutIcon, ResizerIcon } from "../../icons/SimulationIcons";
import { useLoadingProgress, useIsComparing } from "../../../store/builder/store"; import { useLoadingProgress, useIsComparing } from "../../../store/builder/store";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore"; import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
import { useSceneContext } from "../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../modules/scene/sceneContext";
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi"; import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
@@ -14,7 +14,7 @@ import useRestStates from "../../../hooks/useResetStates";
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi"; import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
const CompareLayOut = () => { const CompareLayOut = () => {
const { clearComparisonProduct, comparisonProduct, setComparisonProduct } = useComparisonProduct(); const { clearComparisonState, comparisonScene, setComparisonState } = useSimulationState();
const { versionStore } = useSceneContext(); const { versionStore } = useSceneContext();
const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion, setVersions } = versionStore(); const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion, setVersions } = versionStore();
const { setLoadingProgress } = useLoadingProgress(); const { setLoadingProgress } = useLoadingProgress();
@@ -32,11 +32,10 @@ const CompareLayOut = () => {
useEffect(() => { useEffect(() => {
return () => { return () => {
if (selectedVersion?.versionId) {
resetStates(); resetStates();
}
}; };
}, [selectedVersion?.versionId]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => { useEffect(() => {
if (!projectId) return; if (!projectId) return;
@@ -63,10 +62,10 @@ const CompareLayOut = () => {
}, [projectId]); }, [projectId]);
useEffect(() => { useEffect(() => {
if (!comparisonProduct) { if (!comparisonScene) {
clearSelectedVersion(); clearSelectedVersion();
} }
}, [comparisonProduct]); }, [comparisonScene]);
OuterClick({ OuterClick({
contextClassName: ["displayLayouts-container", "selectLayout"], contextClassName: ["displayLayouts-container", "selectLayout"],
@@ -108,7 +107,7 @@ const CompareLayOut = () => {
if (finalWidthVw <= 10) { if (finalWidthVw <= 10) {
setWidth("0px"); setWidth("0px");
setIsComparing(false); setIsComparing(false);
clearComparisonProduct(); clearComparisonState();
setIsPlaying(false); setIsPlaying(false);
} else { } else {
setWidth(`${finalWidthVw}vw`); setWidth(`${finalWidthVw}vw`);
@@ -154,7 +153,13 @@ const CompareLayOut = () => {
getAllProductsApi(projectId || "", version.versionId || "").then((data) => { getAllProductsApi(projectId || "", version.versionId || "").then((data) => {
if (data && data.length > 0) { if (data && data.length > 0) {
setSelectedVersion(version); setSelectedVersion(version);
setComparisonProduct(data[0].productUuid, data[0].productName); const comparisonData = {
productUuid: data[0].productUuid,
productName: data[0].productName,
versionUuid: version.versionId,
versionName: version.versionName,
};
setComparisonState(comparisonData);
setLoadingProgress(1); setLoadingProgress(1);
} }
}); });

View File

@@ -1,10 +1,9 @@
import React, { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import PerformanceResult from "./result-card/PerformanceResult"; import PerformanceResult from "./result-card/PerformanceResult";
import EnergyUsage from "./result-card/EnergyUsage"; import { Bar, Pie } from "react-chartjs-2";
import { Bar, Line, Pie } from "react-chartjs-2";
import { useCompareProductDataStore } from "../../../store/builder/store"; import { useCompareProductDataStore } from "../../../store/builder/store";
// import { CompareProduct, useCompareProductDataStore } from "../../../store/builder/store"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
export interface CompareProduct { export interface CompareProduct {
productUuid: string; productUuid: string;
productName: string; productName: string;
@@ -21,16 +20,16 @@ export interface CompareProduct {
efficiencyScore?: number; efficiencyScore?: number;
}; };
} }
const ComparisonResult = () => { const ComparisonResult = () => {
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore(); const { compareProductsData } = useCompareProductDataStore();
const { comparisonProduct, setComparisonProduct } = useComparisonProduct(); const { comparisonScene, mainScene } = useSimulationState();
const { mainProduct } = useMainProduct();
const [comparedProducts, setComparedProducts] = useState<[CompareProduct, CompareProduct] | []>([]); const [comparedProducts, setComparedProducts] = useState<[CompareProduct, CompareProduct] | []>([]);
useEffect(() => { useEffect(() => {
if (compareProductsData.length > 0 && mainProduct && comparisonProduct) { if (compareProductsData.length > 0 && comparisonScene && mainScene) {
const mainProductData = compareProductsData.find((product) => product.productUuid === mainProduct.productUuid); const mainProductData = compareProductsData.find((product) => product.productUuid === mainScene.product.productUuid);
const comparisonProductData = compareProductsData.find((product) => product.productUuid === comparisonProduct.productUuid); const comparisonProductData = compareProductsData.find((product) => product.productUuid === comparisonScene.product.productUuid);
if (mainProductData && comparisonProductData) { if (mainProductData && comparisonProductData) {
setComparedProducts([mainProductData, comparisonProductData]); setComparedProducts([mainProductData, comparisonProductData]);
@@ -40,7 +39,7 @@ const ComparisonResult = () => {
} else { } else {
setComparedProducts([]); setComparedProducts([]);
} }
}, [compareProductsData, mainProduct, comparisonProduct]); }, [compareProductsData, comparisonScene, mainScene]);
useEffect(() => { useEffect(() => {
if (comparedProducts.length === 2) { if (comparedProducts.length === 2) {

View File

@@ -1,40 +1,16 @@
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, useProcessBar, useViewSceneStore } from "../../../store/builder/store";
comparsionMaterialData, import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from "../../../store/ui/usePlayButtonStore";
useActiveTool, import { DailyProductionIcon, EndIcon, ExpandIcon, EyeCloseIcon, HourlySimulationIcon, InfoIcon, MonthlyROI, SpeedIcon, StartIcon } from "../../icons/ExportCommonIcons";
useProcessBar,
useViewSceneStore,
} from "../../../store/builder/store";
import {
useAnimationPlaySpeed,
usePauseButtonStore,
usePlayButtonStore,
useResetButtonStore,
} from "../../../store/ui/usePlayButtonStore";
import {
DailyProductionIcon,
EndIcon,
ExpandIcon,
EyeCloseIcon,
HourlySimulationIcon,
InfoIcon,
MonthlyROI,
SpeedIcon,
StartIcon,
} from "../../icons/ExportCommonIcons";
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor"; import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
import useModuleStore, { import useModuleStore, { useSubModuleStore } from "../../../store/ui/useModuleStore";
useSubModuleStore,
} from "../../../store/ui/useModuleStore";
import ProductionCapacity from "../analysis/ThroughputSummary"; import ProductionCapacity from "../analysis/ThroughputSummary";
import ThroughputSummary from "../analysis/ProductionCapacity"; import ThroughputSummary from "../analysis/ProductionCapacity";
import ROISummary from "../analysis/ROISummary"; import ROISummary from "../analysis/ROISummary";
import { usePlayerStore } from "../../../store/ui/useUIToggleStore"; import { usePlayerStore } from "../../../store/ui/useUIToggleStore";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import InputToggle from "../inputs/InputToggle"; import InputToggle from "../inputs/InputToggle";
import { saveSimulationData } from "../../layout/scenes/functions/simulationStorage";
import { useSceneContext } from "../../../modules/scene/sceneContext";
const SimulationPlayer: React.FC = () => { const SimulationPlayer: React.FC = () => {
const MAX_SPEED = 8; // Maximum speed const MAX_SPEED = 8; // Maximum speed
@@ -50,13 +26,12 @@ const SimulationPlayer: React.FC = () => {
const { isPaused, setIsPaused } = usePauseButtonStore(); const { isPaused, setIsPaused } = usePauseButtonStore();
const { isReset, setReset } = useResetButtonStore(); const { isReset, setReset } = useResetButtonStore();
const { subModule } = useSubModuleStore(); const { subModule } = useSubModuleStore();
const { clearComparisonProduct } = useComparisonProduct(); const { clearComparisonState } = useSimulationState();
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore(); const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
const { materialData, setMaterialData } = comparsionMaterialData() const { materialData } = comparsionMaterialData();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { productStore } = useSceneContext();
const { selectedProduct, setSelectedProduct } = productStore();
useEffect(() => { useEffect(() => {
if (isReset) { if (isReset) {
setTimeout(() => { setTimeout(() => {
@@ -67,9 +42,9 @@ const SimulationPlayer: React.FC = () => {
useEffect(() => { useEffect(() => {
if (materialData.length === 0) return; if (materialData.length === 0) return;
console.log('materialData: ', materialData); // console.log("materialData: ", materialData);
// saveSimulationData({ key: selectedProduct.productUuid, data: materialData }); // saveSimulationData({ key: selectedProduct.productUuid, data: materialData });
}, [materialData]) }, [materialData]);
// Button functions // Button functions
const handleReset = () => { const handleReset = () => {
@@ -78,6 +53,7 @@ const SimulationPlayer: React.FC = () => {
setSpeed(1); setSpeed(1);
echo.info("Simulation RESET....."); echo.info("Simulation RESET.....");
}; };
const handlePlayStop = () => { const handlePlayStop = () => {
setIsPaused(!isPaused); setIsPaused(!isPaused);
if (isPaused) { if (isPaused) {
@@ -85,10 +61,11 @@ const SimulationPlayer: React.FC = () => {
} }
echo.warn(`Simulation is ${isPaused ? "Resumed" : "Paused"}`); echo.warn(`Simulation is ${isPaused ? "Resumed" : "Paused"}`);
}; };
const handleExit = () => { const handleExit = () => {
setIsPlaying(false); setIsPlaying(false);
setIsPaused(false); setIsPaused(false);
clearComparisonProduct(); clearComparisonState();
setActiveTool("cursor"); setActiveTool("cursor");
echo.info("Exit Simulation"); echo.info("Exit Simulation");
}; };
@@ -121,23 +98,23 @@ const SimulationPlayer: React.FC = () => {
}; };
const handleVisibility = () => { const handleVisibility = () => {
if (document.visibilityState !== 'visible' && isPlaying) { if (document.visibilityState !== "visible" && isPlaying) {
setIsPaused(!isPaused); setIsPaused(!isPaused);
if (isPaused) { if (isPaused) {
setIsPlaying(true); setIsPlaying(true);
} }
echo.warn(`Simulation is ${isPaused ? "Resumed" : "Paused"}`); echo.warn(`Simulation is ${isPaused ? "Resumed" : "Paused"}`);
} }
} };
useEffect(() => { useEffect(() => {
document.addEventListener("mousemove", handleMouseMove); document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp); document.addEventListener("mouseup", handleMouseUp);
document.addEventListener('visibilitychange', handleVisibility); document.addEventListener("visibilitychange", handleVisibility);
return () => { return () => {
document.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp); document.removeEventListener("mouseup", handleMouseUp);
document.removeEventListener('visibilitychange', handleVisibility); document.removeEventListener("visibilitychange", handleVisibility);
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
@@ -149,7 +126,7 @@ const SimulationPlayer: React.FC = () => {
const monthlyROI = 10; const monthlyROI = 10;
const { processBar } = useProcessBar(); const { processBar } = useProcessBar();
useEffect(() => { }, [processBar]); useEffect(() => {}, [processBar]);
const intervals = [50, 20, 30, 40, 50, 60]; // in minutes const intervals = [50, 20, 30, 40, 50, 60]; // in minutes
const totalSegments = intervals.length; const totalSegments = intervals.length;
@@ -190,13 +167,10 @@ const SimulationPlayer: React.FC = () => {
return ( return (
<> <>
{isPlaying && activeModule === "simulation" && ( {isPlaying && activeModule === "simulation" && (
<div className="label-toogler "> {/* bottom */} <div className="label-toogler ">
<InputToggle {" "}
value={viewSceneLabels} {/* bottom */}
inputKey="1" <InputToggle value={viewSceneLabels} inputKey="1" label="Enable View Labels" onClick={() => setViewSceneLabels(!viewSceneLabels)} />
label="Enable View Labels"
onClick={() => setViewSceneLabels(!viewSceneLabels)}
/>
</div> </div>
)} )}
<div className={`simulation-player-wrapper${hidePlayer ? " hide" : ""}`}> <div className={`simulation-player-wrapper${hidePlayer ? " hide" : ""}`}>
@@ -213,10 +187,7 @@ const SimulationPlayer: React.FC = () => {
<h4 className="label">ThroughPut</h4> <h4 className="label">ThroughPut</h4>
</div> </div>
<div className="progress-wrapper"> <div className="progress-wrapper">
<div <div className="progress" style={{ width: hourlySimulation }}></div>
className="progress"
style={{ width: hourlySimulation }}
></div>
</div> </div>
</div> </div>
{/* dailyProduction */} {/* dailyProduction */}
@@ -228,10 +199,7 @@ const SimulationPlayer: React.FC = () => {
<div className="label">Production Capacity</div> <div className="label">Production Capacity</div>
</div> </div>
<div className="progress-wrapper"> <div className="progress-wrapper">
<div <div className="progress" style={{ width: dailyProduction }}></div>
className="progress"
style={{ width: dailyProduction }}
></div>
</div> </div>
</div> </div>
{/* monthlyROI */} {/* monthlyROI */}
@@ -243,10 +211,7 @@ const SimulationPlayer: React.FC = () => {
<div className="label">ROI</div> <div className="label">ROI</div>
</div> </div>
<div className="progress-wrapper"> <div className="progress-wrapper">
<div <div className="progress" style={{ width: `${monthlyROI}%` }}></div>
className="progress"
style={{ width: `${monthlyROI}%` }}
></div>
</div>{" "} </div>{" "}
</div> </div>
</div> </div>
@@ -303,11 +268,7 @@ const SimulationPlayer: React.FC = () => {
{!hidePlayer && "Hide"} {!hidePlayer && "Hide"}
</button> </button>
{subModule === "analysis" && ( {subModule === "analysis" && (
<button <button id="simulation-expand-button" className="expand-icon-container" onClick={() => setExpand(!expand)}>
id="simulation-expand-button"
className="expand-icon-container"
onClick={() => setExpand(!expand)}
>
<ExpandIcon isActive={!expand} /> <ExpandIcon isActive={!expand} />
</button> </button>
)} )}
@@ -334,18 +295,9 @@ const SimulationPlayer: React.FC = () => {
<React.Fragment key={`${index}-${label}`}> <React.Fragment key={`${index}-${label}`}>
<div className="label-dot-wrapper"> <div className="label-dot-wrapper">
<div className="label">{label} mins</div> <div className="label">{label} mins</div>
<div <div className={`dot ${isFilled ? "filled" : ""}`}></div>
className={`dot ${isFilled ? "filled" : ""}`}
></div>
</div> </div>
{index < intervals.length - 1 && ( {index < intervals.length - 1 && <div className={`line ${progress >= ((index + 1) / totalSegments) * 100 ? "filled" : ""}`}></div>}
<div
className={`line ${progress >= ((index + 1) / totalSegments) * 100
? "filled"
: ""
}`}
></div>
)}
</React.Fragment> </React.Fragment>
); );
})} })}
@@ -381,24 +333,10 @@ const SimulationPlayer: React.FC = () => {
<div className="marker marker-90"></div> <div className="marker marker-90"></div>
<div className="custom-slider-wrapper"> <div className="custom-slider-wrapper">
<div className="custom-slider"> <div className="custom-slider">
<button <button id="slider-handle" className={`slider-handle ${isDragging ? "dragging" : ""}`} style={{ left: `${calculateHandlePosition()}%` }} onMouseDown={handleMouseDown}>
id="slider-handle"
className={`slider-handle ${isDragging ? "dragging" : ""
}`}
style={{ left: `${calculateHandlePosition()}%` }}
onMouseDown={handleMouseDown}
>
{speed.toFixed(1)}x {speed.toFixed(1)}x
</button> </button>
<input <input type="range" min="0.5" max={MAX_SPEED} step="0.1" value={speed} onChange={handleSpeedChange} className="slider-input" />
type="range"
min="0.5"
max={MAX_SPEED}
step="0.1"
value={speed}
onChange={handleSpeedChange}
className="slider-input"
/>
</div> </div>
<div className="speed-label max-value">{MAX_SPEED}x</div> <div className="speed-label max-value">{MAX_SPEED}x</div>
</div> </div>
@@ -410,16 +348,9 @@ const SimulationPlayer: React.FC = () => {
<div className="processDisplayer"> <div className="processDisplayer">
<div className="start-displayer timmer">00:00</div> <div className="start-displayer timmer">00:00</div>
<div className="end-displayer timmer">24:00</div> <div className="end-displayer timmer">24:00</div>
<div <div className="process-wrapper" style={{ padding: expand ? "0px" : "5px 35px" }}>
className="process-wrapper"
style={{ padding: expand ? "0px" : "5px 35px" }}
>
{/* eslint-disable-next-line */} {/* eslint-disable-next-line */}
<div <div className="process-container" ref={processWrapperRef} onMouseDown={handleProcessMouseDown}>
className="process-container"
ref={processWrapperRef}
onMouseDown={handleProcessMouseDown}
>
{processBar?.length > 0 ? ( {processBar?.length > 0 ? (
processBar.map((item: any, index: any) => ( processBar.map((item: any, index: any) => (
<div <div
@@ -430,11 +361,7 @@ const SimulationPlayer: React.FC = () => {
backgroundColor: getAvatarColor(index), backgroundColor: getAvatarColor(index),
}} }}
> >
<div <div className="process-player" ref={processPlayerRef} style={{ left: playerPosition, position: "absolute" }}></div>
className="process-player"
ref={processPlayerRef}
style={{ left: playerPosition, position: "absolute" }}
></div>
</div> </div>
)) ))
) : ( ) : (

View File

@@ -4,7 +4,7 @@ import { CameraControls } from "@react-three/drei";
import { useSceneContext } from "../sceneContext"; import { useSceneContext } from "../sceneContext";
import { useIsComparing } from "../../../store/builder/store"; import { useIsComparing } from "../../../store/builder/store";
import { useSceneStore } from "../../../store/scene/useSceneStore"; import { useSceneStore } from "../../../store/scene/useSceneStore";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import useModuleStore from "../../../store/ui/useModuleStore"; import useModuleStore from "../../../store/ui/useModuleStore";
import * as CONSTANTS from "../../../types/world/worldConstants"; import * as CONSTANTS from "../../../types/world/worldConstants";
@@ -14,7 +14,7 @@ function SyncCam() {
const { controls } = useThree(); const { controls } = useThree();
const { isComparing } = useIsComparing(); const { isComparing } = useIsComparing();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { comparisonProduct } = useComparisonProduct(); const { comparisonScene } = useSimulationState();
const { setCamera, camState } = useSceneStore(); const { setCamera, camState } = useSceneStore();
useFrame(() => { useFrame(() => {
@@ -25,7 +25,7 @@ function SyncCam() {
(controls as any).mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse; (controls as any).mouseButtons.middle = CONSTANTS.controlsTransition.middleMouse;
(controls as CameraControls).setLookAt(camState.position.x, camState.position.y, camState.position.z, camState.target.x, camState.target.y, camState.target.z, true); (controls as CameraControls).setLookAt(camState.position.x, camState.position.y, camState.position.z, camState.target.x, camState.target.y, camState.target.z, true);
} }
if (layout === "Main Layout" && controls && isComparing && activeModule === "simulation" && comparisonProduct) { if (layout === "Main Layout" && controls && isComparing && activeModule === "simulation" && comparisonScene) {
const position = (controls as CameraControls).getPosition(new Vector3()); const position = (controls as CameraControls).getPosition(new Vector3());
const target = (controls as CameraControls).getTarget(new Vector3()); const target = (controls as CameraControls).getTarget(new Vector3());
setCamera(position, target); setCamera(position, target);

View File

@@ -4,13 +4,12 @@ import { upsertProductOrEventApi } from "../../../services/simulation/products/U
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi"; import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
import { usePlayButtonStore, useResetButtonStore } from "../../../store/ui/usePlayButtonStore"; import { usePlayButtonStore, useResetButtonStore } from "../../../store/ui/usePlayButtonStore";
import { useSceneContext } from "../../scene/sceneContext"; import { useSceneContext } from "../../scene/sceneContext";
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../../store/simulation/useSimulationStore";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
function Products() { function Products() {
const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, craneStore, layout, productStore, versionStore } = useSceneContext(); const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, craneStore, layout, productStore, versionStore } = useSceneContext();
const { products, getProductById, addProduct, setProducts, selectedProduct, setSelectedProduct } = productStore(); const { products, getProductById, addProduct, setProducts, selectedProduct, setSelectedProduct } = productStore();
const { setMainProduct } = useMainProduct();
const { addVehicle, clearVehicles } = vehicleStore(); const { addVehicle, clearVehicles } = vehicleStore();
const { addArmBot, clearArmBots } = armBotStore(); const { addArmBot, clearArmBots } = armBotStore();
const { addMachine, clearMachines } = machineStore(); const { addMachine, clearMachines } = machineStore();
@@ -20,26 +19,25 @@ function Products() {
const { addCrane, addCurrentAction: addCurrentActionCrane, clearCranes } = craneStore(); const { addCrane, addCurrentAction: addCurrentActionCrane, clearCranes } = craneStore();
const { isReset } = useResetButtonStore(); const { isReset } = useResetButtonStore();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { mainProduct } = useMainProduct(); const { setMainState, mainScene, comparisonScene } = useSimulationState();
const { comparisonProduct } = useComparisonProduct();
const { selectedVersion } = versionStore(); const { selectedVersion } = versionStore();
const { projectId } = useParams(); const { projectId } = useParams();
useEffect(() => { useEffect(() => {
if (layout === "Main Layout" && mainProduct) { if (layout === "Main Layout" && mainScene) {
setSelectedProduct(mainProduct.productUuid, mainProduct.productName); setSelectedProduct(mainScene.product.productUuid, mainScene.product.productName);
} }
}, [mainProduct]); }, [mainScene, layout]);
useEffect(() => { useEffect(() => {
if (layout === "Comparison Layout" && comparisonProduct) { if (layout === "Comparison Layout" && comparisonScene) {
setSelectedProduct(comparisonProduct.productUuid, comparisonProduct.productName); setSelectedProduct(comparisonScene.product.productUuid, comparisonScene.product.productName);
} }
}, [comparisonProduct]); }, [comparisonScene, layout]);
useEffect(() => { useEffect(() => {
if (!selectedVersion) return; if (!selectedVersion) return;
getAllProductsApi(projectId || "", selectedVersion?.versionId || "") getAllProductsApi(projectId || "", selectedVersion.versionId)
.then((data) => { .then((data) => {
if (data && data.length === 0) { if (data && data.length === 0) {
const id = THREE.MathUtils.generateUUID(); const id = THREE.MathUtils.generateUUID();
@@ -49,17 +47,29 @@ function Products() {
productName: name, productName: name,
productUuid: id, productUuid: id,
projectId: projectId || "", projectId: projectId || "",
versionId: selectedVersion?.versionId || "", versionId: selectedVersion.versionId,
}); });
if (layout === "Main Layout") { if (layout === "Main Layout" && selectedVersion) {
setSelectedProduct(id, name); setSelectedProduct(id, name);
setMainProduct(id, name); const mainData = {
productUuid: id,
productName: name,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setMainState(mainData);
} }
} else { } else {
setProducts(data); setProducts(data);
if (layout === "Main Layout") { if (layout === "Main Layout") {
setSelectedProduct(data[0].productUuid, data[0].productName); setSelectedProduct(data[0].productUuid, data[0].productName);
setMainProduct(data[0].productUuid, data[0].productName); const mainData = {
productUuid: data[0].productUuid,
productName: data[0].productName,
versionUuid: selectedVersion.versionId,
versionName: selectedVersion.versionName,
};
setMainState(mainData);
} }
} }
}) })

View File

@@ -108,7 +108,7 @@ export function useCheckActiveRoboticArmsInSubsequence() {
} }
// Helper function to get machine sequences (simplified from your example) // Helper function to get machine sequences (simplified from your example)
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] { function determineExecutionMachineSequences(products: ProductsSchema): EventsSchema[][] {
const pointToEventMap = new Map<string, EventsSchema>(); const pointToEventMap = new Map<string, EventsSchema>();
const allPoints: PointsScheme[] = []; const allPoints: PointsScheme[] = [];

View File

@@ -1,6 +1,6 @@
import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
export async function determineExecutionMachineSequences(products: productsSchema): Promise<EventsSchema[][]> { export async function determineExecutionMachineSequences(products: ProductsSchema): Promise<EventsSchema[][]> {
const pointToEventMap = new Map<string, EventsSchema>(); const pointToEventMap = new Map<string, EventsSchema>();
const allPoints: PointsScheme[] = []; const allPoints: PointsScheme[] = [];

View File

@@ -1,6 +1,6 @@
import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
export function determineExecutionOrder(products: productsSchema): Action[] { export function determineExecutionOrder(products: ProductsSchema): Action[] {
// Create maps for all events and points // Create maps for all events and points
const pointMap = new Map<string, PointsScheme>(); const pointMap = new Map<string, PointsScheme>();
const allPoints: PointsScheme[] = []; const allPoints: PointsScheme[] = [];

View File

@@ -1,6 +1,6 @@
import { extractTriggersFromPoint } from "./extractTriggersFromPoint"; import { extractTriggersFromPoint } from "./extractTriggersFromPoint";
export async function determineExecutionSequences(products: productsSchema): Promise<PointsScheme[][]> { export async function determineExecutionSequences(products: ProductsSchema): Promise<PointsScheme[][]> {
// Create maps for all points // Create maps for all points
const pointMap = new Map<string, PointsScheme>(); const pointMap = new Map<string, PointsScheme>();
const allPoints: PointsScheme[] = []; const allPoints: PointsScheme[] = [];

View File

@@ -75,7 +75,7 @@ export function findConveyorSubsequence(
} }
// Helper function to get machine sequences (simplified from your example) // Helper function to get machine sequences (simplified from your example)
function determineExecutionMachineSequences(products: productsSchema): EventsSchema[][] { function determineExecutionMachineSequences(products: ProductsSchema): EventsSchema[][] {
const pointToEventMap = new Map<string, EventsSchema>(); const pointToEventMap = new Map<string, EventsSchema>();
const allPoints: PointsScheme[] = []; const allPoints: PointsScheme[] = [];

View File

@@ -5,7 +5,10 @@ import { determineExecutionOrder } from "./functions/determineExecutionOrder";
import { useSceneContext } from "../../scene/sceneContext"; import { useSceneContext } from "../../scene/sceneContext";
import SimulationHandler from "./SimulationHandler"; import SimulationHandler from "./SimulationHandler";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { getSimulationData, saveSimulationData } from "../../../components/layout/scenes/functions/simulationStorage"; import {
getSimulationData,
saveSimulationData,
} from "../../../components/layout/scenes/functions/simulationStorage";
import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore"; import { useSimulationManager } from "../../../store/rough/useSimulationManagerStore";
import { useSimulateId } from "../../../store/builder/store"; import { useSimulateId } from "../../../store/builder/store";
@@ -32,18 +35,23 @@ function Simulator() {
handleAction(action); handleAction(action);
}); });
}, [products, isPlaying, isReset, selectedProduct]); }, [products, isPlaying, isReset, selectedProduct]);
useEffect(() => { useEffect(() => {
if (!projectId || !selectedVersion || !selectedProduct?.productUuid) return; if (!projectId || !selectedVersion || !selectedProduct?.productUuid) return;
const fetchSimulateData = async () => { const fetchSimulateData = async () => {
const getData = await getSimulationData(projectId, selectedVersion.versionId, selectedProduct?.productUuid); const getData = await getSimulationData(
projectId,
selectedVersion.versionId,
selectedProduct?.productUuid
);
const product = getProductById(selectedProduct.productUuid); const product = getProductById(selectedProduct.productUuid);
if (!product) return; if (!product) return;
const products: productsSchema = [product]; const products: ProductsSchema = [product];
const getSimulate = getData?.data; const getSimulate = getData?.data;
console.log("getSimulate: ", getSimulate); // console.log("getSimulate: ", getSimulate);
if (getData && getSimulate && getSimulate.productTimestamp === products[0]?.timestamp) { if (getData && getSimulate && getSimulate.productTimestamp === products[0]?.timestamp) {
setSimulateId(getSimulate._id); setSimulateId(getSimulate._id);
console.log(" getSimulate.data: ", getSimulate.data); // console.log(" getSimulate.data: ", getSimulate.data);
addSimulationRecords( addSimulationRecords(
projectId, projectId,
selectedVersion?.versionId || "", selectedVersion?.versionId || "",
@@ -58,15 +66,22 @@ function Simulator() {
projectId: projectId, projectId: projectId,
versionId: selectedVersion.versionId, versionId: selectedVersion.versionId,
productUuid: selectedProduct.productUuid, productUuid: selectedProduct.productUuid,
simulateData: useSimulationManager.getState().getProductById(projectId, selectedVersion?.versionId, selectedProduct.productUuid)?.simulateData, simulateData: useSimulationManager
.getState()
.getProductById(
projectId,
selectedVersion?.versionId,
selectedProduct.productUuid
)?.simulateData,
}; };
const simulations = await saveSimulationData(data); const simulations = await saveSimulationData(data);
console.log("simulations: ", simulations); // console.log("simulations: ", simulations);
echo.log("Simulation data saved successfully"); echo.log("Simulation data saved successfully");
} }
}; };
fetchSimulateData(); fetchSimulateData();
}, []); }, []);
return ( return (
<> <>
{/* <simulationHandler/> */} {/* <simulationHandler/> */}

View File

@@ -2,7 +2,7 @@ import { create } from "zustand";
import { immer } from "zustand/middleware/immer"; import { immer } from "zustand/middleware/immer";
type ProductsStore = { type ProductsStore = {
products: productsSchema; products: ProductsSchema;
selectedProduct: { productUuid: string; productName: string }; selectedProduct: { productUuid: string; productName: string };
setSelectedProduct: (productUuid: string, productName: string) => void; setSelectedProduct: (productUuid: string, productName: string) => void;
@@ -10,7 +10,7 @@ type ProductsStore = {
// Product-level actions // Product-level actions
addProduct: (productName: string, productUuid: string) => void; addProduct: (productName: string, productUuid: string) => void;
setProducts: (products: productsSchema) => void; setProducts: (products: ProductsSchema) => void;
clearProducts: () => void; clearProducts: () => void;
removeProduct: (productUuid: string) => void; removeProduct: (productUuid: string) => void;
updateProduct: (productUuid: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void; updateProduct: (productUuid: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void;

View File

@@ -1,6 +1,6 @@
import { create } from 'zustand'; import { create } from "zustand";
import { immer } from 'zustand/middleware/immer'; import { immer } from "zustand/middleware/immer";
import * as THREE from 'three'; import * as THREE from "three";
interface SelectedEventSphereState { interface SelectedEventSphereState {
selectedEventSphere: THREE.Mesh | null; selectedEventSphere: THREE.Mesh | null;
@@ -120,15 +120,9 @@ interface SelectedAnimationState {
animationName: string; animationName: string;
animationType: "behaviour" | "animatedTravel"; animationType: "behaviour" | "animatedTravel";
animation: string | null; animation: string | null;
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; } travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null };
} | null; } | null;
setSelectedAnimation: (animation: { setSelectedAnimation: (animation: { animationUuid: string; animationName: string; animationType: "behaviour" | "animatedTravel"; animation: string | null; travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null } }) => void;
animationUuid: string;
animationName: string;
animationType: "behaviour" | "animatedTravel";
animation: string | null;
travelPoints?: { startPoint: [number, number, number] | null; endPoint: [number, number, number] | null; }
}) => void;
clearSelectedAnimation: () => void; clearSelectedAnimation: () => void;
} }
@@ -180,45 +174,55 @@ export const useIsRotating = create<IsRotatingState>()(
})) }))
); );
interface MainProductState { interface SimulationState {
mainProduct: { productUuid: string; productName: string } | null; mainScene: {
setMainProduct: (productUuid: string, productName: string) => void; product: { productUuid: string; productName: string };
clearMainProduct: () => void; version: { versionUuid: string; versionName: string };
};
comparisonScene: {
product: { productUuid: string; productName: string };
version: { versionUuid: string; versionName: string };
} | null;
setMainState: (mainScene: { productUuid: string; productName: string; versionUuid: string; versionName: string }) => void;
setComparisonState: (comparisonScene: { productUuid: string; productName: string; versionUuid: string; versionName: string } | null) => void;
clearMainState: () => void;
clearComparisonState: () => void;
} }
export const useMainProduct = create<MainProductState>()( export const useSimulationState = create<SimulationState>()(
immer((set) => ({ immer((set) => ({
mainProduct: null, mainScene: {
setMainProduct: (productUuid: string, productName: string) => { product: { productUuid: "", productName: "" },
version: { versionUuid: "", versionName: "" },
},
comparisonScene: null,
setMainState: (mainScene) => {
set((state) => { set((state) => {
state.mainProduct = { productUuid, productName }; state.mainScene.product = { productUuid: mainScene.productUuid, productName: mainScene.productName };
state.mainScene.version = { versionUuid: mainScene.versionUuid, versionName: mainScene.versionName };
}); });
}, },
clearMainProduct: () => { setComparisonState: (comparisonScene) => {
set((state) => { set((state) => {
state.mainProduct = null; if (comparisonScene) {
state.comparisonScene = {
product: { productUuid: comparisonScene.productUuid, productName: comparisonScene.productName },
version: { versionUuid: comparisonScene.versionUuid, versionName: comparisonScene.versionName },
};
} else {
state.comparisonScene = null;
}
}); });
}, },
})) clearMainState: () => {
);
interface ComparisonProductState {
comparisonProduct: { productUuid: string; productName: string } | null;
setComparisonProduct: (productUuid: string, productName: string) => void;
clearComparisonProduct: () => void;
}
export const useComparisonProduct = create<ComparisonProductState>()(
immer((set) => ({
comparisonProduct: null,
setComparisonProduct: (productUuid: string, productName: string) => {
set((state) => { set((state) => {
state.comparisonProduct = { productUuid, productName }; state.mainScene.product = { productUuid: "", productName: "" };
state.mainScene.version = { versionUuid: "", versionName: "" };
}); });
}, },
clearComparisonProduct: () => { clearComparisonState: () => {
set((state) => { set((state) => {
state.comparisonProduct = null; state.comparisonScene = null;
}); });
}, },
})) }))
@@ -242,14 +246,14 @@ export const useSelectedPoints = create<SelectedPointsState>()(
}, },
addSelectedPoint: (point) => { addSelectedPoint: (point) => {
set((state) => { set((state) => {
if (!state.selectedPoints.find(p => p.uuid === point.uuid)) { if (!state.selectedPoints.find((p) => p.uuid === point.uuid)) {
state.selectedPoints.push(point); state.selectedPoints.push(point);
} }
}); });
}, },
removeSelectedPoint: (uuid) => { removeSelectedPoint: (uuid) => {
set((state) => { set((state) => {
state.selectedPoints = state.selectedPoints.filter(p => p.uuid !== uuid); state.selectedPoints = state.selectedPoints.filter((p) => p.uuid !== uuid);
}); });
}, },
clearSelectedPoints: () => { clearSelectedPoints: () => {

View File

@@ -400,7 +400,7 @@ type MaterialsSchema = MaterialSchema[];
// Products // Products
type productsSchema = { type ProductsSchema = {
productName: string; productName: string;
productUuid: string; productUuid: string;
eventDatas: EventsSchema[]; eventDatas: EventsSchema[];

View File

@@ -6,12 +6,12 @@ import useCameraModeStore, { usePlayButtonStore } from "../../store/ui/usePlayBu
import { detectModifierKeys } from "./detectModifierKeys"; import { detectModifierKeys } from "./detectModifierKeys";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore"; import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
import { useLogger } from "../../components/ui/log/LoggerContext"; import { useLogger } from "../../components/ui/log/LoggerContext";
import { useComparisonProduct } from "../../store/simulation/useSimulationStore"; import { useSimulationState } from "../../store/simulation/useSimulationStore";
import { useBuilderStore } from "../../store/builder/useBuilderStore"; import { useBuilderStore } from "../../store/builder/useBuilderStore";
import { useSceneContext } from "../../modules/scene/sceneContext"; import { useSceneContext } from "../../modules/scene/sceneContext";
const KeyPressListener: React.FC = () => { const KeyPressListener: React.FC = () => {
const { comparisonProduct, clearComparisonProduct } = useComparisonProduct(); const { comparisonScene, clearComparisonState } = useSimulationState();
const { activeModule, setActiveModule } = useModuleStore(); const { activeModule, setActiveModule } = useModuleStore();
const { assetStore, versionStore } = useSceneContext(); const { assetStore, versionStore } = useSceneContext();
const { selectedAssets } = assetStore(); const { selectedAssets } = assetStore();
@@ -178,7 +178,7 @@ const KeyPressListener: React.FC = () => {
clearSelectedZone(); clearSelectedZone();
setShowShortcuts(false); setShowShortcuts(false);
setIsComparing(false); setIsComparing(false);
clearComparisonProduct(); clearComparisonState();
setIsLogListVisible(false); setIsLogListVisible(false);
setIsRenameMode(false); setIsRenameMode(false);
setDfxUploaded([]); setDfxUploaded([]);
@@ -203,7 +203,7 @@ const KeyPressListener: React.FC = () => {
handleBuilderShortcuts(keyCombination); handleBuilderShortcuts(keyCombination);
// Shortcut to enter play mode // Shortcut to enter play mode
if (keyCombination === "Ctrl+P" && !toggleView && !comparisonProduct) { if (keyCombination === "Ctrl+P" && !toggleView && !comparisonScene) {
setIsPlaying(true); setIsPlaying(true);
} }