feat(panel.js): move js from inline to separate script
This commit is contained in:
163
src/judas_server/web/static/js/panel.js
Normal file
163
src/judas_server/web/static/js/panel.js
Normal file
@@ -0,0 +1,163 @@
|
||||
$(document).ready(function () {
|
||||
const socket = io();
|
||||
|
||||
const showNotify = (message) => {
|
||||
$("#notify").stop().fadeIn();
|
||||
$("#notify").text(message);
|
||||
setTimeout(() => {
|
||||
$("#notify").fadeOut();
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
const loadClientDetails = (clientId) => {
|
||||
fetch(`/client/${clientId}`)
|
||||
.then((response) => response.text())
|
||||
.then((html) => {
|
||||
$("#content").html(html);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching client details:", error);
|
||||
});
|
||||
};
|
||||
|
||||
// load client_details for the client specified in the URL
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const clientId = urlParams.get("client");
|
||||
if (clientId) {
|
||||
loadClientDetails(clientId);
|
||||
$(`#client-list a[href="?client=${clientId}"]`).addClass("active");
|
||||
}
|
||||
|
||||
$("#notify").hide();
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("Connected to server");
|
||||
$("#no-connection-message").hide();
|
||||
showNotify("Connected to server");
|
||||
});
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log("Disconnected from server");
|
||||
$("#no-connection-message").show();
|
||||
showNotify("Disconnected from server");
|
||||
});
|
||||
|
||||
socket.on("update_data", (data) => {
|
||||
const clientList = $("#client-list");
|
||||
const existingItems = {};
|
||||
|
||||
// Index current <li> by clientId
|
||||
clientList.children("li").each(function () {
|
||||
const a = $(this).find("a");
|
||||
if (a.length) {
|
||||
const clientId = a.attr("href").substring(1);
|
||||
existingItems[clientId] = $(this);
|
||||
}
|
||||
});
|
||||
|
||||
// Track which clientIds are still present
|
||||
const seen = new Set();
|
||||
|
||||
Object.entries(data).forEach(([clientId, client]) => {
|
||||
seen.add(clientId);
|
||||
|
||||
// Build icon
|
||||
const iconElement = document.createElement("i");
|
||||
switch (client.status) {
|
||||
case "online":
|
||||
iconElement.className = "fi fi-sr-play text-ctp-green";
|
||||
break;
|
||||
case "offline":
|
||||
iconElement.className = "fi fi-sr-stop text-ctp-red";
|
||||
break;
|
||||
case "pending":
|
||||
iconElement.className = "fi fi-sr-pending text-ctp-yellow";
|
||||
break;
|
||||
case "stale":
|
||||
iconElement.className = "fi fi-sr-skull text-ctp-text";
|
||||
break;
|
||||
default:
|
||||
iconElement.className = "fi fi-rr-question text-ctp-gray";
|
||||
}
|
||||
|
||||
// Time since last seen
|
||||
const lastSeen = new Date(client.last_seen * 1000);
|
||||
const now = new Date();
|
||||
const timeSinceLastSeen = Math.floor((now - lastSeen) / 1000);
|
||||
const days = Math.floor(timeSinceLastSeen / 86400);
|
||||
const hours = Math.floor((timeSinceLastSeen % 86400) / 3600);
|
||||
const minutes = Math.floor((timeSinceLastSeen % 3600) / 60);
|
||||
const seconds = timeSinceLastSeen % 60;
|
||||
let timeSinceLastSeenText = "";
|
||||
if (days > 0) timeSinceLastSeenText += `${days}d `;
|
||||
if (hours > 0) timeSinceLastSeenText += `${hours}h `;
|
||||
if (minutes > 0) timeSinceLastSeenText += `${minutes}m `;
|
||||
if (seconds > 0) timeSinceLastSeenText += `${seconds}s`;
|
||||
|
||||
timeSinceLastSeenText = timeSinceLastSeenText.trim() || "0s";
|
||||
|
||||
let statusText = `${client.id} (${timeSinceLastSeenText})`;
|
||||
|
||||
// check if <li> exists
|
||||
if (existingItems[clientId]) {
|
||||
// update if needed
|
||||
const li = existingItems[clientId];
|
||||
const a = li.find("a");
|
||||
if (a.text() !== statusText) {
|
||||
a.text(statusText);
|
||||
}
|
||||
|
||||
li.attr(
|
||||
"title",
|
||||
`Status: ${client.status}\nLast Seen: ${lastSeen.toISOString()}`,
|
||||
);
|
||||
|
||||
// update icon
|
||||
const icon = li.find("i")[0];
|
||||
if (icon) {
|
||||
icon.className = iconElement.className;
|
||||
}
|
||||
} else {
|
||||
// add new <li>
|
||||
const li = $("<li></li>");
|
||||
li.append(iconElement);
|
||||
const a = $("<a></a>")
|
||||
.text(statusText)
|
||||
.attr("href", `?client=${clientId}`);
|
||||
|
||||
li.attr(
|
||||
"title",
|
||||
`Status: ${client.status}\nLast Seen: ${lastSeen.toISOString()}`,
|
||||
);
|
||||
|
||||
li.append(a);
|
||||
clientList.append(li);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove <li> for clients no longer present
|
||||
Object.keys(existingItems).forEach((clientId) => {
|
||||
if (!seen.has(clientId)) {
|
||||
existingItems[clientId].remove();
|
||||
}
|
||||
});
|
||||
|
||||
// Re-bind click handlers
|
||||
$("#client-list li > a")
|
||||
.off("click")
|
||||
.on("click", function (e) {
|
||||
let clientId = $(this).attr("href").substring(1);
|
||||
// this is client=clientId
|
||||
|
||||
clientId = clientId.replace("client=", "");
|
||||
|
||||
loadClientDetails(clientId);
|
||||
$("#client-list a").removeClass("bg-ctp-surface0");
|
||||
$(this).addClass("bg-ctp-surface0");
|
||||
e.preventDefault();
|
||||
|
||||
let newUrl = `${window.location.pathname}?client=${clientId}`;
|
||||
window.history.pushState({ path: newUrl }, "", newUrl);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user