code structure updated
This commit is contained in:
@@ -45,7 +45,8 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||||||
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>(
|
const [expandedZones, setExpandedZones] = useState<Record<string, boolean>>(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
const { floorItems, setFloorItems } = useFloorItems();
|
const { setFloorItems } = useFloorItems();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
useSelectedZoneStore.getState().setSelectedZone({
|
useSelectedZoneStore.getState().setSelectedZone({
|
||||||
@@ -143,6 +144,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
console.log('newName: ', newName);
|
console.log('newName: ', newName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useFrame, useThree } from "@react-three/fiber";
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteTool, useFloorItems, useLoadingProgress, useRenderDistance, useSelectedFloorItem, useSelectedItem, useSimulationStates, useSocketStore, useToggleView, useTransformMode, } from "../../../store/store";
|
import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteTool, useFloorItems, useLoadingProgress, useRenderDistance, useSelectedFloorItem, useSelectedItem, useSimulationStates, useSocketStore, useToggleView, useTransformMode, useZoneAssetId, } from "../../../store/store";
|
||||||
import assetVisibility from "../geomentries/assets/assetVisibility";
|
import assetVisibility from "../geomentries/assets/assetVisibility";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
@@ -32,12 +32,13 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
|
|||||||
const { setSelectedFloorItem } = useSelectedFloorItem();
|
const { setSelectedFloorItem } = useSelectedFloorItem();
|
||||||
const { activeTool } = useActiveTool();
|
const { activeTool } = useActiveTool();
|
||||||
const { selectedItem, setSelectedItem } = useSelectedItem();
|
const { selectedItem, setSelectedItem } = useSelectedItem();
|
||||||
const { simulationStates, setSimulationStates } = useSimulationStates();
|
const { setSimulationStates } = useSimulationStates();
|
||||||
const { setLoadingProgress } = useLoadingProgress();
|
const { setLoadingProgress } = useLoadingProgress();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
const dracoLoader = new DRACOLoader();
|
const dracoLoader = new DRACOLoader();
|
||||||
|
const { setZoneAssetId } = useZoneAssetId();
|
||||||
|
|
||||||
dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
|
dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
|
||||||
loader.setDRACOLoader(dracoLoader);
|
loader.setDRACOLoader(dracoLoader);
|
||||||
@@ -220,6 +221,7 @@ const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject
|
|||||||
const target = controls.getTarget(new THREE.Vector3());
|
const target = controls.getTarget(new THREE.Vector3());
|
||||||
await controls.setTarget(target.x, 0, target.z, true);
|
await controls.setTarget(target.x, 0, target.z, true);
|
||||||
setSelectedFloorItem(null);
|
setSelectedFloorItem(null);
|
||||||
|
setZoneAssetId(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -795,7 +795,7 @@ export default function SocketResponses({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (data.message === "zone deleted") {
|
if (data.message === "zone deleted") {
|
||||||
const updatedZones = zones.filter((zone: any) => zone.zoneId !== data.data.zoneId);
|
const updatedZones = zones?.filter((zone: any) => zone.zoneId !== data.data.zoneId);
|
||||||
setZones(updatedZones);
|
setZones(updatedZones);
|
||||||
|
|
||||||
const zoneIndex = zones.findIndex((zone: any) => zone.zoneId === data.data.zoneId);
|
const zoneIndex = zones.findIndex((zone: any) => zone.zoneId === data.data.zoneId);
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
import React, { useEffect, useRef, useState, useCallback } from "react";
|
import React, { useEffect, useRef, useState, useCallback } from "react";
|
||||||
import { useWidgetStore, Widget } from "../../store/useWidgetStore";
|
import { Widget } from "../../store/useWidgetStore";
|
||||||
|
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 {MoveArrowLeft, MoveArrowRight,} from "../../components/icons/SimulationIcons";
|
||||||
import {
|
|
||||||
MoveArrowLeft,
|
|
||||||
MoveArrowRight,
|
|
||||||
} from "../../components/icons/SimulationIcons";
|
|
||||||
import { InfoIcon } from "../../components/icons/ExportCommonIcons";
|
import { InfoIcon } from "../../components/icons/ExportCommonIcons";
|
||||||
|
import { useSelectedZoneStore } from "../../store/useZoneStore";
|
||||||
|
|
||||||
// Define the type for `Side`
|
// Define the type for `Side`
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
@@ -34,62 +27,20 @@ interface DisplayZoneProps {
|
|||||||
zoneViewPortPosition: number[];
|
zoneViewPortPosition: number[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
selectedZone: {
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
zoneId: string;
|
|
||||||
points: [];
|
|
||||||
zoneViewPortTarget: number[];
|
|
||||||
zoneViewPortPosition: number[];
|
|
||||||
widgets: {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}[];
|
|
||||||
};
|
|
||||||
setSelectedZone: React.Dispatch<
|
|
||||||
React.SetStateAction<{
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
points: [];
|
|
||||||
zoneId: string;
|
|
||||||
zoneViewPortTarget: number[];
|
|
||||||
zoneViewPortPosition: number[];
|
|
||||||
widgets: {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}[];
|
|
||||||
}>
|
|
||||||
>;
|
|
||||||
hiddenPanels: HiddenPanels; // Updated prop type
|
hiddenPanels: HiddenPanels; // Updated prop type
|
||||||
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
const DisplayZone: React.FC<DisplayZoneProps> = ({ zonesData, hiddenPanels }) => {
|
||||||
zonesData,
|
|
||||||
selectedZone,
|
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||||
setSelectedZone,
|
const [showRightArrow, setShowRightArrow] = useState(false);
|
||||||
hiddenPanels,
|
|
||||||
}) => {
|
|
||||||
// Ref for the container element
|
// 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);
|
||||||
|
//zustand
|
||||||
// State to track overflow visibility
|
const { setFloatingWidget } = useFloatingWidget();
|
||||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
const [showRightArrow, setShowRightArrow] = useState(false);
|
|
||||||
const { floatingWidget, setFloatingWidget } = useFloatingWidget();
|
|
||||||
|
|
||||||
const { setSelectedChartId } = useWidgetStore();
|
|
||||||
|
|
||||||
// Function to calculate overflow state
|
// Function to calculate overflow state
|
||||||
const updateOverflowState = useCallback(() => {
|
const updateOverflowState = useCallback(() => {
|
||||||
@@ -97,16 +48,9 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
if (container) {
|
if (container) {
|
||||||
const isOverflowing = container.scrollWidth > container.clientWidth;
|
const isOverflowing = container.scrollWidth > container.clientWidth;
|
||||||
const canScrollLeft = container.scrollLeft > 0;
|
const canScrollLeft = container.scrollLeft > 0;
|
||||||
|
const canScrollRight = container.scrollLeft + container.clientWidth + 1 < container.scrollWidth;
|
||||||
const canScrollRight =
|
|
||||||
container.scrollLeft + container.clientWidth + 1 <
|
|
||||||
container.scrollWidth;
|
|
||||||
setShowLeftArrow(isOverflowing && canScrollLeft);
|
setShowLeftArrow(isOverflowing && canScrollLeft);
|
||||||
setShowRightArrow(isOverflowing && canScrollRight);
|
setShowRightArrow(isOverflowing && canScrollRight);
|
||||||
|
|
||||||
// console.log('canScrollRight: ', canScrollRight);
|
|
||||||
// console.log('isOverflowing: ', isOverflowing);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -126,10 +70,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
const handleWheel = (event: WheelEvent) => {
|
const handleWheel = (event: WheelEvent) => {
|
||||||
if (Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
|
if (Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
container.scrollBy({
|
container.scrollBy({ left: event.deltaY * 2, behavior: "smooth", });
|
||||||
left: event.deltaY * 2,
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -171,23 +112,11 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
if (selectedZone?.zoneId === zoneId) {
|
if (selectedZone?.zoneId === zoneId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// setSelectedChartId(null);
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
|
//api for getting 2d widget Data
|
||||||
let response = await getSelect2dZoneData(zoneId, organization);
|
let response = await getSelect2dZoneData(zoneId, organization);
|
||||||
console.log("response: ", response);
|
|
||||||
let res = await getFloatingZoneData(zoneId, organization);
|
|
||||||
console.log("res: ", res);
|
|
||||||
|
|
||||||
setFloatingWidget(res);
|
|
||||||
// Set the selected zone in the store
|
|
||||||
useDroppedObjectsStore.getState().setZone(zoneName, zoneId);
|
|
||||||
if (Array.isArray(res)) {
|
|
||||||
res.forEach((val) => {
|
|
||||||
useDroppedObjectsStore.getState().addObject(zoneName, val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelectedZone({
|
setSelectedZone({
|
||||||
zoneName,
|
zoneName,
|
||||||
activeSides: response.activeSides || [],
|
activeSides: response.activeSides || [],
|
||||||
@@ -199,62 +128,42 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|||||||
zoneViewPortTarget: response.viewPortCenter || {},
|
zoneViewPortTarget: response.viewPortCenter || {},
|
||||||
zoneViewPortPosition: response.viewPortposition || {},
|
zoneViewPortPosition: response.viewPortposition || {},
|
||||||
});
|
});
|
||||||
} catch (error) {}
|
|
||||||
|
//api for getting floating widget Data
|
||||||
|
let res = await getFloatingZoneData(zoneId, organization);
|
||||||
|
setFloatingWidget(res);
|
||||||
|
useDroppedObjectsStore.getState().setZone(zoneName, zoneId);
|
||||||
|
if (Array.isArray(res)) {
|
||||||
|
res.forEach((val) => {
|
||||||
|
useDroppedObjectsStore.getState().addObject(zoneName, val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div ref={containerRef} className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") && !hiddenPanels[selectedZone.zoneId]?.includes("bottom") ? "bottom" : ""}`}>
|
||||||
ref={containerRef}
|
|
||||||
className={`zone-wrapper ${
|
|
||||||
selectedZone?.activeSides?.includes("bottom") &&
|
|
||||||
!hiddenPanels[selectedZone.zoneId]?.includes("bottom")
|
|
||||||
? "bottom"
|
|
||||||
: ""
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{/* Left Arrow */}
|
{/* Left Arrow */}
|
||||||
{showLeftArrow && (
|
{showLeftArrow && (<button className="arrow left-arrow" onClick={handleScrollLeft}><MoveArrowLeft /></button>)}
|
||||||
<button className="arrow left-arrow" onClick={handleScrollLeft}>
|
|
||||||
<MoveArrowLeft />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Scrollable Zones Container */}
|
{/* Scrollable Zones Container */}
|
||||||
<div
|
<div ref={scrollContainerRef} className="zones-wrapper" style={{ overflowX: "auto", whiteSpace: "nowrap" }}>
|
||||||
ref={scrollContainerRef}
|
|
||||||
className="zones-wrapper"
|
|
||||||
style={{ overflowX: "auto", whiteSpace: "nowrap" }}
|
|
||||||
>
|
|
||||||
{Object.keys(zonesData).length !== 0 ? (
|
{Object.keys(zonesData).length !== 0 ? (
|
||||||
<>
|
<>
|
||||||
{Object.keys(zonesData).map((zoneName, index) => (
|
{Object.keys(zonesData).map((zoneName, index) => (
|
||||||
<div
|
<div key={index} className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""}`}
|
||||||
key={index}
|
onClick={() => handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)}
|
||||||
className={`zone ${
|
|
||||||
selectedZone.zoneName === zoneName ? "active" : ""
|
|
||||||
}`}
|
|
||||||
onClick={() =>
|
|
||||||
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{zoneName}
|
{zoneName}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="no-zone">
|
<div className="no-zone"><InfoIcon />No zones? Create one!</div>
|
||||||
<InfoIcon />
|
|
||||||
No zones? Create one!
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right Arrow */}
|
{/* Right Arrow */}
|
||||||
{showRightArrow && (
|
{showRightArrow && (<button className="arrow right-arrow" onClick={handleScrollRight}><MoveArrowRight /></button>)}
|
||||||
<button className="arrow right-arrow" onClick={handleScrollRight}>
|
|
||||||
<MoveArrowRight />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,32 +6,17 @@ import { useSelectedZoneStore } from "../../store/useZoneStore";
|
|||||||
import DisplayZone from "./DisplayZone";
|
import DisplayZone from "./DisplayZone";
|
||||||
import Scene from "../scene/scene";
|
import Scene from "../scene/scene";
|
||||||
import useModuleStore from "../../store/useModuleStore";
|
import useModuleStore from "../../store/useModuleStore";
|
||||||
|
import { useDroppedObjectsStore, useFloatingWidget, } from "../../store/useDroppedObjectsStore";
|
||||||
import {
|
import { useAsset3dWidget, useSocketStore, useWidgetSubOption } from "../../store/store";
|
||||||
useDroppedObjectsStore,
|
|
||||||
useFloatingWidget,
|
|
||||||
} from "../../store/useDroppedObjectsStore";
|
|
||||||
import {
|
|
||||||
useAsset3dWidget,
|
|
||||||
useSocketStore,
|
|
||||||
useWidgetSubOption,
|
|
||||||
useZones,
|
|
||||||
} from "../../store/store";
|
|
||||||
import { getZone2dData } from "../../services/realTimeVisulization/zoneData/getZoneData";
|
import { getZone2dData } from "../../services/realTimeVisulization/zoneData/getZoneData";
|
||||||
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 SocketRealTimeViz from "./socket/realTimeVizSocket.dev";
|
import SocketRealTimeViz from "./socket/realTimeVizSocket.dev";
|
||||||
import RenderOverlay from "../../components/templates/Overlay";
|
import RenderOverlay from "../../components/templates/Overlay";
|
||||||
import ConfirmationPopup from "../../components/layout/confirmationPopup/ConfirmationPopup";
|
import ConfirmationPopup from "../../components/layout/confirmationPopup/ConfirmationPopup";
|
||||||
import DroppedObjects from "./widgets/floating/DroppedFloatingWidgets";
|
import DroppedObjects from "./widgets/floating/DroppedFloatingWidgets";
|
||||||
import EditWidgetOption from "../../components/ui/menu/EditWidgetOption";
|
import EditWidgetOption from "../../components/ui/menu/EditWidgetOption";
|
||||||
import {
|
import { useEditWidgetOptionsStore, useRightClickSelected, useRightSelected, } from "../../store/useZone3DWidgetStore";
|
||||||
useEditWidgetOptionsStore,
|
|
||||||
useRightClickSelected,
|
|
||||||
useRightSelected,
|
|
||||||
} from "../../store/useZone3DWidgetStore";
|
|
||||||
import Dropped3dWidgets from "./widgets/3d/Dropped3dWidget";
|
|
||||||
import OuterClick from "../../utils/outerClick";
|
import OuterClick from "../../utils/outerClick";
|
||||||
import { useWidgetStore } from "../../store/useWidgetStore";
|
import { useWidgetStore } from "../../store/useWidgetStore";
|
||||||
import { getActiveProperties } from "./functions/getActiveProperties";
|
import { getActiveProperties } from "./functions/getActiveProperties";
|
||||||
@@ -65,36 +50,26 @@ interface HiddenPanels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RealTimeVisulization: React.FC = () => {
|
const RealTimeVisulization: React.FC = () => {
|
||||||
const [hiddenPanels, setHiddenPanels] = React.useState<HiddenPanels>({});
|
//zustand
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const [droppedObjects, setDroppedObjects] = useState<any[]>([]);
|
|
||||||
const [zonesData, setZonesData] = useState<FormattedZoneData>({});
|
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
|
const { setRightSelect } = useRightSelected();
|
||||||
const { rightSelect, setRightSelect } = useRightSelected();
|
const { editWidgetOptions } = useEditWidgetOptionsStore();
|
||||||
const { editWidgetOptions, setEditWidgetOptions } =
|
|
||||||
useEditWidgetOptionsStore();
|
|
||||||
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
const { rightClickSelected, setRightClickSelected } = useRightClickSelected();
|
||||||
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
const { setFloatingWidget } = useFloatingWidget();
|
||||||
|
const { widgetSubOption } = useWidgetSubOption();
|
||||||
// const [floatingWidgets, setFloatingWidgets] = useState<Record<string, { zoneName: string; zoneId: string; objects: any[] }>>({});
|
|
||||||
const { floatingWidget, setFloatingWidget } = useFloatingWidget();
|
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
|
||||||
const { widgetSubOption, setWidgetSubOption } = useWidgetSubOption();
|
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
const { setSelectedChartId } = useWidgetStore();
|
const { setSelectedChartId } = useWidgetStore();
|
||||||
|
|
||||||
|
const [hiddenPanels, setHiddenPanels] = React.useState<HiddenPanels>({});
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
|
||||||
|
const [zonesData, setZonesData] = useState<FormattedZoneData>({});
|
||||||
|
const [canvasDimensions, setCanvasDimensions] = useState({ width: 0, height: 0, });
|
||||||
|
|
||||||
OuterClick({
|
OuterClick({
|
||||||
contextClassName: [
|
contextClassName: ["chart-container","floating","sidebar-right-wrapper","card","dropdown-menu","dropdown-options",],
|
||||||
"chart-container",
|
|
||||||
"floating",
|
|
||||||
"sidebar-right-wrapper",
|
|
||||||
"card",
|
|
||||||
"dropdown-menu",
|
|
||||||
"dropdown-options",
|
|
||||||
],
|
|
||||||
setMenuVisible: () => setSelectedChartId(null),
|
setMenuVisible: () => setSelectedChartId(null),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -104,7 +79,6 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
try {
|
try {
|
||||||
const response = await getZone2dData(organization);
|
const response = await getZone2dData(organization);
|
||||||
// console.log('response: ', response);
|
|
||||||
|
|
||||||
if (!Array.isArray(response)) {
|
if (!Array.isArray(response)) {
|
||||||
return;
|
return;
|
||||||
@@ -126,11 +100,11 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
setZonesData(formattedData);
|
setZonesData(formattedData);
|
||||||
} catch (error) {}
|
} catch (error) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
GetZoneData();
|
GetZoneData();
|
||||||
}, [activeModule]); // Removed `zones` from dependencies
|
}, [activeModule]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setZonesData((prev) => {
|
setZonesData((prev) => {
|
||||||
@@ -152,7 +126,6 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
});
|
});
|
||||||
}, [selectedZone]);
|
}, [selectedZone]);
|
||||||
|
|
||||||
// useEffect(() => {}, [floatingWidgets]);
|
|
||||||
|
|
||||||
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
const handleDrop = async (event: React.DragEvent<HTMLDivElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -251,10 +224,10 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
);
|
);
|
||||||
setFloatingWidget(currentZone.objects);
|
setFloatingWidget(currentZone.objects);
|
||||||
} else {
|
} else {
|
||||||
console.warn("Zone not found or zoneId mismatch");
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error in handleDrop:", error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -278,10 +251,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
};
|
};
|
||||||
}, [setRightClickSelected]);
|
}, [setRightClickSelected]);
|
||||||
|
|
||||||
const [canvasDimensions, setCanvasDimensions] = useState({
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
});
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvas = document.getElementById("real-time-vis-canvas");
|
const canvas = document.getElementById("real-time-vis-canvas");
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
@@ -304,14 +274,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<style>
|
<style>
|
||||||
{`
|
{`:root {--realTimeViz-container-width: ${canvasDimensions.width}px;--realTimeViz-container-height: ${canvasDimensions.height}px; }`}
|
||||||
:root {
|
|
||||||
--realTimeViz-container-width: ${canvasDimensions.width}px;
|
|
||||||
|
|
||||||
--realTimeViz-container-height: ${canvasDimensions.height}px;
|
|
||||||
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
</style>
|
</style>
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
@@ -326,11 +289,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
<div className="realTime-viz-wrapper">
|
<div className="realTime-viz-wrapper">
|
||||||
{openConfirmationPopup && (
|
{openConfirmationPopup && (
|
||||||
<RenderOverlay>
|
<RenderOverlay>
|
||||||
<ConfirmationPopup
|
<ConfirmationPopup message={"Are you sure want to delete?"} onConfirm={() => { }} onCancel={() => setOpenConfirmationPopup(false)} />
|
||||||
message={"Are you sure want to delete?"}
|
|
||||||
onConfirm={() => console.log("Confirmed")}
|
|
||||||
onCancel={() => setOpenConfirmationPopup(false)}
|
|
||||||
/>
|
|
||||||
</RenderOverlay>
|
</RenderOverlay>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
@@ -346,51 +305,15 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<Scene />
|
<Scene />
|
||||||
</div>
|
</div>
|
||||||
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
|
{activeModule === "visualization" && selectedZone.zoneName !== "" && (<DroppedObjects />)}
|
||||||
<DroppedObjects />
|
|
||||||
)}
|
|
||||||
{activeModule === "visualization" && <SocketRealTimeViz />}
|
{activeModule === "visualization" && <SocketRealTimeViz />}
|
||||||
|
{activeModule === "visualization" && editWidgetOptions && rightClickSelected && (<EditWidgetOption options={["Duplicate", "Vertical Move", "Horizontal Move", "RotateX", "RotateY", "Delete",]} />)}
|
||||||
{activeModule === "visualization" &&
|
|
||||||
editWidgetOptions &&
|
|
||||||
rightClickSelected && (
|
|
||||||
<EditWidgetOption
|
|
||||||
options={[
|
|
||||||
"Duplicate",
|
|
||||||
"Vertical Move",
|
|
||||||
"Horizontal Move",
|
|
||||||
"RotateX",
|
|
||||||
"RotateY",
|
|
||||||
"Delete",
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{activeModule === "visualization" && (
|
{activeModule === "visualization" && (
|
||||||
<>
|
<>
|
||||||
<DisplayZone
|
<DisplayZone zonesData={zonesData} hiddenPanels={hiddenPanels} setHiddenPanels={setHiddenPanels} />
|
||||||
zonesData={zonesData}
|
{!isPlaying && selectedZone?.zoneName !== "" &&
|
||||||
selectedZone={selectedZone}
|
(<AddButtons hiddenPanels={hiddenPanels} setHiddenPanels={setHiddenPanels} />)}
|
||||||
setSelectedZone={setSelectedZone}
|
<Panel hiddenPanels={hiddenPanels} setZonesData={setZonesData} />
|
||||||
hiddenPanels={hiddenPanels}
|
|
||||||
setHiddenPanels={setHiddenPanels}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!isPlaying && selectedZone?.zoneName !== "" && (
|
|
||||||
<AddButtons
|
|
||||||
hiddenPanels={hiddenPanels}
|
|
||||||
setHiddenPanels={setHiddenPanels}
|
|
||||||
selectedZone={selectedZone}
|
|
||||||
setSelectedZone={setSelectedZone}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Panel
|
|
||||||
selectedZone={selectedZone}
|
|
||||||
setSelectedZone={setSelectedZone}
|
|
||||||
hiddenPanels={hiddenPanels}
|
|
||||||
setZonesData={setZonesData}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,100 +6,48 @@ import {
|
|||||||
} from "../../../../components/icons/RealTimeVisulationIcons";
|
} from "../../../../components/icons/RealTimeVisulationIcons";
|
||||||
import { AddIcon } from "../../../../components/icons/ExportCommonIcons";
|
import { AddIcon } from "../../../../components/icons/ExportCommonIcons";
|
||||||
import { useSocketStore } from "../../../../store/store";
|
import { useSocketStore } from "../../../../store/store";
|
||||||
import { clearPanel } from "../../../../services/realTimeVisulization/zoneData/clearPanel";
|
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
||||||
import { lockPanel } from "../../../../services/realTimeVisulization/zoneData/lockPanel";
|
|
||||||
|
|
||||||
// Define the type for `Side`
|
// Define the type for `Side`
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
// Define the type for HiddenPanels, where keys are zone IDs and values are arrays of hidden sides
|
|
||||||
interface HiddenPanels {
|
interface HiddenPanels {
|
||||||
[zoneId: string]: Side[];
|
[zoneId: string]: Side[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the type for the props passed to the Buttons component
|
|
||||||
interface ButtonsProps {
|
interface ButtonsProps {
|
||||||
selectedZone: {
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
points: [];
|
|
||||||
zoneId: string;
|
|
||||||
zoneViewPortTarget: number[];
|
|
||||||
zoneViewPortPosition: number[];
|
|
||||||
widgets: {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}[];
|
|
||||||
};
|
|
||||||
setSelectedZone: React.Dispatch<
|
|
||||||
React.SetStateAction<{
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
points: [];
|
|
||||||
zoneId: string;
|
|
||||||
zoneViewPortTarget: number[];
|
|
||||||
zoneViewPortPosition: number[];
|
|
||||||
widgets: {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}[];
|
|
||||||
}>
|
|
||||||
>;
|
|
||||||
hiddenPanels: HiddenPanels; // Updated prop type
|
hiddenPanels: HiddenPanels; // Updated prop type
|
||||||
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
||||||
}
|
}
|
||||||
|
|
||||||
const AddButtons: React.FC<ButtonsProps> = ({
|
const AddButtons: React.FC<ButtonsProps> = ({ setHiddenPanels, hiddenPanels, }) => {
|
||||||
selectedZone,
|
|
||||||
setSelectedZone,
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
setHiddenPanels,
|
|
||||||
hiddenPanels,
|
|
||||||
}) => {
|
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
|
|
||||||
// Function to toggle visibility of a panel
|
// Function to toggle visibility of a panel
|
||||||
const toggleVisibility = (side: Side) => {
|
const toggleVisibility = (side: Side) => {
|
||||||
const isHidden = hiddenPanels[selectedZone.zoneId]?.includes(side) ?? false;
|
const isHidden = hiddenPanels[selectedZone.zoneId]?.includes(side) ?? false;
|
||||||
|
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
// If the panel is already hidden, remove it from the hiddenPanels array for this zone
|
// If the panel is already hidden, remove it from the hiddenPanels array for this zone
|
||||||
setHiddenPanels((prevHiddenPanels) => ({
|
setHiddenPanels((prevHiddenPanels) => ({
|
||||||
...prevHiddenPanels,
|
...prevHiddenPanels,
|
||||||
[selectedZone.zoneId]: prevHiddenPanels[selectedZone.zoneId].filter(
|
[selectedZone.zoneId]: prevHiddenPanels[selectedZone.zoneId].filter((panel) => panel !== side),
|
||||||
(panel) => panel !== side
|
|
||||||
),
|
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
// If the panel is visible, add it to the hiddenPanels array for this zone
|
// If the panel is visible, add it to the hiddenPanels array for this zone
|
||||||
setHiddenPanels((prevHiddenPanels) => ({
|
setHiddenPanels((prevHiddenPanels) => ({
|
||||||
...prevHiddenPanels,
|
...prevHiddenPanels,
|
||||||
[selectedZone.zoneId]: [
|
[selectedZone.zoneId]: [...(prevHiddenPanels[selectedZone.zoneId] || []), side,],
|
||||||
...(prevHiddenPanels[selectedZone.zoneId] || []),
|
|
||||||
side,
|
|
||||||
],
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to toggle lock/unlock a panel
|
// Function to toggle lock/unlock a panel
|
||||||
const toggleLockPanel = async (side: Side) => {
|
const toggleLockPanel = async (side: Side) => {
|
||||||
// console.log('side: ', side);
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
||||||
//add api
|
|
||||||
const newLockedPanels = selectedZone.lockedPanels.includes(side)
|
const newLockedPanels = selectedZone.lockedPanels.includes(side) ? selectedZone.lockedPanels.filter((panel) => panel !== side) : [...selectedZone.lockedPanels, side];
|
||||||
? selectedZone.lockedPanels.filter((panel) => panel !== side)
|
|
||||||
: [...selectedZone.lockedPanels, side];
|
|
||||||
|
|
||||||
const updatedZone = {
|
const updatedZone = {
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
@@ -114,10 +62,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-panel:locked", lockedPanel);
|
visualizationSocket.emit("v2:viz-panel:locked", lockedPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
// let response = await lockPanel(selectedZone.zoneId, organization, newLockedPanels)
|
// let response = await lockPanel(selectedZone.zoneId, organization, newLockedPanels)
|
||||||
// console.log('response: ', response);
|
//
|
||||||
// if (response.message === 'locked panel updated successfully') {
|
// if (response.message === 'locked panel updated successfully') {
|
||||||
// // Update the selectedZone state
|
// // Update the selectedZone state
|
||||||
// setSelectedZone(updatedZone);
|
// setSelectedZone(updatedZone);
|
||||||
@@ -126,17 +73,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
|
|
||||||
// Function to clean all widgets from a panel
|
// Function to clean all widgets from a panel
|
||||||
const cleanPanel = async (side: Side) => {
|
const cleanPanel = async (side: Side) => {
|
||||||
//add api
|
if (hiddenPanels[selectedZone.zoneId]?.includes(side) || selectedZone.lockedPanels.includes(side)) return;
|
||||||
// console.log('side: ', side);
|
|
||||||
if (
|
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(side) ||
|
|
||||||
selectedZone.lockedPanels.includes(side)
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
||||||
|
|
||||||
let clearPanel = {
|
let clearPanel = {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
panelName: side,
|
panelName: side,
|
||||||
@@ -145,54 +84,33 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-panel:clear", clearPanel);
|
visualizationSocket.emit("v2:viz-panel:clear", clearPanel);
|
||||||
}
|
}
|
||||||
const cleanedWidgets = selectedZone.widgets.filter(
|
const cleanedWidgets = selectedZone.widgets.filter((widget) => widget.panel !== side);
|
||||||
(widget) => widget.panel !== side
|
|
||||||
);
|
|
||||||
const updatedZone = {
|
const updatedZone = {
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
widgets: cleanedWidgets,
|
widgets: cleanedWidgets,
|
||||||
};
|
};
|
||||||
// Update the selectedZone state
|
// Update the selectedZone state
|
||||||
// console.log('updatedZone: ', updatedZone);
|
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
|
|
||||||
// let response = await clearPanel(selectedZone.zoneId, organization, side)
|
|
||||||
// console.log('response: ', response);
|
|
||||||
// if (response.message === 'PanelWidgets cleared successfully') {
|
|
||||||
|
|
||||||
// const cleanedWidgets = selectedZone.widgets.filter(
|
|
||||||
// (widget) => widget.panel !== side
|
|
||||||
// );
|
|
||||||
// const updatedZone = {
|
|
||||||
// ...selectedZone,
|
|
||||||
// widgets: cleanedWidgets,
|
|
||||||
// };
|
|
||||||
// // Update the selectedZone state
|
|
||||||
// setSelectedZone(updatedZone);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to handle "+" button click
|
// Function to handle "+" button click
|
||||||
const handlePlusButtonClick = async (side: Side) => {
|
const handlePlusButtonClick = async (side: Side) => {
|
||||||
if (selectedZone.activeSides.includes(side)) {
|
|
||||||
console.log("open");
|
// Get email and organization safely with a default fallback
|
||||||
// Panel already exists: Remove widgets from that side and update activeSides
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]; // Fallback value
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
|
||||||
|
if (selectedZone.activeSides.includes(side)) {
|
||||||
|
// Panel already exists: Remove widgets from that side and update activeSides
|
||||||
// Remove all widgets associated with the side and update active sides
|
// 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
|
|
||||||
);
|
|
||||||
const newActiveSides = selectedZone.activeSides.filter((s) => s !== side);
|
const newActiveSides = selectedZone.activeSides.filter((s) => s !== side);
|
||||||
|
|
||||||
const updatedZone = {
|
const updatedZone = {
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
widgets: cleanedWidgets,
|
widgets: cleanedWidgets,
|
||||||
activeSides: newActiveSides,
|
activeSides: newActiveSides,
|
||||||
panelOrder: newActiveSides,
|
panelOrder: newActiveSides,
|
||||||
};
|
};
|
||||||
|
|
||||||
let deletePanel = {
|
let deletePanel = {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
panelName: side,
|
panelName: side,
|
||||||
@@ -202,41 +120,17 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
visualizationSocket.emit("v2:viz-panel:delete", deletePanel);
|
visualizationSocket.emit("v2:viz-panel:delete", deletePanel);
|
||||||
}
|
}
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
|
|
||||||
if (hiddenPanels[selectedZone.zoneId]?.includes(side)) {
|
if (hiddenPanels[selectedZone.zoneId]?.includes(side)) {
|
||||||
setHiddenPanels((prev) => ({
|
setHiddenPanels((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[selectedZone.zoneId]: prev[selectedZone.zoneId].filter(
|
[selectedZone.zoneId]: prev[selectedZone.zoneId].filter((s) => s !== side),
|
||||||
(s) => s !== side
|
|
||||||
),
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(hiddenPanels[selectedZone.zoneId].includes(side))
|
|
||||||
|
|
||||||
// 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 {
|
||||||
// Panel does not exist: Create panel
|
// Panel does not exist: Create panel
|
||||||
try {
|
try {
|
||||||
// Get email and organization safely with a default fallback
|
|
||||||
const email = localStorage.getItem("email") || "";
|
|
||||||
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, side];
|
||||||
? [...selectedZone.activeSides]
|
|
||||||
: [...selectedZone.activeSides, side];
|
|
||||||
|
|
||||||
const updatedZone = {
|
const updatedZone = {
|
||||||
...selectedZone,
|
...selectedZone,
|
||||||
activeSides: newActiveSides,
|
activeSides: newActiveSides,
|
||||||
@@ -251,15 +145,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
visualizationSocket.emit("v2:viz-panel:add", addPanel);
|
visualizationSocket.emit("v2:viz-panel:add", addPanel);
|
||||||
}
|
}
|
||||||
setSelectedZone(updatedZone);
|
setSelectedZone(updatedZone);
|
||||||
// API call to create panels
|
} catch (error) { }
|
||||||
// const response = await panelData(organization, selectedZone.zoneId, newActiveSides);
|
|
||||||
//
|
|
||||||
|
|
||||||
// if (response.message === "Panels created successfully") {
|
|
||||||
// } else {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
} catch (error) {}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@@ -268,20 +154,11 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
{(["top", "right", "bottom", "left"] as Side[]).map((side) => (
|
{(["top", "right", "bottom", "left"] as Side[]).map((side) => (
|
||||||
<div key={side} className={`side-button-container ${side}`}>
|
<div key={side} className={`side-button-container ${side}`}>
|
||||||
{/* "+" Button */}
|
{/* "+" Button */}
|
||||||
<button
|
<button className={`side-button ${side}${selectedZone.activeSides.includes(side) ? " active" : ""}`}
|
||||||
className={`side-button ${side}${
|
|
||||||
selectedZone.activeSides.includes(side) ? " active" : ""
|
|
||||||
}`}
|
|
||||||
onClick={() => handlePlusButtonClick(side)}
|
onClick={() => handlePlusButtonClick(side)}
|
||||||
title={
|
title={selectedZone.activeSides.includes(side) ? `Remove all items and close ${side} panel` : `Activate ${side} panel`}
|
||||||
selectedZone.activeSides.includes(side)
|
|
||||||
? `Remove all items and close ${side} panel`
|
|
||||||
: `Activate ${side} panel`
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<div className="add-icon">
|
<div className="add-icon"><AddIcon /></div>
|
||||||
<AddIcon />
|
|
||||||
</div>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Extra Buttons */}
|
{/* Extra Buttons */}
|
||||||
@@ -289,62 +166,28 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
|||||||
<div className="extra-Bs">
|
<div className="extra-Bs">
|
||||||
{/* Hide Panel */}
|
{/* Hide Panel */}
|
||||||
<div
|
<div
|
||||||
className={`icon ${
|
className={`icon ${hiddenPanels[selectedZone.zoneId]?.includes(side) ? "active" : ""}`}
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
title={hiddenPanels[selectedZone.zoneId]?.includes(side) ? "Show Panel" : "Hide Panel"}
|
||||||
? "active"
|
|
||||||
: ""
|
|
||||||
}`}
|
|
||||||
title={
|
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
|
||||||
? "Show Panel"
|
|
||||||
: "Hide Panel"
|
|
||||||
}
|
|
||||||
onClick={() => toggleVisibility(side)}
|
onClick={() => toggleVisibility(side)}
|
||||||
>
|
>
|
||||||
<EyeIcon
|
<EyeIcon fill={hiddenPanels[selectedZone.zoneId]?.includes(side) ? "var(--primary-color)" : "var(--text-color)"} />
|
||||||
fill={
|
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
|
||||||
? "var(--primary-color)"
|
|
||||||
: "var(--text-color)"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Clean Panel */}
|
{/* Clean Panel */}
|
||||||
<div
|
<div className="icon" title="Clean Panel"
|
||||||
className="icon"
|
|
||||||
title="Clean Panel"
|
|
||||||
onClick={() => cleanPanel(side)}
|
onClick={() => cleanPanel(side)}
|
||||||
style={{
|
style={{ cursor: hiddenPanels[selectedZone.zoneId]?.includes(side) || selectedZone.lockedPanels.includes(side) ? "not-allowed" : "pointer", }}
|
||||||
cursor:
|
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(side) ||
|
|
||||||
selectedZone.lockedPanels.includes(side)
|
|
||||||
? "not-allowed"
|
|
||||||
: "pointer",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<CleanPannel />
|
<CleanPannel />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Lock/Unlock Panel */}
|
{/* Lock/Unlock Panel */}
|
||||||
<div
|
<div
|
||||||
className={`icon ${
|
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""}`}
|
||||||
selectedZone.lockedPanels.includes(side) ? "active" : ""
|
title={selectedZone.lockedPanels.includes(side) ? "Unlock Panel" : "Lock Panel"}
|
||||||
}`}
|
|
||||||
title={
|
|
||||||
selectedZone.lockedPanels.includes(side)
|
|
||||||
? "Unlock Panel"
|
|
||||||
: "Lock Panel"
|
|
||||||
}
|
|
||||||
onClick={() => toggleLockPanel(side)}
|
onClick={() => toggleLockPanel(side)}
|
||||||
>
|
>
|
||||||
<LockIcon
|
<LockIcon fill={selectedZone.lockedPanels.includes(side) ? "var(--primary-color)" : "var(--text-color)"} />
|
||||||
fill={
|
|
||||||
selectedZone.lockedPanels.includes(side)
|
|
||||||
? "var(--primary-color)"
|
|
||||||
: "var(--text-color)"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -5,94 +5,46 @@ import { useAsset3dWidget, useSocketStore } from "../../../../store/store";
|
|||||||
import { usePlayButtonStore } from "../../../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../../store/usePlayButtonStore";
|
||||||
import { useWidgetStore } from "../../../../store/useWidgetStore";
|
import { useWidgetStore } from "../../../../store/useWidgetStore";
|
||||||
import { DraggableWidget } from "../2d/DraggableWidget";
|
import { DraggableWidget } from "../2d/DraggableWidget";
|
||||||
|
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
interface Widget {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PanelProps {
|
interface PanelProps {
|
||||||
selectedZone: {
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
points: [];
|
|
||||||
zoneId: string;
|
|
||||||
zoneViewPortTarget: number[];
|
|
||||||
zoneViewPortPosition: number[];
|
|
||||||
widgets: Widget[];
|
|
||||||
};
|
|
||||||
setSelectedZone: React.Dispatch<
|
|
||||||
React.SetStateAction<{
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
points: [];
|
|
||||||
zoneId: string;
|
|
||||||
zoneViewPortTarget: number[];
|
|
||||||
zoneViewPortPosition: number[];
|
|
||||||
widgets: Widget[];
|
|
||||||
}>
|
|
||||||
>;
|
|
||||||
hiddenPanels: any;
|
hiddenPanels: any;
|
||||||
setZonesData: React.Dispatch<React.SetStateAction<any>>;
|
setZonesData: React.Dispatch<React.SetStateAction<any>>;
|
||||||
}
|
}
|
||||||
|
const generateUniqueId = () =>`${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
|
||||||
const generateUniqueId = () =>
|
const Panel: React.FC<PanelProps> = ({hiddenPanels,setZonesData,}) => {
|
||||||
`${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
//zustand state
|
||||||
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
const Panel: React.FC<PanelProps> = ({
|
|
||||||
selectedZone,
|
|
||||||
setSelectedZone,
|
|
||||||
hiddenPanels,
|
|
||||||
setZonesData,
|
|
||||||
}) => {
|
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
|
||||||
const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
|
|
||||||
const [panelDimensions, setPanelDimensions] = useState<{
|
|
||||||
[side in Side]?: { width: number; height: number };
|
|
||||||
}>({});
|
|
||||||
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
const [canvasDimensions, setCanvasDimensions] = useState({
|
|
||||||
width: 0,
|
const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
|
||||||
height: 0,
|
const [panelDimensions, setPanelDimensions] = useState<{ [side in Side]?: { width: number; height: number }; }>({});
|
||||||
});
|
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
||||||
|
const [canvasDimensions, setCanvasDimensions] = useState({ width: 0, height: 0, });
|
||||||
|
|
||||||
// Track canvas dimensions
|
// Track canvas dimensions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvas = document.getElementById("real-time-vis-canvas");
|
const canvas = document.getElementById("real-time-vis-canvas");
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
|
|
||||||
const updateCanvasDimensions = () => {
|
const updateCanvasDimensions = () => {
|
||||||
const rect = canvas.getBoundingClientRect();
|
const rect = canvas.getBoundingClientRect();
|
||||||
setCanvasDimensions({
|
setCanvasDimensions({ width: rect.width, height: rect.height, });
|
||||||
width: rect.width,
|
|
||||||
height: rect.height,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCanvasDimensions();
|
updateCanvasDimensions();
|
||||||
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
const resizeObserver = new ResizeObserver(updateCanvasDimensions);
|
||||||
resizeObserver.observe(canvas);
|
resizeObserver.observe(canvas);
|
||||||
|
|
||||||
return () => resizeObserver.unobserve(canvas);
|
return () => resizeObserver.unobserve(canvas);
|
||||||
}, []);
|
}, []);
|
||||||
|
// Calculate panel size // Min 170px
|
||||||
// Calculate panel size
|
const panelSize = Math.max(Math.min(canvasDimensions.width * 0.25, canvasDimensions.height * 0.25), 170);
|
||||||
const panelSize = Math.max(
|
// Check if panel is locked
|
||||||
Math.min(canvasDimensions.width * 0.25, canvasDimensions.height * 0.25),
|
const isPanelLocked = (panel: Side) => selectedZone.lockedPanels.includes(panel);
|
||||||
170 // Min 170px
|
// Get current widget count in a panel
|
||||||
);
|
const getCurrentWidgetCount = (panel: Side) => selectedZone.widgets.filter((w) => w.panel === panel).length;
|
||||||
|
|
||||||
// Define getPanelStyle
|
// Define getPanelStyle
|
||||||
const getPanelStyle = useMemo(
|
const getPanelStyle = useMemo(
|
||||||
() => (side: Side) => {
|
() => (side: Side) => {
|
||||||
@@ -108,8 +60,7 @@ const Panel: React.FC<PanelProps> = ({
|
|||||||
case "bottom":
|
case "bottom":
|
||||||
return {
|
return {
|
||||||
minWidth: "170px",
|
minWidth: "170px",
|
||||||
width: `calc(100% - ${(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)
|
width: `calc(100% - ${(leftActive ? panelSize : 0) + (rightActive ? panelSize : 0)}px)`,
|
||||||
}px)`,
|
|
||||||
minHeight: "170px",
|
minHeight: "170px",
|
||||||
height: `${panelSize}px`,
|
height: `${panelSize}px`,
|
||||||
left: leftActive ? `${panelSize}px` : "0",
|
left: leftActive ? `${panelSize}px` : "0",
|
||||||
@@ -122,8 +73,7 @@ const Panel: React.FC<PanelProps> = ({
|
|||||||
minWidth: "170px",
|
minWidth: "170px",
|
||||||
width: `${panelSize}px`,
|
width: `${panelSize}px`,
|
||||||
minHeight: "170px",
|
minHeight: "170px",
|
||||||
height: `calc(100% - ${(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)
|
height: `calc(100% - ${(topActive ? panelSize : 0) + (bottomActive ? panelSize : 0)}px)`,
|
||||||
}px)`,
|
|
||||||
top: topActive ? `${panelSize}px` : "0",
|
top: topActive ? `${panelSize}px` : "0",
|
||||||
bottom: bottomActive ? `${panelSize}px` : "0",
|
bottom: bottomActive ? `${panelSize}px` : "0",
|
||||||
[side]: "0",
|
[side]: "0",
|
||||||
@@ -134,82 +84,54 @@ const Panel: React.FC<PanelProps> = ({
|
|||||||
},
|
},
|
||||||
[selectedZone.panelOrder, panelSize]
|
[selectedZone.panelOrder, panelSize]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Handle drop event
|
// Handle drop event
|
||||||
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
const handleDrop = (e: React.DragEvent, panel: Side) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { draggedAsset } = useWidgetStore.getState();
|
const { draggedAsset } = useWidgetStore.getState();
|
||||||
if (
|
if (!draggedAsset || isPanelLocked(panel) || hiddenPanels[selectedZone.zoneId]?.includes(panel)) return;
|
||||||
!draggedAsset ||
|
|
||||||
isPanelLocked(panel) ||
|
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(panel)
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const currentWidgetsCount = getCurrentWidgetCount(panel);
|
const currentWidgetsCount = getCurrentWidgetCount(panel);
|
||||||
const maxCapacity = calculatePanelCapacity(panel);
|
const maxCapacity = calculatePanelCapacity(panel);
|
||||||
|
|
||||||
|
|
||||||
if (currentWidgetsCount < maxCapacity) {
|
if (currentWidgetsCount < maxCapacity) {
|
||||||
addWidgetToPanel(draggedAsset, panel);
|
addWidgetToPanel(draggedAsset, panel);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if panel is locked
|
|
||||||
const isPanelLocked = (panel: Side) =>
|
|
||||||
selectedZone.lockedPanels.includes(panel);
|
|
||||||
|
|
||||||
// Get current widget count in a panel
|
|
||||||
const getCurrentWidgetCount = (panel: Side) =>
|
|
||||||
selectedZone.widgets.filter((w) => w.panel === panel).length;
|
|
||||||
|
|
||||||
// Calculate panel capacity
|
// Calculate panel capacity
|
||||||
const calculatePanelCapacity = (panel: Side) => {
|
const calculatePanelCapacity = (panel: Side) => {
|
||||||
const CHART_WIDTH = panelSize - 10;
|
const CHART_WIDTH = panelSize - 10;
|
||||||
const CHART_HEIGHT = panelSize - 10;
|
const CHART_HEIGHT = panelSize - 10;
|
||||||
|
|
||||||
const dimensions = panelDimensions[panel];
|
const dimensions = panelDimensions[panel];
|
||||||
if (!dimensions) {
|
if (!dimensions) {
|
||||||
return panel === "top" || panel === "bottom" ? 5 : 3; // Fallback capacities
|
return panel === "top" || panel === "bottom" ? 5 : 3; // Fallback capacities
|
||||||
}
|
}
|
||||||
|
return panel === "top" || panel === "bottom" ? Math.max(1, Math.floor(dimensions.width / CHART_WIDTH)) : Math.max(1, Math.floor(dimensions.height / CHART_HEIGHT));
|
||||||
return panel === "top" || panel === "bottom"
|
|
||||||
? Math.max(1, Math.floor(dimensions.width / CHART_WIDTH))
|
|
||||||
: Math.max(1, Math.floor(dimensions.height / CHART_HEIGHT));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add widget to panel
|
// Add widget to panel
|
||||||
const addWidgetToPanel = async (asset: any, panel: Side) => {
|
const addWidgetToPanel = async (asset: any, panel: Side) => {
|
||||||
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 newWidget = {
|
const newWidget = {
|
||||||
...asset,
|
...asset,
|
||||||
id: generateUniqueId(),
|
id: generateUniqueId(),
|
||||||
panel,
|
panel,
|
||||||
};
|
};
|
||||||
|
|
||||||
let addWidget = {
|
let addWidget = {
|
||||||
organization: organization,
|
organization: organization,
|
||||||
zoneId: selectedZone.zoneId,
|
zoneId: selectedZone.zoneId,
|
||||||
widget: newWidget,
|
widget: newWidget,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
visualizationSocket.emit("v2:viz-widget:add", addWidget);
|
visualizationSocket.emit("v2:viz-widget:add", addWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelectedZone((prev) => ({
|
setSelectedZone((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
widgets: [...prev.widgets, newWidget],
|
widgets: [...prev.widgets, newWidget],
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Observe panel dimensions
|
// Observe panel dimensions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const observers: ResizeObserver[] = [];
|
const observers: ResizeObserver[] = [];
|
||||||
const currentPanelRefs = panelRefs.current;
|
const currentPanelRefs = panelRefs.current;
|
||||||
|
|
||||||
selectedZone.activeSides.forEach((side) => {
|
selectedZone.activeSides.forEach((side) => {
|
||||||
const element = currentPanelRefs[side];
|
const element = currentPanelRefs[side];
|
||||||
if (element) {
|
if (element) {
|
||||||
@@ -232,24 +154,18 @@ const Panel: React.FC<PanelProps> = ({
|
|||||||
observers.forEach((observer) => observer.disconnect());
|
observers.forEach((observer) => observer.disconnect());
|
||||||
};
|
};
|
||||||
}, [selectedZone.activeSides]);
|
}, [selectedZone.activeSides]);
|
||||||
|
|
||||||
// Handle widget reordering
|
// Handle widget reordering
|
||||||
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
|
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
|
||||||
setSelectedZone((prev) => {
|
setSelectedZone((prev) => {
|
||||||
const widgetsInPanel = prev.widgets.filter((w) => w.panel === panel);
|
const widgetsInPanel = prev.widgets.filter((w) => w.panel === panel);
|
||||||
const reorderedWidgets = arrayMove(widgetsInPanel, fromIndex, toIndex);
|
const reorderedWidgets = arrayMove(widgetsInPanel, fromIndex, toIndex);
|
||||||
|
const updatedWidgets = prev.widgets.filter((widget) => widget.panel !== panel).concat(reorderedWidgets);
|
||||||
const updatedWidgets = prev.widgets
|
|
||||||
.filter((widget) => widget.panel !== panel)
|
|
||||||
.concat(reorderedWidgets);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
widgets: updatedWidgets,
|
widgets: updatedWidgets,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate capacities and dimensions
|
// Calculate capacities and dimensions
|
||||||
const topWidth = getPanelStyle("top").width;
|
const topWidth = getPanelStyle("top").width;
|
||||||
const bottomWidth = getPanelStyle("bottom").height;
|
const bottomWidth = getPanelStyle("bottom").height;
|
||||||
@@ -283,41 +199,29 @@ const Panel: React.FC<PanelProps> = ({
|
|||||||
<div
|
<div
|
||||||
key={side}
|
key={side}
|
||||||
id="panel-wrapper"
|
id="panel-wrapper"
|
||||||
className={`panel ${side}-panel absolute ${hiddenPanels[selectedZone.zoneId]?.includes(side) ? "hidePanel" : ""
|
className={`panel ${side}-panel absolute ${hiddenPanels[selectedZone.zoneId]?.includes(side) ? "hidePanel" : ""}`}
|
||||||
}`}
|
|
||||||
style={getPanelStyle(side)}
|
style={getPanelStyle(side)}
|
||||||
onDrop={(e) => handleDrop(e, side)}
|
onDrop={(e) => handleDrop(e, side)}
|
||||||
onDragOver={(e) => e.preventDefault()}
|
onDragOver={(e) => e.preventDefault()}
|
||||||
ref={(el) => {
|
ref={(el) => {
|
||||||
if (el) {
|
if (el) { panelRefs.current[side] = el; }
|
||||||
panelRefs.current[side] = el;
|
else { delete panelRefs.current[side]; }
|
||||||
} else {
|
|
||||||
delete panelRefs.current[side];
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`panel-content ${isPlaying && "fullScreen"}`}
|
className={`panel-content ${isPlaying && "fullScreen"}`}
|
||||||
style={{
|
style={{
|
||||||
pointerEvents:
|
pointerEvents:selectedZone.lockedPanels.includes(side) || hiddenPanels[selectedZone.zoneId]?.includes(side)? "none": "auto",
|
||||||
selectedZone.lockedPanels.includes(side) ||
|
|
||||||
hiddenPanels[selectedZone.zoneId]?.includes(side)
|
|
||||||
? "none"
|
|
||||||
: "auto",
|
|
||||||
opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1",
|
opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{selectedZone.widgets
|
{selectedZone.widgets.filter((w) => w.panel === side).map((widget, index) => (
|
||||||
.filter((w) => w.panel === side)
|
|
||||||
.map((widget, index) => (
|
|
||||||
<DraggableWidget
|
<DraggableWidget
|
||||||
hiddenPanels={hiddenPanels}
|
hiddenPanels={hiddenPanels}
|
||||||
widget={widget}
|
widget={widget}
|
||||||
key={widget.id}
|
key={widget.id}
|
||||||
index={index}
|
index={index}
|
||||||
onReorder={(fromIndex, toIndex) =>
|
onReorder={(fromIndex, toIndex) =>handleReorder(fromIndex, toIndex, side)}
|
||||||
handleReorder(fromIndex, toIndex, side)
|
|
||||||
}
|
|
||||||
openKebabId={openKebabId}
|
openKebabId={openKebabId}
|
||||||
setOpenKebabId={setOpenKebabId}
|
setOpenKebabId={setOpenKebabId}
|
||||||
selectedZone={selectedZone}
|
selectedZone={selectedZone}
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
import React, { useEffect, useRef } from 'react'
|
import React, { useEffect, useRef } from 'react'
|
||||||
import { useSelectedFloorItem, useZoneAssetId } from '../../store/store';
|
import { useSelectedFloorItem, useZoneAssetId, useToggleView } from '../../store/store';
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useThree } from '@react-three/fiber';
|
import { useThree } from '@react-three/fiber';
|
||||||
import * as Types from "../../types/world/worldTypes";
|
|
||||||
export default function ZoneAssets() {
|
export default function ZoneAssets() {
|
||||||
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
|
const { zoneAssetId } = useZoneAssetId();
|
||||||
const { setSelectedFloorItem } = useSelectedFloorItem();
|
const { setSelectedFloorItem } = useSelectedFloorItem();
|
||||||
const { raycaster, controls, scene }: any = useThree();
|
const { toggleView } = useToggleView();
|
||||||
useEffect(() => {
|
const { controls, scene }: any = useThree();
|
||||||
// console.log('zoneAssetId: ', zoneAssetId);
|
|
||||||
if (!zoneAssetId) return
|
function focusAsset(AssetMesh: any) {
|
||||||
console.log('zoneAssetId: ', zoneAssetId);
|
console.log('AssetMesh: ', AssetMesh);
|
||||||
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
if (toggleView) return;
|
||||||
if (AssetMesh) {
|
|
||||||
const bbox = new THREE.Box3().setFromObject(AssetMesh);
|
const bbox = new THREE.Box3().setFromObject(AssetMesh);
|
||||||
const size = bbox.getSize(new THREE.Vector3());
|
const size = bbox.getSize(new THREE.Vector3());
|
||||||
const center = bbox.getCenter(new THREE.Vector3());
|
const center = bbox.getCenter(new THREE.Vector3());
|
||||||
@@ -29,53 +27,33 @@ export default function ZoneAssets() {
|
|||||||
controls.fitToBox(AssetMesh, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
controls.fitToBox(AssetMesh, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
||||||
|
|
||||||
setSelectedFloorItem(AssetMesh);
|
setSelectedFloorItem(AssetMesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!zoneAssetId) return
|
||||||
|
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
||||||
|
|
||||||
|
if (AssetMesh) {
|
||||||
|
focusAsset(AssetMesh)
|
||||||
} else {
|
} else {
|
||||||
console.log('zoneAssetId: ', zoneAssetId)
|
|
||||||
if (Array.isArray(zoneAssetId.position) && zoneAssetId.position.length >= 3) {
|
if (Array.isArray(zoneAssetId.position) && zoneAssetId.position.length >= 3) {
|
||||||
let selectedAssetPosition = [
|
let selectedAssetPosition = [zoneAssetId.position[0], 10, zoneAssetId.position[2]];
|
||||||
zoneAssetId.position[0],
|
let selectedAssetTarget = [zoneAssetId.position[0], zoneAssetId.position[1], zoneAssetId.position[2]];
|
||||||
10,
|
const setCamera = async () => {
|
||||||
zoneAssetId.position[2]
|
|
||||||
];
|
|
||||||
console.log('selectedAssetPosition: ', selectedAssetPosition);
|
|
||||||
let selectedAssetTarget = [
|
|
||||||
zoneAssetId.position[0],
|
|
||||||
zoneAssetId.position[1],
|
|
||||||
zoneAssetId.position[2]
|
|
||||||
];
|
|
||||||
console.log('selectedAssetTarget: ', selectedAssetTarget);
|
|
||||||
const setCam = async () => {
|
|
||||||
await controls?.setLookAt(...selectedAssetPosition, ...selectedAssetTarget, true);
|
await controls?.setLookAt(...selectedAssetPosition, ...selectedAssetTarget, true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
let AssetMesh = scene.getObjectByProperty("uuid", zoneAssetId.id);
|
||||||
if (AssetMesh) {
|
if (AssetMesh) {
|
||||||
const bbox = new THREE.Box3().setFromObject(AssetMesh);
|
focusAsset(AssetMesh)
|
||||||
const size = bbox.getSize(new THREE.Vector3());
|
|
||||||
const center = bbox.getCenter(new THREE.Vector3());
|
|
||||||
|
|
||||||
const front = new THREE.Vector3(0, 0, 1);
|
|
||||||
AssetMesh.localToWorld(front);
|
|
||||||
front.sub(AssetMesh.position).normalize();
|
|
||||||
|
|
||||||
const distance = Math.max(size.x, size.y, size.z) * 2;
|
|
||||||
const newPosition = center.clone().addScaledVector(front, distance);
|
|
||||||
|
|
||||||
controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
|
|
||||||
controls.setTarget(center.x, center.y, center.z, true);
|
|
||||||
controls.fitToBox(AssetMesh, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
|
|
||||||
|
|
||||||
setSelectedFloorItem(AssetMesh);
|
|
||||||
}
|
}
|
||||||
}, 500)
|
}, 500)
|
||||||
|
|
||||||
};
|
};
|
||||||
setCam();
|
setCamera();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [zoneAssetId, scene, controls])
|
}, [zoneAssetId, scene, controls])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user