Files
overlord/Overlord-Server/public/assets/nav.js
T
KingKDot d26668df78 huge update.
fix issues with failing tests (I'm just gonna fucking assume directx isn't installed on the github actions machines).

Added MUCH better RBAC support and control

Fixed an issue when you have over a million clients RBAC would be slow asf

Add settings page with some basic settings and configs you can change.
2026-03-06 20:50:02 -06:00

121 lines
3.4 KiB
JavaScript

import {
startNotificationClient,
setNotificationsEnabled,
getNotificationsEnabled,
subscribeStatus,
subscribeUnread,
} from "./notify-client.js";
import { mountNav } from "./nav/template.js";
import { createAdaptiveNavController } from "./nav/layout.js";
import { applyUserRoleUI } from "./nav/role-ui.js";
const host = document.getElementById("top-nav");
if (host) {
const refs = mountNav(host);
const { applyAdaptiveNavLayout } = createAdaptiveNavController(host, refs);
const path = window.location.pathname;
const activeMap = {
"/": "nav-clients",
"/metrics": "metrics-link",
"/logs": "logs-link",
"/scripts": "scripts-link",
"/plugins": "plugins-link",
"/build": "build-link",
"/users": "users-link",
"/user-client-access": "users-link",
"/notifications": "notifications-link",
};
const activeId = activeMap[path];
if (activeId) {
const el = document.getElementById(activeId);
if (el) {
el.classList.remove("bg-slate-900/70", "text-slate-300");
el.classList.add("bg-slate-800", "text-slate-50");
el.classList.add("nav-active");
}
}
if (refs.logoutBtn && !refs.logoutBtn.dataset.boundLogout) {
refs.logoutBtn.dataset.boundLogout = "true";
refs.logoutBtn.addEventListener("click", async () => {
if (!confirm("Are you sure you want to logout?")) return;
try {
const res = await fetch("/api/logout", {
method: "POST",
headers: { "Content-Type": "application/json" },
});
if (res.ok) {
window.location.href = "/";
} else {
alert("Logout failed. Please try again.");
}
} catch (err) {
console.error("Logout error:", err);
alert("Logout failed. Please try again.");
}
});
}
if (refs.accountSettingsBtn && !refs.accountSettingsBtn.dataset.boundSettings) {
refs.accountSettingsBtn.dataset.boundSettings = "true";
refs.accountSettingsBtn.addEventListener("click", () => {
window.location.href = "/settings";
});
}
if (path === "/settings" && refs.accountSettingsBtn) {
refs.accountSettingsBtn.classList.add("ring-1", "ring-sky-500/60", "bg-slate-700");
}
const updateToggle = () => {
const enabled = getNotificationsEnabled();
if (refs.notifyToggle) {
refs.notifyToggle.classList.toggle("text-emerald-200", enabled);
refs.notifyToggle.classList.toggle("border-emerald-500/40", enabled);
refs.notifyToggle.classList.toggle("text-slate-300", !enabled);
}
};
refs.notifyToggle?.addEventListener("click", () => {
const next = !getNotificationsEnabled();
setNotificationsEnabled(next);
updateToggle();
});
subscribeUnread((count) => {
if (!refs.notifyBadge) return;
refs.notifyBadge.textContent = String(count);
refs.notifyBadge.classList.toggle("hidden", count <= 0);
});
updateToggle();
startNotificationClient();
subscribeStatus((status) => {
if (status === "connected") {
// no-op
}
});
async function loadCurrentUser() {
try {
const res = await fetch("/api/auth/me", { credentials: "include" });
if (!res.ok) {
return;
}
const user = await res.json();
applyUserRoleUI(user, refs);
applyAdaptiveNavLayout();
} catch (err) {
console.error("Failed to load user:", err);
}
}
if (refs.usernameDisplay && refs.roleBadge) {
loadCurrentUser();
}
}