diff --git a/dashboard/frontend/src/App.svelte b/dashboard/frontend/src/App.svelte index 68bf340..c877037 100644 --- a/dashboard/frontend/src/App.svelte +++ b/dashboard/frontend/src/App.svelte @@ -16,6 +16,21 @@ import { onMount } from "svelte"; import { getToken, checkAuth, setToken, setRefreshToken, currentUser, setCurrentUser, getPreferences, savePreferences } from "./lib/api.js"; + const KNOWN_PAGES = new Set([ + "dashboard", + "docker", + "gitea", + "files", + "terminal", + "openclaw", + "chat-digest", + "settings", + "security", + "litellm", + "cc-connect", + "info-engine", + ]); + let page = $state("dashboard"); let dark = $state(false); let sidebarOpen = $state(false); @@ -27,6 +42,26 @@ let sidebarOrder = $state(null); let orderSaveTimer = null; + function getRequestedPage() { + const requestedPage = new URLSearchParams(window.location.search).get("page"); + return KNOWN_PAGES.has(requestedPage) ? requestedPage : null; + } + + function canOpenPage(pageId) { + if (!pageId || !KNOWN_PAGES.has(pageId)) return false; + if (pageId === "settings") return userRole === "admin"; + if (["litellm", "cc-connect", "info-engine"].includes(pageId)) return hasPageAccess("dashboard"); + return hasPageAccess(pageId); + } + + function syncPageQuery(pageId) { + const url = new URL(window.location.href); + if (pageId === "dashboard") url.searchParams.delete("page"); + else url.searchParams.set("page", pageId); + if (pageId !== "terminal") url.searchParams.delete("host"); + history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`); + } + async function fetchUserInfo() { try { const data = await checkAuth(); @@ -78,6 +113,8 @@ setRefreshToken(data.refresh_token); authorized = true; await fetchUserInfo(); + const requestedPage = getRequestedPage(); + if (canOpenPage(requestedPage)) page = requestedPage; loading = false; return; } @@ -96,6 +133,8 @@ try { await fetchUserInfo(); authorized = true; + const requestedPage = getRequestedPage(); + if (canOpenPage(requestedPage)) page = requestedPage; } catch (e) { console.error("Auth check failed:", e); setToken(""); @@ -105,6 +144,11 @@ } }); + $effect(() => { + if (!authorized || loading || !canOpenPage(page)) return; + syncPageQuery(page); + }); + function toggleTheme() { dark = !dark; if (dark) {