v3-ui #99

Merged
Vishnu merged 28 commits from v3-ui into main 2025-06-12 04:27:40 +00:00
21 changed files with 251 additions and 175 deletions
Showing only changes of commit 6bdb50e0e5 - Show all commits

47
app/package-lock.json generated
View File

@ -2026,7 +2026,7 @@
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/trace-mapping": "0.3.9" "@jridgewell/trace-mapping": "0.3.9"
}, },
@ -2038,7 +2038,7 @@
"version": "0.3.9", "version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10" "@jridgewell/sourcemap-codec": "^1.4.10"
@ -4180,25 +4180,6 @@
"url": "https://github.com/sponsors/gregberge" "url": "https://github.com/sponsors/gregberge"
} }
}, },
"node_modules/@testing-library/dom": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
"@types/aria-query": "^5.0.1",
"aria-query": "5.3.0",
"chalk": "^4.1.0",
"dom-accessibility-api": "^0.5.9",
"lz-string": "^1.5.0",
"pretty-format": "^27.0.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@testing-library/jest-dom": { "node_modules/@testing-library/jest-dom": {
"version": "5.17.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
@ -4310,25 +4291,25 @@
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"devOptional": true "dev": true
}, },
"node_modules/@tsconfig/node12": { "node_modules/@tsconfig/node12": {
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"devOptional": true "dev": true
}, },
"node_modules/@tsconfig/node14": { "node_modules/@tsconfig/node14": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"devOptional": true "dev": true
}, },
"node_modules/@tsconfig/node16": { "node_modules/@tsconfig/node16": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"devOptional": true "dev": true
}, },
"node_modules/@turf/along": { "node_modules/@turf/along": {
"version": "7.2.0", "version": "7.2.0",
@ -9082,7 +9063,7 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"devOptional": true "dev": true
}, },
"node_modules/cross-env": { "node_modules/cross-env": {
"version": "7.0.3", "version": "7.0.3",
@ -9959,7 +9940,7 @@
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true, "dev": true,
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
} }
@ -15343,7 +15324,7 @@
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"devOptional": true "dev": true
}, },
"node_modules/makeerror": { "node_modules/makeerror": {
"version": "1.0.12", "version": "1.0.12",
@ -20820,7 +20801,7 @@
"version": "10.9.2", "version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"@cspotcode/source-map-support": "^0.8.0", "@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7", "@tsconfig/node10": "^1.0.7",
@ -20863,7 +20844,7 @@
"version": "8.3.4", "version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"devOptional": true, "dev": true,
"dependencies": { "dependencies": {
"acorn": "^8.11.0" "acorn": "^8.11.0"
}, },
@ -20875,7 +20856,7 @@
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"devOptional": true "dev": true
}, },
"node_modules/tsconfig-paths": { "node_modules/tsconfig-paths": {
"version": "3.15.0", "version": "3.15.0",
@ -21371,7 +21352,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"devOptional": true "dev": true
}, },
"node_modules/v8-to-istanbul": { "node_modules/v8-to-istanbul": {
"version": "8.1.1", "version": "8.1.1",
@ -22430,7 +22411,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"devOptional": true, "dev": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }

View File

@ -183,6 +183,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
className="dashboard-card-container" className="dashboard-card-container"
onClick={navigateToProject} onClick={navigateToProject}
title={projectName} title={projectName}
onMouseLeave={() => setIsKebabOpen(false)}
> >
<div className="dashboard-card-wrapper"> <div className="dashboard-card-wrapper">
<div className="preview-container"> <div className="preview-container">

View File

@ -48,12 +48,12 @@ function MainScene() {
const { setFloatingWidget } = useFloatingWidget(); const { setFloatingWidget } = useFloatingWidget();
const { comparisonProduct } = useComparisonProduct(); const { comparisonProduct } = useComparisonProduct();
const handleSelectLayout = (option: string) => { const handleSelectLayout = (option: string) => {
const product = products.find((product) => product.productName === option); const product = products.find((product) => product.productName === option);
if (product) { if (product) {
setMainProduct(product.productUuid, product.productName); setMainProduct(product.productUuid, product.productName);
} }
}; };
return ( return (
<> <>
@ -108,7 +108,7 @@ function MainScene() {
<Scene layout="Main Layout" /> <Scene layout="Main Layout" />
</div> </div>
{selectedProduct && isVersionSaved && !isPlaying && ( {selectedProduct && isVersionSaved && !isPlaying && activeModule === "simulation" && (
<div className="selectLayout-wrapper"> <div className="selectLayout-wrapper">
<RegularDropDown <RegularDropDown
header={selectedProduct.productName} header={selectedProduct.productName}

View File

@ -10,12 +10,13 @@ const Header: React.FC = () => {
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore(); const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<div className="header-container"> <div className="header-container">
<div className="header-content"> <div className="header-content">
<div className="logo-container" onClick={() => navigate("/Dashboard")}> <button className="logo-container" onClick={()=>navigate("/Dashboard")}>
<LogoIcon /> <LogoIcon />
</div> </button>
<div className="header-title"> <div className="header-title">
<FileMenu /> <FileMenu />
</div> </div>

View File

@ -35,9 +35,8 @@ const SideBarLeft: React.FC = () => {
return ( return (
<div <div
className={`sidebar-left-wrapper ${ className={`sidebar-left-wrapper ${toggleUILeft && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"
toggleUILeft && !isVersionSaved ? "open" : "closed" }`}
}`}
> >
<Header /> <Header />
{toggleUILeft && ( {toggleUILeft && (

View File

@ -66,7 +66,7 @@ const SideBarRight: React.FC = () => {
return ( return (
<div <div
className={`sidebar-right-wrapper ${toggleUIRight && !isVersionSaved ? "open" : "closed" className={`sidebar-right-wrapper ${toggleUIRight && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"
}`} }`}
> >
<Header /> <Header />

View File

@ -19,7 +19,7 @@ const Analysis: React.FC = () => {
// { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } }, // { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } },
], ],
"Production capacity": [ "Production capacity": [
{ type: "default", inputs: { label: "Shift length", activeOption: "hr" } }, { type: "range", inputs: { label: "Shift length", activeOption: "hr" } },
{ type: "default", inputs: { label: "Shifts / day", activeOption: "unit" } }, { type: "default", inputs: { label: "Shifts / day", activeOption: "unit" } },
{ type: "default", inputs: { label: "Working days / year", activeOption: "days" } }, { type: "default", inputs: { label: "Working days / year", activeOption: "days" } },
{ type: "default", inputs: { label: "Yield rate", activeOption: "%" } }, { type: "default", inputs: { label: "Yield rate", activeOption: "%" } },

View File

@ -31,7 +31,7 @@ const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets,i
key={index} key={index}
label={preset.inputs.label} label={preset.inputs.label}
min={0} min={0}
max={0} max={8}
value={5} value={5}
/> />
); );

View File

@ -82,7 +82,7 @@ const ZoneProperties: React.FC = () => {
const checkZoneNameDuplicate = (name: string) => { const checkZoneNameDuplicate = (name: string) => {
return zones.some( return zones.some(
(zone: any) => (zone: any) =>
zone.zoneName.trim().toLowerCase() === name.trim().toLowerCase() && zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&
zone.zoneUuid !== selectedZone.zoneUuid zone.zoneUuid !== selectedZone.zoneUuid
); );
}; };

View File

@ -4,12 +4,14 @@ import { useDfxUpload } from "../../store/builder/store";
import DxfParser from "dxf-parser"; import DxfParser from "dxf-parser";
import { getWallPointsFromBlueprint } from "../../modules/builder/dfx/functions/getWallPointsFromBlueprint"; import { getWallPointsFromBlueprint } from "../../modules/builder/dfx/functions/getWallPointsFromBlueprint";
import { convertDXFToThree } from "../../modules/builder/dfx/functions/convertDxfToThree"; import { convertDXFToThree } from "../../modules/builder/dfx/functions/convertDxfToThree";
type DXFData = any import { AIIcon } from "../icons/ExportCommonIcons";
type DXFData = any;
const SelectFloorPlan: React.FC = () => { const SelectFloorPlan: React.FC = () => {
// Access layout state and state setters // Access layout state and state setters
const { currentLayout, setLayout } = useLayoutStore(); const { currentLayout, setLayout } = useLayoutStore();
// Access DXF-related states and setters // Access DXF-related states and setters
const { setDfxUploaded, setDfxGenerate, setObjValue, objValue } = useDfxUpload(); const { setDfxUploaded, setDfxGenerate, setObjValue, objValue } =
useDfxUpload();
// Local state to store the parsed DXF file // Local state to store the parsed DXF file
const [parsedFile, setParsedFile] = useState<DXFData | undefined>(undefined); const [parsedFile, setParsedFile] = useState<DXFData | undefined>(undefined);
@ -18,7 +20,9 @@ const SelectFloorPlan: React.FC = () => {
const [generate, setGenerate] = useState<boolean>(false); const [generate, setGenerate] = useState<boolean>(false);
// Handles file upload and DXF parsing // Handles file upload and DXF parsing
const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => { const handleFileUpload = async (
event: React.ChangeEvent<HTMLInputElement>
) => {
setLayout(null); // Reset current layout setLayout(null); // Reset current layout
setParsedFile(undefined); // Clear any previously parsed file setParsedFile(undefined); // Clear any previously parsed file
const file = event.target.files?.[0]; const file = event.target.files?.[0];
@ -52,15 +56,54 @@ const SelectFloorPlan: React.FC = () => {
// Trigger wall point generation when `generate` flag changes // Trigger wall point generation when `generate` flag changes
useEffect(() => { useEffect(() => {
if (parsedFile !== undefined) { if (parsedFile !== undefined) {
getWallPointsFromBlueprint({ parsedData: parsedFile, setDfxGenerate, objValue }); getWallPointsFromBlueprint({
parsedData: parsedFile,
setDfxGenerate,
objValue,
});
} }
}, [generate]); }, [generate]);
return ( return (
<div className="select-floorplane-wrapper"> <div className="select-floorplane-wrapper">
Preset Layouts Upload Layouts
<div className="presets-container">
<input
type="file"
id="file-upload"
accept=".dxf"
style={{ display: "none", width: "10px" }}
onChange={handleFileUpload}
/>
<label
htmlFor="file-upload"
className="preset upload-btn"
style={{
cursor: "pointer",
padding: "10px 48px",
}}
>
Upload
</label>
{parsedFile && (
<button
type="button"
id="generate-upload"
className="generate-walls-btn"
onClick={() => {
setDfxUploaded([]);
setLayout(null);
setGenerate(!generate);
}}
>
<AIIcon />
Generate
</button>
)}
</div>
or
<div className="presets-container"> <div className="presets-container">
<button <button
className={`preset ${currentLayout === "layout1" ? "active" : ""}`} className={`preset ${currentLayout === "layout1" ? "active" : ""}`}
@ -83,37 +126,6 @@ const SelectFloorPlan: React.FC = () => {
> >
Preset 2 Preset 2
</button> </button>
<input
type="file"
id="file-upload"
accept=".dxf"
style={{ display: "none", width: "10px" }}
onChange={handleFileUpload}
/>
<label
htmlFor="file-upload"
className="preset"
style={{
cursor: "pointer",
padding: "10px 48px",
}}
>
Upload
</label>
<button
type="button"
id="generate-upload"
onClick={() => {
setDfxUploaded([]);
setLayout(null);
setGenerate(!generate);
}}
>
Generate
</button>
</div> </div>
</div> </div>
); );

View File

@ -9,7 +9,7 @@ import {
} from "chart.js"; } from "chart.js";
import { PowerIcon, ProductionCapacityIcon } from "../../icons/analysis"; import { PowerIcon, ProductionCapacityIcon } from "../../icons/analysis";
import SkeletonUI from "../../templates/SkeletonUI"; import SkeletonUI from "../../templates/SkeletonUI";
import { useInputValues, useMachineUptime, useProductionCapacityData } from "../../../store/builder/store"; import { useInputValues, useMachineUptime, useProductionCapacityData, useThroughPutData } from "../../../store/builder/store";
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement); ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
@ -34,6 +34,7 @@ const ThroughputSummary: React.FC = () => {
]; ];
const { productionCapacityData } = useProductionCapacityData() const { productionCapacityData } = useProductionCapacityData()
const { throughputData: data } = useThroughPutData()
const chartOptions = { const chartOptions = {
@ -103,6 +104,7 @@ const ThroughputSummary: React.FC = () => {
} }
}, [productionCapacityData]); }, [productionCapacityData]);
return ( return (
<> <>
{!isLoading && <div className="production analysis-card"> {!isLoading && <div className="production analysis-card">

View File

@ -14,7 +14,6 @@ const ProductionCapacity = ({
const { machineActiveTime } = useMachineUptime(); const { machineActiveTime } = useMachineUptime();
const { materialCycleTime } = useMaterialCycle(); const { materialCycleTime } = useMaterialCycle();
const { throughputData } = useThroughPutData() const { throughputData } = useThroughPutData()
const { productionCapacityData } = useProductionCapacityData()
const progressPercent = machineActiveTime; const progressPercent = machineActiveTime;

View File

@ -1,57 +1,89 @@
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import PerformanceResult from "./result-card/PerformanceResult"; import PerformanceResult from "./result-card/PerformanceResult";
import EnergyUsage from "./result-card/EnergyUsage"; import EnergyUsage from "./result-card/EnergyUsage";
import { Bar } from "react-chartjs-2"; import { Bar, Line } from "react-chartjs-2";
const ComparisonResult = () => { const ComparisonResult = () => {
const defaultData = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "Dataset",
data: [12, 19, 3, 5, 2, 3],
backgroundColor: ["#6f42c1"],
borderColor: "#b392f0",
borderWidth: 1,
},
],
};
// Memoize Chart Options
const options = useMemo( const options = useMemo(
() => ({ () => ({
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { plugins: {
title: { title: { display: false },
display: true, legend: { display: false },
},
legend: {
display: false,
},
}, },
scales: { scales: {
x: { x: { display: false, grid: { display: false } },
display: false, // Hide x-axis y: { display: false, grid: { display: false } },
grid: {
display: false,
},
},
y: {
display: false, // Hide y-axis
grid: {
display: false,
},
},
}, },
}), }),
[] []
); );
// Color palette
const purpleDark = "#6a0dad";
const purpleLight = "#b19cd9";
const throughputData = {
labels: ["Layout 1", "Layout 2"],
datasets: [
{
label: "Throughput (units/hr)",
data: [500, 550],
backgroundColor: [purpleDark, purpleLight],
borderColor: [purpleDark, purpleLight],
borderWidth: 1,
},
],
};
const cycleTimeData = {
labels: ["Layout 1", "Layout 2"],
datasets: [
{
label: "Cycle Time (sec)",
data: [110, 110],
backgroundColor: [purpleLight],
borderColor: purpleDark,
borderWidth: 2,
tension: 0.4,
fill: false,
},
],
};
const downtimeData = {
labels: ["Layout 1", "Layout 2"],
datasets: [
{
label: "Downtime (mins)",
data: [17, 12],
backgroundColor: [purpleDark, purpleLight],
borderColor: [purpleDark, purpleLight],
borderWidth: 1,
},
],
};
const scrapRateData = {
labels: ["Layout 1", "Layout 2"],
datasets: [
{
label: "Scrap Rate (tons)",
data: [2.7, 1.9],
backgroundColor: [purpleDark, purpleLight],
borderColor: [purpleDark, purpleLight],
borderWidth: 1,
},
],
};
return ( return (
<div className="compare-result-container"> <div className="compare-result-container">
<div className="header">Performance Comparison</div> <div className="header">Performance Comparison</div>
<div className="compare-result-wrapper"> <div className="compare-result-wrapper">
<EnergyUsage /> <EnergyUsage />
<div className="throughPutCard-container comparisionCard"> <div className="throughPutCard-container comparisionCard">
<h4>Throughput (units/hr)</h4> <h4>Throughput (units/hr)</h4>
<div className="layers-wrapper"> <div className="layers-wrapper">
@ -64,8 +96,11 @@ const ComparisonResult = () => {
<div className="value">550/ hr</div> <div className="value">550/ hr</div>
</div> </div>
</div> </div>
<div className="chart"></div> <div className="chart">
<Bar data={throughputData} options={options} />
</div>
</div> </div>
<div className="cycle-time-container comparisionCard"> <div className="cycle-time-container comparisionCard">
<div className="cycle-main"> <div className="cycle-main">
<div className="cycle-header">Cycle Time</div> <div className="cycle-header">Cycle Time</div>
@ -81,12 +116,16 @@ const ComparisonResult = () => {
<div className="layer-name">Layout 2</div> <div className="layer-name">Layout 2</div>
<div className="layer-time">110 Sec</div> <div className="layer-time">110 Sec</div>
<div className="layer-profit"> <div className="layer-profit">
<span></span>19.6%1.6% <span></span>1.6%
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div className="chart">
<Line data={cycleTimeData} options={options} />
</div>
</div> </div>
<div className="overallDowntime-container comparisionCard"> <div className="overallDowntime-container comparisionCard">
<div className="overallDowntime-header">Overall Downtime</div> <div className="overallDowntime-header">Overall Downtime</div>
<div className="totalDownTime-wrapper"> <div className="totalDownTime-wrapper">
@ -101,10 +140,7 @@ const ComparisonResult = () => {
</div> </div>
</div> </div>
<div className="chart"> <div className="chart">
<div className="vertical-chart"> <Bar data={downtimeData} options={options} />
<div className="layout1"></div>
<div className="layout2"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -114,16 +150,15 @@ const ComparisonResult = () => {
<div className="overallScrapRate-wrapper"> <div className="overallScrapRate-wrapper">
<div className="overallScrapRate-value"> <div className="overallScrapRate-value">
<div className="overallScrapRate-label">Layout 1</div> <div className="overallScrapRate-label">Layout 1</div>
<div className="overallScrapRate-key"> <div className="overallScrapRate-key">Total scrap produced by</div>
Total scrap produced by
</div>
<div className="overallScrapRateKey-value">2.7 ton</div> <div className="overallScrapRateKey-value">2.7 ton</div>
</div> </div>
<div className="chart"> <div className="chart">
<Bar data={defaultData} options={options} /> <Bar data={scrapRateData} options={options} />
</div> </div>
</div> </div>
</div> </div>
<PerformanceResult /> <PerformanceResult />
</div> </div>
</div> </div>

View File

@ -18,7 +18,6 @@ import {
} from "../../../store/builder/store"; } from "../../../store/builder/store";
import { zoneCameraUpdate } from "../../../services/visulization/zone/zoneCameraUpdation"; import { zoneCameraUpdate } from "../../../services/visulization/zone/zoneCameraUpdation";
import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
import OuterClick from "../../../utils/outerClick";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useAssetsStore } from "../../../store/builder/useAssetStore"; import { useAssetsStore } from "../../../store/builder/useAssetStore";
@ -111,7 +110,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
const isDuplicate = zones.some( const isDuplicate = zones.some(
(zone: any) => (zone: any) =>
zone.zoneName.trim().toLowerCase() === newName.trim().toLowerCase() && zone.zoneName?.trim().toLowerCase() === newName?.trim().toLowerCase() &&
zone.zoneUuid !== selectedZone.zoneUuid zone.zoneUuid !== selectedZone.zoneUuid
); );
@ -154,7 +153,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
const checkZoneNameDuplicate = (name: string) => { const checkZoneNameDuplicate = (name: string) => {
return zones.some( return zones.some(
(zone: any) => (zone: any) =>
zone.zoneName.trim().toLowerCase() === name.trim().toLowerCase() && zone.zoneName?.trim().toLowerCase() === name?.trim().toLowerCase() &&
zone.zoneUuid !== selectedZone.zoneUuid zone.zoneUuid !== selectedZone.zoneUuid
); );
}; };

View File

@ -1,6 +1,10 @@
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 { useActiveTool, useProcessBar } from "../../../store/builder/store"; import {
useActiveTool,
useProcessBar,
useViewSceneStore,
} from "../../../store/builder/store";
import { import {
useAnimationPlaySpeed, useAnimationPlaySpeed,
usePauseButtonStore, usePauseButtonStore,
@ -19,12 +23,15 @@ import {
StartIcon, StartIcon,
} from "../../icons/ExportCommonIcons"; } from "../../icons/ExportCommonIcons";
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor"; import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
import { useSubModuleStore } from "../../../store/useModuleStore"; import useModuleStore, {
useSubModuleStore,
} from "../../../store/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/useUIToggleStore"; import { usePlayerStore } from "../../../store/useUIToggleStore";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore"; import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
import InputToggle from "../inputs/InputToggle";
const SimulationPlayer: React.FC = () => { const SimulationPlayer: React.FC = () => {
const MAX_SPEED = 4; // Maximum speed const MAX_SPEED = 4; // Maximum speed
@ -41,7 +48,10 @@ const SimulationPlayer: React.FC = () => {
const { isReset, setReset } = useResetButtonStore(); const { isReset, setReset } = useResetButtonStore();
const { subModule } = useSubModuleStore(); const { subModule } = useSubModuleStore();
const { clearComparisonProduct } = useComparisonProduct(); const { clearComparisonProduct } = useComparisonProduct();
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
const { isPlaying } = usePlayButtonStore();
const { activeModule } = useModuleStore();
useEffect(() => { useEffect(() => {
if (isReset) { if (isReset) {
setTimeout(() => { setTimeout(() => {
@ -113,11 +123,10 @@ const SimulationPlayer: React.FC = () => {
// UI-Part // UI-Part
const hourlySimulation = 25; const hourlySimulation = 25;
const dailyProduction = 75; const dailyProduction = 75;
const monthlyROI = 50; const monthlyROI = 10;
const { processBar } = useProcessBar(); const { processBar } = useProcessBar();
useEffect(() => { useEffect(() => { }, [processBar]);
}, [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;
@ -157,6 +166,16 @@ const SimulationPlayer: React.FC = () => {
return ( return (
<> <>
{isPlaying && activeModule === "simulation" && (
<div className="label-toogler">
<InputToggle
value={viewSceneLabels}
inputKey="1"
label="Enable View Labels"
onClick={() => setViewSceneLabels(!viewSceneLabels)}
/>
</div>
)}
<div className={`simulation-player-wrapper${hidePlayer ? " hide" : ""}`}> <div className={`simulation-player-wrapper${hidePlayer ? " hide" : ""}`}>
<div className={`simulation-player-container ${expand ? "open" : ""}`}> <div className={`simulation-player-container ${expand ? "open" : ""}`}>
<div className="controls-container"> <div className="controls-container">
@ -203,7 +222,7 @@ const SimulationPlayer: React.FC = () => {
<div className="progress-wrapper"> <div className="progress-wrapper">
<div <div
className="progress" className="progress"
style={{ width: monthlyROI }} style={{ width: `${monthlyROI}%` }}
></div> ></div>
</div>{" "} </div>{" "}
</div> </div>
@ -212,9 +231,7 @@ const SimulationPlayer: React.FC = () => {
{!hidePlayer && subModule !== "analysis" && ( {!hidePlayer && subModule !== "analysis" && (
<div className="header"> <div className="header">
<InfoIcon /> <InfoIcon />
{isPaused {isPaused ? "Paused - system idle." : "Running simulation..."}
? "Paused - system idle."
: "Running simulation..."}
</div> </div>
)} )}
<div className="controls-wrapper"> <div className="controls-wrapper">

View File

@ -373,7 +373,7 @@
left: 50%; left: 50%;
transform: translate(-50%, 0); transform: translate(-50%, 0);
color: var(--accent-color); color: var(--accent-color);
z-index: 100; z-index: 2;
isolation: isolate; isolation: isolate;
font-weight: 700; font-weight: 700;
padding: 8px; padding: 8px;

View File

@ -36,6 +36,7 @@
align-items: center; align-items: center;
animation: slideInFromRight 0.4s ease-out forwards; animation: slideInFromRight 0.4s ease-out forwards;
user-select: none; user-select: none;
border-left: 2px solid var(--border-color);
.resizer { .resizer {
width: 32px; width: 32px;
@ -474,6 +475,7 @@
} }
.chart { .chart {
width: 80%;
height: 90%; height: 90%;
position: absolute; position: absolute;
bottom: 0; bottom: 0;

View File

@ -73,6 +73,7 @@
.logo-container { .logo-container {
@include flex-center; @include flex-center;
cursor: pointer;
} }
.header-title { .header-title {
@ -221,7 +222,7 @@
padding: 13px 5px; padding: 13px 5px;
background: var(--background-color-secondary); background: var(--background-color-secondary);
border-radius: #{$border-radius-medium}; border-radius: #{$border-radius-medium};
box-shadow:var(--box-shadow-light); box-shadow: var(--box-shadow-light);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -873,8 +874,6 @@
.input-range-container { .input-range-container {
width: 100%; width: 100%;
padding: 0; padding: 0;
.input-container {}
} }
} }
@ -1360,9 +1359,11 @@
.aisle-properties-container { .aisle-properties-container {
max-height: 65vh; max-height: 65vh;
overflow: auto; overflow: auto;
.aisle-texture-container { .aisle-texture-container {
max-height: 40vh; max-height: 40vh;
overflow: auto; overflow: auto;
.aisle-list { .aisle-list {
width: calc(100% - 8px); width: calc(100% - 8px);
text-align: start; text-align: start;
@ -1372,6 +1373,7 @@
gap: 6px; gap: 6px;
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
margin: 2px 6px; margin: 2px 6px;
.texture-display { .texture-display {
height: 34px; height: 34px;
width: 34px; width: 34px;
@ -1380,63 +1382,78 @@
margin-right: 4px; margin-right: 4px;
overflow: hidden; overflow: hidden;
} }
.aisle-color { .aisle-color {
text-transform: capitalize; text-transform: capitalize;
} }
.aisle-brief { .aisle-brief {
font-size: var(--font-size-small); font-size: var(--font-size-small);
color: var(--input-text-color); color: var(--input-text-color);
} }
&.selected { &.selected {
background: var(--background-color-accent); background: var(--background-color-accent);
color: var(--text-button-color); color: var(--text-button-color);
&:hover { &:hover {
background: var(--background-color-accent); background: var(--background-color-accent);
} }
} }
&:hover { &:hover {
background: var(--background-color-secondary); background: var(--background-color-secondary);
} }
} }
} }
.value-field-container { .value-field-container {
margin: 0; margin: 0;
} }
.presets-list-container { .presets-list-container {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 6px; gap: 6px;
padding: 6px; padding: 6px;
padding-left: 7px; padding-left: 7px;
.preset-list { .preset-list {
background: #444; background: #444;
height: 90px; height: 90px;
width: 90px; width: 90px;
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
overflow: hidden; overflow: hidden;
.thumbnail { .thumbnail {
height: 100%; height: 100%;
width: 100%; width: 100%;
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
outline-offset: -1px; outline-offset: -1px;
img { img {
height: 100%; height: 100%;
width: 100%; width: 100%;
object-fit: cover; object-fit: cover;
transition: all 0.2s; transition: all 0.2s;
} }
&.selected { &.selected {
outline: 2px solid var(--border-color-accent); outline: 2px solid var(--border-color-accent);
outline-offset: -2px; outline-offset: -2px;
&:hover { &:hover {
outline: 2px solid var(--border-color-accent); outline: 2px solid var(--border-color-accent);
img { img {
transform: scale(1); transform: scale(1);
} }
} }
} }
&:hover { &:hover {
outline: 1px solid var(--border-color); outline: 1px solid var(--border-color);
img { img {
transform: scale(1.1); transform: scale(1.1);
} }
@ -1456,6 +1473,7 @@
padding: 10px 12px; padding: 10px 12px;
color: var(--text-color); color: var(--text-color);
width: 100%; width: 100%;
.input-value { .input-value {
color: inherit; color: inherit;
} }
@ -1509,7 +1527,6 @@
.header { .header {
@include flex-space-between; @include flex-space-between;
border: none; border: none;
.eyedrop-button { .eyedrop-button {
@include flex-center; @include flex-center;
} }
@ -1517,9 +1534,8 @@
.inputs-container { .inputs-container {
@include flex-space-between; @include flex-space-between;
.input-container { .input-container {
padding: 0 12px; padding: 0 4px;
gap: 6px; gap: 6px;
} }
} }
@ -1837,11 +1853,9 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
font-size: var(--font-size-regular); font-size: var(--font-size-regular);
background: linear-gradient( background: linear-gradient(0deg,
0deg, rgba(37, 24, 51, 0) 0%,
rgba(37, 24, 51, 0) 0%, rgba(52, 41, 61, 0.5) 100%);
rgba(52, 41, 61, 0.5) 100%
);
pointer-events: none; pointer-events: none;
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
opacity: 0; opacity: 0;

View File

@ -14,7 +14,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
// border-right: 1px solid var(--border-color);
background: var(--background-color); background: var(--background-color);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
border-radius: 30px; border-radius: 30px;
@ -33,8 +32,8 @@
line-height: 32px; line-height: 32px;
text-align: center; text-align: center;
font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium);
background: var(--accent-color); background: var(--background-color-accent);
color: var(--primary-color); color: var(--text-button-color);
border-radius: #{$border-radius-circle}; border-radius: #{$border-radius-circle};
} }
@ -85,6 +84,12 @@
font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium);
background: var(--background-color-button); background: var(--background-color-button);
svg {
path {
stroke: var(--background-color-selected);
}
}
&:hover { &:hover {
background: var(--background-color-button); background: var(--background-color-button);
} }
@ -165,10 +170,8 @@
position: relative; position: relative;
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
border-radius: #{$border-radius-extra-large}; border-radius: #{$border-radius-extra-large};
overflow: hidden;
cursor: pointer; cursor: pointer;
overflow: visible; overflow: visible;
position: relative;
.dashboard-card-wrapper { .dashboard-card-wrapper {
width: 100%; width: 100%;
@ -199,13 +202,16 @@
width: 100%; width: 100%;
padding: 13px 16px; padding: 13px 16px;
background: var(--background-color); background: var(--background-color);
// backdrop-filter: blur(18px);
border-radius: #{$border-radius-xlarge}; border-radius: #{$border-radius-xlarge};
// transform: translateY(100%);///////hovered // transform: translateY(100%);///////hovered
transition: transform 0.25s linear; transition: transform 0.25s linear;
.project-details { .project-details {
display: flex;
flex-direction: column;
align-items: flex-start;
.project-name { .project-name {
margin-bottom: 7px; margin-bottom: 7px;
} }
@ -226,7 +232,7 @@
line-height: 26px; line-height: 26px;
text-align: center; text-align: center;
background: var(--accent-color); background: var(--accent-color);
color: var(--primary-color); color: var(--text-color);
border-radius: #{$border-radius-circle}; border-radius: #{$border-radius-circle};
} }
@ -247,7 +253,7 @@
border-radius: 8px; border-radius: 8px;
z-index: 100; z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
display: flex; backdrop-filter: blur(20px);
flex-direction: column; flex-direction: column;
transform: translate(100%, 100%); transform: translate(100%, 100%);
overflow: hidden; overflow: hidden;
@ -265,16 +271,18 @@
text-transform: capitalize; text-transform: capitalize;
&:hover { &:hover {
background-color: var(--background-color-secondary); background-color: var(--background-color-selected);
} }
} }
} }
&:hover { &:hover {
overflow: visible; overflow: visible;
.kebab-options-wrapper { .kebab-options-wrapper {
display: flex; display: flex;
} }
.project-details-container { .project-details-container {
transform: translateY(0); transform: translateY(0);
} }

View File

@ -66,7 +66,7 @@
.presets-container { .presets-container {
@include flex-center; @include flex-center;
gap: 4px; gap: 6px;
.preset { .preset {
background: var(--background-color); background: var(--background-color);
@ -74,7 +74,17 @@
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
outline: 1px solid var(--border-color); outline: 1px solid var(--border-color);
} }
.upload-btn{
padding: 4px 16px !important;
}
.generate-walls-btn{
padding: 4px 16px;
@include flex-center;
gap: 4px;
color: var(--text-button-color);
background: var(--background-color-button);
border-radius: #{$border-radius-extra-large};
}
.active { .active {
background: var(--background-color-accent); background: var(--background-color-accent);
color: var(--text-button-color); color: var(--text-button-color);
@ -82,17 +92,11 @@
} }
} }
.label-toogler { .label-toogler {
position: fixed; position: fixed;
bottom: 4%; bottom: 4%;
right: 1.5%; right: 1.5%;
z-index: 10; z-index: 10;
// background: var(--background-color);
// backdrop-filter: blur(10px);
// outline: 1px solid var(--border-color);
border-radius: 8px; border-radius: 8px;
.input-toggle-container { .input-toggle-container {

View File

@ -3,6 +3,8 @@ type Preset = {
inputs: { inputs: {
label: string; label: string;
activeOption: string; activeOption: string;
min?: number;
max?: number;
}; };
}; };