diff --git a/app/package-lock.json b/app/package-lock.json
index f627d25..9a7d772 100644
--- a/app/package-lock.json
+++ b/app/package-lock.json
@@ -2018,7 +2018,7 @@
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
+ "devOptional": true,
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
@@ -2030,7 +2030,7 @@
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
+ "devOptional": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -4133,6 +4133,26 @@
"url": "https://github.com/sponsors/gregberge"
}
},
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
+ "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "chalk": "^4.1.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@testing-library/jest-dom": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
@@ -4244,25 +4264,25 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
- "dev": true
+ "devOptional": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true
+ "devOptional": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true
+ "devOptional": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
- "dev": true
+ "devOptional": true
},
"node_modules/@turf/along": {
"version": "7.2.0",
@@ -8987,7 +9007,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true
+ "devOptional": true
},
"node_modules/cross-env": {
"version": "7.0.3",
@@ -9855,7 +9875,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
+ "devOptional": true,
"engines": {
"node": ">=0.3.1"
}
@@ -15205,7 +15225,7 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
+ "devOptional": true
},
"node_modules/makeerror": {
"version": "1.0.12",
@@ -20664,7 +20684,7 @@
"version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
- "dev": true,
+ "devOptional": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -20707,7 +20727,7 @@
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
+ "devOptional": true,
"dependencies": {
"acorn": "^8.11.0"
},
@@ -20719,7 +20739,7 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true
+ "devOptional": true
},
"node_modules/tsconfig-paths": {
"version": "3.15.0",
@@ -21206,7 +21226,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true
+ "devOptional": true
},
"node_modules/v8-to-istanbul": {
"version": "8.1.1",
@@ -22265,7 +22285,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true,
+ "devOptional": true,
"engines": {
"node": ">=6"
}
diff --git a/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets.tsx b/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets.tsx
index 15bc313..d4a64ae 100644
--- a/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets.tsx
+++ b/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets.tsx
@@ -3,24 +3,26 @@ import ToggleHeader from "../../../../ui/inputs/ToggleHeader";
import Widgets2D from "./Widgets2D";
import Widgets3D from "./Widgets3D";
import WidgetsFloating from "./WidgetsFloating";
+import { useWidgetSubOption } from "../../../../../store/store";
const Widgets = () => {
const [activeOption, setActiveOption] = useState("2D");
+ const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
const handleToggleClick = (option: string) => {
- setActiveOption(option);
+ setWidgetSubOption(option);
};
return (
- {activeOption === "2D" && }
- {activeOption === "3D" && }
- {activeOption === "Floating" && }
+ {widgetSubOption === "2D" && }
+ {widgetSubOption === "3D" && }
+ {widgetSubOption === "Floating" && }
);
};
diff --git a/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets3D.tsx b/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets3D.tsx
index 849c051..6872497 100644
--- a/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets3D.tsx
+++ b/app/src/components/layout/sidebarLeft/visualization/widgets/Widgets3D.tsx
@@ -24,9 +24,8 @@ const Widgets3D = () => {
let crt = e.target
if (crt instanceof HTMLElement) {
const widget = crt.cloneNode(true) as HTMLElement;
- console.log('widget: ', widget);
- e.dataTransfer.setDragImage(widget,0,0)
- e.dataTransfer.effectAllowed="move"
+ e.dataTransfer.setDragImage(widget, 0, 0)
+ e.dataTransfer.effectAllowed = "move"
}
}}
onPointerDown={() => {
@@ -41,7 +40,7 @@ const Widgets3D = () => {
className="widget-image"
src={widget.img}
alt={widget.name}
- // draggable={false}
+ // draggable={false}
/>
))}
diff --git a/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx b/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
index c707f14..9234cc5 100644
--- a/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
@@ -3,6 +3,7 @@ import RenameInput from "../../../ui/inputs/RenameInput";
import Vector3Input from "../customInput/Vector3Input";
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
import { useEditPosition, usezonePosition, usezoneTarget } from "../../../../store/store";
+import { zoneCameraUpdate } from "../../../../services/realTimeVisulization/zoneData/zoneCameraUpdation";
const ZoneProperties: React.FC = () => {
const { Edit, setEdit } = useEditPosition();
@@ -15,12 +16,25 @@ const ZoneProperties: React.FC = () => {
setZoneTarget(selectedZone.zoneViewPortTarget)
}, [selectedZone?.zoneViewPortPosition, selectedZone?.zoneViewPortTarget])
- function handleSetView() {
- console.log("setApi");
-
- console.log('zoneTarget: ', zoneTarget);
- console.log('zonePosition: ', zonePosition);
- setEdit(false);
+ async function handleSetView() {
+ try {
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
+
+ let zonesdata = {
+ zoneId: selectedZone.zoneId,
+ viewPortposition: zonePosition,
+ viewPortCenter: zoneTarget
+ };
+
+ let response = await zoneCameraUpdate(zonesdata, organization);
+ console.log('response: ', response);
+
+
+ setEdit(false);
+ } catch (error) {
+ console.error("Error in handleSetView:", error);
+ }
}
function handleEditView() {
@@ -36,7 +50,7 @@ const ZoneProperties: React.FC = () => {
}
useEffect(() => {
- console.log("Updated selectedZone: ", selectedZone);
+
}, [selectedZone]);
return (
diff --git a/app/src/components/ui/ModuleToggle.tsx b/app/src/components/ui/ModuleToggle.tsx
index b81ddf8..b7421af 100644
--- a/app/src/components/ui/ModuleToggle.tsx
+++ b/app/src/components/ui/ModuleToggle.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useEffect } from "react";
import useModuleStore from "../../store/useModuleStore";
import {
BuilderIcon,
@@ -7,11 +7,13 @@ import {
VisualizationIcon,
} from "../icons/ExportModuleIcons";
import useToggleStore from "../../store/useUIToggleStore";
+import { useSelectedZoneStore } from "../../store/useZoneStore";
const ModuleToggle: React.FC = () => {
const { activeModule, setActiveModule } = useModuleStore();
const { setToggleUI } = useToggleStore();
+
return (
= ({
};
// Delete the selectedZone state
- console.log("updatedZone: ", updatedZone);
+
setSelectedZone(updatedZone);
} else {
const updatePanelData = async () => {
@@ -141,13 +141,13 @@ const AddButtons: React.FC
= ({
// API call
const response = await panelData(organization, selectedZone.zoneId, newActiveSides);
- console.log("response: ", response);
+
// Update state
- console.log("updatedZone: ", updatedZone);
+
setSelectedZone(updatedZone);
} catch (error) {
- console.error("Error updating panel data:", error);
+
}
};
diff --git a/app/src/components/ui/componets/DisplayZone.tsx b/app/src/components/ui/componets/DisplayZone.tsx
index a321836..7689e51 100644
--- a/app/src/components/ui/componets/DisplayZone.tsx
+++ b/app/src/components/ui/componets/DisplayZone.tsx
@@ -4,6 +4,7 @@ import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
import { InfoIcon } from "../../icons/ExportCommonIcons";
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
import { getSelect2dZoneData } from "../../../services/realTimeVisulization/zoneData/getSelect2dZoneData";
+import { getFloatingZoneData } from "../../../services/realTimeVisulization/zoneData/getFloatingData";
// Define the type for `Side`
type Side = "top" | "bottom" | "left" | "right";
@@ -147,23 +148,41 @@ const DisplayZone: React.FC = ({
};
async function handleSelect2dZoneData(zoneId: string, zoneName: string) {
- const email = localStorage.getItem("email") || "";
- const organization = email?.split("@")[1]?.split(".")[0]
- let response = await getSelect2dZoneData(zoneId, organization)
- setSelectedZone({
- zoneName,
- activeSides: response.activeSides,
- panelOrder: response.panelOrder,
- lockedPanels: response.lockedPanels,
- widgets: response.widgets,
- zoneId: zoneId,
- zoneViewPortTarget:
- response.viewPortCenter,
- zoneViewPortPosition:
- response.viewPortposition,
- });
+ try {
+ if (selectedZone?.zoneId === zoneId) {
+ console.log("Zone is already selected:", zoneName);
+ return;
+ }
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
+ // Fetch data from backend
+ let response = await getSelect2dZoneData(zoneId, organization);
+ let res = await getFloatingZoneData(zoneId, organization);
+ // Set the selected zone in the store
+ useDroppedObjectsStore.getState().setZone(zoneName, zoneId);
+ if (Array.isArray(res)) {
+ res.forEach((val) => {
+ useDroppedObjectsStore.getState().addObject(zoneName, val);
+ });
+ }
+ // Update selected zone state
+ setSelectedZone({
+ zoneName,
+ activeSides: response.activeSides || [],
+ panelOrder: response.panelOrder || [],
+ lockedPanels: response.lockedPanels || [],
+ widgets: response.widgets || [],
+ zoneId: zoneId,
+ zoneViewPortTarget: response.viewPortCenter || {},
+ zoneViewPortPosition: response.viewPortposition || {},
+ });
+ } catch (error) {
+ console.log('error: ', error);
+
+ }
}
+
return (
= ({
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
}`}
onClick={() => {
- useDroppedObjectsStore.getState().setZone(zoneName, zonesData[zoneName]?.zoneId);
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
}}
>
diff --git a/app/src/components/ui/componets/DraggableWidget.tsx b/app/src/components/ui/componets/DraggableWidget.tsx
index 9c17c03..14916b0 100644
--- a/app/src/components/ui/componets/DraggableWidget.tsx
+++ b/app/src/components/ui/componets/DraggableWidget.tsx
@@ -11,6 +11,8 @@ import {
KebabIcon,
} from "../../icons/ExportCommonIcons";
import { useEffect, useRef, useState } from "react";
+import { duplicateWidgetApi } from "../../../services/realTimeVisulization/zoneData/duplicateWidget";
+import { deleteWidgetApi } from "../../../services/realTimeVisulization/zoneData/deleteWidgetApi";
type Side = "top" | "bottom" | "left" | "right";
@@ -34,9 +36,9 @@ export const DraggableWidget = ({
}: {
selectedZone: {
zoneName: string;
+ zoneId: string;
activeSides: Side[];
panelOrder: Side[];
-
lockedPanels: Side[];
widgets: Widget[];
};
@@ -79,21 +81,28 @@ export const DraggableWidget = ({
const isPanelHidden = hiddenPanels.includes(widget.panel);
- const deleteSelectedChart = () => {
- console.log('widget.id: ', widget.id);
- const updatedWidgets = selectedZone.widgets.filter(
- (w: Widget) => w.id !== widget.id
- );
- console.log('updatedWidgets: ', updatedWidgets);
+ const deleteSelectedChart = async () => {
+ try {
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
+ const response = await deleteWidgetApi(widget.id, organization);
+ if (response?.message === "Widget deleted successfully") {
+ const updatedWidgets = selectedZone.widgets.filter(
+ (w: Widget) => w.id !== widget.id
+ );
+ setSelectedZone((prevZone: any) => ({
+ ...prevZone,
+ widgets: updatedWidgets,
+ }));
+ }
+ } catch (error) {
- setSelectedZone((prevZone: any) => ({
- ...prevZone,
- widgets: updatedWidgets,
- }));
-
- setOpenKebabId(null);
+ } finally {
+ setOpenKebabId(null);
+ }
};
+
const getCurrentWidgetCount = (panel: Side) =>
selectedZone.widgets.filter((w) => w.panel === panel).length;
@@ -121,21 +130,32 @@ export const DraggableWidget = ({
return currentWidgetCount >= panelCapacity;
};
- const duplicateWidget = () => {
- const duplicatedWidget: Widget = {
- ...widget,
- id: `${widget.id}-copy-${Date.now()}`,
- };
- setSelectedZone((prevZone: any) => ({
- ...prevZone,
- widgets: [...prevZone.widgets, duplicatedWidget],
- }));
+ const duplicateWidget = async () => {
+ try {
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
- setOpenKebabId(null);
+ const duplicatedWidget: Widget = {
+ ...widget,
+ id: `${widget.id}-copy-${Date.now()}`,
+ };
+ const response = await duplicateWidgetApi(selectedZone.zoneId, organization, duplicatedWidget);
+ if (response?.message === "Widget created successfully") {
+ setSelectedZone((prevZone: any) => ({
+ ...prevZone,
+ widgets: [...prevZone.widgets, duplicatedWidget],
+ }));
+ }
+ } catch (error) {
+
+ } finally {
+ setOpenKebabId(null);
+ }
};
+
const handleKebabClick = (event: React.MouseEvent
) => {
event.stopPropagation();
if (openKebabId === widget.id) {
@@ -176,7 +196,6 @@ export const DraggableWidget = ({
};
const handleDrop = (event: React.DragEvent) => {
-
event.preventDefault();
const fromIndex = parseInt(event.dataTransfer.getData("text/plain"), 10); // Get the dragged widget's index
const toIndex = index; // The index of the widget where the drop occurred
diff --git a/app/src/components/ui/componets/Dropped3dWidget.tsx b/app/src/components/ui/componets/Dropped3dWidget.tsx
index e0e2a7d..10dd343 100644
--- a/app/src/components/ui/componets/Dropped3dWidget.tsx
+++ b/app/src/components/ui/componets/Dropped3dWidget.tsx
@@ -1,7 +1,7 @@
import { useThree } from "@react-three/fiber";
import React, { useState, useEffect } from "react";
-import { useAsset3dWidget } from "../../../store/store";
+import { useAsset3dWidget, useWidgetSubOption } from "../../../store/store";
import useModuleStore from "../../../store/useModuleStore";
import { ThreeState } from "../../../types/world/worldTypes";
import * as THREE from "three";
@@ -9,71 +9,80 @@ import Throughput from "../../layout/3D-cards/cards/Throughput";
import ProductionCapacity from "../../layout/3D-cards/cards/ProductionCapacity";
import ReturnOfInvestment from "../../layout/3D-cards/cards/ReturnOfInvestment";
import StateWorking from "../../layout/3D-cards/cards/StateWorking";
+import { useSelectedZoneStore } from "../../../store/useZoneStore";
export default function Dropped3dWidgets() {
- const { widgetSelect } = useAsset3dWidget();
+ const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
const { activeModule } = useModuleStore();
const { raycaster, gl, scene }: ThreeState = useThree();
+ const { selectedZone } = useSelectedZoneStore(); // Get currently selected zone
+ const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption()
+ // π₯ Store widget positions per zone
+ const [zoneWidgets, setZoneWidgets] = useState // Widget type -> Positions array
+ >>({});
- // π₯ Store multiple instances per widget type
- const [widgetPositions, setWidgetPositions] = useState>({});
useEffect(() => {
- if (activeModule !== "visualization") return;
+ if (widgetSubOption === "Floating") return
+ // if (activeModule !== "visualization") return;
const canvasElement = gl.domElement;
-
const onDrop = (event: DragEvent) => {
event.preventDefault(); // Prevent default browser behavior
+ if (widgetSubOption === "3D") {
+ if (selectedZone.zoneName === "") return
+ if (!widgetSelect?.startsWith("ui")) return;
+ const group1 = scene.getObjectByName("itemsGroup");
+ if (!group1) return;
+ const Assets = group1.children
+ .map((val) => scene.getObjectByProperty("uuid", val.uuid))
+ .filter(Boolean) as THREE.Object3D[];
+ const intersects = raycaster.intersectObjects(scene.children, true).filter(
+ (intersect) =>
+ !intersect.object.name.includes("Roof") &&
+ !intersect.object.name.includes("agv-collider") &&
+ !intersect.object.name.includes("MeasurementReference") &&
+ !intersect.object.userData.isPathObject &&
+ !(intersect.object.type === "GridHelper")
+ );
+ if (intersects.length > 0) {
+ const { x, y, z } = intersects[0].point;
- if (!widgetSelect.startsWith("ui")) return;
-
-
- const group1 = scene.getObjectByName("itemsGroup");
- if (!group1) return;
-
-
-
- const Assets = group1.children
- .map((val) => scene.getObjectByProperty("uuid", val.uuid))
- .filter(Boolean) as THREE.Object3D[];
-
-
- const intersects = raycaster.intersectObjects(Assets);
-
- if (intersects.length > 0) {
- const { x, y, z } = intersects[0].point;
-
-
- // β
Allow multiple instances by storing positions in an array
- setWidgetPositions((prev) => ({
- ...prev,
- [widgetSelect]: [...(prev[widgetSelect] || []), [x, y, z]],
- }));
+ setZoneWidgets((prev) => ({
+ ...prev,
+ [selectedZone.zoneId]: {
+ ...(prev[selectedZone.zoneId] || {}),
+ [widgetSelect]: [...(prev[selectedZone.zoneId]?.[widgetSelect] || []), [x, y, z]],
+ },
+ }));
+ }
}
};
canvasElement.addEventListener("drop", onDrop);
-
return () => {
- canvasElement.removeEventListener("drop", onDrop);
+ canvasElement.removeEventListener("drop", onDrop)
+ // setWidgetSelect()
};
- }, [widgetSelect, activeModule]);
+ }, [widgetSelect, activeModule, widgetSubOption]);
return (
<>
- {widgetPositions["ui-Widget 1"]?.map((pos, index) => (
+ {zoneWidgets[selectedZone.zoneId]?.["ui-Widget 1"]?.map((pos, index) => (
))}
- {widgetPositions["ui-Widget 2"]?.map((pos, index) => (
+ {zoneWidgets[selectedZone.zoneId]?.["ui-Widget 2"]?.map((pos, index) => (
))}
- {widgetPositions["ui-Widget 3"]?.map((pos, index) => (
+ {zoneWidgets[selectedZone.zoneId]?.["ui-Widget 3"]?.map((pos, index) => (
))}
- {widgetPositions["ui-Widget 4"]?.map((pos, index) => (
+ {zoneWidgets[selectedZone.zoneId]?.["ui-Widget 4"]?.map((pos, index) => (
))}
>
);
}
+
diff --git a/app/src/components/ui/componets/DroppedFloatingWidgets.tsx b/app/src/components/ui/componets/DroppedFloatingWidgets.tsx
index ffddc23..bf19bb9 100644
--- a/app/src/components/ui/componets/DroppedFloatingWidgets.tsx
+++ b/app/src/components/ui/componets/DroppedFloatingWidgets.tsx
@@ -1,59 +1,79 @@
-
-
-
import { WalletIcon } from "../../icons/3dChartIcons";
import { useEffect, useRef, useState } from "react";
import { Line } from "react-chartjs-2";
-import { useDroppedObjectsStore, Zones } from "../../../store/useDroppedObjectsStore";
+import {
+ useDroppedObjectsStore,
+ Zones,
+} from "../../../store/useDroppedObjectsStore";
+import useModuleStore from "../../../store/useModuleStore";
+import { determinePosition } from "./functions/determinePosition";
+import { getActiveProperties } from "./functions/getActiveProperties";
+import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
const DroppedObjects: React.FC = () => {
const zones = useDroppedObjectsStore((state) => state.zones);
- const updateObjectPosition = useDroppedObjectsStore((state) => state.updateObjectPosition);
- const [draggingIndex, setDraggingIndex] = useState<{ zone: string; index: number } | null>(null);
+
+ const updateObjectPosition = useDroppedObjectsStore(
+ (state) => state.updateObjectPosition
+ );
+ const [draggingIndex, setDraggingIndex] = useState<{
+ zone: string;
+ index: number;
+ } | null>(null);
const [offset, setOffset] = useState<[number, number] | null>(null);
const positionRef = useRef<[number, number] | null>(null);
const animationRef = useRef(null);
+ const { activeModule } = useModuleStore();
- // useEffect(() => {
- // const initialZones: Record = {
- // "Zone 1": {
- // zoneName: "Zone 1",
- // zoneId: "2e996073-546c-470c-8323-55bd3700c6aa",
- // objects: [
- // {
- // header: "Todayβs Money",
- // value: 53000, // β
Converted to number
- // per: "+55%",
- // className: "floating total-card",
- // position: [146, 214], // β
No need for 'as' here
- // },
- // {
- // header: "New Clients",
- // value: 250, // β
Converted to number
- // per: "+12%",
- // className: "floating total-card",
- // position: [344, 295],
- // },
- // ],
- // },
- // };
-
- // useDroppedObjectsStore.setState({ zones: initialZones });
- // }, []);
-
+ // Get the first zone and its objects
const zoneEntries = Object.entries(zones);
if (zoneEntries.length === 0) return null; // No zone, nothing to render
const [zoneName, zone] = zoneEntries[0]; // Only render the first zone
+ // Handle pointer down event
function handlePointerDown(event: React.PointerEvent, index: number) {
const obj = zone.objects[index];
- const offsetX = event.clientX - obj.position[1];
- const offsetY = event.clientY - obj.position[0];
+ const container = document.getElementById("real-time-vis-canvas");
+ if (!container) return;
+
+ const rect = container.getBoundingClientRect();
+ const relativeX = event.clientX - rect.left;
+ const relativeY = event.clientY - rect.top;
+
+ // Determine which properties are active for this object
+ const [activeProp1, activeProp2] = getActiveProperties(obj.position);
+
+ // Calculate the offset based on the active properties
+ let offsetX = 0;
+ let offsetY = 0;
+
+ if (activeProp1 === "top") {
+ offsetY =
+ relativeY -
+ (typeof obj.position.top === "number" ? obj.position.top : 0);
+ } else if (activeProp1 === "bottom") {
+ offsetY =
+ rect.height -
+ relativeY -
+ (typeof obj.position.bottom === "number" ? obj.position.bottom : 0);
+ }
+
+ if (activeProp2 === "left") {
+ offsetX =
+ relativeX -
+ (typeof obj.position.left === "number" ? obj.position.left : 0);
+ } else if (activeProp2 === "right") {
+ offsetX =
+ rect.width -
+ relativeX -
+ (typeof obj.position.right === "number" ? obj.position.right : 0);
+ }
setDraggingIndex({ zone: zoneName, index });
setOffset([offsetY, offsetX]);
}
+ // Handle pointer move event
function handlePointerMove(event: React.PointerEvent) {
if (!draggingIndex || !offset) return;
@@ -61,34 +81,92 @@ const DroppedObjects: React.FC = () => {
if (!container) return;
const rect = container.getBoundingClientRect();
+ const relativeX = event.clientX - rect.left;
+ const relativeY = event.clientY - rect.top;
- let newX = event.clientX - offset[1];
- let newY = event.clientY - offset[0];
+ // Determine which properties are active for the dragged object
+ const obj = zone.objects[draggingIndex.index];
+ const [activeProp1, activeProp2] = getActiveProperties(obj.position);
+ // Calculate the new position based on the active properties
+ let newX = 0;
+ let newY = 0;
+
+ if (activeProp2 === "left") {
+ newX = relativeX - offset[1];
+ } else if (activeProp2 === "right") {
+ newX = rect.width - (relativeX + offset[1]);
+ }
+
+ if (activeProp1 === "top") {
+ newY = relativeY - offset[0];
+ } else if (activeProp1 === "bottom") {
+ newY = rect.height - (relativeY + offset[0]);
+ }
+
+ // Ensure the object stays within the canvas boundaries
newX = Math.max(0, Math.min(rect.width - 50, newX));
newY = Math.max(0, Math.min(rect.height - 50, newY));
+ // Update the position reference
positionRef.current = [newY, newX];
+ // Update the object's position using requestAnimationFrame for smoother animations
if (!animationRef.current) {
animationRef.current = requestAnimationFrame(() => {
if (positionRef.current) {
- updateObjectPosition(zoneName, draggingIndex.index, positionRef.current);
+ updateObjectPosition(zoneName, draggingIndex.index, {
+ ...obj.position,
+ [activeProp1]: positionRef.current[0],
+ [activeProp2]: positionRef.current[1],
+ });
}
animationRef.current = null;
});
}
}
- function handlePointerUp() {
- setDraggingIndex(null);
- setOffset(null);
- if (animationRef.current) {
- cancelAnimationFrame(animationRef.current);
- animationRef.current = null;
+ // Handle pointer up event
+ async function handlePointerUp(event: React.MouseEvent) {
+ try {
+ if (!draggingIndex || !offset) return;
+
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
+ const container = document.getElementById("real-time-vis-canvas");
+ if (!container) throw new Error("Canvas container not found");
+
+ const rect = container.getBoundingClientRect();
+ const relativeX = event.clientX - rect.left;
+ const relativeY = event.clientY - rect.top;
+
+ // Recalculate the position using determinePosition
+ const newPosition = determinePosition(rect, relativeX, relativeY);
+
+ // Validate the dragging index and get the object
+ if (!zone.objects[draggingIndex.index]) {
+ throw new Error("Dragged object not found in the zone");
+ }
+ const obj = { ...zone.objects[draggingIndex.index], position: newPosition };
+ let response = await addingFloatingWidgets(zone.zoneId, organization, obj);
+ if (response.message === "Widget updated successfully") {
+ updateObjectPosition(zoneName, draggingIndex.index, newPosition);
+ }
+
+ // Reset states
+ setDraggingIndex(null);
+ setOffset(null);
+
+ if (animationRef.current) {
+ cancelAnimationFrame(animationRef.current);
+ animationRef.current = null;
+ }
+ } catch (error) {
+
}
}
+
return (
{zone.objects.map((obj, index) => (
@@ -96,14 +174,29 @@ const DroppedObjects: React.FC = () => {
key={`${zoneName}-${index}`}
className={obj.className}
style={{
- top: obj.position[0] + "px",
- left: obj.position[1] + "px",
- transition: draggingIndex?.index === index ? "none" : "transform 0.1s ease-out",
+ position: "absolute",
+ top:
+ typeof obj.position.top !== "string"
+ ? `${obj.position.top}px`
+ : "auto",
+ left:
+ typeof obj.position.left !== "string"
+ ? `${obj.position.left}px`
+ : "auto",
+ right:
+ typeof obj.position.right !== "string"
+ ? `${obj.position.right}px`
+ : "auto",
+ bottom:
+ typeof obj.position.bottom !== "string"
+ ? `${obj.position.bottom}px`
+ : "auto",
+ // transition: draggingIndex?.index === index ? "none" : "transform 0.1s ease-out",
}}
onPointerDown={(event) => handlePointerDown(event, index)}
>
{obj.className === "floating total-card" ? (
-
+ <>
{obj.header}
@@ -114,9 +207,9 @@ const DroppedObjects: React.FC = () => {
-
+ >
) : obj.className === "warehouseThroughput floating" ? (
-
+ <>
Warehouse Throughput
@@ -126,9 +219,9 @@ const DroppedObjects: React.FC = () => {
{/* */}
-
+ >
) : obj.className === "fleetEfficiency floating" ? (
-
+ <>
Fleet Efficiency
@@ -148,7 +241,7 @@ const DroppedObjects: React.FC = () => {
100%
-
+ >
) : null}
))}
@@ -156,59 +249,4 @@ const DroppedObjects: React.FC = () => {
);
};
-
-
-
-
export default DroppedObjects;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// import { Html } from "@react-three/drei";
-// import { useDroppedObjectsStore } from "../../../store/store";
-// import { CartIcon, DocumentIcon, GlobeIcon, WalletIcon } from "../../icons/3dChartIcons";
-// import SimpleCard from "../realTimeVis/floating/SimpleCard";
-
-// const ICON_MAP: Record
>> = {
-// WalletIcon,
-// GlobeIcon,
-// DocumentIcon,
-// CartIcon
-// };
-// const DroppedObjects: React.FC = () => {
-// const objects = useDroppedObjectsStore((state) => state.objects); // Get objects from Zustand store
-//
-
-// return (
-// <>
-// {objects.map((obj, index) => {
-// const IconComponent = obj.Icon || WalletIcon; // Use obj.Icon directly if it exists
-// return (
-//
-// );
-// })}
-// >
-// );
-// };
-
-// export default DroppedObjects;
diff --git a/app/src/components/ui/componets/Panel.tsx b/app/src/components/ui/componets/Panel.tsx
index 1d4cc44..6500119 100644
--- a/app/src/components/ui/componets/Panel.tsx
+++ b/app/src/components/ui/componets/Panel.tsx
@@ -149,7 +149,7 @@ const Panel: React.FC = ({
};
try {
let response = await addingWidgets(selectedZone.zoneId, organization, newWidget);
- console.log("response: ", response);
+
if (response.message === "Widget created successfully") {
setSelectedZone((prev) => ({
...prev,
diff --git a/app/src/components/ui/componets/RealTimeVisulization.tsx b/app/src/components/ui/componets/RealTimeVisulization.tsx
index 17dd452..45db987 100644
--- a/app/src/components/ui/componets/RealTimeVisulization.tsx
+++ b/app/src/components/ui/componets/RealTimeVisulization.tsx
@@ -9,9 +9,15 @@ import useModuleStore from "../../../store/useModuleStore";
import DroppedObjects from "./DroppedFloatingWidgets";
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
-import { useAsset3dWidget, useZones } from "../../../store/store";
-import { getZoneData } from "../../../services/realTimeVisulization/zoneData/getZones";
+import {
+ useAsset3dWidget,
+ useWidgetSubOption,
+ useZones,
+} from "../../../store/store";
import { getZone2dData } from "../../../services/realTimeVisulization/zoneData/getZoneData";
+import { generateUniqueId } from "../../../functions/generateUniqueId";
+import { determinePosition } from "./functions/determinePosition";
+import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
type Side = "top" | "bottom" | "left" | "right";
@@ -49,6 +55,8 @@ const RealTimeVisulization: React.FC = () => {
Record
>({});
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
+ const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
+
useEffect(() => {
async function GetZoneData() {
const email = localStorage.getItem("email") || "";
@@ -103,48 +111,67 @@ const RealTimeVisulization: React.FC = () => {
useEffect(() => {}, [floatingWidgets]);
- const handleDrop = (event: React.DragEvent) => {
- event.preventDefault();
- const data = event.dataTransfer.getData("text/plain");
- if (widgetSelect !== "") return;
- if (!data || selectedZone.zoneName === "") return;
+ const handleDrop = async (event: React.DragEvent) => {
+ try {
+ event.preventDefault();
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
- const droppedData = JSON.parse(data);
- const canvasElement = document.getElementById("real-time-vis-canvas");
- if (!canvasElement) return;
+ const data = event.dataTransfer.getData("text/plain");
+ // if (widgetSelect !== "") return;
+ if (widgetSubOption === "3D") return;
+ if (!data || selectedZone.zoneName === "") return;
- const canvasRect = canvasElement.getBoundingClientRect();
- const relativeX = event.clientX - canvasRect.left;
- const relativeY = event.clientY - canvasRect.top;
+ const droppedData = JSON.parse(data);
+ const canvasElement = document.getElementById("real-time-vis-canvas");
+ if (!canvasElement) throw new Error("Canvas element not found");
- const newObject = {
- ...droppedData,
- position: [relativeY, relativeX], // Y first because of top/left style
- };
- // Only set zone if itβs not already in the store (prevents overwriting objects)
- const existingZone =
- useDroppedObjectsStore.getState().zones[selectedZone.zoneName];
- if (!existingZone) {
- useDroppedObjectsStore
- .getState()
- .setZone(selectedZone.zoneName, selectedZone.zoneId);
- }
- // Add the dropped object to the zone
- useDroppedObjectsStore
- .getState()
- .addObject(selectedZone.zoneName, newObject);
- setFloatingWidgets((prevWidgets) => ({
- ...prevWidgets,
- [selectedZone.zoneName]: {
- ...prevWidgets[selectedZone.zoneName],
- zoneName: selectedZone.zoneName,
- zoneId: selectedZone.zoneId,
- objects: [
- ...(prevWidgets[selectedZone.zoneName]?.objects || []),
- newObject,
- ],
- },
- }));
+ const canvasRect = canvasElement.getBoundingClientRect();
+ const relativeX = event.clientX - canvasRect.left;
+ const relativeY = event.clientY - canvasRect.top;
+
+ const newObject = {
+ ...droppedData,
+ id: generateUniqueId(),
+ position: determinePosition(canvasRect, relativeX, relativeY),
+ };
+
+ let response = await addingFloatingWidgets(
+ selectedZone.zoneId,
+ organization,
+ newObject
+ );
+
+ // Only set zone if itβs not already in the store (prevents overwriting objects)
+ const existingZone =
+ useDroppedObjectsStore.getState().zones[selectedZone.zoneName];
+ if (!existingZone) {
+ useDroppedObjectsStore
+ .getState()
+ .setZone(selectedZone.zoneName, selectedZone.zoneId);
+ }
+
+ // Add the dropped object to the zone if the API call is successful
+ if (response.message === "FloatWidget created successfully") {
+ useDroppedObjectsStore
+ .getState()
+ .addObject(selectedZone.zoneName, newObject);
+ }
+
+ // Update floating widgets state
+ setFloatingWidgets((prevWidgets) => ({
+ ...prevWidgets,
+ [selectedZone.zoneName]: {
+ ...prevWidgets[selectedZone.zoneName],
+ zoneName: selectedZone.zoneName,
+ zoneId: selectedZone.zoneId,
+ objects: [
+ ...(prevWidgets[selectedZone.zoneName]?.objects || []),
+ newObject,
+ ],
+ },
+ }));
+ } catch (error) {}
};
return (
diff --git a/app/src/components/ui/componets/functions/convertAutoToNumeric.ts b/app/src/components/ui/componets/functions/convertAutoToNumeric.ts
new file mode 100644
index 0000000..3addac2
--- /dev/null
+++ b/app/src/components/ui/componets/functions/convertAutoToNumeric.ts
@@ -0,0 +1,41 @@
+import { getActiveProperties } from "./getActiveProperties";
+
+export const convertAutoToNumeric = (
+ canvasRect: DOMRect,
+ position: {
+ top: number | "auto";
+ left: number | "auto";
+ right: number | "auto";
+ bottom: number | "auto";
+ }
+): { top: number; left: number; right: number; bottom: number } => {
+ const { width, height } = canvasRect;
+
+ // Determine which properties are active
+ const [activeProp1, activeProp2] = getActiveProperties(position);
+
+ let top = typeof position.top !== "string" ? position.top : 0;
+ let left = typeof position.left !== "string" ? position.left : 0;
+ let right = typeof position.right !== "string" ? position.right : 0;
+ let bottom = typeof position.bottom !== "string" ? position.bottom : 0;
+
+ // Calculate missing properties based on active properties
+ if (activeProp1 === "top") {
+ bottom = height - top;
+ } else if (activeProp1 === "bottom") {
+ top = height - bottom;
+ }
+
+ if (activeProp2 === "left") {
+ right = width - left;
+ } else if (activeProp2 === "right") {
+ left = width - right;
+ }
+
+ return {
+ top,
+ left,
+ right,
+ bottom,
+ };
+};
diff --git a/app/src/components/ui/componets/functions/determinePosition.ts b/app/src/components/ui/componets/functions/determinePosition.ts
new file mode 100644
index 0000000..0fcd727
--- /dev/null
+++ b/app/src/components/ui/componets/functions/determinePosition.ts
@@ -0,0 +1,64 @@
+export function determinePosition(
+ canvasRect: DOMRect,
+ relativeX: number,
+ relativeY: number
+): {
+ top: number | "auto";
+ left: number | "auto";
+ right: number | "auto";
+ bottom: number | "auto";
+} {
+ // Calculate the midpoints of the canvas
+ const centerX = canvasRect.width / 2;
+ const centerY = canvasRect.height / 2;
+
+ // Initialize position with default values
+ let position: {
+ top: number | "auto";
+ left: number | "auto";
+ right: number | "auto";
+ bottom: number | "auto";
+ };
+
+ if (relativeY < centerY) {
+ // Top half
+ if (relativeX < centerX) {
+ // Left side
+ position = {
+ top: relativeY,
+ left: relativeX,
+ right: "auto",
+ bottom: "auto",
+ };
+ } else {
+ // Right side
+ position = {
+ top: relativeY,
+ right: canvasRect.width - relativeX,
+ left: "auto",
+ bottom: "auto",
+ };
+ }
+ } else {
+ // Bottom half
+ if (relativeX < centerX) {
+ // Left side
+ position = {
+ bottom: canvasRect.height - relativeY,
+ left: relativeX,
+ right: "auto",
+ top: "auto",
+ };
+ } else {
+ // Right side
+ position = {
+ bottom: canvasRect.height - relativeY,
+ right: canvasRect.width - relativeX,
+ left: "auto",
+ top: "auto",
+ };
+ }
+ }
+
+ return position;
+}
diff --git a/app/src/components/ui/componets/functions/getActiveProperties.ts b/app/src/components/ui/componets/functions/getActiveProperties.ts
new file mode 100644
index 0000000..2cb0b1b
--- /dev/null
+++ b/app/src/components/ui/componets/functions/getActiveProperties.ts
@@ -0,0 +1,17 @@
+export const getActiveProperties = (position: {
+ top: number | "auto";
+ left: number | "auto";
+ right: number | "auto";
+ bottom: number | "auto";
+}) => {
+ let activeProps: ["top", "left"] | ["bottom", "right"] = ["top", "left"]; // Default to top-left
+
+ if (
+ typeof position.bottom !== "string" &&
+ typeof position.right !== "string"
+ ) {
+ activeProps = ["bottom", "right"];
+ }
+
+ return activeProps;
+};
diff --git a/app/src/components/ui/componets/zoneCameraTarget.tsx b/app/src/components/ui/componets/zoneCameraTarget.tsx
index 57804b9..f022b32 100644
--- a/app/src/components/ui/componets/zoneCameraTarget.tsx
+++ b/app/src/components/ui/componets/zoneCameraTarget.tsx
@@ -14,6 +14,7 @@ export default function ZoneCentreTarget() {
const { Edit, setEdit } = useEditPosition();
+
useEffect(() => {
if (
selectedZone.zoneViewPortTarget &&
@@ -39,22 +40,22 @@ export default function ZoneCentreTarget() {
if (centrePoint.length > 0) {
- let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
- let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
+ // let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
+ // let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
- const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
+ // const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
- const worldUp = new THREE.Vector3(0, 0, 1);
- const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
- const up = new THREE.Vector3().crossVectors(direction, right).normalize();
- const offsetPosition = up.clone().multiplyScalar(20);
- camPosition.add(offsetPosition);
+ // const worldUp = new THREE.Vector3(0, 0, 1);
+ // const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
+ // const up = new THREE.Vector3().crossVectors(direction, right).normalize();
+ // const offsetPosition = up.clone().multiplyScalar(20);
+ // camPosition.add(offsetPosition);
const setCam = async () => {
controls.setLookAt(centrePoint[0], 100, centrePoint[2], ...centrePoint, true);
setTimeout(() => {
controls?.setLookAt(
- ...camPosition.toArray(),
+ ...selectedZone.zoneViewPortPosition,
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
@@ -65,21 +66,9 @@ export default function ZoneCentreTarget() {
setCam();
} else {
- let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
- let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
-
- const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
-
- const worldUp = new THREE.Vector3(0, 0, 1);
- const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
- const up = new THREE.Vector3().crossVectors(direction, right).normalize();
-
- const offsetPosition = up.clone().multiplyScalar(20);
-
- camPosition.add(offsetPosition);
const setCam = async () => {
controls?.setLookAt(
- ...camPosition.toArray(),
+ ...selectedZone.zoneViewPortPosition,
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
diff --git a/app/src/components/ui/list/DropDownList.tsx b/app/src/components/ui/list/DropDownList.tsx
index 4ff51ca..e77f35b 100644
--- a/app/src/components/ui/list/DropDownList.tsx
+++ b/app/src/components/ui/list/DropDownList.tsx
@@ -32,7 +32,7 @@ const DropDownList: React.FC = ({
listType = "default",
remove,
}) => {
-
+
const [isOpen, setIsOpen] = useState(defaultOpen);
const { zones, setZones } = useZones()
@@ -43,6 +43,17 @@ const DropDownList: React.FC = ({
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
diff --git a/app/src/components/ui/list/List.tsx b/app/src/components/ui/list/List.tsx
index 7a7da8d..0b2e63b 100644
--- a/app/src/components/ui/list/List.tsx
+++ b/app/src/components/ui/list/List.tsx
@@ -1,9 +1,9 @@
-import React from "react";
+import React, { useEffect } from "react";
import RenameInput from "../inputs/RenameInput";
import { EyeIcon, LockIcon, RmoveIcon } from "../../icons/ExportCommonIcons";
import { useSelectedZoneStore } from "../../../store/useZoneStore";
import { getZoneData } from "../../../services/realTimeVisulization/zoneData/getZones";
-import { useSubModuleStore } from "../../../store/useModuleStore";
+import useModuleStore, { useSubModuleStore } from "../../../store/useModuleStore";
interface ListProps {
items?: { id: string; name: string }[]; // Optional array of items to render
@@ -12,27 +12,55 @@ interface ListProps {
}
const List: React.FC = ({ items = [], remove }) => {
- const { setSelectedZone } = useSelectedZoneStore();
+ const { activeModule, setActiveModule } = useModuleStore();
+ const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const { setSubModule } = useSubModuleStore();
+ useEffect(() => {
+ useSelectedZoneStore.getState().setSelectedZone({
+ zoneName: "",
+ activeSides: [],
+ panelOrder: [],
+ lockedPanels: [],
+ zoneId: "",
+ zoneViewPortTarget: [],
+ zoneViewPortPosition: [],
+ widgets: [],
+ });
+ }, [activeModule]);
+
async function handleSelectZone(id: string) {
- setSubModule("zoneProperties")
- const email = localStorage.getItem('email')
- const organization = (email!.split("@")[1]).split(".")[0];
- let response = await getZoneData(id, organization)
- setSelectedZone({
- zoneName: response?.zoneName,
- activeSides: response?.activeSides || [],
- panelOrder: response?.panelOrder || [],
- lockedPanels: response?.lockedPanels || [],
- widgets: response?.widgets || [],
- zoneId: response?.zoneId,
- zoneViewPortTarget: response?.viewPortCenter || [],
- zoneViewPortPosition:
- response?.viewPortposition || [],
- });
+ try {
+ // Avoid re-fetching if the same zone is already selected
+ if (selectedZone?.zoneId === id) {
+ console.log("Zone is already selected:", selectedZone.zoneName);
+ return;
+ }
+ setSubModule("zoneProperties");
+
+ const email = localStorage.getItem("email");
+ const organization = email?.split("@")[1]?.split(".")[0] || "";
+
+ let response = await getZoneData(id, organization);
+
+ setSelectedZone({
+ zoneName: response?.zoneName,
+ activeSides: response?.activeSides || [],
+ panelOrder: response?.panelOrder || [],
+ lockedPanels: response?.lockedPanels || [],
+ widgets: response?.widgets || [],
+ zoneId: response?.zoneId,
+ zoneViewPortTarget: response?.viewPortCenter || [],
+ zoneViewPortPosition: response?.viewPortposition || [],
+ });
+
+ console.log("Zone selected:", response?.zoneName);
+ } catch (error) {
+ console.error("Error selecting zone:", error);
+ }
}
+
return (
<>
{items.length > 0 ? (
diff --git a/app/src/components/ui/realTimeVis/floating/FleetEfficiency.tsx b/app/src/components/ui/realTimeVis/floating/FleetEfficiency.tsx
index 03c00e8..07e5f19 100644
--- a/app/src/components/ui/realTimeVis/floating/FleetEfficiency.tsx
+++ b/app/src/components/ui/realTimeVis/floating/FleetEfficiency.tsx
@@ -14,8 +14,6 @@ const FleetEfficiency = () => {
per: progress,
});
-
- console.log("Dragged Data:", cardData);
event.dataTransfer.setData("text/plain", cardData);
};
diff --git a/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx b/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx
index ee996bd..0c36977 100644
--- a/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx
+++ b/app/src/components/ui/realTimeVis/floating/SimpleCard.tsx
@@ -23,6 +23,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/scene/scene.tsx b/app/src/modules/scene/scene.tsx
index ac74240..74693b4 100644
--- a/app/src/modules/scene/scene.tsx
+++ b/app/src/modules/scene/scene.tsx
@@ -21,6 +21,7 @@ import DroppedObjects from "../../components/ui/componets/DroppedFloatingWidgets
import ZoneCentreTarget from "../../components/ui/componets/zoneCameraTarget";
import ProductionCapacity from "../../components/layout/3D-cards/cards/ProductionCapacity";
import Dropped3dWidgets from "../../components/ui/componets/Dropped3dWidget";
+import { useWidgetSubOption } from "../../store/store";
export default function Scene() {
@@ -31,9 +32,6 @@ export default function Scene() {
{ name: "right", keys: ["ArrowRight", "d", "D"] },
], [])
-
-
-
return (