1
- import { useRef , FC , useState , useMemo , useEffect } from "react" ;
1
+ import { FC , useState , useMemo } from "react" ;
2
2
import {
3
3
Menu ,
4
4
MenuItem ,
@@ -8,10 +8,13 @@ import {
8
8
TextField ,
9
9
InputAdornment ,
10
10
IconButton ,
11
+ ListSubheader ,
12
+ ListItem ,
11
13
} from "@mui/material" ;
12
14
import SearchIcon from "@mui/icons-material/Search" ;
13
15
import CloseRoundedIcon from "@mui/icons-material/CloseRounded" ;
14
16
import { theme } from "@zesty-io/material" ;
17
+ import { cloneDeep } from "lodash" ;
15
18
16
19
import { FilterButton } from "./FilterButton" ;
17
20
import { useGetUsersQuery } from "../../services/accounts" ;
@@ -20,37 +23,55 @@ import { MD5 } from "../../../utility/md5";
20
23
interface UserFilterProps {
21
24
value : string ;
22
25
onChange : ( filter : string ) => void ;
26
+ defaultButtonText ?: string ;
23
27
}
24
- export const UserFilter : FC < UserFilterProps > = ( { value, onChange } ) => {
28
+ export const UserFilter : FC < UserFilterProps > = ( {
29
+ value,
30
+ onChange,
31
+ defaultButtonText = "Created By" ,
32
+ } ) => {
25
33
const [ filter , setFilter ] = useState ( "" ) ;
26
34
const [ menuAnchorEl , setMenuAnchorEl ] = useState < HTMLButtonElement | null > (
27
35
null
28
36
) ;
29
37
const isFilterMenuOpen = Boolean ( menuAnchorEl ) ;
30
38
const { data : users } = useGetUsersQuery ( ) ;
31
- const searchField = useRef < HTMLInputElement | null > ( null ) ;
32
39
33
40
const filteredUsers = useMemo ( ( ) => {
41
+ const _users = cloneDeep ( users ) ;
42
+
43
+ const sortedUsers = _users ?. sort ( ( a , b ) => {
44
+ const nameA = a . firstName . toLowerCase ( ) ;
45
+ const nameB = b . firstName . toLowerCase ( ) ;
46
+
47
+ if ( nameA < nameB ) {
48
+ return - 1 ;
49
+ }
50
+
51
+ if ( nameA > nameB ) {
52
+ return 1 ;
53
+ }
54
+
55
+ return 0 ;
56
+ } ) ;
57
+
34
58
if ( ! filter . length ) {
35
- return users ;
59
+ return sortedUsers ;
36
60
}
37
- const _filter = filter . toLowerCase ( ) ;
38
61
39
- return users ?. filter (
62
+ const _filterTerm = filter . toLowerCase ( ) ;
63
+
64
+ return sortedUsers ?. filter (
40
65
( user ) =>
41
- user ?. firstName ?. toLowerCase ( ) . includes ( _filter ) ||
42
- user ?. lastName ?. toLowerCase ( ) . includes ( _filter )
66
+ user ?. firstName ?. toLowerCase ( ) . includes ( _filterTerm ) ||
67
+ user ?. lastName ?. toLowerCase ( ) . includes ( _filterTerm )
43
68
) ;
44
69
} , [ filter , users ] ) ;
45
70
46
- useEffect ( ( ) => {
47
- searchField . current ?. focus ( ) ;
48
- } , [ filteredUsers ] ) ;
49
-
50
71
const activeUserFilter = users ?. find ( ( user ) => user ?. ZUID === value ) ;
51
72
const buttonText = activeUserFilter
52
73
? `${ activeUserFilter . firstName } ${ activeUserFilter . lastName } `
53
- : "Created By" ;
74
+ : defaultButtonText ;
54
75
55
76
const handleOpenMenuClick = ( e : React . MouseEvent < HTMLButtonElement > ) => {
56
77
setMenuAnchorEl ( e . currentTarget ) ;
@@ -86,26 +107,34 @@ export const UserFilter: FC<UserFilterProps> = ({ value, onChange }) => {
86
107
} ,
87
108
} ,
88
109
} }
110
+ MenuListProps = { {
111
+ sx : {
112
+ pt : 0 ,
113
+ pb : 1 ,
114
+ } ,
115
+ } }
116
+ autoFocus = { false }
89
117
>
90
- < MenuItem
91
- disableRipple
118
+ < ListSubheader
92
119
onKeyDown = { ( e : React . KeyboardEvent ) => {
93
- const allowedKeys = [ "ArrowUp" , "ArrowDown" ] ;
120
+ const allowedKeys = [ "ArrowUp" , "ArrowDown" , "Escape" ] ;
94
121
95
122
if ( ! allowedKeys . includes ( e . key ) ) {
96
123
e . stopPropagation ( ) ;
97
124
}
98
125
} }
99
126
sx = { {
100
- "&:hover" : {
101
- backgroundColor : "common.white" ,
102
- } ,
103
- "&.Mui-focusVisible" : {
104
- backgroundColor : "common.white" ,
127
+ pt : 1 ,
128
+ height : "60px" ,
129
+ display : "flex" ,
130
+ alignItems : "center" ,
131
+ "&:focus-visible" : {
132
+ outline : "none" ,
105
133
} ,
106
134
} }
107
135
>
108
136
< TextField
137
+ autoFocus
109
138
fullWidth
110
139
placeholder = "Search Users"
111
140
value = { filter }
@@ -122,15 +151,24 @@ export const UserFilter: FC<UserFilterProps> = ({ value, onChange }) => {
122
151
</ IconButton >
123
152
) : null ,
124
153
} }
125
- inputProps = { { ref : searchField } }
126
154
/>
127
- </ MenuItem >
128
- { filteredUsers ?. map ( ( user , index ) => {
155
+ </ ListSubheader >
156
+
157
+ { ! filteredUsers ?. length && Boolean ( filter ) && (
158
+ < ListItem >
159
+ < ListItemText > No users found</ ListItemText >
160
+ </ ListItem >
161
+ ) }
162
+
163
+ { filteredUsers ?. map ( ( user ) => {
129
164
return (
130
165
< MenuItem
131
166
key = { user ?. ZUID }
132
167
onClick = { ( ) => handleFilterSelect ( user ?. ZUID ) }
133
- selected = { value ? value === user ?. ZUID : index === 0 }
168
+ selected = { value && value === user ?. ZUID }
169
+ sx = { {
170
+ height : "52px" ,
171
+ } }
134
172
>
135
173
< ListItemAvatar >
136
174
< Avatar
0 commit comments