fix: sync dashboard page query state
Deploy Claude Dev (Dev) / deploy-claude-dev-dev (push) Successful in 17m2s
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 2m48s

Keep the selected dashboard page in sync with lightweight URL query params so direct terminal links can land on the right page without exposing extra client state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gan, Jimmy
2026-03-07 11:02:53 +08:00
parent c8255dccec
commit 175ebeede4
+44
View File
@@ -16,6 +16,21 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import { getToken, checkAuth, setToken, setRefreshToken, currentUser, setCurrentUser, getPreferences, savePreferences } from "./lib/api.js"; 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 page = $state("dashboard");
let dark = $state(false); let dark = $state(false);
let sidebarOpen = $state(false); let sidebarOpen = $state(false);
@@ -27,6 +42,26 @@
let sidebarOrder = $state(null); let sidebarOrder = $state(null);
let orderSaveTimer = 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() { async function fetchUserInfo() {
try { try {
const data = await checkAuth(); const data = await checkAuth();
@@ -78,6 +113,8 @@
setRefreshToken(data.refresh_token); setRefreshToken(data.refresh_token);
authorized = true; authorized = true;
await fetchUserInfo(); await fetchUserInfo();
const requestedPage = getRequestedPage();
if (canOpenPage(requestedPage)) page = requestedPage;
loading = false; loading = false;
return; return;
} }
@@ -96,6 +133,8 @@
try { try {
await fetchUserInfo(); await fetchUserInfo();
authorized = true; authorized = true;
const requestedPage = getRequestedPage();
if (canOpenPage(requestedPage)) page = requestedPage;
} catch (e) { } catch (e) {
console.error("Auth check failed:", e); console.error("Auth check failed:", e);
setToken(""); setToken("");
@@ -105,6 +144,11 @@
} }
}); });
$effect(() => {
if (!authorized || loading || !canOpenPage(page)) return;
syncPageQuery(page);
});
function toggleTheme() { function toggleTheme() {
dark = !dark; dark = !dark;
if (dark) { if (dark) {