added sockets and dynamic saving function
This commit is contained in:
138
app/package-lock.json
generated
138
app/package-lock.json
generated
@@ -14,6 +14,7 @@
|
|||||||
"react-chartjs-2": "^5.3.0",
|
"react-chartjs-2": "^5.3.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-router-dom": "^7.3.0",
|
"react-router-dom": "^7.3.0",
|
||||||
|
"socket.io-client": "^4.8.1",
|
||||||
"zustand": "^5.0.3"
|
"zustand": "^5.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1655,6 +1656,12 @@
|
|||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@socket.io/component-emitter": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/axios": {
|
"node_modules/@types/axios": {
|
||||||
"version": "0.14.4",
|
"version": "0.14.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.4.tgz",
|
||||||
@@ -2795,6 +2802,45 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/engine.io-client": {
|
||||||
|
"version": "6.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz",
|
||||||
|
"integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~5.2.1",
|
||||||
|
"ws": "~8.17.1",
|
||||||
|
"xmlhttprequest-ssl": "~2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-client/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-parser": {
|
||||||
|
"version": "5.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||||
|
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/es-define-property": {
|
"node_modules/es-define-property": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
@@ -3708,7 +3754,6 @@
|
|||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
@@ -4607,6 +4652,68 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/socket.io-client": {
|
||||||
|
"version": "4.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
|
||||||
|
"integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.2",
|
||||||
|
"engine.io-client": "~6.6.1",
|
||||||
|
"socket.io-parser": "~4.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-client/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
@@ -4996,6 +5103,35 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xmlhttprequest-ssl": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"react-chartjs-2": "^5.3.0",
|
"react-chartjs-2": "^5.3.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-router-dom": "^7.3.0",
|
"react-router-dom": "^7.3.0",
|
||||||
|
"socket.io-client": "^4.8.1",
|
||||||
"zustand": "^5.0.3"
|
"zustand": "^5.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,3 +1,199 @@
|
|||||||
|
// import React from "react";
|
||||||
|
// import {
|
||||||
|
// CleanPannel,
|
||||||
|
// EyeIcon,
|
||||||
|
// LockIcon,
|
||||||
|
// } from "../../icons/RealTimeVisulationIcons";
|
||||||
|
|
||||||
|
// // Define the type for `Side`
|
||||||
|
// type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
// // Define the type for the props passed to the Buttons component
|
||||||
|
// interface ButtonsProps {
|
||||||
|
// selectedZone: {
|
||||||
|
// zoneName: string;
|
||||||
|
// activeSides: Side[];
|
||||||
|
// panelOrder: Side[];
|
||||||
|
// lockedPanels: Side[];
|
||||||
|
// widgets: {
|
||||||
|
// id: string;
|
||||||
|
// type: string;
|
||||||
|
// title: string;
|
||||||
|
// panel: Side;
|
||||||
|
// data: any;
|
||||||
|
// }[];
|
||||||
|
// };
|
||||||
|
// setSelectedZone: React.Dispatch<
|
||||||
|
// React.SetStateAction<{
|
||||||
|
// zoneName: string;
|
||||||
|
// activeSides: Side[];
|
||||||
|
// panelOrder: Side[];
|
||||||
|
// lockedPanels: Side[];
|
||||||
|
// widgets: {
|
||||||
|
// id: string;
|
||||||
|
// type: string;
|
||||||
|
// title: string;
|
||||||
|
// panel: Side;
|
||||||
|
// data: any;
|
||||||
|
// }[];
|
||||||
|
// }>
|
||||||
|
// >;
|
||||||
|
// hiddenPanels: Side[]; // Add this prop for hidden panels
|
||||||
|
// setHiddenPanels: React.Dispatch<React.SetStateAction<Side[]>>; // Add this prop for updating hidden panels
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const AddButtons: React.FC<ButtonsProps> = ({
|
||||||
|
// selectedZone,
|
||||||
|
// setSelectedZone,
|
||||||
|
// setHiddenPanels,
|
||||||
|
// hiddenPanels,
|
||||||
|
// }) => {
|
||||||
|
// // Local state to track hidden panels
|
||||||
|
|
||||||
|
// // Function to toggle lock/unlock a panel
|
||||||
|
// const toggleLockPanel = (side: Side) => {
|
||||||
|
// const newLockedPanels = selectedZone.lockedPanels.includes(side)
|
||||||
|
// ? selectedZone.lockedPanels.filter((panel) => panel !== side)
|
||||||
|
// : [...selectedZone.lockedPanels, side];
|
||||||
|
|
||||||
|
// const updatedZone = {
|
||||||
|
// ...selectedZone,
|
||||||
|
// lockedPanels: newLockedPanels,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Update the selectedZone state
|
||||||
|
// setSelectedZone(updatedZone);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Function to toggle visibility of a panel
|
||||||
|
// const toggleVisibility = (side: Side) => {
|
||||||
|
// const isHidden = hiddenPanels.includes(side);
|
||||||
|
// if (isHidden) {
|
||||||
|
// // If the panel is already hidden, remove it from the hiddenPanels array
|
||||||
|
// setHiddenPanels(hiddenPanels.filter((panel) => panel !== side));
|
||||||
|
// } else {
|
||||||
|
// // If the panel is visible, add it to the hiddenPanels array
|
||||||
|
// setHiddenPanels([...hiddenPanels, side]);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Function to clean all widgets from a panel
|
||||||
|
// const cleanPanel = (side: Side) => {
|
||||||
|
// 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
|
||||||
|
// const handlePlusButtonClick = (side: Side) => {
|
||||||
|
// if (selectedZone.activeSides.includes(side)) {
|
||||||
|
// // If the panel is already active, remove all widgets and close the panel
|
||||||
|
// const cleanedWidgets = selectedZone.widgets.filter(
|
||||||
|
// (widget) => widget.panel !== side
|
||||||
|
// );
|
||||||
|
// const newActiveSides = selectedZone.activeSides.filter((s) => s !== side);
|
||||||
|
|
||||||
|
// const updatedZone = {
|
||||||
|
// ...selectedZone,
|
||||||
|
// widgets: cleanedWidgets,
|
||||||
|
// activeSides: newActiveSides,
|
||||||
|
// panelOrder: newActiveSides,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Update the selectedZone state
|
||||||
|
// setSelectedZone(updatedZone);
|
||||||
|
// } else {
|
||||||
|
// // If the panel is not active, activate it
|
||||||
|
// const newActiveSides = [...selectedZone.activeSides, side];
|
||||||
|
|
||||||
|
// const updatedZone = {
|
||||||
|
// ...selectedZone,
|
||||||
|
// activeSides: newActiveSides,
|
||||||
|
// panelOrder: newActiveSides,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Update the selectedZone state
|
||||||
|
// setSelectedZone(updatedZone);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <div>
|
||||||
|
// {(["top", "right", "bottom", "left"] as Side[]).map((side) => (
|
||||||
|
// <div key={side} className={`side-button-container ${side}`}>
|
||||||
|
// {/* "+" Button */}
|
||||||
|
// <button
|
||||||
|
// className={`side-button ${side}`}
|
||||||
|
// onClick={() => handlePlusButtonClick(side)}
|
||||||
|
// title={
|
||||||
|
// selectedZone.activeSides.includes(side)
|
||||||
|
// ? `Remove all items and close ${side} panel`
|
||||||
|
// : `Activate ${side} panel`
|
||||||
|
// }
|
||||||
|
// >
|
||||||
|
// +
|
||||||
|
// </button>
|
||||||
|
|
||||||
|
// {/* Extra Buttons */}
|
||||||
|
// {selectedZone.activeSides.includes(side) && (
|
||||||
|
// <div className="extra-Bs">
|
||||||
|
// {/* Hide Panel */}
|
||||||
|
// <div
|
||||||
|
// className={`icon ${
|
||||||
|
// hiddenPanels.includes(side) ? "active" : ""
|
||||||
|
// }`}
|
||||||
|
// title={
|
||||||
|
// hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
|
||||||
|
// }
|
||||||
|
// onClick={() => toggleVisibility(side)}
|
||||||
|
// >
|
||||||
|
// <EyeIcon />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// {/* Clean Panel */}
|
||||||
|
// <div
|
||||||
|
// className="icon"
|
||||||
|
// title="Clean Panel"
|
||||||
|
// onClick={() => cleanPanel(side)}
|
||||||
|
// >
|
||||||
|
// <CleanPannel />
|
||||||
|
// </div>
|
||||||
|
|
||||||
|
// {/* Lock/Unlock Panel */}
|
||||||
|
// <div
|
||||||
|
// className={`icon ${
|
||||||
|
// selectedZone.lockedPanels.includes(side) ? "active" : ""
|
||||||
|
// }`}
|
||||||
|
// title={
|
||||||
|
// selectedZone.lockedPanels.includes(side)
|
||||||
|
// ? "Unlock Panel"
|
||||||
|
// : "Lock Panel"
|
||||||
|
// }
|
||||||
|
// onClick={() => toggleLockPanel(side)}
|
||||||
|
// >
|
||||||
|
// <LockIcon />
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// )}
|
||||||
|
// </div>
|
||||||
|
// ))}
|
||||||
|
// </div>
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default AddButtons;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
CleanPannel,
|
CleanPannel,
|
||||||
|
|||||||
@@ -1,188 +1,3 @@
|
|||||||
import React, { useEffect, useRef } from "react";
|
|
||||||
import { Widget } from "../../../store/useWidgetStore";
|
|
||||||
|
|
||||||
// Define the type for `Side`
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
|
||||||
|
|
||||||
interface DisplayZoneProps {
|
|
||||||
zonesData: {
|
|
||||||
[key: string]: {
|
|
||||||
zoneId: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
widgets: Widget[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
selectedZone: {
|
|
||||||
zoneId: string;
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
widgets: {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}[];
|
|
||||||
};
|
|
||||||
setSelectedZone: React.Dispatch<
|
|
||||||
React.SetStateAction<{
|
|
||||||
zoneId: string;
|
|
||||||
zoneName: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
widgets: {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}[];
|
|
||||||
}>
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
|
||||||
zonesData,
|
|
||||||
selectedZone,
|
|
||||||
setSelectedZone,
|
|
||||||
}) => {
|
|
||||||
// Ref for the container element
|
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
||||||
|
|
||||||
// Example state for selectedOption and options (adjust based on your actual use case)
|
|
||||||
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 (index !== -1) {
|
|
||||||
const optionElement = container.children[index] as HTMLElement;
|
|
||||||
if (optionElement) {
|
|
||||||
optionElement.scrollIntoView({
|
|
||||||
behavior: "smooth",
|
|
||||||
block: "nearest",
|
|
||||||
inline: "center",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [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) {
|
|
||||||
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) {
|
|
||||||
container.removeEventListener("wheel", handleWheel);
|
|
||||||
container.removeEventListener("mousedown", handleMouseDown);
|
|
||||||
container.removeEventListener("mousemove", handleMouseMove);
|
|
||||||
container.removeEventListener("mouseup", handleMouseUp);
|
|
||||||
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
ref={containerRef}
|
|
||||||
className={`zoon-wrapper ${
|
|
||||||
selectedZone.activeSides.includes("bottom") && "bottom"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{Object.keys(zonesData).map((zoneName, index) => (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className={`zone ${
|
|
||||||
selectedZone.zoneName === zoneName ? "active" : ""
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedZone({
|
|
||||||
zoneName,
|
|
||||||
...zonesData[zoneName],
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{zoneName}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DisplayZone;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// import React, { useEffect, useRef } from "react";
|
// import React, { useEffect, useRef } from "react";
|
||||||
// import { Widget } from "../../../store/useWidgetStore";
|
// import { Widget } from "../../../store/useWidgetStore";
|
||||||
|
|
||||||
@@ -191,11 +6,13 @@ export default DisplayZone;
|
|||||||
|
|
||||||
// interface DisplayZoneProps {
|
// interface DisplayZoneProps {
|
||||||
// zonesData: {
|
// zonesData: {
|
||||||
// _id: string;
|
// [key: string]: {
|
||||||
// zoneName: string;
|
// activeSides: Side[];
|
||||||
// zoneUUID: string;
|
// panelOrder: Side[];
|
||||||
// sceneID: string;
|
// lockedPanels: Side[];
|
||||||
// }[];
|
// widgets: Widget[];
|
||||||
|
// };
|
||||||
|
// };
|
||||||
// selectedZone: {
|
// selectedZone: {
|
||||||
// zoneName: string;
|
// zoneName: string;
|
||||||
// activeSides: Side[];
|
// activeSides: Side[];
|
||||||
@@ -339,24 +156,237 @@ export default DisplayZone;
|
|||||||
// selectedZone.activeSides.includes("bottom") && "bottom"
|
// selectedZone.activeSides.includes("bottom") && "bottom"
|
||||||
// }`}
|
// }`}
|
||||||
// >
|
// >
|
||||||
// {zonesData && zonesData.length > 0 && zonesData?.map((zone, index) => (
|
// {Object.keys(zonesData).map((zoneName, index) => (
|
||||||
// <div
|
// <div
|
||||||
// key={index}
|
// key={index}
|
||||||
// className={`zone ${
|
// className={`zone ${
|
||||||
// selectedZone.zoneName === zone._id ? "active" : ""
|
// selectedZone.zoneName === zoneName ? "active" : ""
|
||||||
// }`}
|
// }`}
|
||||||
// // onClick={() => {
|
// onClick={() => {
|
||||||
// // setSelectedZone({
|
// setSelectedZone({
|
||||||
// // zoneName,
|
// zoneName,
|
||||||
// // ...zonesData[zoneName],
|
// ...zonesData[zoneName],
|
||||||
// // });
|
// });
|
||||||
// // }}
|
// }}
|
||||||
// >
|
// >
|
||||||
// {zone.zoneName}
|
// {zoneName}
|
||||||
// </div>
|
// </div>
|
||||||
// ))}
|
// ))}
|
||||||
// </div>
|
// </div>
|
||||||
// );
|
// );
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// export default DisplayZone;
|
// export default DisplayZone;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import React, { useEffect, useRef } from "react";
|
||||||
|
import { Widget } from "../../../store/useWidgetStore";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
// Define the type for `Side`
|
||||||
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
interface DisplayZoneProps {
|
||||||
|
zonesData: {
|
||||||
|
_id: string;
|
||||||
|
zoneName: string;
|
||||||
|
zoneUUID: string;
|
||||||
|
sceneID: string;
|
||||||
|
}[];
|
||||||
|
selectedZone: {
|
||||||
|
zoneId: string;
|
||||||
|
zoneName: string;
|
||||||
|
activeSides: Side[];
|
||||||
|
panelOrder: Side[];
|
||||||
|
lockedPanels: Side[];
|
||||||
|
widgets: {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
panel: Side;
|
||||||
|
data: any;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
setSelectedZone: React.Dispatch<
|
||||||
|
React.SetStateAction<{
|
||||||
|
zoneId: string;
|
||||||
|
zoneName: string;
|
||||||
|
activeSides: Side[];
|
||||||
|
panelOrder: Side[];
|
||||||
|
lockedPanels: Side[];
|
||||||
|
widgets: {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
panel: Side;
|
||||||
|
data: any
|
||||||
|
}[];
|
||||||
|
}>
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||||
|
zonesData,
|
||||||
|
selectedZone,
|
||||||
|
setSelectedZone,
|
||||||
|
}) => {
|
||||||
|
// Ref for the container element
|
||||||
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
// Example state for selectedOption and options (adjust based on your actual use case)
|
||||||
|
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 (index !== -1) {
|
||||||
|
const optionElement = container.children[index] as HTMLElement;
|
||||||
|
if (optionElement) {
|
||||||
|
optionElement.scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "nearest",
|
||||||
|
inline: "center",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [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) {
|
||||||
|
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) {
|
||||||
|
container.removeEventListener("wheel", handleWheel);
|
||||||
|
container.removeEventListener("mousedown", handleMouseDown);
|
||||||
|
container.removeEventListener("mousemove", handleMouseMove);
|
||||||
|
container.removeEventListener("mouseup", handleMouseUp);
|
||||||
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchSelectedZone = async (selectedZoneId: string) => {
|
||||||
|
try {
|
||||||
|
// Send POST request to the server
|
||||||
|
const response = await axios.get('http://192.168.0.192:4000/fetchzonedetails',
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
zoneId: selectedZoneId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check the response and show a success message if needed
|
||||||
|
if (response.status === 200) {
|
||||||
|
console.log('broker details responce:', response.data);
|
||||||
|
setSelectedZone(response.data)
|
||||||
|
} else {
|
||||||
|
console.log('Unexpected response:', response);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('There was an error!', error);
|
||||||
|
// setZonesData([])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(zonesData);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className={`zoon-wrapper ${selectedZone.activeSides.includes("bottom") && "bottom"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{zonesData && zonesData.length > 0 && zonesData?.map((zone, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`zone ${selectedZone.zoneId === zone._id ? "active" : ""
|
||||||
|
}`}
|
||||||
|
// onClick={() => {
|
||||||
|
// setSelectedZone({
|
||||||
|
// zoneName,
|
||||||
|
// ...zonesData[zoneName],
|
||||||
|
// });
|
||||||
|
// }}
|
||||||
|
|
||||||
|
onClick={() => {
|
||||||
|
fetchSelectedZone(zone._id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{zone.zoneName}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DisplayZone;
|
||||||
@@ -1,3 +1,209 @@
|
|||||||
|
// import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
// import { useWidgetStore } from "../../../store/useWidgetStore";
|
||||||
|
// import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
|
// import { DraggableWidget } from "./DraggableWidget";
|
||||||
|
|
||||||
|
// type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
// interface Widget {
|
||||||
|
// id: string;
|
||||||
|
// type: string;
|
||||||
|
// title: string;
|
||||||
|
// panel: Side;
|
||||||
|
// data: any;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface PanelProps {
|
||||||
|
// selectedZone: {
|
||||||
|
// zoneName: string;
|
||||||
|
// activeSides: Side[];
|
||||||
|
// panelOrder: Side[];
|
||||||
|
// lockedPanels: Side[];
|
||||||
|
// widgets: Widget[];
|
||||||
|
// };
|
||||||
|
// setSelectedZone: React.Dispatch<
|
||||||
|
// React.SetStateAction<{
|
||||||
|
// zoneName: string;
|
||||||
|
// activeSides: Side[];
|
||||||
|
// panelOrder: Side[];
|
||||||
|
// lockedPanels: Side[];
|
||||||
|
// widgets: Widget[];
|
||||||
|
// }>
|
||||||
|
// >;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const generateUniqueId = () =>
|
||||||
|
// `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
|
||||||
|
// const Panel: React.FC<PanelProps> = ({ selectedZone, setSelectedZone }) => {
|
||||||
|
// const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({});
|
||||||
|
// const [panelDimensions, setPanelDimensions] = useState<{
|
||||||
|
// [side in Side]?: { width: number; height: number };
|
||||||
|
// }>({});
|
||||||
|
|
||||||
|
// const getPanelStyle = useMemo(
|
||||||
|
// () => (side: Side) => {
|
||||||
|
// const currentIndex = selectedZone.panelOrder.indexOf(side);
|
||||||
|
// const previousPanels = selectedZone.panelOrder.slice(0, currentIndex);
|
||||||
|
// const leftActive = previousPanels.includes("left");
|
||||||
|
// const rightActive = previousPanels.includes("right");
|
||||||
|
// const topActive = previousPanels.includes("top");
|
||||||
|
// const bottomActive = previousPanels.includes("bottom");
|
||||||
|
|
||||||
|
// switch (side) {
|
||||||
|
// case "top":
|
||||||
|
// case "bottom":
|
||||||
|
// return {
|
||||||
|
// width: `calc(100% - ${
|
||||||
|
// (leftActive ? 204 : 0) + (rightActive ? 204 : 0)
|
||||||
|
// }px)`,
|
||||||
|
// left: leftActive ? "204px" : "0",
|
||||||
|
// right: rightActive ? "204px" : "0",
|
||||||
|
// [side]: "0",
|
||||||
|
// height: "200px",
|
||||||
|
// };
|
||||||
|
// case "left":
|
||||||
|
// case "right":
|
||||||
|
// return {
|
||||||
|
// height: `calc(100% - ${
|
||||||
|
// (topActive ? 204 : 0) + (bottomActive ? 204 : 0)
|
||||||
|
// }px)`,
|
||||||
|
// top: topActive ? "204px" : "0",
|
||||||
|
// bottom: bottomActive ? "204px" : "0",
|
||||||
|
// [side]: "0",
|
||||||
|
// width: "200px",
|
||||||
|
// };
|
||||||
|
// default:
|
||||||
|
// return {};
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// [selectedZone.panelOrder]
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const handleDrop = (e: React.DragEvent, panel: Side) => {
|
||||||
|
// e.preventDefault();
|
||||||
|
// const { draggedAsset } = useWidgetStore.getState();
|
||||||
|
|
||||||
|
// if (!draggedAsset) return;
|
||||||
|
// if (isPanelLocked(panel)) return;
|
||||||
|
|
||||||
|
// const currentWidgetsCount = getCurrentWidgetCount(panel);
|
||||||
|
// const maxCapacity = calculatePanelCapacity(panel);
|
||||||
|
|
||||||
|
// if (currentWidgetsCount >= maxCapacity) return;
|
||||||
|
|
||||||
|
// addWidgetToPanel(draggedAsset, panel);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Helper functions
|
||||||
|
// const isPanelLocked = (panel: Side) =>
|
||||||
|
// selectedZone.lockedPanels.includes(panel);
|
||||||
|
|
||||||
|
// const getCurrentWidgetCount = (panel: Side) =>
|
||||||
|
// selectedZone.widgets.filter(w => w.panel === panel).length;
|
||||||
|
|
||||||
|
// const calculatePanelCapacity = (panel: Side) => {
|
||||||
|
// const CHART_WIDTH = 200;
|
||||||
|
// const CHART_HEIGHT = 200;
|
||||||
|
// 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 addWidgetToPanel = (asset: any, panel: Side) => {
|
||||||
|
// const newWidget = {
|
||||||
|
// ...asset,
|
||||||
|
// id: generateUniqueId(),
|
||||||
|
// panel,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// setSelectedZone(prev => ({
|
||||||
|
// ...prev,
|
||||||
|
// widgets: [...prev.widgets, newWidget]
|
||||||
|
// }));
|
||||||
|
// };
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const observers: ResizeObserver[] = [];
|
||||||
|
// const currentPanelRefs = panelRefs.current;
|
||||||
|
|
||||||
|
// selectedZone.activeSides.forEach((side) => {
|
||||||
|
// const element = currentPanelRefs[side];
|
||||||
|
// if (element) {
|
||||||
|
// const observer = new ResizeObserver((entries) => {
|
||||||
|
// for (const entry of entries) {
|
||||||
|
// const { width, height } = entry.contentRect;
|
||||||
|
// setPanelDimensions((prev) => ({
|
||||||
|
// ...prev,
|
||||||
|
// [side]: { width, height },
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// observer.observe(element);
|
||||||
|
// observers.push(observer);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return () => {
|
||||||
|
// observers.forEach((observer) => observer.disconnect());
|
||||||
|
// };
|
||||||
|
// }, [selectedZone.activeSides]);
|
||||||
|
|
||||||
|
// const { isPlaying } = usePlayButtonStore();
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// {selectedZone.activeSides.map((side) => (
|
||||||
|
// <div
|
||||||
|
// key={side}
|
||||||
|
// className={`panel ${side}-panel absolute ${isPlaying && ""}`}
|
||||||
|
// style={getPanelStyle(side)}
|
||||||
|
// onDrop={(e) => handleDrop(e, side)}
|
||||||
|
// onDragOver={(e) => e.preventDefault()}
|
||||||
|
// ref={(el) => {
|
||||||
|
// if (el) {
|
||||||
|
// panelRefs.current[side] = el;
|
||||||
|
// } else {
|
||||||
|
// delete panelRefs.current[side];
|
||||||
|
// }
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <div
|
||||||
|
// className={`panel-content ${isPlaying && "fullScreen"}`}
|
||||||
|
// style={{
|
||||||
|
// pointerEvents: selectedZone.lockedPanels.includes(side)
|
||||||
|
// ? "none"
|
||||||
|
// : "auto",
|
||||||
|
// opacity: selectedZone.lockedPanels.includes(side) ? "0.8" : "1",
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <>{}</>
|
||||||
|
// {selectedZone.widgets
|
||||||
|
// .filter((w) => w.panel === side)
|
||||||
|
// .map((widget) => (
|
||||||
|
// <DraggableWidget widget={widget} key={widget.id} />
|
||||||
|
// ))}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// ))}
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default Panel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { useWidgetStore } from "../../../store/useWidgetStore";
|
import { useWidgetStore } from "../../../store/useWidgetStore";
|
||||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
@@ -203,3 +409,4 @@ const Panel: React.FC<PanelProps> = ({ selectedZone, setSelectedZone }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default Panel;
|
export default Panel;
|
||||||
|
|
||||||
|
|||||||
@@ -1,123 +1,9 @@
|
|||||||
import React, { useEffect, useState, useRef } from "react";
|
|
||||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
|
||||||
import Panel from "./Panel";
|
|
||||||
import AddButtons from "./AddButtons";
|
|
||||||
import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
|
||||||
import DisplayZone from "./DisplayZone";
|
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
|
||||||
|
|
||||||
interface Widget {
|
|
||||||
id: string;
|
|
||||||
type: string;
|
|
||||||
title: string;
|
|
||||||
panel: Side;
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RealTimeVisulization: React.FC = () => {
|
|
||||||
const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
|
||||||
const [zonesData, setZonesData] = useState<{
|
|
||||||
[key: string]: {
|
|
||||||
zoneId: string;
|
|
||||||
activeSides: Side[];
|
|
||||||
panelOrder: Side[];
|
|
||||||
lockedPanels: Side[];
|
|
||||||
widgets: Widget[];
|
|
||||||
};
|
|
||||||
}>({
|
|
||||||
"Manufacturing unit": {
|
|
||||||
zoneId: "Manufacturing unit",
|
|
||||||
activeSides: [],
|
|
||||||
panelOrder: [],
|
|
||||||
lockedPanels: [],
|
|
||||||
widgets: [],
|
|
||||||
},
|
|
||||||
"Assembly unit": {
|
|
||||||
zoneId: "Assembly unit",
|
|
||||||
activeSides: [],
|
|
||||||
panelOrder: [],
|
|
||||||
lockedPanels: [],
|
|
||||||
widgets: [],
|
|
||||||
},
|
|
||||||
"Packing unit": {
|
|
||||||
zoneId: "Packing unit",
|
|
||||||
activeSides: [],
|
|
||||||
panelOrder: [],
|
|
||||||
lockedPanels: [],
|
|
||||||
widgets: [],
|
|
||||||
},
|
|
||||||
Warehouse: {
|
|
||||||
zoneId: "Warehouse",
|
|
||||||
activeSides: [],
|
|
||||||
panelOrder: [],
|
|
||||||
lockedPanels: [],
|
|
||||||
widgets: [],
|
|
||||||
},
|
|
||||||
Inventory: {
|
|
||||||
zoneId: "Inventory",
|
|
||||||
activeSides: [],
|
|
||||||
panelOrder: [],
|
|
||||||
lockedPanels: [],
|
|
||||||
widgets: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { isPlaying } = usePlayButtonStore();
|
|
||||||
|
|
||||||
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
|
||||||
useEffect(() => {
|
|
||||||
setZonesData((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[selectedZone.zoneName]: selectedZone,
|
|
||||||
}));
|
|
||||||
}, [selectedZone]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
ref={containerRef}
|
|
||||||
id="real-time-vis-canvas"
|
|
||||||
className="realTime-viz canvas"
|
|
||||||
style={{
|
|
||||||
height: isPlaying ? "100vh" : "",
|
|
||||||
width: isPlaying ? "100%" : "",
|
|
||||||
left: isPlaying ? "0%" : "",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DisplayZone
|
|
||||||
zonesData={zonesData}
|
|
||||||
selectedZone={selectedZone}
|
|
||||||
setSelectedZone={setSelectedZone}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!isPlaying && (
|
|
||||||
<AddButtons
|
|
||||||
hiddenPanels={hiddenPanels}
|
|
||||||
setHiddenPanels={setHiddenPanels}
|
|
||||||
selectedZone={selectedZone}
|
|
||||||
setSelectedZone={setSelectedZone}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Panel selectedZone={selectedZone} setSelectedZone={setSelectedZone} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RealTimeVisulization;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// import React, { useEffect, useState, useRef } from "react";
|
// import React, { useEffect, useState, useRef } from "react";
|
||||||
// import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
// import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
// import Panel from "./Panel";
|
// import Panel from "./Panel";
|
||||||
// import AddButtons from "./AddButtons";
|
// import AddButtons from "./AddButtons";
|
||||||
// import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
// import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
||||||
// import DisplayZone from "./DisplayZone";
|
// import DisplayZone from "./DisplayZone";
|
||||||
// import axios from "axios";
|
|
||||||
|
|
||||||
// type Side = "top" | "bottom" | "left" | "right";
|
// type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
@@ -132,80 +18,45 @@ export default RealTimeVisulization;
|
|||||||
// const RealTimeVisulization: React.FC = () => {
|
// const RealTimeVisulization: React.FC = () => {
|
||||||
// const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
|
// const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
|
||||||
// const containerRef = useRef<HTMLDivElement>(null);
|
// const containerRef = useRef<HTMLDivElement>(null);
|
||||||
// // const [zonesData, setZonesData] = useState<{
|
|
||||||
// // [key: string]: {
|
|
||||||
// // activeSides: Side[];
|
|
||||||
// // panelOrder: Side[];
|
|
||||||
// // lockedPanels: Side[];
|
|
||||||
// // widgets: Widget[];
|
|
||||||
// // };
|
|
||||||
// // }>({
|
|
||||||
// // "Manufacturing unit": {
|
|
||||||
// // activeSides: [],
|
|
||||||
// // panelOrder: [],
|
|
||||||
// // lockedPanels: [],
|
|
||||||
// // widgets: [],
|
|
||||||
// // },
|
|
||||||
// // "Assembly unit": {
|
|
||||||
// // activeSides: [],
|
|
||||||
// // panelOrder: [],
|
|
||||||
// // lockedPanels: [],
|
|
||||||
// // widgets: [],
|
|
||||||
// // },
|
|
||||||
// // "Packing unit": {
|
|
||||||
// // activeSides: [],
|
|
||||||
// // panelOrder: [],
|
|
||||||
// // lockedPanels: [],
|
|
||||||
// // widgets: [],
|
|
||||||
// // },
|
|
||||||
// // Warehouse: {
|
|
||||||
// // activeSides: [],
|
|
||||||
// // panelOrder: [],
|
|
||||||
// // lockedPanels: [],
|
|
||||||
// // widgets: [],
|
|
||||||
// // },
|
|
||||||
// // Inventory: {
|
|
||||||
// // activeSides: [],
|
|
||||||
// // panelOrder: [],
|
|
||||||
// // lockedPanels: [],
|
|
||||||
// // widgets: [],
|
|
||||||
// // },
|
|
||||||
// // });
|
|
||||||
|
|
||||||
// const [zonesData, setZonesData] = useState<{
|
// const [zonesData, setZonesData] = useState<{
|
||||||
// _id: string;
|
// [key: string]: {
|
||||||
// zoneName: string;
|
// activeSides: Side[];
|
||||||
// zoneUUID: string;
|
// panelOrder: Side[];
|
||||||
// sceneID: string;
|
// lockedPanels: Side[];
|
||||||
// }[]>([]);
|
// widgets: Widget[];
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// const fetchZoneData = async () => {
|
|
||||||
// try {
|
|
||||||
// // Send POST request to the server
|
|
||||||
// const response = await axios.get('http://192.168.0.102:2000/zone_sets/6656cbf555be4ff11327fd7f?organization=organization',
|
|
||||||
// // {
|
|
||||||
// // params: {
|
|
||||||
// // sceneId:"123456789"
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// // Check the response and show a success message if needed
|
|
||||||
// if (response.status === 200) {
|
|
||||||
// console.log('broker details responce:', response.data);
|
|
||||||
// setZonesData(response.data)
|
|
||||||
// } else {
|
|
||||||
// console.log('Unexpected response:', response);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } catch (error) {
|
|
||||||
// console.error('There was an error!', error);
|
|
||||||
// setZonesData([])
|
|
||||||
// }
|
|
||||||
// };
|
// };
|
||||||
// fetchZoneData();
|
// }>({
|
||||||
// }, []);
|
// "Manufacturing unit": {
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// "Assembly unit": {
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// "Packing unit": {
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// Warehouse: {
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// Inventory: {
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
// const { isPlaying } = usePlayButtonStore();
|
// const { isPlaying } = usePlayButtonStore();
|
||||||
|
|
||||||
@@ -250,3 +101,150 @@ export default RealTimeVisulization;
|
|||||||
|
|
||||||
// export default RealTimeVisulization;
|
// export default RealTimeVisulization;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import React, { useEffect, useState, useRef } from "react";
|
||||||
|
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||||
|
import Panel from "./Panel";
|
||||||
|
import AddButtons from "./AddButtons";
|
||||||
|
import { useSelectedZoneStore } from "../../../store/useZoneStore";
|
||||||
|
import DisplayZone from "./DisplayZone";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
interface Widget {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
title: string;
|
||||||
|
panel: Side;
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RealTimeVisulization: React.FC = () => {
|
||||||
|
const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const [zonesData, setZonesData] = useState<{
|
||||||
|
_id: string;
|
||||||
|
zoneName: string;
|
||||||
|
zoneUUID: string;
|
||||||
|
sceneID: string;
|
||||||
|
}[]>([]);
|
||||||
|
// const [zonesData, setZonesData] = useState<{
|
||||||
|
// [key: string]: {
|
||||||
|
// zoneId: string;
|
||||||
|
// activeSides: Side[];
|
||||||
|
// panelOrder: Side[];
|
||||||
|
// lockedPanels: Side[];
|
||||||
|
// widgets: Widget[];
|
||||||
|
// };
|
||||||
|
// }>({
|
||||||
|
// "Manufacturing unit": {
|
||||||
|
// zoneId: "Manufacturing unit",
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// "Assembly unit": {
|
||||||
|
// zoneId: "Assembly unit",
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// "Packing unit": {
|
||||||
|
// zoneId: "Packing unit",
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// Warehouse: {
|
||||||
|
// zoneId: "Warehouse",
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// Inventory: {
|
||||||
|
// zoneId: "Inventory",
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchZoneData = async () => {
|
||||||
|
try {
|
||||||
|
// Send POST request to the server
|
||||||
|
const response = await axios.get('http://192.168.0.192:4000/fetchzone',
|
||||||
|
// {
|
||||||
|
// params: {
|
||||||
|
// sceneId:"123456789"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check the response and show a success message if needed
|
||||||
|
if (response.status === 200) {
|
||||||
|
console.log('broker details responce:', response.data);
|
||||||
|
setZonesData(response.data)
|
||||||
|
} else {
|
||||||
|
console.log('Unexpected response:', response);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('There was an error!', error);
|
||||||
|
setZonesData([])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchZoneData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const { isPlaying } = usePlayButtonStore();
|
||||||
|
|
||||||
|
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// setZonesData((prev) => ({
|
||||||
|
// ...prev,
|
||||||
|
// [selectedZone.zoneName]: selectedZone,
|
||||||
|
// }));
|
||||||
|
// }, [selectedZone]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
id="real-time-vis-canvas"
|
||||||
|
className="realTime-viz canvas"
|
||||||
|
style={{
|
||||||
|
height: isPlaying ? "100vh" : "",
|
||||||
|
width: isPlaying ? "100%" : "",
|
||||||
|
left: isPlaying ? "0%" : "",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DisplayZone
|
||||||
|
zonesData={zonesData}
|
||||||
|
selectedZone={selectedZone}
|
||||||
|
setSelectedZone={setSelectedZone}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{!isPlaying && (
|
||||||
|
<AddButtons
|
||||||
|
hiddenPanels={hiddenPanels}
|
||||||
|
setHiddenPanels={setHiddenPanels}
|
||||||
|
selectedZone={selectedZone}
|
||||||
|
setSelectedZone={setSelectedZone}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Panel selectedZone={selectedZone} setSelectedZone={setSelectedZone} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RealTimeVisulization;
|
||||||
@@ -41,7 +41,60 @@
|
|||||||
// }));
|
// }));
|
||||||
|
|
||||||
|
|
||||||
|
// import { create } from "zustand";
|
||||||
|
|
||||||
|
// type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
|
// interface Widget {
|
||||||
|
// id: string;
|
||||||
|
// type: string;
|
||||||
|
// title: string;
|
||||||
|
// panel: Side;
|
||||||
|
// data: any;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface SelectedZoneState {
|
||||||
|
// zoneId: string;
|
||||||
|
// zoneName: string;
|
||||||
|
// activeSides: Side[];
|
||||||
|
// panelOrder: Side[];
|
||||||
|
// lockedPanels: Side[];
|
||||||
|
// widgets: Widget[];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface SelectedZoneStore {
|
||||||
|
// selectedZone: SelectedZoneState;
|
||||||
|
// setSelectedZone: (zone: Partial<SelectedZoneState> | ((prev: SelectedZoneState) => SelectedZoneState)) => void;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
||||||
|
// selectedZone: {
|
||||||
|
// zoneId:"",
|
||||||
|
// zoneName: "",
|
||||||
|
// activeSides: [],
|
||||||
|
// panelOrder: [],
|
||||||
|
// lockedPanels: [],
|
||||||
|
// widgets: [],
|
||||||
|
// },
|
||||||
|
// setSelectedZone: (zone) =>
|
||||||
|
// set((state) => {
|
||||||
|
// const newState =
|
||||||
|
// typeof zone === "function"
|
||||||
|
// ? zone(state.selectedZone) // Handle functional updates
|
||||||
|
// : { ...state.selectedZone, ...zone }; // Handle partial updates
|
||||||
|
|
||||||
|
// console.log("Previous state:", state.selectedZone);
|
||||||
|
// console.log("Updated state:", newState);
|
||||||
|
|
||||||
|
// return { selectedZone: newState };
|
||||||
|
// }),
|
||||||
|
// }));
|
||||||
|
|
||||||
|
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
|
import { io } from "socket.io-client";
|
||||||
|
|
||||||
|
const socket = io("http://192.168.0.192:4000");
|
||||||
|
|
||||||
type Side = "top" | "bottom" | "left" | "right";
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
|
||||||
@@ -69,7 +122,7 @@ interface SelectedZoneStore {
|
|||||||
|
|
||||||
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
||||||
selectedZone: {
|
selectedZone: {
|
||||||
zoneId:"",
|
zoneId: "",
|
||||||
zoneName: "",
|
zoneName: "",
|
||||||
activeSides: [],
|
activeSides: [],
|
||||||
panelOrder: [],
|
panelOrder: [],
|
||||||
@@ -80,12 +133,22 @@ export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
|||||||
set((state) => {
|
set((state) => {
|
||||||
const newState =
|
const newState =
|
||||||
typeof zone === "function"
|
typeof zone === "function"
|
||||||
? zone(state.selectedZone) // Handle functional updates
|
? zone(state.selectedZone)
|
||||||
: { ...state.selectedZone, ...zone }; // Handle partial updates
|
: { ...state.selectedZone, ...zone };
|
||||||
|
|
||||||
console.log("Previous state:", state.selectedZone);
|
console.log("Previous state:", state.selectedZone);
|
||||||
console.log("Updated state:", newState);
|
console.log("Updated state:", newState);
|
||||||
|
|
||||||
|
// Send updates to the backend
|
||||||
|
socket.emit("updateZone", newState);
|
||||||
|
|
||||||
return { selectedZone: newState };
|
return { selectedZone: newState };
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Listen for backend updates
|
||||||
|
// socket.on("zoneUpdated", (updatedZone: SelectedZoneState) => {
|
||||||
|
// console.log("Received update from server:", updatedZone);
|
||||||
|
// useSelectedZoneStore.setState({ selectedZone: updatedZone });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user