4
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
6
*/
7
- import React , { useCallback , useEffect , useRef , useState } from 'react' ;
7
+ import {
8
+ Fragment ,
9
+ FunctionComponent ,
10
+ Ref ,
11
+ SyntheticEvent ,
12
+ useCallback ,
13
+ useEffect ,
14
+ useRef ,
15
+ useState ,
16
+ } from 'react' ;
8
17
import { Autocomplete , TextField } from '@mui/material' ;
9
18
import {
10
19
fetchDirectoryContent ,
@@ -16,23 +25,38 @@ import { useDispatch, useSelector } from 'react-redux';
16
25
import { setSelectedDirectory , setTreeData } from '../../redux/actions' ;
17
26
import { updatedTree } from '../tree-views-container' ;
18
27
import { useIntl } from 'react-intl' ;
19
- import SearchItem from './search-item' ;
28
+ import { SearchItem } from './search-item' ;
29
+ import { IDirectory , ITreeData , ReduxState } from '../../redux/reducer.type' ;
20
30
21
31
export const SEARCH_FETCH_TIMEOUT_MILLIS = 1000 ; // 1 second
22
32
23
- export const SearchBar = ( { inputRef } ) => {
33
+ interface matchingElementProps {
34
+ id : string ;
35
+ name : string ;
36
+ type : string ;
37
+ pathName : string [ ] ;
38
+ pathUuid : string [ ] ;
39
+ }
40
+
41
+ interface SearchBarProps {
42
+ inputRef : Ref < any > ;
43
+ }
44
+
45
+ export const SearchBar : FunctionComponent < SearchBarProps > = ( { inputRef } ) => {
24
46
const dispatch = useDispatch ( ) ;
25
47
const { snackError } = useSnackMessage ( ) ;
26
- const [ elementsFound , setElementsFound ] = useState ( [ ] ) ;
48
+ const [ elementsFound , setElementsFound ] = useState < matchingElementProps [ ] > (
49
+ [ ]
50
+ ) ;
27
51
const [ inputValue , onInputChange ] = useState ( '' ) ;
28
52
const lastSearchTermRef = useRef ( '' ) ;
29
53
const [ loading , setLoading ] = useState ( false ) ;
30
- const treeData = useSelector ( ( state ) => state . treeData ) ;
31
- const treeDataRef = useRef ( ) ;
54
+ const treeData = useSelector ( ( state : ReduxState ) => state . treeData ) ;
55
+ const treeDataRef = useRef < ITreeData > ( ) ;
32
56
const intl = useIntl ( ) ;
33
57
treeDataRef . current = treeData ;
34
58
const searchMatchingEquipments = useCallback (
35
- ( searchTerm ) => {
59
+ ( searchTerm : string ) => {
36
60
lastSearchTermRef . current = searchTerm ;
37
61
searchTerm &&
38
62
searchElementsInfos ( searchTerm )
@@ -59,7 +83,7 @@ export const SearchBar = ({ inputRef }) => {
59
83
) ;
60
84
61
85
const handleChangeInput = useCallback (
62
- ( searchTerm ) => {
86
+ ( searchTerm : string ) => {
63
87
onInputChange ( searchTerm ) ;
64
88
searchTerm && setLoading ( true ) ;
65
89
debouncedSearchMatchingElements ( searchTerm ) ;
@@ -72,9 +96,9 @@ export const SearchBar = ({ inputRef }) => {
72
96
} , [ elementsFound ] ) ;
73
97
74
98
const renderOptionItem = useCallback (
75
- ( props , option ) => {
99
+ ( props : any , option : matchingElementProps ) => {
76
100
const matchingElement = elementsFound . find (
77
- ( element ) => element . id === option . id
101
+ ( element : matchingElementProps ) => element . id === option . id
78
102
) ;
79
103
return (
80
104
< SearchItem
@@ -88,7 +112,10 @@ export const SearchBar = ({ inputRef }) => {
88
112
) ;
89
113
90
114
const updateMapData = useCallback (
91
- ( nodeId , children ) => {
115
+ ( nodeId : string , children : IDirectory ) => {
116
+ if ( ! treeDataRef . current ) {
117
+ return ;
118
+ }
92
119
let [ newRootDirectories , newMapData ] = updatedTree (
93
120
treeDataRef . current . rootDirectories ,
94
121
treeDataRef . current . mapData ,
@@ -106,24 +133,25 @@ export const SearchBar = ({ inputRef }) => {
106
133
) ;
107
134
108
135
const handleDispatchDirectory = useCallback (
109
- ( elementUuidPath ) => {
110
- const selectedDirectory =
111
- treeDataRef . current . mapData [ elementUuidPath ] ;
136
+ ( elementUuidPath : string | undefined ) => {
137
+ if ( treeDataRef . current && elementUuidPath !== undefined ) {
138
+ const selectedDirectory =
139
+ treeDataRef . current . mapData [ elementUuidPath ] ;
112
140
113
- dispatch ( setSelectedDirectory ( selectedDirectory ) ) ;
141
+ dispatch ( setSelectedDirectory ( selectedDirectory ) ) ;
142
+ }
114
143
} ,
115
144
[ dispatch ]
116
145
) ;
117
146
118
147
const handleMatchingElement = useCallback (
119
- ( event , data ) => {
148
+ ( event : SyntheticEvent , data : matchingElementProps | string | null ) => {
120
149
const matchingElement = elementsFound . find (
121
- ( element ) => element === data
150
+ ( element : matchingElementProps ) => element === data
122
151
) ;
123
152
if ( matchingElement !== undefined ) {
124
153
const elementUuidPath = matchingElement ?. pathUuid . reverse ( ) ;
125
-
126
- const promises = elementUuidPath . map ( ( e ) => {
154
+ const promises = elementUuidPath . map ( ( e : string ) => {
127
155
return fetchDirectoryContent ( e )
128
156
. then ( ( res ) => {
129
157
updateMapData ( e , res ) ;
@@ -159,9 +187,21 @@ export const SearchBar = ({ inputRef }) => {
159
187
inputValue = { inputValue }
160
188
onInputChange = { ( _ , data ) => handleChangeInput ( data ) }
161
189
onChange = { handleMatchingElement }
162
- key = { ( option ) => option . id }
190
+ getOptionKey = { ( option ) => {
191
+ if ( typeof option === 'string' ) {
192
+ return option ;
193
+ } else {
194
+ return option . id ;
195
+ }
196
+ } }
163
197
options = { loading ? [ ] : elementsFound }
164
- getOptionLabel = { ( option ) => option . name }
198
+ getOptionLabel = { ( option ) => {
199
+ if ( typeof option === 'string' ) {
200
+ return inputValue ;
201
+ } else {
202
+ return option . name ;
203
+ }
204
+ } }
165
205
loading = { loading }
166
206
renderOption = { renderOptionItem }
167
207
renderInput = { ( params ) => (
@@ -176,10 +216,10 @@ export const SearchBar = ({ inputRef }) => {
176
216
InputProps = { {
177
217
...params . InputProps ,
178
218
startAdornment : (
179
- < React . Fragment >
219
+ < Fragment >
180
220
< Search />
181
221
{ params . InputProps . startAdornment }
182
- </ React . Fragment >
222
+ </ Fragment >
183
223
) ,
184
224
} }
185
225
/>
@@ -188,5 +228,3 @@ export const SearchBar = ({ inputRef }) => {
188
228
</ >
189
229
) ;
190
230
} ;
191
-
192
- export default SearchBar ;
0 commit comments