Merge pull request 'ui' (#57) from ui into main
Reviewed-on: http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev/pulls/57
This commit is contained in:
commit
8ed035b969
app/src
components
layout/sidebarLeft/visualization
ui
modules/visualization
styles
|
@ -88,22 +88,22 @@ const Templates = () => {
|
||||||
return (
|
return (
|
||||||
<div className="template-list">
|
<div className="template-list">
|
||||||
{templates.map((template, index) => (
|
{templates.map((template, index) => (
|
||||||
<div key={template.id} className="template-item">
|
<div
|
||||||
|
key={template.id}
|
||||||
|
className="template-item"
|
||||||
|
onClick={() => handleLoadTemplate(template)}
|
||||||
|
>
|
||||||
{template?.snapshot && (
|
{template?.snapshot && (
|
||||||
<div className="template-image-container">
|
<div className="template-image-container">
|
||||||
<img
|
<img
|
||||||
src={template.snapshot}
|
src={template.snapshot}
|
||||||
alt={`${template.name} preview`}
|
alt={`${template.name} preview`}
|
||||||
className="template-image"
|
className="template-image"
|
||||||
onClick={() => handleLoadTemplate(template)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="template-details">
|
<div className="template-details">
|
||||||
<div
|
<div className="template-name">
|
||||||
onClick={() => handleLoadTemplate(template)}
|
|
||||||
className="template-name"
|
|
||||||
>
|
|
||||||
{/* {`Template ${index + 1}`} */}
|
{/* {`Template ${index + 1}`} */}
|
||||||
<RenameInput value={`Template ${index + 1}`} />
|
<RenameInput value={`Template ${index + 1}`} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -104,7 +104,7 @@ const ProgressBarWidget = ({
|
||||||
|
|
||||||
const Widgets2D = () => {
|
const Widgets2D = () => {
|
||||||
return (
|
return (
|
||||||
<div className="widget2D">
|
<div className="widget2D widgets-wrapper">
|
||||||
<div className="chart-container">
|
<div className="chart-container">
|
||||||
{chartTypes.map((type, index) => {
|
{chartTypes.map((type, index) => {
|
||||||
const widgetTitle = `Widget ${index + 1}`;
|
const widgetTitle = `Widget ${index + 1}`;
|
||||||
|
|
|
@ -12,22 +12,21 @@ const Widgets3D = () => {
|
||||||
];
|
];
|
||||||
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
const { widgetSelect, setWidgetSelect } = useAsset3dWidget();
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="widgets-container widget3D">
|
<div className="widgets-container widgets-wrapper widget3D">
|
||||||
{widgets?.map((widget, index) => (
|
{widgets?.map((widget, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="widget-item"
|
className="widget-item"
|
||||||
draggable
|
draggable
|
||||||
onDragStart={(e) => {
|
onDragStart={(e) => {
|
||||||
let name = widget.name
|
let name = widget.name;
|
||||||
let crt = e.target
|
let crt = e.target;
|
||||||
if (crt instanceof HTMLElement) {
|
if (crt instanceof HTMLElement) {
|
||||||
const widget = crt.cloneNode(true) as HTMLElement;
|
const widget = crt.cloneNode(true) as HTMLElement;
|
||||||
e.dataTransfer.setDragImage(widget, 0, 0)
|
e.dataTransfer.setDragImage(widget, 0, 0);
|
||||||
e.dataTransfer.effectAllowed = "move"
|
e.dataTransfer.effectAllowed = "move";
|
||||||
e.dataTransfer.setData("text/plain", "ui-" + name)
|
e.dataTransfer.setData("text/plain", "ui-" + name);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onPointerDown={() => {
|
onPointerDown={() => {
|
||||||
|
@ -42,7 +41,7 @@ const Widgets3D = () => {
|
||||||
className="widget-image"
|
className="widget-image"
|
||||||
src={widget.img}
|
src={widget.img}
|
||||||
alt={widget.name}
|
alt={widget.name}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -122,7 +122,6 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
// // Update the selectedZone state
|
// // Update the selectedZone state
|
||||||
// setSelectedZone(updatedZone);
|
// setSelectedZone(updatedZone);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to clean all widgets from a panel
|
// Function to clean all widgets from a panel
|
||||||
|
@ -170,6 +169,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
// 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)) {
|
if (selectedZone.activeSides.includes(side)) {
|
||||||
|
console.log("open");
|
||||||
// Panel already exists: Remove widgets from that side and update activeSides
|
// 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]; // Fallback value
|
||||||
|
@ -254,7 +254,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
// } else {
|
// } else {
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
} catch (error) { }
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
@ -264,8 +264,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
<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)
|
selectedZone.activeSides.includes(side)
|
||||||
|
@ -314,8 +315,9 @@ const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
|
|
||||||
{/* Lock/Unlock Panel */}
|
{/* Lock/Unlock Panel */}
|
||||||
<div
|
<div
|
||||||
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
|
className={`icon ${
|
||||||
}`}
|
selectedZone.lockedPanels.includes(side) ? "active" : ""
|
||||||
|
}`}
|
||||||
title={
|
title={
|
||||||
selectedZone.lockedPanels.includes(side)
|
selectedZone.lockedPanels.includes(side)
|
||||||
? "Unlock Panel"
|
? "Unlock Panel"
|
||||||
|
|
|
@ -13,6 +13,10 @@ import { get3dWidgetZoneData } from "../../../services/realTimeVisulization/zone
|
||||||
// Define the type for `Side`
|
// Define the type for `Side`
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
interface HiddenPanels {
|
||||||
|
[zoneId: string]: Side[];
|
||||||
|
}
|
||||||
|
|
||||||
interface DisplayZoneProps {
|
interface DisplayZoneProps {
|
||||||
zonesData: {
|
zonesData: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
|
@ -62,12 +66,15 @@ interface DisplayZoneProps {
|
||||||
}[];
|
}[];
|
||||||
}>
|
}>
|
||||||
>;
|
>;
|
||||||
|
hiddenPanels: HiddenPanels; // Updated prop type
|
||||||
|
setHiddenPanels: React.Dispatch<React.SetStateAction<HiddenPanels>>; // Updated prop type
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
zonesData,
|
zonesData,
|
||||||
selectedZone,
|
selectedZone,
|
||||||
setSelectedZone,
|
setSelectedZone,
|
||||||
|
hiddenPanels,
|
||||||
}) => {
|
}) => {
|
||||||
// Ref for the container element
|
// Ref for the container element
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
@ -155,7 +162,7 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
if (selectedZone?.zoneId === zoneId) {
|
if (selectedZone?.zoneId === zoneId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSelectedChartId(null)
|
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];
|
||||||
let response = await getSelect2dZoneData(zoneId, organization);
|
let response = await getSelect2dZoneData(zoneId, organization);
|
||||||
|
@ -191,7 +198,12 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") ? "bottom" : ""}`}
|
className={`zone-wrapper ${
|
||||||
|
selectedZone?.activeSides?.includes("bottom") &&
|
||||||
|
!hiddenPanels[selectedZone.zoneId]?.includes("bottom")
|
||||||
|
? "bottom"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
{/* Left Arrow */}
|
{/* Left Arrow */}
|
||||||
{showLeftArrow && (
|
{showLeftArrow && (
|
||||||
|
@ -211,8 +223,12 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
{Object.keys(zonesData).map((zoneName, index) => (
|
{Object.keys(zonesData).map((zoneName, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""}`}
|
className={`zone ${
|
||||||
onClick={() => handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)}
|
selectedZone.zoneName === zoneName ? "active" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() =>
|
||||||
|
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{zoneName}
|
{zoneName}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -95,6 +95,7 @@ export const DraggableWidget = ({
|
||||||
"floating",
|
"floating",
|
||||||
"sidebar-right-wrapper",
|
"sidebar-right-wrapper",
|
||||||
"card",
|
"card",
|
||||||
|
"dropdown-menu",
|
||||||
],
|
],
|
||||||
setMenuVisible: () => setSelectedChartId(null),
|
setMenuVisible: () => setSelectedChartId(null),
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,6 +49,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
const { visualizationSocket } = useSocketStore();
|
const { visualizationSocket } = useSocketStore();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const zones = useDroppedObjectsStore((state) => state.zones);
|
const zones = useDroppedObjectsStore((state) => state.zones);
|
||||||
|
|
||||||
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
const [openKebabId, setOpenKebabId] = useState<string | null>(null);
|
||||||
const updateObjectPosition = useDroppedObjectsStore(
|
const updateObjectPosition = useDroppedObjectsStore(
|
||||||
(state) => state.updateObjectPosition
|
(state) => state.updateObjectPosition
|
||||||
|
@ -70,6 +71,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
vertical: "top" | "bottom";
|
vertical: "top" | "bottom";
|
||||||
horizontal: "left" | "right";
|
horizontal: "left" | "right";
|
||||||
} | null>(null); // State to track active edges for distance lines
|
} | null>(null); // State to track active edges for distance lines
|
||||||
|
|
||||||
const [currentPosition, setCurrentPosition] = useState<{
|
const [currentPosition, setCurrentPosition] = useState<{
|
||||||
top: number | "auto";
|
top: number | "auto";
|
||||||
left: number | "auto";
|
left: number | "auto";
|
||||||
|
@ -143,7 +145,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
// if (res.message === "FloatingWidget deleted successfully") {
|
// if (res.message === "FloatingWidget deleted successfully") {
|
||||||
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
// deleteObject(zoneName, id, index); // Call the deleteObject method from the store
|
||||||
// }
|
// }
|
||||||
} catch (error) { }
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
const handlePointerDown = (event: React.PointerEvent, index: number) => {
|
||||||
|
@ -519,41 +521,46 @@ const DroppedObjects: React.FC = () => {
|
||||||
{zone.objects.map((obj, index) => {
|
{zone.objects.map((obj, index) => {
|
||||||
const topPosition =
|
const topPosition =
|
||||||
typeof obj.position.top === "number"
|
typeof obj.position.top === "number"
|
||||||
? `calc(${obj.position.top}px + ${isPlaying && selectedZone.activeSides.includes("top")
|
? `calc(${obj.position.top}px + ${
|
||||||
? `${heightMultiplier - 55}px`
|
isPlaying && selectedZone.activeSides.includes("top")
|
||||||
: "0px"
|
? `${heightMultiplier - 55}px`
|
||||||
})`
|
: "0px"
|
||||||
|
})`
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
const leftPosition =
|
const leftPosition =
|
||||||
typeof obj.position.left === "number"
|
typeof obj.position.left === "number"
|
||||||
? `calc(${obj.position.left}px + ${isPlaying && selectedZone.activeSides.includes("left")
|
? `calc(${obj.position.left}px + ${
|
||||||
? `${widthMultiplier - 100}px`
|
isPlaying && selectedZone.activeSides.includes("left")
|
||||||
: "0px"
|
? `${widthMultiplier - 100}px`
|
||||||
})`
|
: "0px"
|
||||||
|
})`
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
const rightPosition =
|
const rightPosition =
|
||||||
typeof obj.position.right === "number"
|
typeof obj.position.right === "number"
|
||||||
? `calc(${obj.position.right}px + ${isPlaying && selectedZone.activeSides.includes("right")
|
? `calc(${obj.position.right}px + ${
|
||||||
? `${widthMultiplier - 100}px`
|
isPlaying && selectedZone.activeSides.includes("right")
|
||||||
: "0px"
|
? `${widthMultiplier - 100}px`
|
||||||
})`
|
: "0px"
|
||||||
|
})`
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
const bottomPosition =
|
const bottomPosition =
|
||||||
typeof obj.position.bottom === "number"
|
typeof obj.position.bottom === "number"
|
||||||
? `calc(${obj.position.bottom}px + ${isPlaying && selectedZone.activeSides.includes("bottom")
|
? `calc(${obj.position.bottom}px + ${
|
||||||
? `${heightMultiplier - 55}px`
|
isPlaying && selectedZone.activeSides.includes("bottom")
|
||||||
: "0px"
|
? `${heightMultiplier - 55}px`
|
||||||
})`
|
: "0px"
|
||||||
|
})`
|
||||||
: "auto";
|
: "auto";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${zoneName}-${index}`}
|
key={`${zoneName}-${index}`}
|
||||||
className={`${obj.className} ${selectedChartId?.id === obj.id && "activeChart"
|
className={`${obj.className} ${
|
||||||
}`}
|
selectedChartId?.id === obj.id && "activeChart"
|
||||||
|
}`}
|
||||||
ref={chartWidget}
|
ref={chartWidget}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
@ -561,6 +568,7 @@ const DroppedObjects: React.FC = () => {
|
||||||
left: leftPosition,
|
left: leftPosition,
|
||||||
right: rightPosition,
|
right: rightPosition,
|
||||||
bottom: bottomPosition,
|
bottom: bottomPosition,
|
||||||
|
pointerEvents: isPlaying ? "none" : "auto",
|
||||||
minHeight: `${obj.className === "warehouseThroughput" && "150px !important"} `
|
minHeight: `${obj.className === "warehouseThroughput" && "150px !important"} `
|
||||||
}}
|
}}
|
||||||
onPointerDown={(event) => {
|
onPointerDown={(event) => {
|
||||||
|
|
|
@ -166,8 +166,8 @@ const Panel: React.FC<PanelProps> = ({
|
||||||
|
|
||||||
// Calculate panel capacity
|
// Calculate panel capacity
|
||||||
const calculatePanelCapacity = (panel: Side) => {
|
const calculatePanelCapacity = (panel: Side) => {
|
||||||
const CHART_WIDTH = panelSize;
|
const CHART_WIDTH = panelSize - 10;
|
||||||
const CHART_HEIGHT = panelSize;
|
const CHART_HEIGHT = panelSize - 10;
|
||||||
|
|
||||||
const dimensions = panelDimensions[panel];
|
const dimensions = panelDimensions[panel];
|
||||||
if (!dimensions) {
|
if (!dimensions) {
|
||||||
|
|
|
@ -298,6 +298,8 @@ const RealTimeVisulization: React.FC = () => {
|
||||||
zonesData={zonesData}
|
zonesData={zonesData}
|
||||||
selectedZone={selectedZone}
|
selectedZone={selectedZone}
|
||||||
setSelectedZone={setSelectedZone}
|
setSelectedZone={setSelectedZone}
|
||||||
|
hiddenPanels={hiddenPanels}
|
||||||
|
setHiddenPanels={setHiddenPanels}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!isPlaying && selectedZone?.zoneName !== "" && (
|
{!isPlaying && selectedZone?.zoneName !== "" && (
|
||||||
|
|
|
@ -1,103 +1,96 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from "react";
|
||||||
import { Line } from 'react-chartjs-2'
|
import { Line } from "react-chartjs-2";
|
||||||
import useChartStore from '../../../../store/useChartStore';
|
import useChartStore from "../../../../store/useChartStore";
|
||||||
import { useWidgetStore } from '../../../../store/useWidgetStore';
|
import { useWidgetStore } from "../../../../store/useWidgetStore";
|
||||||
import axios from 'axios';
|
import axios from "axios";
|
||||||
import io from "socket.io-client";
|
import io from "socket.io-client";
|
||||||
import { WalletIcon } from '../../../icons/3dChartIcons';
|
import { WalletIcon } from "../../../icons/3dChartIcons";
|
||||||
|
|
||||||
|
const TotalCardComponent = ({ object }: any) => {
|
||||||
|
const [progress, setProgress] = useState<any>(0);
|
||||||
|
const [measurements, setmeasurements] = useState<any>({});
|
||||||
|
const [duration, setDuration] = useState("1h");
|
||||||
|
const [name, setName] = useState(object.header ? object.header : "");
|
||||||
|
const email = localStorage.getItem("email") || "";
|
||||||
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
|
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
||||||
|
const { selectedChartId } = useWidgetStore();
|
||||||
|
|
||||||
const TotalCardComponent = ({
|
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||||
object
|
|
||||||
}: any) => {
|
|
||||||
|
|
||||||
const [ progress, setProgress ] = useState<any>(0)
|
useEffect(() => {
|
||||||
const [measurements, setmeasurements] = useState<any>({});
|
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0)
|
||||||
const [duration, setDuration] = useState("1h")
|
return;
|
||||||
const [name, setName] = useState(object.header ? object.header : '')
|
|
||||||
const email = localStorage.getItem("email") || "";
|
|
||||||
const organization = email?.split("@")[1]?.split(".")[0]
|
|
||||||
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
|
||||||
const { selectedChartId } = useWidgetStore();
|
|
||||||
|
|
||||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
const socket = io(`http://${iotApiUrl}`);
|
||||||
|
|
||||||
useEffect(() => {
|
const inputData = {
|
||||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
measurements,
|
||||||
|
duration,
|
||||||
const socket = io(`http://${iotApiUrl}`);
|
interval: 1000,
|
||||||
|
};
|
||||||
const inputData = {
|
|
||||||
measurements,
|
const startStream = () => {
|
||||||
duration,
|
socket.emit("lastInput", inputData);
|
||||||
interval: 1000,
|
};
|
||||||
};
|
|
||||||
|
socket.on("connect", startStream);
|
||||||
|
|
||||||
const startStream = () => {
|
socket.on("lastOutput", (response) => {
|
||||||
socket.emit("lastInput", inputData);
|
const responseData = response.input1;
|
||||||
};
|
|
||||||
|
if (typeof responseData === "number") {
|
||||||
socket.on("connect", startStream);
|
setProgress(responseData);
|
||||||
|
|
||||||
socket.on("lastOutput", (response) => {
|
|
||||||
const responseData = response.input1;
|
|
||||||
|
|
||||||
if (typeof responseData === "number") {
|
|
||||||
setProgress(responseData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
socket.off("lastOutput");
|
|
||||||
socket.emit("stop_stream"); // Stop streaming when component unmounts
|
|
||||||
socket.disconnect();
|
|
||||||
};
|
|
||||||
}, [measurements, duration, iotApiUrl]);
|
|
||||||
|
|
||||||
const fetchSavedInputes = async() => {
|
|
||||||
|
|
||||||
if (object?.id !== "") {
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`);
|
|
||||||
if (response.status === 200) {
|
|
||||||
setmeasurements(response.data.Data.measurements)
|
|
||||||
setDuration(response.data.Data.duration)
|
|
||||||
setName(response.data.header)
|
|
||||||
} else {
|
|
||||||
console.log("Unexpected response:", response);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("There was an error!", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
useEffect(() => {
|
|
||||||
fetchSavedInputes();
|
return () => {
|
||||||
}, []);
|
socket.off("lastOutput");
|
||||||
|
socket.emit("stop_stream"); // Stop streaming when component unmounts
|
||||||
useEffect(() => {
|
socket.disconnect();
|
||||||
if (selectedChartId?.id === object?.id) {
|
};
|
||||||
fetchSavedInputes();
|
}, [measurements, duration, iotApiUrl]);
|
||||||
|
|
||||||
|
const fetchSavedInputes = async () => {
|
||||||
|
if (object?.id !== "") {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/A_floatWidget/${object?.id}/${organization}`
|
||||||
|
);
|
||||||
|
if (response.status === 200) {
|
||||||
|
setmeasurements(response.data.Data.measurements);
|
||||||
|
setDuration(response.data.Data.duration);
|
||||||
|
setName(response.data.header);
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
}
|
} catch (error) {}
|
||||||
,[header, flotingDuration, flotingMeasurements])
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
useEffect(() => {
|
||||||
<>
|
fetchSavedInputes();
|
||||||
<div className="header-wrapper" >
|
}, []);
|
||||||
<div className="header">{name}</div>
|
|
||||||
<div className="data-values">
|
|
||||||
<div className="value">{progress}</div>
|
|
||||||
<div className="per">{object.per}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="icon">
|
|
||||||
<WalletIcon />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TotalCardComponent
|
useEffect(() => {
|
||||||
|
if (selectedChartId?.id === object?.id) {
|
||||||
|
fetchSavedInputes();
|
||||||
|
}
|
||||||
|
}, [header, flotingDuration, flotingMeasurements]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="header-wrapper">
|
||||||
|
<div className="header">{name}</div>
|
||||||
|
<div className="data-values">
|
||||||
|
<div className="value">{progress}</div>
|
||||||
|
<div className="per">{object.per}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="icon">
|
||||||
|
<WalletIcon />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TotalCardComponent;
|
||||||
|
|
|
@ -1,22 +1,33 @@
|
||||||
// import html2canvas from "html2canvas";
|
import html2canvas from "html2canvas";
|
||||||
|
|
||||||
export const captureVisualization = async (): Promise<string | null> => {
|
export const captureVisualization = async (): Promise<string | null> => {
|
||||||
const container = document.getElementById("real-time-vis-canvas");
|
const container = document.getElementById("real-time-vis-canvas");
|
||||||
if (!container) return null;
|
if (!container) {
|
||||||
|
console.error("Container element not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use html2canvas to capture the container
|
// Hide any elements you don't want in the screenshot
|
||||||
// const canvas = await html2canvas(container, {
|
const originalVisibility = container.style.visibility;
|
||||||
// scale: 1, // Adjust scale for higher/lower resolution
|
container.style.visibility = 'visible';
|
||||||
// });
|
|
||||||
|
const canvas = await html2canvas(container, {
|
||||||
|
scale: 2, // Higher scale for better quality
|
||||||
|
logging: false, // Disable console logging
|
||||||
|
useCORS: true, // Handle cross-origin images
|
||||||
|
allowTaint: true, // Allow tainted canvas
|
||||||
|
backgroundColor: '#ffffff', // Set white background
|
||||||
|
removeContainer: true // Clean up temporary containers
|
||||||
|
});
|
||||||
|
|
||||||
// // Convert the canvas to a data URL (PNG format)
|
// Restore original visibility
|
||||||
// const dataUrl = canvas.toDataURL("image/png");
|
container.style.visibility = originalVisibility;
|
||||||
// return dataUrl;
|
|
||||||
|
|
||||||
return null;
|
// Convert to PNG with highest quality
|
||||||
|
return canvas.toDataURL('image/png', 1.0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error capturing visualization:", error);
|
console.error("Error capturing visualization:", error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -1,5 +1,3 @@
|
||||||
import { saveTemplateApi } from "../../services/realTimeVisulization/zoneData/saveTempleteApi";
|
|
||||||
import { useSocketStore } from "../../store/store";
|
|
||||||
import { Template } from "../../store/useTemplateStore";
|
import { Template } from "../../store/useTemplateStore";
|
||||||
import { captureVisualization } from "./captureVisualization";
|
import { captureVisualization } from "./captureVisualization";
|
||||||
|
|
||||||
|
@ -28,7 +26,7 @@ export const handleSaveTemplate = async ({
|
||||||
templates = [],
|
templates = [],
|
||||||
visualizationSocket,
|
visualizationSocket,
|
||||||
}: HandleSaveTemplateProps): Promise<void> => {
|
}: HandleSaveTemplateProps): Promise<void> => {
|
||||||
console.log('floatingWidget: ', floatingWidget);
|
console.log("floatingWidget: ", floatingWidget);
|
||||||
try {
|
try {
|
||||||
// Check if the selected zone has any widgets
|
// Check if the selected zone has any widgets
|
||||||
if (!selectedZone.panelOrder || selectedZone.panelOrder.length === 0) {
|
if (!selectedZone.panelOrder || selectedZone.panelOrder.length === 0) {
|
||||||
|
@ -49,12 +47,12 @@ export const handleSaveTemplate = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture visualization snapshot
|
// Capture visualization snapshot
|
||||||
// const snapshot = await captureVisualization();
|
const snapshot = await captureVisualization();
|
||||||
const snapshot = null;
|
|
||||||
|
if (!snapshot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if (!snapshot) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// Create a new template
|
// Create a new template
|
||||||
const newTemplate: Template = {
|
const newTemplate: Template = {
|
||||||
id: generateUniqueId(),
|
id: generateUniqueId(),
|
||||||
|
|
|
@ -59,6 +59,7 @@ input {
|
||||||
.toggle-header-container {
|
.toggle-header-container {
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
|
margin: 6px 0;
|
||||||
|
|
||||||
.toggle-header-item {
|
.toggle-header-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -567,6 +568,7 @@ input {
|
||||||
.input-value {
|
.input-value {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
&::-webkit-inner-spin-button,
|
&::-webkit-inner-spin-button,
|
||||||
&::-webkit-outer-spin-button {
|
&::-webkit-outer-spin-button {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
@ -669,4 +671,4 @@ input {
|
||||||
.multi-email-invite-input.active {
|
.multi-email-invite-input.active {
|
||||||
border: 1px solid var(--accent-color);
|
border: 1px solid var(--accent-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -66,9 +66,9 @@
|
||||||
.sidebar-left-content-container {
|
.sidebar-left-content-container {
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
// flex: 1;
|
// flex: 1;
|
||||||
height: calc(100% - 36px);
|
// height: calc(100% - 36px);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
// overflow: auto;
|
||||||
|
|
||||||
.template-list {
|
.template-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -131,8 +131,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget-left-sideBar {
|
.widget-left-sideBar {
|
||||||
min-height: 50vh;
|
.widgets-wrapper {
|
||||||
max-height: 60vh;
|
|
||||||
|
min-height: 50vh;
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.widget2D {
|
.widget2D {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
|
@ -365,7 +365,7 @@
|
||||||
|
|
||||||
.panel.hidePanel {
|
.panel.hidePanel {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.1;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue