diff --git a/frontend-web/src/App.tsx b/frontend-web/src/App.tsx index 277f3974..e2c8695c 100644 --- a/frontend-web/src/App.tsx +++ b/frontend-web/src/App.tsx @@ -7,6 +7,7 @@ import { QueryClientProvider } from "@/components/query-client-provider"; import { AuthSyncWatcher } from "@/core/auth/sync"; import { I18nProvider } from "@/core/i18n/context"; import { detectLocale } from "@/core/i18n/locale"; +import { resolveForcedThemeForPath } from "@/core/page-layout/chats-iframe-route"; import { ChatProvider } from "@/contexts/ChatContext"; import { ThemeProvider } from "@/contexts/ThemeContext"; @@ -29,7 +30,7 @@ import { NotFoundPage } from "./pages/NotFoundPage"; function AppProviders({ children }: { children: React.ReactNode }) { const locale = useMemo(() => detectLocale(), []); const location = useLocation(); - const forcedTheme = location.pathname === "/landing" ? "light" : undefined; + const forcedTheme = resolveForcedThemeForPath(location.pathname); return ( { + assert.equal( + isChatsIframeWorkspacePath("/page/workspace/chats_iframe/new"), + true, + ); + assert.equal( + isChatsIframeWorkspacePath("/page/workspace/chats_iframe/thread-123"), + true, + ); + assert.equal(isChatsIframeWorkspacePath("/page/workspace/chats/new"), false); + assert.equal(isChatsIframeWorkspacePath("/landing"), false); +}); + +test("forces light theme for landing and chats_iframe routes only", () => { + assert.equal(resolveForcedThemeForPath("/landing"), "light"); + assert.equal( + resolveForcedThemeForPath("/page/workspace/chats_iframe/new"), + "light", + ); + assert.equal( + resolveForcedThemeForPath("/page/workspace/chats_iframe/thread-123"), + "light", + ); + assert.equal(resolveForcedThemeForPath("/page/workspace/chats/new"), undefined); +}); diff --git a/frontend-web/src/core/page-layout/chats-iframe-route.ts b/frontend-web/src/core/page-layout/chats-iframe-route.ts new file mode 100644 index 00000000..30c6ba78 --- /dev/null +++ b/frontend-web/src/core/page-layout/chats-iframe-route.ts @@ -0,0 +1,16 @@ +export function isChatsIframeWorkspacePath(pathname: string): boolean { + return ( + pathname === "/page/workspace/chats_iframe/new" || + pathname.startsWith("/page/workspace/chats_iframe/") + ); +} + +export function resolveForcedThemeForPath( + pathname: string, +): "light" | undefined { + if (pathname === "/landing" || isChatsIframeWorkspacePath(pathname)) { + return "light"; + } + + return undefined; +} diff --git a/frontend-web/src/pages/PageRoutes.tsx b/frontend-web/src/pages/PageRoutes.tsx index 96400566..1e9b0e43 100644 --- a/frontend-web/src/pages/PageRoutes.tsx +++ b/frontend-web/src/pages/PageRoutes.tsx @@ -3,8 +3,10 @@ import { Navigate, Route, Routes } from "react-router-dom"; import { PageSidebar } from "@/components/page-sidebar"; import { PageSidebarDark } from "@/components/page-sidebar-dark"; +import { isChatsIframeWorkspacePath } from "@/core/page-layout/chats-iframe-route"; import { readSidebarEnabled } from "@/core/page-layout/sidebar-enabled"; import { useTheme } from "@/contexts/ThemeContext"; +import { useLocation } from "react-router-dom"; import WorkspaceRoutes from "./WorkspaceRoutes"; import StrategyRoutes from "./StrategyRoutes"; @@ -16,17 +18,20 @@ import NotebookRoutes from "./NotebookRoutes"; function PageLayout() { const [collapsed, setCollapsed] = useState(false); const sidebarEnabled = useMemo(() => readSidebarEnabled(), []); + const location = useLocation(); const { theme } = useTheme(); const isDark = theme === "dark"; + const pageSidebarAllowed = + sidebarEnabled && !isChatsIframeWorkspacePath(location.pathname); // h-full(100%)而非 h-screen(100vh):配合 globals.css 的 html/body/#root height:100% // 高度链,根布局跟随容器高度。全屏下 100% 解析到视口,与 h-screen 等价;无界等嵌套 // 下容器不占满整屏时,高度才能正确收缩而非锁死整屏。 return (
- {sidebarEnabled &&
} + {pageSidebarAllowed &&
}
- {sidebarEnabled && ( + {pageSidebarAllowed && ( isDark ? ( } diff --git a/frontend-web/src/pages/WorkspaceRoutes.tsx b/frontend-web/src/pages/WorkspaceRoutes.tsx index 462b5d5b..bb7df093 100644 --- a/frontend-web/src/pages/WorkspaceRoutes.tsx +++ b/frontend-web/src/pages/WorkspaceRoutes.tsx @@ -67,6 +67,7 @@ export function WorkspaceLayout({ children, pageSidebarCollapsed, pageSidebarHidden = false, + workspaceSidebarHidden = false, headerHidden = false, compactWorkspaceSidebar = false, wrapperOverflowHidden = false, @@ -76,6 +77,7 @@ export function WorkspaceLayout({ children: ReactNode; pageSidebarCollapsed: boolean; pageSidebarHidden?: boolean; + workspaceSidebarHidden?: boolean; headerHidden?: boolean; compactWorkspaceSidebar?: boolean; wrapperOverflowHidden?: boolean; @@ -109,7 +111,9 @@ export function WorkspaceLayout({ data-page-sidebar-collapsed={pageSidebarCollapsed} defaultOpen > - + {!workspaceSidebarHidden && ( + + )} @@ -205,7 +209,11 @@ export default function WorkspaceRoutes({ + @@ -217,6 +225,8 @@ export default function WorkspaceRoutes({ element={