merged with main
This commit is contained in:
commit
f13065f811
|
@ -25,7 +25,7 @@ interface ProductionCapacityProps {
|
||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ position }) => {
|
const ProductionCapacity: React.FC<ProductionCapacityProps> = ({ position }) => {
|
||||||
// Chart data for a week
|
// Chart data for a week
|
||||||
const chartData = {
|
const chartData = {
|
||||||
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], // Days of the week
|
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], // Days of the week
|
||||||
|
@ -79,10 +79,11 @@ const ProductionCapacity : React.FC<ProductionCapacityProps> = ({ position }) =>
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html position={[position[0], position[1], position[2]] }
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
sprite>
|
zIndexRange={[1,0]}
|
||||||
|
sprite>
|
||||||
<div className="productionCapacity-wrapper card">
|
<div className="productionCapacity-wrapper card">
|
||||||
<div className="headeproductionCapacityr-wrapper">
|
<div className="headeproductionCapacityr-wrapper">
|
||||||
<div className="header">Production Capacity</div>
|
<div className="header">Production Capacity</div>
|
||||||
|
|
|
@ -111,6 +111,7 @@ const ReturnOfInvestment: React.FC<ReturnOfInvestmentProps> = ({ position }) =>
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html position={[position[0], position[1], position[2]]}
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
|
zIndexRange={[1,0]}
|
||||||
sprite>
|
sprite>
|
||||||
<div className="returnOfInvestment card">
|
<div className="returnOfInvestment card">
|
||||||
<div className="header">Return of Investment</div>
|
<div className="header">Return of Investment</div>
|
||||||
|
|
|
@ -16,6 +16,7 @@ const StateWorking: React.FC<StateWorkingProps> = ({ position }) => {
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html position={[position[0], position[1], position[2]]}
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
|
zIndexRange={[1,0]}
|
||||||
sprite>
|
sprite>
|
||||||
<div className="stateWorking-wrapper card">
|
<div className="stateWorking-wrapper card">
|
||||||
<div className="header-wrapper">
|
<div className="header-wrapper">
|
||||||
|
|
|
@ -94,6 +94,7 @@ const Throughput: React.FC<ThroughputProps> = ({ position }) => {
|
||||||
<Html position={[position[0], position[1], position[2]]}
|
<Html position={[position[0], position[1], position[2]]}
|
||||||
scale={[0.5, 0.5, 0.5]}
|
scale={[0.5, 0.5, 0.5]}
|
||||||
transform
|
transform
|
||||||
|
zIndexRange={[1, 0]}
|
||||||
sprite>
|
sprite>
|
||||||
<div className="throughput-wrapper">
|
<div className="throughput-wrapper">
|
||||||
<div className="header">Throughput</div>
|
<div className="header">Throughput</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
CleanPannel,
|
CleanPannel,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
|
@ -6,6 +6,8 @@ import {
|
||||||
} from "../../icons/RealTimeVisulationIcons";
|
} from "../../icons/RealTimeVisulationIcons";
|
||||||
import { panelData } from "../../../services/realTimeVisulization/zoneData/panel";
|
import { panelData } from "../../../services/realTimeVisulization/zoneData/panel";
|
||||||
import { AddIcon } from "../../icons/ExportCommonIcons";
|
import { AddIcon } from "../../icons/ExportCommonIcons";
|
||||||
|
import { deletePanelApi } from "../../../services/realTimeVisulization/zoneData/deletePanel";
|
||||||
|
import { useSocketStore } from "../../../store/store";
|
||||||
|
|
||||||
// Define the type for `Side`
|
// Define the type for `Side`
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
@ -16,7 +18,6 @@ interface ButtonsProps {
|
||||||
zoneName: string;
|
zoneName: string;
|
||||||
activeSides: Side[];
|
activeSides: Side[];
|
||||||
panelOrder: Side[];
|
panelOrder: Side[];
|
||||||
|
|
||||||
lockedPanels: Side[];
|
lockedPanels: Side[];
|
||||||
zoneId: string;
|
zoneId: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
|
@ -34,7 +35,7 @@ interface ButtonsProps {
|
||||||
zoneName: string;
|
zoneName: string;
|
||||||
activeSides: Side[];
|
activeSides: Side[];
|
||||||
panelOrder: Side[];
|
panelOrder: Side[];
|
||||||
|
|
||||||
lockedPanels: Side[];
|
lockedPanels: Side[];
|
||||||
zoneId: string;
|
zoneId: string;
|
||||||
zoneViewPortTarget: number[];
|
zoneViewPortTarget: number[];
|
||||||
|
@ -58,6 +59,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
setHiddenPanels,
|
setHiddenPanels,
|
||||||
hiddenPanels,
|
hiddenPanels,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
|
||||||
// Local state to track hidden panels
|
// Local state to track hidden panels
|
||||||
|
|
||||||
// Function to toggle lock/unlock a panel
|
// Function to toggle lock/unlock a panel
|
||||||
|
@ -103,9 +107,13 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to handle "+" button click
|
// Function to handle "+" button click
|
||||||
const handlePlusButtonClick = (side: Side) => {
|
const handlePlusButtonClick = async (side: Side) => {
|
||||||
if (selectedZone.activeSides.includes(side)) {
|
if (selectedZone.activeSides.includes(side)) {
|
||||||
// If the panel is already active, remove all widgets and close the panel
|
// Panel already exists: Remove widgets from that side and update activeSides
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
||||||
|
|
||||||
|
// Remove all widgets associated with the side and update active sides
|
||||||
const cleanedWidgets = selectedZone.widgets.filter(
|
const cleanedWidgets = selectedZone.widgets.filter(
|
||||||
(widget) => widget.panel !== side
|
(widget) => widget.panel !== side
|
||||||
);
|
);
|
||||||
|
@ -118,44 +126,68 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
panelOrder: newActiveSides,
|
panelOrder: newActiveSides,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Delete the selectedZone state
|
let deletePanel = {
|
||||||
|
organization: organization,
|
||||||
|
panelName: side,
|
||||||
|
zoneId: selectedZone.zoneId
|
||||||
|
}
|
||||||
|
if (visualizationSocket) {
|
||||||
|
visualizationSocket.emit("v2:viz-panel:delete", deletePanel)
|
||||||
|
}
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
|
|
||||||
|
// API call to delete the panel
|
||||||
|
// try {
|
||||||
|
// const response = await deletePanelApi(selectedZone.zoneId, side, organization);
|
||||||
|
//
|
||||||
|
// if (response.message === "Panel deleted successfully") {
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
const updatePanelData = async () => {
|
// Panel does not exist: Create panel
|
||||||
try {
|
try {
|
||||||
// Get email and organization safely
|
// Get email and organization safely with a default fallback
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0] || "defaultOrg"; // Fallback value
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
// Prevent duplicate side entries
|
// Prevent duplicate side entries
|
||||||
const newActiveSides = selectedZone.activeSides.includes(side)
|
const newActiveSides = selectedZone.activeSides.includes(side)
|
||||||
? [...selectedZone.activeSides]
|
? [...selectedZone.activeSides]
|
||||||
: [...selectedZone.activeSides, side];
|
: [...selectedZone.activeSides, side];
|
||||||
|
|
||||||
const updatedZone = {
|
const updatedZone = {
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
activeSides: newActiveSides,
|
activeSides: newActiveSides,
|
||||||
panelOrder: newActiveSides,
|
panelOrder: newActiveSides,
|
||||||
};
|
};
|
||||||
|
let addPanel = {
|
||||||
// API call
|
organization: organization,
|
||||||
const response = await panelData(organization, selectedZone.zoneId, newActiveSides);
|
zoneId: selectedZone.zoneId,
|
||||||
|
panelOrder: newActiveSides
|
||||||
|
|
||||||
// Update state
|
|
||||||
|
|
||||||
setSelectedZone(updatedZone);
|
|
||||||
} catch (error) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
if (visualizationSocket) {
|
||||||
|
visualizationSocket.emit("v2:viz-panel:add", addPanel)
|
||||||
|
}
|
||||||
|
setSelectedZone(updatedZone);
|
||||||
|
// API call to create panels
|
||||||
|
// const response = await panelData(organization, selectedZone.zoneId, newActiveSides);
|
||||||
|
//
|
||||||
|
|
||||||
updatePanelData(); // Call the async function
|
// if (response.message === "Panels created successfully") {
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -2,7 +2,10 @@ import React, { useEffect, useRef, useState, useCallback } from "react";
|
||||||
import { Widget } from "../../../store/useWidgetStore";
|
import { Widget } from "../../../store/useWidgetStore";
|
||||||
import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
|
import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
|
||||||
import { InfoIcon } from "../../icons/ExportCommonIcons";
|
import { InfoIcon } from "../../icons/ExportCommonIcons";
|
||||||
import { useDroppedObjectsStore, useFloatingWidget } from "../../../store/useDroppedObjectsStore";
|
import {
|
||||||
|
useDroppedObjectsStore,
|
||||||
|
useFloatingWidget,
|
||||||
|
} from "../../../store/useDroppedObjectsStore";
|
||||||
import { getSelect2dZoneData } from "../../../services/realTimeVisulization/zoneData/getSelect2dZoneData";
|
import { getSelect2dZoneData } from "../../../services/realTimeVisulization/zoneData/getSelect2dZoneData";
|
||||||
import { getFloatingZoneData } from "../../../services/realTimeVisulization/zoneData/getFloatingData";
|
import { getFloatingZoneData } from "../../../services/realTimeVisulization/zoneData/getFloatingData";
|
||||||
import { get3dWidgetZoneData } from "../../../services/realTimeVisulization/zoneData/get3dWidgetData";
|
import { get3dWidgetZoneData } from "../../../services/realTimeVisulization/zoneData/get3dWidgetData";
|
||||||
|
@ -63,7 +66,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
selectedZone,
|
selectedZone,
|
||||||
setSelectedZone,
|
setSelectedZone,
|
||||||
}) => {
|
}) => {
|
||||||
// Refs
|
// Ref for the container element
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const scrollContainerRef = useRef<HTMLDivElement | null>(null);
|
const scrollContainerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
@ -150,10 +153,11 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
let response = await getSelect2dZoneData(zoneId, organization);
|
let response = await getSelect2dZoneData(zoneId, organization);
|
||||||
console.log('response: ', response);
|
|
||||||
let res = await getFloatingZoneData(zoneId, organization);
|
let res = await getFloatingZoneData(zoneId, organization);
|
||||||
|
|
||||||
setFloatingWidget(res);
|
setFloatingWidget(res);
|
||||||
|
// Set the selected zone in the store
|
||||||
useDroppedObjectsStore.getState().setZone(zoneName, zoneId);
|
useDroppedObjectsStore.getState().setZone(zoneName, zoneId);
|
||||||
if (Array.isArray(res)) {
|
if (Array.isArray(res)) {
|
||||||
res.forEach((val) => {
|
res.forEach((val) => {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { useEffect, useRef, useState } from "react";
|
||||||
import { duplicateWidgetApi } from "../../../services/realTimeVisulization/zoneData/duplicateWidget";
|
import { duplicateWidgetApi } from "../../../services/realTimeVisulization/zoneData/duplicateWidget";
|
||||||
import { deleteWidgetApi } from "../../../services/realTimeVisulization/zoneData/deleteWidgetApi";
|
import { deleteWidgetApi } from "../../../services/realTimeVisulization/zoneData/deleteWidgetApi";
|
||||||
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
|
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
|
||||||
|
import { useSocketStore } from "../../../store/store";
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ export const DraggableWidget = ({
|
||||||
openKebabId: string | null;
|
openKebabId: string | null;
|
||||||
setOpenKebabId: (id: string | null) => void;
|
setOpenKebabId: (id: string | null) => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const { visualizationSocket } = useSocketStore();
|
||||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||||
const [panelDimensions, setPanelDimensions] = useState<{
|
const [panelDimensions, setPanelDimensions] = useState<{
|
||||||
[side in Side]?: { width: number; height: number };
|
[side in Side]?: { width: number; height: number };
|
||||||
|
@ -88,16 +90,34 @@ export const DraggableWidget = ({
|
||||||
try {
|
try {
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
const response = await deleteWidgetApi(widget.id, organization);
|
let deleteWidget = {
|
||||||
if (response?.message === "Widget deleted successfully") {
|
zoneId: selectedZone.zoneId,
|
||||||
const updatedWidgets = selectedZone.widgets.filter(
|
widgetID: widget.id,
|
||||||
(w: Widget) => w.id !== widget.id
|
organization: organization
|
||||||
);
|
|
||||||
setSelectedZone((prevZone: any) => ({
|
|
||||||
...prevZone,
|
|
||||||
widgets: updatedWidgets,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
if (visualizationSocket) {
|
||||||
|
visualizationSocket.emit("v2:viz-widget:delete", deleteWidget)
|
||||||
|
}
|
||||||
|
const updatedWidgets = selectedZone.widgets.filter(
|
||||||
|
(w: Widget) => w.id !== widget.id
|
||||||
|
);
|
||||||
|
console.log('updatedWidgets: ', updatedWidgets);
|
||||||
|
setSelectedZone((prevZone: any) => ({
|
||||||
|
...prevZone,
|
||||||
|
widgets: updatedWidgets,
|
||||||
|
}));
|
||||||
|
setOpenKebabId(null);
|
||||||
|
|
||||||
|
// 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) {
|
} catch (error) {
|
||||||
} finally {
|
} finally {
|
||||||
setOpenKebabId(null);
|
setOpenKebabId(null);
|
||||||
|
@ -271,14 +291,14 @@ export const DraggableWidget = ({
|
||||||
title={widget.title}
|
title={widget.title}
|
||||||
fontSize={widget.fontSize}
|
fontSize={widget.fontSize}
|
||||||
fontWeight={widget.fontWeight}
|
fontWeight={widget.fontWeight}
|
||||||
// data={{
|
// data={{
|
||||||
// measurements: [
|
// measurements: [
|
||||||
// { name: "testDevice", fields: "powerConsumption" },
|
// { name: "testDevice", fields: "powerConsumption" },
|
||||||
// { name: "furnace", fields: "powerConsumption" },
|
// { name: "furnace", fields: "powerConsumption" },
|
||||||
// ],
|
// ],
|
||||||
// interval: 1000,
|
// interval: 1000,
|
||||||
// duration: "1h",
|
// duration: "1h",
|
||||||
// }}
|
// }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{widget.type === "bar" && (
|
{widget.type === "bar" && (
|
||||||
|
@ -288,14 +308,14 @@ export const DraggableWidget = ({
|
||||||
title={widget.title}
|
title={widget.title}
|
||||||
fontSize={widget.fontSize}
|
fontSize={widget.fontSize}
|
||||||
fontWeight={widget.fontWeight}
|
fontWeight={widget.fontWeight}
|
||||||
// data={{
|
// data={{
|
||||||
// measurements: [
|
// measurements: [
|
||||||
// { name: "testDevice", fields: "powerConsumption" },
|
// { name: "testDevice", fields: "powerConsumption" },
|
||||||
// { name: "furnace", fields: "powerConsumption" },
|
// { name: "furnace", fields: "powerConsumption" },
|
||||||
// ],
|
// ],
|
||||||
// interval: 1000,
|
// interval: 1000,
|
||||||
// duration: "1h",
|
// duration: "1h",
|
||||||
// }}
|
// }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{widget.type === "pie" && (
|
{widget.type === "pie" && (
|
||||||
|
@ -305,14 +325,14 @@ export const DraggableWidget = ({
|
||||||
title={widget.title}
|
title={widget.title}
|
||||||
fontSize={widget.fontSize}
|
fontSize={widget.fontSize}
|
||||||
fontWeight={widget.fontWeight}
|
fontWeight={widget.fontWeight}
|
||||||
// data={{
|
// data={{
|
||||||
// measurements: [
|
// measurements: [
|
||||||
// { name: "testDevice", fields: "powerConsumption" },
|
// { name: "testDevice", fields: "powerConsumption" },
|
||||||
// { name: "furnace", fields: "powerConsumption" },
|
// { name: "furnace", fields: "powerConsumption" },
|
||||||
// ],
|
// ],
|
||||||
// interval: 1000,
|
// interval: 1000,
|
||||||
// duration: "1h",
|
// duration: "1h",
|
||||||
// }}
|
// }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{widget.type === "doughnut" && (
|
{widget.type === "doughnut" && (
|
||||||
|
|
|
@ -35,15 +35,16 @@ export default function Dropped3dWidgets() {
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
async function get3dWidgetData() {
|
async function get3dWidgetData() {
|
||||||
let result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
|
let result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
|
||||||
setWidgets3D(result);
|
console.log('result: ', result);
|
||||||
// Ensure the extracted data has id, type, and position correctly mapped
|
setWidgets3D(result)
|
||||||
const formattedWidgets = result.map((widget: any) => ({
|
// Ensure the extracted data has id, type, and position correctly mapped
|
||||||
id: widget.id,
|
const formattedWidgets = result.map((widget: any) => ({
|
||||||
type: widget.type,
|
id: widget.id,
|
||||||
position: widget.position,
|
type: widget.type,
|
||||||
}));
|
position: widget.position,
|
||||||
|
}));
|
||||||
|
|
||||||
setZoneWidgetData((prev) => ({
|
setZoneWidgetData((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
|
|
|
@ -80,6 +80,8 @@ const DroppedObjects: React.FC = () => {
|
||||||
// useClickOutside(chartWidget, () => {
|
// useClickOutside(chartWidget, () => {
|
||||||
// setSelectedChartId(null);
|
// setSelectedChartId(null);
|
||||||
// });
|
// });
|
||||||
|
const kebabRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
|
||||||
// Clean up animation frame on unmount
|
// Clean up animation frame on unmount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -89,6 +91,21 @@ const DroppedObjects: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (kebabRef.current && !kebabRef.current.contains(event.target as Node)) {
|
||||||
|
setOpenKebabId(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add event listener when component mounts
|
||||||
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
|
|
||||||
|
// Clean up event listener when component unmounts
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("mousedown", handleClickOutside);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const zoneEntries = Object.entries(zones);
|
const zoneEntries = Object.entries(zones);
|
||||||
if (zoneEntries.length === 0) return null;
|
if (zoneEntries.length === 0) return null;
|
||||||
|
@ -107,25 +124,18 @@ const DroppedObjects: React.FC = () => {
|
||||||
let res = await deleteFloatingWidgetApi(id, organization);
|
let res = await deleteFloatingWidgetApi(id, organization);
|
||||||
|
|
||||||
if (res.message === "FloatingWidget deleted successfully") {
|
if (res.message === "FloatingWidget deleted successfully") {
|
||||||
deleteObject(zoneName, index); // Call the deleteObject method from the store
|
deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
||||||
if (
|
if ((event.target as HTMLElement).closest(".kebab-options") || (event.target as HTMLElement).closest(".kebab")) {
|
||||||
(event.target as HTMLElement).closest(".kebab-options") ||
|
return; // Prevent dragging when clicking on the kebab menu or its options
|
||||||
(event.target as HTMLElement).closest(".kebab")
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (isPlaying === true) return;
|
|
||||||
const obj = zone.objects[index];
|
const obj = zone.objects[index];
|
||||||
const element = event.currentTarget as HTMLElement;
|
const element = event.currentTarget as HTMLElement;
|
||||||
|
|
||||||
// Set pointer capture to ensure we get all move events
|
|
||||||
element.setPointerCapture(event.pointerId);
|
element.setPointerCapture(event.pointerId);
|
||||||
|
|
||||||
const container = document.getElementById("real-time-vis-canvas");
|
const container = document.getElementById("real-time-vis-canvas");
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
|
@ -169,6 +179,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
// Add native event listeners for smoother tracking
|
// Add native event listeners for smoother tracking
|
||||||
const handlePointerMoveNative = (e: PointerEvent) => {
|
const handlePointerMoveNative = (e: PointerEvent) => {
|
||||||
if (!draggingIndex || !offset) return;
|
if (!draggingIndex || !offset) return;
|
||||||
|
if (isPlaying === true) return;
|
||||||
|
|
||||||
const rect = container.getBoundingClientRect();
|
const rect = container.getBoundingClientRect();
|
||||||
const relativeX = e.clientX - rect.left;
|
const relativeX = e.clientX - rect.left;
|
||||||
|
@ -356,14 +367,21 @@ const DroppedObjects: React.FC = () => {
|
||||||
|
|
||||||
// Update the current position state for DistanceLines
|
// Update the current position state for DistanceLines
|
||||||
setCurrentPosition(newPosition);
|
setCurrentPosition(newPosition);
|
||||||
|
|
||||||
// Update position immediately without animation frame
|
// Update position immediately without animation frame
|
||||||
updateObjectPosition(zoneName, draggingIndex.index, newPosition);
|
updateObjectPosition(zoneName, draggingIndex.index, newPosition);
|
||||||
|
|
||||||
|
// if (!animationRef.current) {
|
||||||
|
// animationRef.current = requestAnimationFrame(() => {
|
||||||
|
// updateObjectPosition(zoneName, draggingIndex.index, newPosition);
|
||||||
|
// animationRef.current = null;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePointerUp = async (event: React.PointerEvent<HTMLDivElement>) => {
|
const handlePointerUp = async (event: React.PointerEvent<HTMLDivElement>) => {
|
||||||
try {
|
try {
|
||||||
if (!draggingIndex || !offset) return;
|
if (!draggingIndex || !offset) return;
|
||||||
|
if (isPlaying === true) return;
|
||||||
|
|
||||||
const container = document.getElementById("real-time-vis-canvas");
|
const container = document.getElementById("real-time-vis-canvas");
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
@ -412,11 +430,23 @@ const DroppedObjects: React.FC = () => {
|
||||||
...zone.objects[draggingIndex.index],
|
...zone.objects[draggingIndex.index],
|
||||||
position: boundedPosition,
|
position: boundedPosition,
|
||||||
});
|
});
|
||||||
|
console.log('response: ', response);
|
||||||
|
|
||||||
if (response.message === "Widget updated successfully") {
|
if (response.message === "Widget updated successfully") {
|
||||||
updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
|
updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // Clean up
|
||||||
|
// setDraggingIndex(null);
|
||||||
|
// setOffset(null);
|
||||||
|
// setActiveEdges(null); // Clear active edges
|
||||||
|
// setCurrentPosition(null); // Reset current position
|
||||||
|
// if (animationRef.current) {
|
||||||
|
// cancelAnimationFrame(animationRef.current);
|
||||||
|
// animationRef.current = null;
|
||||||
|
// }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error("Error in handlePointerUp:", error);
|
||||||
} finally {
|
} finally {
|
||||||
// Clean up regardless of success or failure
|
// Clean up regardless of success or failure
|
||||||
setDraggingIndex(null);
|
setDraggingIndex(null);
|
||||||
|
@ -505,19 +535,20 @@ const DroppedObjects: React.FC = () => {
|
||||||
) : null}
|
) : null}
|
||||||
<div
|
<div
|
||||||
className="icon kebab"
|
className="icon kebab"
|
||||||
onClick={(event) => handleKebabClick(obj.id, event)}
|
ref={kebabRef}
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
handleKebabClick(obj.id, event)
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<KebabIcon />
|
<KebabIcon />
|
||||||
</div>
|
</div>
|
||||||
{openKebabId === obj.id && (
|
{openKebabId === obj.id && (
|
||||||
<div className="kebab-options">
|
<div className="kebab-options" ref={kebabRef}>
|
||||||
<div
|
<div className="dublicate btn" onClick={(event) => {
|
||||||
className="dublicate btn"
|
event.stopPropagation();
|
||||||
onClick={(event) => {
|
handleDuplicate(zoneName, index); // Call the duplicate handler
|
||||||
event.stopPropagation();
|
}}>
|
||||||
handleDuplicate(zoneName, index); // Call the duplicate handler
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="icon">
|
<div className="icon">
|
||||||
<DublicateIcon />
|
<DublicateIcon />
|
||||||
</div>
|
</div>
|
||||||
|
@ -537,6 +568,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
import { DraggableWidget } from "./DraggableWidget";
|
import { DraggableWidget } from "./DraggableWidget";
|
||||||
import { arrayMove } from "@dnd-kit/sortable";
|
import { arrayMove } from "@dnd-kit/sortable";
|
||||||
import { addingWidgets } from "../../../services/realTimeVisulization/zoneData/addWidgets";
|
import { addingWidgets } from "../../../services/realTimeVisulization/zoneData/addWidgets";
|
||||||
|
import { useAsset3dWidget, useSocketStore } from "../../../store/store";
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
hiddenPanels,
|
hiddenPanels,
|
||||||
setZonesData,
|
setZonesData,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||||
const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
|
const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
|
||||||
const [panelDimensions, setPanelDimensions] = useState<{
|
const [panelDimensions, setPanelDimensions] = useState<{
|
||||||
[side in Side]?: { width: number; height: number };
|
[side in Side]?: { width: number; height: number };
|
||||||
|
@ -60,14 +62,7 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
||||||
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
console.log("selectedZone: ", selectedZone.panelOrder);
|
const { visualizationSocket } = useSocketStore();
|
||||||
console.log("hiddenPanels: ", hiddenPanels);
|
|
||||||
|
|
||||||
// Check if any hidden panel is in the panelOrder of selectedZone
|
|
||||||
const isPanelInSelectedZone = hiddenPanels.some(
|
|
||||||
(panel) => selectedZone.panelOrder.includes(panel as Side) // Typecast to Side
|
|
||||||
);
|
|
||||||
console.log("Is panel in selectedZone: ", isPanelInSelectedZone);
|
|
||||||
|
|
||||||
const getPanelStyle = useMemo(
|
const getPanelStyle = useMemo(
|
||||||
() => (side: Side) => {
|
() => (side: Side) => {
|
||||||
|
@ -119,7 +114,6 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
const maxCapacity = calculatePanelCapacity(panel);
|
const maxCapacity = calculatePanelCapacity(panel);
|
||||||
|
|
||||||
if (currentWidgetsCount >= maxCapacity) return;
|
if (currentWidgetsCount >= maxCapacity) return;
|
||||||
|
|
||||||
addWidgetToPanel(draggedAsset, panel);
|
addWidgetToPanel(draggedAsset, panel);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,22 +150,34 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
id: generateUniqueId(),
|
id: generateUniqueId(),
|
||||||
panel,
|
panel,
|
||||||
};
|
};
|
||||||
try {
|
let addWidget = {
|
||||||
let response = await addingWidgets(
|
organization: organization,
|
||||||
selectedZone.zoneId,
|
zoneId: selectedZone.zoneId,
|
||||||
organization,
|
widget: newWidget
|
||||||
newWidget
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.message === "Widget created successfully") {
|
|
||||||
setSelectedZone((prev) => ({
|
|
||||||
...prev,
|
|
||||||
widgets: [...prev.widgets, newWidget],
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error adding widget:", error);
|
|
||||||
}
|
}
|
||||||
|
console.log('newWidget: ', newWidget);
|
||||||
|
console.log('addWidget: ', addWidget);
|
||||||
|
if (visualizationSocket) {
|
||||||
|
visualizationSocket.emit("v2:viz-widget:add", addWidget)
|
||||||
|
}
|
||||||
|
setSelectedZone((prev) => ({
|
||||||
|
...prev,
|
||||||
|
widgets: [...prev.widgets, newWidget],
|
||||||
|
}));
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// let response = await addingWidgets(selectedZone.zoneId, organization, newWidget);
|
||||||
|
|
||||||
|
// if (response.message === "Widget created successfully") {
|
||||||
|
// setSelectedZone((prev) => ({
|
||||||
|
// ...prev,
|
||||||
|
// widgets: [...prev.widgets, newWidget],
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("Error adding widget:", error);
|
||||||
|
// }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -7,10 +7,11 @@ import DisplayZone from "./DisplayZone";
|
||||||
import Scene from "../../../modules/scene/scene";
|
import Scene from "../../../modules/scene/scene";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
|
|
||||||
import DroppedObjects from "./DroppedFloatingWidgets";
|
|
||||||
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
|
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
|
||||||
import {
|
import {
|
||||||
useAsset3dWidget,
|
useAsset3dWidget,
|
||||||
|
useSocketStore,
|
||||||
useWidgetSubOption,
|
useWidgetSubOption,
|
||||||
useZones,
|
useZones,
|
||||||
} from "../../../store/store";
|
} from "../../../store/store";
|
||||||
|
@ -18,9 +19,10 @@ import { getZone2dData } from "../../../services/realTimeVisulization/zoneData/g
|
||||||
import { generateUniqueId } from "../../../functions/generateUniqueId";
|
import { generateUniqueId } from "../../../functions/generateUniqueId";
|
||||||
import { determinePosition } from "./functions/determinePosition";
|
import { determinePosition } from "./functions/determinePosition";
|
||||||
import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
|
import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
|
||||||
import EditWidgetOption from "../menu/EditWidgetOption";
|
import SocketRealTimeViz from "../../../modules/visualization/realTimeVizSocket.dev";
|
||||||
import RenderOverlay from "../../templates/Overlay";
|
import RenderOverlay from "../../templates/Overlay";
|
||||||
import ConfirmationPopup from "../../layout/confirmationPopup/ConfirmationPopup";
|
import ConfirmationPopup from "../../layout/confirmationPopup/ConfirmationPopup";
|
||||||
|
import DroppedObjects from "./DroppedFloatingWidgets";
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
@ -62,6 +64,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
>({});
|
>({});
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||||
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
||||||
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function GetZoneData() {
|
async function GetZoneData() {
|
||||||
|
@ -136,6 +139,8 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
const relativeX = event.clientX - canvasRect.left;
|
const relativeX = event.clientX - canvasRect.left;
|
||||||
const relativeY = event.clientY - canvasRect.top;
|
const relativeY = event.clientY - canvasRect.top;
|
||||||
|
|
||||||
|
const newPosition = determinePosition(canvasRect, relativeX, relativeY)
|
||||||
|
console.log('newPosition: ', newPosition);
|
||||||
const newObject = {
|
const newObject = {
|
||||||
...droppedData,
|
...droppedData,
|
||||||
id: generateUniqueId(),
|
id: generateUniqueId(),
|
||||||
|
@ -216,11 +221,10 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
onDrop={(event) => handleDrop(event)}
|
onDrop={(event) => handleDrop(event)}
|
||||||
onDragOver={(event) => event.preventDefault()}
|
onDragOver={(event) => event.preventDefault()}
|
||||||
>
|
>
|
||||||
{/* <Scene /> */}
|
<Scene />
|
||||||
</div>
|
</div>
|
||||||
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
|
{activeModule === "visualization" && selectedZone.zoneName !== "" && <DroppedObjects />}
|
||||||
<DroppedObjects />
|
{activeModule === "visualization" && <SocketRealTimeViz />}
|
||||||
)}
|
|
||||||
{/* <DroppedObjects /> */}
|
{/* <DroppedObjects /> */}
|
||||||
{activeModule === "visualization" && (
|
{activeModule === "visualization" && (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,69 +1,3 @@
|
||||||
// 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;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function determinePosition(
|
export function determinePosition(
|
||||||
canvasRect: DOMRect,
|
canvasRect: DOMRect,
|
||||||
|
@ -89,16 +23,16 @@ export function determinePosition(
|
||||||
if (relativeX < centerX) {
|
if (relativeX < centerX) {
|
||||||
|
|
||||||
position = {
|
position = {
|
||||||
top: relativeY,
|
top: relativeY - 41.5,
|
||||||
left: relativeX,
|
left: relativeX - 125,
|
||||||
right: "auto",
|
right: "auto",
|
||||||
bottom: "auto",
|
bottom: "auto",
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
position = {
|
position = {
|
||||||
top: relativeY,
|
top: relativeY - 41.5,
|
||||||
right: canvasRect.width - relativeX,
|
right: canvasRect.width - relativeX - 125,
|
||||||
left: "auto",
|
left: "auto",
|
||||||
bottom: "auto",
|
bottom: "auto",
|
||||||
};
|
};
|
||||||
|
@ -107,16 +41,16 @@ export function determinePosition(
|
||||||
if (relativeX < centerX) {
|
if (relativeX < centerX) {
|
||||||
|
|
||||||
position = {
|
position = {
|
||||||
bottom: canvasRect.height - relativeY,
|
bottom: canvasRect.height - relativeY - 41.5,
|
||||||
left: relativeX,
|
left: relativeX - 125,
|
||||||
right: "auto",
|
right: "auto",
|
||||||
top: "auto",
|
top: "auto",
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
position = {
|
position = {
|
||||||
bottom: canvasRect.height - relativeY,
|
bottom: canvasRect.height - relativeY - 41.5,
|
||||||
right: canvasRect.width - relativeX,
|
right: canvasRect.width - relativeX - 125,
|
||||||
left: "auto",
|
left: "auto",
|
||||||
top: "auto",
|
top: "auto",
|
||||||
};
|
};
|
||||||
|
@ -124,4 +58,4 @@ export function determinePosition(
|
||||||
}
|
}
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useSocketStore } from "../../store/store";
|
||||||
|
import { useSelectedZoneStore } from "../../store/useZoneStore";
|
||||||
|
|
||||||
|
export default function SocketRealTimeViz() {
|
||||||
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
|
useEffect(() => {
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
if (visualizationSocket) {
|
||||||
|
//add panel response
|
||||||
|
visualizationSocket.on("viz-panel:response:updates", (addPanel: any) => {
|
||||||
|
if (addPanel.success) {
|
||||||
|
let addPanelData = addPanel.data.data
|
||||||
|
setSelectedZone(addPanelData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//delete panel response
|
||||||
|
visualizationSocket.on("viz-panel:response:delete", (deletePanel: any) => {
|
||||||
|
if (deletePanel.success) {
|
||||||
|
let deletePanelData = deletePanel.data.data
|
||||||
|
setSelectedZone(deletePanelData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// add 2dWidget
|
||||||
|
visualizationSocket.on("viz-widget:response:updates", (response: any) => {
|
||||||
|
console.log('response: ', response);
|
||||||
|
if (response.success && response.data) {
|
||||||
|
setSelectedZone((prev) => {
|
||||||
|
const isWidgetAlreadyAdded = prev.widgets.some(
|
||||||
|
(widget) => widget.id === response.data.widgetData.id
|
||||||
|
);
|
||||||
|
if (isWidgetAlreadyAdded) return prev; // Prevent duplicate addition
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
zoneId: response.data.zoneId,
|
||||||
|
zoneName: response.data.zoneName,
|
||||||
|
widgets: [...prev.widgets, response.data.widgetData], // Append new widget
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//delete 2D Widget
|
||||||
|
visualizationSocket.on("viz-widget:response:delete", (deleteWidget: any) => {
|
||||||
|
console.log('deleteWidget: ', deleteWidget);
|
||||||
|
if (deleteWidget?.success && deleteWidget.data) {
|
||||||
|
setSelectedZone((prevZone: any) => ({
|
||||||
|
...prevZone,
|
||||||
|
zoneId: deleteWidget.data.zoneId,
|
||||||
|
zoneName: deleteWidget.data.zoneName,
|
||||||
|
widgets: deleteWidget.data.widgetDeleteDatas, // Replace with new widget list
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
}, [selectedZone])
|
||||||
|
return (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ const Project: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="project-main">
|
<div className="project-main">
|
||||||
{/* {loadingProgress && <LoadingPage progress={loadingProgress} />} */}
|
{loadingProgress && <LoadingPage progress={loadingProgress} />}
|
||||||
{!isPlaying && (
|
{!isPlaying && (
|
||||||
<>
|
<>
|
||||||
{toggleThreeD && <ModuleToggle />}
|
{toggleThreeD && <ModuleToggle />}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
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 deletePanelApi = async (
|
||||||
|
zoneId: string,
|
||||||
|
panelName: string,
|
||||||
|
organization: string
|
||||||
|
) => {
|
||||||
|
console.log('panelName: ', panelName);
|
||||||
|
console.log('organization: ', organization);
|
||||||
|
console.log('zoneId: ', zoneId);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${url_Backend_dwinzo}/api/v2/panel/delete`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ organization, zoneId, panelName }),
|
||||||
|
});
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,8 +0,0 @@
|
||||||
import { create } from "zustand";
|
|
||||||
|
|
||||||
const useFloatingDataStore = create((set) => ({
|
|
||||||
floatingdata: [], // Initial state
|
|
||||||
setfloatingadata: (newData: []) => set({ floatingdata: newData }), // Setter function
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default useFloatingDataStore;
|
|
|
@ -11,16 +11,28 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const socket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`, {
|
const socket = io(
|
||||||
reconnection: false,
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}`,
|
||||||
auth: { email, organization },
|
{
|
||||||
});
|
reconnection: false,
|
||||||
|
auth: { email, organization },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
set({ socket });
|
const visualizationSocket = io(
|
||||||
|
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
|
||||||
|
{
|
||||||
|
reconnection: false,
|
||||||
|
auth: { email, organization },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
set({ socket, visualizationSocket });
|
||||||
},
|
},
|
||||||
disconnectSocket: () => {
|
disconnectSocket: () => {
|
||||||
set((state: any) => {
|
set((state: any) => {
|
||||||
state.socket?.disconnect();
|
state.socket?.disconnect();
|
||||||
|
state.visualizationSocket?.disconnect();
|
||||||
return { socket: null };
|
return { socket: null };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -205,7 +217,9 @@ export const useActiveLayer = create<any>((set: any) => ({
|
||||||
|
|
||||||
interface RefTextUpdateState {
|
interface RefTextUpdateState {
|
||||||
refTextupdate: number;
|
refTextupdate: number;
|
||||||
setRefTextUpdate: (callback: (currentValue: number) => number | number) => void;
|
setRefTextUpdate: (
|
||||||
|
callback: (currentValue: number) => number | number
|
||||||
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
|
export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
|
||||||
|
@ -213,7 +227,9 @@ export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
|
||||||
setRefTextUpdate: (callback) =>
|
setRefTextUpdate: (callback) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
refTextupdate:
|
refTextupdate:
|
||||||
typeof callback === "function" ? callback(state.refTextupdate) : callback,
|
typeof callback === "function"
|
||||||
|
? callback(state.refTextupdate)
|
||||||
|
: callback,
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -393,4 +409,3 @@ export const useWidgetSubOption = create<any>((set: any) => ({
|
||||||
widgetSubOption: "2D",
|
widgetSubOption: "2D",
|
||||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ type DroppedObjectsState = {
|
||||||
bottom: number | "auto";
|
bottom: number | "auto";
|
||||||
}
|
}
|
||||||
) => void;
|
) => void;
|
||||||
deleteObject: (zoneName: string, index: number) => void; // Add this line
|
deleteObject: (zoneName: string, id: string, index: number) => void; // Add this line
|
||||||
duplicateObject: (zoneName: string, index: number) => void; // Add this line
|
duplicateObject: (zoneName: string, index: number) => void; // Add this line
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,15 +77,16 @@ export const useDroppedObjectsStore = create<DroppedObjectsState>((set) => ({
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteObject: (zoneName: string, index: number) =>
|
deleteObject: (zoneName: string, id: string, index: number) =>
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const zone = state.zones[zoneName];
|
const zone = state.zones[zoneName];
|
||||||
|
console.log("zone: ", zone);
|
||||||
if (!zone) return state;
|
if (!zone) return state;
|
||||||
return {
|
return {
|
||||||
zones: {
|
zones: {
|
||||||
[zoneName]: {
|
[zoneName]: {
|
||||||
...zone,
|
...zone,
|
||||||
objects: zone.objects.filter((_, i) => i !== index), // Remove object at the given index
|
objects: zone.objects.filter((obj) => obj.id !== id), // Remove object at the given index
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue