@@ -3,19 +3,74 @@ import { Button, Menu } from "antd";
33import {
44 CloseOutlined ,
55 MenuOutlined ,
6- OrderedListOutlined ,
76 SettingOutlined ,
87} from "@ant-design/icons" ;
9- import { Sparkles , X , Menu as MenuIcon } from "lucide-react" ;
8+ import { ClipboardList , Sparkles } from "lucide-react" ;
109import { antMenuItems , antMenuItems as items } from "@/pages/Layout/menu" ;
11- import TaskPopover from "../../components/TaskPopover" ;
1210import { NavLink , useLocation , useNavigate } from "react-router" ;
11+ import TaskUpload from "./TaskUpload" ;
12+
13+ const TaskUploadPopover = ( { sidebarOpen, toggleShowTaskPopover } ) => {
14+ const arrowStyle = sidebarOpen ? { } : { top : "calc(100% - 68px)" } ;
15+ const popoverStyle = sidebarOpen
16+ ? {
17+ bottom : "48px" ,
18+ left : "0px" ,
19+ }
20+ : {
21+ bottom : "-48px" ,
22+ left : "68px" ,
23+ } ;
24+
25+ return (
26+ < div
27+ id = "header-task-popover"
28+ className = { `absolute left-full w-md transition-all duration-300 ease-in-out z-50 opacity-0 invisible transform -translate-x-4` }
29+ style = { popoverStyle }
30+ >
31+ { /* 箭头 - 指向按钮中心 */ }
32+ { /* <div
33+ className="absolute -left-2 w-0 h-0 transform -translate-y-1/2"
34+ style={{
35+ borderTop: "8px solid transparent",
36+ borderBottom: "8px solid transparent",
37+ borderRight: "8px solid #e5e7eb",
38+ ...arrowStyle,
39+ }}
40+ />
41+ <div
42+ className="absolute -left-1.5 top-1/2 w-0 h-0 transform -translate-y-1/2"
43+ style={{
44+ borderTop: "8px solid transparent",
45+ borderBottom: "8px solid transparent",
46+ borderRight: "8px solid white",
47+ ...arrowStyle,
48+ }}
49+ /> */ }
50+ < div className = "bg-white rounded-lg shadow-lg border border-gray-200 min-w-80" >
51+ < div className = "flex justify-between items-center p-3 border-b border-gray-100" >
52+ < span className = "text-sm font-medium text-gray-900" > 任务中心</ span >
53+ < Button
54+ type = "text"
55+ size = "small"
56+ icon = { < CloseOutlined /> }
57+ onClick = { ( ) => toggleShowTaskPopover ( false ) }
58+ />
59+ </ div >
60+ < div className = "p-0 h-[250px] overflow-y-auto" >
61+ < TaskUpload />
62+ </ div >
63+ </ div >
64+ </ div >
65+ ) ;
66+ } ;
1367
1468const AsiderAndHeaderLayout = ( ) => {
1569 const { pathname } = useLocation ( ) ;
1670 const navigate = useNavigate ( ) ;
1771 const [ activeItem , setActiveItem ] = useState < string > ( "management" ) ;
1872 const [ sidebarOpen , setSidebarOpen ] = useState ( true ) ;
73+ const [ taskCenterVisible , setTaskCenterVisible ] = useState ( false ) ;
1974
2075 // Initialize active item based on current pathname
2176 const initActiveItem = ( ) => {
@@ -39,11 +94,22 @@ const AsiderAndHeaderLayout = () => {
3994 initActiveItem ( ) ;
4095 } , [ pathname ] ) ;
4196
97+ const toggleShowTaskPopover = ( show : boolean = true ) => {
98+ const taskEl = document . getElementById ( "header-task-popover" ) ;
99+ if ( show && ! taskEl ?. classList . contains ( "show-task-popover" ) ) {
100+ taskEl ?. classList ?. add ( "show-task-popover" ) ;
101+ return ;
102+ }
103+ if ( ! show && taskEl ?. classList . contains ( "show-task-popover" ) ) {
104+ taskEl ?. classList ?. remove ( "show-task-popover" ) ;
105+ }
106+ } ;
107+
42108 return (
43109 < div
44110 className = { `${
45111 sidebarOpen ? "w-64" : "w-20"
46- } bg-white border-r border-gray-200 transition-all duration-300 flex flex-col`}
112+ } bg-white border-r border-gray-200 transition-all duration-300 flex flex-col relative `}
47113 >
48114 { /* Header */ }
49115 < div className = "flex items-center justify-between p-4 border-b border-gray-200" >
@@ -55,12 +121,11 @@ const AsiderAndHeaderLayout = () => {
55121 < span className = "text-lg font-bold text-gray-900" > ModelEngine</ span >
56122 </ NavLink >
57123 ) }
58- < span className = "cursor-pointer hover:text-blue-500" onClick = { ( ) => setSidebarOpen ( ! sidebarOpen ) } >
59- { sidebarOpen ? (
60- < CloseOutlined />
61- ) : (
62- < MenuOutlined className = "ml-4" />
63- ) }
124+ < span
125+ className = "cursor-pointer hover:text-blue-500"
126+ onClick = { ( ) => setSidebarOpen ( ! sidebarOpen ) }
127+ >
128+ { sidebarOpen ? < CloseOutlined /> : < MenuOutlined className = "ml-4" /> }
64129 </ span >
65130 </ div >
66131
@@ -84,22 +149,51 @@ const AsiderAndHeaderLayout = () => {
84149 < div className = "p-4 border-t border-gray-200" >
85150 { sidebarOpen ? (
86151 < div className = "space-y-2" >
87- { /* <TaskPopover /> */ }
152+ < div className = "relative" >
153+ < Button block onClick = { ( ) => toggleShowTaskPopover ( true ) } >
154+ 任务中心
155+ </ Button >
156+ < TaskUploadPopover
157+ sidebarOpen = { sidebarOpen }
158+ toggleShowTaskPopover = { toggleShowTaskPopover }
159+ />
160+ </ div >
88161 < Button block onClick = { ( ) => navigate ( "/data/settings" ) } >
89162 设置
90163 </ Button >
91164 </ div >
92165 ) : (
93166 < div className = "space-y-2" >
94- < Button block >
95- < OrderedListOutlined />
96- </ Button >
167+ < div className = "relative" >
168+ < Button
169+ block
170+ onClick = { ( ) => toggleShowTaskPopover ( true ) }
171+ icon = { < ClipboardList className = "w-4 h-4" /> }
172+ > </ Button >
173+ < TaskUploadPopover
174+ sidebarOpen = { sidebarOpen }
175+ toggleShowTaskPopover = { toggleShowTaskPopover }
176+ />
177+ </ div >
97178 < Button block onClick = { ( ) => navigate ( "/data/settings" ) } >
98179 < SettingOutlined />
99180 </ Button >
100181 </ div >
101182 ) }
102183 </ div >
184+
185+ { /* 添加遮罩层,点击外部区域时关闭 */ }
186+ { taskCenterVisible && (
187+ < div
188+ className = "fixed inset-0 z-40"
189+ onClick = { ( ) => {
190+ console . log ( 'clicked outside' ) ;
191+
192+ setTaskCenterVisible ( false ) ;
193+ toggleShowTaskPopover ( false ) ;
194+ } }
195+ />
196+ ) }
103197 </ div >
104198 ) ;
105199} ;
0 commit comments