floatingwidgets Api and 3dwidget frontend and 2d widget delete Api and zonecameraUpdation
This commit is contained in:
parent
71310bdbdd
commit
6ccdb28f52
|
@ -2017,7 +2017,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"
|
||||
},
|
||||
|
@ -2029,7 +2029,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"
|
||||
|
@ -4128,6 +4128,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",
|
||||
|
@ -4239,25 +4259,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",
|
||||
|
@ -8864,7 +8884,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",
|
||||
|
@ -9729,7 +9749,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"
|
||||
}
|
||||
|
@ -15073,7 +15093,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",
|
||||
|
@ -20516,7 +20536,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",
|
||||
|
@ -20559,7 +20579,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"
|
||||
},
|
||||
|
@ -20571,7 +20591,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",
|
||||
|
@ -21058,7 +21078,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",
|
||||
|
@ -22117,7 +22137,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"
|
||||
}
|
||||
|
|
|
@ -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 (
|
||||
<div className="widget-left-sideBar">
|
||||
<ToggleHeader
|
||||
options={["2D", "3D", "Floating"]}
|
||||
activeOption={activeOption}
|
||||
activeOption={widgetSubOption}
|
||||
handleClick={handleToggleClick}
|
||||
/>
|
||||
{activeOption === "2D" && <Widgets2D />}
|
||||
{activeOption === "3D" && <Widgets3D />}
|
||||
{activeOption === "Floating" && <WidgetsFloating />}
|
||||
{widgetSubOption === "2D" && <Widgets2D />}
|
||||
{widgetSubOption === "3D" && <Widgets3D />}
|
||||
{widgetSubOption === "Floating" && <WidgetsFloating />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 (
|
||||
<div className="module-toggle-container">
|
||||
<div
|
||||
|
@ -39,9 +41,8 @@ const ModuleToggle: React.FC = () => {
|
|||
<div className="module">Simulation</div>
|
||||
</div>
|
||||
<div
|
||||
className={`module-list ${
|
||||
activeModule === "visualization" && "active"
|
||||
}`}
|
||||
className={`module-list ${activeModule === "visualization" && "active"
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveModule("visualization");
|
||||
setToggleUI(true);
|
||||
|
|
|
@ -119,7 +119,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
};
|
||||
|
||||
// Delete the selectedZone state
|
||||
console.log("updatedZone: ", updatedZone);
|
||||
|
||||
setSelectedZone(updatedZone);
|
||||
} else {
|
||||
const updatePanelData = async () => {
|
||||
|
@ -141,13 +141,13 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||
|
||||
// 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);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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<DisplayZoneProps> = ({
|
|||
};
|
||||
|
||||
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 (
|
||||
<div
|
||||
className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom"
|
||||
|
@ -185,7 +204,6 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
useDroppedObjectsStore.getState().setZone(zoneName, zonesData[zoneName]?.zoneId);
|
||||
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -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<HTMLDivElement>) => {
|
||||
event.stopPropagation();
|
||||
if (openKebabId === widget.id) {
|
||||
|
@ -176,7 +196,6 @@ export const DraggableWidget = ({
|
|||
};
|
||||
|
||||
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
|
||||
|
||||
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
|
||||
|
|
|
@ -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<Record<
|
||||
string, // Zone ID
|
||||
Record<string, [number, number, number][]> // Widget type -> Positions array
|
||||
>>({});
|
||||
|
||||
// 🔥 Store multiple instances per widget type
|
||||
const [widgetPositions, setWidgetPositions] = useState<Record<string, [number, number, number][]>>({});
|
||||
|
||||
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) => (
|
||||
<ProductionCapacity key={`Widget1-${index}`} position={pos} />
|
||||
))}
|
||||
{widgetPositions["ui-Widget 2"]?.map((pos, index) => (
|
||||
{zoneWidgets[selectedZone.zoneId]?.["ui-Widget 2"]?.map((pos, index) => (
|
||||
<ReturnOfInvestment key={`Widget2-${index}`} position={pos} />
|
||||
))}
|
||||
{widgetPositions["ui-Widget 3"]?.map((pos, index) => (
|
||||
{zoneWidgets[selectedZone.zoneId]?.["ui-Widget 3"]?.map((pos, index) => (
|
||||
<StateWorking key={`Widget3-${index}`} position={pos} />
|
||||
))}
|
||||
{widgetPositions["ui-Widget 4"]?.map((pos, index) => (
|
||||
{zoneWidgets[selectedZone.zoneId]?.["ui-Widget 4"]?.map((pos, index) => (
|
||||
<Throughput key={`Widget4-${index}`} position={pos} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<number | null>(null);
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
// useEffect(() => {
|
||||
// const initialZones: Record<string, Zones> = {
|
||||
// "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<HTMLDivElement>) {
|
||||
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 (
|
||||
<div onPointerMove={handlePointerMove} onPointerUp={handlePointerUp}>
|
||||
{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" ? (
|
||||
<div>
|
||||
<>
|
||||
<div className="header-wrapper">
|
||||
<div className="header">{obj.header}</div>
|
||||
<div className="data-values">
|
||||
|
@ -114,9 +207,9 @@ const DroppedObjects: React.FC = () => {
|
|||
<div className="icon">
|
||||
<WalletIcon />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : obj.className === "warehouseThroughput floating" ? (
|
||||
<div>
|
||||
<>
|
||||
<div className="header">
|
||||
<h2>Warehouse Throughput</h2>
|
||||
<p>
|
||||
|
@ -126,9 +219,9 @@ const DroppedObjects: React.FC = () => {
|
|||
<div className="lineGraph" style={{ height: "100%" }}>
|
||||
{/* <Line data={lineGraphData} options={lineGraphOptions} /> */}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : obj.className === "fleetEfficiency floating" ? (
|
||||
<div>
|
||||
<>
|
||||
<h2 className="header">Fleet Efficiency</h2>
|
||||
<div className="progressContainer">
|
||||
<div className="progress">
|
||||
|
@ -148,7 +241,7 @@ const DroppedObjects: React.FC = () => {
|
|||
</div>
|
||||
<span>100%</span>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
))}
|
||||
|
@ -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<string, React.ComponentType<React.SVGProps<SVGSVGElement>>> = {
|
||||
// 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 (
|
||||
// <SimpleCard
|
||||
// key={index}
|
||||
// position={obj.position}
|
||||
// header={obj.header}
|
||||
// icon={IconComponent} // ✅ No need to look it up in ICON_MAP
|
||||
// value={obj.value}
|
||||
// per={obj.per}
|
||||
// />
|
||||
// );
|
||||
// })}
|
||||
// </>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default DroppedObjects;
|
||||
|
|
|
@ -149,7 +149,7 @@ const Panel: React.FC<PanelProps> = ({
|
|||
};
|
||||
try {
|
||||
let response = await addingWidgets(selectedZone.zoneId, organization, newWidget);
|
||||
console.log("response: ", response);
|
||||
|
||||
if (response.message === "Widget created successfully") {
|
||||
setSelectedZone((prev) => ({
|
||||
...prev,
|
||||
|
|
|
@ -9,9 +9,11 @@ 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";
|
||||
|
@ -48,6 +50,8 @@ const RealTimeVisulization: React.FC = () => {
|
|||
const { zones } = useZones()
|
||||
const [floatingWidgets, setFloatingWidgets] = useState<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
|
||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption()
|
||||
|
||||
useEffect(() => {
|
||||
async function GetZoneData() {
|
||||
const email = localStorage.getItem("email") || "";
|
||||
|
@ -72,12 +76,12 @@ const RealTimeVisulization: React.FC = () => {
|
|||
setZonesData(formattedData);
|
||||
} catch (error) {
|
||||
console.log('error: ', error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GetZoneData();
|
||||
}, []); // Removed `zones` from dependencies
|
||||
|
||||
}, [activeModule]); // Removed `zones` from dependencies
|
||||
|
||||
useEffect(() => {
|
||||
setZonesData((prev) => {
|
||||
|
@ -97,48 +101,68 @@ const RealTimeVisulization: React.FC = () => {
|
|||
};
|
||||
});
|
||||
}, [selectedZone]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, [floatingWidgets])
|
||||
|
||||
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
|
||||
event.preventDefault();
|
||||
const data = event.dataTransfer.getData("text/plain");
|
||||
if (widgetSelect !== "") return;
|
||||
if (!data || selectedZone.zoneName === "") return;
|
||||
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
||||
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 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) {
|
||||
|
||||
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],
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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],
|
||||
|
|
|
@ -32,7 +32,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
|||
listType = "default",
|
||||
remove,
|
||||
}) => {
|
||||
|
||||
|
||||
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
|
||||
const { zones, setZones } = useZones()
|
||||
|
||||
|
@ -43,6 +43,17 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
|||
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
|
||||
|
|
|
@ -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<ListProps> = ({ 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 ? (
|
||||
|
|
|
@ -53,7 +53,7 @@ const PieChartComponent = ({
|
|||
.getPropertyValue("--accent-color")
|
||||
.trim();
|
||||
|
||||
console.log("accentColor: ", accentColor);
|
||||
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
|
|
|
@ -14,8 +14,6 @@ const FleetEfficiency = () => {
|
|||
per: progress,
|
||||
|
||||
});
|
||||
|
||||
console.log("Dragged Data:", cardData);
|
||||
event.dataTransfer.setData("text/plain", cardData);
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ const SimpleCard: React.FC<SimpleCardProps> = ({
|
|||
value,
|
||||
per,
|
||||
icon: Icon,
|
||||
|
||||
className: event.currentTarget.className,
|
||||
position: [rect.top, rect.left], // ✅ Store position
|
||||
});
|
||||
|
|
|
@ -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 (
|
||||
<KeyboardControls map={map}>
|
||||
<Canvas
|
||||
|
@ -45,7 +43,7 @@ export default function Scene() {
|
|||
}}
|
||||
|
||||
>
|
||||
<Dropped3dWidgets/>
|
||||
<Dropped3dWidgets />
|
||||
<Controls />
|
||||
<TransformControl />
|
||||
<SelectionControls />
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
export const addingFloatingWidgets = async (
|
||||
zoneId: string,
|
||||
organization: string,
|
||||
widget: {}
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v2/floatwidget/save`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ organization, zoneId, widget }),
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add Floatingwidget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
export const addingWidgets = async (
|
||||
zoneId: string,
|
||||
organization: string,
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
|
||||
export const deleteWidgetApi = async (
|
||||
widgetID: string,
|
||||
organization: string
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/v2/delete/widget`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ organization, widgetID }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to delete widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
export const duplicateWidgetApi = async (
|
||||
zoneId: string,
|
||||
organization: string,
|
||||
widget: {}
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/v2/widget/save`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ organization, zoneId, widget }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to duplicate widget in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
export const getFloatingZoneData = async (
|
||||
ZoneId?: string,
|
||||
organization?: string
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${url_Backend_dwinzo}/api/v2/floadData/${ZoneId}/${organization}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch ZoneFloatingData");
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error: any) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
console.log("url_Backend_dwinzo: ", url_Backend_dwinzo);
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
|
||||
export const getSelect2dZoneData = async (
|
||||
ZoneId?: string,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
export const getZone2dData = async (organization?: string) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
|
||||
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}`,
|
||||
|
@ -12,6 +14,7 @@ export const getZoneData = async (zoneId: string, organization: string) => {
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch zoneData");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
|
||||
export const panelData = async (
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
|
||||
|
||||
export const zoneCameraUpdate = async (
|
||||
zonesdata:{},organization:string
|
||||
) => {
|
||||
try {
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/v2/zone/save`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ zonesdata, organization }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to update camera position in the zone");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
} else {
|
||||
throw new Error("An unknown error occurred");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -29,7 +29,10 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
export const useLoadingProgress = create<{ loadingProgress: number; setLoadingProgress: (x: number) => void }>((set) => ({
|
||||
export const useLoadingProgress = create<{
|
||||
loadingProgress: number;
|
||||
setLoadingProgress: (x: number) => void;
|
||||
}>((set) => ({
|
||||
loadingProgress: 1,
|
||||
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
||||
}));
|
||||
|
@ -312,7 +315,9 @@ export const useSelectedPath = create<any>((set: any) => ({
|
|||
|
||||
interface SimulationPathsStore {
|
||||
simulationPaths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[];
|
||||
setSimulationPaths: (paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]) => void;
|
||||
setSimulationPaths: (
|
||||
paths: (Types.ConveyorEventsSchema | Types.VehicleEventsSchema)[]
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const useSimulationPaths = create<SimulationPathsStore>((set) => ({
|
||||
|
@ -352,3 +357,7 @@ export const useAsset3dWidget = create<any>((set: any) => ({
|
|||
widgetSelect: "",
|
||||
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
||||
}));
|
||||
export const useWidgetSubOption = create<any>((set: any) => ({
|
||||
widgetSubOption: "2D",
|
||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||
}));
|
||||
|
|
|
@ -2,10 +2,17 @@ import { create } from "zustand";
|
|||
|
||||
type DroppedObject = {
|
||||
className: string;
|
||||
position: [number, number];
|
||||
id: string;
|
||||
position: {
|
||||
top: number | "auto";
|
||||
left: number | "auto";
|
||||
right: number | "auto";
|
||||
bottom: number | "auto";
|
||||
};
|
||||
value?: number;
|
||||
per?: string;
|
||||
header?: string;
|
||||
Data: {};
|
||||
};
|
||||
|
||||
type Zone = {
|
||||
|
@ -21,7 +28,12 @@ type DroppedObjectsState = {
|
|||
updateObjectPosition: (
|
||||
zoneName: string,
|
||||
index: number,
|
||||
newPosition: [number, number]
|
||||
newPosition: {
|
||||
top: number | "auto";
|
||||
left: number | "auto";
|
||||
right: number | "auto";
|
||||
bottom: number | "auto";
|
||||
}
|
||||
) => void;
|
||||
};
|
||||
|
||||
|
@ -64,15 +76,17 @@ export const useDroppedObjectsStore = create<DroppedObjectsState>((set) => ({
|
|||
}));
|
||||
|
||||
export interface DroppedObjects {
|
||||
header: string;
|
||||
value: string | number; // ✅ Allows both numbers and formatted strings
|
||||
per: string;
|
||||
className: string;
|
||||
position: [number, number]; // ✅ Ensures position is a tuple
|
||||
}
|
||||
|
||||
export interface Zones {
|
||||
zoneName: string;
|
||||
zoneId: string;
|
||||
objects: DroppedObject[];
|
||||
}
|
||||
header: string;
|
||||
id: string;
|
||||
Data: {};
|
||||
value: string | number; // ✅ Allows both numbers and formatted strings
|
||||
per: string;
|
||||
className: string;
|
||||
position: { top: number; left: number; right: number; bottom: number }; // ✅ Ensures position is a tuple
|
||||
}
|
||||
|
||||
export interface Zones {
|
||||
zoneName: string;
|
||||
zoneId: string;
|
||||
objects: DroppedObject[];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue