// Store the latest node data globally
let latestNodeData = [];
let latestNodeStatus = [];
let checkedNodeInfo = [];
let firstNode = null;
let secondNode = null;
document.addEventListener("DOMContentLoaded", function() {
loadStateFromCookies(); // Load saved state
document.querySelectorAll('.dropdown-item input[type="checkbox"]').forEach((checkbox) => {
if (checkedNodeInfo.includes(checkbox.id)) {
checkbox.checked = true; // ✅ Ensures checkboxes visually stay checked
}
checkbox.addEventListener('change', handleCheckboxChange);
});
document.querySelectorAll('.dropdown-submenu a.dropdown-toggle').forEach(function(element) {
element.addEventListener('click', function(e) {
if (!this.nextElementSibling.classList.contains('show')) {
this.parentElement.parentElement.querySelectorAll('.dropdown-menu').forEach(function(menu) {
menu.classList.remove('show');
});
}
this.nextElementSibling.classList.toggle('show');
e.stopPropagation();
});
});
});
// Function to save state in cookies
function saveStateToCookies() {
document.cookie = `checkedNodeInfo=${JSON.stringify(checkedNodeInfo)}; path=/; max-age=86400`; // Expires in 1 day
document.cookie = `selectedNodes=${JSON.stringify([firstNode, secondNode])}; path=/; max-age=86400`;
}
// Function to load state from cookies
function loadStateFromCookies() {
const cookies = document.cookie.split("; ");
for (let cookie of cookies) {
let [name, value] = cookie.split("=");
if (name === "checkedNodeInfo") {
checkedNodeInfo = JSON.parse(value);
} else if (name === "selectedNodes") {
[firstNode, secondNode] = JSON.parse(value || "[null, null]");
}
}
}
// Function to handle checkbox state changes
function handleCheckboxChange() {
checkedNodeInfo = Array.from(document.querySelectorAll('.dropdown-item input[type="checkbox"]:checked'))
.map(checkbox => checkbox.id);
console.log("Checked metrics:", checkedNodeInfo);
// Save selection state
saveStateToCookies();
renderGrid(latestNodeData, latestNodeStatus);
}
// Attach event listeners to checkboxes
document.querySelectorAll('.dropdown-item input[type="checkbox"]').forEach((checkbox) => {
checkbox.addEventListener('change', handleCheckboxChange);
});
function formatTime(seconds) {
const days = Math.floor(seconds / (3600*24))
const hours = Math.floor((seconds / 3600) % 24);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
// return `${days}d ${hours}h ${minutes}m ${secs}s`;
return `${days}d ${hours}h ${minutes}m`;
}
const socket = new WebSocket("ws://" + location.host);
socket.onmessage = (event) => {
const { nodeData, nodeStatus } = JSON.parse(event.data);
latestNodeData = nodeData;
latestNodeStatus = nodeStatus;
// Now using global variables to prevent "undefined" errors
renderGrid(latestNodeData, latestNodeStatus);
};
function renderGrid(nodeData, nodeStatus) {
const gridContainer = document.getElementById("grid");
gridContainer.innerHTML = "";
nodeData.forEach((row, y) => {
const rowDiv = document.createElement("div");
rowDiv.className = "row";
row.forEach((node, x) => {
const cellDiv = document.createElement("div");
const nodeKey = `${y}-${x}`;
cellDiv.className = "node";
cellDiv.setAttribute("data-node-id", nodeKey);
cellDiv.style.backgroundColor = nodeStatus[y][x];
// Ensure the indicator exists before adding text
const indicator = document.createElement("div");
indicator.className = "indicator";
if (nodeKey === firstNode) {
indicator.innerText = "1";
indicator.style.display = "flex";
} else if (nodeKey === secondNode) {
indicator.innerText = "2";
indicator.style.display = "flex";
} else {
indicator.style.display = "none"; // Hide if not selected
}
if (node) {
let displayText = `ID: ${node.id}`;
if (checkedNodeInfo.includes("temp")) {
displayText += `
Temp: ${node.cpu_temp}°C`;
}
if (checkedNodeInfo.includes("cutil")) {
displayText += `
CPU: ${node.cpu_util}%`;
}
if (checkedNodeInfo.includes("mutil")) {
displayText += `
Mem: ${node.mem_util}%`;
}
if (checkedNodeInfo.includes("uptime")) {
displayText += `
Up: ${formatTime(node.uptime)}`;
}
cellDiv.innerHTML = displayText;
} else {
cellDiv.innerHTML = "-";
}
cellDiv.appendChild(indicator);
cellDiv.addEventListener("click", () => {
if (nodeKey === firstNode) {
firstNode = null;
secondNode = null;
} else if (nodeKey === secondNode) {
secondNode = null;
} else if (!firstNode) {
firstNode = nodeKey;
} else {
secondNode = nodeKey;
}
console.log("Clicked node:", nodeKey);
saveStateToCookies();
renderGrid(nodeData, nodeStatus);
});
rowDiv.appendChild(cellDiv);
});
gridContainer.appendChild(rowDiv);
});
}
// Initialize with an empty grid
renderGrid(
Array.from({ length: 5 }, () => Array(5).fill(null)),
Array.from({ length: 5 }, () => Array(5).fill("white"))
);