Refactor components and improve loading behavior
- Simplified rendering of CompareLayOut and ComparisonScene components. - Enhanced MainScene to log createNewWindow state and conditionally render LoadingPage. - Updated GlobalProperties to improve environment settings handling. - Refactored LoadingPage to support rendering as a portal and added new props for flexibility. - Improved NewWindowScene to include LoadingPage and handle loading progress. - Added console logs for debugging in calculateSimulationData and ComparisonResult components. - Cleaned up unused code and improved readability across various components. - Adjusted styles in loading.scss for better visual consistency and responsiveness.
This commit is contained in:
@@ -220,7 +220,7 @@ function ComparisonScene() {
|
|||||||
<Button />
|
<Button />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{<CompareLayOut />}
|
<CompareLayOut />
|
||||||
{createNewWindow && <NewWindowScene />}
|
{createNewWindow && <NewWindowScene />}
|
||||||
{shouldShowComparisonResult && !loadingProgress && <ComparisonResult />}
|
{shouldShowComparisonResult && !loadingProgress && <ComparisonResult />}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useLoadingProgress, useRenameModeStore, useIsComparing, useSelectedComment, useWidgetSubOption, useToggleView } from "../../../store/builder/store";
|
import {
|
||||||
|
useLoadingProgress,
|
||||||
|
useRenameModeStore,
|
||||||
|
useIsComparing,
|
||||||
|
useSelectedComment,
|
||||||
|
useWidgetSubOption,
|
||||||
|
useToggleView,
|
||||||
|
useCreateNewWindow,
|
||||||
|
} from "../../../store/builder/store";
|
||||||
import useModuleStore from "../../../store/ui/useModuleStore";
|
import useModuleStore from "../../../store/ui/useModuleStore";
|
||||||
import { useSocketStore } from "../../../store/socket/useSocketStore";
|
import { useSocketStore } from "../../../store/socket/useSocketStore";
|
||||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||||
@@ -55,7 +63,11 @@ function MainScene() {
|
|||||||
const { selectedComment, commentPositionState } = useSelectedComment();
|
const { selectedComment, commentPositionState } = useSelectedComment();
|
||||||
const { resetStates } = useRestStates();
|
const { resetStates } = useRestStates();
|
||||||
const { organization, userId } = getUserData();
|
const { organization, userId } = getUserData();
|
||||||
|
const { createNewWindow } = useCreateNewWindow();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("createNewWindow: ", createNewWindow);
|
||||||
|
}, [createNewWindow]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
resetStates();
|
resetStates();
|
||||||
@@ -106,9 +118,13 @@ function MainScene() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (versionHistory.length > 0) {
|
if (versionHistory.length > 0) {
|
||||||
recentlyViewedApi().then((projects) => {
|
recentlyViewedApi().then((projects) => {
|
||||||
const recent_opened_verisionID = (Object.values(projects?.RecentlyViewed || {})[0] as any)?.Present_version._id;
|
const recent_opened_verisionID = (
|
||||||
|
Object.values(projects?.RecentlyViewed || {})[0] as any
|
||||||
|
)?.Present_version._id;
|
||||||
if (recent_opened_verisionID && projects.RecentlyViewed[0]._id === projectId) {
|
if (recent_opened_verisionID && projects.RecentlyViewed[0]._id === projectId) {
|
||||||
const version = versionHistory.find((ver) => ver.versionId === recent_opened_verisionID);
|
const version = versionHistory.find(
|
||||||
|
(ver) => ver.versionId === recent_opened_verisionID
|
||||||
|
);
|
||||||
if (version) {
|
if (version) {
|
||||||
setSelectedVersion(version);
|
setSelectedVersion(version);
|
||||||
}
|
}
|
||||||
@@ -186,7 +202,9 @@ function MainScene() {
|
|||||||
{!selectedUser && (
|
{!selectedUser && (
|
||||||
<>
|
<>
|
||||||
<KeyPressListener />
|
<KeyPressListener />
|
||||||
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
{!createNewWindow && loadingProgress > 0 && (
|
||||||
|
<LoadingPage progress={loadingProgress} />
|
||||||
|
)}
|
||||||
{!isPlaying && (
|
{!isPlaying && (
|
||||||
<>
|
<>
|
||||||
{!toggleView && !isComparing && <ModuleToggle />}
|
{!toggleView && !isComparing && <ModuleToggle />}
|
||||||
@@ -197,18 +215,39 @@ function MainScene() {
|
|||||||
<RealTimeVisulization />
|
<RealTimeVisulization />
|
||||||
{activeModule === "market" && <MarketPlace />}
|
{activeModule === "market" && <MarketPlace />}
|
||||||
{activeModule !== "market" && !isPlaying && !isComparing && <Tools />}
|
{activeModule !== "market" && !isPlaying && !isComparing && <Tools />}
|
||||||
{isPlaying && activeModule === "simulation" && loadingProgress === 0 && <SimulationPlayer />}
|
{isPlaying && activeModule === "simulation" && loadingProgress === 0 && (
|
||||||
|
<SimulationPlayer />
|
||||||
|
)}
|
||||||
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
|
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
|
||||||
|
|
||||||
{isRenameMode && selectedAssets.length === 1 && <RenameTooltip name={selectedAssets[0].userData.modelName} onSubmit={handleObjectRename} />}
|
{isRenameMode && selectedAssets.length === 1 && (
|
||||||
|
<RenameTooltip
|
||||||
|
name={selectedAssets[0].userData.modelName}
|
||||||
|
onSubmit={handleObjectRename}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{activeModule === "builder" && toggleView && <SelectFloorPlan />}
|
{activeModule === "builder" && toggleView && <SelectFloorPlan />}
|
||||||
|
|
||||||
{selectedProduct && selectedVersion && isComparing && !isPlaying && activeModule === "simulation" && (
|
{selectedProduct &&
|
||||||
|
selectedVersion &&
|
||||||
|
isComparing &&
|
||||||
|
!isPlaying &&
|
||||||
|
activeModule === "simulation" && (
|
||||||
<div className="selectLayout-wrapper">
|
<div className="selectLayout-wrapper">
|
||||||
<RegularDropDown header={selectedVersion.versionName} options={versionHistory.map((v) => v.versionName)} onSelect={handleSelectVersion} search={false} />
|
<RegularDropDown
|
||||||
|
header={selectedVersion.versionName}
|
||||||
|
options={versionHistory.map((v) => v.versionName)}
|
||||||
|
onSelect={handleSelectVersion}
|
||||||
|
search={false}
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
<RegularDropDown header={selectedProduct.productName} options={products.map((l) => l.productName)} onSelect={handleSelectProduct} search={false} />
|
<RegularDropDown
|
||||||
|
header={selectedProduct.productName}
|
||||||
|
options={products.map((l) => l.productName)}
|
||||||
|
onSelect={handleSelectProduct}
|
||||||
|
search={false}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export const calculateSimulationData = (assets: AssetData[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const machineActiveTime = assets.filter((a) => a.type === "human").reduce((acc, a) => acc + a.activeTime, 0);
|
const machineActiveTime = assets.filter((a) => a.type === "human").reduce((acc, a) => acc + a.activeTime, 0);
|
||||||
|
console.log('assets: ', assets);
|
||||||
|
|
||||||
const machineIdleTime = assets.filter((a) => a.type === "machine").reduce((acc, a) => acc + a.idleTime, 0);
|
const machineIdleTime = assets.filter((a) => a.type === "machine").reduce((acc, a) => acc + a.idleTime, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,16 @@ const GlobalProperties: React.FC = () => {
|
|||||||
|
|
||||||
const optimizeScene = async (value: any) => {
|
const optimizeScene = async (value: any) => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
setEnvironment(organization, userId, wallVisibility, roofVisibility, shadows, 30, true, projectId);
|
setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
30,
|
||||||
|
true,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
setRenderDistance(30);
|
setRenderDistance(30);
|
||||||
setLimitDistance(true);
|
setLimitDistance(true);
|
||||||
};
|
};
|
||||||
@@ -52,10 +61,28 @@ const GlobalProperties: React.FC = () => {
|
|||||||
const limitRenderDistance = async () => {
|
const limitRenderDistance = async () => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
if (limitDistance) {
|
if (limitDistance) {
|
||||||
setEnvironment(organization, userId, wallVisibility, roofVisibility, shadows, 75, !limitDistance, projectId);
|
setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
75,
|
||||||
|
!limitDistance,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
setRenderDistance(75);
|
setRenderDistance(75);
|
||||||
} else {
|
} else {
|
||||||
setEnvironment(organization, userId, wallVisibility, roofVisibility, shadows, renderDistance, !limitDistance, projectId);
|
setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
renderDistance,
|
||||||
|
!limitDistance,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
setLimitDistance(!limitDistance);
|
setLimitDistance(!limitDistance);
|
||||||
};
|
};
|
||||||
@@ -84,7 +111,16 @@ const GlobalProperties: React.FC = () => {
|
|||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
setRenderDistance(value);
|
setRenderDistance(value);
|
||||||
// setDistance(value);
|
// setDistance(value);
|
||||||
const data = await setEnvironment(organization, userId, wallVisibility, roofVisibility, shadows, value, limitDistance, projectId);
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
value,
|
||||||
|
limitDistance,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to toggle roof visibility
|
// Function to toggle roof visibility
|
||||||
@@ -92,7 +128,16 @@ const GlobalProperties: React.FC = () => {
|
|||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
|
|
||||||
//using REST
|
//using REST
|
||||||
const data = await setEnvironment(organization, userId, wallVisibility, !roofVisibility, shadows, renderDistance, limitDistance, projectId);
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
wallVisibility,
|
||||||
|
!roofVisibility,
|
||||||
|
shadows,
|
||||||
|
renderDistance,
|
||||||
|
limitDistance,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
|
||||||
//using Socket
|
//using Socket
|
||||||
// const visData = {
|
// const visData = {
|
||||||
@@ -112,7 +157,16 @@ const GlobalProperties: React.FC = () => {
|
|||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
|
|
||||||
//using REST
|
//using REST
|
||||||
const data = await setEnvironment(organization, userId, !wallVisibility, roofVisibility, shadows, renderDistance, limitDistance, projectId);
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
!wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
shadows,
|
||||||
|
renderDistance,
|
||||||
|
limitDistance,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
|
||||||
//using Socket
|
//using Socket
|
||||||
// const visData = {
|
// const visData = {
|
||||||
@@ -132,7 +186,16 @@ const GlobalProperties: React.FC = () => {
|
|||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
|
|
||||||
//using REST
|
//using REST
|
||||||
const data = await setEnvironment(organization, userId, wallVisibility, roofVisibility, !shadows, renderDistance, limitDistance, projectId);
|
const data = await setEnvironment(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
wallVisibility,
|
||||||
|
roofVisibility,
|
||||||
|
!shadows,
|
||||||
|
renderDistance,
|
||||||
|
limitDistance,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
|
||||||
//using Socket
|
//using Socket
|
||||||
// const visData = {
|
// const visData = {
|
||||||
@@ -165,14 +228,34 @@ const GlobalProperties: React.FC = () => {
|
|||||||
|
|
||||||
<div className="split"></div>
|
<div className="split"></div>
|
||||||
|
|
||||||
<InputToggle value={roofVisibility} inputKey="1" label="Roof Visibility" onClick={changeRoofVisibility} />
|
<InputToggle
|
||||||
<InputToggle value={wallVisibility} inputKey="2" label="Wall Visibility" onClick={changeWallVisibility} />
|
value={roofVisibility}
|
||||||
<InputToggle value={shadows} inputKey="3" label="Shadows Visibility" onClick={shadowVisibility} />
|
inputKey="1"
|
||||||
|
label="Roof Visibility"
|
||||||
|
onClick={changeRoofVisibility}
|
||||||
|
/>
|
||||||
|
<InputToggle
|
||||||
|
value={wallVisibility}
|
||||||
|
inputKey="2"
|
||||||
|
label="Wall Visibility"
|
||||||
|
onClick={changeWallVisibility}
|
||||||
|
/>
|
||||||
|
<InputToggle
|
||||||
|
value={shadows}
|
||||||
|
inputKey="3"
|
||||||
|
label="Shadows Visibility"
|
||||||
|
onClick={shadowVisibility}
|
||||||
|
/>
|
||||||
<LabeledButton label="Reset Camera" onClick={toggleResetCamera} value="Reset" />
|
<LabeledButton label="Reset Camera" onClick={toggleResetCamera} value="Reset" />
|
||||||
|
|
||||||
<div className="split"></div>
|
<div className="split"></div>
|
||||||
|
|
||||||
<InputToggle inputKey="4" label="Limit Render Distance" value={limitDistance} onClick={limitRenderDistance} />
|
<InputToggle
|
||||||
|
inputKey="4"
|
||||||
|
label="Limit Render Distance"
|
||||||
|
value={limitDistance}
|
||||||
|
onClick={limitRenderDistance}
|
||||||
|
/>
|
||||||
<InputRange
|
<InputRange
|
||||||
label="Distance"
|
label="Distance"
|
||||||
disabled={!limitDistance}
|
disabled={!limitDistance}
|
||||||
@@ -186,7 +269,12 @@ const GlobalProperties: React.FC = () => {
|
|||||||
|
|
||||||
<div className="split"></div>
|
<div className="split"></div>
|
||||||
|
|
||||||
<InputToggle inputKey="7" label="Limit Fps" value={limitFps} onClick={limitFpsToggle} />
|
<InputToggle
|
||||||
|
inputKey="7"
|
||||||
|
label="Limit Fps"
|
||||||
|
value={limitFps}
|
||||||
|
onClick={limitFpsToggle}
|
||||||
|
/>
|
||||||
<InputRange
|
<InputRange
|
||||||
label="Fps"
|
label="Fps"
|
||||||
disabled={!limitFps}
|
disabled={!limitFps}
|
||||||
|
|||||||
@@ -24,159 +24,6 @@ type NewWindowProps = {
|
|||||||
theme?: string | null;
|
theme?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// export const RenderInNewWindow: React.FC<NewWindowProps> = ({
|
|
||||||
// children,
|
|
||||||
// title = "New Window",
|
|
||||||
// width = 900,
|
|
||||||
// height = 700,
|
|
||||||
// left,
|
|
||||||
// top,
|
|
||||||
// center = true,
|
|
||||||
// features,
|
|
||||||
// onClose,
|
|
||||||
// copyStyles = true,
|
|
||||||
// noopener = true,
|
|
||||||
// className,
|
|
||||||
// theme = localStorage.getItem("theme") ?? "light",
|
|
||||||
// }) => {
|
|
||||||
// const [mounted, setMounted] = useState(false);
|
|
||||||
// const childWindowRef = useRef<Window | null>(null);
|
|
||||||
// const containerElRef = useRef<HTMLDivElement | null>(null);
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (typeof window === "undefined") return;
|
|
||||||
|
|
||||||
// const screenLeft = window.screenLeft ?? window.screenX ?? 0;
|
|
||||||
// const screenTop = window.screenTop ?? window.screenY ?? 0;
|
|
||||||
// const availWidth = window.outerWidth ?? window.innerWidth;
|
|
||||||
// const availHeight = window.outerHeight ?? window.innerHeight;
|
|
||||||
|
|
||||||
// const finalLeft =
|
|
||||||
// center && availWidth ? Math.max(0, screenLeft + (availWidth - width) / 2) : left ?? 100;
|
|
||||||
|
|
||||||
// const finalTop =
|
|
||||||
// center && availHeight
|
|
||||||
// ? Math.max(0, screenTop + (availHeight - height) / 2)
|
|
||||||
// : top ?? 100;
|
|
||||||
|
|
||||||
// const baseFeatures = [
|
|
||||||
// `width=${Math.floor(width)}`,
|
|
||||||
// `height=${Math.floor(height)}`,
|
|
||||||
// `left=${Math.floor(finalLeft)}`,
|
|
||||||
// `top=${Math.floor(finalTop)}`,
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// const featureFlags = features ?? {
|
|
||||||
// toolbar: false,
|
|
||||||
// menubar: false,
|
|
||||||
// scrollbars: true,
|
|
||||||
// resizable: true,
|
|
||||||
// location: false,
|
|
||||||
// status: false,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Object.entries(featureFlags).forEach(([k, v]) =>
|
|
||||||
// baseFeatures.push(`${k}=${v ? "yes" : "no"}`)
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const newWin = window.open("", "_blank", baseFeatures.join(","));
|
|
||||||
// if (!newWin) {
|
|
||||||
// console.warn("Popup blocked or failed to open window.");
|
|
||||||
// onClose?.();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (noopener) {
|
|
||||||
// try {
|
|
||||||
// newWin.opener = null;
|
|
||||||
// } catch {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
// newWin.document.open();
|
|
||||||
// newWin.document.write(`<!doctype html>
|
|
||||||
// <html data-theme=${theme}>
|
|
||||||
// <head>
|
|
||||||
// <meta charset="utf-8" />
|
|
||||||
// <title>${title}</title>
|
|
||||||
// <meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
// </head>
|
|
||||||
// <body style="margin:0;"></body>
|
|
||||||
// </html>`);
|
|
||||||
// newWin.document.close();
|
|
||||||
|
|
||||||
// if (copyStyles) {
|
|
||||||
// const head = newWin.document.head;
|
|
||||||
// Array.from(document.styleSheets).forEach((styleSheet) => {
|
|
||||||
// try {
|
|
||||||
// if ((styleSheet as CSSStyleSheet).cssRules) {
|
|
||||||
// const newStyleEl = newWin.document.createElement("style");
|
|
||||||
// const rules = Array.from((styleSheet as CSSStyleSheet).cssRules).map(
|
|
||||||
// (r) => r.cssText
|
|
||||||
// );
|
|
||||||
// newStyleEl.appendChild(newWin.document.createTextNode(rules.join("\n")));
|
|
||||||
// head.appendChild(newStyleEl);
|
|
||||||
// }
|
|
||||||
// } catch {
|
|
||||||
// const ownerNode = styleSheet.ownerNode as HTMLElement | null;
|
|
||||||
// if (ownerNode && ownerNode.tagName === "LINK") {
|
|
||||||
// const link = ownerNode as HTMLLinkElement;
|
|
||||||
// const newLink = newWin.document.createElement("link");
|
|
||||||
// newLink.rel = link.rel;
|
|
||||||
// newLink.href = link.href;
|
|
||||||
// newLink.media = link.media;
|
|
||||||
// head.appendChild(newLink);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const container = newWin.document.createElement("div");
|
|
||||||
// if (className) container.className = className;
|
|
||||||
// newWin.document.body.appendChild(container);
|
|
||||||
|
|
||||||
// newWin.document.title = title;
|
|
||||||
|
|
||||||
// // Handle child window close
|
|
||||||
// const handleChildUnload = () => {
|
|
||||||
// onClose?.();
|
|
||||||
// };
|
|
||||||
// newWin.addEventListener("beforeunload", handleChildUnload);
|
|
||||||
|
|
||||||
// // 👇 Handle parent refresh/close → auto close child
|
|
||||||
// const handleParentUnload = () => {
|
|
||||||
// try {
|
|
||||||
// newWin.close();
|
|
||||||
// } catch {}
|
|
||||||
// };
|
|
||||||
// window.addEventListener("beforeunload", handleParentUnload);
|
|
||||||
|
|
||||||
// childWindowRef.current = newWin;
|
|
||||||
// containerElRef.current = container;
|
|
||||||
// setMounted(true);
|
|
||||||
|
|
||||||
// return () => {
|
|
||||||
// newWin.removeEventListener("beforeunload", handleChildUnload);
|
|
||||||
// window.removeEventListener("beforeunload", handleParentUnload);
|
|
||||||
// try {
|
|
||||||
// newWin.close();
|
|
||||||
// } catch {}
|
|
||||||
// childWindowRef.current = null;
|
|
||||||
// containerElRef.current = null;
|
|
||||||
// };
|
|
||||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// const w = childWindowRef.current;
|
|
||||||
// if (w && !w.closed) {
|
|
||||||
// w.document.title = title;
|
|
||||||
// }
|
|
||||||
// }, [title]);
|
|
||||||
|
|
||||||
// if (!mounted || !containerElRef.current) return null;
|
|
||||||
|
|
||||||
// return createPortal(children, containerElRef.current);
|
|
||||||
// };
|
|
||||||
export const RenderInNewWindow: React.FC<NewWindowProps> = ({
|
export const RenderInNewWindow: React.FC<NewWindowProps> = ({
|
||||||
children,
|
children,
|
||||||
title = "3D Viewer",
|
title = "3D Viewer",
|
||||||
@@ -207,10 +54,12 @@ export const RenderInNewWindow: React.FC<NewWindowProps> = ({
|
|||||||
const finalLeft =
|
const finalLeft =
|
||||||
center && availWidth ? Math.max(0, screenLeft + (availWidth - width) / 2) : left ?? 100;
|
center && availWidth ? Math.max(0, screenLeft + (availWidth - width) / 2) : left ?? 100;
|
||||||
|
|
||||||
|
console.log("finalLeft: ", finalLeft);
|
||||||
const finalTop =
|
const finalTop =
|
||||||
center && availHeight
|
center && availHeight
|
||||||
? Math.max(0, screenTop + (availHeight - height) / 2)
|
? Math.max(0, screenTop + (availHeight - height) / 2)
|
||||||
: top ?? 100;
|
: top ?? 100;
|
||||||
|
console.log("finalTop: ", finalTop);
|
||||||
|
|
||||||
const baseFeatures = [
|
const baseFeatures = [
|
||||||
`width=${Math.floor(width)}`,
|
`width=${Math.floor(width)}`,
|
||||||
@@ -370,6 +219,16 @@ export const RenderInNewWindow: React.FC<NewWindowProps> = ({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
childWindowRef.current?.dispatchEvent(new Event("resize"));
|
||||||
|
};
|
||||||
|
childWindowRef.current?.addEventListener("resize", handleResize);
|
||||||
|
return () => {
|
||||||
|
childWindowRef.current?.removeEventListener("resize", handleResize);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const w = childWindowRef.current;
|
const w = childWindowRef.current;
|
||||||
if (w && !w.closed) {
|
if (w && !w.closed) {
|
||||||
|
|||||||
@@ -1,25 +1,34 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import RenderOverlay from "./Overlay";
|
import ReactDOM from "react-dom";
|
||||||
import { LogoIconLarge } from "../icons/Logo";
|
import { LogoIconLarge } from "../icons/Logo";
|
||||||
import { useProjectName } from "../../store/builder/store";
|
import { useProjectName } from "../../store/builder/store";
|
||||||
import { useSimulationState } from "../../store/simulation/useSimulationStore";
|
import { useSimulationState } from "../../store/simulation/useSimulationStore";
|
||||||
|
import RenderOverlay from "./Overlay";
|
||||||
|
|
||||||
interface LoadingPageProps {
|
interface LoadingPageProps {
|
||||||
progress: number; // Expect progress as a percentage (0-100)
|
progress: number;
|
||||||
|
renderOver?: boolean;
|
||||||
|
returnDefault?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
|
const LoadingPage: React.FC<LoadingPageProps> = ({
|
||||||
console.log('progress: ', progress);
|
progress,
|
||||||
|
renderOver = true,
|
||||||
|
returnDefault = false,
|
||||||
|
}) => {
|
||||||
const { projectName } = useProjectName();
|
const { projectName } = useProjectName();
|
||||||
const { comparisonScene } = useSimulationState();
|
const { comparisonScene } = useSimulationState();
|
||||||
|
|
||||||
const validatedProgress = Math.min(100, Math.max(0, progress));
|
const validatedProgress = Math.min(100, Math.max(0, progress));
|
||||||
|
|
||||||
console.log("comparisonScene: ", comparisonScene);
|
// Portal target (defaults to body)
|
||||||
return (
|
const portalRoot = document.getElementById("root") || document.body;
|
||||||
<RenderOverlay>
|
|
||||||
|
const content = (
|
||||||
<div
|
<div
|
||||||
className={`loading-wrapper ${comparisonScene != null ? "comparisionLoading" : ""}`}
|
className={`loading-wrapper ${
|
||||||
|
comparisonScene != null && !returnDefault ? "comparisionLoading" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<div className="loading-container">
|
<div className="loading-container">
|
||||||
<div className="project-name">{projectName}</div>
|
<div className="project-name">{projectName}</div>
|
||||||
@@ -34,14 +43,23 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
|
|||||||
<div className="progress-indicator-container">
|
<div className="progress-indicator-container">
|
||||||
<div
|
<div
|
||||||
className="progress-bar"
|
className="progress-bar"
|
||||||
style={{ width: `${validatedProgress}%` }} // Dynamic width
|
style={{ width: `${validatedProgress}%` }}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</RenderOverlay>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (returnDefault) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderOver) {
|
||||||
|
return <RenderOverlay>{content}</RenderOverlay>;
|
||||||
|
}
|
||||||
|
// Render the loading screen as a portal
|
||||||
|
return ReactDOM.createPortal(content, portalRoot);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoadingPage;
|
export default LoadingPage;
|
||||||
|
|||||||
@@ -2,26 +2,35 @@ import React from "react";
|
|||||||
import {
|
import {
|
||||||
useCreateNewWindow,
|
useCreateNewWindow,
|
||||||
useIsComparing,
|
useIsComparing,
|
||||||
useLoadingProgress,
|
useLimitDistance,
|
||||||
|
useRenderDistance,
|
||||||
} from "../../../store/builder/store";
|
} from "../../../store/builder/store";
|
||||||
import { useSimulationState } from "../../../store/simulation/useSimulationStore";
|
import { useSimulationState } from "../../../store/simulation/useSimulationStore";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { findEnvironment } from "../../../services/factoryBuilder/environment/findEnvironment";
|
||||||
|
|
||||||
const Button = () => {
|
const Button = () => {
|
||||||
const { isComparing, setIsComparing } = useIsComparing();
|
const { isComparing, setIsComparing } = useIsComparing();
|
||||||
const { createNewWindow, setCreateNewWindow } = useCreateNewWindow();
|
const { createNewWindow, setCreateNewWindow } = useCreateNewWindow();
|
||||||
const { setLoadingProgress } = useLoadingProgress();
|
|
||||||
const { clearComparisonState } = useSimulationState();
|
const { clearComparisonState } = useSimulationState();
|
||||||
|
const { projectId } = useParams();
|
||||||
|
const { setRenderDistance } = useRenderDistance();
|
||||||
|
const { setLimitDistance } = useLimitDistance();
|
||||||
|
|
||||||
const handleExit = () => {
|
const handleExit = () => {
|
||||||
setIsComparing(false);
|
setIsComparing(false);
|
||||||
setCreateNewWindow(false);
|
setCreateNewWindow(false);
|
||||||
setLoadingProgress(0);
|
|
||||||
clearComparisonState();
|
clearComparisonState();
|
||||||
|
if (!projectId) return;
|
||||||
|
findEnvironment(projectId).then((data) => {
|
||||||
|
if (!data) return;
|
||||||
|
setRenderDistance(data.renderDistance);
|
||||||
|
setLimitDistance(data.limitDistance);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenInNewWindow = () => {
|
const handleOpenInNewWindow = () => {
|
||||||
// 🧹 Immediately reset any loading or scene state
|
// setLoadingProgress(0);
|
||||||
setLoadingProgress(0);
|
|
||||||
setCreateNewWindow(true);
|
setCreateNewWindow(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
useLoadingProgress,
|
useLoadingProgress,
|
||||||
useIsComparing,
|
useIsComparing,
|
||||||
useCreateNewWindow,
|
useCreateNewWindow,
|
||||||
|
useLimitDistance,
|
||||||
} from "../../../store/builder/store";
|
} from "../../../store/builder/store";
|
||||||
import { useSimulationState } from "../../../store/simulation/useSimulationStore";
|
import { useSimulationState } from "../../../store/simulation/useSimulationStore";
|
||||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||||
@@ -17,7 +18,6 @@ import useRestStates from "../../../hooks/useResetStates";
|
|||||||
|
|
||||||
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
||||||
import { validateSimulationDataApi } from "../../../services/simulation/comparison/validateSimulationDataApi";
|
import { validateSimulationDataApi } from "../../../services/simulation/comparison/validateSimulationDataApi";
|
||||||
import Button from "./Button";
|
|
||||||
|
|
||||||
const CompareLayOut = () => {
|
const CompareLayOut = () => {
|
||||||
const { clearComparisonState, comparisonScene, setComparisonState } = useSimulationState();
|
const { clearComparisonState, comparisonScene, setComparisonState } = useSimulationState();
|
||||||
@@ -42,6 +42,7 @@ const CompareLayOut = () => {
|
|||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { resetStates } = useRestStates();
|
const { resetStates } = useRestStates();
|
||||||
const { createNewWindow } = useCreateNewWindow();
|
const { createNewWindow } = useCreateNewWindow();
|
||||||
|
const { limitDistance, setLimitDistance } = useLimitDistance();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
resetStates();
|
resetStates();
|
||||||
@@ -188,7 +189,10 @@ const CompareLayOut = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
console.log("limitDistance: ", limitDistance);
|
||||||
|
useEffect(() => {
|
||||||
|
setLimitDistance(false);
|
||||||
|
}, [limitDistance]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!createNewWindow && (
|
{!createNewWindow && (
|
||||||
|
|||||||
@@ -24,9 +24,12 @@ export interface CompareProduct {
|
|||||||
const ComparisonResult = () => {
|
const ComparisonResult = () => {
|
||||||
const { compareProductsData } = useCompareProductDataStore();
|
const { compareProductsData } = useCompareProductDataStore();
|
||||||
const { comparisonScene, mainScene } = useSimulationState();
|
const { comparisonScene, mainScene } = useSimulationState();
|
||||||
const [comparedProducts, setComparedProducts] = useState<[CompareProduct, CompareProduct] | []>([]);
|
const [comparedProducts, setComparedProducts] = useState<[CompareProduct, CompareProduct] | []>(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log("compareProductsData: ", compareProductsData);
|
||||||
if (compareProductsData.length > 0 && comparisonScene && mainScene) {
|
if (compareProductsData.length > 0 && comparisonScene && mainScene) {
|
||||||
setComparedProducts([compareProductsData[0], compareProductsData[1]]);
|
setComparedProducts([compareProductsData[0], compareProductsData[1]]);
|
||||||
} else {
|
} else {
|
||||||
@@ -34,11 +37,6 @@ const ComparisonResult = () => {
|
|||||||
}
|
}
|
||||||
}, [compareProductsData, comparisonScene, mainScene]);
|
}, [compareProductsData, comparisonScene, mainScene]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (comparedProducts.length === 2) {
|
|
||||||
}
|
|
||||||
}, [comparedProducts]);
|
|
||||||
|
|
||||||
const options = useMemo(
|
const options = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
responsive: true,
|
responsive: true,
|
||||||
@@ -64,7 +62,10 @@ const ComparisonResult = () => {
|
|||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Throughput (units/hr)",
|
label: "Throughput (units/hr)",
|
||||||
data: [comparedProducts[0]?.simulationData.throughputData, comparedProducts[1]?.simulationData.throughputData],
|
data: [
|
||||||
|
comparedProducts[0]?.simulationData.throughputData,
|
||||||
|
comparedProducts[1]?.simulationData.throughputData,
|
||||||
|
],
|
||||||
backgroundColor: [purpleDark, purpleLight],
|
backgroundColor: [purpleDark, purpleLight],
|
||||||
borderColor: [purpleDark, purpleLight],
|
borderColor: [purpleDark, purpleLight],
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
@@ -79,7 +80,10 @@ const ComparisonResult = () => {
|
|||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Cycle Time (sec)",
|
label: "Cycle Time (sec)",
|
||||||
data: [comparedProducts[0]?.simulationData.machineActiveTime, comparedProducts[1]?.simulationData.machineActiveTime],
|
data: [
|
||||||
|
comparedProducts[0]?.simulationData.machineActiveTime,
|
||||||
|
comparedProducts[1]?.simulationData.machineActiveTime,
|
||||||
|
],
|
||||||
backgroundColor: [purpleDark, purpleLight],
|
backgroundColor: [purpleDark, purpleLight],
|
||||||
borderColor: "#fff",
|
borderColor: "#fff",
|
||||||
borderWidth: 2,
|
borderWidth: 2,
|
||||||
@@ -92,7 +96,10 @@ const ComparisonResult = () => {
|
|||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Downtime (mins)",
|
label: "Downtime (mins)",
|
||||||
data: [comparedProducts[0]?.simulationData.machineIdleTime, comparedProducts[1]?.simulationData.machineIdleTime],
|
data: [
|
||||||
|
comparedProducts[0]?.simulationData.machineIdleTime,
|
||||||
|
comparedProducts[1]?.simulationData.machineIdleTime,
|
||||||
|
],
|
||||||
backgroundColor: [purpleDark, purpleLight],
|
backgroundColor: [purpleDark, purpleLight],
|
||||||
borderColor: "#fff",
|
borderColor: "#fff",
|
||||||
borderWidth: 2,
|
borderWidth: 2,
|
||||||
@@ -105,7 +112,10 @@ const ComparisonResult = () => {
|
|||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Production Capacity (units)",
|
label: "Production Capacity (units)",
|
||||||
data: [comparedProducts[0]?.simulationData.productionCapacity, comparedProducts[1]?.simulationData.productionCapacity],
|
data: [
|
||||||
|
comparedProducts[0]?.simulationData.productionCapacity,
|
||||||
|
comparedProducts[1]?.simulationData.productionCapacity,
|
||||||
|
],
|
||||||
backgroundColor: [purpleDark, purpleLight],
|
backgroundColor: [purpleDark, purpleLight],
|
||||||
borderColor: [purpleDark, purpleLight],
|
borderColor: [purpleDark, purpleLight],
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
@@ -116,25 +126,40 @@ const ComparisonResult = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const highestProductivityProduct =
|
const highestProductivityProduct =
|
||||||
(comparedProducts[0]?.simulationData?.productionCapacity ?? 0) > (comparedProducts[1]?.simulationData?.productionCapacity ?? 0) ? comparedProducts[0] : comparedProducts[1];
|
(comparedProducts[0]?.simulationData?.productionCapacity ?? 0) >
|
||||||
|
(comparedProducts[1]?.simulationData?.productionCapacity ?? 0)
|
||||||
|
? comparedProducts[0]
|
||||||
|
: comparedProducts[1];
|
||||||
|
|
||||||
const product1CyclePercentage =
|
const product1CyclePercentage =
|
||||||
((comparedProducts[0]?.simulationData?.machineActiveTime ?? 0) /
|
((comparedProducts[0]?.simulationData?.machineActiveTime ?? 0) /
|
||||||
((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[0]?.simulationData?.machineIdleTime ?? 0))) *
|
((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) +
|
||||||
|
(compareProductsData[0]?.simulationData?.machineIdleTime ?? 0))) *
|
||||||
100;
|
100;
|
||||||
const product2CyclePercentage =
|
const product2CyclePercentage =
|
||||||
((comparedProducts[1]?.simulationData?.machineActiveTime ?? 0) /
|
((comparedProducts[1]?.simulationData?.machineActiveTime ?? 0) /
|
||||||
((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) *
|
((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) +
|
||||||
|
(compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) *
|
||||||
100;
|
100;
|
||||||
|
|
||||||
const product1IdlePercentage =
|
const product1IdlePercentage =
|
||||||
((comparedProducts[0]?.simulationData?.machineIdleTime ?? 0) /
|
((comparedProducts[0]?.simulationData?.machineIdleTime ?? 0) /
|
||||||
((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[0]?.simulationData?.machineIdleTime ?? 0))) *
|
((compareProductsData[0]?.simulationData?.machineActiveTime ?? 0) +
|
||||||
|
(compareProductsData[0]?.simulationData?.machineIdleTime ?? 0))) *
|
||||||
100;
|
100;
|
||||||
|
console.log(
|
||||||
|
"product1IdlePercentage: ",
|
||||||
|
compareProductsData[0]?.simulationData?.machineIdleTime
|
||||||
|
);
|
||||||
const product2IdlePercentage =
|
const product2IdlePercentage =
|
||||||
((comparedProducts[1]?.simulationData?.machineIdleTime ?? 0) /
|
((comparedProducts[1]?.simulationData?.machineIdleTime ?? 0) /
|
||||||
((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) + (compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) *
|
((compareProductsData[1]?.simulationData?.machineActiveTime ?? 0) +
|
||||||
|
(compareProductsData[1]?.simulationData?.machineIdleTime ?? 0))) *
|
||||||
100;
|
100;
|
||||||
|
console.log(
|
||||||
|
"product2IdlePercentage: ",
|
||||||
|
compareProductsData[1]?.simulationData?.machineIdleTime
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="compare-result-container">
|
<div className="compare-result-container">
|
||||||
@@ -147,16 +172,28 @@ const ComparisonResult = () => {
|
|||||||
<div className="layers-wrapper">
|
<div className="layers-wrapper">
|
||||||
<div className="layers">
|
<div className="layers">
|
||||||
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
||||||
<div className="layer-time">{compareProductsData[0]?.simulationData.machineActiveTime} Sec</div>
|
<div className="layer-time">
|
||||||
<div className={`layer-change ${product1CyclePercentage >= 50 ? "profit" : "loss"}`}>
|
{compareProductsData[0]?.simulationData.machineActiveTime} Sec
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`layer-change ${
|
||||||
|
product1CyclePercentage >= 50 ? "profit" : "loss"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<span>{product1CyclePercentage >= 50 ? "↑" : "↓"}</span>
|
<span>{product1CyclePercentage >= 50 ? "↑" : "↓"}</span>
|
||||||
{(100 - product1CyclePercentage).toFixed(2)}%
|
{(100 - product1CyclePercentage).toFixed(2)}%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="layers">
|
<div className="layers">
|
||||||
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
||||||
<div className="layer-time">{compareProductsData[1]?.simulationData.machineActiveTime} Sec</div>
|
<div className="layer-time">
|
||||||
<div className={`layer-change ${product2CyclePercentage >= 50 ? "profit" : "loss"}`}>
|
{compareProductsData[1]?.simulationData.machineActiveTime} Sec
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`layer-change ${
|
||||||
|
product2CyclePercentage >= 50 ? "profit" : "loss"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<span>{product2CyclePercentage >= 50 ? "↑" : "↓"}</span>
|
<span>{product2CyclePercentage >= 50 ? "↑" : "↓"}</span>
|
||||||
{(100 - product2CyclePercentage).toFixed(2)}%
|
{(100 - product2CyclePercentage).toFixed(2)}%
|
||||||
</div>
|
</div>
|
||||||
@@ -171,23 +208,69 @@ const ComparisonResult = () => {
|
|||||||
{/* <EnergyUsage comparedProducts={comparedProducts} /> */}
|
{/* <EnergyUsage comparedProducts={comparedProducts} /> */}
|
||||||
<div className="cycle-time-container comparisionCard">
|
<div className="cycle-time-container comparisionCard">
|
||||||
<div className="cycle-main">
|
<div className="cycle-main">
|
||||||
<div className="cycle-header">Human Idle Time</div>
|
<div className="cycle-header">Machine Idle Time</div>
|
||||||
{/* <div className="cycle-header">Overall Downtime</div> */}
|
{/* <div className="cycle-header">Overall Downtime</div> */}
|
||||||
<div className="layers-wrapper">
|
<div className="layers-wrapper">
|
||||||
<div className="layers">
|
<div className="layers">
|
||||||
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
<div className="layer-name">{comparedProducts[0]?.productName}</div>
|
||||||
<div className="layer-time">{compareProductsData[0]?.simulationData.machineIdleTime} Sec</div>
|
<div className="layer-time">
|
||||||
<div className={`layer-profit ${product1IdlePercentage >= 50 ? "profit" : "loss"}`}>
|
{compareProductsData[0]?.simulationData.machineIdleTime} Sec
|
||||||
<span>{product1IdlePercentage >= 50 ? "↑" : "↓"}</span>
|
</div>
|
||||||
{(100 - product1IdlePercentage).toFixed(2)}%
|
<div
|
||||||
|
className={`layer-profit ${
|
||||||
|
compareProductsData[0]?.simulationData?.machineIdleTime >
|
||||||
|
compareProductsData[1]?.simulationData?.machineIdleTime
|
||||||
|
? "profit"
|
||||||
|
: "loss"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{compareProductsData[0]?.simulationData?.machineIdleTime >
|
||||||
|
compareProductsData[1]?.simulationData?.machineIdleTime
|
||||||
|
? "↑"
|
||||||
|
: "↓"}
|
||||||
|
</span>
|
||||||
|
{(
|
||||||
|
((compareProductsData[0]?.simulationData?.machineIdleTime ??
|
||||||
|
0) /
|
||||||
|
((compareProductsData[0]?.simulationData
|
||||||
|
?.machineActiveTime ?? 0) +
|
||||||
|
(compareProductsData[1]?.simulationData
|
||||||
|
?.machineIdleTime ?? 0))) *
|
||||||
|
100
|
||||||
|
).toFixed(2)}
|
||||||
|
%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="layers">
|
<div className="layers">
|
||||||
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
<div className="layer-name">{comparedProducts[1]?.productName}</div>
|
||||||
<div className="layer-time">{compareProductsData[1]?.simulationData.machineIdleTime} Sec</div>
|
<div className="layer-time">
|
||||||
<div className={`layer-profit ${product2IdlePercentage >= 50 ? "profit" : "loss"}`}>
|
{compareProductsData[1]?.simulationData.machineIdleTime} Sec
|
||||||
<span>{product2IdlePercentage >= 50 ? "↑" : "↓"}</span>
|
</div>
|
||||||
{(100 - product2IdlePercentage).toFixed(2)}%
|
<div
|
||||||
|
className={`layer-profit ${
|
||||||
|
compareProductsData[1]?.simulationData?.machineIdleTime >
|
||||||
|
compareProductsData[0]?.simulationData?.machineIdleTime
|
||||||
|
? "profit"
|
||||||
|
: "loss"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{compareProductsData[1]?.simulationData?.machineIdleTime >
|
||||||
|
compareProductsData[0]?.simulationData?.machineIdleTime
|
||||||
|
? "↑"
|
||||||
|
: "↓"}
|
||||||
|
</span>
|
||||||
|
{(
|
||||||
|
((compareProductsData[1]?.simulationData?.machineIdleTime ??
|
||||||
|
0) /
|
||||||
|
((compareProductsData[1]?.simulationData
|
||||||
|
?.machineActiveTime ?? 0) +
|
||||||
|
(compareProductsData[0]?.simulationData
|
||||||
|
?.machineIdleTime ?? 0))) *
|
||||||
|
100
|
||||||
|
).toFixed(2)}
|
||||||
|
%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -201,11 +284,15 @@ const ComparisonResult = () => {
|
|||||||
<div className="layers-wrapper">
|
<div className="layers-wrapper">
|
||||||
<div className="layer-wrapper">
|
<div className="layer-wrapper">
|
||||||
<div className="key">{comparedProducts[0]?.productName}</div>
|
<div className="key">{comparedProducts[0]?.productName}</div>
|
||||||
<div className="value">{comparedProducts[0]?.simulationData.throughputData}/ hr</div>
|
<div className="value">
|
||||||
|
{comparedProducts[0]?.simulationData.throughputData}/ hr
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="layer-wrapper">
|
<div className="layer-wrapper">
|
||||||
<div className="key">{comparedProducts[1]?.productName}</div>
|
<div className="key">{comparedProducts[1]?.productName}</div>
|
||||||
<div className="value">{comparedProducts[1]?.simulationData.throughputData}/ hr</div>
|
<div className="value">
|
||||||
|
{comparedProducts[1]?.simulationData.throughputData}/ hr
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="chart">
|
<div className="chart">
|
||||||
<Bar data={throughputData} options={options} />
|
<Bar data={throughputData} options={options} />
|
||||||
@@ -236,9 +323,13 @@ const ComparisonResult = () => {
|
|||||||
<h4 className="overallScrapRate-header">Production Capacity</h4>
|
<h4 className="overallScrapRate-header">Production Capacity</h4>
|
||||||
<div className="overallScrapRate-wrapper">
|
<div className="overallScrapRate-wrapper">
|
||||||
<div className="overallScrapRate-value">
|
<div className="overallScrapRate-value">
|
||||||
<div className="overallScrapRate-label">{highestProductivityProduct?.productName}</div>
|
<div className="overallScrapRate-label">
|
||||||
|
{highestProductivityProduct?.productName}
|
||||||
|
</div>
|
||||||
<div className="overallScrapRate-key">Total product produced</div>
|
<div className="overallScrapRate-key">Total product produced</div>
|
||||||
<div className="overallScrapRateKey-value">{highestProductivityProduct?.simulationData.productionCapacity}</div>
|
<div className="overallScrapRateKey-value">
|
||||||
|
{highestProductivityProduct?.simulationData.productionCapacity}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="chart">
|
<div className="chart">
|
||||||
<Bar data={productionCapacityData} options={options} />
|
<Bar data={productionCapacityData} options={options} />
|
||||||
@@ -246,7 +337,9 @@ const ComparisonResult = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{comparedProducts.length === 2 && <PerformanceResult comparedProducts={comparedProducts} />}
|
{comparedProducts.length === 2 && (
|
||||||
|
<PerformanceResult comparedProducts={comparedProducts} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import React, { Suspense, useEffect, useState } from "react";
|
import { Suspense } from "react";
|
||||||
import { RenderInNewWindow } from "../../templates/CreateNewWindow";
|
import { RenderInNewWindow } from "../../templates/CreateNewWindow";
|
||||||
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
||||||
import { useCreateNewWindow, useLoadingProgress } from "../../../store/builder/store";
|
import { useCreateNewWindow, useLoadingProgress } from "../../../store/builder/store";
|
||||||
import Scene from "../../../modules/scene/scene";
|
import Scene from "../../../modules/scene/scene";
|
||||||
import ComparisonResult from "./ComparisonResult";
|
import ComparisonResult from "./ComparisonResult";
|
||||||
import Button from "./Button";
|
import Button from "./Button";
|
||||||
|
import LoadingPage from "../../templates/LoadingPage";
|
||||||
|
|
||||||
const NewWindowScene = () => {
|
const NewWindowScene = () => {
|
||||||
const { versionStore } = useSceneContext();
|
const { versionStore } = useSceneContext();
|
||||||
@@ -15,12 +16,21 @@ const NewWindowScene = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{selectedVersion?.versionId && (
|
{selectedVersion?.versionId && (
|
||||||
<div style={{ width: "100%", height: "100%" }}>
|
<div>
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<RenderInNewWindow
|
<RenderInNewWindow
|
||||||
title="3D Viewer"
|
title="3D Viewer"
|
||||||
onClose={() => setCreateNewWindow(false)}
|
onClose={() => setCreateNewWindow(false)}
|
||||||
>
|
>
|
||||||
|
{/* Wait a tick to access child window */}
|
||||||
|
<Scene layout="Comparison Layout" />
|
||||||
|
{
|
||||||
|
<LoadingPage
|
||||||
|
progress={loadingProgress}
|
||||||
|
renderOver={false}
|
||||||
|
returnDefault={true}
|
||||||
|
/>
|
||||||
|
}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@@ -31,7 +41,6 @@ const NewWindowScene = () => {
|
|||||||
>
|
>
|
||||||
<Button />
|
<Button />
|
||||||
</div>
|
</div>
|
||||||
<Scene layout="Comparison Layout" />
|
|
||||||
{!loadingProgress && <ComparisonResult />}
|
{!loadingProgress && <ComparisonResult />}
|
||||||
</RenderInNewWindow>
|
</RenderInNewWindow>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|||||||
@@ -11,7 +11,15 @@ import { useFrame, useThree } from "@react-three/fiber";
|
|||||||
|
|
||||||
import { useSceneContext } from "../scene/sceneContext";
|
import { useSceneContext } from "../scene/sceneContext";
|
||||||
import { useBuilderStore } from "../../store/builder/useBuilderStore";
|
import { useBuilderStore } from "../../store/builder/useBuilderStore";
|
||||||
import { useToggleView, useWallVisibility, useRoofVisibility, useShadows, useToolMode, useRenderDistance, useLimitDistance } from "../../store/builder/store";
|
import {
|
||||||
|
useToggleView,
|
||||||
|
useWallVisibility,
|
||||||
|
useRoofVisibility,
|
||||||
|
useShadows,
|
||||||
|
useToolMode,
|
||||||
|
useRenderDistance,
|
||||||
|
useLimitDistance,
|
||||||
|
} from "../../store/builder/store";
|
||||||
|
|
||||||
////////// 3D Function Imports //////////
|
////////// 3D Function Imports //////////
|
||||||
|
|
||||||
@@ -36,12 +44,12 @@ export default function Builder() {
|
|||||||
const csgRef = useRef<any>(null);
|
const csgRef = useRef<any>(null);
|
||||||
|
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
const { setToolMode } = useToolMode();
|
const { toolMode, setToolMode } = useToolMode();
|
||||||
const { setRoofVisibility } = useRoofVisibility();
|
const { setRoofVisibility } = useRoofVisibility();
|
||||||
const { setWallVisibility } = useWallVisibility();
|
const { setWallVisibility } = useWallVisibility();
|
||||||
const { setShadows } = useShadows();
|
const { setShadows } = useShadows();
|
||||||
const { setRenderDistance } = useRenderDistance();
|
const { setRenderDistance } = useRenderDistance();
|
||||||
const { setLimitDistance } = useLimitDistance();
|
const { limitDistance, setLimitDistance } = useLimitDistance();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { scene: storeScene, camera: storeCamera, controls: storeControls } = useSceneContext();
|
const { scene: storeScene, camera: storeCamera, controls: storeControls } = useSceneContext();
|
||||||
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
|
const { setHoveredPoint, setHoveredLine } = useBuilderStore();
|
||||||
@@ -72,7 +80,7 @@ export default function Builder() {
|
|||||||
setRenderDistance(data.renderDistance);
|
setRenderDistance(data.renderDistance);
|
||||||
setLimitDistance(data.limitDistance);
|
setLimitDistance(data.limitDistance);
|
||||||
});
|
});
|
||||||
}, [projectId]);
|
}, [projectId, toolMode]);
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (csgRef.current) {
|
if (csgRef.current) {
|
||||||
|
|||||||
@@ -5,16 +5,24 @@
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
background: var(--background-color-solid);
|
background: var(--background-color-solid);
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
&.comparisionLoading {
|
&.comparisionLoading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 50vw;
|
width: 50vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.newWindowLoading {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.loading-container {
|
.loading-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -32,8 +40,6 @@
|
|||||||
background: var(--faint-gradient-color);
|
background: var(--faint-gradient-color);
|
||||||
height: 50vh;
|
height: 50vh;
|
||||||
width: 50vw;
|
width: 50vw;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
|
|||||||
Reference in New Issue
Block a user