@@ -2,15 +2,13 @@ import Drawer from "@mui/material/Drawer";
2
2
import IconButton from "@mui/material/IconButton" ;
3
3
import List from "@mui/material/List" ;
4
4
import ListItem from "@mui/material/ListItem" ;
5
- import { makeStyles } from "@mui/styles" ;
6
5
import MenuIcon from "@mui/icons-material/Menu" ;
7
6
import { CoderIcon } from "components/Icons/CoderIcon" ;
8
- import { FC , useRef , useState } from "react" ;
7
+ import { type FC , type ReactNode , useRef , useState } from "react" ;
9
8
import { NavLink , useLocation , useNavigate } from "react-router-dom" ;
10
9
import { colors } from "theme/colors" ;
11
10
import * as TypesGen from "api/typesGenerated" ;
12
11
import { navHeight } from "theme/constants" ;
13
- import { combineClasses } from "utils/combineClasses" ;
14
12
import { UserDropdown } from "./UserDropdown/UserDropdown" ;
15
13
import Box from "@mui/material/Box" ;
16
14
import Menu from "@mui/material/Menu" ;
@@ -25,6 +23,7 @@ import { BUTTON_SM_HEIGHT } from "theme/theme";
25
23
import { ProxyStatusLatency } from "components/ProxyStatusLatency/ProxyStatusLatency" ;
26
24
import { usePermissions } from "hooks/usePermissions" ;
27
25
import Typography from "@mui/material/Typography" ;
26
+ import { css , type Interpolation , type Theme , useTheme } from "@emotion/react" ;
28
27
29
28
export const USERS_LINK = `/users?filter=${ encodeURIComponent (
30
29
"status:active" ,
@@ -50,52 +49,128 @@ export const Language = {
50
49
deployment : "Deployment" ,
51
50
} ;
52
51
53
- const NavItems : React . FC <
54
- React . PropsWithChildren < {
55
- className ?: string ;
56
- canViewAuditLog : boolean ;
57
- canViewDeployment : boolean ;
58
- canViewAllUsers : boolean ;
59
- } >
60
- > = ( { className, canViewAuditLog, canViewDeployment, canViewAllUsers } ) => {
61
- const styles = useStyles ( ) ;
52
+ const styles = {
53
+ desktopNavItems : ( theme ) => css `
54
+ display : none;
55
+
56
+ ${ theme . breakpoints . up ( "md" ) } {
57
+ display : flex;
58
+ }
59
+ ` ,
60
+ mobileMenuButton : ( theme ) => css `
61
+ ${ theme . breakpoints . up ( "md" ) } {
62
+ display : none;
63
+ }
64
+ ` ,
65
+ wrapper : ( theme ) => css `
66
+ position : relative;
67
+ display : flex;
68
+ justify-content : space-between;
69
+ align-items : center;
70
+
71
+ ${ theme . breakpoints . up ( "md" ) } {
72
+ justify-content : flex-start;
73
+ }
74
+ ` ,
75
+ drawerHeader : ( theme ) => ( {
76
+ padding : theme . spacing ( 2 ) ,
77
+ paddingTop : theme . spacing ( 4 ) ,
78
+ paddingBottom : theme . spacing ( 4 ) ,
79
+ } ) ,
80
+ logo : ( theme ) => css `
81
+ align-items : center;
82
+ display : flex;
83
+ height : ${ navHeight } px;
84
+ color : ${ theme . palette . text . primary } ;
85
+ padding : ${ theme . spacing ( 2 ) } ;
86
+
87
+ // svg is for the Coder logo, img is for custom images
88
+ & svg ,
89
+ & img {
90
+ height : 100% ;
91
+ object-fit : contain;
92
+ }
93
+ ` ,
94
+ drawerLogo : ( theme ) => ( {
95
+ padding : 0 ,
96
+ maxHeight : theme . spacing ( 5 ) ,
97
+ } ) ,
98
+ item : {
99
+ padding : 0 ,
100
+ } ,
101
+ link : ( theme ) => css `
102
+ align-items : center;
103
+ color : ${ colors . gray [ 6 ] } ;
104
+ display : flex;
105
+ flex : 1 ;
106
+ font-size : 16px ;
107
+ padding : ${ theme . spacing ( 1.5 ) } ${ theme . spacing ( 2 ) } ;
108
+ text-decoration : none;
109
+ transition : background-color 0.15s ease-in-out;
110
+
111
+ & : hover {
112
+ background-color : theme.palette.action.hover;
113
+ }
114
+
115
+ ${ theme . breakpoints . up ( "md" ) } {
116
+ height : ${ navHeight } ;
117
+ padding : 0 ${ theme . spacing ( 3 ) } ;
118
+ }
119
+ ` ,
120
+ } satisfies Record < string , Interpolation < Theme > > ;
121
+
122
+ interface NavItemsProps {
123
+ children ?: ReactNode ;
124
+ className ?: string ;
125
+ canViewAuditLog : boolean ;
126
+ canViewDeployment : boolean ;
127
+ canViewAllUsers : boolean ;
128
+ }
129
+
130
+ const NavItems : React . FC < NavItemsProps > = ( props ) => {
131
+ const { className, canViewAuditLog, canViewDeployment, canViewAllUsers } =
132
+ props ;
62
133
const location = useLocation ( ) ;
134
+ const theme = useTheme ( ) ;
63
135
64
136
return (
65
- < List className = { combineClasses ( [ styles . navItems , className ] ) } >
66
- < ListItem button className = { styles . item } >
137
+ < List css = { { padding : 0 } } className = { className } >
138
+ < ListItem button css = { styles . item } >
67
139
< NavLink
68
- className = { combineClasses ( [
140
+ css = { [
69
141
styles . link ,
70
- location . pathname . startsWith ( "/@" ) && "active" ,
71
- ] ) }
142
+ location . pathname . startsWith ( "/@" ) && {
143
+ color : theme . palette . text . primary ,
144
+ fontWeight : 500 ,
145
+ } ,
146
+ ] }
72
147
to = "/workspaces"
73
148
>
74
149
{ Language . workspaces }
75
150
</ NavLink >
76
151
</ ListItem >
77
- < ListItem button className = { styles . item } >
78
- < NavLink className = { styles . link } to = "/templates" >
152
+ < ListItem button css = { styles . item } >
153
+ < NavLink css = { styles . link } to = "/templates" >
79
154
{ Language . templates }
80
155
</ NavLink >
81
156
</ ListItem >
82
157
{ canViewAllUsers && (
83
- < ListItem button className = { styles . item } >
84
- < NavLink className = { styles . link } to = { USERS_LINK } >
158
+ < ListItem button css = { styles . item } >
159
+ < NavLink css = { styles . link } to = { USERS_LINK } >
85
160
{ Language . users }
86
161
</ NavLink >
87
162
</ ListItem >
88
163
) }
89
164
{ canViewAuditLog && (
90
- < ListItem button className = { styles . item } >
91
- < NavLink className = { styles . link } to = "/audit" >
165
+ < ListItem button css = { styles . item } >
166
+ < NavLink css = { styles . link } to = "/audit" >
92
167
{ Language . audit }
93
168
</ NavLink >
94
169
</ ListItem >
95
170
) }
96
171
{ canViewDeployment && (
97
- < ListItem button className = { styles . item } >
98
- < NavLink className = { styles . link } to = "/deployment/general" >
172
+ < ListItem button css = { styles . item } >
173
+ < NavLink css = { styles . link } to = "/deployment/general" >
99
174
{ Language . deployment }
100
175
</ NavLink >
101
176
</ ListItem >
@@ -114,15 +189,20 @@ export const NavbarView: FC<NavbarViewProps> = ({
114
189
canViewAllUsers,
115
190
proxyContextValue,
116
191
} ) => {
117
- const styles = useStyles ( ) ;
118
192
const [ isDrawerOpen , setIsDrawerOpen ] = useState ( false ) ;
119
193
120
194
return (
121
- < nav className = { styles . root } >
122
- < div className = { styles . wrapper } >
195
+ < nav
196
+ css = { ( theme ) => ( {
197
+ height : navHeight ,
198
+ background : theme . palette . background . paper ,
199
+ borderBottom : `1px solid ${ theme . palette . divider } ` ,
200
+ } ) }
201
+ >
202
+ < div css = { styles . wrapper } >
123
203
< IconButton
124
204
aria-label = "Open menu"
125
- className = { styles . mobileMenuButton }
205
+ css = { styles . mobileMenuButton }
126
206
onClick = { ( ) => {
127
207
setIsDrawerOpen ( true ) ;
128
208
} }
@@ -136,9 +216,9 @@ export const NavbarView: FC<NavbarViewProps> = ({
136
216
open = { isDrawerOpen }
137
217
onClose = { ( ) => setIsDrawerOpen ( false ) }
138
218
>
139
- < div className = { styles . drawer } >
140
- < div className = { styles . drawerHeader } >
141
- < div className = { combineClasses ( [ styles . logo , styles . drawerLogo ] ) } >
219
+ < div css = { { width : 250 } } >
220
+ < div css = { styles . drawerHeader } >
221
+ < div css = { [ styles . logo , styles . drawerLogo ] } >
142
222
{ logo_url ? (
143
223
< img src = { logo_url } alt = "Custom Logo" />
144
224
) : (
@@ -154,7 +234,7 @@ export const NavbarView: FC<NavbarViewProps> = ({
154
234
</ div >
155
235
</ Drawer >
156
236
157
- < NavLink className = { styles . logo } to = "/workspaces" >
237
+ < NavLink css = { styles . logo } to = "/workspaces" >
158
238
{ logo_url ? (
159
239
< img src = { logo_url } alt = "Custom Logo" />
160
240
) : (
@@ -163,7 +243,7 @@ export const NavbarView: FC<NavbarViewProps> = ({
163
243
</ NavLink >
164
244
165
245
< NavItems
166
- className = { styles . desktopNavItems }
246
+ css = { styles . desktopNavItems }
167
247
canViewAuditLog = { canViewAuditLog }
168
248
canViewDeployment = { canViewDeployment }
169
249
canViewAllUsers = { canViewAllUsers }
@@ -385,93 +465,3 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
385
465
</ >
386
466
) ;
387
467
} ;
388
-
389
- const useStyles = makeStyles ( ( theme ) => ( {
390
- displayInitial : {
391
- display : "initial" ,
392
- } ,
393
- root : {
394
- height : navHeight ,
395
- background : theme . palette . background . paper ,
396
- borderBottom : `1px solid ${ theme . palette . divider } ` ,
397
- } ,
398
- wrapper : {
399
- position : "relative" ,
400
- display : "flex" ,
401
- justifyContent : "space-between" ,
402
- alignItems : "center" ,
403
- [ theme . breakpoints . up ( "md" ) ] : {
404
- justifyContent : "flex-start" ,
405
- } ,
406
- } ,
407
- drawer : {
408
- width : 250 ,
409
- } ,
410
- drawerHeader : {
411
- padding : theme . spacing ( 2 ) ,
412
- paddingTop : theme . spacing ( 4 ) ,
413
- paddingBottom : theme . spacing ( 4 ) ,
414
- } ,
415
- navItems : {
416
- padding : 0 ,
417
- } ,
418
- desktopNavItems : {
419
- display : "none" ,
420
- [ theme . breakpoints . up ( "md" ) ] : {
421
- display : "flex" ,
422
- } ,
423
- } ,
424
- mobileMenuButton : {
425
- [ theme . breakpoints . up ( "md" ) ] : {
426
- display : "none" ,
427
- } ,
428
- } ,
429
- logo : {
430
- alignItems : "center" ,
431
- display : "flex" ,
432
- height : navHeight ,
433
- color : theme . palette . text . primary ,
434
- padding : theme . spacing ( 2 ) ,
435
- // svg is for the Coder logo, img is for custom images
436
- "& svg, & img" : {
437
- height : "100%" ,
438
- objectFit : "contain" ,
439
- } ,
440
- } ,
441
- drawerLogo : {
442
- padding : 0 ,
443
- maxHeight : theme . spacing ( 5 ) ,
444
- } ,
445
- title : {
446
- flex : 1 ,
447
- textAlign : "center" ,
448
- } ,
449
- item : {
450
- padding : 0 ,
451
- } ,
452
- link : {
453
- alignItems : "center" ,
454
- color : colors . gray [ 6 ] ,
455
- display : "flex" ,
456
- flex : 1 ,
457
- fontSize : 16 ,
458
- padding : `${ theme . spacing ( 1.5 ) } ${ theme . spacing ( 2 ) } ` ,
459
- textDecoration : "none" ,
460
- transition : "background-color 0.15s ease-in-out" ,
461
-
462
- "&:hover" : {
463
- backgroundColor : theme . palette . action . hover ,
464
- } ,
465
-
466
- // NavLink adds this class when the current route matches.
467
- "&.active" : {
468
- color : theme . palette . text . primary ,
469
- fontWeight : 500 ,
470
- } ,
471
-
472
- [ theme . breakpoints . up ( "md" ) ] : {
473
- height : navHeight ,
474
- padding : `0 ${ theme . spacing ( 3 ) } ` ,
475
- } ,
476
- } ,
477
- } ) ) ;
0 commit comments