Merge branch 'main' into rtViz

This commit is contained in:
2025-03-27 18:10:13 +05:30
51 changed files with 2815 additions and 14707 deletions

View File

@@ -5,6 +5,7 @@ import {
LockIcon,
} from "../../icons/RealTimeVisulationIcons";
import { panelData } from "../../../services/realTimeVisulization/zoneData/panel";
import { AddIcon } from "../../icons/ExportCommonIcons";
// Define the type for `Side`
type Side = "top" | "bottom" | "left" | "right";
@@ -18,7 +19,7 @@ interface ButtonsProps {
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
zoneViewPortPosition: number[];
widgets: {
id: string;
type: string;
@@ -35,7 +36,7 @@ interface ButtonsProps {
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
zoneViewPortPosition: number[];
widgets: {
id: string;
type: string;
@@ -116,7 +117,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
};
// Delete the selectedZone state
console.log('updatedZone: ', updatedZone);
console.log("updatedZone: ", updatedZone);
setSelectedZone(updatedZone);
} else {
// If the panel is not active, activate it
@@ -127,8 +128,8 @@ const AddButtons: React.FC<ButtonsProps> = ({
activeSides: newActiveSides,
panelOrder: newActiveSides,
};
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
const email = localStorage.getItem("email");
const organization = email!.split("@")[1].split(".")[0];
// let response = panelData(organization, selectedZone.zoneId, newActiveSides)
// console.log('response: ', response);
@@ -145,7 +146,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
<div key={side} className={`side-button-container ${side}`}>
{/* "+" Button */}
<button
className={`side-button ${side}`}
className={`side-button ${side}${
selectedZone.activeSides.includes(side) ? " active" : ""
}`}
onClick={() => handlePlusButtonClick(side)}
title={
selectedZone.activeSides.includes(side)
@@ -153,7 +156,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
: `Activate ${side} panel`
}
>
+
<div className="add-icon">
<AddIcon />
</div>
</button>
{/* Extra Buttons */}
@@ -161,19 +166,16 @@ const AddButtons: React.FC<ButtonsProps> = ({
<div className="extra-Bs">
{/* Hide Panel */}
<div
className={`icon ${hiddenPanels.includes(side) ? "active" : ""
}`}
className={`icon ${
hiddenPanels.includes(side) ? "active" : ""
}`}
title={
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
}
onClick={() => toggleVisibility(side)}
>
<EyeIcon
fill={
hiddenPanels.includes(side)
? "white"
: "#1D1E21"
}
fill={hiddenPanels.includes(side) ? "var(--primary-color)" : "var(--text-color)"}
/>
</div>
@@ -188,8 +190,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
{/* Lock/Unlock Panel */}
<div
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
}`}
className={`icon ${
selectedZone.lockedPanels.includes(side) ? "active" : ""
}`}
title={
selectedZone.lockedPanels.includes(side)
? "Unlock Panel"
@@ -197,7 +200,13 @@ const AddButtons: React.FC<ButtonsProps> = ({
}
onClick={() => toggleLockPanel(side)}
>
<LockIcon fill={selectedZone.lockedPanels.includes(side) ? "#ffffff" : "#1D1E21"} />
<LockIcon
fill={
selectedZone.lockedPanels.includes(side)
? "var(--primary-color)"
: "var(--text-color)"
}
/>
</div>
</div>
)}

View File

@@ -1,6 +1,5 @@
import React, { useEffect, useRef } from "react";
import React, { useEffect, useRef, useState, useCallback } from "react";
import { Widget } from "../../../store/useWidgetStore";
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
// Define the type for `Side`
type Side = "top" | "bottom" | "left" | "right";
@@ -65,133 +64,139 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
const [selectedOption, setSelectedOption] = React.useState<string | null>(
null
);
//
// console.log('setSelectedOption: ', setSelectedOption);
const [options, setOptions] = React.useState<string[]>([]);
//
// console.log('setOptions: ', setOptions);
// Scroll to the selected option when it changes
useEffect(() => {
const container = containerRef.current;
if (container && selectedOption) {
// Handle scrolling to the selected option
const index = options.findIndex((option) => {
const formattedOption = formatOptionName(option);
const selectedFormattedOption =
selectedOption?.split("_")[1] || selectedOption;
return formattedOption === selectedFormattedOption;
});
if (container) {
const isOverflowing = container.scrollWidth > container.clientWidth;
const canScrollLeft = container.scrollLeft > 0;
const canScrollRight =
container.scrollLeft + container.clientWidth < container.scrollWidth;
if (index !== -1) {
const optionElement = container.children[index] as HTMLElement;
if (optionElement) {
optionElement.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "center",
});
}
}
setShowLeftArrow(isOverflowing && canScrollLeft);
setShowRightArrow(isOverflowing && canScrollRight);
}
}, [selectedOption, options]);
}, []);
useEffect(() => {
const container = containerRef.current;
const handleWheel = (event: WheelEvent) => {
event.preventDefault();
if (container) {
container.scrollBy({
left: event.deltaY * 2, // Adjust the multiplier for faster scrolling
behavior: "smooth",
});
}
};
let isDragging = false;
let startX: number;
let scrollLeft: number;
const handleMouseDown = (event: MouseEvent) => {
isDragging = true;
startX = event.pageX - (container?.offsetLeft || 0);
scrollLeft = container?.scrollLeft || 0;
};
const handleMouseMove = (event: MouseEvent) => {
if (!isDragging || !container) return;
event.preventDefault();
const x = event.pageX - (container.offsetLeft || 0);
const walk = (x - startX) * 2; // Adjust the multiplier for faster dragging
container.scrollLeft = scrollLeft - walk;
};
const handleMouseUp = () => {
isDragging = false;
};
const handleMouseLeave = () => {
isDragging = false;
};
if (container) {
// Initial calculation after the DOM has been rendered
const handleInitialRender = () => {
requestAnimationFrame(updateOverflowState);
};
handleInitialRender();
// Update on window resize or scroll
const handleResize = () => updateOverflowState();
const handleScroll = () => updateOverflowState();
// Add mouse wheel listener for horizontal scrolling
const handleWheel = (event: WheelEvent) => {
event.preventDefault(); // Prevent default vertical scrolling
if (container) {
container.scrollBy({
left: event.deltaY * 2, // Translate vertical scroll to horizontal scroll
behavior: "smooth",
});
}
};
container.addEventListener("scroll", handleScroll);
window.addEventListener("resize", handleResize);
container.addEventListener("wheel", handleWheel, { passive: false });
container.addEventListener("mousedown", handleMouseDown);
container.addEventListener("mousemove", handleMouseMove);
container.addEventListener("mouseup", handleMouseUp);
container.addEventListener("mouseleave", handleMouseLeave);
}
return () => {
if (container) {
return () => {
container.removeEventListener("scroll", handleScroll);
window.removeEventListener("resize", handleResize);
container.removeEventListener("wheel", handleWheel);
container.removeEventListener("mousedown", handleMouseDown);
container.removeEventListener("mousemove", handleMouseMove);
container.removeEventListener("mouseup", handleMouseUp);
container.removeEventListener("mouseleave", handleMouseLeave);
}
};
}, []);
};
}
}, [updateOverflowState]);
// Helper function to format option names (customize as needed)
const formatOptionName = (option: string): string => {
// Replace underscores with spaces and capitalize the first letter
return option.replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase());
// Handle scrolling with navigation arrows
const handleScrollLeft = () => {
const container = containerRef.current;
if (container) {
container.scrollBy({
left: -200, // Scroll left by 200px
behavior: "smooth",
});
}
};
const handleScrollRight = () => {
const container = containerRef.current;
if (container) {
container.scrollBy({
left: 200, // Scroll right by 200px
behavior: "smooth",
});
}
};
return (
<div
ref={containerRef}
className={`zoon-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom"
}`}
className={`zone-wrapper ${
selectedZone?.activeSides?.includes("bottom") && "bottom"
}`}
>
{Object.keys(zonesData).map((zoneName, index) => (
<div
key={index}
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
}`}
onClick={() => {
useDroppedObjectsStore.getState().setZone(zoneName, zonesData[zoneName]?.zoneId);
setSelectedZone({
zoneName,
activeSides: zonesData[zoneName].activeSides || [],
panelOrder: zonesData[zoneName].panelOrder || [],
lockedPanels: zonesData[zoneName].lockedPanels || [],
widgets: zonesData[zoneName].widgets || [],
zoneId: zonesData[zoneName]?.zoneId || "",
zoneViewPortTarget: zonesData[zoneName].zoneViewPortTarget || [],
zoneViewPortPosition:
zonesData[zoneName].zoneViewPortPosition || [],
});
// setSelectedZone({
// zoneName,
// ...zonesData[zoneName],
// });
}}
>
{zoneName}
{/* Left Arrow */}
{showLeftArrow && (
<button className="arrow left-arrow" onClick={handleScrollLeft}>
<MoveArrowLeft />
</button>
)}
{/* Zones Wrapper */}
{Object.keys(zonesData).length !== 0 ? (
<div ref={containerRef} className="zones-wrapper">
{Object.keys(zonesData).map((zoneName, index) => (
<div
key={index}
className={`zone ${
selectedZone.zoneName === zoneName ? "active" : ""
}`}
onClick={() => {
console.log("zoneName: ", zoneName);
setSelectedZone({
zoneName,
activeSides: zonesData[zoneName].activeSides || [],
panelOrder: zonesData[zoneName].panelOrder || [],
lockedPanels: zonesData[zoneName].lockedPanels || [],
widgets: zonesData[zoneName].widgets || [],
zoneId: zonesData[zoneName]?.zoneId || "",
zoneViewPortTarget:
zonesData[zoneName].zoneViewPortTarget || [],
zoneViewPortPosition:
zonesData[zoneName].zoneViewPortPosition || [],
});
}}
>
{zoneName}
</div>
))}
</div>
))}
) : (
<div className="no-zone">
<InfoIcon />
No zones? Create one!
</div>
)}
{/* Right Arrow */}
{showRightArrow && (
<button className="arrow right-arrow" onClick={handleScrollRight}>
<MoveArrowRight />
</button>
)}
</div>
);
};

View File

@@ -1,164 +1,317 @@
import { useWidgetStore } from "../../../store/useWidgetStore";
import ProgressCard from "../realTimeVis/charts/ProgressCard";
import PieGraphComponent from "../realTimeVis/charts/PieGraphComponent";
import BarGraphComponent from "../realTimeVis/charts/BarGraphComponent";
import LineGraphComponent from "../realTimeVis/charts/LineGraphComponent";
import RadarGraphComponent from "../realTimeVis/charts/RadarGraphComponent";
import DoughnutGraphComponent from "../realTimeVis/charts/DoughnutGraphComponent";
import PolarAreaGraphComponent from "../realTimeVis/charts/PolarAreaGraphComponent";
export const DraggableWidget = ({
widget,
hiddenPanels, // Add this prop to track hidden panels
index, onReorder
}: {
widget: any;
hiddenPanels: string[]; // Array of hidden panel names
index: number; onReorder: (fromIndex: number, toIndex: number) => void
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const handlePointerDown = () => {
if (selectedChartId?.id !== widget.id) {
setSelectedChartId(widget);
}
};
// Determine if the widget's panel is hidden
const isPanelHidden = hiddenPanels.includes(widget.panel);
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
event.dataTransfer.setData('text/plain', index.toString()); // Store the index of the dragged widget
};
const handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault(); // Allow drop
};
const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault(); // Allow drop
};
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const fromIndex = parseInt(event.dataTransfer.getData('text/plain'), 10); // Get the dragged widget's index
const toIndex = index; // The index of the widget where the drop occurred
if (fromIndex !== toIndex) {
onReorder(fromIndex, toIndex); // Call the reorder function passed as a prop
}
};
return (
<>
<div
draggable
key={widget.id}
className={`chart-container ${selectedChartId?.id === widget.id && "activeChart"
}`}
onPointerDown={handlePointerDown}
onDragStart={handleDragStart}
onDragEnter={handleDragEnter}
onDragOver={handleDragOver}
onDrop={handleDrop}
style={{
opacity: isPanelHidden ? 0 : 1, // Set opacity to 0 if the panel is hidden
pointerEvents: isPanelHidden ? "none" : "auto", // Disable interaction when hidden
}}
>
{/* Render charts based on widget type */}
{widget.type === "progress" && (
<ProgressCard title={widget.title} data={widget.data} />
)}
{widget.type === "line" && (
<LineGraphComponent
type={widget.type}
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" && (
<BarGraphComponent
type={widget.type}
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 === "radar" && (
<RadarGraphComponent
type={widget.type}
title={widget.title}
fontSize={widget.fontSize}
fontWeight={widget.fontWeight}
data={widget.data.measurements.map((item: any) => item.fields)}
/>
)} */}
{widget.type === "pie" && (
<PieGraphComponent
type={widget.type}
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" && (
<DoughnutGraphComponent
type={widget.type}
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 === "polarArea" && (
<PolarAreaGraphComponent
type={widget.type}
title={widget.title}
fontSize={widget.fontSize}
fontWeight={widget.fontWeight}
data={{
measurements: [
{ name: "testDevice", fields: "powerConsumption" },
{ name: "furnace", fields: "powerConsumption" },
],
interval: 1000,
duration: "1h",
}}
/>
)}
</div>
</>
);
};
import { useWidgetStore } from "../../../store/useWidgetStore";
import ProgressCard from "../realTimeVis/charts/ProgressCard";
import PieGraphComponent from "../realTimeVis/charts/PieGraphComponent";
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 {
DeleteIcon,
DublicateIcon,
KebabIcon,
} from "../../icons/ExportCommonIcons";
import { useEffect, useRef, useState } from "react";
type Side = "top" | "bottom" | "left" | "right";
interface Widget {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}
export const DraggableWidget = ({
widget,
hiddenPanels,
index,
onReorder,
openKebabId,
setOpenKebabId,
selectedZone,
setSelectedZone,
}: {
selectedZone: {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
widgets: Widget[];
};
setSelectedZone: React.Dispatch<
React.SetStateAction<{
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}[];
}>
>;
widget: any;
hiddenPanels: string[];
index: number;
onReorder: (fromIndex: number, toIndex: number) => void;
openKebabId: string | null;
setOpenKebabId: (id: string | null) => void;
}) => {
const { selectedChartId, setSelectedChartId } = useWidgetStore();
const [panelDimensions, setPanelDimensions] = useState<{
[side in Side]?: { width: number; height: number };
}>({});
const handlePointerDown = () => {
if (selectedChartId?.id !== widget.id) {
setSelectedChartId(widget);
}
};
const isPanelHidden = hiddenPanels.includes(widget.panel);
const deleteSelectedChart = () => {
const updatedWidgets = selectedZone.widgets.filter(
(w: Widget) => w.id !== widget.id
);
setSelectedZone((prevZone: any) => ({
...prevZone,
widgets: updatedWidgets,
}));
setOpenKebabId(null);
};
const getCurrentWidgetCount = (panel: Side) =>
selectedZone.widgets.filter((w) => w.panel === panel).length;
const calculatePanelCapacity = (panel: Side) => {
const CHART_WIDTH = 150;
const CHART_HEIGHT = 150;
const FALLBACK_HORIZONTAL_CAPACITY = 5;
const FALLBACK_VERTICAL_CAPACITY = 3;
const dimensions = panelDimensions[panel];
if (!dimensions) {
return panel === "top" || panel === "bottom"
? FALLBACK_HORIZONTAL_CAPACITY
: FALLBACK_VERTICAL_CAPACITY;
}
return panel === "top" || panel === "bottom"
? Math.floor(dimensions.width / CHART_WIDTH)
: Math.floor(dimensions.height / CHART_HEIGHT);
};
const isPanelFull = (panel: Side) => {
const currentWidgetCount = getCurrentWidgetCount(panel);
const panelCapacity = calculatePanelCapacity(panel);
return currentWidgetCount >= panelCapacity;
};
const duplicateWidget = () => {
const duplicatedWidget: Widget = {
...widget,
id: `${widget.id}-copy-${Date.now()}`,
};
setSelectedZone((prevZone: any) => ({
...prevZone,
widgets: [...prevZone.widgets, duplicatedWidget],
}));
setOpenKebabId(null);
console.log("Duplicated widget with ID:", duplicatedWidget.id);
};
const handleKebabClick = (event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
if (openKebabId === widget.id) {
setOpenKebabId(null);
} else {
setOpenKebabId(widget.id);
}
};
const widgetRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
widgetRef.current &&
!widgetRef.current.contains(event.target as Node)
) {
setOpenKebabId(null);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [setOpenKebabId]);
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
event.dataTransfer.setData("text/plain", index.toString()); // Store the index of the dragged widget
};
const handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault(); // Allow drop
};
const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault(); // Allow drop
};
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const fromIndex = parseInt(event.dataTransfer.getData("text/plain"), 10); // Get the dragged widget's index
const toIndex = index; // The index of the widget where the drop occurred
if (fromIndex !== toIndex) {
onReorder(fromIndex, toIndex); // Call the reorder function passed as a prop
}
};
return (
<>
<div
draggable
key={widget.id}
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",
}}
>
{/* Kebab Icon */}
<div className="icon kebab" onClick={handleKebabClick}>
<KebabIcon />
</div>
{/* Kebab Options */}
{openKebabId === widget.id && (
<div className="kebab-options" ref={widgetRef}>
<div
className={`edit btn ${
isPanelFull(widget.panel) ? "btn-blur" : ""
}`}
onClick={isPanelFull(widget.panel) ? undefined : duplicateWidget}
>
<div className="icon">
<DublicateIcon />
</div>
<div className="label">Duplicate</div>
</div>
<div className="edit btn" onClick={deleteSelectedChart}>
<div className="icon">
<DeleteIcon />
</div>
<div className="label">Delete</div>
</div>
</div>
)}
{/* Render charts based on widget type */}
{widget.type === "progress" && (
<ProgressCard title={widget.title} data={widget.data} />
)}
{widget.type === "line" && (
<LineGraphComponent
type={widget.type}
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" && (
<BarGraphComponent
type={widget.type}
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" && (
<PieGraphComponent
type={widget.type}
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" && (
<DoughnutGraphComponent
type={widget.type}
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 === "polarArea" && (
<PolarAreaGraphComponent
type={widget.type}
title={widget.title}
fontSize={widget.fontSize}
fontWeight={widget.fontWeight}
data={{
measurements: [
{ name: "testDevice", fields: "powerConsumption" },
{ name: "furnace", fields: "powerConsumption" },
],
interval: 1000,
duration: "1h",
}}
/>
)}
</div>
</>
);
};

View File

@@ -38,6 +38,7 @@ interface PanelProps {
}>
>;
hiddenPanels: string[];
setZonesData: React.Dispatch<React.SetStateAction<any>>; // Add this line
}
const generateUniqueId = () =>
@@ -47,11 +48,13 @@ const Panel: React.FC<PanelProps> = ({
selectedZone,
setSelectedZone,
hiddenPanels,
setZonesData,
}) => {
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();
@@ -69,8 +72,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",
@@ -80,8 +84,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",
@@ -104,8 +109,8 @@ const Panel: React.FC<PanelProps> = ({
if (currentWidgetsCount >= maxCapacity) return;
console.log('draggedAsset: ', draggedAsset);
console.log('panel: ', panel);
console.log("draggedAsset: ", draggedAsset);
console.log("panel: ", panel);
addWidgetToPanel(draggedAsset, panel);
};
@@ -133,6 +138,7 @@ const Panel: React.FC<PanelProps> = ({
: Math.floor(dimensions.height / CHART_HEIGHT);
};
// while dublicate check this and add
const addWidgetToPanel = (asset: any, panel: Side) => {
const newWidget = {
...asset,
@@ -174,7 +180,7 @@ const Panel: React.FC<PanelProps> = ({
const handleReorder = (fromIndex: number, toIndex: number, panel: Side) => {
if (!selectedZone) return; // Ensure selectedZone is not null
console.log('selectedZone: ', selectedZone);
console.log("selectedZone: ", selectedZone);
setSelectedZone((prev) => {
if (!prev) return prev; // Ensure prev is not null
@@ -197,9 +203,6 @@ const Panel: React.FC<PanelProps> = ({
});
};
return (
<>
{selectedZone.activeSides.map((side) => (
@@ -237,6 +240,10 @@ const Panel: React.FC<PanelProps> = ({
onReorder={(fromIndex, toIndex) =>
handleReorder(fromIndex, toIndex, side)
}
openKebabId={openKebabId}
setOpenKebabId={setOpenKebabId}
selectedZone={selectedZone}
setSelectedZone={setSelectedZone}
/>
))}
</div>
@@ -247,5 +254,3 @@ const Panel: React.FC<PanelProps> = ({
};
export default Panel;

View File

@@ -12,7 +12,6 @@ import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
import { useZones } from "../../../store/store";
type Side = "top" | "bottom" | "left" | "right";
type FormattedZoneData = Record<
@@ -130,7 +129,8 @@ const RealTimeVisulization: React.FC = () => {
style={{
height: "100%",
width: "100%",
borderRadius: isPlaying || activeModule !== "visualization" ? "" : "6px",
borderRadius:
isPlaying || activeModule !== "visualization" ? "" : "6px",
}}
onDrop={(event) => handleDrop(event)}
onDragOver={(event) => event.preventDefault()}
@@ -157,10 +157,10 @@ const RealTimeVisulization: React.FC = () => {
)}
<Panel
hiddenPanels={hiddenPanels}
selectedZone={selectedZone}
setSelectedZone={setSelectedZone}
hiddenPanels={hiddenPanels}
setZonesData={setZonesData}
/>
</>
)}