added sockets and dynamic saving function
This commit is contained in:
parent
3caab7aa36
commit
b85820d410
|
@ -14,6 +14,7 @@
|
|||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router-dom": "^7.3.0",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1655,6 +1656,12 @@
|
|||
"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": {
|
||||
"version": "0.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.4.tgz",
|
||||
|
@ -2795,6 +2802,45 @@
|
|||
"dev": true,
|
||||
"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": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
|
@ -3708,7 +3754,6 @@
|
|||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
|
@ -4607,6 +4652,68 @@
|
|||
"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": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
|
@ -4996,6 +5103,35 @@
|
|||
"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": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router-dom": "^7.3.0",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"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 {
|
||||
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 { Widget } from "../../../store/useWidgetStore";
|
||||
|
||||
|
@ -191,11 +6,13 @@ export default DisplayZone;
|
|||
|
||||
// interface DisplayZoneProps {
|
||||
// zonesData: {
|
||||
// _id: string;
|
||||
// zoneName: string;
|
||||
// zoneUUID: string;
|
||||
// sceneID: string;
|
||||
// }[];
|
||||
// [key: string]: {
|
||||
// activeSides: Side[];
|
||||
// panelOrder: Side[];
|
||||
// lockedPanels: Side[];
|
||||
// widgets: Widget[];
|
||||
// };
|
||||
// };
|
||||
// selectedZone: {
|
||||
// zoneName: string;
|
||||
// activeSides: Side[];
|
||||
|
@ -339,24 +156,237 @@ export default DisplayZone;
|
|||
// selectedZone.activeSides.includes("bottom") && "bottom"
|
||||
// }`}
|
||||
// >
|
||||
// {zonesData && zonesData.length > 0 && zonesData?.map((zone, index) => (
|
||||
// {Object.keys(zonesData).map((zoneName, index) => (
|
||||
// <div
|
||||
// key={index}
|
||||
// className={`zone ${
|
||||
// selectedZone.zoneName === zone._id ? "active" : ""
|
||||
// selectedZone.zoneName === zoneName ? "active" : ""
|
||||
// }`}
|
||||
// // onClick={() => {
|
||||
// // setSelectedZone({
|
||||
// // zoneName,
|
||||
// // ...zonesData[zoneName],
|
||||
// // });
|
||||
// // }}
|
||||
// onClick={() => {
|
||||
// setSelectedZone({
|
||||
// zoneName,
|
||||
// ...zonesData[zoneName],
|
||||
// });
|
||||
// }}
|
||||
// >
|
||||
// {zone.zoneName}
|
||||
// {zoneName}
|
||||
// </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 { useWidgetStore } from "../../../store/useWidgetStore";
|
||||
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
||||
|
@ -203,3 +409,4 @@ const Panel: React.FC<PanelProps> = ({ selectedZone, setSelectedZone }) => {
|
|||
};
|
||||
|
||||
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 { 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";
|
||||
|
||||
|
@ -132,80 +18,45 @@ export default RealTimeVisulization;
|
|||
// const RealTimeVisulization: React.FC = () => {
|
||||
// const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
|
||||
// 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<{
|
||||
// _id: string;
|
||||
// zoneName: string;
|
||||
// zoneUUID: string;
|
||||
// sceneID: string;
|
||||
// }[]>([]);
|
||||
|
||||
// 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([])
|
||||
// }
|
||||
// [key: string]: {
|
||||
// activeSides: Side[];
|
||||
// panelOrder: Side[];
|
||||
// lockedPanels: Side[];
|
||||
// widgets: Widget[];
|
||||
// };
|
||||
// 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();
|
||||
|
||||
|
@ -250,3 +101,150 @@ 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 { io } from "socket.io-client";
|
||||
|
||||
const socket = io("http://192.168.0.192:4000");
|
||||
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
|
||||
|
@ -69,7 +122,7 @@ interface SelectedZoneStore {
|
|||
|
||||
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
||||
selectedZone: {
|
||||
zoneId:"",
|
||||
zoneId: "",
|
||||
zoneName: "",
|
||||
activeSides: [],
|
||||
panelOrder: [],
|
||||
|
@ -80,12 +133,22 @@ export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
|||
set((state) => {
|
||||
const newState =
|
||||
typeof zone === "function"
|
||||
? zone(state.selectedZone) // Handle functional updates
|
||||
: { ...state.selectedZone, ...zone }; // Handle partial updates
|
||||
? zone(state.selectedZone)
|
||||
: { ...state.selectedZone, ...zone };
|
||||
|
||||
console.log("Previous state:", state.selectedZone);
|
||||
console.log("Updated state:", newState);
|
||||
|
||||
// Send updates to the backend
|
||||
socket.emit("updateZone", newState);
|
||||
|
||||
return { selectedZone: newState };
|
||||
}),
|
||||
}));
|
||||
|
||||
// Listen for backend updates
|
||||
// socket.on("zoneUpdated", (updatedZone: SelectedZoneState) => {
|
||||
// console.log("Received update from server:", updatedZone);
|
||||
// useSelectedZoneStore.setState({ selectedZone: updatedZone });
|
||||
// });
|
||||
|
||||
|
|
Loading…
Reference in New Issue