feat: Refactor product selection and comparison functionality

- Created a new store for selected products using Zustand and immer for state management.
- Introduced `useMainProduct` and `useComparisonProduct` hooks to manage main and comparison products.
- Implemented `ComparisonScene` and `ComparisonSceneProvider` components to handle product comparisons.
- Updated `MainScene` to allow selection of main products with a dropdown.
- Enhanced styles for comparison layout and product selection UI.
- Established a context for product management to streamline state access across components.
This commit is contained in:
Jerald-Golden-B 2025-05-29 12:00:16 +05:30
parent 5e58606f8f
commit d3ea36d1ba
46 changed files with 996 additions and 776 deletions

View File

@ -0,0 +1,48 @@
import { useProductContext } from '../../../modules/simulation/products/productContext'
import RegularDropDown from '../../ui/inputs/RegularDropDown';
import { useProductStore } from '../../../store/simulation/useProductStore';
import { useSaveVersion } from '../../../store/builder/store';
import useModuleStore from '../../../store/useModuleStore';
import CompareLayOut from '../../ui/compareVersion/CompareLayOut';
import ComparisonResult from '../../ui/compareVersion/ComparisonResult';
import { useComparisonProduct } from '../../../store/simulation/useSimulationStore';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
function ComparisonScene() {
const { isPlaying } = usePlayButtonStore();
const { products } = useProductStore();
const { isVersionSaved } = useSaveVersion();
const { activeModule } = useModuleStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
const handleSelectLayout = (option: string) => {
const product = products.find((product) => product.productName === option);
if (product) {
setComparisonProduct(product.productId, product.productName);
}
};
return (
<>
{isVersionSaved && activeModule === "simulation" && selectedProduct && (
<>
{comparisonProduct && !isPlaying &&
<div className="initial-selectLayout-wrapper">
<RegularDropDown
header={selectedProduct.productName}
options={products.map((l) => l.productName)} // Pass layout names as options
onSelect={handleSelectLayout}
search={false}
/>
</div>
}
<CompareLayOut />
{false && <ComparisonResult />}
</>
)}
</>
)
}
export default ComparisonScene;

View File

@ -0,0 +1,12 @@
import { ProductProvider } from '../../../modules/simulation/products/productContext'
import ComparisonScene from './ComparisonScene';
function ComparisonSceneProvider() {
return (
<ProductProvider>
<ComparisonScene />
</ProductProvider>
)
}
export default ComparisonSceneProvider

View File

@ -0,0 +1,113 @@
import React from 'react'
import { useLoadingProgress, useSaveVersion, useSocketStore, useWidgetSubOption } from '../../../store/builder/store';
import useModuleStore, { useThreeDStore } from '../../../store/useModuleStore';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
import { useSelectedZoneStore } from '../../../store/visualization/useZoneStore';
import { useFloatingWidget } from '../../../store/visualization/useDroppedObjectsStore';
import { useSelectedUserStore } from '../../../store/collaboration/useCollabStore';
import KeyPressListener from '../../../utils/shortcutkeys/handleShortcutKeys';
import LoadingPage from '../../templates/LoadingPage';
import ModuleToggle from '../../ui/ModuleToggle';
import SideBarLeft from '../sidebarLeft/SideBarLeft';
import SideBarRight from '../sidebarRight/SideBarRight';
import RealTimeVisulization from '../../../modules/visualization/RealTimeVisulization';
import MarketPlace from '../../../modules/market/MarketPlace';
import Tools from '../../ui/Tools';
import SimulationPlayer from '../../ui/simulation/simulationPlayer';
import ControlsPlayer from '../controls/ControlsPlayer';
import SelectFloorPlan from '../../temporary/SelectFloorPlan';
import { createHandleDrop } from '../../../modules/visualization/functions/handleUiDrop';
import Scene from '../../../modules/scene/scene';
import { useMainProduct } from '../../../store/simulation/useSimulationStore';
import { useProductContext } from '../../../modules/simulation/products/productContext';
import { useProductStore } from '../../../store/simulation/useProductStore';
import RegularDropDown from '../../ui/inputs/RegularDropDown';
function MainScene() {
const { products } = useProductStore();
const { setMainProduct } = useMainProduct();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { isVersionSaved } = useSaveVersion();
const { activeModule } = useModuleStore();
const { selectedUser } = useSelectedUserStore();
const { loadingProgress } = useLoadingProgress();
const { toggleThreeD } = useThreeDStore();
const { isPlaying } = usePlayButtonStore();
const { widgetSubOption } = useWidgetSubOption();
const { visualizationSocket } = useSocketStore();
const { selectedZone } = useSelectedZoneStore();
const { setFloatingWidget } = useFloatingWidget();
const handleSelectLayout = (option: string) => {
const product = products.find((product) => product.productName === option);
if (product) {
setMainProduct(product.productId, product.productName);
}
};
return (
<>
{!selectedUser && (
<>
<KeyPressListener />
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
{!isPlaying && (
<>
{toggleThreeD && <ModuleToggle />}
<SideBarLeft />
<SideBarRight />
</>
)}
<RealTimeVisulization />
{activeModule === "market" && <MarketPlace />}
{activeModule !== "market" && !isPlaying && !isVersionSaved && (
<Tools />
)}
{isPlaying && activeModule === "simulation" && <SimulationPlayer />}
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
{/* remove this later */}
{activeModule === "builder" && !toggleThreeD && <SelectFloorPlan />}
</>
)}
<div
className="scene-container"
id="work-space-three-d-canvas"
style={{
height: isPlaying || activeModule !== "visualization" ? "100vh" : "",
width: isPlaying || activeModule !== "visualization" ? "100vw" : "",
left: isPlaying || activeModule !== "visualization" ? "0%" : "",
borderRadius:
isPlaying || activeModule !== "visualization" ? "" : "6px",
}}
role="application"
onDrop={(event) =>
createHandleDrop({
widgetSubOption,
visualizationSocket,
selectedZone,
setFloatingWidget,
event,
})
}
onDragOver={(event) => event.preventDefault()}
>
<Scene layout="Main Layout" />
</div>
{selectedProduct && isVersionSaved && !isPlaying && (
<div className="selectLayout-wrapper">
<RegularDropDown
header={selectedProduct.productName}
options={products.map((l) => l.productName)} // Pass layout names as options
onSelect={handleSelectLayout}
search={false}
/>
</div>
)}
</>
)
}
export default MainScene

View File

@ -0,0 +1,12 @@
import { ProductProvider } from '../../../modules/simulation/products/productContext'
import MainScene from './MainScene'
function MainSceneProvider() {
return (
<ProductProvider>
<MainScene />
</ProductProvider>
)
}
export default MainSceneProvider

View File

@ -2,7 +2,6 @@ import React, { useEffect, useState } from "react";
import { import {
useSelectedEventData, useSelectedEventData,
useSelectedEventSphere, useSelectedEventSphere,
useSelectedProduct,
} from "../../../../../store/simulation/useSimulationStore"; } from "../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import ConveyorMechanics from "./mechanics/conveyorMechanics"; import ConveyorMechanics from "./mechanics/conveyorMechanics";
@ -13,11 +12,13 @@ import StorageMechanics from "./mechanics/storageMechanics";
import { AddIcon } from "../../../../icons/ExportCommonIcons"; import { AddIcon } from "../../../../icons/ExportCommonIcons";
import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct"; import { handleAddEventToProduct } from "../../../../../modules/simulation/events/points/functions/handleAddEventToProduct";
import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
import { useProductContext } from "../../../../../modules/simulation/products/productContext";
const EventProperties: React.FC = () => { const EventProperties: React.FC = () => {
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getEventByModelUuid } = useProductStore(); const { getEventByModelUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>( const [currentEventData, setCurrentEventData] = useState<EventsSchema | null>(
null null
); );

View File

@ -8,10 +8,10 @@ import RenameInput from "../../../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../../../functions/handleResizePannel"; import { handleResize } from "../../../../../../functions/handleResizePannel";
import { import {
useSelectedAction, useSelectedAction,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore"; } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
interface ActionsListProps { interface ActionsListProps {
selectedPointData: any; selectedPointData: any;
@ -33,7 +33,8 @@ const ActionsList: React.FC<ActionsListProps> = ({
// store // store
const { renameAction } = useProductStore(); const { renameAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { selectedAction, setSelectedAction } = useSelectedAction(); const { selectedAction, setSelectedAction } = useSelectedAction();
const handleRenameAction = (newName: string) => { const handleRenameAction = (newName: string) => {
@ -87,8 +88,7 @@ const ActionsList: React.FC<ActionsListProps> = ({
selectedPointData?.actions?.map((action: any) => ( selectedPointData?.actions?.map((action: any) => (
<div <div
key={action.actionUuid} key={action.actionUuid}
className={`list-item ${ className={`list-item ${selectedAction.actionId === action.actionUuid
selectedAction.actionId === action.actionUuid
? "active" ? "active"
: "" : ""
}`} }`}

View File

@ -8,17 +8,19 @@ import SwapAction from "../actions/SwapAction";
import SpawnAction from "../actions/SpawnAction"; import SpawnAction from "../actions/SpawnAction";
import DefaultAction from "../actions/DefaultAction"; import DefaultAction from "../actions/DefaultAction";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { useSelectedAction, useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
function ConveyorMechanics() { function ConveyorMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default"); const [activeOption, setActiveOption] = useState<"default" | "spawn" | "swap" | "delay" | "despawn">("default");
const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>(); const [selectedPointData, setSelectedPointData] = useState<ConveyorPointSchema | undefined>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore(); const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction(); const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const email = localStorage.getItem('email') const email = localStorage.getItem('email')

View File

@ -2,18 +2,20 @@ import { useEffect, useState } from "react";
import RenameInput from "../../../../../ui/inputs/RenameInput"; import RenameInput from "../../../../../ui/inputs/RenameInput";
import LabledDropdown from "../../../../../ui/inputs/LabledDropdown"; import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { useSelectedAction, useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import ProcessAction from "../actions/ProcessAction"; import ProcessAction from "../actions/ProcessAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
function MachineMechanics() { function MachineMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "process">("default"); const [activeOption, setActiveOption] = useState<"default" | "process">("default");
const [selectedPointData, setSelectedPointData] = useState<MachinePointSchema | undefined>(); const [selectedPointData, setSelectedPointData] = useState<MachinePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateAction } = useProductStore(); const { getPointByUuid, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction(); const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const email = localStorage.getItem('email') const email = localStorage.getItem('email')

View File

@ -6,13 +6,13 @@ import LabledDropdown from "../../../../../ui/inputs/LabledDropdown";
import Trigger from "../trigger/Trigger"; import Trigger from "../trigger/Trigger";
import { import {
useSelectedEventData, useSelectedEventData,
useSelectedProduct,
useSelectedAction, useSelectedAction,
} from "../../../../../../store/simulation/useSimulationStore"; } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import PickAndPlaceAction from "../actions/PickAndPlaceAction"; import PickAndPlaceAction from "../actions/PickAndPlaceAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
function RoboticArmMechanics() { function RoboticArmMechanics() {
const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">( const [activeOption, setActiveOption] = useState<"default" | "pickAndPlace">(
@ -30,7 +30,8 @@ function RoboticArmMechanics() {
addAction, addAction,
removeAction, removeAction,
} = useProductStore(); } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { selectedAction, setSelectedAction, clearSelectedAction } = const { selectedAction, setSelectedAction, clearSelectedAction } =
useSelectedAction(); useSelectedAction();

View File

@ -6,9 +6,10 @@ import StorageAction from "../actions/StorageAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { useSelectedAction, useSelectedEventData, useSelectedProduct } from "../../../../../../store/simulation/useSimulationStore"; import { useSelectedAction, useSelectedEventData } from "../../../../../../store/simulation/useSimulationStore";
import * as THREE from 'three'; import * as THREE from 'three';
import { useSceneContext } from "../../../../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
function StorageMechanics() { function StorageMechanics() {
const { storageUnitStore } = useSceneContext(); const { storageUnitStore } = useSceneContext();
@ -16,7 +17,8 @@ function StorageMechanics() {
const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>(); const [selectedPointData, setSelectedPointData] = useState<StoragePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, updateAction } = useProductStore(); const { getPointByUuid, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction(); const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { setCurrentMaterials, clearCurrentMaterials, updateCurrentLoad, getStorageUnitById } = storageUnitStore(); const { setCurrentMaterials, clearCurrentMaterials, updateCurrentLoad, getStorageUnitById } = storageUnitStore();

View File

@ -7,13 +7,13 @@ import {
useSelectedAction, useSelectedAction,
useSelectedEventData, useSelectedEventData,
useSelectedEventSphere, useSelectedEventSphere,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore"; } from "../../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import TravelAction from "../actions/TravelAction"; import TravelAction from "../actions/TravelAction";
import ActionsList from "../components/ActionsList"; import ActionsList from "../components/ActionsList";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useSceneContext } from "../../../../../../modules/scene/sceneContext"; import { useSceneContext } from "../../../../../../modules/scene/sceneContext";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
function VehicleMechanics() { function VehicleMechanics() {
const { vehicleStore } = useSceneContext(); const { vehicleStore } = useSceneContext();
@ -21,7 +21,8 @@ function VehicleMechanics() {
const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>(); const [selectedPointData, setSelectedPointData] = useState<VehiclePointSchema | undefined>();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore(); const { getPointByUuid, getEventByModelUuid, updateEvent, updateAction } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAction, clearSelectedAction } = useSelectedAction(); const { setSelectedAction, clearSelectedAction } = useSelectedAction();
const { getVehicleById } = vehicleStore(); const { getVehicleById } = vehicleStore();

View File

@ -11,9 +11,9 @@ import { handleResize } from "../../../../../../functions/handleResizePannel";
import { useProductStore } from "../../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../../store/simulation/useProductStore";
import { import {
useSelectedAction, useSelectedAction,
useSelectedProduct,
} from "../../../../../../store/simulation/useSimulationStore"; } from "../../../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../../../../modules/simulation/products/productContext";
type TriggerProps = { type TriggerProps = {
selectedPointData?: PointsScheme | undefined; selectedPointData?: PointsScheme | undefined;
@ -22,7 +22,8 @@ type TriggerProps = {
const Trigger = ({ selectedPointData, type }: TriggerProps) => { const Trigger = ({ selectedPointData, type }: TriggerProps) => {
const [currentAction, setCurrentAction] = useState<string | undefined>(); const [currentAction, setCurrentAction] = useState<string | undefined>();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { const {
getActionByUuid, getActionByUuid,
getEventByModelUuid, getEventByModelUuid,
@ -416,8 +417,7 @@ const Trigger = ({ selectedPointData, type }: TriggerProps) => {
{triggers.map((trigger) => ( {triggers.map((trigger) => (
<div <div
key={trigger.triggerUuid} key={trigger.triggerUuid}
className={`list-item ${ className={`list-item ${selectedTrigger?.triggerUuid === trigger.triggerUuid
selectedTrigger?.triggerUuid === trigger.triggerUuid
? "active" ? "active"
: "" : ""
}`} }`}

View File

@ -9,7 +9,6 @@ import RenameInput from "../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../functions/handleResizePannel"; import { handleResize } from "../../../../functions/handleResizePannel";
import { import {
useSelectedAsset, useSelectedAsset,
useSelectedProduct,
} from "../../../../store/simulation/useSimulationStore"; } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { generateUUID } from "three/src/math/MathUtils"; import { generateUUID } from "three/src/math/MathUtils";
@ -29,6 +28,7 @@ import {
} from "../../../../store/builder/store"; } from "../../../../store/builder/store";
import CompareLayOut from "../../../ui/compareVersion/CompareLayOut"; import CompareLayOut from "../../../ui/compareVersion/CompareLayOut";
import { useToggleStore } from "../../../../store/useUIToggleStore"; import { useToggleStore } from "../../../../store/useUIToggleStore";
import { useProductContext } from "../../../../modules/simulation/products/productContext";
interface Event { interface Event {
modelName: string; modelName: string;
@ -58,7 +58,8 @@ const Simulations: React.FC = () => {
removeEvent, removeEvent,
getProductById, getProductById,
} = useProductStore(); } = useProductStore();
const { selectedProduct, setSelectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct, setSelectedProduct } = selectedProductStore();
const { getEventByModelUuid } = useEventsStore(); const { getEventByModelUuid } = useEventsStore();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");

View File

@ -4,27 +4,20 @@ import {
LayoutIcon, LayoutIcon,
ResizerIcon, ResizerIcon,
} from "../../icons/SimulationIcons"; } from "../../icons/SimulationIcons";
import { useSaveVersion } from "../../../store/builder/store"; import { useLoadingProgress, useSaveVersion } from "../../../store/builder/store";
import Search from "../inputs/Search"; import Search from "../inputs/Search";
import OuterClick from "../../../utils/outerClick"; import OuterClick from "../../../utils/outerClick";
import RegularDropDown from "../inputs/RegularDropDown";
import { useProductStore } from "../../../store/simulation/useProductStore"; import { useProductStore } from "../../../store/simulation/useProductStore";
import Scene from "../../../modules/scene/scene"; import Scene from "../../../modules/scene/scene";
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
interface Layout { const CompareLayOut = () => {
id: number; const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
name: string;
}
interface CompareLayoutProps {
dummyLayouts: Layout[];
}
const CompareLayOut: React.FC<CompareLayoutProps> = ({ dummyLayouts }) => {
const { products } = useProductStore(); const { products } = useProductStore();
const { setLoadingProgress } = useLoadingProgress();
const [width, setWidth] = useState("50vw"); const [width, setWidth] = useState("50vw");
const [isResizing, setIsResizing] = useState(false); const [isResizing, setIsResizing] = useState(false);
const [showLayoutDropdown, setShowLayoutDropdown] = useState(false); const [showLayoutDropdown, setShowLayoutDropdown] = useState(false);
const [selectedLayout, setSelectedLayout] = useState<string | null>(null); // Track selected layout
const wrapperRef = useRef<HTMLDivElement>(null); const wrapperRef = useRef<HTMLDivElement>(null);
const startWidthRef = useRef<number>(0); const startWidthRef = useRef<number>(0);
const startXRef = useRef<number>(0); const startXRef = useRef<number>(0);
@ -111,8 +104,11 @@ const CompareLayOut: React.FC<CompareLayoutProps> = ({ dummyLayouts }) => {
}, [isResizing]); }, [isResizing]);
const handleSelectLayout = (option: string) => { const handleSelectLayout = (option: string) => {
setSelectedLayout(option); // Set selected layout const product = products.find((product) => product.productName === option);
console.log("Selected layout:", option); if (product) {
setComparisonProduct(product.productId, product.productName);
setLoadingProgress(1);
}
}; };
return ( return (
@ -130,16 +126,16 @@ const CompareLayOut: React.FC<CompareLayoutProps> = ({ dummyLayouts }) => {
<ResizerIcon /> <ResizerIcon />
</button> </button>
<div className="chooseLayout-container"> <div className="chooseLayout-container">
{selectedLayout && ( {comparisonProduct && (
<div className="compare-layout-canvas-container"> <div className="compare-layout-canvas-container">
<Suspense fallback={null}> <Suspense fallback={null}>
<Scene /> <Scene layout="Comparison Layout" />
</Suspense> </Suspense>
</div> </div>
)} )}
{width !== "0px" && {width !== "0px" &&
!selectedLayout && ( // Show only if no layout selected !comparisonProduct && ( // Show only if no layout selected
<div className="chooseLayout-wrapper"> <div className="chooseLayout-wrapper">
<div className="icon"> <div className="icon">
<CompareLayoutIcon /> <CompareLayoutIcon />
@ -177,16 +173,6 @@ const CompareLayOut: React.FC<CompareLayoutProps> = ({ dummyLayouts }) => {
)} )}
{/* Always show after layout is selected */} {/* Always show after layout is selected */}
{width !== "0px" && selectedLayout && (
<div className="selectLayout-wrapper">
<RegularDropDown
header={selectedLayout}
options={products.map((l) => l.productName)} // Pass layout names as options
onSelect={handleSelectLayout}
search={false}
/>
</div>
)}
</div> </div>
</div> </div>
); );

View File

@ -12,6 +12,7 @@ import useModuleStore from "../../../store/useModuleStore";
import { useThree } from "@react-three/fiber"; import { useThree } from "@react-three/fiber";
import { CameraControls } from "@react-three/drei"; import { CameraControls } from "@react-three/drei";
import addAssetModel from "./functions/addAssetModel"; import addAssetModel from "./functions/addAssetModel";
import { useSceneContext } from "../../scene/sceneContext";
const gltfLoaderWorker = new Worker( const gltfLoaderWorker = new Worker(
new URL( new URL(
@ -20,8 +21,9 @@ const gltfLoaderWorker = new Worker(
) )
); );
function AssetsGroup({ floorGroup, plane }: { floorGroup: RefGroup, plane: RefMesh }) { function AssetsGroup({ floorGroup, plane }: { readonly floorGroup: RefGroup, readonly plane: RefMesh }) {
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const { layout } = useSceneContext();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { controls, gl, pointer, camera, raycaster } = useThree(); const { controls, gl, pointer, camera, raycaster } = useThree();
const { setLoadingProgress } = useLoadingProgress(); const { setLoadingProgress } = useLoadingProgress();

View File

@ -12,7 +12,8 @@ import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore'; import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore';
import { useLeftData, useTopData } from '../../../../../store/visualization/useZone3DWidgetStore'; import { useLeftData, useTopData } from '../../../../../store/visualization/useZone3DWidgetStore';
import { useSelectedAsset, useSelectedProduct } from '../../../../../store/simulation/useSimulationStore'; import { useSelectedAsset } from '../../../../../store/simulation/useSimulationStore';
import { useProductContext } from '../../../../simulation/products/productContext';
function Model({ asset }: { readonly asset: Asset }) { function Model({ asset }: { readonly asset: Asset }) {
const { camera, controls, gl } = useThree(); const { camera, controls, gl } = useThree();
@ -24,7 +25,8 @@ function Model({ asset }: { readonly asset: Asset }) {
const { setLeft } = useLeftData(); const { setLeft } = useLeftData();
const { getIsEventInProduct } = useProductStore(); const { getIsEventInProduct } = useProductStore();
const { getEventByModelUuid } = useEventsStore(); const { getEventByModelUuid } = useEventsStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { setSelectedAsset, clearSelectedAsset } = useSelectedAsset(); const { setSelectedAsset, clearSelectedAsset } = useSelectedAsset();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem(); const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
@ -250,10 +252,10 @@ function Model({ asset }: { readonly asset: Asset }) {
userData={asset} userData={asset}
onDoubleClick={(e) => { onDoubleClick={(e) => {
e.stopPropagation(); e.stopPropagation();
handleDblClick(asset);
}} }}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
handleDblClick(asset);
handleClick(asset); handleClick(asset);
}} }}
onPointerOver={(e) => { onPointerOver={(e) => {

View File

@ -11,11 +11,11 @@ import * as Types from "../../../../types/world/worldTypes";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
import { snapControls } from "../../../../utils/handleSnap"; import { snapControls } from "../../../../utils/handleSnap";
import DistanceFindingControls from "./distanceFindingControls"; import DistanceFindingControls from "./distanceFindingControls";
import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { useAssetsStore } from "../../../../store/builder/useAssetStore";
import { useProductContext } from "../../../simulation/products/productContext";
function MoveControls({ function MoveControls({
movedObjects, movedObjects,
@ -34,7 +34,8 @@ function MoveControls({
const { toggleView } = useToggleView(); const { toggleView } = useToggleView();
const { selectedAssets, setSelectedAssets } = useSelectedAssets(); const { selectedAssets, setSelectedAssets } = useSelectedAssets();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">(""); const [keyEvent, setKeyEvent] = useState<"Ctrl" | "Shift" | "Ctrl+Shift" | "">("");
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");

View File

@ -6,9 +6,9 @@ import { useSelectedAssets, useSocketStore, useToggleView } from "../../../../st
import * as Types from "../../../../types/world/worldTypes"; import * as Types from "../../../../types/world/worldTypes";
import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { useAssetsStore } from "../../../../store/builder/useAssetStore";
import { useProductContext } from "../../../simulation/products/productContext";
function RotateControls({ function RotateControls({
rotatedObjects, rotatedObjects,
@ -27,7 +27,8 @@ function RotateControls({
const { toggleView } = useToggleView(); const { toggleView } = useToggleView();
const { selectedAssets, setSelectedAssets } = useSelectedAssets(); const { selectedAssets, setSelectedAssets } = useSelectedAssets();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const email = localStorage.getItem('email') const email = localStorage.getItem('email')
@ -208,7 +209,7 @@ function RotateControls({
if (obj.userData.eventData) { if (obj.userData.eventData) {
const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modelUuid); const eventData = useEventsStore.getState().getEventByModelUuid(obj.userData.modelUuid);
const productData = useProductStore.getState().getEventByModelUuid(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modelUuid); const productData = useProductStore.getState().getEventByModelUuid(selectedProductStore.getState().selectedProduct.productId, obj.userData.modelUuid);
if (eventData) { if (eventData) {
useEventsStore.getState().updateEvent(obj.userData.modelUuid, { useEventsStore.getState().updateEvent(obj.userData.modelUuid, {
@ -217,7 +218,7 @@ function RotateControls({
}) })
} }
if (productData) { if (productData) {
const event = useProductStore.getState().updateEvent(useSelectedProduct.getState().selectedProduct.productId, obj.userData.modelUuid, { const event = useProductStore.getState().updateEvent(selectedProductStore.getState().selectedProduct.productId, obj.userData.modelUuid, {
position: [worldPosition.x, worldPosition.y, worldPosition.z], position: [worldPosition.x, worldPosition.y, worldPosition.z],
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z], rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
}) })

View File

@ -8,10 +8,10 @@ import { useEffect, useState } from "react";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys"; import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi"; import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
import { useAssetsStore } from "../../../../store/builder/useAssetStore"; import { useAssetsStore } from "../../../../store/builder/useAssetStore";
import { useProductContext } from "../../../simulation/products/productContext";
export default function TransformControl() { export default function TransformControl() {
const state = useThree(); const state = useThree();
@ -21,7 +21,8 @@ export default function TransformControl() {
const { setObjectRotation } = useObjectRotation(); const { setObjectRotation } = useObjectRotation();
const { activeTool } = useActiveTool(); const { activeTool } = useActiveTool();
const { socket } = useSocketStore(); const { socket } = useSocketStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { updateAsset, getAssetById } = useAssetsStore(); const { updateAsset, getAssetById } = useAssetsStore();
const email = localStorage.getItem('email') const email = localStorage.getItem('email')

View File

@ -1,5 +1,6 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { Canvas } from "@react-three/fiber"; import { Canvas } from "@react-three/fiber";
import { Color } from "three";
import { KeyboardControls } from "@react-three/drei"; import { KeyboardControls } from "@react-three/drei";
import { SceneProvider } from "./sceneContext"; import { SceneProvider } from "./sceneContext";
@ -9,7 +10,7 @@ import Setup from "./setup/setup";
import Simulation from "../simulation/simulation"; import Simulation from "../simulation/simulation";
import Collaboration from "../collaboration/collaboration"; import Collaboration from "../collaboration/collaboration";
export default function Scene() { export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Comparison Layout' }) {
const map = useMemo(() => [ const map = useMemo(() => [
{ name: "forward", keys: ["ArrowUp", "w", "W"] }, { name: "forward", keys: ["ArrowUp", "w", "W"] },
{ name: "backward", keys: ["ArrowDown", "s", "S"] }, { name: "backward", keys: ["ArrowDown", "s", "S"] },
@ -18,7 +19,7 @@ export default function Scene() {
], []); ], []);
return ( return (
<SceneProvider> <SceneProvider layout={layout}>
<KeyboardControls map={map}> <KeyboardControls map={map}>
<Canvas <Canvas
eventPrefix="client" eventPrefix="client"
@ -26,6 +27,9 @@ export default function Scene() {
onContextMenu={(e) => { onContextMenu={(e) => {
e.preventDefault(); e.preventDefault();
}} }}
onCreated={(e) => {
e.scene.background = new Color(0x19191d);
}}
> >
<Setup /> <Setup />
<Collaboration /> <Collaboration />

View File

@ -13,11 +13,18 @@ type SceneContextValue = {
conveyorStore: ConveyorStoreType; conveyorStore: ConveyorStoreType;
vehicleStore: VehicleStoreType; vehicleStore: VehicleStoreType;
storageUnitStore: StorageUnitStoreType; storageUnitStore: StorageUnitStoreType;
layout: 'Main Layout' | 'Comparison Layout';
}; };
const SceneContext = createContext<SceneContextValue | null>(null); const SceneContext = createContext<SceneContextValue | null>(null);
export function SceneProvider({ children }: { readonly children: React.ReactNode }) { export function SceneProvider({
children,
layout
}: {
readonly children: React.ReactNode;
readonly layout: 'Main Layout' | 'Comparison Layout';
}) {
const materialStore = useMemo(() => createMaterialStore(), []); const materialStore = useMemo(() => createMaterialStore(), []);
const armBotStore = useMemo(() => createArmBotStore(), []); const armBotStore = useMemo(() => createArmBotStore(), []);
const machineStore = useMemo(() => createMachineStore(), []); const machineStore = useMemo(() => createMachineStore(), []);
@ -32,9 +39,10 @@ export function SceneProvider({ children }: { readonly children: React.ReactNode
machineStore, machineStore,
conveyorStore, conveyorStore,
vehicleStore, vehicleStore,
storageUnitStore storageUnitStore,
layout
} }
), [materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore]); ), [materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, layout]);
return ( return (
<SceneContext.Provider value={contextValue}> <SceneContext.Provider value={contextValue}>

View File

@ -2,9 +2,9 @@ import { useCallback, useEffect, useState } from "react";
import * as THREE from 'three'; import * as THREE from 'three';
import { useFrame } from "@react-three/fiber"; import { useFrame } from "@react-three/fiber";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { usePlayButtonStore, useAnimationPlaySpeed, usePauseButtonStore, useResetButtonStore } from "../../../../../store/usePlayButtonStore"; import { usePlayButtonStore, useAnimationPlaySpeed, usePauseButtonStore, useResetButtonStore } from "../../../../../store/usePlayButtonStore";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext";
interface SpawnInstance { interface SpawnInstance {
lastSpawnTime: number | null; lastSpawnTime: number | null;
@ -30,7 +30,8 @@ export function useSpawnHandler() {
const { isPaused } = usePauseButtonStore(); const { isPaused } = usePauseButtonStore();
const { speed } = useAnimationPlaySpeed(); const { speed } = useAnimationPlaySpeed();
const { isReset } = useResetButtonStore(); const { isReset } = useResetButtonStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const [activeSpawns, setActiveSpawns] = useState<Map<string, SpawnInstance>>(new Map()); const [activeSpawns, setActiveSpawns] = useState<Map<string, SpawnInstance>>(new Map());

View File

@ -1,14 +1,15 @@
import { useCallback } from "react"; import { useCallback } from "react";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext";
export function useProcessHandler() { export function useProcessHandler() {
const { materialStore, machineStore } = useSceneContext(); const { materialStore, machineStore } = useSceneContext();
const { selectedProductStore } = useProductContext();
const { getMaterialById, setMaterial } = materialStore(); const { getMaterialById, setMaterial } = materialStore();
const { addCurrentAction } = machineStore(); const { addCurrentAction } = machineStore();
const { getModelUuidByActionUuid } = useProductStore(); const { getModelUuidByActionUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const processLogStatus = (materialUuid: string, status: string) => { const processLogStatus = (materialUuid: string, status: string) => {
echo.log(`${materialUuid}, ${status}`); echo.log(`${materialUuid}, ${status}`);

View File

@ -1,14 +1,15 @@
import { useCallback } from "react"; import { useCallback } from "react";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext";
export function usePickAndPlaceHandler() { export function usePickAndPlaceHandler() {
const { materialStore, armBotStore } = useSceneContext(); const { materialStore, armBotStore } = useSceneContext();
const { selectedProductStore } = useProductContext();
const { getMaterialById } = materialStore(); const { getMaterialById } = materialStore();
const { addCurrentAction } = armBotStore(); const { addCurrentAction } = armBotStore();
const { getModelUuidByActionUuid } = useProductStore(); const { getModelUuidByActionUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const pickAndPlaceLogStatus = (materialUuid: string, status: string) => { const pickAndPlaceLogStatus = (materialUuid: string, status: string) => {
echo.warn(`${materialUuid}, ${status}`); echo.warn(`${materialUuid}, ${status}`);

View File

@ -1,17 +1,18 @@
import { useCallback, useState, useEffect, useRef } from "react"; import { useCallback, useState, useEffect, useRef } from "react";
import { useFrame } from "@react-three/fiber"; import { useFrame } from "@react-three/fiber";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore, useAnimationPlaySpeed } from "../../../../../store/usePlayButtonStore"; import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore, useAnimationPlaySpeed } from "../../../../../store/usePlayButtonStore";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext";
export function useRetrieveHandler() { export function useRetrieveHandler() {
const { materialStore, armBotStore, vehicleStore, storageUnitStore } = useSceneContext(); const { materialStore, armBotStore, vehicleStore, storageUnitStore } = useSceneContext();
const { selectedProductStore } = useProductContext();
const { addMaterial } = materialStore(); const { addMaterial } = materialStore();
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = useProductStore(); const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = useProductStore();
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore(); const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore();
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore(); const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { getArmBotById, addCurrentAction } = armBotStore(); const { getArmBotById, addCurrentAction } = armBotStore();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { speed } = useAnimationPlaySpeed(); const { speed } = useAnimationPlaySpeed();

View File

@ -1,14 +1,15 @@
import { useCallback } from "react"; import { useCallback } from "react";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext";
export function useStoreHandler() { export function useStoreHandler() {
const { materialStore, storageUnitStore } = useSceneContext(); const { materialStore, storageUnitStore } = useSceneContext();
const { getMaterialById, removeMaterial, setEndTime } = materialStore(); const { getMaterialById, removeMaterial, setEndTime } = materialStore();
const { addCurrentMaterial, updateCurrentLoad } = storageUnitStore(); const { addCurrentMaterial, updateCurrentLoad } = storageUnitStore();
const { getModelUuidByActionUuid } = useProductStore(); const { getModelUuidByActionUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const storeLogStatus = (materialUuid: string, status: string) => { const storeLogStatus = (materialUuid: string, status: string) => {
echo.info(`${materialUuid}, ${status}`); echo.info(`${materialUuid}, ${status}`);

View File

@ -1,13 +1,14 @@
import { useCallback } from "react"; import { useCallback } from "react";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { useSceneContext } from "../../../../scene/sceneContext"; import { useSceneContext } from "../../../../scene/sceneContext";
import { useProductContext } from "../../../products/productContext";
export function useTravelHandler() { export function useTravelHandler() {
const { materialStore, vehicleStore } = useSceneContext(); const { materialStore, vehicleStore } = useSceneContext();
const { selectedProductStore } = useProductContext();
const { getMaterialById } = materialStore(); const { getMaterialById } = materialStore();
const { getModelUuidByActionUuid } = useProductStore(); const { getModelUuidByActionUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { incrementVehicleLoad, addCurrentMaterial } = vehicleStore(); const { incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
const travelLogStatus = (materialUuid: string, status: string) => { const travelLogStatus = (materialUuid: string, status: string) => {

View File

@ -1,12 +1,13 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { useInputValues, useProductionCapacityData, useROISummaryData } from '../../../../store/builder/store'; import { useInputValues, useProductionCapacityData, useROISummaryData } from '../../../../store/builder/store';
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore'; import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { useProductContext } from '../../products/productContext';
export default function ROIData() { export default function ROIData() {
const { selectedProductStore } = useProductContext();
const { inputValues } = useInputValues(); const { inputValues } = useInputValues();
const { productionCapacityData } = useProductionCapacityData() const { productionCapacityData } = useProductionCapacityData()
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { setRoiSummaryData } = useROISummaryData(); const { setRoiSummaryData } = useROISummaryData();
useEffect(() => { useEffect(() => {

View File

@ -1,14 +1,15 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
import { useProductStore } from '../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../store/simulation/useProductStore';
import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences'; import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences';
import { useMachineCount, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store'; import { useMachineCount, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore'; import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { useSceneContext } from '../../../scene/sceneContext'; import { useSceneContext } from '../../../scene/sceneContext';
import { useProductContext } from '../../products/productContext';
export default function ThroughPutData() { export default function ThroughPutData() {
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore } = useSceneContext(); const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore } = useSceneContext();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { products, getProductById } = useProductStore(); const { products, getProductById } = useProductStore();
const { armBots } = armBotStore(); const { armBots } = armBotStore();
const { vehicles } = vehicleStore(); const { vehicles } = vehicleStore();

View File

@ -1,13 +1,14 @@
import { useEffect } from 'react' import { useEffect } from 'react'
import { useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useResetButtonStore } from '../../../../../store/usePlayButtonStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../../store/simulation/useProductStore';
import { useSceneContext } from '../../../../scene/sceneContext'; import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext';
// import { findConveyorSubsequence } from '../../../simulator/functions/getConveyorSequencesInProduct'; // import { findConveyorSubsequence } from '../../../simulator/functions/getConveyorSequencesInProduct';
function ConveyorInstance({ conveyor }: { conveyor: ConveyorStatus }) { function ConveyorInstance({ conveyor }: { readonly conveyor: ConveyorStatus }) {
const { getProductById } = useProductStore(); const { getProductById } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { materialStore, conveyorStore } = useSceneContext(); const { materialStore, conveyorStore } = useSceneContext();
const { getMaterialsByCurrentModelUuid, materials } = materialStore(); const { getMaterialsByCurrentModelUuid, materials } = materialStore();
const { isReset } = useResetButtonStore(); const { isReset } = useResetButtonStore();

View File

@ -2,7 +2,6 @@ import { useEffect, useRef, useState } from "react";
import * as THREE from "three"; import * as THREE from "three";
import { useEventsStore } from "../../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../../store/simulation/useProductStore";
import { useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore"; import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore";
import { TransformControls } from "@react-three/drei"; import { TransformControls } from "@react-three/drei";
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys"; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
@ -10,13 +9,15 @@ import { useSelectedEventSphere, useSelectedEventData, } from "../../../../../st
import { useThree } from "@react-three/fiber"; import { useThree } from "@react-three/fiber";
import { usePlayButtonStore } from "../../../../../store/usePlayButtonStore"; import { usePlayButtonStore } from "../../../../../store/usePlayButtonStore";
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
import { useProductContext } from "../../../products/productContext";
function PointsCreator() { function PointsCreator() {
const { gl, raycaster, scene, pointer, camera } = useThree(); const { gl, raycaster, scene, pointer, camera } = useThree();
const { subModule } = useSubModuleStore(); const { subModule } = useSubModuleStore();
const { selectedProductStore } = useProductContext();
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore(); const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getEventByModelUuid: getEventByModelUuidFromProduct2, getPointByUuid: getPointByUuidFromProduct } = useProductStore(); const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getEventByModelUuid: getEventByModelUuidFromProduct2, getPointByUuid: getPointByUuidFromProduct } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { activeModule } = useModuleStore(); const { activeModule } = useModuleStore();
const transformRef = useRef<any>(null); const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null); const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);

View File

@ -5,13 +5,13 @@ import { useSubModuleStore } from "../../../../store/useModuleStore";
import { useSelectedAction, useSelectedAsset } from "../../../../store/simulation/useSimulationStore"; import { useSelectedAction, useSelectedAsset } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { useEventsStore } from "../../../../store/simulation/useEventsStore"; import { useEventsStore } from "../../../../store/simulation/useEventsStore";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { handleAddEventToProduct } from "../points/functions/handleAddEventToProduct"; import { handleAddEventToProduct } from "../points/functions/handleAddEventToProduct";
import { QuadraticBezierLine } from "@react-three/drei"; import { QuadraticBezierLine } from "@react-three/drei";
import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi"; import { upsertProductOrEventApi } from "../../../../services/simulation/products/UpsertProductOrEventApi";
import { useDeleteTool } from "../../../../store/builder/store"; import { useDeleteTool } from "../../../../store/builder/store";
import { usePlayButtonStore } from "../../../../store/usePlayButtonStore"; import { usePlayButtonStore } from "../../../../store/usePlayButtonStore";
import { ArrowOnQuadraticBezier, Arrows } from "../arrows/arrows"; import { ArrowOnQuadraticBezier, Arrows } from "../arrows/arrows";
import { useProductContext } from "../../products/productContext";
interface ConnectionLine { interface ConnectionLine {
id: string; id: string;
@ -23,9 +23,10 @@ interface ConnectionLine {
function TriggerConnector() { function TriggerConnector() {
const { gl, raycaster, scene, pointer, camera } = useThree(); const { gl, raycaster, scene, pointer, camera } = useThree();
const { subModule } = useSubModuleStore(); const { subModule } = useSubModuleStore();
const { selectedProductStore } = useProductContext();
const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getPointUuidByActionUuid, getProductById } = useProductStore(); const { products, getPointByUuid, getIsEventInProduct, getActionByUuid, addTrigger, removeTrigger, addEvent, getEventByModelUuid, getPointUuidByActionUuid, getProductById } = useProductStore();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null); const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
const groupRefs = useRef<Record<string, any>>({}); const groupRefs = useRef<Record<string, any>>({});
const [helperlineColor, setHelperLineColor] = useState<string>("red"); const [helperlineColor, setHelperLineColor] = useState<string>("red");

View File

@ -2,9 +2,9 @@ import { useEffect, useRef, useState } from 'react'
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import MachineAnimator from '../animator/machineAnimator'; import MachineAnimator from '../animator/machineAnimator';
import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
import { useSceneContext } from '../../../../scene/sceneContext'; import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext';
function MachineInstance({ machineDetail }: { readonly machineDetail: MachineStatus }) { function MachineInstance({ machineDetail }: { readonly machineDetail: MachineStatus }) {
const [currentPhase, setCurrentPhase] = useState<string>('idle'); const [currentPhase, setCurrentPhase] = useState<string>('idle');
@ -17,8 +17,9 @@ function MachineInstance({ machineDetail }: { readonly machineDetail: MachineSta
const isPausedRef = useRef<boolean>(false); const isPausedRef = useRef<boolean>(false);
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { machineStore } = useSceneContext(); const { machineStore } = useSceneContext();
const { selectedProductStore } = useProductContext();
const { machines, setMachineState, setMachineActive, incrementIdleTime, incrementActiveTime, resetTime } = machineStore(); const { machines, setMachineState, setMachineActive, incrementIdleTime, incrementActiveTime, resetTime } = machineStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { getActionByUuid } = useProductStore(); const { getActionByUuid } = useProductStore();
const { triggerPointActions } = useTriggerHandler(); const { triggerPointActions } = useTriggerHandler();
const { speed } = useAnimationPlaySpeed(); const { speed } = useAnimationPlaySpeed();

View File

@ -1,18 +1,19 @@
import React, { useEffect, useMemo, useRef, useState } from 'react' import { useMemo, useRef } from 'react'
import * as THREE from 'three'; import * as THREE from 'three';
import MaterialAnimator from '../animator/materialAnimator'; import MaterialAnimator from '../animator/materialAnimator';
import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { MaterialModel } from '../material/materialModel'; import { MaterialModel } from '../material/materialModel';
import { useThree } from '@react-three/fiber'; import { useThree } from '@react-three/fiber';
import { useAnimationPlaySpeed } from '../../../../../store/usePlayButtonStore'; import { useAnimationPlaySpeed } from '../../../../../store/usePlayButtonStore';
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
import { useProductContext } from '../../../products/productContext';
function MaterialInstance({ material }: { material: MaterialSchema }) { function MaterialInstance({ material }: { readonly material: MaterialSchema }) {
const matRef: any = useRef(); const matRef: any = useRef();
const { scene } = useThree(); const { scene } = useThree();
const { selectedProductStore } = useProductContext();
const { getModelUuidByPointUuid, getPointByUuid, getEventByModelUuid, getActionByUuid, getTriggerByUuid, getActionByPointUuid } = useProductStore(); const { getModelUuidByPointUuid, getPointByUuid, getEventByModelUuid, getActionByUuid, getTriggerByUuid, getActionByPointUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { speed } = useAnimationPlaySpeed(); const { speed } = useAnimationPlaySpeed();
const { triggerPointActions } = useTriggerHandler(); const { triggerPointActions } = useTriggerHandler();

View File

@ -0,0 +1,37 @@
import { createContext, useContext, useMemo } from 'react';
import { createSelectedProductStore, SelectedProductType } from '../../../store/simulation/useSimulationStore';
type ProductContextValue = {
selectedProductStore: SelectedProductType,
};
const ProductContext = createContext<ProductContextValue | null>(null);
export function ProductProvider({
children,
}: {
readonly children: React.ReactNode;
}) {
const selectedProductStore = useMemo(() => createSelectedProductStore(), []);
const contextValue = useMemo(() => (
{
selectedProductStore
}
), [selectedProductStore]);
return (
<ProductContext.Provider value={contextValue}>
{children}
</ProductContext.Provider>
);
}
// Base hook to get the context
export function useProductContext() {
const context = useContext(ProductContext);
if (!context) {
throw new Error('useProductContext must be used within a ProductProvider');
}
return context;
}

View File

@ -1,16 +1,18 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useProductStore } from '../../../store/simulation/useProductStore'; import { useProductStore } from '../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../store/simulation/useSimulationStore';
import { upsertProductOrEventApi } from '../../../services/simulation/products/UpsertProductOrEventApi'; import { upsertProductOrEventApi } from '../../../services/simulation/products/UpsertProductOrEventApi';
import { getAllProductsApi } from '../../../services/simulation/products/getallProductsApi'; import { getAllProductsApi } from '../../../services/simulation/products/getallProductsApi';
import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayButtonStore'; import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayButtonStore';
import { useSceneContext } from '../../scene/sceneContext'; import { useSceneContext } from '../../scene/sceneContext';
import { useProductContext } from './productContext';
import { useComparisonProduct, useMainProduct } from '../../../store/simulation/useSimulationStore';
function Products() { function Products() {
const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore } = useSceneContext(); const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, layout } = useSceneContext();
const { products, getProductById, addProduct, setProducts } = useProductStore(); const { products, getProductById, addProduct, setProducts } = useProductStore();
const { selectedProduct, setSelectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct, setSelectedProduct } = selectedProductStore();
const { addVehicle, clearvehicles } = vehicleStore(); const { addVehicle, clearvehicles } = vehicleStore();
const { addArmBot, clearArmBots } = armBotStore(); const { addArmBot, clearArmBots } = armBotStore();
const { addMachine, clearMachines } = machineStore(); const { addMachine, clearMachines } = machineStore();
@ -18,6 +20,24 @@ function Products() {
const { setCurrentMaterials, clearStorageUnits, updateCurrentLoad, addStorageUnit } = storageUnitStore(); const { setCurrentMaterials, clearStorageUnits, updateCurrentLoad, addStorageUnit } = storageUnitStore();
const { isReset } = useResetButtonStore(); const { isReset } = useResetButtonStore();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { mainProduct } = useMainProduct();
const { comparisonProduct } = useComparisonProduct();
useEffect(() => {
if (layout === 'Main Layout' && mainProduct) {
setSelectedProduct(mainProduct.productId, mainProduct.productName);
}
}, [mainProduct])
useEffect(() => {
if (layout === 'Comparison Layout' && comparisonProduct) {
setSelectedProduct(comparisonProduct.productId, comparisonProduct.productName);
}
}, [comparisonProduct])
useEffect(() => {
console.log(selectedProduct);
}, [selectedProduct])
useEffect(() => { useEffect(() => {
const email = localStorage.getItem('email') const email = localStorage.getItem('email')
@ -28,11 +48,15 @@ function Products() {
const name = 'Product 1'; const name = 'Product 1';
addProduct(name, id); addProduct(name, id);
upsertProductOrEventApi({ productName: name, productId: id, organization: organization }) upsertProductOrEventApi({ productName: name, productId: id, organization: organization })
if (layout === 'Main Layout') {
setSelectedProduct(id, name); setSelectedProduct(id, name);
}
} else { } else {
setProducts(data); setProducts(data);
if (layout === 'Main Layout') {
setSelectedProduct(data[0].productId, data[0].productName); setSelectedProduct(data[0].productId, data[0].productName);
} }
}
}) })
}, []) }, [])

View File

@ -7,9 +7,9 @@ import MaterialAnimator from '../animator/materialAnimator';
import armModel from "../../../../../assets/gltf-glb/rigged/ik_arm_1.glb"; import armModel from "../../../../../assets/gltf-glb/rigged/ik_arm_1.glb";
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
import { useSceneContext } from '../../../../scene/sceneContext'; import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext';
function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) { function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
@ -25,12 +25,13 @@ function RoboticArmInstance({ armBot }: { readonly armBot: ArmBotStatus }) {
const isSpeedRef = useRef<any>(null); const isSpeedRef = useRef<any>(null);
let startTime: number; let startTime: number;
const { selectedProductStore } = useProductContext();
const { materialStore, armBotStore, vehicleStore, storageUnitStore } = useSceneContext(); const { materialStore, armBotStore, vehicleStore, storageUnitStore } = useSceneContext();
const { setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = armBotStore(); const { setArmBotActive, setArmBotState, removeCurrentAction, incrementActiveTime, incrementIdleTime } = armBotStore();
const { decrementVehicleLoad, removeLastMaterial } = vehicleStore(); const { decrementVehicleLoad, removeLastMaterial } = vehicleStore();
const { removeLastMaterial: removeLastStorageMaterial, updateCurrentLoad } = storageUnitStore(); const { removeLastMaterial: removeLastStorageMaterial, updateCurrentLoad } = storageUnitStore();
const { getMaterialById, setIsVisible, setIsPaused } = materialStore(); const { getMaterialById, setIsVisible, setIsPaused } = materialStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { getActionByUuid, getEventByActionUuid, getEventByModelUuid } = useProductStore(); const { getActionByUuid, getEventByActionUuid, getEventByModelUuid } = useProductStore();
const { triggerPointActions } = useTriggerHandler(); const { triggerPointActions } = useTriggerHandler();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();

View File

@ -3,12 +3,13 @@ import { useProductStore } from '../../../store/simulation/useProductStore';
import { useActionHandler } from '../actions/useActionHandler'; import { useActionHandler } from '../actions/useActionHandler';
import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayButtonStore'; import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayButtonStore';
import { determineExecutionOrder } from './functions/determineExecutionOrder'; import { determineExecutionOrder } from './functions/determineExecutionOrder';
import { useSelectedProduct } from '../../../store/simulation/useSimulationStore'; import { useProductContext } from '../products/productContext';
function Simulator() { function Simulator() {
const { selectedProductStore } = useProductContext();
const { products, getProductById } = useProductStore(); const { products, getProductById } = useProductStore();
const { handleAction } = useActionHandler(); const { handleAction } = useActionHandler();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { isPlaying } = usePlayButtonStore(); const { isPlaying } = usePlayButtonStore();
const { isReset } = useResetButtonStore(); const { isReset } = useResetButtonStore();

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useSelectedAction, useSelectedEventSphere, useSelectedProduct } from '../../../../store/simulation/useSimulationStore'; import { useSelectedAction, useSelectedEventSphere } from '../../../../store/simulation/useSimulationStore';
import { useGLTF } from '@react-three/drei'; import { useGLTF } from '@react-three/drei';
import { useThree } from '@react-three/fiber'; import { useThree } from '@react-three/fiber';
import { useProductStore } from '../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../store/simulation/useProductStore';
@ -11,6 +11,7 @@ import armPick from "../../../../assets/gltf-glb/ui/arm_ui_pick.glb";
import armDrop from "../../../../assets/gltf-glb/ui/arm_ui_drop.glb"; import armDrop from "../../../../assets/gltf-glb/ui/arm_ui_drop.glb";
import { upsertProductOrEventApi } from '../../../../services/simulation/products/UpsertProductOrEventApi'; import { upsertProductOrEventApi } from '../../../../services/simulation/products/UpsertProductOrEventApi';
import { useSceneContext } from '../../../scene/sceneContext'; import { useSceneContext } from '../../../scene/sceneContext';
import { useProductContext } from '../../products/productContext';
type Positions = { type Positions = {
pick: [number, number, number]; pick: [number, number, number];
@ -21,7 +22,8 @@ type Positions = {
const ArmBotUI = () => { const ArmBotUI = () => {
const { getEventByModelUuid, updateAction, getActionByUuid } = useProductStore(); const { getEventByModelUuid, updateAction, getActionByUuid } = useProductStore();
const { selectedEventSphere } = useSelectedEventSphere(); const { selectedEventSphere } = useSelectedEventSphere();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { scene } = useThree(); const { scene } = useThree();
const { selectedAction } = useSelectedAction(); const { selectedAction } = useSelectedAction();
const { armBotStore } = useSceneContext(); const { armBotStore } = useSceneContext();

View File

@ -4,21 +4,19 @@ import { ThreeEvent, useThree } from "@react-three/fiber";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
import { import {
useSelectedEventData, useSelectedEventData,
useSelectedProduct,
} from "../../../../store/simulation/useSimulationStore"; } from "../../../../store/simulation/useSimulationStore";
import { useProductContext } from "../../products/productContext";
type OnUpdateCallback = (object: THREE.Object3D) => void; type OnUpdateCallback = (object: THREE.Object3D) => void;
export default function useDraggableGLTF(onUpdate: OnUpdateCallback) { export default function useDraggableGLTF(onUpdate: OnUpdateCallback) {
const { getEventByModelUuid, updateAction, getActionByUuid } = const { getEventByModelUuid } = useProductStore();
useProductStore();
const { selectedEventData } = useSelectedEventData(); const { selectedEventData } = useSelectedEventData();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { camera, gl, controls } = useThree(); const { camera, gl, controls } = useThree();
const activeObjRef = useRef<THREE.Object3D | null>(null); const activeObjRef = useRef<THREE.Object3D | null>(null);
const planeRef = useRef<THREE.Plane>( const planeRef = useRef<THREE.Plane>(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0));
new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)
);
const offsetRef = useRef<THREE.Vector3>(new THREE.Vector3()); const offsetRef = useRef<THREE.Vector3>(new THREE.Vector3());
const initialPositionRef = useRef<THREE.Vector3>(new THREE.Vector3()); const initialPositionRef = useRef<THREE.Vector3>(new THREE.Vector3());

View File

@ -5,7 +5,6 @@ import { useFrame, useThree } from "@react-three/fiber";
import { import {
useSelectedEventSphere, useSelectedEventSphere,
useIsDragging, useIsDragging,
useSelectedProduct,
useIsRotating, useIsRotating,
} from "../../../../store/simulation/useSimulationStore"; } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore"; import { useProductStore } from "../../../../store/simulation/useProductStore";
@ -15,6 +14,7 @@ import { DoubleSide, Group, Plane, Vector3 } from "three";
import startPoint from "../../../../assets/gltf-glb/ui/arrow_green.glb"; import startPoint from "../../../../assets/gltf-glb/ui/arrow_green.glb";
import startEnd from "../../../../assets/gltf-glb/ui/arrow_red.glb"; import startEnd from "../../../../assets/gltf-glb/ui/arrow_red.glb";
import { useSceneContext } from "../../../scene/sceneContext"; import { useSceneContext } from "../../../scene/sceneContext";
import { useProductContext } from "../../products/productContext";
const VehicleUI = () => { const VehicleUI = () => {
const { scene: startScene } = useGLTF(startPoint) as any; const { scene: startScene } = useGLTF(startPoint) as any;
@ -23,8 +23,9 @@ const VehicleUI = () => {
const endMarker = useRef<Group>(null); const endMarker = useRef<Group>(null);
const prevMousePos = useRef({ x: 0, y: 0 }); const prevMousePos = useRef({ x: 0, y: 0 });
const { selectedEventSphere } = useSelectedEventSphere(); const { selectedEventSphere } = useSelectedEventSphere();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { vehicleStore } = useSceneContext(); const { vehicleStore } = useSceneContext();
const { selectedProduct } = selectedProductStore();
const { vehicles, getVehicleById } = vehicleStore(); const { vehicles, getVehicleById } = vehicleStore();
const { updateEvent } = useProductStore(); const { updateEvent } = useProductStore();
const [startPosition, setStartPosition] = useState<[number, number, number]>([ const [startPosition, setStartPosition] = useState<[number, number, number]>([

View File

@ -1,17 +1,18 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useActionHandler } from '../../actions/useActionHandler'; import { useActionHandler } from '../../actions/useActionHandler';
import { useProductStore } from '../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
import { useArmBotEventManager } from '../../roboticArm/eventManager/useArmBotEventManager'; import { useArmBotEventManager } from '../../roboticArm/eventManager/useArmBotEventManager';
import { useConveyorEventManager } from '../../conveyor/eventManager/useConveyorEventManager'; import { useConveyorEventManager } from '../../conveyor/eventManager/useConveyorEventManager';
import { useVehicleEventManager } from '../../vehicle/eventManager/useVehicleEventManager'; import { useVehicleEventManager } from '../../vehicle/eventManager/useVehicleEventManager';
import { useMachineEventManager } from '../../machine/eventManager/useMachineEventManager'; import { useMachineEventManager } from '../../machine/eventManager/useMachineEventManager';
import { useSceneContext } from '../../../scene/sceneContext'; import { useSceneContext } from '../../../scene/sceneContext';
import { useProductContext } from '../../products/productContext';
export function useTriggerHandler() { export function useTriggerHandler() {
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore } = useSceneContext(); const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore } = useSceneContext();
const { selectedProductStore } = useProductContext();
const { handleAction } = useActionHandler(); const { handleAction } = useActionHandler();
const { selectedProduct } = useSelectedProduct(); const { selectedProduct } = selectedProductStore();
const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore(); const { getEventByTriggerUuid, getEventByModelUuid, getActionByUuid, getModelUuidByActionUuid } = useProductStore();
const { getArmBotById } = armBotStore(); const { getArmBotById } = armBotStore();
const { getConveyorById } = conveyorStore(); const { getConveyorById } = conveyorStore();

View File

@ -5,10 +5,10 @@ import { NavMeshQuery } from '@recast-navigation/core';
import { useNavMesh } from '../../../../../store/builder/store'; import { useNavMesh } from '../../../../../store/builder/store';
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
import { useProductStore } from '../../../../../store/simulation/useProductStore'; import { useProductStore } from '../../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore';
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
import MaterialAnimator from '../animator/materialAnimator'; import MaterialAnimator from '../animator/materialAnimator';
import { useSceneContext } from '../../../../scene/sceneContext'; import { useSceneContext } from '../../../../scene/sceneContext';
import { useProductContext } from '../../../products/productContext';
function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) { function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) {
const { navMesh } = useNavMesh(); const { navMesh } = useNavMesh();
@ -20,7 +20,8 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
const { getConveyorById } = conveyorStore(); const { getConveyorById } = conveyorStore();
const { triggerPointActions } = useTriggerHandler(); const { triggerPointActions } = useTriggerHandler();
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore(); const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct(); const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, getLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = vehicleStore(); const { vehicles, setVehicleActive, setVehicleState, setVehiclePicking, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial, getLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = vehicleStore();
const [currentPhase, setCurrentPhase] = useState<string>('stationed'); const [currentPhase, setCurrentPhase] = useState<string>('stationed');

View File

@ -1,61 +1,39 @@
import React, { useEffect, useState } from "react"; import React, { useEffect } from "react";
import ModuleToggle from "../components/ui/ModuleToggle"; import useModuleStore from "../store/useModuleStore";
import SideBarLeft from "../components/layout/sidebarLeft/SideBarLeft";
import SideBarRight from "../components/layout/sidebarRight/SideBarRight";
import useModuleStore, { useThreeDStore } from "../store/useModuleStore";
import RealTimeVisulization from "../modules/visualization/RealTimeVisulization";
import Tools from "../components/ui/Tools";
import { import {
useSocketStore, useSocketStore,
useOrganization, useOrganization,
useUserName, useUserName,
useWallItems, useWallItems,
useZones, useZones,
useLoadingProgress,
useWidgetSubOption,
useSaveVersion, useSaveVersion,
} from "../store/builder/store"; } from "../store/builder/store";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { usePlayButtonStore } from "../store/usePlayButtonStore";
import MarketPlace from "../modules/market/MarketPlace";
import LoadingPage from "../components/templates/LoadingPage";
import KeyPressListener from "../utils/shortcutkeys/handleShortcutKeys";
import { useSelectedUserStore } from "../store/collaboration/useCollabStore"; import { useSelectedUserStore } from "../store/collaboration/useCollabStore";
import FollowPerson from "../components/templates/FollowPerson"; import FollowPerson from "../components/templates/FollowPerson";
import Scene from "../modules/scene/scene";
import { createHandleDrop } from "../modules/visualization/functions/handleUiDrop";
import { useSelectedZoneStore } from "../store/visualization/useZoneStore";
import { useFloatingWidget } from "../store/visualization/useDroppedObjectsStore";
import { useLogger } from "../components/ui/log/LoggerContext"; import { useLogger } from "../components/ui/log/LoggerContext";
import RenderOverlay from "../components/templates/Overlay"; import RenderOverlay from "../components/templates/Overlay";
import LogList from "../components/ui/log/LogList"; import LogList from "../components/ui/log/LogList";
import Footer from "../components/footer/Footer"; import Footer from "../components/footer/Footer";
import SelectFloorPlan from "../components/temporary/SelectFloorPlan";
import ControlsPlayer from "../components/layout/controls/ControlsPlayer";
import CompareLayOut from "../components/ui/compareVersion/CompareLayOut";
import { useToggleStore } from "../store/useUIToggleStore"; import { useToggleStore } from "../store/useUIToggleStore";
import RegularDropDown from "../components/ui/inputs/RegularDropDown";
import VersionSaved from "../components/layout/sidebarRight/versionHisory/VersionSaved"; import VersionSaved from "../components/layout/sidebarRight/versionHisory/VersionSaved";
import SimulationPlayer from "../components/ui/simulation/simulationPlayer";
import { useAssetsStore } from "../store/builder/useAssetStore"; import { useAssetsStore } from "../store/builder/useAssetStore";
import { useProductStore } from "../store/simulation/useProductStore"; import ComparisonSceneProvider from "../components/layout/scenes/ComparisonSceneProvider";
import ThreadChat from "../components/ui/collaboration/ThreadChat"; import MainSceneProvider from "../components/layout/scenes/MainSceneProvider";
import ComparisonResult from "../components/ui/compareVersion/ComparisonResult";
const Project: React.FC = () => { const Project: React.FC = () => {
let navigate = useNavigate(); let navigate = useNavigate();
const echo = useLogger(); const echo = useLogger();
const { setToggleUI } = useToggleStore(); const { setToggleUI } = useToggleStore();
const { activeModule, setActiveModule } = useModuleStore(); const { activeModule, setActiveModule } = useModuleStore();
const { loadingProgress } = useLoadingProgress();
const { setAssets } = useAssetsStore(); const { setAssets } = useAssetsStore();
const { setUserName } = useUserName(); const { setUserName } = useUserName();
const { setOrganization } = useOrganization(); const { setOrganization } = useOrganization();
const { setWallItems } = useWallItems(); const { setWallItems } = useWallItems();
const { setZones } = useZones(); const { setZones } = useZones();
const { isVersionSaved } = useSaveVersion(); const { isVersionSaved } = useSaveVersion();
const { products } = useProductStore(); const { selectedUser } = useSelectedUserStore();
const { isLogListVisible } = useLogger();
useEffect(() => { useEffect(() => {
if (!isVersionSaved) { if (!isVersionSaved) {
@ -85,84 +63,10 @@ const Project: React.FC = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
// global store
const { toggleThreeD } = useThreeDStore();
// simulation store
const { isPlaying } = usePlayButtonStore();
// collaboration store
const { selectedUser } = useSelectedUserStore();
const { isLogListVisible } = useLogger();
// real-time visualization store
const { widgetSubOption } = useWidgetSubOption();
const { visualizationSocket } = useSocketStore();
const { selectedZone } = useSelectedZoneStore();
const { setFloatingWidget } = useFloatingWidget();
const [selectedLayout, setSelectedLayout] = useState<string | null>(null); // Track selected layout
const dummyLayouts = [
{ id: 1, name: "Layout 1" },
{ id: 2, name: "Layout 2" },
{ id: 3, name: "Layout 3" },
{ id: 4, name: "Layout 4" },
];
const handleSelectLayout = (option: string) => {
setSelectedLayout(option); // Set selected layout
console.log("Selected layout:", option);
};
return ( return (
<div className="project-main"> <div className="project-main">
{!selectedUser && ( <ComparisonSceneProvider />
<> <MainSceneProvider />
<KeyPressListener />
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
{!isPlaying && (
<>
{toggleThreeD && <ModuleToggle />}
<SideBarLeft />
<SideBarRight />
</>
)}
<RealTimeVisulization />
{activeModule === "market" && <MarketPlace />}
{activeModule !== "market" && !isPlaying && !isVersionSaved && (
<Tools />
)}
{isPlaying && activeModule === "simulation" && <SimulationPlayer />}
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
{/* remove this later */}
{activeModule === "builder" && !toggleThreeD && <SelectFloorPlan />}
</>
)}
<div
className="scene-container"
id="work-space-three-d-canvas"
style={{
height: isPlaying || activeModule !== "visualization" ? "100vh" : "",
width: isPlaying || activeModule !== "visualization" ? "100vw" : "",
left: isPlaying || activeModule !== "visualization" ? "0%" : "",
borderRadius:
isPlaying || activeModule !== "visualization" ? "" : "6px",
}}
role="application"
onDrop={(event) =>
createHandleDrop({
widgetSubOption,
visualizationSocket,
selectedZone,
setFloatingWidget,
event,
})
}
onDragOver={(event) => event.preventDefault()}
>
<Scene />
</div>
{selectedUser && <FollowPerson />} {selectedUser && <FollowPerson />}
{isLogListVisible && ( {isLogListVisible && (
<RenderOverlay> <RenderOverlay>
@ -170,20 +74,6 @@ const Project: React.FC = () => {
</RenderOverlay> </RenderOverlay>
)} )}
{activeModule !== "market" && !selectedUser && <Footer />} {activeModule !== "market" && !selectedUser && <Footer />}
{isVersionSaved && activeModule === "simulation" && (
<>
<div className="initial-selectLayout-wrapper">
<RegularDropDown
header={selectedLayout ?? "Layout 1"}
options={products.map((l) => l.productName)} // Pass layout names as options
onSelect={handleSelectLayout}
search={false}
/>
</div>
<CompareLayOut dummyLayouts={dummyLayouts} />
{false && <ComparisonResult />}
</>
)}
<VersionSaved /> <VersionSaved />
</div> </div>
); );

View File

@ -74,7 +74,8 @@ interface SelectedProductState {
clearSelectedProduct: () => void; clearSelectedProduct: () => void;
} }
export const useSelectedProduct = create<SelectedProductState>()( export const createSelectedProductStore = () => {
return create<SelectedProductState>()(
immer((set) => ({ immer((set) => ({
selectedProduct: { productId: '', productName: '' }, selectedProduct: { productId: '', productName: '' },
setSelectedProduct: (productId, productName) => { setSelectedProduct: (productId, productName) => {
@ -90,7 +91,10 @@ export const useSelectedProduct = create<SelectedProductState>()(
}); });
}, },
})) }))
); )
}
export type SelectedProductType = ReturnType<typeof createSelectedProductStore>;
interface SelectedActionState { interface SelectedActionState {
selectedAction: { actionId: string | null; actionName: string | null }; selectedAction: { actionId: string | null; actionName: string | null };
@ -147,3 +151,47 @@ export const useIsRotating = create<IsRotatingState>()(
}, },
})) }))
); );
interface MainProductState {
mainProduct: { productId: string; productName: string } | null;
setMainProduct: (productId: string, productName: string) => void;
clearMainProduct: () => void;
}
export const useMainProduct = create<MainProductState>()(
immer((set) => ({
mainProduct: null,
setMainProduct: (productId: string, productName: string) => {
set((state) => {
state.mainProduct = { productId, productName };
});
},
clearMainProduct: () => {
set((state) => {
state.mainProduct = null;
});
},
}))
);
interface ComparisonProductState {
comparisonProduct: { productId: string; productName: string } | null;
setComparisonProduct: (productId: string, productName: string) => void;
clearComparisonProduct: () => void;
}
export const useComparisonProduct = create<ComparisonProductState>()(
immer((set) => ({
comparisonProduct: null,
setComparisonProduct: (productId: string, productName: string) => {
set((state) => {
state.comparisonProduct = { productId, productName };
});
},
clearComparisonProduct: () => {
set((state) => {
state.comparisonProduct = null;
});
},
}))
);

View File

@ -4,7 +4,18 @@
.initial-selectLayout-wrapper { .initial-selectLayout-wrapper {
position: fixed; position: fixed;
top: 100px; top: 100px;
right: 40px;
z-index: 10;
.regularDropdown-container {
background: var(--background-color);
}
}
.selectLayout-wrapper {
position: fixed;
left: 40px; left: 40px;
top: 100px;
z-index: 10; z-index: 10;
.regularDropdown-container { .regularDropdown-container {
@ -26,16 +37,6 @@
animation: slideInFromRight 0.4s ease-out forwards; animation: slideInFromRight 0.4s ease-out forwards;
user-select: none; user-select: none;
.selectLayout-wrapper {
position: absolute;
top: 100px;
right: 40px;
.regularDropdown-container {
background: var(--background-color);
}
}
.resizer { .resizer {
width: 32px; width: 32px;
height: 32px; height: 32px;
@ -160,7 +161,9 @@
width: 100%; width: 100%;
&:hover { &:hover {
background-color: var(--highlight-text-color) !important; background-color: var(
--highlight-text-color
) !important;
border-radius: 4px; border-radius: 4px;
.layout { .layout {