Merge pull request #22463 from BerriAI/litellm_fix_queryclient_scope

[Fix] UI - QueryClient: move to single root-level provider
This commit is contained in:
yuneng-jiang 2026-02-28 18:15:51 -08:00 committed by GitHub
commit 74d8a1a3fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 56 additions and 87 deletions

View File

@ -3,25 +3,20 @@
import SpendLogsTable from "@/components/view_logs";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import useTeams from "@/app/(dashboard)/hooks/useTeams";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const LogsPage = () => {
const { accessToken, token, userRole, userId, premiumUser } = useAuthorized();
const { teams } = useTeams();
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<SpendLogsTable
accessToken={accessToken}
token={token}
userRole={userRole}
userID={userId}
allTeams={teams || []}
premiumUser={premiumUser}
/>
</QueryClientProvider>
<SpendLogsTable
accessToken={accessToken}
token={token}
userRole={userRole}
userID={userId}
allTeams={teams || []}
premiumUser={premiumUser}
/>
);
};

View File

@ -2,18 +2,11 @@
import { MCPServers } from "@/components/mcp_tools";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const MCPServersPage = () => {
const { accessToken, userRole, userId } = useAuthorized();
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<MCPServers accessToken={accessToken} userRole={userRole} userID={userId} />
</QueryClientProvider>
);
return <MCPServers accessToken={accessToken} userRole={userRole} userID={userId} />;
};
export default MCPServersPage;

View File

@ -4,27 +4,23 @@ import ViewUserDashboard from "@/components/view_users";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import useTeams from "@/app/(dashboard)/hooks/useTeams";
import { useState } from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const UsersPage = () => {
const { accessToken, userRole, userId, token } = useAuthorized();
const [keys, setKeys] = useState<null | any[]>([]);
const { teams } = useTeams();
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<ViewUserDashboard
accessToken={accessToken}
token={token}
keys={keys}
userRole={userRole}
userID={userId}
teams={teams as any}
setKeys={setKeys}
/>
</QueryClientProvider>
<ViewUserDashboard
accessToken={accessToken}
token={token}
keys={keys}
userRole={userRole}
userID={userId}
teams={teams as any}
setKeys={setKeys}
/>
);
};

View File

@ -2,7 +2,6 @@
import { useState } from "react";
import useKeyList from "@/components/key_team_helpers/key_list";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import UserDashboard from "@/components/user_dashboard";
import useTeams from "@/app/(dashboard)/hooks/useTeams";
@ -14,8 +13,6 @@ const VirtualKeysPage = () => {
const [createClicked, setCreateClicked] = useState<boolean>(false);
const [organizations, setOrganizations] = useState<Organization[]>([]);
const queryClient = new QueryClient();
const { keys, isLoading, error, pagination, refresh, setKeys } = useKeyList({
selectedKeyAlias: null,
currentOrg: null,
@ -29,23 +26,21 @@ const VirtualKeysPage = () => {
};
return (
<QueryClientProvider client={queryClient}>
<UserDashboard
userID={userId}
userRole={userRole}
userEmail={userEmail}
teams={teams}
keys={keys}
setUserRole={() => {}}
setUserEmail={() => {}}
setTeams={setTeams}
setKeys={setKeys}
premiumUser={premiumUser}
organizations={organizations}
addKey={addKey}
createClicked={createClicked}
/>
</QueryClientProvider>
<UserDashboard
userID={userId}
userRole={userRole}
userEmail={userEmail}
teams={teams}
keys={keys}
setUserRole={() => {}}
setUserEmail={() => {}}
setTeams={setTeams}
setKeys={setKeys}
premiumUser={premiumUser}
organizations={organizations}
addKey={addKey}
createClicked={createClicked}
/>
);
};

View File

@ -3,6 +3,7 @@ import { Inter } from "next/font/google";
import "./globals.css";
import AntdGlobalProvider from "@/contexts/AntdGlobalProvider";
import ReactQueryProvider from "@/contexts/ReactQueryProvider";
const inter = Inter({ subsets: ["latin"] });
@ -20,7 +21,9 @@ export default function RootLayout({
return (
<html lang="en">
<body className={inter.className}>
<AntdGlobalProvider>{children}</AntdGlobalProvider>
<ReactQueryProvider>
<AntdGlobalProvider>{children}</AntdGlobalProvider>
</ReactQueryProvider>
</body>
</html>
);

View File

@ -7,7 +7,6 @@ import { getProxyBaseUrl } from "@/components/networking";
import { getCookie } from "@/utils/cookieUtils";
import { isJwtExpired } from "@/utils/jwtUtils";
import { InfoCircleOutlined } from "@ant-design/icons";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Alert, Button, Card, Form, Input, Popover, Space, Typography } from "antd";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
@ -218,11 +217,5 @@ function LoginPageContent() {
}
export default function LoginPage() {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<LoginPageContent />
</QueryClientProvider>
);
return <LoginPageContent />;
}

View File

@ -2,9 +2,6 @@
import React, { Suspense, useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import ModelHubTable from "@/components/AIHub/ModelHubTable";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
function PublicModelHubTableContent() {
const searchParams = useSearchParams()!;
@ -20,9 +17,7 @@ function PublicModelHubTableContent() {
}, [key]);
return (
<QueryClientProvider client={queryClient}>
<ModelHubTable accessToken={accessToken} publicPage={true} premiumUser={false} userRole={null} />
</QueryClientProvider>
<ModelHubTable accessToken={accessToken} publicPage={true} premiumUser={false} userRole={null} />
);
}

View File

@ -1,11 +1,8 @@
"use client";
import React, { Suspense } from "react";
import { useSearchParams } from "next/navigation";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { OnboardingForm } from "./OnboardingForm";
const queryClient = new QueryClient();
function OnboardingContent() {
const searchParams = useSearchParams()!;
const action = searchParams.get("action");
@ -15,14 +12,12 @@ function OnboardingContent() {
export default function Onboarding() {
return (
<QueryClientProvider client={queryClient}>
<Suspense
fallback={
<div className="flex items-center justify-center min-h-screen">Loading...</div>
}
>
<OnboardingContent />
</Suspense>
</QueryClientProvider>
<Suspense
fallback={
<div className="flex items-center justify-center min-h-screen">Loading...</div>
}
>
<OnboardingContent />
</Suspense>
);
}

View File

@ -45,7 +45,6 @@ import ViewUserDashboard from "@/components/view_users";
import { ThemeProvider } from "@/contexts/ThemeContext";
import { isJwtExpired } from "@/utils/jwtUtils";
import { isAdminRole } from "@/utils/roles";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { jwtDecode } from "jwt-decode";
import { useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react";
@ -103,8 +102,6 @@ interface ProxySettings {
LITELLM_UI_API_DOC_BASE_URL?: string | null;
}
const queryClient = new QueryClient();
function CreateKeyPageContent() {
const [userRole, setUserRole] = useState("");
const [premiumUser, setPremiumUser] = useState(false);
@ -372,8 +369,7 @@ function CreateKeyPageContent() {
return (
<Suspense fallback={<LoadingScreen />}>
<QueryClientProvider client={queryClient}>
<ConfigProvider theme={{
<ConfigProvider theme={{
algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm,
}}>
<ThemeProvider accessToken={accessToken}>
@ -600,7 +596,6 @@ function CreateKeyPageContent() {
)}
</ThemeProvider>
</ConfigProvider>
</QueryClientProvider>
</Suspense>
);
}

View File

@ -0,0 +1,9 @@
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
export default function ReactQueryProvider({ children }: { children: React.ReactNode }) {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}