Compare commits

..

1 Commits

Author SHA1 Message Date
a0cc6c3ec7 fix(web): add ReactQueryProvider to root layout for Mission Control
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Mission Control components (AuditLogDrawer, GlobalAgentRoster, PanelControls)
use @tanstack/react-query hooks but no QueryClientProvider existed in the
layout tree. This caused a crash: 'No QueryClient set, use QueryClientProvider'.

Added ReactQueryProvider wrapper in apps/web/src/providers/ and wired it into
the root layout above ErrorBoundary/AuthProvider so all routes have access.
2026-03-08 10:30:33 -05:00
3 changed files with 34 additions and 7 deletions

View File

@@ -4,6 +4,7 @@ import { Outfit, Fira_Code } from "next/font/google";
import { AuthProvider } from "@/lib/auth/auth-context"; import { AuthProvider } from "@/lib/auth/auth-context";
import { ErrorBoundary } from "@/components/error-boundary"; import { ErrorBoundary } from "@/components/error-boundary";
import { ThemeProvider } from "@/providers/ThemeProvider"; import { ThemeProvider } from "@/providers/ThemeProvider";
import { ReactQueryProvider } from "@/providers/ReactQueryProvider";
import "./globals.css"; import "./globals.css";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
@@ -56,9 +57,11 @@ export default function RootLayout({ children }: { children: ReactNode }): React
</head> </head>
<body> <body>
<ThemeProvider> <ThemeProvider>
<ReactQueryProvider>
<ErrorBoundary> <ErrorBoundary>
<AuthProvider>{children}</AuthProvider> <AuthProvider>{children}</AuthProvider>
</ErrorBoundary> </ErrorBoundary>
</ReactQueryProvider>
</ThemeProvider> </ThemeProvider>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,28 @@
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState, type ReactNode } from "react";
interface ReactQueryProviderProps {
children: ReactNode;
}
export function ReactQueryProvider({ children }: ReactQueryProviderProps): React.JSX.Element {
// Create a stable QueryClient per component mount (one per app session)
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
// Don't refetch on window focus in a dashboard context
refetchOnWindowFocus: false,
// Stale time of 30s — short enough for live data, avoids hammering
staleTime: 30_000,
retry: 1,
},
},
})
);
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}

View File

@@ -316,8 +316,6 @@ services:
SANDBOX_ENABLED: "true" SANDBOX_ENABLED: "true"
# API key for authenticating requests from the web proxy # API key for authenticating requests from the web proxy
ORCHESTRATOR_API_KEY: ${ORCHESTRATOR_API_KEY} ORCHESTRATOR_API_KEY: ${ORCHESTRATOR_API_KEY}
# Prisma database connection (uses the shared openbrain postgres)
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@openbrain_brain-db:5432/${POSTGRES_DB:-mosaic}
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
- orchestrator_workspace:/workspace - orchestrator_workspace:/workspace
@@ -333,7 +331,6 @@ services:
start_period: 40s start_period: 40s
networks: networks:
- internal - internal
- openbrain_brain-internal
cap_drop: cap_drop:
- ALL - ALL
cap_add: cap_add:
@@ -406,7 +403,6 @@ services:
networks: networks:
- internal - internal
- traefik-public - traefik-public
- openbrain_brain-internal
deploy: deploy:
restart_policy: restart_policy:
condition: on-failure condition: on-failure