@@ -22,7 +22,7 @@ import {
2222} from "lucide-react" ;
2323import type { MenuProps } from "antd" ;
2424import { useAuth } from "@/hooks/useAuth" ;
25- import { HEADER_CONFIG , FOOTER_CONFIG } from "@/const/layoutConstants" ;
25+ import { HEADER_CONFIG , FOOTER_CONFIG , SIDER_CONFIG } from "@/const/layoutConstants" ;
2626
2727const { Sider } = Layout ;
2828
@@ -75,10 +75,6 @@ export function SideNavigation({
7575 const pathname = usePathname ( ) ;
7676 const [ collapsed , setCollapsed ] = useState ( false ) ;
7777 const [ selectedKey , setSelectedKey ] = useState ( "0" ) ;
78- const expandedWidth = 277 ;
79- const collapsedWidth = 64 ;
80- const siderWidth = collapsed ? collapsedWidth : expandedWidth ;
81-
8278 // Update selected key when pathname or currentView changes
8379 useEffect ( ( ) => {
8480 // If we have a currentView from parent, use it to determine the key
@@ -105,197 +101,61 @@ export function SideNavigation({
105101 }
106102 } , [ pathname , currentView ] ) ;
107103
104+ // Helper function to create menu item with consistent icon styling
105+ const createMenuItem = ( key : string , Icon : any , labelKey : string , view : string , requiresAuth = false , requiresAdmin = false ) => ( {
106+ key,
107+ icon : < Icon className = "w-4 h-4" /> ,
108+ label : t ( labelKey ) ,
109+ onClick : ( ) => {
110+ if ( ! isSpeedMode && requiresAdmin && user ?. role !== "admin" ) {
111+ onAdminRequired ?.( ) ;
112+ } else if ( ! isSpeedMode && requiresAuth && ! user ) {
113+ onAuthRequired ?.( ) ;
114+ } else {
115+ onViewChange ?.( view ) ;
116+ }
117+ } ,
118+ } ) ;
119+
108120 // Menu items configuration
109121 const menuItems : MenuProps [ "items" ] = [
110- {
111- key : "0" ,
112- icon : < Home className = "h-4 w-4" /> ,
113- label : t ( "sidebar.homePage" ) ,
114- onClick : ( ) => {
115- onViewChange ?.( "home" ) ;
116- } ,
117- } ,
118- {
119- key : "1" ,
120- icon : < Bot className = "h-4 w-4" /> ,
121- label : t ( "sidebar.startChat" ) ,
122- onClick : ( ) => {
123- if ( ! isSpeedMode && ! user ) {
124- onAuthRequired ?.( ) ;
125- } else {
126- onViewChange ?.( "chat" ) ;
127- }
128- } ,
129- } ,
130- {
131- key : "2" ,
132- icon : < Zap className = "h-4 w-4" /> ,
133- label : t ( "sidebar.quickConfig" ) ,
134- onClick : ( ) => {
135- if ( ! isSpeedMode && user ?. role !== "admin" ) {
136- onAdminRequired ?.( ) ;
137- } else {
138- onViewChange ?.( "setup" ) ;
139- }
140- } ,
141- } ,
142- {
143- key : "3" ,
144- icon : < Globe className = "h-4 w-4" /> ,
145- label : t ( "sidebar.agentSpace" ) ,
146- onClick : ( ) => {
147- if ( ! isSpeedMode && ! user ) {
148- onAuthRequired ?.( ) ;
149- } else {
150- onViewChange ?.( "space" ) ;
151- }
152- } ,
153- } ,
154- {
155- key : "4" ,
156- icon : < ShoppingBag className = "h-4 w-4" /> ,
157- label : t ( "sidebar.agentMarket" ) ,
158- onClick : ( ) => {
159- if ( ! isSpeedMode && ! user ) {
160- onAuthRequired ?.( ) ;
161- } else {
162- onViewChange ?.( "market" ) ;
163- }
164- } ,
165- } ,
166- {
167- key : "5" ,
168- icon : < Code className = "h-4 w-4" /> ,
169- label : t ( "sidebar.agentDev" ) ,
170- onClick : ( ) => {
171- if ( ! isSpeedMode && user ?. role !== "admin" ) {
172- onAdminRequired ?.( ) ;
173- } else {
174- onViewChange ?.( "agents" ) ;
175- }
176- } ,
177- } ,
178- {
179- key : "6" ,
180- icon : < BookOpen className = "h-4 w-4" /> ,
181- label : t ( "sidebar.knowledgeBase" ) ,
182- onClick : ( ) => {
183- if ( ! isSpeedMode && ! user ) {
184- onAuthRequired ?.( ) ;
185- } else {
186- onViewChange ?.( "knowledges" ) ;
187- }
188- } ,
189- } ,
190- {
191- key : "10" ,
192- icon : < Puzzle className = "h-4 w-4" /> ,
193- label : t ( "sidebar.mcpToolsManagement" ) ,
194- onClick : ( ) => {
195- if ( ! isSpeedMode && user ?. role !== "admin" ) {
196- onAdminRequired ?.( ) ;
197- } else {
198- onViewChange ?.( "mcpTools" ) ;
199- }
200- } ,
201- } ,
202- {
203- key : "11" ,
204- icon : < Activity className = "h-4 w-4" /> ,
205- label : t ( "sidebar.monitoringManagement" ) ,
206- onClick : ( ) => {
207- if ( ! isSpeedMode && user ?. role !== "admin" ) {
208- onAdminRequired ?.( ) ;
209- } else {
210- onViewChange ?.( "monitoring" ) ;
211- }
212- } ,
213- } ,
214- {
215- key : "7" ,
216- icon : < Settings className = "h-4 w-4" /> ,
217- label : t ( "sidebar.modelManagement" ) ,
218- onClick : ( ) => {
219- if ( ! isSpeedMode && user ?. role !== "admin" ) {
220- onAdminRequired ?.( ) ;
221- } else {
222- onViewChange ?.( "models" ) ;
223- }
224- } ,
225- } ,
226- {
227- key : "8" ,
228- icon : < Database className = "h-4 w-4" /> ,
229- label : t ( "sidebar.memoryManagement" ) ,
230- onClick : ( ) => {
231- if ( ! isSpeedMode && user ?. role !== "admin" ) {
232- onAdminRequired ?.( ) ;
233- } else {
234- onViewChange ?.( "memory" ) ;
235- }
236- } ,
237- } ,
238- {
239- key : "9" ,
240- icon : < Users className = "h-4 w-4" /> ,
241- label : t ( "sidebar.userManagement" ) ,
242- onClick : ( ) => {
243- if ( ! isSpeedMode && user ?. role !== "admin" ) {
244- onAdminRequired ?.( ) ;
245- } else {
246- onViewChange ?.( "users" ) ;
247- }
248- } ,
249- } ,
122+ createMenuItem ( "0" , Home , "sidebar.homePage" , "home" ) ,
123+ createMenuItem ( "1" , Bot , "sidebar.startChat" , "chat" , true ) ,
124+ createMenuItem ( "2" , Zap , "sidebar.quickConfig" , "setup" , false , true ) ,
125+ createMenuItem ( "3" , Globe , "sidebar.agentSpace" , "space" , true ) ,
126+ createMenuItem ( "4" , ShoppingBag , "sidebar.agentMarket" , "market" , true ) ,
127+ createMenuItem ( "5" , Code , "sidebar.agentDev" , "agents" , false , true ) ,
128+ createMenuItem ( "6" , BookOpen , "sidebar.knowledgeBase" , "knowledges" , true ) ,
129+ createMenuItem ( "10" , Puzzle , "sidebar.mcpToolsManagement" , "mcpTools" , false , true ) ,
130+ createMenuItem ( "11" , Activity , "sidebar.monitoringManagement" , "monitoring" , false , true ) ,
131+ createMenuItem ( "7" , Settings , "sidebar.modelManagement" , "models" , false , true ) ,
132+ createMenuItem ( "8" , Database , "sidebar.memoryManagement" , "memory" , false , true ) ,
133+ createMenuItem ( "9" , Users , "sidebar.userManagement" , "users" , false , true ) ,
250134 ] ;
251135
252- // Calculate sidebar height dynamically based on header and footer reserved heights
253- const headerReservedHeight = parseInt ( HEADER_CONFIG . RESERVED_HEIGHT ) ;
254- const footerReservedHeight = parseInt ( FOOTER_CONFIG . RESERVED_HEIGHT ) ;
255- const sidebarHeight = `calc(100vh - ${ headerReservedHeight } px - ${ footerReservedHeight } px)` ;
256- const sidebarTop = `${ headerReservedHeight } px` ;
136+ // Calculate sidebar height and position dynamically
137+ const sidebarHeight = `calc(100vh - ${ HEADER_CONFIG . RESERVED_HEIGHT } - ${ FOOTER_CONFIG . RESERVED_HEIGHT } )` ;
138+ const sidebarTop = HEADER_CONFIG . RESERVED_HEIGHT ;
257139
258140 return (
259- < ConfigProvider
260- theme = { {
261- components : {
262- Layout : {
263- siderBg : "rgba(255, 255, 255, 0.95)" ,
264- } ,
265- Menu : {
266- itemBg : "transparent" ,
267- itemSelectedBg : "#e6f4ff" ,
268- itemSelectedColor : "#1677ff" ,
269- itemHoverBg : "#f5f5f5" ,
270- itemHoverColor : "#1677ff" ,
271- itemActiveBg : "#e6f4ff" ,
272- itemColor : "#334155" ,
273- iconSize : 16 ,
274- itemBorderRadius : 6 ,
275- itemMarginInline : 6 ,
276- itemPaddingInline : 12 ,
277- itemHeight : 36 ,
278- } ,
279- } ,
280- } }
281- >
282- < div style = { { position : "relative" } } >
283- < div style = { { width : `${ siderWidth } px` , flexShrink : 0 } } >
141+ < ConfigProvider >
142+ < div className = "relative" >
143+ < div
144+ className = "flex-shrink-0"
145+ style = { {
146+ width : collapsed ? SIDER_CONFIG . COLLAPSED_WIDTH : SIDER_CONFIG . EXPANDED_WIDTH
147+ } }
148+ >
284149 < Sider
285150 collapsed = { collapsed }
286151 trigger = { null }
287152 breakpoint = "lg"
288- collapsedWidth = { collapsedWidth }
289- width = { expandedWidth }
290- className = "! bg-white/95 dark:! bg-slate-900/95 border-r border-slate-200 dark:border-slate-700 backdrop-blur-sm shadow-sm"
153+ collapsedWidth = { SIDER_CONFIG . COLLAPSED_WIDTH }
154+ width = { SIDER_CONFIG . EXPANDED_WIDTH }
155+ className = "fixed left-0 bg-white/95 dark:bg-slate-900/95 border-r border-slate-200 dark:border-slate-700 backdrop-blur-sm shadow-sm"
291156 style = { {
292- overflow : "auto" ,
293- minHeight : sidebarHeight ,
294157 height : sidebarHeight ,
295- position : "fixed" ,
296158 top : sidebarTop ,
297- left : 0 ,
298- width : `${ siderWidth } px` ,
299159 } }
300160 >
301161 < div className = "py-2 h-full" >
@@ -304,11 +164,7 @@ export function SideNavigation({
304164 selectedKeys = { [ selectedKey ] }
305165 items = { menuItems }
306166 onClick = { ( { key } ) => setSelectedKey ( key ) }
307- className = "!bg-transparent !border-r-0"
308- style = { {
309- height : "100%" ,
310- borderRight : 0 ,
311- } }
167+ className = "bg-transparent border-r-0 h-full"
312168 />
313169 </ div >
314170 </ Sider >
@@ -320,30 +176,14 @@ export function SideNavigation({
320176 shape = "circle"
321177 size = "small"
322178 onClick = { ( ) => setCollapsed ( ! collapsed ) }
323- className = "shadow-md hover:shadow-lg transition-all"
179+ className = "fixed top-1/2 -translate-y-1/2 w-6 h-6 min-w-6 p-0 border-2 border-white shadow-md hover:shadow-lg transition-all z-[800] "
324180 style = { {
325- position : "fixed" ,
326- left : collapsed ? "52px" : "264px" ,
327- top : "50vh" ,
328- transform : "translateY(-50%)" ,
329- width : "24px" ,
330- height : "24px" ,
331- minWidth : "24px" ,
332- padding : 0 ,
333- display : "flex" ,
334- alignItems : "center" ,
335- justifyContent : "center" ,
336- border : "2px solid white" ,
337- zIndex : 800 ,
181+ left : collapsed
182+ ? `${ SIDER_CONFIG . COLLAPSED_WIDTH - 12 } px`
183+ : `${ SIDER_CONFIG . EXPANDED_WIDTH - 13 } px` ,
338184 transition : "left 0.2s ease" ,
339185 } }
340- icon = {
341- collapsed ? (
342- < ChevronRight className = "h-3 w-3" />
343- ) : (
344- < ChevronLeft className = "h-3 w-3" />
345- )
346- }
186+ icon = { collapsed ? < ChevronRight className = "w-3 h-3" /> : < ChevronLeft className = "w-3 h-3" /> }
347187 />
348188 </ div >
349189 </ ConfigProvider >
0 commit comments