@@ -2,6 +2,7 @@ import { ChevronLeft, Menu } from "@mui/icons-material";
2
2
import {
3
3
Backdrop ,
4
4
Box ,
5
+ Chip ,
5
6
CssBaseline ,
6
7
Divider ,
7
8
IconButton ,
@@ -22,16 +23,23 @@ import { Outlet, useNavigate } from "react-router-dom";
22
23
23
24
import { MiniVariantAppBar , MiniVariantDrawer } from "./sidebar" ;
24
25
25
- export type RouteDef = {
26
- icon : typeof SvgIcon ;
27
- title : string ;
28
- app : string ;
29
- resource : string ;
30
- route ?: string ; // If specified, this will be used as the route instead of the default one
31
- isAdminPage ?: boolean ;
32
- hideOnSidebar ?: boolean ;
33
- placeOnBottom ?: boolean ;
34
- } ;
26
+ export type RouteDef =
27
+ | {
28
+ type : "routeDefinition" ;
29
+ key : string ; // Unique key for the route
30
+ icon : typeof SvgIcon ;
31
+ title : string ;
32
+ app : string ;
33
+ resource : string ;
34
+ route ?: string ; // If specified, this will be used as the route instead of the default one
35
+ hideOnSidebar ?: boolean ;
36
+ placeOnBottom ?: boolean ;
37
+ }
38
+ | {
39
+ type : "separator" ;
40
+ key : string ; // Unique key for the route
41
+ title : string ;
42
+ } ;
35
43
36
44
type LayoutState = {
37
45
showDrawer : boolean ;
@@ -65,35 +73,61 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
65
73
const toggleDrawer = ( ) =>
66
74
dispatch ( ( ps ) => ( { ...ps , showDrawer : ! ps . showDrawer } ) ) ;
67
75
68
- const SidebarItem : React . FC < { routeInfo : RouteDef } > = ( { routeInfo } ) => (
69
- < ListItem
70
- key = { `${ routeInfo . app } -${ routeInfo . resource } ` }
71
- sx = { routeInfo . placeOnBottom ? { marginTop : "auto" } : { } }
72
- disablePadding
73
- >
74
- < ListItemButton
75
- sx = { {
76
- minHeight : 48 ,
77
- px : 2.5 ,
78
- justifyContent : state . showDrawer ? "initial" : "center" ,
79
- } }
80
- onClick = { ( ) =>
81
- navigate ( routeInfo . route || `/${ routeInfo . app } /${ routeInfo . resource } ` )
82
- }
76
+ const SidebarItem : React . FC < { routeInfo : RouteDef } > = ( { routeInfo } ) =>
77
+ routeInfo . type === "separator" ? (
78
+ < ListItem key = { routeInfo . title } disablePadding sx = { { minHeight : 48 } } >
79
+ { state . showDrawer ? (
80
+ < ListItemButton disabled >
81
+ < ListItemText primary = { routeInfo . title } />
82
+ </ ListItemButton >
83
+ ) : (
84
+ < Stack
85
+ alignItems = "center"
86
+ sx = { ( t ) => ( {
87
+ width : t . spacing ( 7 ) ,
88
+ [ t . breakpoints . up ( "sm" ) ] : { width : t . spacing ( 8 ) } ,
89
+ } ) }
90
+ >
91
+ < Chip
92
+ label = { routeInfo . title }
93
+ variant = "outlined"
94
+ size = "small"
95
+ sx = { { flexGrow : 0 } }
96
+ />
97
+ </ Stack >
98
+ ) }
99
+ </ ListItem >
100
+ ) : (
101
+ < ListItem
102
+ key = { `${ routeInfo . app } -${ routeInfo . resource } ` }
103
+ sx = { routeInfo . placeOnBottom ? { marginTop : "auto" } : { } }
104
+ disablePadding
83
105
>
84
- < ListItemIcon
106
+ < ListItemButton
85
107
sx = { {
86
- minWidth : 0 ,
87
- justifyContent : "center" ,
88
- mr : state . showDrawer ? 3 : "auto " ,
108
+ minHeight : 48 ,
109
+ px : 2.5 ,
110
+ justifyContent : state . showDrawer ? "initial" : "center " ,
89
111
} }
112
+ onClick = { ( ) =>
113
+ navigate (
114
+ routeInfo . route || `/${ routeInfo . app } /${ routeInfo . resource } `
115
+ )
116
+ }
90
117
>
91
- < routeInfo . icon />
92
- </ ListItemIcon >
93
- { state . showDrawer && < ListItemText primary = { routeInfo . title } /> }
94
- </ ListItemButton >
95
- </ ListItem >
96
- ) ;
118
+ < ListItemIcon
119
+ sx = { {
120
+ minWidth : 0 ,
121
+ justifyContent : "center" ,
122
+ mr : state . showDrawer ? 3 : "auto" ,
123
+ } }
124
+ >
125
+ < routeInfo . icon />
126
+ </ ListItemIcon >
127
+ { state . showDrawer && < ListItemText primary = { routeInfo . title } /> }
128
+ </ ListItemButton >
129
+ </ ListItem >
130
+ ) ;
97
131
98
132
const menuButtonStyle : ( t : Theme ) => React . CSSProperties = ( t ) => ( {
99
133
width : `calc(${ t . spacing ( 7 ) } + 1px)` ,
@@ -152,9 +186,9 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
152
186
< Divider />
153
187
< Stack sx = { { height : "100%" } } >
154
188
{ routes
155
- . filter ( ( r ) => ! r . hideOnSidebar )
189
+ . filter ( ( r ) => r . type === "separator" || ! r . hideOnSidebar )
156
190
. map ( ( r ) => (
157
- < SidebarItem key = { ` ${ r . app } - ${ r . resource } ` } routeInfo = { r } />
191
+ < SidebarItem key = { r . key } routeInfo = { r } />
158
192
) ) }
159
193
</ Stack >
160
194
</ MiniVariantDrawer >
0 commit comments