added logs list
This commit is contained in:
@@ -458,7 +458,7 @@ export function InfoIcon() {
|
||||
>
|
||||
<path
|
||||
d="M5.46289 7.75441C5.46289 7.68342 5.47691 7.6131 5.50422 7.54758C5.53158 7.48201 5.57156 7.42254 5.62201 7.37257C5.67246 7.3226 5.73231 7.2831 5.79807 7.25636C5.86388 7.22963 5.93425 7.21619 6.00529 7.21681C6.11003 7.21873 6.21188 7.25142 6.29814 7.31089C6.38435 7.37036 6.45121 7.45398 6.49019 7.55118C6.52921 7.64843 6.53862 7.75499 6.5174 7.85757C6.49614 7.96014 6.44511 8.05417 6.37071 8.12795C6.29631 8.20168 6.20185 8.25184 6.09908 8.27219C5.99631 8.29254 5.8898 8.28212 5.79294 8.24224C5.69603 8.2024 5.61308 8.13486 5.55438 8.04808C5.49567 7.96134 5.46385 7.8592 5.46289 7.75441ZM5.63564 6.44401L5.56844 3.93842C5.56206 3.87819 5.56844 3.81729 5.58716 3.75968C5.60583 3.70207 5.63641 3.64902 5.67692 3.604C5.71743 3.55897 5.76697 3.52297 5.82227 3.49832C5.87761 3.47368 5.93751 3.46094 5.99804 3.46094C6.05862 3.46094 6.11852 3.47368 6.17387 3.49832C6.22916 3.52297 6.2787 3.55897 6.31921 3.604C6.35972 3.64902 6.3903 3.70207 6.40897 3.75968C6.42769 3.81729 6.43407 3.87819 6.42769 3.93842L6.36529 6.44401C6.36529 6.54073 6.32689 6.63356 6.25844 6.70196C6.19004 6.77036 6.09721 6.80881 6.00049 6.80881C5.90372 6.80881 5.81094 6.77036 5.74254 6.70196C5.67414 6.63356 5.63564 6.54073 5.63564 6.44401Z"
|
||||
fill="var(--icon-default-color)"
|
||||
fill="var(--text-color)"
|
||||
/>
|
||||
<path
|
||||
d="M6.00006 10.3175C8.45219 10.3175 10.4401 8.32963 10.4401 5.8775C10.4401 3.42536 8.45219 1.4375 6.00006 1.4375C3.54792 1.4375 1.56006 3.42536 1.56006 5.8775C1.56006 8.32963 3.54792 10.3175 6.00006 10.3175Z"
|
||||
@@ -471,7 +471,7 @@ export function InfoIcon() {
|
||||
);
|
||||
}
|
||||
|
||||
export function AI_Icon() {
|
||||
export function AIIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="20"
|
||||
|
||||
@@ -125,21 +125,21 @@ export function ResetIcon() {
|
||||
>
|
||||
<path
|
||||
d="M2.54182 4.09637C3.33333 2.73422 4.80832 1.81836 6.49721 1.81836C9.02194 1.81836 11.0686 3.86506 11.0686 6.38979C11.0686 8.91452 9.02194 10.9612 6.49721 10.9612C3.97248 10.9612 1.92578 8.91452 1.92578 6.38979"
|
||||
stroke="var(--icon-default-color-active)"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M7.64118 6.38895C7.64118 7.02013 7.12951 7.53181 6.49833 7.53181C5.86714 7.53181 5.35547 7.02013 5.35547 6.38895C5.35547 5.75777 5.86714 5.24609 6.49833 5.24609C7.12951 5.24609 7.64118 5.75777 7.64118 6.38895Z"
|
||||
fill="var(--icon-default-color-active)"
|
||||
stroke="var(--icon-default-color-active)"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.571429"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M4.78125 4.10407H2.49554V1.81836"
|
||||
stroke="var(--icon-default-color-active)"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
@@ -158,7 +158,7 @@ export function PlayStopIcon() {
|
||||
>
|
||||
<path
|
||||
d="M8 2.88867V9.88867M11 2.88867V9.88867M2 3.99171V8.78562C2 9.28847 2 9.53987 2.09943 9.65627C2.1857 9.75732 2.31512 9.81092 2.44756 9.80047C2.60019 9.78847 2.77796 9.61072 3.13352 9.25517L5.5305 6.85817C5.69485 6.69382 5.777 6.61167 5.8078 6.51692C5.83485 6.43357 5.83485 6.34377 5.8078 6.26042C5.777 6.16567 5.69485 6.08352 5.5305 5.91917L3.13352 3.52219C2.77796 3.16664 2.60019 2.98886 2.44756 2.97685C2.31512 2.96643 2.1857 3.02004 2.09943 3.12105C2 3.23747 2 3.48888 2 3.99171Z"
|
||||
stroke="var(--icon-default-color-active)"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
@@ -177,7 +177,7 @@ export function ExitIcon() {
|
||||
>
|
||||
<path
|
||||
d="M2.08203 6.34311L5.03647 3.38867M2.08203 6.34311L5.03647 9.29755M2.08203 6.34311H5.9228C7.22276 6.34334 9.34995 7.05241 10.7681 9.88867"
|
||||
stroke="var(--icon-default-color-active)"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
|
||||
@@ -19,7 +19,7 @@ const Header: React.FC = () => {
|
||||
<FileMenu />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<button
|
||||
className={`toggle-sidebar-ui-button ${!toggleUI ? "active" : ""}`}
|
||||
onClick={() => {
|
||||
if (activeModule !== "market") {
|
||||
@@ -29,7 +29,7 @@ const Header: React.FC = () => {
|
||||
}}
|
||||
>
|
||||
<ToggleSidebarIcon />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { AI_Icon } from "../../../icons/ExportCommonIcons";
|
||||
import { AIIcon } from "../../../icons/ExportCommonIcons";
|
||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
||||
import { AnalysisPresetsType } from "../../../../types/analysis";
|
||||
import RenderAnalysisInputs from "./RenderAnalysisInputs";
|
||||
@@ -13,53 +13,24 @@ const Analysis: React.FC = () => {
|
||||
|
||||
const AnalysisPresets: AnalysisPresetsType = {
|
||||
"Throughput time": [
|
||||
{ type: "default", inputs: { label: "Height", activeOption: "mm" } },
|
||||
{ type: "default", inputs: { label: "Width", activeOption: "mm" } },
|
||||
{ type: "default", inputs: { label: "Length", activeOption: "mtr" } },
|
||||
{ type: "default", inputs: { label: "Thickness", activeOption: "mm" } },
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Raw Material", activeOption: "mm" },
|
||||
},
|
||||
{
|
||||
type: "range",
|
||||
inputs: { label: "Material flow", activeOption: "m/min" },
|
||||
},
|
||||
{ type: "default", inputs: { label: "Cycle time", activeOption: "s" } },
|
||||
{ type: "default", inputs: { label: "machines / lines", activeOption: "item" } },
|
||||
{ type: "default", inputs: { label: "Machine uptime", activeOption: "%" } },
|
||||
],
|
||||
"Production capacity": [
|
||||
{ type: "default", inputs: { label: "Height", activeOption: "mm" } },
|
||||
{ type: "default", inputs: { label: "Width", activeOption: "mm" } },
|
||||
{ type: "default", inputs: { label: "Length", activeOption: "mtr" } },
|
||||
{ type: "default", inputs: { label: "Thickness", activeOption: "mm" } },
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Raw Material", activeOption: "mm" },
|
||||
},
|
||||
{
|
||||
type: "range",
|
||||
inputs: { label: "Material flow", activeOption: "m/min" },
|
||||
},
|
||||
{
|
||||
type: "range",
|
||||
inputs: { label: "Shift 1", activeOption: "hr(s)" },
|
||||
},
|
||||
{
|
||||
type: "range",
|
||||
inputs: { label: "Shift 2", activeOption: "hr(s)" },
|
||||
},
|
||||
{
|
||||
type: "range",
|
||||
inputs: { label: "Over time", activeOption: "hr(s)" },
|
||||
},
|
||||
{ type: "default", inputs: { label: "Shift length", activeOption: "hr" } },
|
||||
{ type: "default", inputs: { label: "Shifts / day", activeOption: "unit" } },
|
||||
{ type: "default", inputs: { label: "Working days / year", activeOption: "days" } },
|
||||
{ type: "default", inputs: { label: "Yield rate", activeOption: "%" } },
|
||||
],
|
||||
ROI: [
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Equipment Cost", activeOption: "INR" },
|
||||
inputs: { label: "Selling price", activeOption: "INR" },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Employee Salary", activeOption: "INR" },
|
||||
inputs: { label: "Material cost", activeOption: "INR" },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
@@ -67,7 +38,7 @@ const Analysis: React.FC = () => {
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Cost per unit", activeOption: "INR" },
|
||||
inputs: { label: "Maintenance cost", activeOption: "INR" },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
@@ -75,20 +46,19 @@ const Analysis: React.FC = () => {
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Upkeep Cost", activeOption: "INR" },
|
||||
inputs: { label: "Fixed costs", activeOption: "INR" },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Working Hours", activeOption: "Hrs" },
|
||||
inputs: { label: "Salvage value", activeOption: "Hrs" },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Power Usage", activeOption: "KWH" },
|
||||
inputs: { label: "Production period", activeOption: "yrs" },
|
||||
},
|
||||
{ type: "default", inputs: { label: "KWH", activeOption: "Mos" } },
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Man Power", activeOption: "Person" },
|
||||
inputs: { label: "Tax rate", activeOption: "%" },
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -98,7 +68,7 @@ const Analysis: React.FC = () => {
|
||||
<div className="analysis-main-container">
|
||||
<div className="header">Object</div>
|
||||
<div className="generate-report-button">
|
||||
<AI_Icon /> Generate Report
|
||||
<AIIcon /> Generate Report
|
||||
</div>
|
||||
<div className="analysis-content-container section">
|
||||
<div className="dropdown-header-container">
|
||||
@@ -121,7 +91,7 @@ const Analysis: React.FC = () => {
|
||||
/>
|
||||
<div className="buttons-container">
|
||||
<input type="button" value={"Clear"} className="cancel" />
|
||||
<input type="button" value={"Calculate"} className="submit" />
|
||||
<input type="button" value={"Update"} className="submit" />
|
||||
</div>
|
||||
<div className="create-custom-analysis-container">
|
||||
<div className="custom-analysis-header">Create Custom Analysis</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import InputRange from "../../../ui/inputs/InputRange";
|
||||
import InputToggle from "../../../ui/inputs/InputToggle";
|
||||
import { AI_Icon } from "../../../icons/ExportCommonIcons";
|
||||
import { AIIcon } from "../../../icons/ExportCommonIcons";
|
||||
import LabeledButton from "../../../ui/inputs/LabledButton";
|
||||
import {
|
||||
useAzimuth,
|
||||
@@ -225,7 +225,7 @@ const GlobalProperties: React.FC = () => {
|
||||
<section>
|
||||
<div className="header">Environment</div>
|
||||
<div className="optimize-button" onClick={optimizeScene}>
|
||||
<AI_Icon />
|
||||
<AIIcon />
|
||||
Optimize
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
useSelectedEventData,
|
||||
useSelectedEventSphere,
|
||||
useSelectedProduct,
|
||||
useSelectedEventData,
|
||||
useSelectedEventSphere,
|
||||
useSelectedProduct,
|
||||
} from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useProductStore } from "../../../../../store/simulation/useProductStore";
|
||||
import ConveyorMechanics from "./mechanics/conveyorMechanics";
|
||||
@@ -15,114 +15,118 @@ import { handleAddEventToProduct } from "../../../../../modules/simulation/event
|
||||
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
||||
|
||||
const EventProperties: React.FC = () => {
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getEventByModelUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(null);
|
||||
const [assetType, setAssetType] = useState<string | null>(null);
|
||||
const { products, addEvent } = useProductStore();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { selectedEventData } = useSelectedEventData();
|
||||
const { getEventByModelUuid } = useProductStore();
|
||||
const { selectedProduct } = useSelectedProduct();
|
||||
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(
|
||||
null
|
||||
);
|
||||
const [assetType, setAssetType] = useState<string | null>(null);
|
||||
const { products, addEvent } = useProductStore();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
|
||||
useEffect(() => {
|
||||
const event = getCurrentEventData();
|
||||
setCurrentEventData(event);
|
||||
useEffect(() => {
|
||||
const event = getCurrentEventData();
|
||||
setCurrentEventData(event);
|
||||
|
||||
const type = determineAssetType(event);
|
||||
setAssetType(type);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const getCurrentEventData = () => {
|
||||
if (!selectedEventData?.data || !selectedProduct) return null;
|
||||
return (
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid
|
||||
) ?? null
|
||||
);
|
||||
};
|
||||
|
||||
const determineAssetType = (event: EventsSchema | null) => {
|
||||
if (!event) return null;
|
||||
|
||||
switch (event.type) {
|
||||
case "transfer":
|
||||
return "conveyor";
|
||||
case "vehicle":
|
||||
return "vehicle";
|
||||
case "roboticArm":
|
||||
return "roboticArm";
|
||||
case "machine":
|
||||
return "machine";
|
||||
case "storageUnit":
|
||||
return "storageUnit";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
const type = determineAssetType(event);
|
||||
setAssetType(type);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedEventData, selectedProduct]);
|
||||
|
||||
const getCurrentEventData = () => {
|
||||
if (!selectedEventData?.data || !selectedProduct) return null;
|
||||
return (
|
||||
<div className="event-proprties-wrapper">
|
||||
{currentEventData && (
|
||||
<>
|
||||
<div className="header">
|
||||
<div className="header-value">
|
||||
{selectedEventData?.data.modelName}
|
||||
</div>
|
||||
</div>
|
||||
{assetType === "conveyor" && <ConveyorMechanics />}
|
||||
{assetType === "vehicle" && <VehicleMechanics />}
|
||||
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
||||
{assetType === "machine" && <MachineMechanics />}
|
||||
{assetType === "storageUnit" && <StorageMechanics />}
|
||||
</>
|
||||
)}
|
||||
{!currentEventData && selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like this object doesn't have an
|
||||
event assigned yet. To continue, please link it to one of the
|
||||
products below.
|
||||
</p>
|
||||
|
||||
<div className="products-list">
|
||||
<p>
|
||||
<strong>Here are some products you can add it to:</strong>
|
||||
</p>
|
||||
<ul>
|
||||
{products.map((product) => (
|
||||
<li key={product.productId}>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (selectedEventData) {
|
||||
handleAddEventToProduct({
|
||||
event: useEventsStore.getState().getEventByModelUuid(selectedEventData?.data.modelUuid),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AddIcon />
|
||||
{product.productName}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{!selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like you haven't selected an event
|
||||
point yet. Please select an event to view its properties.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div >
|
||||
getEventByModelUuid(
|
||||
selectedProduct.productId,
|
||||
selectedEventData.data.modelUuid
|
||||
) ?? null
|
||||
);
|
||||
};
|
||||
|
||||
const determineAssetType = (event: EventsSchema | null) => {
|
||||
if (!event) return null;
|
||||
|
||||
switch (event.type) {
|
||||
case "transfer":
|
||||
return "conveyor";
|
||||
case "vehicle":
|
||||
return "vehicle";
|
||||
case "roboticArm":
|
||||
return "roboticArm";
|
||||
case "machine":
|
||||
return "machine";
|
||||
case "storageUnit":
|
||||
return "storageUnit";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="event-proprties-wrapper">
|
||||
{currentEventData && (
|
||||
<>
|
||||
<div className="header">
|
||||
<div className="header-value">
|
||||
{selectedEventData?.data.modelName}
|
||||
</div>
|
||||
</div>
|
||||
{assetType === "conveyor" && <ConveyorMechanics />}
|
||||
{assetType === "vehicle" && <VehicleMechanics />}
|
||||
{assetType === "roboticArm" && <RoboticArmMechanics />}
|
||||
{assetType === "machine" && <MachineMechanics />}
|
||||
{assetType === "storageUnit" && <StorageMechanics />}
|
||||
</>
|
||||
)}
|
||||
{!currentEventData && selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like this object doesn't have an
|
||||
event assigned yet. To continue, please link it to one of the
|
||||
products below.
|
||||
</p>
|
||||
|
||||
<div className="products-list">
|
||||
<p>
|
||||
<strong>Here are some products you can add it to:</strong>
|
||||
</p>
|
||||
<div className="product-item">
|
||||
{products.map((product) => (
|
||||
<button
|
||||
key={product.productId}
|
||||
onClick={() => {
|
||||
if (selectedEventData) {
|
||||
handleAddEventToProduct({
|
||||
event: useEventsStore
|
||||
.getState()
|
||||
.getEventByModelUuid(
|
||||
selectedEventData?.data.modelUuid
|
||||
),
|
||||
addEvent,
|
||||
selectedProduct,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AddIcon />
|
||||
{product.productName}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!selectedEventSphere && (
|
||||
<div className="no-event-selected">
|
||||
<p>
|
||||
<strong>Oops!</strong> It looks like you haven't selected an event
|
||||
point yet. Please select an event to view its properties.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EventProperties;
|
||||
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
import useToggleStore from "../../store/useUIToggleStore";
|
||||
import {
|
||||
use3DWidget,
|
||||
useDroppedObjectsStore,
|
||||
useFloatingWidget,
|
||||
} from "../../store/visualization/useDroppedObjectsStore";
|
||||
|
||||
@@ -57,20 +56,18 @@ const Tools: React.FC = () => {
|
||||
|
||||
const { widgets3D } = use3DWidget();
|
||||
|
||||
const zones = useDroppedObjectsStore((state) => state.zones);
|
||||
|
||||
// wall options
|
||||
const { toggleView, setToggleView } = useToggleView();
|
||||
const { setDeleteTool } = useDeleteTool();
|
||||
const { setAddAction } = useAddAction();
|
||||
const { setSelectedWallItem } = useSelectedWallItem();
|
||||
|
||||
const { transformMode, setTransformMode } = useTransformMode();
|
||||
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
||||
const { movePoint, setMovePoint } = useMovePoint();
|
||||
const { toolMode, setToolMode } = useToolMode();
|
||||
const { setTransformMode } = useTransformMode();
|
||||
const { setDeletePointOrLine } = useDeletePointOrLine();
|
||||
const { setMovePoint } = useMovePoint();
|
||||
const { setToolMode } = useToolMode();
|
||||
const { activeTool, setActiveTool } = useActiveTool();
|
||||
const { refTextupdate, setRefTextUpdate } = useRefTextUpdate();
|
||||
const { setRefTextUpdate } = useRefTextUpdate();
|
||||
|
||||
// Reset activeTool whenever activeModule changes
|
||||
useEffect(() => {
|
||||
@@ -209,268 +206,266 @@ const Tools: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
{!isPlaying ? (
|
||||
<>
|
||||
<div className="tools-container">
|
||||
<div className="drop-down-icons">
|
||||
<div className="activeDropicon">
|
||||
{activeSubTool == "cursor" && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "cursor" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("cursor");
|
||||
}}
|
||||
>
|
||||
<CursorIcon isActive={activeTool === "cursor"} />
|
||||
</div>
|
||||
)}
|
||||
{activeSubTool == "free-hand" && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "free-hand" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("free-hand");
|
||||
}}
|
||||
>
|
||||
<FreeMoveIcon isActive={activeTool === "free-hand"} />
|
||||
</div>
|
||||
)}
|
||||
{activeSubTool == "delete" && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "delete" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("delete");
|
||||
}}
|
||||
>
|
||||
<DeleteIcon isActive={activeTool === "delete"} />
|
||||
</div>
|
||||
)}
|
||||
{activeModule !== "visualization" && (
|
||||
<div
|
||||
className="drop-down-option-button"
|
||||
ref={dropdownRef}
|
||||
onClick={() => {
|
||||
setOpenDrop(!openDrop);
|
||||
}}
|
||||
>
|
||||
<ArrowIcon />
|
||||
{openDrop && (
|
||||
<div className="drop-down-container">
|
||||
<div
|
||||
className="option-list"
|
||||
onClick={() => {
|
||||
setOpenDrop(false);
|
||||
setActiveTool("cursor");
|
||||
setActiveSubTool("cursor");
|
||||
}}
|
||||
>
|
||||
<div className="active-option">
|
||||
{activeSubTool === "cursor" && <TickIcon />}
|
||||
</div>
|
||||
<CursorIcon isActive={false} />
|
||||
<div className="option">Cursor</div>
|
||||
</div>
|
||||
<div
|
||||
className="option-list"
|
||||
onClick={() => {
|
||||
setOpenDrop(false);
|
||||
setActiveTool("free-hand");
|
||||
setActiveSubTool("free-hand");
|
||||
}}
|
||||
>
|
||||
<div className="active-option">
|
||||
{activeSubTool === "free-hand" && <TickIcon />}
|
||||
</div>
|
||||
<FreeMoveIcon isActive={false} />
|
||||
<div className="option">Free Hand</div>
|
||||
</div>
|
||||
<div
|
||||
className="option-list"
|
||||
onClick={() => {
|
||||
setOpenDrop(false);
|
||||
setActiveTool("delete");
|
||||
setActiveSubTool("delete");
|
||||
}}
|
||||
>
|
||||
<div className="active-option">
|
||||
{activeSubTool === "delete" && <TickIcon />}
|
||||
</div>
|
||||
<DeleteIcon isActive={false} />
|
||||
<div className="option">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{!toggleThreeD && activeModule === "builder" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-wall" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-wall");
|
||||
}}
|
||||
title="Wall"
|
||||
>
|
||||
<WallIcon isActive={activeTool === "draw-wall"} />
|
||||
</div>
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-zone" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-zone");
|
||||
}}
|
||||
title="Zone"
|
||||
>
|
||||
<ZoneIcon isActive={activeTool === "draw-zone"} />
|
||||
</div>
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-aisle" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-aisle");
|
||||
}}
|
||||
title="Aisle"
|
||||
>
|
||||
<AsileIcon isActive={activeTool === "draw-aisle"} />
|
||||
</div>
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-floor" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-floor");
|
||||
}}
|
||||
title="Floor"
|
||||
>
|
||||
<FloorIcon isActive={activeTool === "draw-floor"} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeModule === "builder" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "measure" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("measure");
|
||||
}}
|
||||
title="Measure"
|
||||
>
|
||||
<MeasureToolIcon isActive={activeTool === "measure"} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeModule === "simulation" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "pen" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("pen");
|
||||
}}
|
||||
>
|
||||
<PenIcon isActive={activeTool === "pen"} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeModule === "visualization" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button`}
|
||||
onClick={() => {
|
||||
handleSaveTemplate({
|
||||
addTemplate,
|
||||
floatingWidget,
|
||||
widgets3D,
|
||||
selectedZone,
|
||||
templates,
|
||||
visualizationSocket,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SaveTemplateIcon isActive={false} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="split"></div>
|
||||
<div className="general-options">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "comment" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("comment");
|
||||
}}
|
||||
>
|
||||
<CommentIcon isActive={activeTool === "comment"} />
|
||||
</div>
|
||||
{toggleThreeD && (
|
||||
<div className="tools-container">
|
||||
<div className="drop-down-icons">
|
||||
<div className="activeDropicon">
|
||||
{activeSubTool == "cursor" && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "play" ? "active" : ""
|
||||
activeTool === "cursor" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setIsPlaying(!isPlaying);
|
||||
setActiveTool("cursor");
|
||||
}}
|
||||
>
|
||||
<PlayIcon isActive={activeTool === "play"} />
|
||||
<CursorIcon isActive={activeTool === "cursor"} />
|
||||
</div>
|
||||
)}
|
||||
{activeSubTool == "free-hand" && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "free-hand" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("free-hand");
|
||||
}}
|
||||
>
|
||||
<FreeMoveIcon isActive={activeTool === "free-hand"} />
|
||||
</div>
|
||||
)}
|
||||
{activeSubTool == "delete" && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "delete" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("delete");
|
||||
}}
|
||||
>
|
||||
<DeleteIcon isActive={activeTool === "delete"} />
|
||||
</div>
|
||||
)}
|
||||
{activeModule !== "visualization" && (
|
||||
<div
|
||||
className="drop-down-option-button"
|
||||
ref={dropdownRef}
|
||||
onClick={() => {
|
||||
setOpenDrop(!openDrop);
|
||||
}}
|
||||
>
|
||||
<ArrowIcon />
|
||||
{openDrop && (
|
||||
<div className="drop-down-container">
|
||||
<div
|
||||
className="option-list"
|
||||
onClick={() => {
|
||||
setOpenDrop(false);
|
||||
setActiveTool("cursor");
|
||||
setActiveSubTool("cursor");
|
||||
}}
|
||||
>
|
||||
<div className="active-option">
|
||||
{activeSubTool === "cursor" && <TickIcon />}
|
||||
</div>
|
||||
<CursorIcon isActive={false} />
|
||||
<div className="option">Cursor</div>
|
||||
</div>
|
||||
<div
|
||||
className="option-list"
|
||||
onClick={() => {
|
||||
setOpenDrop(false);
|
||||
setActiveTool("free-hand");
|
||||
setActiveSubTool("free-hand");
|
||||
}}
|
||||
>
|
||||
<div className="active-option">
|
||||
{activeSubTool === "free-hand" && <TickIcon />}
|
||||
</div>
|
||||
<FreeMoveIcon isActive={false} />
|
||||
<div className="option">Free Hand</div>
|
||||
</div>
|
||||
<div
|
||||
className="option-list"
|
||||
onClick={() => {
|
||||
setOpenDrop(false);
|
||||
setActiveTool("delete");
|
||||
setActiveSubTool("delete");
|
||||
}}
|
||||
>
|
||||
<div className="active-option">
|
||||
{activeSubTool === "delete" && <TickIcon />}
|
||||
</div>
|
||||
<DeleteIcon isActive={false} />
|
||||
<div className="option">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{activeModule === "builder" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
</div>
|
||||
{!toggleThreeD && activeModule === "builder" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`toggle-threed-button${
|
||||
toggleThreeD ? " toggled" : ""
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-wall" ? "active" : ""
|
||||
}`}
|
||||
onClick={toggleSwitch}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-wall");
|
||||
}}
|
||||
title="Wall"
|
||||
>
|
||||
<div
|
||||
className={`toggle-option${!toggleThreeD ? " active" : ""}`}
|
||||
>
|
||||
2d
|
||||
</div>
|
||||
<div
|
||||
className={`toggle-option${toggleThreeD ? " active" : ""}`}
|
||||
>
|
||||
3d
|
||||
</div>
|
||||
<WallIcon isActive={activeTool === "draw-wall"} />
|
||||
</div>
|
||||
</>
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-zone" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-zone");
|
||||
}}
|
||||
title="Zone"
|
||||
>
|
||||
<ZoneIcon isActive={activeTool === "draw-zone"} />
|
||||
</div>
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-aisle" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-aisle");
|
||||
}}
|
||||
title="Aisle"
|
||||
>
|
||||
<AsileIcon isActive={activeTool === "draw-aisle"} />
|
||||
</div>
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "draw-floor" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("draw-floor");
|
||||
}}
|
||||
title="Floor"
|
||||
>
|
||||
<FloorIcon isActive={activeTool === "draw-floor"} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeModule === "builder" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "measure" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("measure");
|
||||
}}
|
||||
title="Measure"
|
||||
>
|
||||
<MeasureToolIcon isActive={activeTool === "measure"} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeModule === "simulation" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "pen" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("pen");
|
||||
}}
|
||||
>
|
||||
<PenIcon isActive={activeTool === "pen"} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{activeModule === "visualization" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div className="draw-tools">
|
||||
<div
|
||||
className={`tool-button`}
|
||||
onClick={() => {
|
||||
handleSaveTemplate({
|
||||
addTemplate,
|
||||
floatingWidget,
|
||||
widgets3D,
|
||||
selectedZone,
|
||||
templates,
|
||||
visualizationSocket,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SaveTemplateIcon isActive={false} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="split"></div>
|
||||
<div className="general-options">
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "comment" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveTool("comment");
|
||||
}}
|
||||
>
|
||||
<CommentIcon isActive={activeTool === "comment"} />
|
||||
</div>
|
||||
{toggleThreeD && (
|
||||
<div
|
||||
className={`tool-button ${
|
||||
activeTool === "play" ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
setIsPlaying(!isPlaying);
|
||||
}}
|
||||
>
|
||||
<PlayIcon isActive={activeTool === "play"} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
{activeModule === "builder" && (
|
||||
<>
|
||||
<div className="split"></div>
|
||||
<div
|
||||
className={`toggle-threed-button${
|
||||
toggleThreeD ? " toggled" : ""
|
||||
}`}
|
||||
onClick={toggleSwitch}
|
||||
>
|
||||
<div
|
||||
className={`toggle-option${!toggleThreeD ? " active" : ""}`}
|
||||
>
|
||||
2d
|
||||
</div>
|
||||
<div
|
||||
className={`toggle-option${toggleThreeD ? " active" : ""}`}
|
||||
>
|
||||
3d
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{activeModule !== "simulation" && (
|
||||
<div className="exitPlay" onClick={() => setIsPlaying(false)}>
|
||||
<button className="exitPlay" onClick={() => setIsPlaying(false)}>
|
||||
X
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
import React from "react";
|
||||
import { HelpIcon } from "../../icons/DashboardIcon";
|
||||
import { useLogger } from "../log/LoggerContext";
|
||||
import {
|
||||
LogInfoIcon,
|
||||
ErrorIcon,
|
||||
WarningIcon,
|
||||
} from "../../icons/ExportCommonIcons"; // Adjust path as needed
|
||||
|
||||
const getLogIcon = (type: string) => {
|
||||
switch (type) {
|
||||
case "info":
|
||||
return <LogInfoIcon />;
|
||||
case "error":
|
||||
return <ErrorIcon />;
|
||||
case "warning":
|
||||
return <WarningIcon />;
|
||||
case "log":
|
||||
default:
|
||||
return <LogInfoIcon />;
|
||||
}
|
||||
};
|
||||
|
||||
const Footer = () => {
|
||||
const { logs, setIsLogListVisible } = useLogger();
|
||||
|
||||
const lastLog = logs.length > 0 ? logs[logs.length - 1] : null;
|
||||
|
||||
return (
|
||||
@@ -26,9 +44,14 @@ const Footer = () => {
|
||||
|
||||
<div className="logs-wrapper">
|
||||
<div className="logs-detail" onClick={() => setIsLogListVisible(true)}>
|
||||
{lastLog
|
||||
? `[${lastLog.type.toUpperCase()}] ${lastLog.message}`
|
||||
: "No logs yet."}
|
||||
{lastLog ? (
|
||||
<>
|
||||
<span className="log-icon">{getLogIcon(lastLog.type)}</span>
|
||||
<span className="log-message">{lastLog.message}</span>
|
||||
</>
|
||||
) : (
|
||||
"No logs yet."
|
||||
)}
|
||||
</div>
|
||||
<div className="version">
|
||||
V 0.01
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
LogInfoIcon,
|
||||
WarningIcon,
|
||||
ErrorIcon,
|
||||
CloseIcon,
|
||||
} from "../../icons/ExportCommonIcons"; // Adjust path as needed
|
||||
import { useLogger } from "./LoggerContext";
|
||||
|
||||
@@ -47,7 +48,7 @@ const LogList: React.FC = () => {
|
||||
<div className="head">Log List</div>
|
||||
</div>
|
||||
<div className="close" onClick={() => setIsLogListVisible(false)}>
|
||||
X
|
||||
{/* <CloseIcon /> */}X
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -12,25 +12,31 @@ import {
|
||||
EndIcon,
|
||||
ExpandIcon,
|
||||
HourlySimulationIcon,
|
||||
InfoIcon,
|
||||
MonthlyROI,
|
||||
SpeedIcon,
|
||||
StartIcon,
|
||||
} from "../../icons/ExportCommonIcons";
|
||||
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
|
||||
import { useSubModuleStore } from "../../../store/useModuleStore";
|
||||
import ProductionCapacity from "../analysis/ProductionCapacity";
|
||||
import ThroughputSummary from "../analysis/ThroughputSummary";
|
||||
import ROISummary from "../analysis/ROISummary";
|
||||
|
||||
const SimulationPlayer: React.FC = () => {
|
||||
const MAX_SPEED = 8; // Maximum speed
|
||||
|
||||
const isDragging = useRef(false);
|
||||
const sliderRef = useRef<HTMLDivElement>(null);
|
||||
const [expand, setExpand] = useState(true);
|
||||
const [playSimulation, setPlaySimulation] = useState(false);
|
||||
|
||||
const { speed, setSpeed } = useAnimationPlaySpeed();
|
||||
const [playSimulation, setPlaySimulation] = useState(false);
|
||||
const { setIsPlaying } = usePlayButtonStore();
|
||||
const sliderRef = useRef<HTMLDivElement>(null);
|
||||
const isDragging = useRef(false);
|
||||
const { setActiveTool } = useActiveTool();
|
||||
const { isPaused, setIsPaused } = usePauseButtonStore();
|
||||
const { isReset, setReset } = useResetButtonStore();
|
||||
const { subModule } = useSubModuleStore();
|
||||
|
||||
// Button functions
|
||||
const handleReset = () => {
|
||||
@@ -113,6 +119,15 @@ const SimulationPlayer: React.FC = () => {
|
||||
return color;
|
||||
};
|
||||
|
||||
// Store colors for each process item
|
||||
const [_, setProcessColors] = useState<string[]>([]);
|
||||
|
||||
// Generate colors on mount or when process changes
|
||||
useEffect(() => {
|
||||
const generatedColors = process.map(() => getRandomColor());
|
||||
setProcessColors(generatedColors);
|
||||
}, []);
|
||||
|
||||
const intervals = [10, 20, 30, 40, 50, 60]; // in minutes
|
||||
const totalSegments = intervals.length;
|
||||
const progress = 20; // percent (example)
|
||||
@@ -150,214 +165,236 @@ const SimulationPlayer: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="simulation-player-wrapper">
|
||||
<div className={`simulation-player-container ${expand ? "open" : ""}`}>
|
||||
<div className="controls-container">
|
||||
<div className="production-details">
|
||||
{/* hourlySimulation */}
|
||||
<div className="hourly-wrapper production-wrapper">
|
||||
<div className="header">
|
||||
<div className="icon">
|
||||
<HourlySimulationIcon />
|
||||
<>
|
||||
<div className="simulation-player-wrapper">
|
||||
<div className={`simulation-player-container ${expand ? "open" : ""}`}>
|
||||
<div className="controls-container">
|
||||
{subModule === "analysis" && (
|
||||
<div className="production-details">
|
||||
{/* hourlySimulation */}
|
||||
<div className="hourly-wrapper production-wrapper">
|
||||
<div className="header">
|
||||
<div className="icon">
|
||||
<HourlySimulationIcon />
|
||||
</div>
|
||||
<div className="label">Hourly Simulation</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div
|
||||
className="progress"
|
||||
style={{ width: hourlySimulation }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="label">Hourly Simulation</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div
|
||||
className="progress"
|
||||
style={{ width: hourlySimulation }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* dailyProduction */}
|
||||
<div className="dailyProduction-wrapper production-wrapper">
|
||||
<div className="header">
|
||||
<div className="icon">
|
||||
<DailyProductionIcon />
|
||||
{/* dailyProduction */}
|
||||
<div className="dailyProduction-wrapper production-wrapper">
|
||||
<div className="header">
|
||||
<div className="icon">
|
||||
<DailyProductionIcon />
|
||||
</div>
|
||||
<div className="label">Daily Production</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div
|
||||
className="progress"
|
||||
style={{ width: dailyProduction }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="label">Daily Production</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div
|
||||
className="progress"
|
||||
style={{ width: dailyProduction }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* monthlyROI */}
|
||||
<div className="monthlyROI-wrapper production-wrapper">
|
||||
<div className="header">
|
||||
<div className="icon">
|
||||
<MonthlyROI />
|
||||
{/* monthlyROI */}
|
||||
<div className="monthlyROI-wrapper production-wrapper">
|
||||
<div className="header">
|
||||
<div className="icon">
|
||||
<MonthlyROI />
|
||||
</div>
|
||||
<div className="label">Monthly ROI</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div
|
||||
className="progress"
|
||||
style={{ width: monthlyROI }}
|
||||
></div>
|
||||
</div>{" "}
|
||||
</div>
|
||||
<div className="label">Monthly ROI</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div className="progress" style={{ width: monthlyROI }}></div>
|
||||
</div>{" "}
|
||||
</div>
|
||||
</div>
|
||||
<div className="controls-wrapper">
|
||||
<button
|
||||
className="simulation-button-container"
|
||||
onClick={() => {
|
||||
handleReset();
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
Reset
|
||||
</button>
|
||||
<button
|
||||
className="simulation-button-container"
|
||||
onClick={() => {
|
||||
handlePlayStop();
|
||||
}}
|
||||
>
|
||||
<PlayStopIcon />
|
||||
{playSimulation ? "Play" : "Stop"}
|
||||
</button>
|
||||
<button
|
||||
className="simulation-button-container"
|
||||
onClick={() => {
|
||||
handleExit();
|
||||
}}
|
||||
>
|
||||
<ExitIcon />
|
||||
Exit
|
||||
</button>
|
||||
<button
|
||||
className="expand-icon-container"
|
||||
onClick={() => setExpand(!expand)}
|
||||
>
|
||||
<ExpandIcon isActive={!expand} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="progresser-wrapper">
|
||||
<div className="time-displayer">
|
||||
<div className="start-time-wrappper">
|
||||
<div className="icon">
|
||||
<StartIcon />
|
||||
)}
|
||||
{subModule === "simulations" && (
|
||||
<div className="header">
|
||||
<InfoIcon />
|
||||
{playSimulation
|
||||
? "Paused - system idle."
|
||||
: "Running simulation..."}
|
||||
</div>
|
||||
<div className="time-wrapper">
|
||||
<div className="date">23 April ,25</div>
|
||||
<div className="time">04:41 PM</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="time-progresser">
|
||||
<div className="timeline">
|
||||
{intervals.map((label, index) => {
|
||||
const segmentProgress = (index / totalSegments) * 100;
|
||||
const isFilled = progress >= segmentProgress;
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<div className="label-dot-wrapper">
|
||||
<div className="label">{label} mins</div>
|
||||
<div
|
||||
className={`dot ${isFilled ? "filled" : ""}`}
|
||||
></div>
|
||||
</div>
|
||||
{index < intervals.length - 1 && (
|
||||
<div
|
||||
className={`line ${
|
||||
progress >= ((index + 1) / totalSegments) * 100
|
||||
? "filled"
|
||||
: ""
|
||||
}`}
|
||||
></div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="end-time-wrappper">
|
||||
<div className="time-wrapper">
|
||||
<div className="time">00:10:20</div>
|
||||
</div>
|
||||
<div className="icon">
|
||||
<EndIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="speed-control-container">
|
||||
<div className="min-value">
|
||||
<div className="icon">
|
||||
<SpeedIcon />
|
||||
</div>
|
||||
Speed
|
||||
</div>
|
||||
<div className="slider-container" ref={sliderRef}>
|
||||
<div className="speed-label mix-value">0.5X</div>
|
||||
<div className="marker marker-10"></div>
|
||||
<div className="marker marker-20"></div>
|
||||
<div className="marker marker-30"></div>
|
||||
<div className="marker marker-40"></div>
|
||||
<div className="marker marker-50"></div>
|
||||
<div className="marker marker-60"></div>
|
||||
<div className="marker marker-70"></div>
|
||||
<div className="marker marker-80"></div>
|
||||
<div className="marker marker-90"></div>
|
||||
<div className="custom-slider">
|
||||
)}
|
||||
<div className="controls-wrapper">
|
||||
<button
|
||||
className="simulation-button-container"
|
||||
onClick={() => {
|
||||
handleReset();
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
Reset
|
||||
</button>
|
||||
<button
|
||||
className="simulation-button-container"
|
||||
onClick={() => {
|
||||
handlePlayStop();
|
||||
}}
|
||||
>
|
||||
<PlayStopIcon />
|
||||
{playSimulation ? "Play" : "Stop"}
|
||||
</button>
|
||||
<button
|
||||
className="simulation-button-container"
|
||||
onClick={() => {
|
||||
handleExit();
|
||||
}}
|
||||
>
|
||||
<ExitIcon />
|
||||
Exit
|
||||
</button>
|
||||
{subModule === "analysis" && (
|
||||
<button
|
||||
className={`slider-handle ${isDragging ? "dragging" : ""}`}
|
||||
style={{ left: `${calculateHandlePosition()}%` }}
|
||||
onMouseDown={handleMouseDown}
|
||||
className="expand-icon-container"
|
||||
onClick={() => setExpand(!expand)}
|
||||
>
|
||||
{speed.toFixed(1)}x
|
||||
<ExpandIcon isActive={!expand} />
|
||||
</button>
|
||||
<input
|
||||
type="range"
|
||||
min="0.5"
|
||||
max={MAX_SPEED}
|
||||
step="0.1"
|
||||
value={speed}
|
||||
onChange={handleSpeedChange}
|
||||
className="slider-input"
|
||||
/>
|
||||
</div>
|
||||
<div className="speed-label max-value">4x</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="processDisplayer">
|
||||
<div className="start-displayer timmer">00:00</div>
|
||||
<div className="end-displayer timmer">24:00</div>
|
||||
<div
|
||||
className="process-player"
|
||||
style={{ left: playerPosition, position: "absolute" }}
|
||||
></div>
|
||||
<div
|
||||
className="process-wrapper"
|
||||
style={{ padding: expand ? "0px" : "5px 35px" }}
|
||||
>
|
||||
<div
|
||||
className="process-container"
|
||||
ref={processWrapperRef}
|
||||
onMouseDown={handleProcessMouseDown}
|
||||
>
|
||||
{process.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="process"
|
||||
style={{
|
||||
width: `${item.completed}%`,
|
||||
backgroundColor: getAvatarColor(index),
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="process-player"
|
||||
ref={processPlayerRef}
|
||||
style={{ left: playerPosition, position: "absolute" }}
|
||||
></div>
|
||||
<div className="progresser-wrapper">
|
||||
<div className="time-displayer">
|
||||
<div className="start-time-wrappper">
|
||||
<div className="icon">
|
||||
<StartIcon />
|
||||
</div>
|
||||
))}
|
||||
<div className="time-wrapper">
|
||||
<div className="date">23 April ,25</div>
|
||||
<div className="time">04:41 PM</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="time-progresser">
|
||||
<div className="timeline">
|
||||
{intervals.map((label, index) => {
|
||||
const segmentProgress = (index / totalSegments) * 100;
|
||||
const isFilled = progress >= segmentProgress;
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<div className="label-dot-wrapper">
|
||||
<div className="label">{label} mins</div>
|
||||
<div
|
||||
className={`dot ${isFilled ? "filled" : ""}`}
|
||||
></div>
|
||||
</div>
|
||||
{index < intervals.length - 1 && (
|
||||
<div
|
||||
className={`line ${
|
||||
progress >= ((index + 1) / totalSegments) * 100
|
||||
? "filled"
|
||||
: ""
|
||||
}`}
|
||||
></div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="end-time-wrappper">
|
||||
<div className="time-wrapper">
|
||||
<div className="time">00:10:20</div>
|
||||
</div>
|
||||
<div className="icon">
|
||||
<EndIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="speed-control-container">
|
||||
<div className="min-value">
|
||||
<div className="icon">
|
||||
<SpeedIcon />
|
||||
</div>
|
||||
Speed
|
||||
</div>
|
||||
<div className="slider-container" ref={sliderRef}>
|
||||
<div className="speed-label mix-value">0.5X</div>
|
||||
<div className="marker marker-10"></div>
|
||||
<div className="marker marker-20"></div>
|
||||
<div className="marker marker-30"></div>
|
||||
<div className="marker marker-40"></div>
|
||||
<div className="marker marker-50"></div>
|
||||
<div className="marker marker-60"></div>
|
||||
<div className="marker marker-70"></div>
|
||||
<div className="marker marker-80"></div>
|
||||
<div className="marker marker-90"></div>
|
||||
<div className="custom-slider">
|
||||
<button
|
||||
className={`slider-handle ${isDragging ? "dragging" : ""}`}
|
||||
style={{ left: `${calculateHandlePosition()}%` }}
|
||||
onMouseDown={handleMouseDown}
|
||||
>
|
||||
{speed.toFixed(1)}x
|
||||
</button>
|
||||
<input
|
||||
type="range"
|
||||
min="0.5"
|
||||
max={MAX_SPEED}
|
||||
step="0.1"
|
||||
value={speed}
|
||||
onChange={handleSpeedChange}
|
||||
className="slider-input"
|
||||
/>
|
||||
</div>
|
||||
<div className="speed-label max-value">4x</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{subModule === "analysis" && (
|
||||
<div className="processDisplayer">
|
||||
<div className="start-displayer timmer">00:00</div>
|
||||
<div className="end-displayer timmer">24:00</div>
|
||||
<div
|
||||
className="process-wrapper"
|
||||
style={{ padding: expand ? "0px" : "5px 35px" }}
|
||||
>
|
||||
<div
|
||||
className="process-container"
|
||||
ref={processWrapperRef}
|
||||
onMouseDown={handleProcessMouseDown}
|
||||
>
|
||||
{process.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="process"
|
||||
style={{
|
||||
width: `${item.completed}%`,
|
||||
backgroundColor: getAvatarColor(index),
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="process-player"
|
||||
ref={processPlayerRef}
|
||||
style={{ left: playerPosition, position: "absolute" }}
|
||||
></div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="analysis">
|
||||
<div className="analysis-wrapper">
|
||||
<ProductionCapacity />
|
||||
<ThroughputSummary />
|
||||
</div>
|
||||
<ROISummary />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user