Merge branch 'main' into rtViz
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { Widget } from "../../../store/useWidgetStore";
|
||||
import { useWidgetStore, Widget } from "../../../store/useWidgetStore";
|
||||
import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
|
||||
import { InfoIcon } from "../../icons/ExportCommonIcons";
|
||||
import {
|
||||
@@ -73,7 +73,8 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||
// State to track overflow visibility
|
||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||
const [showRightArrow, setShowRightArrow] = useState(false);
|
||||
const { floatingWidget, setFloatingWidget } = useFloatingWidget();
|
||||
const { floatingWidget, setFloatingWidget } = useFloatingWidget()
|
||||
const{setSelectedChartId}=useWidgetStore()
|
||||
|
||||
// Function to calculate overflow state
|
||||
const updateOverflowState = useCallback(() => {
|
||||
@@ -150,6 +151,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||
if (selectedZone?.zoneId === zoneId) {
|
||||
return;
|
||||
}
|
||||
setSelectedChartId(null)
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
let response = await getSelect2dZoneData(zoneId, organization);
|
||||
|
||||
@@ -5,6 +5,8 @@ import BarGraphComponent from "../realTimeVis/charts/BarGraphComponent";
|
||||
import LineGraphComponent from "../realTimeVis/charts/LineGraphComponent";
|
||||
import DoughnutGraphComponent from "../realTimeVis/charts/DoughnutGraphComponent";
|
||||
import PolarAreaGraphComponent from "../realTimeVis/charts/PolarAreaGraphComponent";
|
||||
import ProgressCard1 from "../realTimeVis/charts/ProgressCard1";
|
||||
import ProgressCard2 from "../realTimeVis/charts/ProgressCard2";
|
||||
import {
|
||||
DeleteIcon,
|
||||
DublicateIcon,
|
||||
@@ -13,6 +15,7 @@ import {
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { duplicateWidgetApi } from "../../../services/realTimeVisulization/zoneData/duplicateWidget";
|
||||
import { deleteWidgetApi } from "../../../services/realTimeVisulization/zoneData/deleteWidgetApi";
|
||||
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
|
||||
import { useSocketStore } from "../../../store/store";
|
||||
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
@@ -81,6 +84,8 @@ export const DraggableWidget = ({
|
||||
}
|
||||
};
|
||||
|
||||
const chartWidget = useRef<HTMLDivElement>(null);
|
||||
|
||||
const isPanelHidden = hiddenPanels.includes(widget.panel);
|
||||
|
||||
const deleteSelectedChart = async () => {
|
||||
@@ -117,13 +122,11 @@ export const DraggableWidget = ({
|
||||
// }));
|
||||
// }
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setOpenKebabId(null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const getCurrentWidgetCount = (panel: Side) =>
|
||||
selectedZone.widgets.filter((w) => w.panel === panel).length;
|
||||
|
||||
@@ -183,13 +186,11 @@ export const DraggableWidget = ({
|
||||
// }));
|
||||
// }
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
setOpenKebabId(null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleKebabClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||
event.stopPropagation();
|
||||
if (openKebabId === widget.id) {
|
||||
@@ -237,23 +238,31 @@ export const DraggableWidget = ({
|
||||
onReorder(fromIndex, toIndex); // Call the reorder function passed as a prop
|
||||
}
|
||||
};
|
||||
console.log("widget.type", widget.type);
|
||||
|
||||
// useClickOutside(chartWidget, () => {
|
||||
// setSelectedChartId(null);
|
||||
// });
|
||||
|
||||
console.log('isPanelHidden: ', isPanelHidden);
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
draggable
|
||||
key={widget.id}
|
||||
className={`chart-container ${selectedChartId?.id === widget.id && "activeChart"
|
||||
}`}
|
||||
className={`chart-container ${
|
||||
selectedChartId?.id === widget.id && "activeChart"
|
||||
}`}
|
||||
onPointerDown={handlePointerDown}
|
||||
onDragStart={handleDragStart}
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragOver={handleDragOver}
|
||||
onDrop={handleDrop}
|
||||
style={{
|
||||
opacity: isPanelHidden ? 0 : 1,
|
||||
pointerEvents: isPanelHidden ? "none" : "auto",
|
||||
}}
|
||||
ref={chartWidget}
|
||||
onClick={() => setSelectedChartId(widget)}
|
||||
>
|
||||
{/* Kebab Icon */}
|
||||
<div className="icon kebab" onClick={handleKebabClick}>
|
||||
@@ -264,8 +273,9 @@ export const DraggableWidget = ({
|
||||
{openKebabId === widget.id && (
|
||||
<div className="kebab-options" ref={widgetRef}>
|
||||
<div
|
||||
className={`edit btn ${isPanelFull(widget.panel) ? "btn-blur" : ""
|
||||
}`}
|
||||
className={`edit btn ${
|
||||
isPanelFull(widget.panel) ? "btn-blur" : ""
|
||||
}`}
|
||||
onClick={isPanelFull(widget.panel) ? undefined : duplicateWidget}
|
||||
>
|
||||
<div className="icon">
|
||||
@@ -284,8 +294,11 @@ export const DraggableWidget = ({
|
||||
|
||||
{/* Render charts based on widget type */}
|
||||
|
||||
{widget.type === "progress" && (
|
||||
<ProgressCard title={widget.title} data={widget.data} />
|
||||
{widget.type === "progress 1" && (
|
||||
<ProgressCard1 title={widget.title} id={widget.id} />
|
||||
)}
|
||||
{widget.type === "progress 2" && (
|
||||
<ProgressCard2 title={widget.title} id={widget.id} />
|
||||
)}
|
||||
{widget.type === "line" && (
|
||||
<LineGraphComponent
|
||||
@@ -294,14 +307,6 @@ export const DraggableWidget = ({
|
||||
title={widget.title}
|
||||
fontSize={widget.fontSize}
|
||||
fontWeight={widget.fontWeight}
|
||||
// data={{
|
||||
// measurements: [
|
||||
// { name: "testDevice", fields: "powerConsumption" },
|
||||
// { name: "furnace", fields: "powerConsumption" },
|
||||
// ],
|
||||
// interval: 1000,
|
||||
// duration: "1h",
|
||||
// }}
|
||||
/>
|
||||
)}
|
||||
{widget.type === "bar" && (
|
||||
@@ -311,14 +316,6 @@ export const DraggableWidget = ({
|
||||
title={widget.title}
|
||||
fontSize={widget.fontSize}
|
||||
fontWeight={widget.fontWeight}
|
||||
// data={{
|
||||
// measurements: [
|
||||
// { name: "testDevice", fields: "powerConsumption" },
|
||||
// { name: "furnace", fields: "powerConsumption" },
|
||||
// ],
|
||||
// interval: 1000,
|
||||
// duration: "1h",
|
||||
// }}
|
||||
/>
|
||||
)}
|
||||
{widget.type === "pie" && (
|
||||
@@ -328,14 +325,6 @@ export const DraggableWidget = ({
|
||||
title={widget.title}
|
||||
fontSize={widget.fontSize}
|
||||
fontWeight={widget.fontWeight}
|
||||
// data={{
|
||||
// measurements: [
|
||||
// { name: "testDevice", fields: "powerConsumption" },
|
||||
// { name: "furnace", fields: "powerConsumption" },
|
||||
// ],
|
||||
// interval: 1000,
|
||||
// duration: "1h",
|
||||
// }}
|
||||
/>
|
||||
)}
|
||||
{widget.type === "doughnut" && (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useAsset3dWidget, useSocketStore, useWidgetSubOption } from "../../../store/store";
|
||||
@@ -32,8 +31,8 @@ export default function Dropped3dWidgets() {
|
||||
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() {
|
||||
let result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
|
||||
@@ -115,15 +114,16 @@ export default function Dropped3dWidgets() {
|
||||
return (
|
||||
<>
|
||||
{activeZoneWidgets.map(({ id, type, position }) => {
|
||||
console.log('Typeeeeeeeeeeee',type);
|
||||
switch (type) {
|
||||
case "ui-Widget 1":
|
||||
return <ProductionCapacity key={id} position={position} />;
|
||||
return <ProductionCapacity key={id} id={id} type={type} position={position} />;
|
||||
case "ui-Widget 2":
|
||||
return <ReturnOfInvestment key={id} position={position} />;
|
||||
return <ReturnOfInvestment key={id} id={id} type={type} position={position} />;
|
||||
case "ui-Widget 3":
|
||||
return <StateWorking key={id} position={position} />;
|
||||
return <StateWorking key={id} id={id} type={type} position={position} />;
|
||||
case "ui-Widget 4":
|
||||
return <Throughput key={id} position={position} />;
|
||||
return <Throughput key={id} id={id} type={type} position={position} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -131,4 +131,3 @@ export default function Dropped3dWidgets() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { WalletIcon } from "../../icons/3dChartIcons";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
@@ -22,6 +21,9 @@ import WarehouseThroughputComponent from "../realTimeVis/floating/WarehouseThrou
|
||||
import FleetEfficiencyComponent from "../realTimeVis/floating/FleetEfficiencyComponent";
|
||||
import { useWidgetStore } from "../../../store/useWidgetStore";
|
||||
import { useSocketStore } from "../../../store/store";
|
||||
import { useClickOutside } from "./functions/handleWidgetsOuterClick";
|
||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||
import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
||||
interface DraggingState {
|
||||
zone: string;
|
||||
index: number;
|
||||
@@ -45,19 +47,24 @@ interface DraggingState {
|
||||
}
|
||||
const DroppedObjects: React.FC = () => {
|
||||
const { visualizationSocket } = useSocketStore();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const zones = useDroppedObjectsStore((state) => state.zones);
|
||||
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
||||
const updateObjectPosition = useDroppedObjectsStore(
|
||||
(state) => state.updateObjectPosition
|
||||
);
|
||||
const { setSelectedZone, selectedZone } = useSelectedZoneStore();
|
||||
|
||||
const deleteObject = useDroppedObjectsStore((state) => state.deleteObject);
|
||||
|
||||
const duplicateObject = useDroppedObjectsStore((state) => state.duplicateObject);
|
||||
const duplicateObject = useDroppedObjectsStore(
|
||||
(state) => state.duplicateObject
|
||||
);
|
||||
const [draggingIndex, setDraggingIndex] = useState<DraggingState | null>(
|
||||
null
|
||||
);
|
||||
const [offset, setOffset] = useState<[number, number] | null>(null);
|
||||
const { setSelectedChartId } = useWidgetStore();
|
||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||
const [activeEdges, setActiveEdges] = useState<{
|
||||
vertical: "top" | "bottom";
|
||||
horizontal: "left" | "right";
|
||||
@@ -70,6 +77,11 @@ const DroppedObjects: React.FC = () => {
|
||||
} | null>(null); // State to track the current position during drag
|
||||
const animationRef = useRef<number | null>(null);
|
||||
const { activeModule } = useModuleStore();
|
||||
const chartWidget = useRef<HTMLDivElement>(null);
|
||||
|
||||
// useClickOutside(chartWidget, () => {
|
||||
// setSelectedChartId(null);
|
||||
// });
|
||||
const kebabRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
|
||||
@@ -103,7 +115,7 @@ const DroppedObjects: React.FC = () => {
|
||||
|
||||
|
||||
function handleDuplicate(zoneName: string, index: number) {
|
||||
setOpenKebabId(null)
|
||||
setOpenKebabId(null);
|
||||
duplicateObject(zoneName, index); // Call the duplicateObject method from the store
|
||||
}
|
||||
|
||||
@@ -181,11 +193,150 @@ const DroppedObjects: React.FC = () => {
|
||||
}
|
||||
|
||||
setOffset([offsetY, offsetX]);
|
||||
|
||||
// Add native event listeners for smoother tracking
|
||||
const handlePointerMoveNative = (e: PointerEvent) => {
|
||||
if (!draggingIndex || !offset) return;
|
||||
if (isPlaying === true) return;
|
||||
|
||||
const rect = container.getBoundingClientRect();
|
||||
const relativeX = e.clientX - rect.left;
|
||||
const relativeY = e.clientY - rect.top;
|
||||
|
||||
// Use requestAnimationFrame for smooth updates
|
||||
animationRef.current = requestAnimationFrame(() => {
|
||||
// Dynamically determine the current position strategy
|
||||
const newPositionStrategy = determinePosition(
|
||||
rect,
|
||||
relativeX,
|
||||
relativeY
|
||||
);
|
||||
const [activeProp1, activeProp2] =
|
||||
getActiveProperties(newPositionStrategy);
|
||||
|
||||
// Update active edges for distance lines
|
||||
const vertical = activeProp1 === "top" ? "top" : "bottom";
|
||||
const horizontal = activeProp2 === "left" ? "left" : "right";
|
||||
setActiveEdges({ vertical, horizontal });
|
||||
|
||||
// Calculate new position based on the active properties
|
||||
let newY = 0;
|
||||
let newX = 0;
|
||||
|
||||
if (activeProp1 === "top") {
|
||||
newY = relativeY - offset[0];
|
||||
} else {
|
||||
newY = rect.height - (relativeY + offset[0]);
|
||||
}
|
||||
|
||||
if (activeProp2 === "left") {
|
||||
newX = relativeX - offset[1];
|
||||
} else {
|
||||
newX = rect.width - (relativeX + offset[1]);
|
||||
}
|
||||
|
||||
// Apply boundaries
|
||||
newX = Math.max(0, Math.min(rect.width - 50, newX));
|
||||
newY = Math.max(0, Math.min(rect.height - 50, newY));
|
||||
|
||||
// Create new position object
|
||||
const newPosition = {
|
||||
...newPositionStrategy,
|
||||
[activeProp1]: newY,
|
||||
[activeProp2]: newX,
|
||||
// Clear opposite properties
|
||||
[activeProp1 === "top" ? "bottom" : "top"]: "auto",
|
||||
[activeProp2 === "left" ? "right" : "left"]: "auto",
|
||||
};
|
||||
|
||||
// Update the current position state for DistanceLines
|
||||
setCurrentPosition(newPosition);
|
||||
updateObjectPosition(zoneName, draggingIndex.index, newPosition);
|
||||
});
|
||||
};
|
||||
|
||||
const handlePointerUpNative = async (e: PointerEvent) => {
|
||||
// Clean up native event listeners
|
||||
element.removeEventListener("pointermove", handlePointerMoveNative);
|
||||
element.removeEventListener("pointerup", handlePointerUpNative);
|
||||
element.releasePointerCapture(e.pointerId);
|
||||
|
||||
if (!draggingIndex || !offset) return;
|
||||
|
||||
const rect = container.getBoundingClientRect();
|
||||
const relativeX = e.clientX - rect.left;
|
||||
const relativeY = e.clientY - rect.top;
|
||||
|
||||
// Determine final position strategy
|
||||
const finalPosition = determinePosition(rect, relativeX, relativeY);
|
||||
const [activeProp1, activeProp2] = getActiveProperties(finalPosition);
|
||||
|
||||
// Calculate final position
|
||||
let finalY = 0;
|
||||
let finalX = 0;
|
||||
|
||||
if (activeProp1 === "top") {
|
||||
finalY = relativeY - offset[0];
|
||||
} else {
|
||||
finalY = rect.height - (relativeY + offset[0]);
|
||||
}
|
||||
|
||||
if (activeProp2 === "left") {
|
||||
finalX = relativeX - offset[1];
|
||||
} else {
|
||||
finalX = rect.width - (relativeX + offset[1]);
|
||||
}
|
||||
|
||||
// Apply boundaries
|
||||
finalX = Math.max(0, Math.min(rect.width - 50, finalX));
|
||||
finalY = Math.max(0, Math.min(rect.height - 50, finalY));
|
||||
|
||||
const boundedPosition = {
|
||||
...finalPosition,
|
||||
[activeProp1]: finalY,
|
||||
[activeProp2]: finalX,
|
||||
[activeProp1 === "top" ? "bottom" : "top"]: "auto",
|
||||
[activeProp2 === "left" ? "right" : "left"]: "auto",
|
||||
};
|
||||
|
||||
try {
|
||||
// Save to backend
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
const response = await addingFloatingWidgets(
|
||||
zone.zoneId,
|
||||
organization,
|
||||
{
|
||||
...zone.objects[draggingIndex.index],
|
||||
position: boundedPosition,
|
||||
}
|
||||
);
|
||||
|
||||
if (response.message === "Widget updated successfully") {
|
||||
updateObjectPosition(zoneName, draggingIndex.index, boundedPosition);
|
||||
}
|
||||
} catch (error) {
|
||||
} finally {
|
||||
setDraggingIndex(null);
|
||||
setOffset(null);
|
||||
setActiveEdges(null);
|
||||
setCurrentPosition(null);
|
||||
|
||||
if (animationRef.current) {
|
||||
cancelAnimationFrame(animationRef.current);
|
||||
animationRef.current = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add native event listeners
|
||||
element.addEventListener("pointermove", handlePointerMoveNative);
|
||||
element.addEventListener("pointerup", handlePointerUpNative);
|
||||
};
|
||||
|
||||
const handlePointerMove = (event: React.PointerEvent) => {
|
||||
if (!draggingIndex || !offset) return;
|
||||
|
||||
if (isPlaying === true) return;
|
||||
const container = document.getElementById("real-time-vis-canvas");
|
||||
if (!container) return;
|
||||
|
||||
@@ -248,6 +399,7 @@ const DroppedObjects: React.FC = () => {
|
||||
const handlePointerUp = async (event: React.PointerEvent<HTMLDivElement>) => {
|
||||
try {
|
||||
if (!draggingIndex || !offset) return;
|
||||
if (isPlaying === true) return;
|
||||
|
||||
const container = document.getElementById("real-time-vis-canvas");
|
||||
if (!container) return;
|
||||
@@ -256,11 +408,11 @@ const DroppedObjects: React.FC = () => {
|
||||
const relativeX = event.clientX - rect.left;
|
||||
const relativeY = event.clientY - rect.top;
|
||||
|
||||
// Only now determine the final position strategy
|
||||
// Determine final position strategy
|
||||
const finalPosition = determinePosition(rect, relativeX, relativeY);
|
||||
const [activeProp1, activeProp2] = getActiveProperties(finalPosition);
|
||||
|
||||
// Calculate final position using the new strategy
|
||||
// Calculate final position
|
||||
let finalY = 0;
|
||||
let finalX = 0;
|
||||
|
||||
@@ -357,29 +509,48 @@ const DroppedObjects: React.FC = () => {
|
||||
{zone.objects.map((obj, index) => (
|
||||
<div
|
||||
key={`${zoneName}-${index}`}
|
||||
className={obj.className}
|
||||
className={`${obj.className} ${
|
||||
selectedChartId?.id === obj.id && "activeChart"
|
||||
}`}
|
||||
ref={chartWidget}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top:
|
||||
typeof obj.position.top === "number"
|
||||
? `${obj.position.top}px`
|
||||
? `calc(${obj.position.top}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("top")
|
||||
? 90
|
||||
: 0
|
||||
}px)`
|
||||
: "auto",
|
||||
left:
|
||||
typeof obj.position.left === "number"
|
||||
? `${obj.position.left}px`
|
||||
? `calc(${obj.position.left}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("left")
|
||||
? 90
|
||||
: 0
|
||||
}px)`
|
||||
: "auto",
|
||||
right:
|
||||
typeof obj.position.right === "number"
|
||||
? `${obj.position.right}px`
|
||||
? `calc(${obj.position.right}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("right")
|
||||
? 90
|
||||
: 0
|
||||
}px)`
|
||||
: "auto",
|
||||
bottom:
|
||||
typeof obj.position.bottom === "number"
|
||||
? `${obj.position.bottom}px`
|
||||
? `calc(${obj.position.bottom}px + ${
|
||||
isPlaying && selectedZone.activeSides.includes("bottom")
|
||||
? 90
|
||||
: 0
|
||||
}px)`
|
||||
: "auto",
|
||||
}}
|
||||
onPointerDown={(event) => handlePointerDown(event, index)}
|
||||
onClick={() => {
|
||||
setSelectedChartId(obj)
|
||||
onPointerDown={(event) => {
|
||||
setSelectedChartId(obj);
|
||||
handlePointerDown(event, index);
|
||||
}}
|
||||
>
|
||||
{obj.className === "floating total-card" ? (
|
||||
@@ -388,7 +559,7 @@ const DroppedObjects: React.FC = () => {
|
||||
</>
|
||||
) : obj.className === "warehouseThroughput floating" ? (
|
||||
<>
|
||||
<WarehouseThroughputComponent />
|
||||
<WarehouseThroughputComponent object={obj}/>
|
||||
</>
|
||||
) : obj.className === "fleetEfficiency floating" ? (
|
||||
<>
|
||||
@@ -432,7 +603,8 @@ const DroppedObjects: React.FC = () => {
|
||||
))}
|
||||
|
||||
{/* Render DistanceLines component during drag */}
|
||||
{draggingIndex !== null &&
|
||||
{isPlaying === false &&
|
||||
draggingIndex !== null &&
|
||||
activeEdges !== null &&
|
||||
currentPosition !== null && (
|
||||
<DistanceLines
|
||||
|
||||
@@ -25,7 +25,7 @@ interface PanelProps {
|
||||
lockedPanels: Side[];
|
||||
zoneId: string;
|
||||
zoneViewPortTarget: number[];
|
||||
zoneViewPortPosition: number[]
|
||||
zoneViewPortPosition: number[];
|
||||
widgets: Widget[];
|
||||
};
|
||||
setSelectedZone: React.Dispatch<
|
||||
@@ -37,7 +37,7 @@ interface PanelProps {
|
||||
lockedPanels: Side[];
|
||||
zoneId: string;
|
||||
zoneViewPortTarget: number[];
|
||||
zoneViewPortPosition: number[]
|
||||
zoneViewPortPosition: number[];
|
||||
widgets: Widget[];
|
||||
}>
|
||||
>;
|
||||
@@ -78,8 +78,9 @@ const Panel: React.FC<PanelProps> = ({
|
||||
case "top":
|
||||
case "bottom":
|
||||
return {
|
||||
width: `calc(100% - ${(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
|
||||
}px)`,
|
||||
width: `calc(100% - ${
|
||||
(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
|
||||
}px)`,
|
||||
height: `${panelSize - 2}px`,
|
||||
left: leftActive ? `${panelSize}px` : "0",
|
||||
right: rightActive ? `${panelSize}px` : "0",
|
||||
@@ -89,8 +90,9 @@ const Panel: React.FC<PanelProps> = ({
|
||||
case "right":
|
||||
return {
|
||||
width: `${panelSize - 2}px`,
|
||||
height: `calc(100% - ${(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
|
||||
}px)`,
|
||||
height: `calc(100% - ${
|
||||
(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
|
||||
}px)`,
|
||||
top: topActive ? `${panelSize}px` : "0",
|
||||
bottom: bottomActive ? `${panelSize}px` : "0",
|
||||
[side]: "0",
|
||||
@@ -142,7 +144,7 @@ const Panel: React.FC<PanelProps> = ({
|
||||
// while dublicate check this and add
|
||||
const addWidgetToPanel = async (asset: any, panel: Side) => {
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
const newWidget = {
|
||||
...asset,
|
||||
id: generateUniqueId(),
|
||||
@@ -205,7 +207,6 @@ const Panel: React.FC<PanelProps> = ({
|
||||
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
|
||||
if (!selectedZone) return; // Ensure selectedZone is not null
|
||||
|
||||
|
||||
setSelectedZone((prev) => {
|
||||
if (!prev) return prev; // Ensure prev is not null
|
||||
|
||||
@@ -232,7 +233,9 @@ const Panel: React.FC<PanelProps> = ({
|
||||
{selectedZone.activeSides.map((side) => (
|
||||
<div
|
||||
key={side}
|
||||
className={`panel ${side}-panel absolute ${isPlaying && ""}`}
|
||||
className={`panel ${side}-panel absolute ${isPlaying ? "" : ""} ${
|
||||
hiddenPanels.includes(side) ? "hidePanel" : ""
|
||||
}`}
|
||||
style={getPanelStyle(side)}
|
||||
onDrop={(e) => handleDrop(e, side)}
|
||||
onDragOver={(e) => e.preventDefault()}
|
||||
|
||||
@@ -7,7 +7,7 @@ import DisplayZone from "./DisplayZone";
|
||||
import Scene from "../../../modules/scene/scene";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
|
||||
import DroppedObjects from "./DroppedFloatingWidgets";
|
||||
|
||||
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
|
||||
import {
|
||||
useAsset3dWidget,
|
||||
@@ -20,6 +20,9 @@ import { generateUniqueId } from "../../../functions/generateUniqueId";
|
||||
import { determinePosition } from "./functions/determinePosition";
|
||||
import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
|
||||
import SocketRealTimeViz from "../../../modules/visualization/realTimeVizSocket.dev";
|
||||
import RenderOverlay from "../../templates/Overlay";
|
||||
import ConfirmationPopup from "../../layout/confirmationPopup/ConfirmationPopup";
|
||||
import DroppedObjects from "./DroppedFloatingWidgets";
|
||||
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
|
||||
@@ -53,6 +56,9 @@ const RealTimeVisulization: React.FC = () => {
|
||||
const [zonesData, setZonesData] = useState<FormattedZoneData>({});
|
||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||
const { zones } = useZones();
|
||||
|
||||
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
||||
|
||||
const [floatingWidgets, setFloatingWidgets] = useState<
|
||||
Record<string, { zoneName: string; zoneId: string; objects: any[] }>
|
||||
>({});
|
||||
@@ -66,7 +72,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||
const organization = email?.split("@")[1]?.split(".")[0];
|
||||
try {
|
||||
const response = await getZone2dData(organization);
|
||||
console.log('response: ', response);
|
||||
// console.log('response: ', response);
|
||||
|
||||
if (!Array.isArray(response)) {
|
||||
return;
|
||||
@@ -87,9 +93,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||
{}
|
||||
);
|
||||
setZonesData(formattedData);
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
GetZoneData();
|
||||
@@ -142,7 +146,6 @@ const RealTimeVisulization: React.FC = () => {
|
||||
id: generateUniqueId(),
|
||||
position: determinePosition(canvasRect, relativeX, relativeY),
|
||||
};
|
||||
console.log('newObject: ', newObject);
|
||||
|
||||
// Only set zone if it’s not already in the store (prevents overwriting objects)
|
||||
const existingZone =
|
||||
@@ -189,7 +192,7 @@ const RealTimeVisulization: React.FC = () => {
|
||||
],
|
||||
},
|
||||
}));
|
||||
} catch (error) { }
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -203,6 +206,20 @@ const RealTimeVisulization: React.FC = () => {
|
||||
left: isPlaying || activeModule !== "visualization" ? "0%" : "",
|
||||
}}
|
||||
>
|
||||
{/* <RenderOverlay>
|
||||
<EditWidgetOption
|
||||
options={["Dublicate", "Vertical Move", "Horizontal Move", "Delete"]}
|
||||
/>
|
||||
</RenderOverlay> */}
|
||||
{openConfirmationPopup && (
|
||||
<RenderOverlay>
|
||||
<ConfirmationPopup
|
||||
message={"Are you sure want to delete?"}
|
||||
onConfirm={() => console.log("confirm")}
|
||||
onCancel={() => setOpenConfirmationPopup(false)}
|
||||
/>
|
||||
</RenderOverlay>
|
||||
)}
|
||||
<div
|
||||
className="scene-container"
|
||||
style={{
|
||||
|
||||
@@ -21,7 +21,7 @@ export function determinePosition(
|
||||
|
||||
if (relativeY < centerY) {
|
||||
if (relativeX < centerX) {
|
||||
console.log("Top-left");
|
||||
|
||||
position = {
|
||||
top: relativeY - 41.5,
|
||||
left: relativeX - 125,
|
||||
@@ -29,7 +29,7 @@ export function determinePosition(
|
||||
bottom: "auto",
|
||||
};
|
||||
} else {
|
||||
console.log("Top-right");
|
||||
|
||||
position = {
|
||||
top: relativeY - 41.5,
|
||||
right: canvasRect.width - relativeX - 125,
|
||||
@@ -39,7 +39,7 @@ export function determinePosition(
|
||||
}
|
||||
} else {
|
||||
if (relativeX < centerX) {
|
||||
console.log("Bottom-left");
|
||||
|
||||
position = {
|
||||
bottom: canvasRect.height - relativeY - 41.5,
|
||||
left: relativeX - 125,
|
||||
@@ -47,7 +47,7 @@ export function determinePosition(
|
||||
top: "auto",
|
||||
};
|
||||
} else {
|
||||
console.log("Bottom-right");
|
||||
|
||||
position = {
|
||||
bottom: canvasRect.height - relativeY - 41.5,
|
||||
right: canvasRect.width - relativeX - 125,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useEffect } from "react";
|
||||
|
||||
export const useClickOutside = (
|
||||
ref: React.RefObject<HTMLElement>,
|
||||
callback: () => void
|
||||
) => {
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (ref.current && !event.composedPath().includes(ref.current)) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", handleClickOutside);
|
||||
};
|
||||
}, [ref, callback]);
|
||||
};
|
||||
Reference in New Issue
Block a user