From 1c50c73aa43ead06f0cb34a3b206ad825aad5e9f Mon Sep 17 00:00:00 2001 From: fengxiangdebaozi <10845145+fengxiangdebaozi@user.noreply.gitee.com> Date: Wed, 13 May 2026 21:41:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend-web/src/components/page-sidebar.tsx | 371 ++++++++++++++++--- 1 file changed, 321 insertions(+), 50 deletions(-) diff --git a/frontend-web/src/components/page-sidebar.tsx b/frontend-web/src/components/page-sidebar.tsx index 963715d0..b5d48c71 100644 --- a/frontend-web/src/components/page-sidebar.tsx +++ b/frontend-web/src/components/page-sidebar.tsx @@ -1,33 +1,333 @@ -import { NavLink, useLocation } from "react-router-dom"; +import { useState } from "react"; +import type { ElementType } from "react"; import { + BarChart3, + Bot, + Brain, ChevronLeft, ChevronRight, + CircleHelp, + Compass, + Database, + FileBox, + FileOutput, FileText, - LayoutDashboard, + Folder, + FolderOpen, + Grid3X3, + HelpCircle, + History, + Layers, + Layout, + Library, + ListTodo, + MessageSquare, + MoreHorizontal, + Network, + PlayCircle, + Plus, + Scale, + Settings, + Target, + TrendingUp, + Users, + Workflow, } from "lucide-react"; -const navItems = [ - { - label: "Workspace", - to: "/page/workspace", - match: "/page/workspace", - icon: LayoutDashboard, - }, -]; +type MenuItem = { + id: string; + label: string; + icon: ElementType; + children?: MenuItem[]; +}; type PageSidebarProps = { collapsed: boolean; onToggleCollapsed: () => void; }; +const menuItems: MenuItem[] = [ + { + id: "qa-center", + label: "QA Center", + icon: HelpCircle, + children: [ + { id: "new-qa", label: "New QA", icon: Plus }, + { id: "general-qa", label: "General QA", icon: CircleHelp }, + { id: "agent-qa", label: "Agent QA", icon: Bot }, + { id: "multi-agent-qa", label: "Multi Agent", icon: Layers }, + { id: "sixstep-chat", label: "Six Step Chat", icon: Workflow }, + { id: "qa-records", label: "QA Records", icon: History }, + { id: "template-editor", label: "Template Config", icon: Settings }, + ], + }, + { + id: "light-app-center", + label: "Light Apps", + icon: Grid3X3, + children: [ + { id: "light-app-square", label: "App Square", icon: Layout }, + { id: "light-app-records", label: "Run Records", icon: History }, + ], + }, + { + id: "task-management", + label: "Task Management", + icon: Target, + children: [ + { id: "dashboard", label: "Dashboard", icon: BarChart3 }, + { + id: "xk-task", + label: "XK Tasks", + icon: Folder, + children: [ + { id: "xk-task-jc", label: "Task JC", icon: ListTodo }, + { id: "xk-task-dispatch", label: "Task Dispatch", icon: ListTodo }, + ], + }, + { + id: "plan-task", + label: "Planning Tasks", + icon: Folder, + children: [ + { id: "plan-task-fx", label: "Task Analysis", icon: ListTodo }, + { id: "plan-task-action", label: "Action Strategy", icon: ListTodo }, + ], + }, + { + id: "mnty-task", + label: "MNTY Tasks", + icon: Folder, + children: [ + { id: "mnty-task-mechanism", label: "Mechanism Study", icon: ListTodo }, + { id: "mnty-task-plan", label: "Plan Task", icon: ListTodo }, + { id: "mnty-task-zsty", label: "ZSTY Task", icon: ListTodo }, + ], + }, + { + id: "effect-task", + label: "Effect PG Tasks", + icon: Folder, + children: [ + { id: "effect-task-pg", label: "Task PG", icon: ListTodo }, + { id: "effect-action-pg", label: "Action PG", icon: ListTodo }, + { id: "effect-info-pg", label: "Info PG", icon: ListTodo }, + { id: "effect-account-pg", label: "Account PG", icon: ListTodo }, + ], + }, + { id: "task-create", label: "Create Task", icon: Plus }, + { id: "task-single", label: "Single Agent Task", icon: Bot }, + { id: "task-scene", label: "Scene Task", icon: Workflow }, + { id: "task-consult-create", label: "Multi Agent Consult", icon: MessageSquare }, + { id: "final-plan", label: "Final Output", icon: FileOutput }, + ], + }, + { id: "scene-list", label: "Scene Management", icon: Layers }, + { + id: "agent-list", + label: "Agent Management", + icon: Bot, + children: [ + { id: "agent-overview", label: "Agent List", icon: Users }, + { id: "agent-trial", label: "Single Agent Trial", icon: PlayCircle }, + ], + }, + { + id: "result-management", + label: "Result Management", + icon: BarChart3, + children: [ + { + id: "result-planning", + label: "Planning Results", + icon: Target, + children: [ + { id: "result-planning-all", label: "All", icon: BarChart3 }, + { id: "result-planning-goal", label: "Goal Analysis", icon: Target }, + { id: "result-planning-brand", label: "Brand Strategy", icon: Target }, + { id: "result-planning-content", label: "Content Planning", icon: Target }, + { id: "result-planning-channel", label: "Channel Planning", icon: Target }, + { id: "result-planning-narrative", label: "Narrative Strategy", icon: Target }, + ], + }, + { + id: "result-mnty", + label: "MNTY Results", + icon: Brain, + children: [ + { id: "result-mnty-all", label: "All", icon: BarChart3 }, + { id: "result-mnty-mechanism", label: "Mechanism Research", icon: Brain }, + { id: "result-mnty-plan", label: "Plan Design", icon: Brain }, + { id: "result-mnty-zsty", label: "ZSTY Analysis", icon: Brain }, + ], + }, + { + id: "result-effect-pg", + label: "Effect PG Results", + icon: TrendingUp, + children: [ + { id: "result-effect-pg-all", label: "All", icon: BarChart3 }, + { id: "result-effect-pg-behavior", label: "Behavior PG", icon: TrendingUp }, + { id: "result-effect-pg-evaluation", label: "Effect Review", icon: TrendingUp }, + { id: "result-effect-pg-info", label: "Info PG", icon: TrendingUp }, + { id: "result-effect-pg-account", label: "Account PG", icon: TrendingUp }, + ], + }, + { + id: "result-xk", + label: "XK Results", + icon: Compass, + children: [ + { id: "result-xk-all", label: "All", icon: BarChart3 }, + { id: "result-xk-jc", label: "Task JC", icon: Compass }, + { id: "result-xk-dispatch", label: "Task Dispatch", icon: Compass }, + ], + }, + { + id: "result-dq", + label: "DQ Results", + icon: Database, + children: [ + { id: "result-dq-all", label: "All", icon: BarChart3 }, + { id: "result-dq-audience", label: "Audience Analysis", icon: Database }, + { id: "result-dq-kb", label: "Knowledge Research", icon: Database }, + { id: "result-dq-trend", label: "Trend Research", icon: Database }, + ], + }, + { + id: "result-other", + label: "Other Results", + icon: MoreHorizontal, + children: [ + { id: "result-other-all", label: "All", icon: BarChart3 }, + { id: "result-other-general", label: "General Analysis", icon: MoreHorizontal }, + { id: "result-other-temp", label: "Temp Tasks", icon: MoreHorizontal }, + { id: "result-other-other", label: "Other", icon: MoreHorizontal }, + ], + }, + ], + }, + { + id: "resource-management", + label: "Resource Management", + icon: Database, + children: [ + { id: "resource-zz", label: "ZZ Resources", icon: FileBox }, + { id: "resource-network-actor", label: "Network Actor", icon: Network }, + { id: "resource-knowledge-base", label: "Knowledge Base", icon: Library }, + { id: "resource-evaluation-index", label: "Evaluation Index", icon: Scale }, + ], + }, +]; + +const defaultExpandedIds = new Set([ + "qa-center", + "task-management", + "xk-task", + "result-management", + "result-planning", +]); + export function PageSidebar({ collapsed, onToggleCollapsed, }: PageSidebarProps) { - const location = useLocation(); + const [expandedIds, setExpandedIds] = useState>(defaultExpandedIds); const iconButtonClass = - "rounded-lg p-2 text-gray-500 transition-all duration-200 hover:bg-red-50 hover:text-red-600"; + "rounded-lg p-2 text-gray-500 transition-all duration-300 ease-out hover:scale-105 hover:bg-red-50 hover:text-red-600"; + const panelClass = "ml-4 space-y-1 border-l border-red-100 pl-4"; + const labelClass = (compact: boolean, small = false) => + `overflow-hidden whitespace-nowrap transition-all duration-300 ease-out ${ + compact ? "max-w-0 opacity-0" : "max-w-[220px] opacity-100" + } ${small ? "text-xs" : "text-sm"} flex-1 font-medium`; + + const toggleExpanded = (id: string) => { + setExpandedIds((prev) => { + const next = new Set(prev); + if (next.has(id)) { + next.delete(id); + } else { + next.add(id); + } + return next; + }); + }; + + const renderLeaf = (item: MenuItem, depth = 0) => { + const Icon = item.icon; + + return ( + + ); + }; + + const renderBranch = (item: MenuItem, depth = 0) => { + const expanded = expandedIds.has(item.id); + const isTopLevel = depth === 0; + const Icon = depth > 0 && item.icon === Folder && expanded ? FolderOpen : item.icon; + + return ( +
+ + + {(!collapsed || !isTopLevel) && item.children && ( +
+ {item.children.map((child) => + child.children ? renderBranch(child, depth + 1) : renderLeaf(child, depth + 1), + )} +
+ )} +
+ ); + }; return (