Skip to content

Commit 7ed4715

Browse files
committed
eliminates loading screen flash
1 parent cc94fb8 commit 7ed4715

File tree

2 files changed

+276
-311
lines changed

2 files changed

+276
-311
lines changed

ui/litellm-dashboard/src/app/(dashboard)/components/Sidebar2.tsx

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Layout, Menu } from "antd";
2-
import { useRouter, usePathname } from "next/navigation"; // UPDATED: also usePathname to detect current route
2+
import { usePathname } from "next/navigation";
33
import {
44
KeyOutlined,
55
PlayCircleOutlined,
@@ -44,23 +44,29 @@ interface MenuItem {
4444
icon?: React.ReactNode;
4545
}
4646

47-
/** ---- BASE URL HELPERS (shared pattern across files) ---- */
47+
/** ---- BASE URL HELPERS ---- */
4848
function normalizeBasePrefix(raw: string | undefined | null): string {
4949
const trimmed = (raw ?? "").trim();
5050
if (!trimmed) return ""; // no base
51-
// strip leading/trailing slashes then rebuild as "/segment/"
5251
const core = trimmed.replace(/^\/+/, "").replace(/\/+$/, "");
53-
return core ? `/${core}/` : "/";
52+
return core ? `/${core}` : "";
5453
}
5554
const BASE_PREFIX = normalizeBasePrefix(process.env.NEXT_PUBLIC_BASE_URL);
56-
/** Builds an app-relative path under the configured base prefix. */
55+
56+
/** Build an absolute path under the configured base. */
5757
function withBase(path: string): string {
58-
// Accepts paths like "/virtual-keys" or "/?page=..." and prefixes with BASE_PREFIX when present.
59-
const body = path.startsWith("/") ? path.slice(1) : path;
60-
const combined = `${BASE_PREFIX}${body}`;
61-
return combined.startsWith("/") ? combined : `/${combined}`;
58+
// path can be "/virtual-keys" or "/?page=..."
59+
const p = path.startsWith("/") ? path : `/${path}`;
60+
return `${BASE_PREFIX}${p}` || p;
61+
}
62+
63+
/** History-based navigation to prevent hard reloads / suspense flashes */
64+
function softNavigate(url: string, replace = false) {
65+
if (typeof window === "undefined") return;
66+
if (replace) window.history.replaceState(null, "", url);
67+
else window.history.pushState(null, "", url);
6268
}
63-
/** -------------------------------------------------------- */
69+
/** -------------------------------- */
6470

6571
const Sidebar2: React.FC<SidebarProps> = ({
6672
accessToken,
@@ -69,7 +75,6 @@ const Sidebar2: React.FC<SidebarProps> = ({
6975
defaultSelectedKey,
7076
collapsed = false,
7177
}) => {
72-
const router = useRouter();
7378
const pathname = usePathname();
7479
const { refactoredUIFlag } = useFeatureFlags();
7580

@@ -243,38 +248,30 @@ const Sidebar2: React.FC<SidebarProps> = ({
243248
return true;
244249
});
245250

246-
// Helper: go to /?page=...; when on /virtual-keys with refactored UI, replace instead of appending
251+
// Helper: update /?page=... under the configured base, WITHOUT triggering App Router nav
247252
const pushToRootWithPage = (page: string, useReplace = false) => {
248253
const params = new URLSearchParams();
249254
params.set("page", page);
250255
const url = withBase(`/?${params.toString()}`);
251-
if (useReplace) {
252-
router.replace(url);
253-
} else {
254-
router.push(url);
255-
}
256+
softNavigate(url, useReplace);
256257
};
257258

258-
// Centralized navigation that satisfies the requirement
259259
const navigateToPage = (page: string) => {
260-
// Special-case: Virtual Keys target
261260
if (page === "api-keys") {
262261
if (refactoredUIFlag) {
263-
// Go to the dedicated /virtual-keys page (always under base)
264-
router.push(withBase("/virtual-keys"));
265-
return; // do not call setPage here (parity with previous behavior)
262+
// vanity URL, keep SPA alive
263+
softNavigate(withBase("/virtual-keys"));
264+
return; // don't call setPage to keep parity, UI already shows api-keys by default
266265
}
267-
// Legacy behavior
268266
pushToRootWithPage(page);
269267
setPage(page);
270268
return;
271269
}
272270

273-
// All other pages
274271
if (refactoredUIFlag) {
275-
// If currently on /virtual-keys, REPLACE it with /?page=...
276-
const onVirtualKeys = pathname?.startsWith(withBase("/virtual-keys"));
277-
pushToRootWithPage(page, !!onVirtualKeys);
272+
const onVirtualKeys =
273+
typeof window !== "undefined" && window.location.pathname.startsWith(withBase("/virtual-keys"));
274+
pushToRootWithPage(page, onVirtualKeys);
278275
} else {
279276
pushToRootWithPage(page);
280277
}
@@ -308,15 +305,9 @@ const Sidebar2: React.FC<SidebarProps> = ({
308305
key: child.key,
309306
icon: child.icon,
310307
label: child.label,
311-
onClick: () => {
312-
navigateToPage(child.page);
313-
},
308+
onClick: () => navigateToPage(child.page),
314309
})),
315-
onClick: !item.children
316-
? () => {
317-
navigateToPage(item.page);
318-
}
319-
: undefined,
310+
onClick: !item.children ? () => navigateToPage(item.page) : undefined,
320311
}))}
321312
/>
322313
</ConfigProvider>

0 commit comments

Comments
 (0)