diff --git a/app/src/components/layout/sidebarLeft/visualization/Templates.tsx b/app/src/components/layout/sidebarLeft/visualization/Templates.tsx
index b99b297..5eb8d4e 100644
--- a/app/src/components/layout/sidebarLeft/visualization/Templates.tsx
+++ b/app/src/components/layout/sidebarLeft/visualization/Templates.tsx
@@ -3,13 +3,10 @@ import { useDroppedObjectsStore } from "../../../../store/useDroppedObjectsStore
import useTemplateStore from "../../../../store/useTemplateStore";
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
import { getTemplateData } from "../../../../services/realTimeVisulization/zoneData/getTemplate";
-import { deleteTemplateApi } from "../../../../services/realTimeVisulization/zoneData/deleteTemplate";
-import { loadTempleteApi } from "../../../../services/realTimeVisulization/zoneData/loadTemplate";
import { useSocketStore } from "../../../../store/store";
const Templates = () => {
- const { templates, removeTemplate } = useTemplateStore();
- const { setTemplates } = useTemplateStore();
+ const { templates, removeTemplate, setTemplates } = useTemplateStore();
const { setSelectedZone, selectedZone } = useSelectedZoneStore();
const { visualizationSocket } = useSocketStore();
@@ -35,15 +32,11 @@ const Templates = () => {
let deleteTemplate = {
organization: organization,
templateID: id,
- }
+ };
if (visualizationSocket) {
- visualizationSocket.emit("v2:viz-template:deleteTemplate", deleteTemplate)
+ visualizationSocket.emit("v2:viz-template:deleteTemplate", deleteTemplate);
}
removeTemplate(id);
- // let response = await deleteTemplateApi(id, organization);
-
- // if (response.message === "Template deleted successfully") {
- // }
} catch (error) {
console.error("Error deleting template:", error);
}
@@ -60,114 +53,54 @@ const Templates = () => {
organization: organization,
zoneId: selectedZone.zoneId,
templateID: template.id,
- }
- console.log('template: ', template);
- console.log('loadingTemplate: ', loadingTemplate);
+ };
if (visualizationSocket) {
- visualizationSocket.emit("v2:viz-template:addToZone", loadingTemplate)
+ visualizationSocket.emit("v2:viz-template:addToZone", loadingTemplate);
}
- // let response = await loadTempleteApi(template.id, selectedZone.zoneId, organization);
- // if (response.message === "Template placed in Zone") {
- setSelectedZone({
- panelOrder: template.panelOrder,
- activeSides: Array.from(new Set(template.panelOrder)), // No merging with previous `activeSides`
- widgets: template.widgets,
+ setSelectedZone({
+ panelOrder: template.panelOrder,
+ activeSides: Array.from(new Set(template.panelOrder)), // No merging with previous `activeSides`
+ widgets: template.widgets,
+ });
+
+ useDroppedObjectsStore.getState().setZone(selectedZone.zoneName, selectedZone.zoneId);
+
+ if (Array.isArray(template.floatingWidget)) {
+ template.floatingWidget.forEach((val: any) => {
+ useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, val);
});
-
- useDroppedObjectsStore.getState().setZone(selectedZone.zoneName, selectedZone.zoneId);
-
- if (Array.isArray(template.floatingWidget)) {
- template.floatingWidget.forEach((val: any) => {
- useDroppedObjectsStore.getState().addObject(selectedZone.zoneName, val);
- });
- }
- // }
+ }
} catch (error) {
console.error("Error loading template:", error);
}
};
-
return (
-
+
{templates.map((template) => (
-
+
{template?.snapshot && (
-
- {" "}
- {/* 16:9 aspect ratio */}
+

handleLoadTemplate(template)}
/>
)}
-
+
handleLoadTemplate(template)}
- style={{
- cursor: "pointer",
- fontWeight: "500",
- // ':hover': {
- // textDecoration: 'underline'
- // }
- }}
+ className="template-name"
>
{template.name}
))}
{templates.length === 0 && (
-
+
No saved templates yet. Create one in the visualization view!
)}
@@ -192,4 +118,3 @@ const Templates = () => {
};
export default Templates;
-
diff --git a/app/src/components/layout/sidebarLeft/visualization/widgets/WidgetsFloating.tsx b/app/src/components/layout/sidebarLeft/visualization/widgets/WidgetsFloating.tsx
index 8c3df32..09c481a 100644
--- a/app/src/components/layout/sidebarLeft/visualization/widgets/WidgetsFloating.tsx
+++ b/app/src/components/layout/sidebarLeft/visualization/widgets/WidgetsFloating.tsx
@@ -46,7 +46,7 @@ const WidgetsFloating = () => {
))} */}
{/* Floating 1 */}
{
const { activeModule } = useModuleStore();
@@ -42,9 +44,8 @@ const SideBarRight: React.FC = () => {
{/* {activeModule === "builder" && ( */}
setSubModule("properties")}
>
@@ -53,25 +54,22 @@ const SideBarRight: React.FC = () => {
{activeModule === "simulation" && (
<>
setSubModule("mechanics")}
>
setSubModule("simulations")}
>
setSubModule("analysis")}
>
@@ -132,10 +130,28 @@ const SideBarRight: React.FC = () => {
)}
+ {subModule === "mechanics" &&
+ selectedActionSphere &&
+ selectedActionSphere.path.type === "StaticMachine" && (
+
+ )}
+ {subModule === "mechanics" &&
+ selectedActionSphere &&
+ selectedActionSphere.path.type === "ArmBot" && (
+
+ )}
{subModule === "mechanics" && !selectedActionSphere && (
)}
diff --git a/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx
new file mode 100644
index 0000000..744d555
--- /dev/null
+++ b/app/src/components/layout/sidebarRight/mechanics/ArmBotMechanics.tsx
@@ -0,0 +1,90 @@
+import React, { useRef, useMemo } from "react";
+import { InfoIcon } from "../../../icons/ExportCommonIcons";
+import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
+import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
+import * as Types from '../../../../types/world/worldTypes';
+import PositionInput from "../customInput/PositionInputs";
+import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
+
+const ArmBotMechanics: React.FC = () => {
+ const { selectedActionSphere } = useSelectedActionSphere();
+ const { simulationStates, setSimulationStates } = useSimulationStates();
+ const { socket } = useSocketStore();
+
+ const propertiesContainerRef = useRef
(null);
+
+ const { selectedPoint, connectedPointUuids } = useMemo(() => {
+ if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
+
+ const vehiclePaths = simulationStates.filter(
+ (path): path is Types.ArmBotEventsSchema => path.type === "ArmBot"
+ );
+
+ const points = vehiclePaths.find(
+ (path) => path.points.uuid === selectedActionSphere.points.uuid
+ )?.points;
+
+ if (!points) return { selectedPoint: null, connectedPointUuids: [] };
+
+ const connectedUuids: string[] = [];
+ if (points.connections?.targets) {
+ points.connections.targets.forEach(target => {
+ connectedUuids.push(target.pointUUID);
+ });
+ }
+
+ return {
+ selectedPoint: points,
+ connectedPointUuids: connectedUuids
+ };
+ }, [selectedActionSphere, simulationStates]);
+
+ const updateBackend = async (updatedPath: Types.ArmBotEventsSchema | undefined) => {
+ if (!updatedPath) return;
+ const email = localStorage.getItem("email");
+ const organization = email ? email.split("@")[1].split(".")[0] : "";
+
+ // await setEventApi(
+ // organization,
+ // updatedPath.modeluuid,
+ // { type: "ArmBot", points: updatedPath.points }
+ // );
+
+ const data = {
+ organization: organization,
+ modeluuid: updatedPath.modeluuid,
+ eventData: { type: "ArmBot", points: updatedPath.points }
+ }
+
+ socket.emit('v2:model-asset:updateEventData', data);
+
+ }
+
+
+ return (
+
+
+ {selectedActionSphere?.path?.modelName || "ArmBot point not found"}
+
+
+
+
+
ArmBot Properties
+
+ {selectedPoint && (
+ <>
+
+ >
+ )}
+
+
+
+
+ Configure armbot properties.
+
+
+
+ );
+};
+
+export default React.memo(ArmBotMechanics);
\ No newline at end of file
diff --git a/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx
index fd64db9..6c7487e 100644
--- a/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx
+++ b/app/src/components/layout/sidebarRight/mechanics/ConveyorMechanics.tsx
@@ -1,20 +1,20 @@
import React, { useRef, useState, useMemo, useEffect } from "react";
import {
- AddIcon,
- InfoIcon,
- RemoveIcon,
- ResizeHeightIcon,
+ AddIcon,
+ InfoIcon,
+ RemoveIcon,
+ ResizeHeightIcon,
} from "../../../icons/ExportCommonIcons";
import RenameInput from "../../../ui/inputs/RenameInput";
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
import LabledDropdown from "../../../ui/inputs/LabledDropdown";
import { handleResize } from "../../../../functions/handleResizePannel";
import {
- useFloorItems,
- useSelectedActionSphere,
- useSelectedPath,
- useSimulationStates,
- useSocketStore,
+ useFloorItems,
+ useSelectedActionSphere,
+ useSelectedPath,
+ useSimulationStates,
+ useSocketStore,
} from "../../../../store/store";
import * as THREE from "three";
import * as Types from "../../../../types/world/worldTypes";
@@ -23,859 +23,857 @@ import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floo
import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
const ConveyorMechanics: React.FC = () => {
- const { selectedActionSphere } = useSelectedActionSphere();
- const { selectedPath, setSelectedPath } = useSelectedPath();
- const { simulationStates, setSimulationStates } = useSimulationStates();
- const { floorItems, setFloorItems } = useFloorItems();
- const { socket } = useSocketStore();
+ const { selectedActionSphere } = useSelectedActionSphere();
+ const { selectedPath, setSelectedPath } = useSelectedPath();
+ const { simulationStates, setSimulationStates } = useSimulationStates();
+ const { floorItems, setFloorItems } = useFloorItems();
+ const { socket } = useSocketStore();
- const actionsContainerRef = useRef(null);
- const triggersContainerRef = useRef(null);
+ const actionsContainerRef = useRef(null);
+ const triggersContainerRef = useRef(null);
- const selectedPoint = useMemo(() => {
- if (!selectedActionSphere) return null;
- return simulationStates
- .filter(
- (path): path is Types.ConveyorEventsSchema => path.type === "Conveyor"
- )
- .flatMap((path) => path.points)
- .find((point) => point.uuid === selectedActionSphere.points.uuid);
- }, [selectedActionSphere, simulationStates]);
+ const selectedPoint = useMemo(() => {
+ if (!selectedActionSphere) return null;
+ return simulationStates
+ .filter(
+ (path): path is Types.ConveyorEventsSchema => path.type === "Conveyor"
+ )
+ .flatMap((path) => path.points)
+ .find((point) => point.uuid === selectedActionSphere.points.uuid);
+ }, [selectedActionSphere, simulationStates]);
- const updateBackend = async (updatedPath: Types.ConveyorEventsSchema | undefined) => {
- if (!updatedPath) return;
- const email = localStorage.getItem("email");
- const organization = email ? email.split("@")[1].split(".")[0] : "";
+ const updateBackend = async (updatedPath: Types.ConveyorEventsSchema | undefined) => {
+ if (!updatedPath) return;
+ const email = localStorage.getItem("email");
+ const organization = email ? email.split("@")[1].split(".")[0] : "";
- // await setEventApi(
- // organization,
- // updatedPath.modeluuid,
- // { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed }
- // );
+ // await setEventApi(
+ // organization,
+ // updatedPath.modeluuid,
+ // { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed }
+ // );
+
+ const data = {
+ organization: organization,
+ modeluuid: updatedPath.modeluuid,
+ eventData: { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed }
+ }
+
+ socket.emit('v2:model-asset:updateEventData', data);
- const data = {
- organization: organization,
- modeluuid: updatedPath.modeluuid,
- eventData: { type: "Conveyor", points: updatedPath.points, speed: updatedPath.speed }
}
- socket.emit('v2:model-asset:updateEventData', data);
+ const handleAddAction = () => {
+ if (!selectedActionSphere) return;
- }
+ const updatedPaths = simulationStates.map((path) => {
+ if (path.type === "Conveyor") {
+ return {
+ ...path,
+ points: path.points.map((point) => {
+ if (point.uuid === selectedActionSphere.points.uuid) {
+ const actionIndex = point.actions.length;
+ const newAction = {
+ uuid: THREE.MathUtils.generateUUID(),
+ name: `Action ${actionIndex + 1}`,
+ type: "Inherit",
+ material: "Inherit",
+ delay: "Inherit",
+ spawnInterval: "Inherit",
+ isUsed: false,
+ };
- const handleAddAction = () => {
- if (!selectedActionSphere) return;
-
- const updatedPaths = simulationStates.map((path) => {
- if (path.type === "Conveyor") {
- return {
- ...path,
- points: path.points.map((point) => {
- if (point.uuid === selectedActionSphere.points.uuid) {
- const actionIndex = point.actions.length;
- const newAction = {
- uuid: THREE.MathUtils.generateUUID(),
- name: `Action ${actionIndex + 1}`,
- type: "Inherit",
- material: "Inherit",
- delay: "Inherit",
- spawnInterval: "Inherit",
- isUsed: false,
- };
-
- return { ...point, actions: [...point.actions, newAction] };
+ return { ...point, actions: [...point.actions, newAction] };
+ }
+ return point;
+ }),
+ };
}
- return point;
- }),
- };
- }
- return path;
- });
-
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
- };
-
- const handleDeleteAction = (uuid: string) => {
- if (!selectedActionSphere) return;
-
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- actions: point.actions.filter(
- (action) => action.uuid !== uuid
- ),
- }
- : point
- ),
- }
- : path
- );
-
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
- };
-
- const handleActionSelect = (uuid: string, actionType: string) => {
- if (!selectedActionSphere) return;
-
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- actions: point.actions.map((action) =>
- action.uuid === uuid
- ? {
- ...action,
- type: actionType,
- material:
- actionType === "Spawn" || actionType === "Swap"
- ? "Inherit"
- : action.material,
- delay:
- actionType === "Delay" ? "Inherit" : action.delay,
- spawnInterval:
- actionType === "Spawn"
- ? "Inherit"
- : action.spawnInterval,
- }
- : action
- ),
- }
- : point
- ),
- }
- : path
- );
-
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
-
- // Update the selected item to reflect changes
- if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
- const updatedAction = updatedPaths
- .filter(
- (path): path is Types.ConveyorEventsSchema => path.type === "Conveyor"
- )
- .flatMap((path) => path.points)
- .find((p) => p.uuid === selectedActionSphere.points.uuid)
- ?.actions.find((a) => a.uuid === uuid);
-
- if (updatedAction) {
- setSelectedItem({
- type: "action",
- item: updatedAction,
+ return path;
});
- }
- }
- };
- // Modified handleMaterialSelect to ensure it only applies to relevant action types
- const handleMaterialSelect = (uuid: string, material: string) => {
- if (!selectedActionSphere) return;
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- actions: point.actions.map((action) =>
- action.uuid === uuid &&
- (action.type === "Spawn" || action.type === "Swap")
- ? { ...action, material }
- : action
- ),
- }
- : point
- ),
- }
- : path
- );
+ setSimulationStates(updatedPaths);
+ };
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
+ const handleDeleteAction = (uuid: string) => {
+ if (!selectedActionSphere) return;
- setSimulationStates(updatedPaths);
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ actions: point.actions.filter(
+ (action) => action.uuid !== uuid
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
- // Update selected item if it's the current action
- if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
- setSelectedItem({
- ...selectedItem,
- item: {
- ...selectedItem.item,
- material,
- },
- });
- }
- };
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- const handleDelayChange = (uuid: string, delay: number | string) => {
- if (!selectedActionSphere) return;
+ setSimulationStates(updatedPaths);
+ };
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- actions: point.actions.map((action) =>
- action.uuid === uuid ? { ...action, delay } : action
- ),
- }
- : point
- ),
- }
- : path
- );
+ const handleActionSelect = (uuid: string, actionType: string) => {
+ if (!selectedActionSphere) return;
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ actions: point.actions.map((action) =>
+ action.uuid === uuid
+ ? {
+ ...action,
+ type: actionType,
+ material:
+ actionType === "Spawn" || actionType === "Swap"
+ ? "Inherit"
+ : action.material,
+ delay:
+ actionType === "Delay" ? "Inherit" : action.delay,
+ spawnInterval:
+ actionType === "Spawn"
+ ? "Inherit"
+ : action.spawnInterval,
+ }
+ : action
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
- setSimulationStates(updatedPaths);
- };
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- const handleSpawnIntervalChange = (
- uuid: string,
- spawnInterval: number | string
- ) => {
- if (!selectedActionSphere) return;
+ setSimulationStates(updatedPaths);
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- actions: point.actions.map((action) =>
- action.uuid === uuid
- ? { ...action, spawnInterval }
- : action
- ),
- }
- : point
- ),
- }
- : path
- );
+ // Update the selected item to reflect changes
+ if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
+ const updatedAction = updatedPaths
+ .filter(
+ (path): path is Types.ConveyorEventsSchema => path.type === "Conveyor"
+ )
+ .flatMap((path) => path.points)
+ .find((p) => p.uuid === selectedActionSphere.points.uuid)
+ ?.actions.find((a) => a.uuid === uuid);
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
- };
-
- const handleSpeedChange = (speed: number | string) => {
- if (!selectedPath) return;
-
- const updatedPaths = simulationStates.map((path) =>
- path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
- );
-
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
- setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
- };
-
- const handleAddTrigger = () => {
- if (!selectedActionSphere) return;
-
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) => {
- if (point.uuid === selectedActionSphere.points.uuid) {
- const triggerIndex = point.triggers.length;
- const newTrigger = {
- uuid: THREE.MathUtils.generateUUID(),
- name: `Trigger ${triggerIndex + 1}`,
- type: "",
- bufferTime: 0,
- isUsed: false,
- };
-
- return { ...point, triggers: [...point.triggers, newTrigger] };
+ if (updatedAction) {
+ setSelectedItem({
+ type: "action",
+ item: updatedAction,
+ });
}
- return point;
- }),
}
- : path
- );
+ };
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
+ // Modified handleMaterialSelect to ensure it only applies to relevant action types
+ const handleMaterialSelect = (uuid: string, material: string) => {
+ if (!selectedActionSphere) return;
- setSimulationStates(updatedPaths);
- };
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ actions: point.actions.map((action) =>
+ action.uuid === uuid &&
+ (action.type === "Spawn" || action.type === "Swap")
+ ? { ...action, material }
+ : action
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
- const handleDeleteTrigger = (uuid: string) => {
- if (!selectedActionSphere) return;
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- triggers: point.triggers.filter(
- (trigger) => trigger.uuid !== uuid
- ),
- }
- : point
- ),
+ setSimulationStates(updatedPaths);
+
+ // Update selected item if it's the current action
+ if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
+ setSelectedItem({
+ ...selectedItem,
+ item: {
+ ...selectedItem.item,
+ material,
+ },
+ });
}
- : path
- );
+ };
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
+ const handleDelayChange = (uuid: string, delay: number | string) => {
+ if (!selectedActionSphere) return;
- setSimulationStates(updatedPaths);
- };
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ actions: point.actions.map((action) =>
+ action.uuid === uuid ? { ...action, delay } : action
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
- const handleTriggerSelect = (uuid: string, triggerType: string) => {
- if (!selectedActionSphere) return;
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- triggers: point.triggers.map((trigger) =>
- trigger.uuid === uuid
- ? { ...trigger, type: triggerType }
- : trigger
- ),
- }
- : point
- ),
- }
- : path
- );
+ setSimulationStates(updatedPaths);
+ };
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
+ const handleSpawnIntervalChange = (
+ uuid: string,
+ spawnInterval: number | string
+ ) => {
+ if (!selectedActionSphere) return;
- setSimulationStates(updatedPaths);
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ actions: point.actions.map((action) =>
+ action.uuid === uuid
+ ? { ...action, spawnInterval }
+ : action
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
- // Ensure the selectedItem is updated immediately
- const updatedTrigger = updatedPaths
- .flatMap((path) => (path.type === "Conveyor" ? path.points : []))
- .flatMap((point) => point.triggers)
- .find((trigger) => trigger.uuid === uuid);
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- if (updatedTrigger) {
- setSelectedItem({ type: "trigger", item: updatedTrigger });
- }
- };
+ setSimulationStates(updatedPaths);
+ };
- // Update the toggle handlers to immediately update the selected item
- const handleActionToggle = (uuid: string) => {
- if (!selectedActionSphere) return;
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- actions: point.actions.map((action) => ({
- ...action,
- isUsed: action.uuid === uuid ? !action.isUsed : false,
- })),
- }
- : point
- ),
- }
- : path
- );
+ const handleSpeedChange = (speed: number | string) => {
+ if (!selectedPath) return;
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
+ const updatedPaths = simulationStates.map((path) =>
+ path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
+ );
- setSimulationStates(updatedPaths);
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.modeluuid === selectedPath.path.modeluuid
+ );
+ updateBackend(updatedPath);
- // Immediately update the selected item if it's the one being toggled
- if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
- setSelectedItem({
- ...selectedItem,
- item: {
- ...selectedItem.item,
- isUsed: !selectedItem.item.isUsed,
- },
- });
- }
- };
+ setSimulationStates(updatedPaths);
+ setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
+ };
- // Do the same for trigger toggle
- const handleTriggerToggle = (uuid: string) => {
- if (!selectedActionSphere) return;
+ const handleAddTrigger = () => {
+ if (!selectedActionSphere) return;
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- triggers: point.triggers.map((trigger) => ({
- ...trigger,
- isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
- })),
- }
- : point
- ),
- }
- : path
- );
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) => {
+ if (point.uuid === selectedActionSphere.points.uuid) {
+ const triggerIndex = point.triggers.length;
+ const newTrigger = {
+ uuid: THREE.MathUtils.generateUUID(),
+ name: `Trigger ${triggerIndex + 1}`,
+ type: "",
+ bufferTime: 0,
+ isUsed: false,
+ };
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
-
- // Immediately update the selected item if it's the one being toggled
- if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
- setSelectedItem({
- ...selectedItem,
- item: {
- ...selectedItem.item,
- isUsed: !selectedItem.item.isUsed,
- },
- });
- }
- };
-
- const handleTriggerBufferTimeChange = (uuid: string, bufferTime: number) => {
- if (!selectedActionSphere) return;
-
- const updatedPaths = simulationStates.map((path) =>
- path.type === "Conveyor"
- ? {
- ...path,
- points: path.points.map((point) =>
- point.uuid === selectedActionSphere.points.uuid
- ? {
- ...point,
- triggers: point.triggers.map((trigger) =>
- trigger.uuid === uuid
- ? { ...trigger, bufferTime }
- : trigger
- ),
- }
- : point
- ),
- }
- : path
- );
-
- const updatedPath = updatedPaths.find(
- (path): path is Types.ConveyorEventsSchema =>
- path.type === "Conveyor" &&
- path.points.some(
- (point) => point.uuid === selectedActionSphere.points.uuid
- )
- );
- updateBackend(updatedPath);
-
- setSimulationStates(updatedPaths);
-
- // Immediately update selectedItem if it's the currently selected trigger
- if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
- setSelectedItem({
- ...selectedItem,
- item: {
- ...selectedItem.item,
- bufferTime,
- },
- });
- }
- };
-
- const [selectedItem, setSelectedItem] = useState<{
- type: "action" | "trigger";
- item: any;
- } | null>(null);
-
- useEffect(() => {
- setSelectedItem(null);
- }, [selectedActionSphere]);
-
- return (
-
- {!selectedPath && (
-
- {selectedActionSphere?.path?.modelName || "point name not found"}
-
- )}
-
- {selectedPath && (
-
- {selectedPath.path.modelName || "path name not found"}
-
- )}
-
-
- {!selectedPath && (
- <>
-
-
-
-
- {selectedPoint?.actions.map((action) => (
-
-
- setSelectedItem({ type: "action", item: action })
+ return { ...point, triggers: [...point.triggers, newTrigger] };
}
- >
-
-
-
-
handleDeleteAction(action.uuid)}
- >
-
-
-
- ))}
-
-
handleResize(e, actionsContainerRef)}
- >
-
-
-
-
-
-
-
-
- {selectedPoint?.triggers.map((trigger) => (
-
-
- setSelectedItem({ type: "trigger", item: trigger })
- }
- >
-
-
-
-
handleDeleteTrigger(trigger.uuid)}
- >
-
-
-
- ))}
-
-
handleResize(e, triggersContainerRef)}
- >
-
-
-
-
- >
- )}
+ return point;
+ }),
+ }
+ : path
+ );
-
- {selectedItem && (
- <>
-
{selectedItem.item.name}
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
- {selectedItem.type === "action" && (
- <>
-
handleActionToggle(selectedItem.item.uuid)}
- />
-
- handleActionSelect(selectedItem.item.uuid, option)
- }
- />
+ setSimulationStates(updatedPaths);
+ };
- {/* Only show material dropdown for Spawn/Swap actions */}
- {(selectedItem.item.type === "Spawn" ||
- selectedItem.item.type === "Swap") && (
-
- handleMaterialSelect(selectedItem.item.uuid, option)
- }
- />
+ const handleDeleteTrigger = (uuid: string) => {
+ if (!selectedActionSphere) return;
+
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ triggers: point.triggers.filter(
+ (trigger) => trigger.uuid !== uuid
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
+
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
+
+ setSimulationStates(updatedPaths);
+ };
+
+ const handleTriggerSelect = (uuid: string, triggerType: string) => {
+ if (!selectedActionSphere) return;
+
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ triggers: point.triggers.map((trigger) =>
+ trigger.uuid === uuid
+ ? { ...trigger, type: triggerType }
+ : trigger
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
+
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
+
+ setSimulationStates(updatedPaths);
+
+ // Ensure the selectedItem is updated immediately
+ const updatedTrigger = updatedPaths
+ .flatMap((path) => (path.type === "Conveyor" ? path.points : []))
+ .flatMap((point) => point.triggers)
+ .find((trigger) => trigger.uuid === uuid);
+
+ if (updatedTrigger) {
+ setSelectedItem({ type: "trigger", item: updatedTrigger });
+ }
+ };
+
+ // Update the toggle handlers to immediately update the selected item
+ const handleActionToggle = (uuid: string) => {
+ if (!selectedActionSphere) return;
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ actions: point.actions.map((action) => ({
+ ...action,
+ isUsed: action.uuid === uuid ? !action.isUsed : false,
+ })),
+ }
+ : point
+ ),
+ }
+ : path
+ );
+
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
+
+ setSimulationStates(updatedPaths);
+
+ // Immediately update the selected item if it's the one being toggled
+ if (selectedItem?.type === "action" && selectedItem.item.uuid === uuid) {
+ setSelectedItem({
+ ...selectedItem,
+ item: {
+ ...selectedItem.item,
+ isUsed: !selectedItem.item.isUsed,
+ },
+ });
+ }
+ };
+
+ // Do the same for trigger toggle
+ const handleTriggerToggle = (uuid: string) => {
+ if (!selectedActionSphere) return;
+
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ triggers: point.triggers.map((trigger) => ({
+ ...trigger,
+ isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
+ })),
+ }
+ : point
+ ),
+ }
+ : path
+ );
+
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
+
+ setSimulationStates(updatedPaths);
+
+ // Immediately update the selected item if it's the one being toggled
+ if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
+ setSelectedItem({
+ ...selectedItem,
+ item: {
+ ...selectedItem.item,
+ isUsed: !selectedItem.item.isUsed,
+ },
+ });
+ }
+ };
+
+ const handleTriggerBufferTimeChange = (uuid: string, bufferTime: number) => {
+ if (!selectedActionSphere) return;
+
+ const updatedPaths = simulationStates.map((path) =>
+ path.type === "Conveyor"
+ ? {
+ ...path,
+ points: path.points.map((point) =>
+ point.uuid === selectedActionSphere.points.uuid
+ ? {
+ ...point,
+ triggers: point.triggers.map((trigger) =>
+ trigger.uuid === uuid
+ ? { ...trigger, bufferTime }
+ : trigger
+ ),
+ }
+ : point
+ ),
+ }
+ : path
+ );
+
+ const updatedPath = updatedPaths.find(
+ (path): path is Types.ConveyorEventsSchema =>
+ path.type === "Conveyor" &&
+ path.points.some(
+ (point) => point.uuid === selectedActionSphere.points.uuid
+ )
+ );
+ updateBackend(updatedPath);
+
+ setSimulationStates(updatedPaths);
+
+ // Immediately update selectedItem if it's the currently selected trigger
+ if (selectedItem?.type === "trigger" && selectedItem.item.uuid === uuid) {
+ setSelectedItem({
+ ...selectedItem,
+ item: {
+ ...selectedItem.item,
+ bufferTime,
+ },
+ });
+ }
+ };
+
+ const [selectedItem, setSelectedItem] = useState<{
+ type: "action" | "trigger";
+ item: any;
+ } | null>(null);
+
+ useEffect(() => {
+ setSelectedItem(null);
+ }, [selectedActionSphere]);
+
+ return (
+
+ {!selectedPath && (
+
+ {selectedActionSphere?.path?.modelName || "point name not found"}
+
+ )}
+
+ {selectedPath && (
+
+ {selectedPath.path.modelName || "path name not found"}
+
+ )}
+
+
+ {!selectedPath && (
+ <>
+
+
+
+
+ {selectedPoint?.actions.map((action) => (
+
+
+ setSelectedItem({ type: "action", item: action })
+ }
+ >
+
+
+
+
handleDeleteAction(action.uuid)}
+ >
+
+
+
+ ))}
+
+
handleResize(e, actionsContainerRef)}
+ >
+
+
+
+
+
+
+
+
+ {selectedPoint?.triggers.map((trigger) => (
+
+
+ setSelectedItem({ type: "trigger", item: trigger })
+ }
+ >
+
+
+
+
handleDeleteTrigger(trigger.uuid)}
+ >
+
+
+
+ ))}
+
+
handleResize(e, triggersContainerRef)}
+ >
+
+
+
+
+ >
+ )}
+
+
+ {selectedItem && (
+ <>
+
{selectedItem.item.name}
+
+ {selectedItem.type === "action" && (
+ <>
+
handleActionToggle(selectedItem.item.uuid)}
+ />
+
+ handleActionSelect(selectedItem.item.uuid, option)
+ }
+ />
+
+ {/* Only show material dropdown for Spawn/Swap actions */}
+ {(selectedItem.item.type === "Spawn" ||
+ selectedItem.item.type === "Swap") && (
+
+ handleMaterialSelect(selectedItem.item.uuid, option)
+ }
+ />
+ )}
+
+ {/* Only show delay input for Delay actions */}
+ {selectedItem.item.type === "Delay" && (
+ {
+ const numValue = parseInt(value);
+ handleDelayChange(
+ selectedItem.item.uuid,
+ !value ? "Inherit" : numValue
+ );
+ }}
+ />
+ )}
+
+ {/* Only show spawn interval for Spawn actions */}
+ {selectedItem.item.type === "Spawn" && (
+ {
+ handleSpawnIntervalChange(
+ selectedItem.item.uuid,
+ value === "" ? "Inherit" : parseInt(value)
+ );
+ }}
+ />
+ )}
+ >
+ )}
+
+ {selectedItem.type === "trigger" && (
+ <>
+ handleTriggerToggle(selectedItem.item.uuid)}
+ />
+
+
+ handleTriggerSelect(selectedItem.item.uuid, option)
+ }
+ />
+
+ {selectedItem.item.type === "Buffer" && (
+ {
+ handleTriggerBufferTimeChange(
+ selectedItem.item.uuid,
+ parseInt(value)
+ );
+ }}
+ />
+ )}
+ >
+ )}
+ >
)}
- {/* Only show delay input for Delay actions */}
- {selectedItem.item.type === "Delay" && (
- {
- const numValue = parseInt(value);
- handleDelayChange(
- selectedItem.item.uuid,
- !value ? "Inherit" : numValue
- );
- }}
- />
- )}
-
- {/* Only show spawn interval for Spawn actions */}
- {selectedItem.item.type === "Spawn" && (
- {
- handleSpawnIntervalChange(
- selectedItem.item.uuid,
- value === "" ? "Inherit" : parseInt(value)
- );
- }}
- />
- )}
- >
- )}
-
- {selectedItem.type === "trigger" && (
- <>
- handleTriggerToggle(selectedItem.item.uuid)}
- />
-
-
- handleTriggerSelect(selectedItem.item.uuid, option)
- }
- />
-
- {selectedItem.item.type === "Buffer" && (
- {
- handleTriggerBufferTimeChange(
- selectedItem.item.uuid,
- parseInt(value)
- );
- }}
- />
- )}
- >
- )}
- >
- )}
-
- {selectedPath && !selectedItem && (
-
-
- handleSpeedChange(value === "" ? "Inherit" : parseInt(value))
- }
- />
+ {selectedPath && !selectedItem && (
+
+
+ handleSpeedChange(value === "" ? "Inherit" : parseInt(value))
+ }
+ />
+
+ )}
+
+ {!selectedPath && (
+
+
+ Configure the point's action and trigger properties.
+
+ )}
+ {selectedPath && (
+
+
+ Configure the path properties.
+
+ )}
- )}
- {!selectedPath && (
-
-
- Configure the point's action and trigger properties.
-
- )}
- {selectedPath && (
-
-
- Configure the path properties.
-
- )}
-
-
- );
+ );
};
export default ConveyorMechanics;
diff --git a/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx b/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx
new file mode 100644
index 0000000..254753e
--- /dev/null
+++ b/app/src/components/layout/sidebarRight/mechanics/StaticMachineMechanics.tsx
@@ -0,0 +1,90 @@
+import React, { useRef, useMemo } from "react";
+import { InfoIcon } from "../../../icons/ExportCommonIcons";
+import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
+import { useEditingPoint, useEyeDropMode, usePreviewPosition, useSelectedActionSphere, useSimulationStates, useSocketStore } from "../../../../store/store";
+import * as Types from '../../../../types/world/worldTypes';
+import PositionInput from "../customInput/PositionInputs";
+import { setEventApi } from "../../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
+
+const StaticMachineMechanics: React.FC = () => {
+ const { selectedActionSphere } = useSelectedActionSphere();
+ const { simulationStates, setSimulationStates } = useSimulationStates();
+ const { socket } = useSocketStore();
+
+ const propertiesContainerRef = useRef
(null);
+
+ const { selectedPoint, connectedPointUuids } = useMemo(() => {
+ if (!selectedActionSphere?.points?.uuid) return { selectedPoint: null, connectedPointUuids: [] };
+
+ const vehiclePaths = simulationStates.filter(
+ (path): path is Types.StaticMachineEventsSchema => path.type === "StaticMachine"
+ );
+
+ const points = vehiclePaths.find(
+ (path) => path.points.uuid === selectedActionSphere.points.uuid
+ )?.points;
+
+ if (!points) return { selectedPoint: null, connectedPointUuids: [] };
+
+ const connectedUuids: string[] = [];
+ if (points.connections?.targets) {
+ points.connections.targets.forEach(target => {
+ connectedUuids.push(target.pointUUID);
+ });
+ }
+
+ return {
+ selectedPoint: points,
+ connectedPointUuids: connectedUuids
+ };
+ }, [selectedActionSphere, simulationStates]);
+
+ const updateBackend = async (updatedPath: Types.StaticMachineEventsSchema | undefined) => {
+ if (!updatedPath) return;
+ const email = localStorage.getItem("email");
+ const organization = email ? email.split("@")[1].split(".")[0] : "";
+
+ // await setEventApi(
+ // organization,
+ // updatedPath.modeluuid,
+ // { type: "StaticMachine", points: updatedPath.points }
+ // );
+
+ const data = {
+ organization: organization,
+ modeluuid: updatedPath.modeluuid,
+ eventData: { type: "StaticMachine", points: updatedPath.points }
+ }
+
+ socket.emit('v2:model-asset:updateEventData', data);
+
+ }
+
+
+ return (
+
+
+ {selectedActionSphere?.path?.modelName || "Machine point not found"}
+
+
+
+
+
Machine Properties
+
+ {selectedPoint && (
+ <>
+
+ >
+ )}
+
+
+
+
+ Configure machine properties.
+
+
+
+ );
+};
+
+export default React.memo(StaticMachineMechanics);
\ No newline at end of file
diff --git a/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx b/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
index 9e8b37e..ce399b4 100644
--- a/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
@@ -28,9 +28,12 @@ const ZoneProperties: React.FC = () => {
};
let response = await zoneCameraUpdate(zonesdata, organization);
- console.log('response: ', response);
+ if (response.message === "updated successfully") {
+ setEdit(false);
+ } else {
+ console.log("Not updated Camera Position and Target");
+ }
- setEdit(false);
} catch (error) {
console.error("Error in handleSetView:", error);
}
diff --git a/app/src/components/ui/Tools.tsx b/app/src/components/ui/Tools.tsx
index 3de44bf..b704241 100644
--- a/app/src/components/ui/Tools.tsx
+++ b/app/src/components/ui/Tools.tsx
@@ -35,6 +35,7 @@ import {
import useToggleStore from "../../store/useUIToggleStore";
import {
use3DWidget,
+ useDroppedObjectsStore,
useFloatingWidget,
} from "../../store/useDroppedObjectsStore";
@@ -52,8 +53,12 @@ const Tools: React.FC = () => {
const { addTemplate } = useTemplateStore();
const { selectedZone } = useSelectedZoneStore();
const { floatingWidget } = useFloatingWidget();
+
const { widgets3D } = use3DWidget();
+ const zones = useDroppedObjectsStore((state) => state.zones);
+
+
// wall options
const { toggleView, setToggleView } = useToggleView();
const { setDeleteModels } = useDeleteModels();
@@ -409,10 +414,9 @@ const Tools: React.FC = () => {
widgets3D,
selectedZone,
templates,
- visualizationSocket
- })
- }
- }
+ visualizationSocket,
+ });
+ }}
>
diff --git a/app/src/components/ui/componets/AddButtons.tsx b/app/src/components/ui/componets/AddButtons.tsx
index 80a88df..6527414 100644
--- a/app/src/components/ui/componets/AddButtons.tsx
+++ b/app/src/components/ui/componets/AddButtons.tsx
@@ -65,6 +65,8 @@ const AddButtons: React.FC
= ({
// Function to toggle lock/unlock a panel
const toggleLockPanel = (side: Side) => {
+ console.log('side: ', side);
+ //add api
const newLockedPanels = selectedZone.lockedPanels.includes(side)
? selectedZone.lockedPanels.filter((panel) => panel !== side)
: [...selectedZone.lockedPanels, side];
@@ -92,6 +94,8 @@ const AddButtons: React.FC = ({
// Function to clean all widgets from a panel
const cleanPanel = (side: Side) => {
+ //add api
+ console.log('side: ', side);
const cleanedWidgets = selectedZone.widgets.filter(
(widget) => widget.panel !== side
);
@@ -100,7 +104,6 @@ const AddButtons: React.FC = ({
...selectedZone,
widgets: cleanedWidgets,
};
-
// Update the selectedZone state
setSelectedZone(updatedZone);
};
diff --git a/app/src/components/ui/componets/DisplayZone.tsx b/app/src/components/ui/componets/DisplayZone.tsx
index 0890e5c..03fd44f 100644
--- a/app/src/components/ui/componets/DisplayZone.tsx
+++ b/app/src/components/ui/componets/DisplayZone.tsx
@@ -74,6 +74,7 @@ const DisplayZone: React.FC = ({
const [showLeftArrow, setShowLeftArrow] = useState(false);
const [showRightArrow, setShowRightArrow] = useState(false);
const { floatingWidget, setFloatingWidget } = useFloatingWidget()
+
const{setSelectedChartId}=useWidgetStore()
// Function to calculate overflow state
@@ -178,7 +179,7 @@ const DisplayZone: React.FC = ({
zoneViewPortPosition: response.viewPortposition || {},
});
} catch (error) {
- console.error(error);
+
}
}
diff --git a/app/src/components/ui/componets/DraggableWidget.tsx b/app/src/components/ui/componets/DraggableWidget.tsx
index fbb376f..09a54e1 100644
--- a/app/src/components/ui/componets/DraggableWidget.tsx
+++ b/app/src/components/ui/componets/DraggableWidget.tsx
@@ -18,6 +18,7 @@ import { deleteWidgetApi } from "../../../services/realTimeVisulization/zoneData
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
import { useSocketStore } from "../../../store/store";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
+import OuterClick from "../../../utils/outerClick";
type Side = "top" | "bottom" | "left" | "right";
@@ -89,6 +90,11 @@ export const DraggableWidget = ({
const isPanelHidden = hiddenPanels.includes(widget.panel);
+ OuterClick({
+ contextClassName: ["chart-container", "floating", "sidebar-right-wrapper"],
+ setMenuVisible: () => setSelectedChartId(null),
+ });
+
const deleteSelectedChart = async () => {
try {
const email = localStorage.getItem("email") || "";
@@ -251,36 +257,35 @@ export const DraggableWidget = ({
});
// Track canvas dimensions
-
+ // Current: Two identical useEffect hooks for canvas dimensions
+ // Remove the duplicate and keep only one
+ useEffect(() => {
+ const canvas = document.getElementById("real-time-vis-canvas");
+ if (!canvas) return;
-// Current: Two identical useEffect hooks for canvas dimensions
-// Remove the duplicate and keep only one
-useEffect(() => {
- const canvas = document.getElementById("real-time-vis-canvas");
- if (!canvas) return;
+ const updateCanvasDimensions = () => {
+ const rect = canvas.getBoundingClientRect();
+ setCanvasDimensions({
+ width: rect.width,
+ height: rect.height,
+ });
+ };
- const updateCanvasDimensions = () => {
- const rect = canvas.getBoundingClientRect();
- setCanvasDimensions({
- width: rect.width,
- height: rect.height,
- });
- };
+ updateCanvasDimensions();
+ const resizeObserver = new ResizeObserver(updateCanvasDimensions);
+ resizeObserver.observe(canvas);
- updateCanvasDimensions();
- const resizeObserver = new ResizeObserver(updateCanvasDimensions);
- resizeObserver.observe(canvas);
-
- return () => resizeObserver.unobserve(canvas);
-}, []);
+ return () => resizeObserver.unobserve(canvas);
+ }, []);
return (
<>
@@ -296,13 +301,12 @@ useEffect(() => {
onDragOver={handleDragOver}
onDrop={handleDrop}
style={{
- // Apply styles based on panel position
width: ["top", "bottom"].includes(widget.panel)
- ? `calc(${canvasDimensions.width * 0.16}px - 2px)` // For top/bottom panels, set width
- : undefined, // Don't set width if it's left or right
+ ? `calc(${canvasDimensions.width}px / 6)`
+ : undefined,
height: ["left", "right"].includes(widget.panel)
- ? `calc(${canvasDimensions.height * 0.25}px - 2px)` // For left/right panels, set height
- : undefined, // Don't set height if it's top or bottom
+ ? `calc(${canvasDimensions.height - 10}px / 4)`
+ : undefined,
}}
ref={chartWidget}
onClick={() => setSelectedChartId(widget)}
@@ -393,4 +397,4 @@ useEffect(() => {
);
};
-// while resize calculate --realTimeViz-container-height pprperly
\ No newline at end of file
+
diff --git a/app/src/components/ui/componets/Dropped3dWidget.tsx b/app/src/components/ui/componets/Dropped3dWidget.tsx
index d870195..f03dea8 100644
--- a/app/src/components/ui/componets/Dropped3dWidget.tsx
+++ b/app/src/components/ui/componets/Dropped3dWidget.tsx
@@ -44,9 +44,7 @@ export default function Dropped3dWidgets() {
const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // Floor plane for horizontal move
const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0)); // Vertical plane for vertical move
const planeIntersect = useRef(new THREE.Vector3());
- // const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
- // const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
- // const planeIntersect = useRef(new THREE.Vector3());
+
const rotationStartRef = useRef<[number, number, number]>([0, 0, 0]);
const mouseStartRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
@@ -60,7 +58,7 @@ export default function Dropped3dWidgets() {
async function get3dWidgetData() {
const result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
- console.log('result: ', result);
+
setWidgets3D(result);
const formattedWidgets = result.map((widget: WidgetData) => ({
@@ -84,8 +82,31 @@ export default function Dropped3dWidgets() {
const canvasElement = gl.domElement;
+ const handleDragEnter = (event: DragEvent) => {
+ event.preventDefault();
+ event.stopPropagation();
+ console.log("Drag enter");
+
+ };
+
+ const handleDragOver = (event: DragEvent) => {
+ event.preventDefault();
+ event.stopPropagation();
+
+ };
+
+ const handleDragLeave = (event: DragEvent) => {
+ event.preventDefault();
+ event.stopPropagation();
+ console.log("Drag leave");
+ // Remove visual feedback
+ canvasElement.style.cursor = "";
+ };
+
const onDrop = async (event: DragEvent) => {
event.preventDefault();
+ event.stopPropagation();
+ canvasElement.style.cursor = ""; // Reset cursor
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
@@ -93,6 +114,12 @@ export default function Dropped3dWidgets() {
const group1 = scene.getObjectByName("itemsGroup");
if (!group1) return;
+ // Update raycaster with current mouse position
+ const rect = canvasElement.getBoundingClientRect();
+ mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
+ mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
+ raycaster.setFromCamera(mouse, camera);
+
const intersects = raycaster.intersectObjects(scene.children, true).filter(
(intersect) =>
!intersect.object.name.includes("Roof") &&
@@ -125,12 +152,21 @@ export default function Dropped3dWidgets() {
}
};
+ // Add all event listeners
+ // canvasElement.addEventListener("dragenter", handleDragEnter);
+ // canvasElement.addEventListener("dragover", handleDragOver);
+ // canvasElement.addEventListener("dragleave", handleDragLeave);
canvasElement.addEventListener("drop", onDrop);
- return () => {
- canvasElement.removeEventListener("drop", onDrop);
- };
- }, [widgetSelect, activeModule, selectedZone.zoneId, widgetSubOption]);
+ return () => {
+ // // Clean up all event listeners
+ // canvasElement.removeEventListener("dragenter", handleDragEnter);
+ // canvasElement.removeEventListener("dragover", handleDragOver);
+ // canvasElement.removeEventListener("dragleave", handleDragLeave);
+ canvasElement.removeEventListener("drop", onDrop);
+ canvasElement.style.cursor = ""; // Ensure cursor is reset
+ };
+ }, [widgetSelect, activeModule, selectedZone.zoneId, widgetSubOption, gl.domElement, scene, raycaster, camera]);
const activeZoneWidgets = zoneWidgetData[selectedZone.zoneId] || [];
useEffect(() => {
@@ -161,7 +197,7 @@ export default function Dropped3dWidgets() {
visualizationSocket.emit("v2:viz-3D-widget:add", adding3dWidget);
}
// let response = await adding3dWidgets(selectedZone.zoneId, organization, newWidget)
- // console.log('response: ', response);
+ //
addWidget(selectedZone.zoneId, newWidget);
setRightSelect(null);
@@ -179,7 +215,7 @@ export default function Dropped3dWidgets() {
zoneId: selectedZone.zoneId,
};
- console.log('deleteWidget: ', deleteWidget);
+
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-3D-widget:delete", deleteWidget);
}
@@ -190,7 +226,7 @@ export default function Dropped3dWidgets() {
activeZoneWidgets.filter((w: WidgetData) => w.id !== rightClickSelected)
);
} catch (error) {
- console.error("Error deleting widget:", error);
+
} finally {
setRightClickSelected(null);
setRightSelect(null);
@@ -304,20 +340,15 @@ export default function Dropped3dWidgets() {
const selectedWidget = zoneWidgetData[selectedZone].find(widget => widget.id === rightClickSelected);
if (!selectedWidget) return;
-
-
-
// Format values to 2 decimal places
const formatValues = (vals: number[]) => vals.map(val => parseFloat(val.toFixed(2)));
-
if (rightSelect === "Horizontal Move" || rightSelect === "Vertical Move") {
- console.log(`${rightSelect} Completed - Full Position:`, formatValues(selectedWidget.position));
let lastPosition = formatValues(selectedWidget.position) as [number, number, number];
// (async () => {
// let response = await update3dWidget(selectedZone, organization, rightClickSelected, lastPosition);
- // console.log('response: ', response);
+ //
// if (response) {
- // console.log("Widget position updated in API:", response);
+ //
// }
// })();
let updatingPosition = {
@@ -333,13 +364,13 @@ export default function Dropped3dWidgets() {
}
else if (rightSelect.includes("Rotate")) {
const rotation = selectedWidget.rotation || [0, 0, 0];
- console.log(`${rightSelect} Completed - Full Rotation:`, formatValues(rotation));
+
let lastRotation = formatValues(rotation) as [number, number, number];
// (async () => {
// let response = await update3dWidgetRotation(selectedZone, organization, rightClickSelected, lastRotation);
- // console.log('response: ', response);
+ //
// if (response) {
- // console.log("Widget position updated in API:", response);
+ //
// }
// })();
let updatingRotation = {
@@ -388,49 +419,13 @@ export default function Dropped3dWidgets() {
switch (type) {
case "ui-Widget 1":
- return (
- handleRightClick(e, id)}
- />
- );
+ return ( handleRightClick(e, id)} />);
case "ui-Widget 2":
- return (
- handleRightClick(e, id)}
- />
- );
+ return ( handleRightClick(e, id)} />);
case "ui-Widget 3":
- return (
- handleRightClick(e, id)}
- />
- );
+ return ( handleRightClick(e, id)} />);
case "ui-Widget 4":
- return (
- handleRightClick(e, id)}
- />
- );
+ return ( handleRightClick(e, id)} />);
default:
return null;
}
diff --git a/app/src/components/ui/componets/DroppedFloatingWidgets.tsx b/app/src/components/ui/componets/DroppedFloatingWidgets.tsx
index 4652ec1..bd707f4 100644
--- a/app/src/components/ui/componets/DroppedFloatingWidgets.tsx
+++ b/app/src/components/ui/componets/DroppedFloatingWidgets.tsx
@@ -126,12 +126,11 @@ const DroppedObjects: React.FC = () => {
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
-
let deleteFloatingWidget = {
floatWidgetID: id,
organization: organization,
- zoneId: zone.zoneId
- }
+ zoneId: zone.zoneId,
+ };
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-float:delete", deleteFloatingWidget);
@@ -144,9 +143,7 @@ const DroppedObjects: React.FC = () => {
// if (res.message === "FloatingWidget deleted successfully") {
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
// }
- } catch (error) {
-
- }
+ } catch (error) {}
}
const handlePointerDown = (event: React.PointerEvent, index: number) => {
@@ -461,15 +458,14 @@ const DroppedObjects: React.FC = () => {
position: boundedPosition,
},
index: draggingIndex.index,
- zoneId: zone.zoneId
- }
+ zoneId: zone.zoneId,
+ };
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-float:add", updateFloatingWidget);
}
// if (response.message === "Widget updated successfully") {
- console.log('boundedPosition: ', boundedPosition);
updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
// }
@@ -503,106 +499,130 @@ const DroppedObjects: React.FC = () => {
setOpenKebabId((prevId) => (prevId === id ? null : id));
};
+ const containerHeight = getComputedStyle(
+ document.documentElement
+ ).getPropertyValue("--realTimeViz-container-height");
+ const containerWidth = getComputedStyle(
+ document.documentElement
+ ).getPropertyValue("--realTimeViz-container-width");
+
+ const heightMultiplier = parseFloat(containerHeight) * 0.14;
+
+ const widthMultiplier = parseFloat(containerWidth) * 0.13;
+
+ console.log("zone.objects: ", zone.objects);
return (
- {zone.objects.map((obj, index) => (
-
{
- setSelectedChartId(obj);
- handlePointerDown(event, index);
- }}
- >
- {obj.className === "floating total-card" ? (
- <>
-
- >
- ) : obj.className === "warehouseThroughput floating" ? (
- <>
-
- >
- ) : obj.className === "fleetEfficiency floating" ? (
- <>
-
- >
- ) : null}
+ {zone.objects.map((obj, index) => {
+ const topPosition =
+ typeof obj.position.top === "number"
+ ? `calc(${obj.position.top}px + ${
+ isPlaying && selectedZone.activeSides.includes("top")
+ ? `${heightMultiplier - 55}px`
+ : "0px"
+ })`
+ : "auto";
+
+ const leftPosition =
+ typeof obj.position.left === "number"
+ ? `calc(${obj.position.left}px + ${
+ isPlaying && selectedZone.activeSides.includes("left")
+ ? `${widthMultiplier - 100}px`
+ : "0px"
+ })`
+ : "auto";
+
+ const rightPosition =
+ typeof obj.position.right === "number"
+ ? `calc(${obj.position.right}px + ${
+ isPlaying && selectedZone.activeSides.includes("right")
+ ? `${widthMultiplier - 100}px`
+ : "0px"
+ })`
+ : "auto";
+
+ const bottomPosition =
+ typeof obj.position.bottom === "number"
+ ? `calc(${obj.position.bottom}px + ${
+ isPlaying && selectedZone.activeSides.includes("bottom")
+ ? `${heightMultiplier - 55}px`
+ : "0px"
+ })`
+ : "auto";
+
+ return (
{
- event.stopPropagation();
- handleKebabClick(obj.id, event);
+ key={`${zoneName}-${index}`}
+ className={`${obj.className} ${
+ selectedChartId?.id === obj.id && "activeChart"
+ }`}
+ ref={chartWidget}
+ style={{
+ position: "absolute",
+ top: topPosition,
+ left: leftPosition,
+ right: rightPosition,
+ bottom: bottomPosition,
+ }}
+ onPointerDown={(event) => {
+ setSelectedChartId(obj);
+ handlePointerDown(event, index);
}}
>
-
-
- {openKebabId === obj.id && (
-
-
{
- event.stopPropagation();
- handleDuplicate(zoneName, index); // Call the duplicate handler
- }}
- >
-
-
-
-
Duplicate
-
-
{
- event.stopPropagation();
- handleDelete(zoneName, obj.id); // Call the delete handler
- }}
- >
-
-
-
-
Delete
-
+ {obj.className === "floating total-card" ? (
+
+ ) : obj.className === "warehouseThroughput floating" ? (
+
+ ) : obj.className === "fleetEfficiency floating" ? (
+
+ ) : null}
+
+
{
+ event.stopPropagation();
+ handleKebabClick(obj.id, event);
+ }}
+ >
+
- )}
-
- ))}
+
+ {openKebabId === obj.id && (
+
+
{
+ event.stopPropagation();
+ handleDuplicate(zoneName, index); // Call the duplicate handler
+ }}
+ >
+
+
+
+
Duplicate
+
+
{
+ event.stopPropagation();
+ handleDelete(zoneName, obj.id); // Call the delete handler
+ }}
+ >
+
+
+
+
Delete
+
+
+ )}
+
+ );
+ })}
{/* Render DistanceLines component during drag */}
{isPlaying === false &&
diff --git a/app/src/components/ui/componets/Panel.tsx b/app/src/components/ui/componets/Panel.tsx
index 2e168b4..fe9836d 100644
--- a/app/src/components/ui/componets/Panel.tsx
+++ b/app/src/components/ui/componets/Panel.tsx
@@ -21,7 +21,6 @@ interface PanelProps {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
-
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
@@ -33,7 +32,6 @@ interface PanelProps {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
-
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
@@ -42,7 +40,7 @@ interface PanelProps {
}>
>;
hiddenPanels: string[];
- setZonesData: React.Dispatch
>; // Add this line
+ setZonesData: React.Dispatch>;
}
const generateUniqueId = () =>
@@ -60,14 +58,13 @@ const Panel: React.FC = ({
[side in Side]?: { width: number; height: number };
}>({});
const [openKebabId, setOpenKebabId] = useState(null);
-
const { isPlaying } = usePlayButtonStore();
const { visualizationSocket } = useSocketStore();
-
const [canvasDimensions, setCanvasDimensions] = useState({
width: 0,
height: 0,
});
+
// Track canvas dimensions
useEffect(() => {
const canvas = document.getElementById("real-time-vis-canvas");
@@ -81,42 +78,20 @@ const Panel: React.FC = ({
});
};
- // Initial measurement
updateCanvasDimensions();
-
- // Set up ResizeObserver to track changes
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
resizeObserver.observe(canvas);
- return () => {
- resizeObserver.unobserve(canvas);
- };
+ return () => resizeObserver.unobserve(canvas);
}, []);
- useEffect(() => {
- const canvas = document.getElementById("real-time-vis-canvas");
- if (!canvas) return;
-
- const updateCanvasDimensions = () => {
- const rect = canvas.getBoundingClientRect();
- setCanvasDimensions({
- width: rect.width,
- height: rect.height,
- });
- };
-
- // Initial measurement
- updateCanvasDimensions();
-
- // Set up ResizeObserver to track changes
- const resizeObserver = new ResizeObserver(updateCanvasDimensions);
- resizeObserver.observe(canvas);
-
- return () => {
- resizeObserver.unobserve(canvas);
- };
- }, []);
+ // Calculate panel size
+ const panelSize = Math.max(
+ Math.min(canvasDimensions.width * 0.25, canvasDimensions.height * 0.25),
+ 170 // Min 170px
+ );
+ // Define getPanelStyle
const getPanelStyle = useMemo(
() => (side: Side) => {
const currentIndex = selectedZone.panelOrder.indexOf(side);
@@ -126,125 +101,105 @@ const Panel: React.FC = ({
const topActive = previousPanels.includes("top");
const bottomActive = previousPanels.includes("bottom");
- // Dynamic panel sizes based on canvas width
- const panelSizeWidth = Math.max(canvasDimensions.width * 0.165, 200); // Ensure minimum width of 200px
- const panelSizeHeight = Math.max(canvasDimensions.width * 0.13, 200); // Ensure minimum height of 200px
-
switch (side) {
case "top":
case "bottom":
return {
- // minWidth: "200px", // Minimum width constraint
+ minWidth: "170px",
width: `calc(100% - ${
- (leftActive ? panelSizeWidth : 0) +
- (rightActive ? panelSizeWidth : 0)
+ (leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
}px)`,
- minHeight: "150px", // Minimum height constraint
- height: `${panelSizeHeight - 2}px`, // Subtracting for border or margin
- left: leftActive ? `${panelSizeWidth}px` : "0",
- right: rightActive ? `${panelSizeWidth}px` : "0",
+ minHeight: "170px",
+ height: `${panelSize}px`,
+ left: leftActive ? `${panelSize}px` : "0",
+ right: rightActive ? `${panelSize}px` : "0",
[side]: "0",
};
-
case "left":
case "right":
return {
- minWidth: "150px", // Minimum width constraint
- width: `${panelSizeWidth - 2}px`, // Subtracting for border or margin
- // minHeight: "200px", // Minimum height constraint
+ minWidth: "170px",
+ width: `${panelSize}px`,
+ minHeight: "170px",
height: `calc(100% - ${
- (topActive ? panelSizeHeight : 0) +
- (bottomActive ? panelSizeHeight : 0)
+ (topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
}px)`,
- top: topActive ? `${panelSizeHeight}px` : "0",
- bottom: bottomActive ? `${panelSizeHeight}px` : "0",
+ top: topActive ? `${panelSize}px` : "0",
+ bottom: bottomActive ? `${panelSize}px` : "0",
[side]: "0",
};
-
default:
return {};
}
},
- [
- selectedZone.panelOrder,
- isPlaying,
- canvasDimensions.width,
- canvasDimensions.height,
- ]
+ [selectedZone.panelOrder, panelSize]
);
+ // Handle drop event
const handleDrop = (e: React.DragEvent, panel: Side) => {
e.preventDefault();
const { draggedAsset } = useWidgetStore.getState();
- if (!draggedAsset) return;
- if (isPanelLocked(panel)) return;
+ if (!draggedAsset || isPanelLocked(panel)) return;
const currentWidgetsCount = getCurrentWidgetCount(panel);
const maxCapacity = calculatePanelCapacity(panel);
- if (currentWidgetsCount >= maxCapacity) return;
- addWidgetToPanel(draggedAsset, panel);
+ if (currentWidgetsCount < maxCapacity) {
+ addWidgetToPanel(draggedAsset, panel);
+ }
};
+ // Check if panel is locked
const isPanelLocked = (panel: Side) =>
selectedZone.lockedPanels.includes(panel);
+ // Get current widget count in a panel
const getCurrentWidgetCount = (panel: Side) =>
selectedZone.widgets.filter((w) => w.panel === panel).length;
+ // Calculate panel capacity
const calculatePanelCapacity = (panel: Side) => {
- const CHART_WIDTH = 170;
- const CHART_HEIGHT = 170;
- const FALLBACK_HORIZONTAL_CAPACITY = 5;
- const FALLBACK_VERTICAL_CAPACITY = 3;
+ const CHART_WIDTH = panelSize;
+ const CHART_HEIGHT = panelSize;
const dimensions = panelDimensions[panel];
if (!dimensions) {
- return panel === "top" || panel === "bottom"
- ? FALLBACK_HORIZONTAL_CAPACITY
- : FALLBACK_VERTICAL_CAPACITY;
+ return panel === "top" || panel === "bottom" ? 5 : 3; // Fallback capacities
}
return panel === "top" || panel === "bottom"
- ? Math.floor(dimensions.width / CHART_WIDTH)
- : Math.floor(dimensions.height / CHART_HEIGHT);
+ ? Math.max(1, Math.floor(dimensions.width / CHART_WIDTH))
+ : Math.max(1, Math.floor(dimensions.height / CHART_HEIGHT));
};
- // while dublicate check this and add
+ // Add widget to panel
const addWidgetToPanel = async (asset: any, panel: Side) => {
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
+
const newWidget = {
...asset,
id: generateUniqueId(),
panel,
};
+
let addWidget = {
organization: organization,
zoneId: selectedZone.zoneId,
widget: newWidget,
};
+
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-widget:add", addWidget);
}
+
setSelectedZone((prev) => ({
...prev,
widgets: [...prev.widgets, newWidget],
}));
-
- try {
- // let response = await addingWidgets(selectedZone.zoneId, organization, newWidget);
- // if (response.message === "Widget created successfully") {
- // setSelectedZone((prev) => ({
- // ...prev,
- // widgets: [...prev.widgets, newWidget],
- // }));
- // }
- } catch (error) {
- console.error("Error adding widget:", error);
- }
};
+ // Observe panel dimensions
useEffect(() => {
const observers: ResizeObserver[] = [];
const currentPanelRefs = panelRefs.current;
@@ -261,6 +216,7 @@ const Panel: React.FC = ({
}));
}
});
+
observer.observe(element);
observers.push(observer);
}
@@ -271,22 +227,15 @@ const Panel: React.FC = ({
};
}, [selectedZone.activeSides]);
+ // Handle widget reordering
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
- if (!selectedZone) return; // Ensure selectedZone is not null
-
setSelectedZone((prev) => {
- if (!prev) return prev; // Ensure prev is not null
-
- // Filter widgets for the specified panel
const widgetsInPanel = prev.widgets.filter((w) => w.panel === panel);
-
- // Reorder widgets within the same panel
const reorderedWidgets = arrayMove(widgetsInPanel, fromIndex, toIndex);
- // Merge the reordered widgets back into the full list while preserving the order
const updatedWidgets = prev.widgets
- .filter((widget) => widget.panel !== panel) // Keep widgets from other panels
- .concat(reorderedWidgets); // Add the reordered widgets for the specified panel
+ .filter((widget) => widget.panel !== panel)
+ .concat(reorderedWidgets);
return {
...prev,
@@ -295,12 +244,40 @@ const Panel: React.FC = ({
});
};
+ // Calculate capacities and dimensions
+ const topWidth = getPanelStyle("top").width;
+ const bottomWidth = getPanelStyle("bottom").width;
+ const leftHeight = getPanelStyle("left").height;
+ const rightHeight = getPanelStyle("right").height;
+
+ const topCapacity = calculatePanelCapacity("top");
+ const bottomCapacity = calculatePanelCapacity("bottom");
+ const leftCapacity = calculatePanelCapacity("left");
+ const rightCapacity = calculatePanelCapacity("right");
+
return (
<>
+
+
{selectedZone.activeSides.map((side) => (
= ({
};
export default Panel;
-
-// canvasDimensions.width as percent
diff --git a/app/src/components/ui/componets/RealTimeVisulization.tsx b/app/src/components/ui/componets/RealTimeVisulization.tsx
index a9ee657..8044ed2 100644
--- a/app/src/components/ui/componets/RealTimeVisulization.tsx
+++ b/app/src/components/ui/componets/RealTimeVisulization.tsx
@@ -67,9 +67,7 @@ const RealTimeVisulization: React.FC = () => {
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
- const [floatingWidgets, setFloatingWidgets] = useState<
- Record
- >({});
+ const [floatingWidgets, setFloatingWidgets] = useState>({});
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
const { visualizationSocket } = useSocketStore();
@@ -81,7 +79,6 @@ const RealTimeVisulization: React.FC = () => {
const organization = email?.split("@")[1]?.split(".")[0];
try {
const response = await getZone2dData(organization);
- // console.log('response: ', response);
if (!Array.isArray(response)) {
return;
@@ -102,7 +99,7 @@ const RealTimeVisulization: React.FC = () => {
{}
);
setZonesData(formattedData);
- } catch (error) {}
+ } catch (error) { }
}
GetZoneData();
@@ -200,7 +197,7 @@ const RealTimeVisulization: React.FC = () => {
],
},
}));
- } catch (error) {}
+ } catch (error) { }
};
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
@@ -267,19 +264,19 @@ const RealTimeVisulization: React.FC = () => {
/>
)}
- {/* handleDrop(event)}
- onDragOver={(event) => event.preventDefault()}
+
handleDrop(event)}
+ onDragOver={(event) => event.preventDefault()}
>
-
-
*/}
+
+
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
)}
diff --git a/app/src/components/ui/list/DropDownList.tsx b/app/src/components/ui/list/DropDownList.tsx
index 3d2a828..3260eb6 100644
--- a/app/src/components/ui/list/DropDownList.tsx
+++ b/app/src/components/ui/list/DropDownList.tsx
@@ -47,80 +47,83 @@ const DropDownList: React.FC = ({
const [zoneDataList, setZoneDataList] = useState<
{ id: string; name: string; assets: Asset[] }[]
>([]);
+ const [zonePoints3D, setZonePoints3D] = useState<[]>([]);
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
useEffect(() => {
- // console.log(zones);
- // setZoneDataList([
- // { id: "2e996073-546c-470c-8323-55bd3700c6aa", name: "zone1" },
- // { id: "3f473bf0-197c-471c-a71f-943fc9ca2b47", name: "zone2" },
- // { id: "905e8fb6-9e18-469b-9474-e0478fb9601b", name: "zone3" },
- // { id: "9d9efcbe-8e96-47eb-bfad-128a9e4c532e", name: "zone4" },
- // { id: "884f3d29-eb5a-49a5-abe9-d11971c08e85", name: "zone5" },
- // { id: "70fa55cd-b5c9-4f80-a8c4-6319af3bfb4e", name: "zone6" },
- // ])
+ // const value = (zones || []).map(
+ // (val: { zoneId: string; zoneName: string }) => ({
+ // id: val.zoneId,
+ // name: val.zoneName,
+ // })
+ // );
+ // console.log('zones: ', zones);
+ const value = (zones || []).map((val: { zoneId: string; zoneName: string }) => ({
+ id: val.zoneId,
+ name: val.zoneName
+ }));
+ setZoneDataList(prev => (JSON.stringify(prev) !== JSON.stringify(value) ? value : prev));
+ const allPoints = zones.flatMap((zone: any) => zone.points);
+ setZonePoints3D(allPoints);
+ // setZoneDataList([
+ // {
+ // id: "zone1",
+ // name: "Zone 1",
+ // assets: [
+ // {
+ // id: "asset1",
+ // name: "Asset 1",
+ // },
+ // {
+ // id: "asset2",
+ // name: "Asset 2",
+ // },
+ // {
+ // id: "asset3",
+ // name: "Asset 3",
+ // },
+ // ],
+ // },
+ // {
+ // id: "zone2",
+ // name: "Zone 2",
+ // assets: [
+ // {
+ // id: "asset4",
+ // name: "Asset 4",
+ // },
+ // {
+ // id: "asset5",
+ // name: "Asset 5",
+ // },
+ // {
+ // id: "asset6",
+ // name: "Asset 6",
+ // },
+ // ],
+ // },
+ // {
+ // id: "zone3",
+ // name: "Zone 3",
+ // assets: [
+ // {
+ // id: "asset7",
+ // name: "Asset 7",
+ // },
+ // {
+ // id: "asset8",
+ // name: "Asset 8",
+ // },
+ // ],
+ // },
+ // ]);
- const value = (zones || []).map(
- (val: { zoneId: string; zoneName: string }) => ({
- id: val.zoneId,
- name: val.zoneName,
- })
- );
- setZoneDataList([
- {
- id: "zone1",
- name: "Zone 1",
- assets: [
- {
- id: "asset1",
- name: "Asset 1",
- },
- {
- id: "asset2",
- name: "Asset 2",
- },
- {
- id: "asset3",
- name: "Asset 3",
- },
- ],
- },
- {
- id: "zone2",
- name: "Zone 2",
- assets: [
- {
- id: "asset4",
- name: "Asset 4",
- },
- {
- id: "asset5",
- name: "Asset 5",
- },
- {
- id: "asset6",
- name: "Asset 6",
- },
- ],
- },
- {
- id: "zone3",
- name: "Zone 3",
- assets: [
- {
- id: "asset7",
- name: "Asset 7",
- },
- {
- id: "asset8",
- name: "Asset 8",
- },
- ],
- },
- ]);
-
}, [zones]);
+ useEffect(() => {
+
+ // console.log('zonePoints3D: ', zonePoints3D);
+ }, [zonePoints3D])
return (
diff --git a/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx b/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx
index 0c36977..7fafb79 100644
--- a/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx
+++ b/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx
@@ -5,7 +5,7 @@ interface SimpleCardProps {
icon: React.ComponentType
>; // React component for SVG icon
value: string;
per: string; // Percentage change
- position?: [number, number]
+ position?: [number, number];
}
const SimpleCard: React.FC = ({
@@ -15,7 +15,6 @@ const SimpleCard: React.FC = ({
per,
position = [0, 0],
}) => {
-
const handleDragStart = (event: React.DragEvent) => {
const rect = event.currentTarget.getBoundingClientRect(); // Get position
const cardData = JSON.stringify({
@@ -23,7 +22,7 @@ const SimpleCard: React.FC = ({
value,
per,
icon: Icon,
-
+
className: event.currentTarget.className,
position: [rect.top, rect.left], // ✅ Store position
});
diff --git a/app/src/modules/builder/agv/pathNavigator.tsx b/app/src/modules/builder/agv/pathNavigator.tsx
index 7d7984c..6369a87 100644
--- a/app/src/modules/builder/agv/pathNavigator.tsx
+++ b/app/src/modules/builder/agv/pathNavigator.tsx
@@ -29,12 +29,15 @@ export default function PathNavigator({
const [dropPickupPath, setDropPickupPath] = useState<[number, number, number][]>([]);
const [initialPosition, setInitialPosition] = useState(null);
const [initialRotation, setInitialRotation] = useState(null);
-
+ const [targetPosition] = useState(new THREE.Vector3());
+ const [smoothPosition] = useState(new THREE.Vector3());
+ const [targetQuaternion] = useState(new THREE.Quaternion());
const distancesRef = useRef([]);
const totalDistanceRef = useRef(0);
const progressRef = useRef(0);
const isWaiting = useRef(false);
const timeoutRef = useRef(null);
+ const pathTransitionProgress = useRef(0);
const { scene } = useThree();
const { isPlaying } = usePlayButtonStore();
@@ -44,6 +47,9 @@ export default function PathNavigator({
if (object) {
setInitialPosition(object.position.clone());
setInitialRotation(object.rotation.clone());
+ smoothPosition.copy(object.position.clone());
+ targetPosition.copy(object.position.clone());
+ targetQuaternion.setFromEuler(object.rotation.clone());
}
}, [scene, id]);
@@ -65,22 +71,23 @@ export default function PathNavigator({
setPath([]);
setCurrentPhase('initial');
- setPickupDropPath([]);
- setDropPickupPath([]);
distancesRef.current = [];
totalDistanceRef.current = 0;
progressRef.current = 0;
isWaiting.current = false;
+ pathTransitionProgress.current = 0;
- if (initialPosition && initialRotation) {
- const object = scene.getObjectByProperty("uuid", id);
- if (object) {
- object.position.copy(initialPosition);
- object.rotation.copy(initialRotation);
- }
+ const object = scene.getObjectByProperty("uuid", id);
+ if (object && initialPosition && initialRotation) {
+ object.position.copy(initialPosition);
+ object.rotation.copy(initialRotation);
+ smoothPosition.copy(initialPosition);
+ targetPosition.copy(initialPosition);
+ targetQuaternion.setFromEuler(initialRotation);
}
};
+
useEffect(() => {
if (!isPlaying) {
resetState();
@@ -171,16 +178,16 @@ export default function PathNavigator({
const end = new THREE.Vector3(...path[index + 1]);
const dist = distancesRef.current[index];
const t = THREE.MathUtils.clamp((covered - accumulated) / dist, 0, 1);
- const position = start.clone().lerp(end, t);
- object.position.copy(position);
+ targetPosition.copy(start).lerp(end, t);
+
+ smoothPosition.lerp(targetPosition, 0.1);
+ object.position.copy(smoothPosition);
const direction = new THREE.Vector3().subVectors(end, start).normalize();
const targetRotationY = Math.atan2(direction.x, direction.z);
-
- let angleDifference = targetRotationY - object.rotation.y;
- angleDifference = ((angleDifference + Math.PI) % (Math.PI * 2)) - Math.PI;
- object.rotation.y += angleDifference * 0.1;
+ targetQuaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), targetRotationY);
+ object.quaternion.slerp(targetQuaternion, 0.1);
});
useEffect(() => {
diff --git a/app/src/modules/builder/geomentries/floors/addFloorToScene.ts b/app/src/modules/builder/geomentries/floors/addFloorToScene.ts
index e2f0baa..c951ba0 100644
--- a/app/src/modules/builder/geomentries/floors/addFloorToScene.ts
+++ b/app/src/modules/builder/geomentries/floors/addFloorToScene.ts
@@ -53,7 +53,7 @@ export default function addFloorToScene(
const mesh = new THREE.Mesh(geometry, material);
mesh.receiveShadow = true;
- mesh.position.y = layer;
+ mesh.position.y = (layer) * CONSTANTS.wallConfig.height;
mesh.rotateX(Math.PI / 2);
mesh.name = `Floor_Layer_${layer}`;
diff --git a/app/src/modules/builder/geomentries/floors/loadOnlyFloors.ts b/app/src/modules/builder/geomentries/floors/loadOnlyFloors.ts
index 8f33b57..9400be2 100644
--- a/app/src/modules/builder/geomentries/floors/loadOnlyFloors.ts
+++ b/app/src/modules/builder/geomentries/floors/loadOnlyFloors.ts
@@ -171,7 +171,7 @@ function loadOnlyFloors(
mesh.castShadow = true;
mesh.receiveShadow = true;
- mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height + 0.03;
+ mesh.position.y = (floor[0][0][2] - 1) * CONSTANTS.wallConfig.height;
mesh.rotateX(Math.PI / 2);
mesh.name = `Only_Floor_Line_${floor[0][0][2]}`;
diff --git a/app/src/modules/builder/groups/floorItemsGroup.tsx b/app/src/modules/builder/groups/floorItemsGroup.tsx
index 96f4fad..6289bd0 100644
--- a/app/src/modules/builder/groups/floorItemsGroup.tsx
+++ b/app/src/modules/builder/groups/floorItemsGroup.tsx
@@ -1,26 +1,11 @@
import { useFrame, useThree } from "@react-three/fiber";
-import {
- useActiveTool,
- useAsset3dWidget,
- useCamMode,
- useDeletableFloorItem,
- useDeleteModels,
- useFloorItems,
- useLoadingProgress,
- useRenderDistance,
- useselectedFloorItem,
- useSelectedItem,
- useSimulationStates,
- useSocketStore,
- useToggleView,
- useTransformMode,
-} from "../../../store/store";
+import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteModels, useFloorItems, useLoadingProgress, useRenderDistance, useselectedFloorItem, useSelectedItem, useSimulationStates, useSocketStore, useToggleView, useTransformMode, } from "../../../store/store";
import assetVisibility from "../geomentries/assets/assetVisibility";
import { useEffect } from "react";
import * as THREE from "three";
import * as Types from "../../../types/world/worldTypes";
import assetManager, {
- cancelOngoingTasks,
+ cancelOngoingTasks,
} from "../geomentries/assets/assetManager";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
@@ -31,413 +16,313 @@ import addAssetModel from "../geomentries/assets/addAssetModel";
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
import useModuleStore from "../../../store/useModuleStore";
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
-const assetManagerWorker = new Worker(
- new URL(
- "../../../services/factoryBuilder/webWorkers/assetManagerWorker.js",
- import.meta.url
- )
-);
-const gltfLoaderWorker = new Worker(
- new URL(
- "../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
- import.meta.url
- )
-);
+const assetManagerWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/assetManagerWorker.js", import.meta.url));
+const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
-const FloorItemsGroup = ({
- itemsGroup,
- hoveredDeletableFloorItem,
- AttachedObject,
- floorGroup,
- tempLoader,
- isTempLoader,
- plane,
-}: any) => {
- const state: Types.ThreeState = useThree();
- const { raycaster, controls }: any = state;
- const { renderDistance } = useRenderDistance();
- const { toggleView } = useToggleView();
- const { floorItems, setFloorItems } = useFloorItems();
- const { camMode } = useCamMode();
- const { deleteModels } = useDeleteModels();
- const { setDeletableFloorItem } = useDeletableFloorItem();
- const { transformMode } = useTransformMode();
- const { setselectedFloorItem } = useselectedFloorItem();
- const { activeTool } = useActiveTool();
- const { selectedItem, setSelectedItem } = useSelectedItem();
- const { simulationStates, setSimulationStates } = useSimulationStates();
- const { setLoadingProgress } = useLoadingProgress();
- const { activeModule } = useModuleStore();
- const { socket } = useSocketStore();
- const loader = new GLTFLoader();
- const dracoLoader = new DRACOLoader();
+const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject, floorGroup, tempLoader, isTempLoader, plane, }: any) => {
+ const state: Types.ThreeState = useThree();
+ const { raycaster, controls }: any = state;
+ const { renderDistance } = useRenderDistance();
+ const { toggleView } = useToggleView();
+ const { floorItems, setFloorItems } = useFloorItems();
+ const { camMode } = useCamMode();
+ const { deleteModels } = useDeleteModels();
+ const { setDeletableFloorItem } = useDeletableFloorItem();
+ const { transformMode } = useTransformMode();
+ const { setselectedFloorItem } = useselectedFloorItem();
+ const { activeTool } = useActiveTool();
+ const { selectedItem, setSelectedItem } = useSelectedItem();
+ const { simulationStates, setSimulationStates } = useSimulationStates();
+ const { setLoadingProgress } = useLoadingProgress();
+ const { activeModule } = useModuleStore();
+ const { socket } = useSocketStore();
+ const loader = new GLTFLoader();
+ const dracoLoader = new DRACOLoader();
- dracoLoader.setDecoderPath(
- "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
- );
- loader.setDRACOLoader(dracoLoader);
+ dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
+ loader.setDRACOLoader(dracoLoader);
- useEffect(() => {
- const email = localStorage.getItem("email");
- const organization = email!.split("@")[1].split(".")[0];
+ useEffect(() => {
+ const email = localStorage.getItem("email");
+ const organization = email!.split("@")[1].split(".")[0];
- let totalAssets = 0;
- let loadedAssets = 0;
+ let totalAssets = 0;
+ let loadedAssets = 0;
- const updateLoadingProgress = (progress: number) => {
- if (progress < 100) {
- setLoadingProgress(progress);
- } else if (progress === 100) {
- setTimeout(() => {
- setLoadingProgress(100);
- setTimeout(() => {
- setLoadingProgress(0);
- }, 1500);
- }, 1000);
- }
- };
+ const updateLoadingProgress = (progress: number) => {
+ if (progress < 100) {
+ setLoadingProgress(progress);
+ } else if (progress === 100) {
+ setTimeout(() => {
+ setLoadingProgress(100);
+ setTimeout(() => {
+ setLoadingProgress(0);
+ }, 1500);
+ }, 1000);
+ }
+ };
- getFloorAssets(organization).then((data) => {
- if (data.length > 0) {
- const uniqueItems = (data as Types.FloorItems).filter(
- (item, index, self) =>
- index === self.findIndex((t) => t.modelfileID === item.modelfileID)
- );
- totalAssets = uniqueItems.length;
- if (totalAssets === 0) {
- updateLoadingProgress(100);
- return;
- }
- gltfLoaderWorker.postMessage({ floorItems: data });
- } else {
- gltfLoaderWorker.postMessage({ floorItems: [] });
- loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
- updateLoadingProgress(100);
- }
- });
-
- gltfLoaderWorker.onmessage = async (event) => {
- if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
- const blobUrl = URL.createObjectURL(event.data.modelBlob);
-
- loader.load(blobUrl, (gltf) => {
- URL.revokeObjectURL(blobUrl);
- THREE.Cache.remove(blobUrl);
- THREE.Cache.add(event.data.modelID, gltf);
-
- loadedAssets++;
- const progress = Math.round((loadedAssets / totalAssets) * 100);
- updateLoadingProgress(progress);
-
- if (loadedAssets === totalAssets) {
- loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
- updateLoadingProgress(100);
- }
+ getFloorAssets(organization).then((data) => {
+ if (data.length > 0) {
+ const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
+ totalAssets = uniqueItems.length;
+ if (totalAssets === 0) {
+ updateLoadingProgress(100);
+ return;
+ }
+ gltfLoaderWorker.postMessage({ floorItems: data });
+ } else {
+ gltfLoaderWorker.postMessage({ floorItems: [] });
+ loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
+ updateLoadingProgress(100);
+ }
});
- }
- };
- }, []);
- useEffect(() => {
- assetManagerWorker.onmessage = async (event) => {
- cancelOngoingTasks(); // Cancel the ongoing process
- await assetManager(event.data, itemsGroup, loader);
- };
- }, [assetManagerWorker]);
+ gltfLoaderWorker.onmessage = async (event) => {
+ if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
+ const blobUrl = URL.createObjectURL(event.data.modelBlob);
- useEffect(() => {
- if (toggleView) return;
+ loader.load(blobUrl, (gltf) => {
+ URL.revokeObjectURL(blobUrl);
+ THREE.Cache.remove(blobUrl);
+ THREE.Cache.add(event.data.modelID, gltf);
- const uuids: string[] = [];
- itemsGroup.current?.children.forEach((child: any) => {
- uuids.push(child.uuid);
- });
- const cameraPosition = state.camera.position;
+ loadedAssets++;
+ const progress = Math.round((loadedAssets / totalAssets) * 100);
+ updateLoadingProgress(progress);
- assetManagerWorker.postMessage({
- floorItems,
- cameraPosition,
- uuids,
- renderDistance,
- });
- }, [camMode, renderDistance]);
+ if (loadedAssets === totalAssets) {
+ loadInitialFloorItems(itemsGroup, setFloorItems, setSimulationStates);
+ updateLoadingProgress(100);
+ }
+ });
+ }
+ };
+ }, []);
- useEffect(() => {
- const controls: any = state.controls;
- const camera: any = state.camera;
+ useEffect(() => {
+ assetManagerWorker.onmessage = async (event) => {
+ cancelOngoingTasks(); // Cancel the ongoing process
+ await assetManager(event.data, itemsGroup, loader);
+ };
+ }, [assetManagerWorker]);
- if (controls) {
- let intervalId: NodeJS.Timeout | null = null;
-
- const handleChange = () => {
+ useEffect(() => {
if (toggleView) return;
const uuids: string[] = [];
- itemsGroup.current?.children.forEach((child: any) => {
- uuids.push(child.uuid);
- });
- const cameraPosition = camera.position;
+ itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
+ const cameraPosition = state.camera.position;
- assetManagerWorker.postMessage({
- floorItems,
- cameraPosition,
- uuids,
- renderDistance,
- });
- };
+ assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
+ }, [camMode, renderDistance]);
- const startInterval = () => {
- if (!intervalId) {
- intervalId = setInterval(handleChange, 50);
+ useEffect(() => {
+ const controls: any = state.controls;
+ const camera: any = state.camera;
+
+ if (controls) {
+ let intervalId: NodeJS.Timeout | null = null;
+
+ const handleChange = () => {
+ if (toggleView) return;
+
+ const uuids: string[] = [];
+ itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
+ const cameraPosition = camera.position;
+
+ assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
+ };
+
+ const startInterval = () => {
+ if (!intervalId) {
+ intervalId = setInterval(handleChange, 50);
+ }
+ };
+
+ const stopInterval = () => {
+ handleChange();
+ if (intervalId) {
+ clearInterval(intervalId);
+ intervalId = null;
+ }
+ };
+
+ controls.addEventListener("rest", handleChange);
+ controls.addEventListener("rest", stopInterval);
+ controls.addEventListener("control", startInterval);
+ controls.addEventListener("controlend", stopInterval);
+
+ return () => {
+ controls.removeEventListener("rest", handleChange);
+ controls.removeEventListener("rest", stopInterval);
+ controls.removeEventListener("control", startInterval);
+ controls.removeEventListener("controlend", stopInterval);
+ if (intervalId) {
+ clearInterval(intervalId);
+ }
+ };
}
- };
+ }, [state.controls, floorItems, toggleView, renderDistance]);
- const stopInterval = () => {
- handleChange();
- if (intervalId) {
- clearInterval(intervalId);
- intervalId = null;
- }
- };
+ useEffect(() => {
+ const canvasElement = state.gl.domElement;
+ let drag = false;
+ let isLeftMouseDown = false;
- controls.addEventListener("rest", handleChange);
- controls.addEventListener("rest", stopInterval);
- controls.addEventListener("control", startInterval);
- controls.addEventListener("controlend", stopInterval);
-
- return () => {
- controls.removeEventListener("rest", handleChange);
- controls.removeEventListener("rest", stopInterval);
- controls.removeEventListener("control", startInterval);
- controls.removeEventListener("controlend", stopInterval);
- if (intervalId) {
- clearInterval(intervalId);
- }
- };
- }
- }, [state.controls, floorItems, toggleView, renderDistance]);
-
- useEffect(() => {
- const canvasElement = state.gl.domElement;
- let drag = false;
- let isLeftMouseDown = false;
-
- const onMouseDown = (evt: any) => {
- if (evt.button === 0) {
- isLeftMouseDown = true;
- drag = false;
- }
- };
-
- const onMouseMove = () => {
- if (isLeftMouseDown) {
- drag = true;
- }
- };
-
- const onMouseUp = async (evt: any) => {
- if (controls) {
- (controls as any).enabled = true;
- }
- if (evt.button === 0) {
- isLeftMouseDown = false;
- if (drag) return;
-
- if (deleteModels) {
- DeleteFloorItems(
- itemsGroup,
- hoveredDeletableFloorItem,
- setFloorItems,
- setSimulationStates,
- socket
- );
- }
- const Mode = transformMode;
-
- if (Mode !== null || activeTool === "cursor") {
- if (!itemsGroup.current) return;
- let intersects = raycaster.intersectObjects(
- itemsGroup.current.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 THREE.Object3D;
- // }
- // if (currentObject) {
- // AttachedObject.current = currentObject as any;
- // setselectedFloorItem(AttachedObject.current!);
- // }
- } else {
- const target = controls.getTarget(new THREE.Vector3());
- await controls.setTarget(target.x, 0, target.z, true);
- setselectedFloorItem(null);
- }
- }
- }
- };
-
- const onDblClick = async (evt: any) => {
- if (evt.button === 0) {
- isLeftMouseDown = false;
- if (drag) return;
-
- const Mode = transformMode;
-
- if (Mode !== null || activeTool === "cursor") {
- if (!itemsGroup.current) return;
- let intersects = raycaster.intersectObjects(
- itemsGroup.current.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 THREE.Object3D;
+ const onMouseDown = (evt: any) => {
+ if (evt.button === 0) {
+ isLeftMouseDown = true;
+ drag = false;
}
- if (currentObject) {
- AttachedObject.current = currentObject as any;
- // controls.fitToSphere(AttachedObject.current!, true);
+ };
- const bbox = new THREE.Box3().setFromObject(
- AttachedObject.current
- );
- const size = bbox.getSize(new THREE.Vector3());
- const center = bbox.getCenter(new THREE.Vector3());
-
- const front = new THREE.Vector3(0, 0, 1);
- AttachedObject.current.localToWorld(front);
- front.sub(AttachedObject.current.position).normalize();
-
- const distance = Math.max(size.x, size.y, size.z) * 2;
- const newPosition = center
- .clone()
- .addScaledVector(front, distance);
-
- controls.setPosition(
- newPosition.x,
- newPosition.y,
- newPosition.z,
- true
- );
- controls.setTarget(center.x, center.y, center.z, true);
- controls.fitToBox(AttachedObject.current!, true, {
- cover: true,
- paddingTop: 5,
- paddingLeft: 5,
- paddingBottom: 5,
- paddingRight: 5,
- });
-
- setselectedFloorItem(AttachedObject.current!);
+ const onMouseMove = () => {
+ if (isLeftMouseDown) {
+ drag = true;
+ }
+ };
+
+ const onMouseUp = async (evt: any) => {
+ if (controls) {
+ (controls as any).enabled = true;
+ }
+ if (evt.button === 0) {
+ isLeftMouseDown = false;
+ if (drag) return;
+
+ if (deleteModels) {
+ DeleteFloorItems(itemsGroup, hoveredDeletableFloorItem, setFloorItems, setSimulationStates, socket);
+ }
+ const Mode = transformMode;
+
+ if (Mode !== null || activeTool === "cursor") {
+ if (!itemsGroup.current) return;
+ let intersects = raycaster.intersectObjects(
+ itemsGroup.current.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 THREE.Object3D;
+ // }
+ // if (currentObject) {
+ // AttachedObject.current = currentObject as any;
+ // setselectedFloorItem(AttachedObject.current!);
+ // }
+ } else {
+ const target = controls.getTarget(new THREE.Vector3());
+ await controls.setTarget(target.x, 0, target.z, true);
+ setselectedFloorItem(null);
+ }
+ }
+ }
+ };
+
+ const onDblClick = async (evt: any) => {
+ if (evt.button === 0) {
+ isLeftMouseDown = false;
+ if (drag) return;
+
+ const Mode = transformMode;
+
+ if (Mode !== null || activeTool === "cursor") {
+ if (!itemsGroup.current) return;
+ let intersects = raycaster.intersectObjects(itemsGroup.current.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 THREE.Object3D;
+ }
+ if (currentObject) {
+ AttachedObject.current = currentObject as any;
+ // controls.fitToSphere(AttachedObject.current!, true);
+
+ const bbox = new THREE.Box3().setFromObject(AttachedObject.current);
+ const size = bbox.getSize(new THREE.Vector3());
+ const center = bbox.getCenter(new THREE.Vector3());
+
+ const front = new THREE.Vector3(0, 0, 1);
+ AttachedObject.current.localToWorld(front);
+ front.sub(AttachedObject.current.position).normalize();
+
+ const distance = Math.max(size.x, size.y, size.z) * 2;
+ const newPosition = center.clone().addScaledVector(front, distance);
+
+ controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
+ controls.setTarget(center.x, center.y, center.z, true);
+ controls.fitToBox(AttachedObject.current!, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
+
+ setselectedFloorItem(AttachedObject.current!);
+ }
+ } else {
+ const target = controls.getTarget(new THREE.Vector3());
+ await controls.setTarget(target.x, 0, target.z, true);
+ setselectedFloorItem(null);
+ }
+ }
+ }
+ };
+
+ const onDrop = (event: any) => {
+ if (!event.dataTransfer?.files[0]) return;
+
+ if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
+ addAssetModel(raycaster, state.camera, state.pointer, floorGroup, setFloorItems, itemsGroup, isTempLoader, tempLoader, socket, selectedItem, setSelectedItem, setSimulationStates, plane);
+ }
+ };
+
+ const onDragOver = (event: any) => {
+ event.preventDefault();
+ };
+
+ if (activeModule === "builder") {
+ canvasElement.addEventListener("mousedown", onMouseDown);
+ canvasElement.addEventListener("mouseup", onMouseUp);
+ canvasElement.addEventListener("mousemove", onMouseMove);
+ canvasElement.addEventListener("dblclick", onDblClick);
+ canvasElement.addEventListener("drop", onDrop);
+ canvasElement.addEventListener("dragover", onDragOver);
+ } else {
+ if (controls) {
+ const target = controls.getTarget(new THREE.Vector3());
+ controls.setTarget(target.x, 0, target.z, true);
+ setselectedFloorItem(null);
}
- } else {
- const target = controls.getTarget(new THREE.Vector3());
- await controls.setTarget(target.x, 0, target.z, true);
- setselectedFloorItem(null);
- }
}
- }
- };
- const onDrop = (event: any) => {
- if (!event.dataTransfer?.files[0]) return;
+ return () => {
+ canvasElement.removeEventListener("mousedown", onMouseDown);
+ canvasElement.removeEventListener("mouseup", onMouseUp);
+ canvasElement.removeEventListener("mousemove", onMouseMove);
+ canvasElement.removeEventListener("dblclick", onDblClick);
+ canvasElement.removeEventListener("drop", onDrop);
+ canvasElement.removeEventListener("dragover", onDragOver);
+ };
+ }, [deleteModels, transformMode, controls, selectedItem, state.camera, state.pointer, activeTool, activeModule,]);
- if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
- addAssetModel(
- raycaster,
- state.camera,
- state.pointer,
- floorGroup,
- setFloorItems,
- itemsGroup,
- isTempLoader,
- tempLoader,
- socket,
- selectedItem,
- setSelectedItem,
- setSimulationStates,
- plane
- );
- }
- };
+ useFrame(() => {
+ if (controls)
+ assetVisibility(itemsGroup, state.camera.position, renderDistance);
+ if (deleteModels && activeModule === "builder") {
+ DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem);
+ } else if (!deleteModels) {
+ if (hoveredDeletableFloorItem.current) {
+ hoveredDeletableFloorItem.current = undefined;
+ setDeletableFloorItem(null);
+ }
+ }
+ });
- const onDragOver = (event: any) => {
- event.preventDefault();
- };
-
- if (activeModule === "builder") {
- canvasElement.addEventListener("mousedown", onMouseDown);
- canvasElement.addEventListener("mouseup", onMouseUp);
- canvasElement.addEventListener("mousemove", onMouseMove);
- canvasElement.addEventListener("dblclick", onDblClick);
- canvasElement.addEventListener("drop", onDrop);
- canvasElement.addEventListener("dragover", onDragOver);
- } else {
- if (controls) {
- const target = controls.getTarget(new THREE.Vector3());
- controls.setTarget(target.x, 0, target.z, true);
- setselectedFloorItem(null);
- }
- }
-
- return () => {
- canvasElement.removeEventListener("mousedown", onMouseDown);
- canvasElement.removeEventListener("mouseup", onMouseUp);
- canvasElement.removeEventListener("mousemove", onMouseMove);
- canvasElement.removeEventListener("dblclick", onDblClick);
- canvasElement.removeEventListener("drop", onDrop);
- canvasElement.removeEventListener("dragover", onDragOver);
- };
- }, [
- deleteModels,
- transformMode,
- controls,
- selectedItem,
- state.camera,
- state.pointer,
- activeTool,
- activeModule,
- ]);
-
-
- useFrame(() => {
- if (controls)
- assetVisibility(itemsGroup, state.camera.position, renderDistance);
- if (deleteModels) {
- DeletableHoveredFloorItems(
- state,
- itemsGroup,
- hoveredDeletableFloorItem,
- setDeletableFloorItem
- );
- } else if (!deleteModels) {
- if (hoveredDeletableFloorItem.current) {
- hoveredDeletableFloorItem.current = undefined;
- setDeletableFloorItem(null);
- }
- }
- });
-
- return ;
+ return ;
};
export default FloorItemsGroup;
diff --git a/app/src/modules/builder/groups/wallItemsGroup.tsx b/app/src/modules/builder/groups/wallItemsGroup.tsx
index c79adde..1439ef5 100644
--- a/app/src/modules/builder/groups/wallItemsGroup.tsx
+++ b/app/src/modules/builder/groups/wallItemsGroup.tsx
@@ -9,9 +9,13 @@ import handleMeshMissed from "../eventFunctions/handleMeshMissed";
import DeleteWallItems from "../geomentries/walls/deleteWallItems";
import loadInitialWallItems from "../../scene/IntialLoad/loadInitialWallItems";
import AddWallItems from "../geomentries/walls/addWallItems";
+import useModuleStore from "../../../store/useModuleStore";
const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => {
+ const state = useThree();
+ const { socket } = useSocketStore();
+ const { pointer, camera, raycaster } = state;
const { deleteModels, setDeleteModels } = useDeleteModels();
const { wallItems, setWallItems } = useWallItems();
const { objectPosition, setObjectPosition } = useObjectPosition();
@@ -19,10 +23,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
const { objectRotation, setObjectRotation } = useObjectRotation();
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
- const { socket } = useSocketStore();
- const state = useThree();
- const { pointer, camera, raycaster } = state;
-
+ const { activeModule } = useModuleStore();
useEffect(() => {
// Load Wall Items from the backend
@@ -209,7 +210,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
const onMouseUp = (evt: any) => {
if (evt.button === 0) {
isLeftMouseDown = false;
- if (!drag && deleteModels) {
+ if (!drag && deleteModels && activeModule === "builder") {
DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket);
}
}
@@ -224,7 +225,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
const onDrop = (event: any) => {
if (!event.dataTransfer?.files[0]) return
-
+
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera);
@@ -259,7 +260,7 @@ const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletable
}, [deleteModels, wallItems])
useEffect(() => {
- if (deleteModels) {
+ if (deleteModels && activeModule === "builder") {
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
setSelectedWallItem(null);
setSelectedItemsIndex(null);
diff --git a/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts b/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts
index ec6033b..22b9a83 100644
--- a/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts
+++ b/app/src/modules/scene/IntialLoad/loadInitialFloorItems.ts
@@ -192,7 +192,7 @@ function processLoadedModel(
},
]);
- if (item.eventData || item.modelfileID === '67e3db95c2e8f37134526fb2') {
+ if (item.eventData || item.modelfileID === '67e3db5ac2e8f37134526f40' || item.modelfileID === '67eb7904c2e8f37134527eae') {
processEventData(item, setSimulationStates);
}
@@ -227,10 +227,10 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
data as Types.VehicleEventsSchema
]);
- } else if (item.modelfileID === '67e3db95c2e8f37134526fb2') {
+ } else if (item.modelfileID === '67e3db5ac2e8f37134526f40') {
const pointUUID = THREE.MathUtils.generateUUID();
- const pointPosition = new THREE.Vector3(0, 1.75, 0);
+ const pointPosition = new THREE.Vector3(0, 1.5, -0.5);
const staticMachine: Types.StaticMachineEventsSchema = {
modeluuid: item.modeluuid,
@@ -243,13 +243,39 @@ function processEventData(item: Types.EventData, setSimulationStates: any) {
triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
},
- position: item.position
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
};
-
+
setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
...(prevEvents || []),
staticMachine as Types.StaticMachineEventsSchema
]);
+
+ } else if (item.modelfileID === '67eb7904c2e8f37134527eae') {
+ const pointUUID = THREE.MathUtils.generateUUID();
+ const pointPosition = new THREE.Vector3(0, 2.75, -0.5);
+
+ const armBot: Types.ArmBotEventsSchema = {
+ modeluuid: item.modeluuid,
+ modelName: item.modelname,
+ type: "ArmBot",
+ points: {
+ uuid: pointUUID,
+ position: [pointPosition.x, pointPosition.y, pointPosition.z],
+ actions: { uuid: THREE.MathUtils.generateUUID(), name: 'Action 1', speed: 1, processes: [] },
+ triggers: { uuid: THREE.MathUtils.generateUUID(), name: 'Trigger 1', type: 'OnComplete' },
+ connections: { source: { modelUUID: item.modeluuid, pointUUID: pointUUID }, targets: [] },
+ },
+ position: item.position,
+ rotation: [item.rotation.x, item.rotation.y, item.rotation.z],
+ }
+
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
+ ...(prevEvents || []),
+ armBot as Types.ArmBotEventsSchema
+ ]);
+
}
}
diff --git a/app/src/modules/scene/controls/selection/copyPasteControls.tsx b/app/src/modules/scene/controls/selection/copyPasteControls.tsx
index 7b494cd..3d2acee 100644
--- a/app/src/modules/scene/controls/selection/copyPasteControls.tsx
+++ b/app/src/modules/scene/controls/selection/copyPasteControls.tsx
@@ -151,7 +151,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
return updatedItems;
});
- let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
+ let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default";
@@ -234,7 +234,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
...(prevEvents || []),
newEventData as Types.ConveyorEventsSchema
]);
@@ -313,13 +313,44 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position;
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
...(prevEvents || []),
newEventData as Types.VehicleEventsSchema
]);
socket.emit("v2:model-asset:add", data);
+ } else {
+
+ //REST
+
+ // await setFloorItemApi(
+ // organization,
+ // obj.uuid,
+ // obj.userData.name,
+ // [worldPosition.x, worldPosition.y, worldPosition.z],
+ // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
+ // obj.userData.modelId,
+ // false,
+ // true,
+ // );
+
+ //SOCKET
+
+ const data = {
+ organization,
+ modeluuid: newFloorItem.modeluuid,
+ modelname: newFloorItem.modelname,
+ modelfileID: newFloorItem.modelfileID,
+ position: newFloorItem.position,
+ rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
+ isLocked: false,
+ isVisible: true,
+ socketId: socket.id,
+ };
+
+ socket.emit("v2:model-asset:add", data);
+
}
} else {
diff --git a/app/src/modules/scene/controls/selection/duplicationControls.tsx b/app/src/modules/scene/controls/selection/duplicationControls.tsx
index 852b541..a71412d 100644
--- a/app/src/modules/scene/controls/selection/duplicationControls.tsx
+++ b/app/src/modules/scene/controls/selection/duplicationControls.tsx
@@ -132,7 +132,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
return updatedItems;
});
- let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
+ let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default";
@@ -216,7 +216,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
...(prevEvents || []),
newEventData as Types.ConveyorEventsSchema
]);
@@ -295,13 +295,44 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position;
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => [
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => [
...(prevEvents || []),
newEventData as Types.VehicleEventsSchema
]);
socket.emit("v2:model-asset:add", data);
+ } else {
+
+ //REST
+
+ // await setFloorItemApi(
+ // organization,
+ // obj.uuid,
+ // obj.userData.name,
+ // [worldPosition.x, worldPosition.y, worldPosition.z],
+ // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
+ // obj.userData.modelId,
+ // false,
+ // true,
+ // );
+
+ //SOCKET
+
+ const data = {
+ organization,
+ modeluuid: newFloorItem.modeluuid,
+ modelname: newFloorItem.modelname,
+ modelfileID: newFloorItem.modelfileID,
+ position: newFloorItem.position,
+ rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
+ isLocked: false,
+ isVisible: true,
+ socketId: socket.id,
+ };
+
+ socket.emit("v2:model-asset:add", data);
+
}
} else {
diff --git a/app/src/modules/scene/controls/selection/moveControls.tsx b/app/src/modules/scene/controls/selection/moveControls.tsx
index 2693531..5883b62 100644
--- a/app/src/modules/scene/controls/selection/moveControls.tsx
+++ b/app/src/modules/scene/controls/selection/moveControls.tsx
@@ -180,12 +180,12 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
return updatedItems;
});
- let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
+ let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default";
- if (eventData && eventData.type !== 'StaticMachine') {
+ if (eventData) {
if (eventData.type === 'Conveyor' && eventData) {
const backendEventData = {
@@ -229,7 +229,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData }
@@ -280,7 +280,113 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position;
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
+ const updatedEvents = (prevEvents || []).map(event =>
+ event.modeluuid === newFloorItem.modeluuid
+ ? { ...event, ...newEventData }
+ : event
+ );
+ return updatedEvents;
+ });
+
+ socket.emit("v2:model-asset:add", data);
+
+ } else if (eventData.type === 'StaticMachine' && eventData) {
+
+ const backendEventData = {
+ type: 'StaticMachine',
+ points: eventData.points,
+ };
+
+ // REST
+
+ // await setFloorItemApi(
+ // organization,
+ // obj.uuid,
+ // obj.userData.name,
+ // obj.userData.modelId,
+ // [worldPosition.x, worldPosition.y, worldPosition.z],
+ // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
+ // false,
+ // true,
+ // { type: backendEventData.type, points: backendEventData.points }
+ // );
+
+ //SOCKET
+
+ const data = {
+ organization,
+ modeluuid: newFloorItem.modeluuid,
+ modelname: newFloorItem.modelname,
+ modelfileID: newFloorItem.modelfileID,
+ position: newFloorItem.position,
+ rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
+ isLocked: false,
+ isVisible: true,
+ // eventData: { type: backendEventData.type, points: backendEventData.points },
+ socketId: socket.id,
+ };
+
+ const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
+ newEventData.modeluuid = newFloorItem.modeluuid;
+ newEventData.modelName = newFloorItem.modelname;
+ newEventData.position = newFloorItem.position;
+ newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
+
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
+ const updatedEvents = (prevEvents || []).map(event =>
+ event.modeluuid === newFloorItem.modeluuid
+ ? { ...event, ...newEventData }
+ : event
+ );
+ return updatedEvents;
+ });
+
+ socket.emit("v2:model-asset:add", data);
+
+ } else if (eventData.type === 'ArmBot' && eventData) {
+
+ const backendEventData = {
+ type: 'ArmBot',
+ points: eventData.points,
+ };
+
+ // REST
+
+ // await setFloorItemApi(
+ // organization,
+ // obj.uuid,
+ // obj.userData.name,
+ // obj.userData.modelId,
+ // [worldPosition.x, worldPosition.y, worldPosition.z],
+ // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
+ // false,
+ // true,
+ // { type: backendEventData.type, points: backendEventData.points }
+ // );
+
+ //SOCKET
+
+ const data = {
+ organization,
+ modeluuid: newFloorItem.modeluuid,
+ modelname: newFloorItem.modelname,
+ modelfileID: newFloorItem.modelfileID,
+ position: newFloorItem.position,
+ rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
+ isLocked: false,
+ isVisible: true,
+ // eventData: { type: backendEventData.type, points: backendEventData.points },
+ socketId: socket.id,
+ };
+
+ const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
+ newEventData.modeluuid = newFloorItem.modeluuid;
+ newEventData.modelName = newFloorItem.modelname;
+ newEventData.position = newFloorItem.position;
+ newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
+
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData }
diff --git a/app/src/modules/scene/controls/selection/rotateControls.tsx b/app/src/modules/scene/controls/selection/rotateControls.tsx
index 020705d..cf1ac83 100644
--- a/app/src/modules/scene/controls/selection/rotateControls.tsx
+++ b/app/src/modules/scene/controls/selection/rotateControls.tsx
@@ -184,13 +184,12 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
return updatedItems;
});
- let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
- console.log('eventData: ', eventData);
+ let eventData: Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema | undefined = simulationStates.find((events) => events.modeluuid === obj.userData.modeluuid);
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "default";
- if (eventData && eventData.type !== 'StaticMachine') {
+ if (eventData) {
if (eventData.type === 'Conveyor' && eventData) {
const backendEventData = {
@@ -233,9 +232,8 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position;
newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
- console.log('newEventData: ', newEventData);
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData }
@@ -287,7 +285,113 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
newEventData.modelName = newFloorItem.modelname;
newEventData.position = newFloorItem.position;
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
+ const updatedEvents = (prevEvents || []).map(event =>
+ event.modeluuid === newFloorItem.modeluuid
+ ? { ...event, ...newEventData }
+ : event
+ );
+ return updatedEvents;
+ });
+
+ socket.emit("v2:model-asset:add", data);
+
+ } else if (eventData.type === 'StaticMachine' && eventData) {
+
+ const backendEventData = {
+ type: 'StaticMachine',
+ points: eventData.points,
+ };
+
+ // REST
+
+ // await setFloorItemApi(
+ // organization,
+ // obj.uuid,
+ // obj.userData.name,
+ // obj.userData.modelId,
+ // [worldPosition.x, worldPosition.y, worldPosition.z],
+ // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
+ // false,
+ // true,
+ // { type: backendEventData.type, points: backendEventData.points }
+ // );
+
+ //SOCKET
+
+ const data = {
+ organization,
+ modeluuid: newFloorItem.modeluuid,
+ modelname: newFloorItem.modelname,
+ modelfileID: newFloorItem.modelfileID,
+ position: newFloorItem.position,
+ rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
+ isLocked: false,
+ isVisible: true,
+ // eventData: { type: backendEventData.type, points: backendEventData.points },
+ socketId: socket.id,
+ };
+
+ const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
+ newEventData.modeluuid = newFloorItem.modeluuid;
+ newEventData.modelName = newFloorItem.modelname;
+ newEventData.position = newFloorItem.position;
+ newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
+
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
+ const updatedEvents = (prevEvents || []).map(event =>
+ event.modeluuid === newFloorItem.modeluuid
+ ? { ...event, ...newEventData }
+ : event
+ );
+ return updatedEvents;
+ });
+
+ socket.emit("v2:model-asset:add", data);
+
+ } else if (eventData.type === 'ArmBot' && eventData) {
+
+ const backendEventData = {
+ type: 'ArmBot',
+ points: eventData.points,
+ };
+
+ // REST
+
+ // await setFloorItemApi(
+ // organization,
+ // obj.uuid,
+ // obj.userData.name,
+ // obj.userData.modelId,
+ // [worldPosition.x, worldPosition.y, worldPosition.z],
+ // { "x": obj.rotation.x, "y": obj.rotation.y, "z": obj.rotation.z },
+ // false,
+ // true,
+ // { type: backendEventData.type, points: backendEventData.points }
+ // );
+
+ //SOCKET
+
+ const data = {
+ organization,
+ modeluuid: newFloorItem.modeluuid,
+ modelname: newFloorItem.modelname,
+ modelfileID: newFloorItem.modelfileID,
+ position: newFloorItem.position,
+ rotation: { x: obj.rotation.x, y: obj.rotation.y, z: obj.rotation.z },
+ isLocked: false,
+ isVisible: true,
+ // eventData: { type: backendEventData.type, points: backendEventData.points },
+ socketId: socket.id,
+ };
+
+ const newEventData: any = { type: backendEventData.type, points: backendEventData.points };
+ newEventData.modeluuid = newFloorItem.modeluuid;
+ newEventData.modelName = newFloorItem.modelname;
+ newEventData.position = newFloorItem.position;
+ newEventData.rotation = [obj.rotation.x, obj.rotation.y, obj.rotation.z];
+
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).map(event =>
event.modeluuid === newFloorItem.modeluuid
? { ...event, ...newEventData }
diff --git a/app/src/modules/scene/controls/selection/selectionControls.tsx b/app/src/modules/scene/controls/selection/selectionControls.tsx
index 8a464d5..686bf42 100644
--- a/app/src/modules/scene/controls/selection/selectionControls.tsx
+++ b/app/src/modules/scene/controls/selection/selectionControls.tsx
@@ -240,7 +240,7 @@ const SelectionControls: React.FC = () => {
}
});
- setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
+ setSimulationStates((prevEvents: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
const updatedEvents = (prevEvents || []).filter(event => event.modeluuid !== selectedMesh.uuid);
return updatedEvents;
});
diff --git a/app/src/modules/simulation/path/pathConnector.tsx b/app/src/modules/simulation/path/pathConnector.tsx
index 8a295be..805821c 100644
--- a/app/src/modules/simulation/path/pathConnector.tsx
+++ b/app/src/modules/simulation/path/pathConnector.tsx
@@ -1,9 +1,9 @@
import { useFrame, useThree } from '@react-three/fiber';
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import * as Types from '../../../types/world/worldTypes';
import { QuadraticBezierLine } from '@react-three/drei';
-import { useIsConnecting, useSimulationStates, useSocketStore } from '../../../store/store';
+import { useIsConnecting, useRenderDistance, useSimulationStates, useSocketStore } from '../../../store/store';
import useModuleStore from '../../../store/useModuleStore';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/setEventsApt';
@@ -11,28 +11,21 @@ import { setEventApi } from '../../../services/factoryBuilder/assest/floorAsset/
function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject }) {
const { activeModule } = useModuleStore();
const { gl, raycaster, scene, pointer, camera } = useThree();
+ const { renderDistance } = useRenderDistance();
const { setIsConnecting } = useIsConnecting();
const { simulationStates, setSimulationStates } = useSimulationStates();
const { isPlaying } = usePlayButtonStore();
const { socket } = useSocketStore();
+ const groupRefs = useRef<{ [key: string]: any }>({});
- const [firstSelected, setFirstSelected] = useState<{
- modelUUID: string;
- sphereUUID: string;
- position: THREE.Vector3;
- isCorner: boolean;
- } | null>(null);
+ const [firstSelected, setFirstSelected] = useState<{ modelUUID: string; sphereUUID: string; position: THREE.Vector3; isCorner: boolean; } | null>(null);
const [currentLine, setCurrentLine] = useState<{ start: THREE.Vector3, end: THREE.Vector3, mid: THREE.Vector3 } | null>(null);
const [helperlineColor, setHelperLineColor] = useState('red');
- const updatePathConnections = (
- fromModelUUID: string,
- fromPointUUID: string,
- toModelUUID: string,
- toPointUUID: string
- ) => {
+ const updatePathConnections = (fromModelUUID: string, fromPointUUID: string, toModelUUID: string, toPointUUID: string) => {
const updatedPaths = simulationStates.map(path => {
if (path.type === 'Conveyor') {
+ // Handle outgoing connections from Conveyor
if (path.modeluuid === fromModelUUID) {
return {
...path,
@@ -61,6 +54,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
})
};
}
+ // Handle incoming connections to Conveyor
else if (path.modeluuid === toModelUUID) {
return {
...path,
@@ -167,82 +161,170 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
}
return path;
}
- // else if (path.type === 'StaticMachine') {
- // if (path.modeluuid === fromModelUUID && path.points.uuid === fromPointUUID) {
- // const newTarget = {
- // modelUUID: toModelUUID,
- // pointUUID: toPointUUID
- // };
- // const existingTargets = path.points.connections.targets || [];
+ else if (path.type === 'StaticMachine') {
+ // Handle outgoing connections from StaticMachine
+ if (path.modeluuid === fromModelUUID && path.points.uuid === fromPointUUID) {
+ const newTarget = {
+ modelUUID: toModelUUID,
+ pointUUID: toPointUUID
+ };
- // // Check if target is an ArmBot
- // const toPath = simulationStates.find(p => p.modeluuid === toModelUUID);
- // if (toPath?.type !== 'ArmBot') {
- // console.log("StaticMachine can only connect to ArmBot");
- // return path;
- // }
+ // Ensure target is an ArmBot
+ const toPath = simulationStates.find(p => p.modeluuid === toModelUUID);
+ if (toPath?.type !== 'ArmBot') {
+ console.log("StaticMachine can only connect to ArmBot");
+ return path;
+ }
- // // Check if already has a connection
- // if (existingTargets.length >= 1) {
- // console.log("StaticMachine can have only one connection");
- // return path;
- // }
+ const existingTargets = path.points.connections.targets || [];
- // if (!existingTargets.some(target =>
- // target.modelUUID === newTarget.modelUUID &&
- // target.pointUUID === newTarget.pointUUID
- // )) {
- // return {
- // ...path,
- // points: {
- // ...path.points,
- // connections: {
- // ...path.points.connections,
- // targets: [...existingTargets, newTarget]
- // }
- // }
- // };
- // }
- // }
- // // Handle incoming connections to StaticMachine
- // else if (path.modeluuid === toModelUUID && path.points.uuid === toPointUUID) {
- // const reverseTarget = {
- // modelUUID: fromModelUUID,
- // pointUUID: fromPointUUID
- // };
- // const existingTargets = path.points.connections.targets || [];
+ // Allow only one connection
+ if (existingTargets.length >= 1) {
+ console.log("StaticMachine can only have one connection");
+ return path;
+ }
- // // Check if source is an ArmBot
- // const fromPath = simulationStates.find(p => p.modeluuid === fromModelUUID);
- // if (fromPath?.type !== 'ArmBot') {
- // console.log("StaticMachine can only connect to ArmBot");
- // return path;
- // }
+ if (!existingTargets.some(target =>
+ target.modelUUID === newTarget.modelUUID &&
+ target.pointUUID === newTarget.pointUUID
+ )) {
+ return {
+ ...path,
+ points: {
+ ...path.points,
+ connections: {
+ ...path.points.connections,
+ targets: [...existingTargets, newTarget]
+ }
+ }
+ };
+ }
+ }
- // // Check if already has a connection
- // if (existingTargets.length >= 1) {
- // console.log("StaticMachine can have only one connection");
- // return path;
- // }
+ // Handle incoming connections to StaticMachine
+ else if (path.modeluuid === toModelUUID && path.points.uuid === toPointUUID) {
+ const reverseTarget = {
+ modelUUID: fromModelUUID,
+ pointUUID: fromPointUUID
+ };
+
+ const fromPath = simulationStates.find(p => p.modeluuid === fromModelUUID);
+ if (fromPath?.type !== 'ArmBot') {
+ console.log("StaticMachine can only be connected from ArmBot");
+ return path;
+ }
+
+ const existingTargets = path.points.connections.targets || [];
+
+ if (existingTargets.length >= 1) {
+ console.log("StaticMachine can only have one connection");
+ return path;
+ }
+
+ if (!existingTargets.some(target =>
+ target.modelUUID === reverseTarget.modelUUID &&
+ target.pointUUID === reverseTarget.pointUUID
+ )) {
+ return {
+ ...path,
+ points: {
+ ...path.points,
+ connections: {
+ ...path.points.connections,
+ targets: [...existingTargets, reverseTarget]
+ }
+ }
+ };
+ }
+ }
+ return path;
+ }
+ else if (path.type === 'ArmBot') {
+ // Handle outgoing connections from ArmBot
+ if (path.modeluuid === fromModelUUID && path.points.uuid === fromPointUUID) {
+ const newTarget = {
+ modelUUID: toModelUUID,
+ pointUUID: toPointUUID
+ };
+
+ const toPath = simulationStates.find(p => p.modeluuid === toModelUUID);
+ if (!toPath) return path;
+
+ const existingTargets = path.points.connections.targets || [];
+
+ // Check if connecting to a StaticMachine and already connected to one
+ const alreadyConnectedToStatic = existingTargets.some(target => {
+ const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
+ return targetPath?.type === 'StaticMachine';
+ });
+
+ if (toPath.type === 'StaticMachine') {
+ if (alreadyConnectedToStatic) {
+ console.log("ArmBot can only connect to one StaticMachine");
+ return path;
+ }
+ }
+
+ if (!existingTargets.some(target =>
+ target.modelUUID === newTarget.modelUUID &&
+ target.pointUUID === newTarget.pointUUID
+ )) {
+ return {
+ ...path,
+ points: {
+ ...path.points,
+ connections: {
+ ...path.points.connections,
+ targets: [...existingTargets, newTarget]
+ }
+ }
+ };
+ }
+ }
+
+ // Handle incoming connections to ArmBot
+ else if (path.modeluuid === toModelUUID && path.points.uuid === toPointUUID) {
+ const reverseTarget = {
+ modelUUID: fromModelUUID,
+ pointUUID: fromPointUUID
+ };
+
+ const fromPath = simulationStates.find(p => p.modeluuid === fromModelUUID);
+ if (!fromPath) return path;
+
+ const existingTargets = path.points.connections.targets || [];
+
+ const alreadyConnectedFromStatic = existingTargets.some(target => {
+ const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
+ return targetPath?.type === 'StaticMachine';
+ });
+
+ if (fromPath.type === 'StaticMachine') {
+ if (alreadyConnectedFromStatic) {
+ console.log("ArmBot can only be connected from one StaticMachine");
+ return path;
+ }
+ }
+
+ if (!existingTargets.some(target =>
+ target.modelUUID === reverseTarget.modelUUID &&
+ target.pointUUID === reverseTarget.pointUUID
+ )) {
+ return {
+ ...path,
+ points: {
+ ...path.points,
+ connections: {
+ ...path.points.connections,
+ targets: [...existingTargets, reverseTarget]
+ }
+ }
+ };
+ }
+ }
+ return path;
+ }
- // if (!existingTargets.some(target =>
- // target.modelUUID === reverseTarget.modelUUID &&
- // target.pointUUID === reverseTarget.pointUUID
- // )) {
- // return {
- // ...path,
- // points: {
- // ...path.points,
- // connections: {
- // ...path.points.connections,
- // targets: [...existingTargets, reverseTarget]
- // }
- // }
- // };
- // }
- // }
- // return path;
- // }
return path;
});
@@ -252,10 +334,10 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
path.modeluuid === fromModelUUID || path.modeluuid === toModelUUID
);
- updateBackend(updatedPathDetails);
+ // updateBackend(updatedPathDetails);
};
- const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]) => {
+ const updateBackend = async (updatedPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]) => {
if (updatedPaths.length === 0) return;
const email = localStorage.getItem("email");
const organization = email ? email.split("@")[1].split(".")[0] : "";
@@ -437,6 +519,69 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return;
}
+ // Check if StaticMachine is involved in the connection
+ if ((firstPath?.type === 'StaticMachine' && secondPath?.type !== 'ArmBot') ||
+ (secondPath?.type === 'StaticMachine' && firstPath?.type !== 'ArmBot')) {
+ console.log("StaticMachine can only connect to ArmBot");
+ return;
+ }
+
+ // Check if StaticMachine already has a connection
+ if (firstPath?.type === 'StaticMachine') {
+ const staticConnections = firstPath.points.connections.targets.length;
+ if (staticConnections >= 1) {
+ console.log("StaticMachine can only have one connection");
+ return;
+ }
+ }
+ if (secondPath?.type === 'StaticMachine') {
+ const staticConnections = secondPath.points.connections.targets.length;
+ if (staticConnections >= 1) {
+ console.log("StaticMachine can only have one connection");
+ return;
+ }
+ }
+
+ // Check if ArmBot is involved
+ if ((firstPath?.type === 'ArmBot' && secondPath?.type === 'StaticMachine') ||
+ (secondPath?.type === 'ArmBot' && firstPath?.type === 'StaticMachine')) {
+
+ const armBotPath = firstPath?.type === 'ArmBot' ? firstPath : secondPath;
+ const staticPath = firstPath?.type === 'StaticMachine' ? firstPath : secondPath;
+
+ const armBotConnections = armBotPath.points.connections.targets || [];
+ const alreadyConnectedToStatic = armBotConnections.some(target => {
+ const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
+ return targetPath?.type === 'StaticMachine';
+ });
+
+ if (alreadyConnectedToStatic) {
+ console.log("ArmBot can only connect to one StaticMachine");
+ return;
+ }
+
+ const staticConnections = staticPath.points.connections.targets.length;
+ if (staticConnections >= 1) {
+ console.log("StaticMachine can only have one connection");
+ return;
+ }
+ }
+
+ // Prevent ArmBot ↔ ArmBot
+ if (firstPath?.type === 'ArmBot' && secondPath?.type === 'ArmBot') {
+ console.log("Cannot connect two ArmBots together");
+ return;
+ }
+
+ // If one is ArmBot, ensure the other is StaticMachine or Conveyor
+ if (firstPath?.type === 'ArmBot' || secondPath?.type === 'ArmBot') {
+ const otherType = firstPath?.type === 'ArmBot' ? secondPath?.type : firstPath?.type;
+ if (otherType !== 'StaticMachine' && otherType !== 'Conveyor') {
+ console.log("ArmBot can only connect to Conveyors or one StaticMachine");
+ return;
+ }
+ }
+
// At least one must be start/end point
if (!firstSelected.isCorner && !isStartOrEnd) {
console.log("At least one of the selected spheres must be a start or end point.");
@@ -489,6 +634,15 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
};
}, [camera, scene, raycaster, firstSelected, simulationStates]);
+ useFrame(() => {
+ Object.values(groupRefs.current).forEach((group) => {
+ if (group) {
+ const distance = new THREE.Vector3(...group.position.toArray()).distanceTo(camera.position);
+ group.visible = ((distance <= renderDistance) && !isPlaying);
+ }
+ });
+ });
+
useFrame(() => {
if (firstSelected) {
raycaster.setFromCamera(pointer, camera);
@@ -574,12 +728,50 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
(firstPath?.type === 'Vehicle' && secondPath?.type !== 'Conveyor') ||
(secondPath?.type === 'Vehicle' && firstPath?.type !== 'Conveyor');
+ // Check if StaticMachine is connecting to non-ArmBot
+ const isStaticMachineToNonArmBot =
+ (firstPath?.type === 'StaticMachine' && secondPath?.type !== 'ArmBot') ||
+ (secondPath?.type === 'StaticMachine' && firstPath?.type !== 'ArmBot');
+
+ // Check if StaticMachine already has a connection
+ const isStaticMachineAtMaxConnections =
+ (firstPath?.type === 'StaticMachine' && firstPath.points.connections.targets.length >= 1) ||
+ (secondPath?.type === 'StaticMachine' && secondPath.points.connections.targets.length >= 1);
+
+ // Check if ArmBot is connecting to StaticMachine
+ const isArmBotToStaticMachine =
+ (firstPath?.type === 'ArmBot' && secondPath?.type === 'StaticMachine') ||
+ (secondPath?.type === 'ArmBot' && firstPath?.type === 'StaticMachine');
+
+ // Prevent multiple StaticMachine connections to ArmBot
+ let isArmBotAlreadyConnectedToStatic = false;
+ if (isArmBotToStaticMachine) {
+ const armBotPath = firstPath?.type === 'ArmBot' ? firstPath : secondPath;
+ isArmBotAlreadyConnectedToStatic = armBotPath.points.connections.targets.some(target => {
+ const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
+ return targetPath?.type === 'StaticMachine';
+ });
+ }
+
+ // Prevent ArmBot to ArmBot
+ const isArmBotToArmBot = firstPath?.type === 'ArmBot' && secondPath?.type === 'ArmBot';
+
+ // If ArmBot is involved, other must be Conveyor or StaticMachine
+ const isArmBotToInvalidType = (firstPath?.type === 'ArmBot' || secondPath?.type === 'ArmBot') &&
+ !(firstPath?.type === 'Conveyor' || firstPath?.type === 'StaticMachine' ||
+ secondPath?.type === 'Conveyor' || secondPath?.type === 'StaticMachine');
+
if (
!isDuplicateConnection &&
!isVehicleToVehicle &&
!isNonVehicleAlreadyConnected &&
!isVehicleAtMaxConnections &&
!isVehicleConnectingToNonConveyor &&
+ !isStaticMachineToNonArmBot &&
+ !isStaticMachineAtMaxConnections &&
+ !isArmBotToArmBot &&
+ !isArmBotToInvalidType &&
+ !isArmBotAlreadyConnectedToStatic &&
firstSelected.sphereUUID !== sphereUUID &&
firstSelected.modelUUID !== modelUUID &&
(firstSelected.isCorner || isConnectable) &&
@@ -596,6 +788,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
} else {
isInvalidConnection = true;
}
+
}
if (snappedSphere) {
@@ -633,7 +826,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
});
return (
-
+
{simulationStates.flatMap(path => {
if (path.type === 'Conveyor') {
return path.points.flatMap(point =>
@@ -652,7 +845,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
const distance = fromWorldPosition.distanceTo(toWorldPosition);
const heightFactor = Math.max(0.5, distance * 0.2);
-
const midPoint = new THREE.Vector3(
(fromWorldPosition.x + toWorldPosition.x) / 2,
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
@@ -662,6 +854,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return (
(groupRefs.current[`${point.uuid}-${target.pointUUID}-${index}`] = el!)}
start={fromWorldPosition.toArray()}
end={toWorldPosition.toArray()}
mid={midPoint.toArray()}
@@ -676,7 +869,9 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return null;
})
);
- } else if (path.type === 'Vehicle') {
+ }
+
+ if (path.type === 'Vehicle') {
return path.points.connections.targets.map((target, index) => {
const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.points.uuid);
const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
@@ -689,7 +884,6 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
const distance = fromWorldPosition.distanceTo(toWorldPosition);
const heightFactor = Math.max(0.5, distance * 0.2);
-
const midPoint = new THREE.Vector3(
(fromWorldPosition.x + toWorldPosition.x) / 2,
Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
@@ -699,6 +893,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return (
(groupRefs.current[`${path.points.uuid}-${target.pointUUID}-${index}`] = el!)}
start={fromWorldPosition.toArray()}
end={toWorldPosition.toArray()}
mid={midPoint.toArray()}
@@ -713,6 +908,48 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
return null;
});
}
+
+ if (path.type === 'StaticMachine') {
+ return path.points.connections.targets.map((target, index) => {
+ const targetPath = simulationStates.find(p => p.modeluuid === target.modelUUID);
+ if (targetPath?.type !== 'ArmBot') return null;
+
+ const fromSphere = pathsGroupRef.current?.getObjectByProperty('uuid', path.points.uuid);
+ const toSphere = pathsGroupRef.current?.getObjectByProperty('uuid', target.pointUUID);
+
+ if (fromSphere && toSphere) {
+ const fromWorldPosition = new THREE.Vector3();
+ const toWorldPosition = new THREE.Vector3();
+ fromSphere.getWorldPosition(fromWorldPosition);
+ toSphere.getWorldPosition(toWorldPosition);
+
+ const distance = fromWorldPosition.distanceTo(toWorldPosition);
+ const heightFactor = Math.max(0.5, distance * 0.2);
+ const midPoint = new THREE.Vector3(
+ (fromWorldPosition.x + toWorldPosition.x) / 2,
+ Math.max(fromWorldPosition.y, toWorldPosition.y) + heightFactor,
+ (fromWorldPosition.z + toWorldPosition.z) / 2
+ );
+
+ return (
+ (groupRefs.current[`${path.points.uuid}-${target.pointUUID}-${index}`] = el!)}
+ start={fromWorldPosition.toArray()}
+ end={toWorldPosition.toArray()}
+ mid={midPoint.toArray()}
+ color="#42a5f5"
+ lineWidth={4}
+ dashed
+ dashSize={0.75}
+ dashScale={20}
+ />
+ );
+ }
+ return null;
+ });
+ }
+
return [];
})}
@@ -730,6 +967,7 @@ function PathConnector({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObjec
)}
);
+
}
export default PathConnector;
\ No newline at end of file
diff --git a/app/src/modules/simulation/path/pathCreation.tsx b/app/src/modules/simulation/path/pathCreation.tsx
index 62bb79e..839cf39 100644
--- a/app/src/modules/simulation/path/pathCreation.tsx
+++ b/app/src/modules/simulation/path/pathCreation.tsx
@@ -206,6 +206,7 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
return (
(groupRefs.current[path.modeluuid] = el!)}
position={path.position}
@@ -271,10 +272,11 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
})}
);
- } else if (path.type === "Vehicle" || path.type === "StaticMachine") {
+ } else if (path.type === "Vehicle") {
return (
(groupRefs.current[path.modeluuid] = el!)}
position={path.position}
@@ -323,6 +325,114 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
);
+ } else if (path.type === "StaticMachine") {
+ return (
+ (groupRefs.current[path.modeluuid] = el!)}
+ position={path.position}
+ rotation={path.rotation}
+ onClick={(e) => {
+ if (isConnecting || eyeDropMode) return;
+ e.stopPropagation();
+ setSelectedPath({
+ path,
+ group: groupRefs.current[path.modeluuid],
+ });
+ setSelectedActionSphere(null);
+ setTransformMode(null);
+ setSubModule("mechanics");
+ }}
+ onPointerMissed={() => {
+ if (eyeDropMode) return;
+ setSelectedPath(null);
+ setSubModule("properties");
+ }}
+ >
+ (sphereRefs.current[path.points.uuid] = el!)}
+ onClick={(e) => {
+ if (isConnecting || eyeDropMode) return;
+ e.stopPropagation();
+ setSelectedActionSphere({
+ path,
+ points: sphereRefs.current[path.points.uuid],
+ });
+ setSubModule("mechanics");
+ setSelectedPath(null);
+ }}
+ userData={{ points: path.points, path }}
+ onPointerMissed={() => {
+ if (eyeDropMode) return;
+ setSubModule("properties");
+ setSelectedActionSphere(null);
+ }}
+ >
+
+
+
+ );
+ } else if (path.type === "ArmBot") {
+ return (
+ (groupRefs.current[path.modeluuid] = el!)}
+ position={path.position}
+ rotation={path.rotation}
+ onClick={(e) => {
+ if (isConnecting || eyeDropMode) return;
+ e.stopPropagation();
+ setSelectedPath({
+ path,
+ group: groupRefs.current[path.modeluuid],
+ });
+ setSelectedActionSphere(null);
+ setTransformMode(null);
+ setSubModule("mechanics");
+ }}
+ onPointerMissed={() => {
+ if (eyeDropMode) return;
+ setSelectedPath(null);
+ setSubModule("properties");
+ }}
+ >
+ (sphereRefs.current[path.points.uuid] = el!)}
+ onClick={(e) => {
+ if (isConnecting || eyeDropMode) return;
+ e.stopPropagation();
+ setSelectedActionSphere({
+ path,
+ points: sphereRefs.current[path.points.uuid],
+ });
+ setSubModule("mechanics");
+ setSelectedPath(null);
+ }}
+ userData={{ points: path.points, path }}
+ onPointerMissed={() => {
+ if (eyeDropMode) return;
+ setSubModule("properties");
+ setSelectedActionSphere(null);
+ }}
+ >
+
+
+
+ );
}
return null;
})}
diff --git a/app/src/modules/visualization/handleSaveTemplate.ts b/app/src/modules/visualization/handleSaveTemplate.ts
index e5f90ab..f192bec 100644
--- a/app/src/modules/visualization/handleSaveTemplate.ts
+++ b/app/src/modules/visualization/handleSaveTemplate.ts
@@ -64,7 +64,8 @@ export const handleSaveTemplate = async ({
floatingWidget,
widgets3D,
};
-
+
+ console.log('newTemplate: ', newTemplate);
// Extract organization from email
const email = localStorage.getItem("email") || "";
const organization = email.includes("@")
diff --git a/app/src/pages/Project.tsx b/app/src/pages/Project.tsx
index 88fd467..54fe61f 100644
--- a/app/src/pages/Project.tsx
+++ b/app/src/pages/Project.tsx
@@ -56,7 +56,7 @@ const Project: React.FC = () => {
return (
- {/* {loadingProgress &&
} */}
+ {loadingProgress &&
}
{!isPlaying && (
<>
{toggleThreeD &&
}
diff --git a/app/src/services/factoryBuilder/zones/deleteZoneApi.ts b/app/src/services/factoryBuilder/zones/deleteZoneApi.ts
index fbe4a83..2537fb6 100644
--- a/app/src/services/factoryBuilder/zones/deleteZoneApi.ts
+++ b/app/src/services/factoryBuilder/zones/deleteZoneApi.ts
@@ -15,7 +15,7 @@ export const deleteZonesApi = async (userId: string, organization: string, zoneI
}
const result = await response.json();
- console.log('result: ', result);
+
return result;
} catch (error) {
if (error instanceof Error) {
diff --git a/app/src/services/realTimeVisulization/zoneData/getZones.ts b/app/src/services/realTimeVisulization/zoneData/getZones.ts
index 8dbf79a..b189050 100644
--- a/app/src/services/realTimeVisulization/zoneData/getZones.ts
+++ b/app/src/services/realTimeVisulization/zoneData/getZones.ts
@@ -2,8 +2,7 @@ let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_UR
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const getZoneData = async (zoneId: string, organization: string) => {
- console.log("organization: ", organization);
- console.log("zoneId: ", zoneId);
+
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v2/A_zone/${zoneId}/${organization}`,
diff --git a/app/src/store/store.ts b/app/src/store/store.ts
index 725180b..89cd1a7 100644
--- a/app/src/store/store.ts
+++ b/app/src/store/store.ts
@@ -347,12 +347,12 @@ export const useSelectedPath = create
((set: any) => ({
}));
interface SimulationPathsStore {
- simulationStates: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[];
+ simulationStates: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[];
setSimulationStates: (
paths:
- | (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]
- | ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[]
- ) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema)[])
+ | (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]
+ | ((prev: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[]
+ ) => (Types.ConveyorEventsSchema | Types.VehicleEventsSchema | Types.StaticMachineEventsSchema | Types.ArmBotEventsSchema)[])
) => void;
}
diff --git a/app/src/styles/layout/sidebar.scss b/app/src/styles/layout/sidebar.scss
index 465af2c..3b14aac 100644
--- a/app/src/styles/layout/sidebar.scss
+++ b/app/src/styles/layout/sidebar.scss
@@ -70,6 +70,67 @@
position: relative;
overflow: auto;
+ .template-list {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ padding: 1rem;
+ min-height: 50vh;
+ max-height: 60vh;
+ }
+
+ .template-item {
+ border: 1px solid #e0e0e0;
+ border-radius: 8px;
+ padding: 1rem;
+ transition: box-shadow 0.3s ease;
+ }
+
+ .template-image-container {
+ position: relative;
+ padding-bottom: 56.25%; // 16:9 aspect ratio
+ }
+
+ .template-image {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: transform 0.3s ease;
+ }
+
+ .template-details {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 0.5rem;
+ }
+
+ .template-name {
+ cursor: pointer;
+ font-weight: 500;
+ }
+
+ .delete-button {
+ padding: 0.25rem 0.5rem;
+ background: #ff4444;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: opacity 0.3s ease;
+ }
+
+ .no-templates {
+ text-align: center;
+ color: #666;
+ padding: 2rem;
+ grid-column: 1 / -1;
+ }
+
+
.widget-left-sideBar {
min-height: 50vh;
max-height: 60vh;
diff --git a/app/src/styles/pages/realTimeViz.scss b/app/src/styles/pages/realTimeViz.scss
index f26ac06..cc3f791 100644
--- a/app/src/styles/pages/realTimeViz.scss
+++ b/app/src/styles/pages/realTimeViz.scss
@@ -24,9 +24,17 @@
}
.floating {
- width: 100%;
- max-width: 250px;
- min-height: 83px;
+
+
+ width: calc(var(--realTimeViz-container-width) * 0.2);
+ height: calc(var(--realTimeViz-container-width) * 0.05);
+
+ min-width: 250px;
+ max-width: 300px;
+
+ min-height: 83px !important;
+ // max-height: 100px !important;
+
background: var(--background-color);
border: 1.23px solid var(--border-color);
box-shadow: 0px 4.91px 4.91px 0px #0000001c;
@@ -60,9 +68,8 @@
display: flex;
background-color: var(--background-color);
position: absolute;
- bottom: 10px;
+ // bottom: 10px;
left: 50%;
- transform: translate(-50%, 0);
gap: 6px;
border-radius: 8px;
@@ -70,6 +77,7 @@
overflow: auto;
max-width: calc(100% - 500px);
z-index: 3;
+ transform: translate(-50%, -100%);
&::-webkit-scrollbar {
display: none;
@@ -116,8 +124,8 @@
}
.zone-wrapper.bottom {
- bottom: calc(var(--realTimeViz-container-height) * 0.27);
- bottom: 200px;
+ top: var(--bottomWidth);
+ // bottom: 200px;
}
.content-container {
@@ -138,7 +146,7 @@
display: flex;
background-color: rgba(224, 223, 255, 0.5);
position: absolute;
- bottom: 10px;
+ // bottom: 10px;
left: 50%;
transform: translate(-50%, 0);
gap: 6px;
@@ -203,9 +211,9 @@
.chart-container {
width: 100%;
- min-height: 150px;
+
max-height: 100%;
- // border: 1px dashed var(--background-color-gray);
+ border: 1px dashed var(--background-color-gray);
border-radius: 8px;
box-shadow: var(--box-shadow-medium);
padding: 6px 0;
@@ -306,7 +314,6 @@
min-height: 150px;
.chart-container {
-
min-width: 160px;
}
}
@@ -324,14 +331,12 @@
left: 0;
top: 0;
bottom: 0;
-
-
}
&.right-panel {
right: 0;
top: 0;
- bottom: 0
+ bottom: 0;
}
&.left-panel,
@@ -342,12 +347,11 @@
flex-direction: column;
width: 100%;
-
gap: 6px;
.chart-container {
width: 100%;
- min-height: 160px;
+ min-height: 150px;
max-height: 100%;
border-radius: 8px;
box-shadow: var(--box-shadow-medium);
@@ -355,8 +359,6 @@
background-color: var(--background-color);
position: relative;
}
-
-
}
}
}
@@ -368,8 +370,8 @@
.playingFlase {
.zone-wrapper.bottom {
- bottom: calc(var(--realTimeViz-container-height) * 0.3);
- bottom: 210px;
+ top: var(--bottomWidth);
+ // bottom: 210px;
}
}
@@ -658,9 +660,6 @@
}
}
}
-
-
-
}
}
@@ -756,14 +755,13 @@
}
.connectionSuccess {
- outline-color: #43C06D;
+ outline-color: #43c06d;
}
.connectionFails {
outline-color: #ffe3e0;
}
-
.editWidgetOptions {
position: absolute;
// top: 50%;
diff --git a/app/src/types/world/worldTypes.d.ts b/app/src/types/world/worldTypes.d.ts
index 7baf5e0..fce09b1 100644
--- a/app/src/types/world/worldTypes.d.ts
+++ b/app/src/types/world/worldTypes.d.ts
@@ -329,6 +329,7 @@ interface StaticMachineEventsSchema {
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
};
position: [number, number, number];
+ rotation: [number, number, number];
}
interface ArmBotEventsSchema {
@@ -343,6 +344,7 @@ interface ArmBotEventsSchema {
connections: { source: { modelUUID: string; pointUUID: string }; targets: { modelUUID: string; pointUUID: string }[] };
};
position: [number, number, number];
+ rotation: [number, number, number];
}
export type EventData = {
diff --git a/app/src/utils/outerClick.ts b/app/src/utils/outerClick.ts
index de8f7ef..280b3f0 100644
--- a/app/src/utils/outerClick.ts
+++ b/app/src/utils/outerClick.ts
@@ -1,7 +1,7 @@
import React from "react";
interface OuterClickProps {
- contextClassName: string;
+ contextClassName: string[]; // Make sure this is an array of strings
setMenuVisible: React.Dispatch>;
}
@@ -11,8 +11,12 @@ export default function OuterClick({
}: OuterClickProps) {
const handleClick = (event: MouseEvent) => {
const targets = event.target as HTMLElement;
- // Check if the click is outside the selectable-dropdown-wrapper
- if (!targets.closest(`.${contextClassName}`)) {
+ // Check if the click is outside of any of the provided class names
+ const isOutside = contextClassName.every(
+ (className) => !targets.closest(`.${className}`)
+ );
+
+ if (isOutside) {
setMenuVisible(false); // Close the menu by updating the state
}
};
@@ -23,7 +27,7 @@ export default function OuterClick({
return () => {
document.removeEventListener("click", handleClick);
};
- }, []);
+ }, [contextClassName]); // Add contextClassName to dependency array to handle any changes
return null; // This component doesn't render anything
}