diff --git a/app/src/components/ui/componets/Dropped3dWidget.tsx b/app/src/components/ui/componets/Dropped3dWidget.tsx index f12712d..7885275 100644 --- a/app/src/components/ui/componets/Dropped3dWidget.tsx +++ b/app/src/components/ui/componets/Dropped3dWidget.tsx @@ -1,6 +1,10 @@ import { useThree } from "@react-three/fiber"; import React, { useEffect, useRef } from "react"; -import { useAsset3dWidget, useSocketStore, useWidgetSubOption } from "../../../store/store"; +import { + useAsset3dWidget, + useSocketStore, + useWidgetSubOption, +} from "../../../store/store"; import useModuleStore from "../../../store/useModuleStore"; import { ThreeState } from "../../../types/world/worldTypes"; import * as THREE from "three"; @@ -13,347 +17,391 @@ import { generateUniqueId } from "../../../functions/generateUniqueId"; import { adding3dWidgets } from "../../../services/realTimeVisulization/zoneData/add3dWidget"; import { get3dWidgetZoneData } from "../../../services/realTimeVisulization/zoneData/get3dWidgetData"; import { use3DWidget } from "../../../store/useDroppedObjectsStore"; -import { useLeftData, useRightClickSelected, useRightSelected, useTopData, useZoneWidgetStore } from "../../../store/useZone3DWidgetStore"; +import { + useEditWidgetOptionsStore, + useLeftData, + useRightClickSelected, + useRightSelected, + useTopData, + useZoneWidgetStore, +} from "../../../store/useZone3DWidgetStore"; import { useWidgetStore } from "../../../store/useWidgetStore"; import EditWidgetOption from "../menu/EditWidgetOption"; type WidgetData = { - id: string; - type: string; - position: [number, number, number]; - rotation?: [number, number, number]; - tempPosition?: [number, number, number]; + id: string; + type: string; + position: [number, number, number]; + rotation?: [number, number, number]; + tempPosition?: [number, number, number]; }; - export default function Dropped3dWidgets() { - const { widgetSelect } = useAsset3dWidget(); - const { activeModule } = useModuleStore(); - const { raycaster, gl, scene, mouse, camera }: ThreeState = useThree(); - const { widgetSubOption } = useWidgetSubOption(); - const { selectedZone } = useSelectedZoneStore(); - const { top, setTop } = useTopData(); - const { left, setLeft } = useLeftData(); - const { rightSelect, setRightSelect } = useRightSelected(); + const { widgetSelect } = useAsset3dWidget(); + const { activeModule } = useModuleStore(); + const { raycaster, gl, scene, mouse, camera }: ThreeState = useThree(); + const { widgetSubOption } = useWidgetSubOption(); + const { selectedZone } = useSelectedZoneStore(); + const { top, setTop } = useTopData(); + const { left, setLeft } = useLeftData(); + const { rightSelect, setRightSelect } = useRightSelected(); + const { setEditWidgetOptions } = useEditWidgetOptionsStore(); - const { zoneWidgetData, setZoneWidgetData, addWidget, updateWidgetPosition, updateWidgetRotation } = useZoneWidgetStore(); - const { setWidgets3D } = use3DWidget(); - const { visualizationSocket } = useSocketStore(); - const { rightClickSelected, setRightClickSelected } = useRightClickSelected(); - const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // Floor plane for horizontal move - const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0)); // Vertical plane for vertical move - const planeIntersect = useRef(new THREE.Vector3()); - // const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0); - // const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0); - // const planeIntersect = useRef(new THREE.Vector3()); - const rotationStartRef = useRef<[number, number, number]>([0, 0, 0]); - const mouseStartRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); + const { + zoneWidgetData, + setZoneWidgetData, + addWidget, + updateWidgetPosition, + updateWidgetRotation, + } = useZoneWidgetStore(); + const { setWidgets3D } = use3DWidget(); + const { visualizationSocket } = useSocketStore(); + const { rightClickSelected, setRightClickSelected } = useRightClickSelected(); + const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // Floor plane for horizontal move + const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0)); // Vertical plane for vertical move + const planeIntersect = useRef(new THREE.Vector3()); + // const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0); + // const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0); + // const planeIntersect = useRef(new THREE.Vector3()); + const rotationStartRef = useRef<[number, number, number]>([0, 0, 0]); + const mouseStartRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); - useEffect(() => { - if (activeModule !== "visualization") return; - if (!selectedZone.zoneId) return; + useEffect(() => { + if (activeModule !== "visualization") return; + if (!selectedZone.zoneId) return; - const email = localStorage.getItem("email") || ""; - const organization = email?.split("@")[1]?.split(".")[0]; + const email = localStorage.getItem("email") || ""; + const organization = email?.split("@")[1]?.split(".")[0]; - async function get3dWidgetData() { - const result = await get3dWidgetZoneData(selectedZone.zoneId, organization); - setWidgets3D(result); + async function get3dWidgetData() { + const result = await get3dWidgetZoneData( + selectedZone.zoneId, + organization + ); + setWidgets3D(result); - const formattedWidgets = result.map((widget: WidgetData) => ({ - id: widget.id, - type: widget.type, - position: widget.position, - rotation: widget.rotation || [0, 0, 0], - })); + const formattedWidgets = result.map((widget: WidgetData) => ({ + id: widget.id, + type: widget.type, + position: widget.position, + rotation: widget.rotation || [0, 0, 0], + })); - setZoneWidgetData(selectedZone.zoneId, formattedWidgets); + setZoneWidgetData(selectedZone.zoneId, formattedWidgets); + } + + get3dWidgetData(); + }, [selectedZone.zoneId, activeModule]); + + useEffect(() => { + if (activeModule !== "visualization") return; + if (widgetSubOption === "Floating" || widgetSubOption === "2D") return; + if (selectedZone.zoneName === "") return; + + const canvasElement = gl.domElement; + + const onDrop = async (event: DragEvent) => { + event.preventDefault(); + + const email = localStorage.getItem("email") || ""; + const organization = email?.split("@")[1]?.split(".")[0]; + if (!widgetSelect.startsWith("ui")) return; + const group1 = scene.getObjectByName("itemsGroup"); + if (!group1) return; + + 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; + const newWidget: WidgetData = { + id: generateUniqueId(), + type: widgetSelect, + position: [x, y, z], + rotation: [0, 0, 0], + }; + + const add3dWidget = { + organization: organization, + widget: newWidget, + zoneId: selectedZone.zoneId, + }; + + if (visualizationSocket) { + visualizationSocket.emit("v2:viz-3D-widget:add", add3dWidget); } - get3dWidgetData(); - }, [selectedZone.zoneId, activeModule]); + addWidget(selectedZone.zoneId, newWidget); + } + }; - useEffect(() => { - if (activeModule !== "visualization") return; - if (widgetSubOption === "Floating" || widgetSubOption === "2D") return; - if (selectedZone.zoneName === "") return; + canvasElement.addEventListener("drop", onDrop); + return () => { + canvasElement.removeEventListener("drop", onDrop); + }; + }, [widgetSelect, activeModule, selectedZone.zoneId, widgetSubOption]); - const canvasElement = gl.domElement; + const activeZoneWidgets = zoneWidgetData[selectedZone.zoneId] || []; - const onDrop = async (event: DragEvent) => { + useEffect(() => { + if (!rightClickSelected) return; + const email = localStorage.getItem("email") || ""; + const organization = email?.split("@")[1]?.split(".")[0]; + + if (rightSelect === "Duplicate") { + const widgetToDuplicate = activeZoneWidgets.find( + (w: WidgetData) => w.id === rightClickSelected + ); + if (!widgetToDuplicate) return; + const newWidget: WidgetData = { + id: generateUniqueId(), + type: widgetToDuplicate.type, + position: [ + widgetToDuplicate.position[0] + 0.5, + widgetToDuplicate.position[1], + widgetToDuplicate.position[2] + 0.5, + ], + rotation: widgetToDuplicate.rotation || [0, 0, 0], + }; + + const add3dWidget = { + organization, + widget: newWidget, + zoneId: selectedZone.zoneId, + }; + + addWidget(selectedZone.zoneId, newWidget); + setRightSelect(null); + setRightClickSelected(null); + } + + if (rightSelect === "Delete") { + const deleteWidget = { + organization, + widgetId: rightClickSelected, + zoneId: selectedZone.zoneId, + }; + + setZoneWidgetData( + selectedZone.zoneId, + activeZoneWidgets.filter((w: WidgetData) => w.id !== rightClickSelected) + ); + setRightClickSelected(null); + setRightSelect(null); + } + }, [rightSelect, rightClickSelected]); + + useEffect(() => { + const handleMouseDown = (event: MouseEvent) => { + if (!rightClickSelected || !rightSelect) return; + + if (rightSelect === "RotateX" || rightSelect === "RotateY") { + mouseStartRef.current = { x: event.clientX, y: event.clientY }; + + const selectedZone = Object.keys(zoneWidgetData).find( + (zoneId: string) => + zoneWidgetData[zoneId].some( + (widget: WidgetData) => widget.id === rightClickSelected + ) + ); + + if (!selectedZone) return; + + const selectedWidget = zoneWidgetData[selectedZone].find( + (widget: WidgetData) => widget.id === rightClickSelected + ); + if (selectedWidget) { + rotationStartRef.current = selectedWidget.rotation || [0, 0, 0]; + } + } + }; + + const handleMouseMove = (event: MouseEvent) => { + if (!rightClickSelected || !rightSelect) return; + const selectedZone = Object.keys(zoneWidgetData).find((zoneId: string) => + zoneWidgetData[zoneId].some( + (widget: WidgetData) => widget.id === rightClickSelected + ) + ); + if (!selectedZone) return; + + const selectedWidget = zoneWidgetData[selectedZone].find( + (widget: WidgetData) => widget.id === rightClickSelected + ); + if (!selectedWidget) return; + + const rect = gl.domElement.getBoundingClientRect(); + mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; + mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; + + raycaster.setFromCamera(mouse, camera); + + if ( + rightSelect === "Horizontal Move" && + raycaster.ray.intersectPlane(plane.current, planeIntersect.current) + ) { + const newPosition: [number, number, number] = [ + planeIntersect.current.x, + selectedWidget.position[1], + planeIntersect.current.z, + ]; + updateWidgetPosition(selectedZone, rightClickSelected, newPosition); + console.log("Horizontal Move - Final Position:", newPosition); + } + + if (rightSelect === "Vertical Move") { + if ( + raycaster.ray.intersectPlane( + verticalPlane.current, + planeIntersect.current + ) + ) { + updateWidgetPosition(selectedZone, rightClickSelected, [ + selectedWidget.position[0], + planeIntersect.current.y, + selectedWidget.position[2], + ]); + } + } + + if (rightSelect === "RotateX") { + const deltaX = event.clientX - mouseStartRef.current.x; + const rotationSpeed = 0.03; + const newRotation: [number, number, number] = [ + rotationStartRef.current[0] + deltaX * rotationSpeed, + rotationStartRef.current[1], + rotationStartRef.current[2], + ]; + updateWidgetRotation(selectedZone, rightClickSelected, newRotation); + } + + if (rightSelect === "RotateY") { + const deltaY = event.clientY - mouseStartRef.current.y; + const rotationSpeed = 0.03; + const newRotation: [number, number, number] = [ + rotationStartRef.current[0], + rotationStartRef.current[1] + deltaY * rotationSpeed, + rotationStartRef.current[2], + ]; + updateWidgetRotation(selectedZone, rightClickSelected, newRotation); + } + if (rightSelect === "RotateZ") { + const deltaX = event.movementX; + const rotationSpeed = 0.03; + const currentRotation = selectedWidget.rotation || [0, 0, 0]; + const newRotation: [number, number, number] = [ + currentRotation[0], + currentRotation[1], + currentRotation[2] + deltaX * rotationSpeed, + ]; + updateWidgetRotation(selectedZone, rightClickSelected, newRotation); + } + }; + + const handleMouseUp = () => { + if ( + rightClickSelected && + (rightSelect === "Horizontal Move" || + rightSelect === "Vertical Move" || + rightSelect === "RotateX" || + rightSelect === "RotateY" || + rightSelect === "RotateZ") + ) { + setTimeout(() => { + setRightClickSelected(null); + setRightSelect(null); + }, 50); + } + }; + + window.addEventListener("mousedown", handleMouseDown); + window.addEventListener("mousemove", handleMouseMove); + window.addEventListener("mouseup", handleMouseUp); + + return () => { + window.removeEventListener("mousedown", handleMouseDown); + window.removeEventListener("mousemove", handleMouseMove); + window.removeEventListener("mouseup", handleMouseUp); + }; + }, [rightClickSelected, rightSelect, zoneWidgetData, gl]); + + return ( + <> + {activeZoneWidgets.map( + ({ id, type, position, rotation = [0, 0, 0] }: WidgetData) => { + const handleRightClick = (event: React.MouseEvent, id: string) => { event.preventDefault(); - - const email = localStorage.getItem("email") || ""; - const organization = email?.split("@")[1]?.split(".")[0]; - if (!widgetSelect.startsWith("ui")) return; - const group1 = scene.getObjectByName("itemsGroup"); - if (!group1) return; - - 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") + 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; + setEditWidgetOptions(true); + setRightClickSelected(id); - if (intersects.length > 0) { - const { x, y, z } = intersects[0].point; - const newWidget: WidgetData = { - id: generateUniqueId(), - type: widgetSelect, - position: [x, y, z], - rotation: [0, 0, 0], - }; + setTop(relativeY); + setLeft(relativeX); + }; - const add3dWidget = { - organization: organization, - widget: newWidget, - zoneId: selectedZone.zoneId - }; - - if (visualizationSocket) { - visualizationSocket.emit("v2:viz-3D-widget:add", add3dWidget); - } - - addWidget(selectedZone.zoneId, newWidget); - } - }; - - canvasElement.addEventListener("drop", onDrop); - return () => { - canvasElement.removeEventListener("drop", onDrop); - }; - }, [widgetSelect, activeModule, selectedZone.zoneId, widgetSubOption]); - - const activeZoneWidgets = zoneWidgetData[selectedZone.zoneId] || []; - - useEffect(() => { - if (!rightClickSelected) return; - const email = localStorage.getItem("email") || ""; - const organization = email?.split("@")[1]?.split(".")[0]; - - if (rightSelect === "Duplicate") { - const widgetToDuplicate = activeZoneWidgets.find((w: WidgetData) => w.id === rightClickSelected); - if (!widgetToDuplicate) return; - const newWidget: WidgetData = { - id: generateUniqueId(), - type: widgetToDuplicate.type, - position: [ - widgetToDuplicate.position[0] + 0.5, - widgetToDuplicate.position[1], - widgetToDuplicate.position[2] + 0.5, - ], - rotation: widgetToDuplicate.rotation || [0, 0, 0], - }; - - const add3dWidget = { - organization, - widget: newWidget, - zoneId: selectedZone.zoneId - }; - - addWidget(selectedZone.zoneId, newWidget); - setRightSelect(null); - setRightClickSelected(null); + switch (type) { + case "ui-Widget 1": + return ( + handleRightClick(e, id)} + /> + ); + case "ui-Widget 2": + return ( + handleRightClick(e, id)} + /> + ); + case "ui-Widget 3": + return ( + handleRightClick(e, id)} + /> + ); + case "ui-Widget 4": + return ( + handleRightClick(e, id)} + /> + ); + default: + return null; + } } - - if (rightSelect === "Delete") { - const deleteWidget = { - organization, - widgetId: rightClickSelected, - zoneId: selectedZone.zoneId - }; - - setZoneWidgetData( - selectedZone.zoneId, - activeZoneWidgets.filter((w: WidgetData) => w.id !== rightClickSelected) - ); - setRightClickSelected(null); - setRightSelect(null); - } - }, [rightSelect, rightClickSelected]); - - useEffect(() => { - const handleMouseDown = (event: MouseEvent) => { - if (!rightClickSelected || !rightSelect) return; - - if (rightSelect === "RotateX" || rightSelect === "RotateY") { - mouseStartRef.current = { x: event.clientX, y: event.clientY }; - - const selectedZone = Object.keys(zoneWidgetData).find((zoneId: string) => - zoneWidgetData[zoneId].some((widget: WidgetData) => widget.id === rightClickSelected) - ); - - if (!selectedZone) return; - - const selectedWidget = zoneWidgetData[selectedZone].find((widget: WidgetData) => widget.id === rightClickSelected); - if (selectedWidget) { - rotationStartRef.current = selectedWidget.rotation || [0, 0, 0]; - } - } - }; - - const handleMouseMove = (event: MouseEvent) => { - if (!rightClickSelected || !rightSelect) return; - const selectedZone = Object.keys(zoneWidgetData).find((zoneId: string) => - zoneWidgetData[zoneId].some((widget: WidgetData) => widget.id === rightClickSelected) - ); - if (!selectedZone) return; - - const selectedWidget = zoneWidgetData[selectedZone].find((widget: WidgetData) => widget.id === rightClickSelected); - if (!selectedWidget) return; - - const rect = gl.domElement.getBoundingClientRect(); - mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; - mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; - - raycaster.setFromCamera(mouse, camera); - - if (rightSelect === "Horizontal Move" && raycaster.ray.intersectPlane(plane.current, planeIntersect.current)) { - const newPosition: [number, number, number] = [ - planeIntersect.current.x, - selectedWidget.position[1], - planeIntersect.current.z - ]; - updateWidgetPosition(selectedZone, rightClickSelected, newPosition); - console.log('Horizontal Move - Final Position:', newPosition); - } - - if (rightSelect === "Vertical Move") { - if (raycaster.ray.intersectPlane(verticalPlane.current, planeIntersect.current)) { - updateWidgetPosition(selectedZone, rightClickSelected, [ - selectedWidget.position[0], - planeIntersect.current.y, - selectedWidget.position[2] - ]); - } - } - - if (rightSelect === "RotateX") { - const deltaX = event.clientX - mouseStartRef.current.x; - const rotationSpeed = 0.03; - const newRotation: [number, number, number] = [ - rotationStartRef.current[0] + deltaX * rotationSpeed, - rotationStartRef.current[1], - rotationStartRef.current[2] - ]; - updateWidgetRotation(selectedZone, rightClickSelected, newRotation); - } - - if (rightSelect === "RotateY") { - const deltaY = event.clientY - mouseStartRef.current.y; - const rotationSpeed = 0.03; - const newRotation: [number, number, number] = [ - rotationStartRef.current[0], - rotationStartRef.current[1] + deltaY * rotationSpeed, - rotationStartRef.current[2] - ]; - updateWidgetRotation(selectedZone, rightClickSelected, newRotation); - } - if (rightSelect === "RotateZ") { - const deltaX = event.movementX; - const rotationSpeed = 0.03; - const currentRotation = selectedWidget.rotation || [0, 0, 0]; - const newRotation: [number, number, number] = [ - currentRotation[0], - currentRotation[1], - currentRotation[2] + deltaX * rotationSpeed - ]; - updateWidgetRotation(selectedZone, rightClickSelected, newRotation); - } - - }; - - const handleMouseUp = () => { - if (rightClickSelected && ( - rightSelect === "Horizontal Move" || - rightSelect === "Vertical Move" || - rightSelect === "RotateX" || - rightSelect === "RotateY" || rightSelect === "RotateZ" - )) { - setTimeout(() => { - setRightClickSelected(null); - setRightSelect(null); - }, 50); - } - }; - - window.addEventListener("mousedown", handleMouseDown); - window.addEventListener("mousemove", handleMouseMove); - window.addEventListener("mouseup", handleMouseUp); - - return () => { - window.removeEventListener("mousedown", handleMouseDown); - window.removeEventListener("mousemove", handleMouseMove); - window.removeEventListener("mouseup", handleMouseUp); - }; - }, [rightClickSelected, rightSelect, zoneWidgetData, gl]); - - return ( - <> - {activeZoneWidgets.map(({ id, type, position, rotation = [0, 0, 0] }: WidgetData) => { - const handleRightClick = (event: React.MouseEvent, id: string) => { - event.preventDefault(); - 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; - setRightClickSelected(id); - setTop(relativeY); - setLeft(relativeX); - }; - - switch (type) { - case "ui-Widget 1": - return ( - handleRightClick(e, id)} - /> - ); - case "ui-Widget 2": - return ( - handleRightClick(e, id)} - /> - ); - case "ui-Widget 3": - return ( - handleRightClick(e, id)} - /> - ); - case "ui-Widget 4": - return ( - handleRightClick(e, id)} - /> - ); - default: - return null; - } - })} - - ); -} \ No newline at end of file + )} + + ); +} diff --git a/app/src/components/ui/componets/RealTimeVisulization.tsx b/app/src/components/ui/componets/RealTimeVisulization.tsx index acbbf68..4b8d7c8 100644 --- a/app/src/components/ui/componets/RealTimeVisulization.tsx +++ b/app/src/components/ui/componets/RealTimeVisulization.tsx @@ -7,7 +7,6 @@ import DisplayZone from "./DisplayZone"; import Scene from "../../../modules/scene/scene"; import useModuleStore from "../../../store/useModuleStore"; - import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore"; import { useAsset3dWidget, @@ -24,7 +23,11 @@ import RenderOverlay from "../../templates/Overlay"; import ConfirmationPopup from "../../layout/confirmationPopup/ConfirmationPopup"; import DroppedObjects from "./DroppedFloatingWidgets"; import EditWidgetOption from "../menu/EditWidgetOption"; -import { useRightClickSelected } from "../../../store/useZone3DWidgetStore"; +import { + useRightClickSelected, + useRightSelected, + useEditWidgetOptionsStore, +} from "../../../store/useZone3DWidgetStore"; type Side = "top" | "bottom" | "left" | "right"; @@ -57,9 +60,9 @@ const RealTimeVisulization: React.FC = () => { const [droppedObjects, setDroppedObjects] = useState([]); const [zonesData, setZonesData] = useState({}); const { selectedZone, setSelectedZone } = useSelectedZoneStore(); - - - const { rightClickSelected, setRightClickSelected } = useRightClickSelected() + + const { editWidgetOptions, setEditWidgetOptions } = useEditWidgetOptionsStore(); + const { rightClickSelected, setRightClickSelected } = useRightClickSelected(); const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false); const [floatingWidgets, setFloatingWidgets] = useState< @@ -68,6 +71,7 @@ const RealTimeVisulization: React.FC = () => { const { widgetSelect, setWidgetSelect } = useAsset3dWidget(); const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption(); const { visualizationSocket } = useSocketStore(); + const { setRightSelect } = useRightSelected(); useEffect(() => { async function GetZoneData() { @@ -96,7 +100,7 @@ const RealTimeVisulization: React.FC = () => { {} ); setZonesData(formattedData); - } catch (error) { } + } catch (error) {} } GetZoneData(); @@ -142,8 +146,8 @@ const RealTimeVisulization: React.FC = () => { const relativeX = event.clientX - canvasRect.left; const relativeY = event.clientY - canvasRect.top; - const newPosition = determinePosition(canvasRect, relativeX, relativeY) - console.log('newPosition: ', newPosition); + const newPosition = determinePosition(canvasRect, relativeX, relativeY); + console.log("newPosition: ", newPosition); const newObject = { ...droppedData, id: generateUniqueId(), @@ -162,12 +166,12 @@ const RealTimeVisulization: React.FC = () => { let addFloatingWidget = { organization: organization, widget: newObject, - zoneId: selectedZone.zoneId - } - console.log('newObject: ', newObject); + zoneId: selectedZone.zoneId, + }; + console.log("newObject: ", newObject); if (visualizationSocket) { - visualizationSocket.emit("v2:viz-float:add", addFloatingWidget) + visualizationSocket.emit("v2:viz-float:add", addFloatingWidget); } // let response = await addingFloatingWidgets( @@ -194,9 +198,30 @@ const RealTimeVisulization: React.FC = () => { ], }, })); - } catch (error) { } + } catch (error) {} }; + // Add this useEffect hook to your component + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + const editWidgetOptions = document.querySelector( + ".editWidgetOptions-wrapper" + ); + if ( + editWidgetOptions && + !editWidgetOptions.contains(event.target as Node) + ) { + setRightClickSelected(null); + setRightSelect(null); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, [setRightClickSelected]); + return (
{ >
- {activeModule === "visualization" && selectedZone.zoneName !== "" && } + {activeModule === "visualization" && selectedZone.zoneName !== "" && ( + + )} {activeModule === "visualization" && } - {activeModule === "visualization" && rightClickSelected && } + {activeModule === "visualization" && + editWidgetOptions && + rightClickSelected && ( + + )} {activeModule === "visualization" && ( <> diff --git a/app/src/components/ui/menu/EditWidgetOption.tsx b/app/src/components/ui/menu/EditWidgetOption.tsx index 3978430..f1d6263 100644 --- a/app/src/components/ui/menu/EditWidgetOption.tsx +++ b/app/src/components/ui/menu/EditWidgetOption.tsx @@ -1,34 +1,51 @@ import React, { useEffect } from "react"; -import { useLeftData, useRightSelected, useTopData } from "../../../store/useZone3DWidgetStore"; +import { + useEditWidgetOptionsStore, + useLeftData, + useRightClickSelected, + useRightSelected, + useTopData, +} from "../../../store/useZone3DWidgetStore"; interface EditWidgetOptionProps { + setWidgetSelect: any; options: string[]; } -const EditWidgetOption: React.FC = ({ options }) => { - const { top, setTop } = useTopData() - const { left, setLeft } = useLeftData() - const { rightSelect, setRightSelect } = useRightSelected() +const EditWidgetOption: React.FC = ({ + setWidgetSelect, + options, +}) => { + const { top, setTop } = useTopData(); + const { left, setLeft } = useLeftData(); + const { rightSelect, setRightSelect } = useRightSelected(); + const { setEditWidgetOptions } = useEditWidgetOptionsStore(); useEffect(() => { - - console.log('left: ', left); - console.log('top: ', top); - }, [top, left]) + console.log("left: ", left); + console.log("top: ", top); + }, [top, left]); return ( -
{options.map((option, index) => ( -
setRightSelect(option)}> +
{ + setRightSelect(option); + setEditWidgetOptions(false); + }} + > {option}
))} diff --git a/app/src/store/useZone3DWidgetStore.ts b/app/src/store/useZone3DWidgetStore.ts index 9700878..425674f 100644 --- a/app/src/store/useZone3DWidgetStore.ts +++ b/app/src/store/useZone3DWidgetStore.ts @@ -96,3 +96,14 @@ export const useRightSelected = create((set) => ({ rightSelect: null, // Default state is null setRightSelect: (x) => set({ rightSelect: x }), })); + + +interface EditWidgetOptionsStore { + editWidgetOptions: boolean; + setEditWidgetOptions: (value: boolean) => void; +} + +export const useEditWidgetOptionsStore = create((set) => ({ + editWidgetOptions: false, // Initial state + setEditWidgetOptions: (value: boolean) => set({ editWidgetOptions: value }), +})); diff --git a/app/src/styles/pages/realTimeViz.scss b/app/src/styles/pages/realTimeViz.scss index a79823c..74ef66e 100644 --- a/app/src/styles/pages/realTimeViz.scss +++ b/app/src/styles/pages/realTimeViz.scss @@ -719,9 +719,9 @@ .editWidgetOptions { position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); + // top: 50%; + // left: 50%; + // transform: translate(-50%, -50%); background-color: var(--background-color); z-index: 3; display: flex; @@ -729,6 +729,7 @@ border-radius: 6px; overflow: hidden; +min-width: 150px; .option { padding: 8px 10px; color: var(--text-color);