1
1
import { ChevronLeft , Menu } from "@mui/icons-material" ;
2
2
import {
3
+ Backdrop ,
3
4
Box ,
5
+ Chip ,
4
6
CssBaseline ,
5
7
Divider ,
6
8
IconButton ,
@@ -21,16 +23,23 @@ import { Outlet, useNavigate } from "react-router-dom";
21
23
22
24
import { MiniVariantAppBar , MiniVariantDrawer } from "./sidebar" ;
23
25
24
- export type RouteDef = {
25
- icon : typeof SvgIcon ;
26
- title : string ;
27
- app : string ;
28
- resource : string ;
29
- route ?: string ; // If specified, this will be used as the route instead of the default one
30
- isAdminPage ?: boolean ;
31
- hideOnSidebar ?: boolean ;
32
- placeOnBottom ?: boolean ;
33
- } ;
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
+ } ;
34
43
35
44
type LayoutState = {
36
45
showDrawer : boolean ;
@@ -64,35 +73,61 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
64
73
const toggleDrawer = ( ) =>
65
74
dispatch ( ( ps ) => ( { ...ps , showDrawer : ! ps . showDrawer } ) ) ;
66
75
67
- const SidebarItem : React . FC < { routeInfo : RouteDef } > = ( { routeInfo } ) => (
68
- < ListItem
69
- key = { `${ routeInfo . app } -${ routeInfo . resource } ` }
70
- sx = { routeInfo . placeOnBottom ? { marginTop : "auto" } : { } }
71
- disablePadding
72
- >
73
- < ListItemButton
74
- sx = { {
75
- minHeight : 48 ,
76
- px : 2.5 ,
77
- justifyContent : state . showDrawer ? "initial" : "center" ,
78
- } }
79
- onClick = { ( ) =>
80
- navigate ( routeInfo . route || `/${ routeInfo . app } /${ routeInfo . resource } ` )
81
- }
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
82
105
>
83
- < ListItemIcon
106
+ < ListItemButton
84
107
sx = { {
85
- minWidth : 0 ,
86
- justifyContent : "center" ,
87
- mr : state . showDrawer ? 3 : "auto " ,
108
+ minHeight : 48 ,
109
+ px : 2.5 ,
110
+ justifyContent : state . showDrawer ? "initial" : "center " ,
88
111
} }
112
+ onClick = { ( ) =>
113
+ navigate (
114
+ routeInfo . route || `/${ routeInfo . app } /${ routeInfo . resource } `
115
+ )
116
+ }
89
117
>
90
- < routeInfo . icon />
91
- </ ListItemIcon >
92
- { state . showDrawer && < ListItemText primary = { routeInfo . title } /> }
93
- </ ListItemButton >
94
- </ ListItem >
95
- ) ;
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
+ ) ;
96
131
97
132
const menuButtonStyle : ( t : Theme ) => React . CSSProperties = ( t ) => ( {
98
133
width : `calc(${ t . spacing ( 7 ) } + 1px)` ,
@@ -151,9 +186,9 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
151
186
< Divider />
152
187
< Stack sx = { { height : "100%" } } >
153
188
{ routes
154
- . filter ( ( r ) => ! r . hideOnSidebar )
189
+ . filter ( ( r ) => r . type === "separator" || ! r . hideOnSidebar )
155
190
. map ( ( r ) => (
156
- < SidebarItem key = { ` ${ r . app } - ${ r . resource } ` } routeInfo = { r } />
191
+ < SidebarItem key = { r . key } routeInfo = { r } />
157
192
) ) }
158
193
</ Stack >
159
194
</ MiniVariantDrawer >
@@ -163,6 +198,7 @@ export const Layout: React.FC<{ routes: RouteDef[] }> = ({ routes }) => {
163
198
< Outlet />
164
199
</ PageInnerContainer >
165
200
</ PageOuterContainer >
201
+ < Backdrop open = { state . showDrawer } onClick = { toggleDrawer } />
166
202
</ Box >
167
203
</ Box >
168
204
) ;
0 commit comments