diff --git a/frontend/app/components/common/Topbar.tsx b/frontend/app/components/common/Topbar.tsx index e04338a..04ac5d5 100644 --- a/frontend/app/components/common/Topbar.tsx +++ b/frontend/app/components/common/Topbar.tsx @@ -2,7 +2,7 @@ import { ChevronRight, LayoutGrid } from "lucide-react"; import type { AuthUser, AuthWorkspace } from "../../context/AuthContext"; type TopbarProps = { - activePage: string; + pageTitle: string; apiOnline: boolean; user: AuthUser | null; currentWorkspace: AuthWorkspace; @@ -14,7 +14,7 @@ type TopbarProps = { }; export function Topbar({ - activePage, + pageTitle, apiOnline, user, currentWorkspace, @@ -24,13 +24,6 @@ export function Topbar({ onSetCurrentWorkspace, onLogout, }: TopbarProps) { - const pageTitles: Record = { - home: "工作台", - scripts: "构建脚本", - schedules: "调度配置", - system: "系统管理", - }; - return (
@@ -45,7 +38,7 @@ export function Topbar({ 开发工作区

- {pageTitles[activePage] || "工作台"} + {pageTitle}

diff --git a/frontend/app/routes/platform.navigation.tsx b/frontend/app/routes/platform.navigation.tsx index 7b856c6..a01731f 100644 --- a/frontend/app/routes/platform.navigation.tsx +++ b/frontend/app/routes/platform.navigation.tsx @@ -21,6 +21,42 @@ export type NavigationItem = { children?: NavigationItem[]; }; +export function pathForPage(page: ActivePage): string { + if (page === "home") return "/workbench"; + return `/${page}`; +} + +function normalizePath(pathname: string): string { + const trimmed = pathname.replace(/\/+$/, ""); + return trimmed || "/"; +} + +/** 根据当前 pathname 解析顶栏标题:二级菜单显示子项名称,一级菜单显示自身名称。 */ +export function pageTitleFromPath(pathname: string): string { + const path = normalizePath(pathname); + + for (const item of navigation) { + if (item.children) { + for (const child of item.children) { + const childPath = + child.activePath ?? `${pathForPage(child.page)}/${child.sub}`; + if (path === childPath) { + return child.label; + } + } + } + } + + for (const item of navigation) { + const itemPath = item.activePath ?? pathForPage(item.page); + if (path === itemPath) { + return item.label; + } + } + + return "工作台"; +} + export const navigation: NavigationItem[] = [ { label: "工作台", icon: Home, page: "home", permission: "dashboard:view" }, { label: "构建脚本", icon: Code, page: "scripts", permission: "script:view" }, diff --git a/frontend/app/routes/platform.tsx b/frontend/app/routes/platform.tsx index 9222340..19b4d47 100644 --- a/frontend/app/routes/platform.tsx +++ b/frontend/app/routes/platform.tsx @@ -1,8 +1,12 @@ import { useEffect, useState } from "react"; import { Outlet, useLocation, useNavigate } from "react-router"; -import { PanelLeft, ChevronRight } from "lucide-react"; -import { navigation } from "./platform.navigation"; +import { ChevronRight, Menu } from "lucide-react"; +import { + navigation, + pathForPage, + pageTitleFromPath, +} from "./platform.navigation"; import type { ActivePage, NavigationItem, SubPage } from "./platform.navigation"; import { Collapsible } from "@base-ui/react/collapsible"; @@ -21,9 +25,10 @@ import { SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, - SidebarTrigger, SidebarInset, + useSidebar, } from "~/components/ui/sidebar"; +import { cn } from "~/lib/utils"; import { useApi, useAuth, usePermission } from "~/context/AuthContext"; import { useEditSessionLifecycle } from "~/features/platform/hooks/useEditSessionLifecycle"; import { @@ -46,11 +51,6 @@ function pageFromPath(pathname: string): ActivePage { return "home"; } -function pathForPage(page: ActivePage): string { - if (page === "home") return "/workbench"; - return `/${page}`; -} - export function meta({}: Route.MetaArgs) { return [ { title: "模型实验开发平台" }, @@ -132,6 +132,26 @@ function NavRow({ ); } +function SidebarCollapseButton() { + const { toggleSidebar, state } = useSidebar(); + const collapsed = state === "collapsed"; + + return ( + + ); +} + export default function PlatformLayout() { const { currentWorkspace } = useAuth(); if (!currentWorkspace) { @@ -151,6 +171,7 @@ function AuthenticatedLayout() { const location = useLocation(); const navigate = useNavigate(); const activePage = pageFromPath(location.pathname); + const pageTitle = pageTitleFromPath(location.pathname); const auth = useAuth(); const { user, @@ -246,16 +267,14 @@ function AuthenticatedLayout() { ))} - - - {!sidebarCollapsed && 收起菜单} - + +