v2-ui #69

Merged
Vishnu merged 33 commits from v2-ui into main 2025-04-28 13:22:26 +00:00
26 changed files with 813 additions and 383 deletions
Showing only changes of commit a305c3c006 - Show all commits

View File

@@ -5,8 +5,8 @@ import Header from "./Header";
import useToggleStore from "../../../store/useUIToggleStore";
import Assets from "./Assets";
import useModuleStore from "../../../store/useModuleStore";
import Widgets from ".//visualization/widgets/Widgets";
import Templates from "../../../modules//visualization/template/Templates";
import Widgets from "./visualization/widgets/Widgets";
import Templates from "../../../modules/visualization/template/Templates";
import Search from "../../ui/inputs/Search";
const SideBarLeft: React.FC = () => {

View File

@@ -5,11 +5,11 @@ import {
GlobeIcon,
WalletIcon,
} from "../../../../icons/3dChartIcons";
import SimpleCard from "../../../../../modules//visualization/widgets/floating/cards/SimpleCard";
import SimpleCard from "../../../../../modules/visualization/widgets/floating/cards/SimpleCard";
import WarehouseThroughput from "../../../../../modules//visualization/widgets/floating/cards/WarehouseThroughput";
import ProductivityDashboard from "../../../../../modules//visualization/widgets/floating/cards/ProductivityDashboard";
import FleetEfficiency from "../../../../../modules//visualization/widgets/floating/cards/FleetEfficiency";
import WarehouseThroughput from "../../../../../modules/visualization/widgets/floating/cards/WarehouseThroughput";
import ProductivityDashboard from "../../../../../modules/visualization/widgets/floating/cards/ProductivityDashboard";
import FleetEfficiency from "../../../../../modules/visualization/widgets/floating/cards/FleetEfficiency";
interface Widget {
id: string;

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";
import Header from "./Header";
import useModuleStore, {
useSubModuleStore,
@@ -14,6 +14,7 @@ import Visualization from "./visualization/Visualization";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import { useSelectedFloorItem } from "../../../store/store";
import { useSelectedEventData, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
import GlobalProperties from "./properties/GlobalProperties";
import AsstePropertiies from "./properties/AssetProperties";
import ZoneProperties from "./properties/ZoneProperties";
@@ -24,53 +25,30 @@ const SideBarRight: React.FC = () => {
const { toggleUI } = useToggleStore();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
// Reset activeList whenever activeModule changes
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("mechanics");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule]);
// romove late
const dummyData = {
assetType: "store",
selectedPoint: {
name: "Point A",
uuid: "123e4567-e89b-12d3-a456-426614174000",
actions: [
{
uuid: "action-1",
name: "Action One",
},
{
uuid: "action-2",
name: "Action Two",
},
{
uuid: "action-3",
name: "Action Three",
},
],
},
selectedItem: {
item: {
uuid: "item-1",
name: "Item One",
isUsed: false,
},
},
setSelectedPoint: (value: string) => {
console.log(`Selected point updated to: ${value}`);
},
selectedActionSphere: "Sphere A",
useEffect(() => {
if (activeModule !== "mechanics" && selectedEventData && selectedEventSphere) {
setSubModule("mechanics");
} else {
if (activeModule === 'simulation') {
setSubModule("simulations");
}
};
}, [activeModule, selectedEventData, selectedEventSphere])
return (
<div className="sidebar-right-wrapper">
<Header />
{toggleUI && (
<div className="sidebar-actions-container">
{/* {activeModule === "builder" && ( */}
<div
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""
}`}
@@ -78,7 +56,6 @@ const SideBarRight: React.FC = () => {
>
<PropertiesIcon isActive={subModule === "properties"} />
</div>
{/* )} */}
{activeModule === "simulation" && (
<>
<div
@@ -137,13 +114,19 @@ const SideBarRight: React.FC = () => {
</div>
)}
{/* simulation */}
{toggleUI && activeModule === "simulation" && (
<>
{subModule === "mechanics" && (
{subModule === "simulations" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<EventProperties {...dummyData} />
<Simulations />
</div>
</div>
)}
{subModule === "mechanics" && selectedEventData && selectedEventSphere && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<EventProperties />
</div>
</div>
)}
@@ -154,16 +137,8 @@ const SideBarRight: React.FC = () => {
</div>
</div>
)}
{subModule === "simulations" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
<Simulations />
</div>
</div>
)}
</>
)}
{/* realtime visualization */}
{toggleUI && activeModule === "visualization" && <Visualization />}
</div>

View File

@@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import InputWithDropDown from "../../../../ui/inputs/InputWithDropDown";
import LabledDropdown from "../../../../ui/inputs/LabledDropdown";
import {
@@ -20,69 +20,73 @@ import ProcessAction from "./actions/ProcessAction";
import StorageAction from "./actions/StorageAction";
import Trigger from "./trigger/Trigger";
interface EventPropertiesProps {
assetType: string;
selectedPoint: {
name: string;
uuid: string;
actions: {
uuid: string;
name: string;
}[];
};
selectedItem: {
item: {
uuid: string;
name: string;
} | null;
};
setSelectedPoint: (value: string) => void;
selectedActionSphere: string;
}
import { useSelectedEventData, useSelectedProduct } from "../../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../../store/simulation/useProductStore";
const EventProperties: React.FC<EventPropertiesProps> = ({
assetType,
selectedPoint,
selectedItem,
setSelectedPoint,
selectedActionSphere,
}) => {
const EventProperties: React.FC = () => {
const actionsContainerRef = useRef<HTMLDivElement>(null);
const [activeOption, setActiveOption] = useState("default");
const [dummyactiveOption, setTypeOption] = useState("default");
const [selectedItem, setSelectedItem] = useState<{ item: { uuid: string; name: string } | null; }>({ item: null });
const { selectedEventData } = useSelectedEventData();
const { getEventByModelUuid } = useProductStore();
const { selectedProduct } = useSelectedProduct();
useEffect(() => {
const actions = getActions();
if (actions.length > 0 && !selectedItem.item) {
setSelectedItem({ item: actions[0] });
}
}, [selectedEventData]);
const getCurrentEventData = () => {
if (!selectedEventData?.data || !selectedProduct) return null;
const event = getEventByModelUuid(selectedProduct.productId, selectedEventData.data.modelUuid);
return event || null;
};
const getAssetType = () => {
const event = getCurrentEventData();
if (!event) return null;
switch (event.type) {
case 'transfer': return 'conveyor';
case 'vehicle': return 'vehicle';
case 'roboticArm': return 'roboticArm';
case 'machine': return 'machine';
case 'storageUnit': return 'storageUnit';
default: return null;
}
};
const getAvailableActions = () => {
if (assetType === "conveyor") {
switch (getAssetType()) {
case "conveyor":
return {
defaultOption: "default",
options: ["default", "spawn", "swap", "despawn"],
};
}
if (assetType === "vehicle") {
case "vehicle":
return {
defaultOption: "travel",
options: ["travel"],
};
}
if (assetType === "roboticArm") {
case "roboticArm":
return {
defaultOption: "pickAndPlace",
options: ["pickAndPlace"],
};
}
if (assetType === "machine") {
case "machine":
return {
defaultOption: "process",
options: ["process"],
};
}
if (assetType === "store") {
case "storageUnit":
return {
defaultOption: "store",
options: ["store", "spawn"],
};
} else {
default:
return {
defaultOption: "default",
options: ["default"],
@@ -90,33 +94,96 @@ const EventProperties: React.FC<EventPropertiesProps> = ({
}
};
// Get actions based on asset type
const getActions = () => {
if (!selectedEventData?.data) return [];
const event = selectedEventData.data;
switch (getAssetType()) {
case "conveyor":
return (event as ConveyorEventSchema).points
.find((point) => point.uuid === selectedEventData?.selectedPoint)
?.action?.triggers.map((trigger) => ({
uuid: trigger.triggerUuid,
name: trigger.triggerName,
})) || [];
case "vehicle":
return (event as VehicleEventSchema).point.action.triggers.map(
(trigger) => ({
uuid: trigger.triggerUuid,
name: trigger.triggerName,
})
) || [];
case "roboticArm":
return (event as RoboticArmEventSchema).point.actions.flatMap(
(action) =>
action.triggers.map((trigger) => ({
uuid: trigger.triggerUuid,
name: trigger.triggerName,
}))
) || [];
case "machine":
return (event as MachineEventSchema).point.action.triggers.map(
(trigger) => ({
uuid: trigger.triggerUuid,
name: trigger.triggerName,
})
) || [];
case "storageUnit":
return [
{
uuid: (event as StorageEventSchema).point.action.actionUuid,
name: (event as StorageEventSchema).point.action.actionName,
},
];
default:
return [];
}
};
const handleActionToggle = (actionUuid: string) => {
const actions = getActions();
const selected = actions.find(action => action.uuid === actionUuid);
if (selected) {
setSelectedItem({ item: selected });
}
};
const handleDeleteAction = (actionUuid: string) => {
};
const actions = getActions();
const getSpeed = () => {
if (!selectedEventData) return "0.5";
if ("speed" in selectedEventData.data) return selectedEventData.data.speed.toString();
return "0.5";
};
return (
<>
{getCurrentEventData() &&
<div className="event-proprties-wrapper">
<div className="header">
<div className="header-value">{selectedPoint.name}</div>
<div className="header-value">{selectedEventData?.data.modelName}</div>
</div>
<div className="global-props">
<div className="property-list-container">
{/* <div className="property-item">
<LabledDropdown
defaultOption={assetType}
options={[]}
onSelect={(option) => setTypeOption(option)}
/>
</div> */}
<div className="property-item">
<InputWithDropDown
label="Speed"
value="0.5"
min={0}
step={0.1}
defaultValue="0.5"
defaultValue={getSpeed()}
max={10}
activeOption="s"
onClick={() => {}}
onClick={() => { }}
onChange={(value) => console.log(value)}
/>
</div>
<div className="property-item">
<InputWithDropDown
label="Delay"
@@ -126,17 +193,18 @@ const EventProperties: React.FC<EventPropertiesProps> = ({
defaultValue="0.5"
max={10}
activeOption="s"
onClick={() => {}}
onClick={() => { }}
onChange={(value) => console.log(value)}
/>
</div>
</div>
</div>
{getAssetType() === 'roboticArm' &&
<div className="actions-list-container">
<div className="actions">
<div className="header">
<div className="header-value">Actions</div>
<div className="add-button" onClick={() => {}}>
<div className="add-button" onClick={() => { }}>
<AddIcon /> Add
</div>
</div>
@@ -146,12 +214,10 @@ const EventProperties: React.FC<EventPropertiesProps> = ({
style={{ height: "120px" }}
>
<div className="list-container">
{selectedPoint?.actions.map((action) => (
{actions.map((action) => (
<div
key={action.uuid}
className={`list-item ${
selectedItem.item?.uuid === action.uuid ? "active" : ""
}`}
className={`list-item ${selectedItem.item?.uuid === action.uuid ? "active" : ""}`}
>
<div
className="value"
@@ -159,7 +225,7 @@ const EventProperties: React.FC<EventPropertiesProps> = ({
>
<RenameInput value={action.name} />
</div>
{selectedPoint?.actions.length > 1 && (
{actions.length > 1 && (
<div
className="remove-button"
onClick={() => handleDeleteAction(action.uuid)}
@@ -180,6 +246,7 @@ const EventProperties: React.FC<EventPropertiesProps> = ({
</div>
</div>
</div>
}
<div className="selected-actions-details">
<div className="selected-actions-header">
<RenameInput value="Action Name" />
@@ -190,20 +257,22 @@ const EventProperties: React.FC<EventPropertiesProps> = ({
options={getAvailableActions().options}
onSelect={(option) => setActiveOption(option)}
/>
{activeOption === "default" && <DefaultAction />} {/* done */}
{activeOption === "spawn" && <SpawnAction />} {/* done */}
{activeOption === "swap" && <SwapAction />} {/* done */}
{activeOption === "despawn" && <DespawnAction />} {/* done */}
{activeOption === "travel" && <TravelAction />} {/* done */}
{activeOption === "pickAndPlace" && <PickAndPlaceAction />} {/* done */}
{activeOption === "process" && <ProcessAction />} {/* done */}
{activeOption === "store" && <StorageAction />} {/* done */}
{activeOption === "default" && <DefaultAction />}
{activeOption === "spawn" && <SpawnAction />}
{activeOption === "swap" && <SwapAction />}
{activeOption === "despawn" && <DespawnAction />}
{activeOption === "travel" && <TravelAction />}
{activeOption === "pickAndPlace" && <PickAndPlaceAction />}
{activeOption === "process" && <ProcessAction />}
{activeOption === "store" && <StorageAction />}
</div>
</div>
<div className="tirgger">
<Trigger />
</div>
</div>
}
</>
);
};

View File

@@ -0,0 +1,10 @@
import React from 'react'
function ConveyorMechanics() {
return (
<>
</>
)
}
export default ConveyorMechanics

View File

@@ -0,0 +1,10 @@
import React from 'react'
function MachineMechanics() {
return (
<>
</>
)
}
export default MachineMechanics

View File

@@ -0,0 +1,10 @@
import React from 'react'
function RoboticArmMechanics() {
return (
<>
</>
)
}
export default RoboticArmMechanics

View File

@@ -0,0 +1,10 @@
import React from 'react'
function StorageMechanics() {
return (
<>
</>
)
}
export default StorageMechanics

View File

@@ -0,0 +1,10 @@
import React from 'react'
function VehicleMechanics() {
return (
<>
</>
)
}
export default VehicleMechanics

View File

@@ -7,9 +7,11 @@ import {
} from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput";
import { handleResize } from "../../../../functions/handleResizePannel";
import { useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { useSelectedAsset, useSelectedProduct } from "../../../../store/simulation/useSimulationStore";
import { useProductStore } from "../../../../store/simulation/useProductStore";
import { generateUUID } from "three/src/math/MathUtils";
import RenderOverlay from "../../../templates/Overlay";
import EditWidgetOption from "../../../ui/menu/EditWidgetOption";
interface Event {
pathName: string;
@@ -31,14 +33,9 @@ const List: React.FC<ListProps> = ({ val }) => {
const Simulations: React.FC = () => {
const productsContainerRef = useRef<HTMLDivElement>(null);
const { products, addProduct, removeProduct, renameProduct } = useProductStore();
const { products, addProduct, removeProduct, renameProduct, addEvent, removeEvent } = useProductStore();
const { selectedProduct, setSelectedProduct } = useSelectedProduct();
useEffect(() => {
if (products.length > 0 && selectedProduct.productId === '' && selectedProduct.productName === '') {
setSelectedProduct(products[0].productId, products[0].productName);
}
}, [products, selectedProduct]);
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const handleAddProduct = () => {
addProduct(`Product ${products.length + 1}`, generateUUID());
@@ -75,12 +72,26 @@ const Simulations: React.FC = () => {
}
};
const handleAddEventToProduct = () => {
if (selectedAsset) {
addEvent(selectedProduct.productId, selectedAsset);
clearSelectedAsset();
}
};
const handleRemoveEventFromProduct = () => {
if (selectedAsset) {
removeEvent(selectedProduct.productId, selectedAsset.modelUuid);
clearSelectedAsset();
}
};
const selectedProductData = products.find(
(product) => product.productId === selectedProduct.productId
);
const events: Event[] = selectedProductData?.eventsData.map((event, index) => ({
pathName: `${event.modelName} - ${event.type} #${index + 1}`,
const events: Event[] = selectedProductData?.eventsData.map((event) => ({
pathName: event.modelName,
})) || [];
return (
@@ -165,6 +176,21 @@ const Simulations: React.FC = () => {
</div>
</div>
</div>
{selectedAsset &&
<RenderOverlay>
<EditWidgetOption
options={['Add to Product', 'Remove from Product']}
onClick={(option) => {
if (option === 'Add to Product') {
handleAddEventToProduct();
} else {
handleRemoveEventFromProduct();
}
}}
/>
</RenderOverlay>
}
</div>
);
};

View File

@@ -1,9 +1,9 @@
import { useState, useEffect, useRef } from "react";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import ChartComponent from "../../../sidebarLeft//visualization/widgets/ChartComponent";
import ChartComponent from "../../../sidebarLeft/visualization/widgets/ChartComponent";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import { WalletIcon } from "../../../../icons/3dChartIcons";
import SimpleCard from "../../../../../modules//visualization/widgets/floating/cards/SimpleCard";
import SimpleCard from "../../../../../modules/visualization/widgets/floating/cards/SimpleCard";
interface Widget {
id: string;

View File

@@ -15,7 +15,7 @@ import {
} from "../icons/ExportToolsIcons";
import { ArrowIcon, TickIcon } from "../icons/ExportCommonIcons";
import useModuleStore, { useThreeDStore } from "../../store/useModuleStore";
import { handleSaveTemplate } from "../../modules//visualization/functions/handleSaveTemplate";
import { handleSaveTemplate } from "../../modules/visualization/functions/handleSaveTemplate";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
import useTemplateStore from "../../store/useTemplateStore";
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";

View File

@@ -1,23 +1,20 @@
import React, { useEffect } from "react";
import {
useEditWidgetOptionsStore,
useLeftData,
useRightClickSelected,
useRightSelected,
useTopData,
} from "../../../store/visualization/useZone3DWidgetStore";
interface EditWidgetOptionProps {
options: string[];
onClick: (option: string) => void;
}
const EditWidgetOption: React.FC<EditWidgetOptionProps> = ({
options,
onClick
}) => {
const { top } = useTopData();
const { left } = useLeftData();
const { setRightSelect } = useRightSelected();
const { setEditWidgetOptions } = useEditWidgetOptionsStore();
useEffect(() => {
@@ -38,10 +35,7 @@ const EditWidgetOption: React.FC<EditWidgetOptionProps> = ({
<div
className="option"
key={index}
onClick={(e) => {
setRightSelect(option);
setEditWidgetOptions(false);
}}
onClick={() => onClick(option)}
>
{option}
</div>

View File

@@ -51,7 +51,7 @@ import Ground from "../scene/environment/ground";
// import ZoneGroup from "../groups/zoneGroup1";
import { findEnvironment } from "../../services/factoryBuilder/environment/findEnvironment";
import Layer2DVisibility from "./geomentries/layers/layer2DVisibility";
import DrieHtmlTemp from "..//visualization/mqttTemp/drieHtmlTemp";
import DrieHtmlTemp from "../visualization/mqttTemp/drieHtmlTemp";
import ZoneGroup from "./groups/zoneGroup";
import useModuleStore from "../../store/useModuleStore";
import MeasurementTool from "../scene/tools/measurementTool";

View File

@@ -4,15 +4,32 @@ import { useEventsStore } from '../../../../../store/simulation/useEventsStore';
import useModuleStore from '../../../../../store/useModuleStore';
import { TransformControls } from '@react-three/drei';
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys';
import { useSelectedEventSphere } from '../../../../../store/simulation/useSimulationStore';
import { useSelectedEventSphere, useSelectedEventData } from '../../../../../store/simulation/useSimulationStore';
function PointsCreator() {
const { events, updatePoint, getPointByUuid } = useEventsStore();
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
const { activeModule } = useModuleStore();
const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere();
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
useEffect(() => {
if (selectedEventSphere) {
const eventData = getEventByModelUuid(selectedEventSphere.userData.modelUuid);
if (eventData) {
setSelectedEventData(
eventData,
selectedEventSphere.userData.pointUuid
);
} else {
clearSelectedEventData();
}
} else {
clearSelectedEventData();
}
}, [selectedEventSphere]);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {

View File

@@ -1,13 +1,18 @@
import React, { useEffect } from 'react'
import { useProductStore } from '../../../store/simulation/useProductStore'
import * as THREE from 'three';
import { useSelectedProduct } from '../../../store/simulation/useSimulationStore';
function Products() {
const { products, addProduct } = useProductStore();
const { setSelectedProduct } = useSelectedProduct();
useEffect(() => {
if (products.length === 0) {
addProduct('Product 1', THREE.MathUtils.generateUUID());
const id = THREE.MathUtils.generateUUID();
const name = 'Product 1';
addProduct(name, id);
setSelectedProduct(id, name);
}
}, [products])

View File

@@ -10,20 +10,27 @@ import Machine from './machine/machine';
import StorageUnit from './storageUnit/storageUnit';
import Simulator from './simulator/simulator';
import Products from './products/products';
import Trigger from './triggers/trigger';
import useModuleStore from '../../store/useModuleStore';
function Simulation() {
const { activeModule } = useModuleStore();
const { events } = useEventsStore();
const { products } = useProductStore();
useEffect(() => {
console.log('events: ', events);
// console.log('events: ', events);
}, [events])
useEffect(() => {
// console.log('products: ', products);
console.log('products: ', products);
}, [products])
return (
<>
{activeModule === 'simulation' &&
<>
<Points />
@@ -32,6 +39,8 @@ function Simulation() {
<Materials />
<Trigger />
<Conveyor />
<Vehicles />
@@ -45,6 +54,10 @@ function Simulation() {
<Simulator />
</>
}
</>
)
}

View File

@@ -0,0 +1,126 @@
import { useThree } from '@react-three/fiber'
import React, { useEffect } from 'react'
import { Object3D } from 'three';
import { useSubModuleStore } from '../../../../store/useModuleStore';
import { useLeftData, useTopData } from '../../../../store/visualization/useZone3DWidgetStore';
import { useEventsStore } from '../../../../store/simulation/useEventsStore';
import { useProductStore } from '../../../../store/simulation/useProductStore';
import { useSelectedProduct } from '../../../../store/simulation/useSimulationStore';
import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore';
function TriggerConnector() {
const { gl, raycaster, scene } = useThree();
const { subModule } = useSubModuleStore();
const { setTop } = useTopData();
const { setLeft } = useLeftData();
const { getIsEventInProduct } = useProductStore();
const { getEventByModelUuid } = useEventsStore();
const { selectedProduct } = useSelectedProduct();
const { selectedAsset, setSelectedAsset, clearSelectedAsset } = useSelectedAsset();
useEffect(() => {
const canvasElement = gl.domElement;
let drag = false;
let isRightMouseDown = false;
const onMouseDown = (evt: MouseEvent) => {
if (selectedAsset) {
clearSelectedAsset();
}
if (evt.button === 2) {
isRightMouseDown = true;
drag = false;
}
};
const onMouseUp = (evt: MouseEvent) => {
if (evt.button === 2) {
isRightMouseDown = false;
}
}
const onMouseMove = () => {
if (isRightMouseDown) {
drag = true;
}
};
const handleRightClick = (evt: MouseEvent) => {
if (drag) return;
evt.preventDefault();
const canvasElement = gl.domElement;
if (!canvasElement) return;
let intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
let currentObject = intersects[0].object;
while (currentObject) {
if (currentObject.name === "Scene") {
break;
}
currentObject = currentObject.parent as Object3D;
}
if (currentObject) {
const isInProduct = getIsEventInProduct(selectedProduct.productId, currentObject.uuid);
if (isInProduct) {
const event = getEventByModelUuid(currentObject.uuid);
if (event) {
setSelectedAsset(event)
const canvasRect = canvasElement.getBoundingClientRect();
const relativeX = evt.clientX - canvasRect.left;
const relativeY = evt.clientY - canvasRect.top;
setTop(relativeY);
setLeft(relativeX);
} else {
clearSelectedAsset()
}
} else {
const event = getEventByModelUuid(currentObject.uuid);
if (event) {
setSelectedAsset(event)
const canvasRect = canvasElement.getBoundingClientRect();
const relativeX = evt.clientX - canvasRect.left;
const relativeY = evt.clientY - canvasRect.top;
setTop(relativeY);
setLeft(relativeX);
} else {
clearSelectedAsset()
}
}
}
} else {
clearSelectedAsset()
}
};
if (subModule === 'simulations') {
canvasElement.addEventListener("mousedown", onMouseDown);
canvasElement.addEventListener("mouseup", onMouseUp);
canvasElement.addEventListener("mousemove", onMouseMove);
canvasElement.addEventListener('contextmenu', handleRightClick);
}
return () => {
canvasElement.removeEventListener("mousedown", onMouseDown);
canvasElement.removeEventListener("mouseup", onMouseUp);
canvasElement.removeEventListener("mousemove", onMouseMove);
canvasElement.removeEventListener('contextmenu', handleRightClick);
};
}, [gl, subModule, selectedProduct, selectedAsset]);
return (
<>
</>
)
}
export default TriggerConnector

View File

@@ -0,0 +1,14 @@
import React from 'react'
import TriggerConnector from './connector/triggerConnector'
function Trigger() {
return (
<>
<TriggerConnector />
</>
)
}
export default Trigger

View File

@@ -125,7 +125,7 @@ const RealTimeVisulization: React.FC = () => {
{}
);
setZonesData(formattedData);
} catch (error) {}
} catch (error) { }
}
GetZoneData();
@@ -362,6 +362,10 @@ const RealTimeVisulization: React.FC = () => {
"RotateY",
"Delete",
]}
onClick={(e) => {
setRightSelect(e);
setEditWidgetOptions(false);
}}
/>
)}

View File

@@ -7,7 +7,7 @@ export const getSelect2dZoneData = async (
) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v2/Zone/visualization/${ZoneId}?organization=${organization}`,
`${url_Backend_dwinzo}/api/v2/ZoneVisualization/${ZoneId}?organization=${organization}`,
{
method: "GET",
headers: {

View File

@@ -55,6 +55,11 @@ type ProductsStore = {
// Helper functions
getProductById: (productId: string) => { productName: string; productId: string; eventsData: EventsSchema[] } | undefined;
getEventByModelUuid: (productId: string, modelUuid: string) => EventsSchema | undefined;
getPointByUuid: (productId: string, modelUuid: string, pointUuid: string) => ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | undefined;
getActionByUuid: (productId: string, actionUuid: string) => (ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']) | undefined;
getTriggerByUuid: (productId: string, triggerUuid: string) => TriggerSchema | undefined;
getIsEventInProduct: (productId: string, modelUuid: string) => boolean;
};
export const useProductStore = create<ProductsStore>()(
@@ -417,6 +422,89 @@ export const useProductStore = create<ProductsStore>()(
// Helper functions
getProductById: (productId) => {
return get().products.find(p => p.productId === productId);
},
getEventByModelUuid: (productId, modelUuid) => {
const product = get().getProductById(productId);
if (!product) return undefined;
return product.eventsData.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
},
getPointByUuid: (productId, modelUuid, pointUuid) => {
const event = get().getEventByModelUuid(productId, modelUuid);
if (!event) return undefined;
if ('points' in event) {
return (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
} else if ('point' in event && (event as any).point.uuid === pointUuid) {
return (event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point;
}
return undefined;
},
getActionByUuid: (productId, actionUuid) => {
const product = get().products.find(p => p.productId === productId);
if (!product) return undefined;
for (const event of product.eventsData) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action?.actionUuid === actionUuid) {
return point.action;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action?.actionUuid === actionUuid) {
return point.action;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) return action;
}
}
}
return undefined;
},
getTriggerByUuid: (productId, triggerUuid) => {
const product = get().products.find(p => p.productId === productId);
if (!product) return undefined;
for (const event of product.eventsData) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
for (const trigger of point.action?.triggers || []) {
if (trigger.triggerUuid === triggerUuid) {
return trigger;
}
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point) {
for (const trigger of point.action?.triggers || []) {
if (trigger.triggerUuid === triggerUuid) {
return trigger;
}
}
} else if ('actions' in point) {
for (const action of point.actions) {
for (const trigger of action.triggers || []) {
if (trigger.triggerUuid === triggerUuid) {
return trigger;
}
}
}
}
}
}
return undefined;
},
getIsEventInProduct: (productId, modelUuid) => {
const product = get().getProductById(productId);
if (!product) return false;
return product.eventsData.some(e => 'modelUuid' in e && e.modelUuid === modelUuid);
}
}))
);

View File

@@ -24,6 +24,50 @@ export const useSelectedEventSphere = create<SelectedEventSphereState>()(
}))
);
interface SelectedEventDataState {
selectedEventData: { data: EventsSchema; selectedPoint: string } | undefined;
setSelectedEventData: (data: EventsSchema, selectedPoint: string) => void;
clearSelectedEventData: () => void;
}
export const useSelectedEventData = create<SelectedEventDataState>()(
immer((set) => ({
selectedEventData: undefined,
setSelectedEventData: (data, selectedPoint) => {
set((state) => {
state.selectedEventData = { data, selectedPoint };
});
},
clearSelectedEventData: () => {
set((state) => {
state.selectedEventData = undefined;
});
},
}))
);
interface SelectedAssetState {
selectedAsset: EventsSchema | undefined;
setSelectedAsset: (EventData: EventsSchema) => void;
clearSelectedAsset: () => void;
}
export const useSelectedAsset = create<SelectedAssetState>()(
immer((set) => ({
selectedAsset: undefined,
setSelectedAsset: (EventData) => {
set((state) => {
state.selectedAsset = EventData;
});
},
clearSelectedAsset: () => {
set((state) => {
state.selectedAsset = undefined;
});
},
}))
);
interface SelectedProductState {
selectedProduct: { productId: string; productName: string };
setSelectedProduct: (productId: string, productName: string) => void;

View File

@@ -13,14 +13,17 @@ const useModuleStore = create<ModuleStore>((set) => ({
export default useModuleStore;
// New store for subModule
type SubModule = 'properties' | 'simulations' | 'mechanics' | 'analysis' | 'zoneProperties';
interface SubModuleStore {
subModule: string;
setSubModule: (subModule: string) => void;
subModule: SubModule;
setSubModule: (subModule: SubModule) => void;
}
const useSubModuleStore = create<SubModuleStore>((set) => ({
subModule: "properties", // Initial subModule state
setSubModule: (subModule) => set({ subModule }), // Update subModule state
setSubModule: (value) => set({ subModule: value }), // Update subModule state
}));
export { useSubModuleStore };

View File

@@ -25,7 +25,7 @@ interface ConveyorPointSchema {
action: {
actionUuid: string;
actionName: string;
actionType: "default" | "spawn" | "swap" | "despawn";
actionType: "default" | "spawn" | "swap" | "delay" | "despawn";
material: string;
delay: number | "inherit";
spawnInterval: number | "inherit";
@@ -119,6 +119,8 @@ interface StorageEventSchema extends AssetEventSchema {
point: StoragePointSchema;
}
type PointsScheme = ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema;
type EventsSchema = ConveyorEventSchema | VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema;
type productsSchema = {