@@ -25,6 +25,32 @@ const activeStyle = {
25
25
color : '#fd9540' ,
26
26
} ;
27
27
28
+ const filterItemsBySearch = ( searchQuery : string , itemList : SourceItem [ ] ) => {
29
+ const caseSensitiveResults : SourceItem [ ] = [ ] ;
30
+ const caseAgnosticResults : SourceItem [ ] = [ ] ;
31
+ itemList . forEach ( item => {
32
+ if ( item . name . search ( searchQuery ) > - 1 ) {
33
+ caseSensitiveResults . push ( item ) ;
34
+ } else if ( item . name . toLowerCase ( ) . search ( searchQuery . toLowerCase ( ) ) > - 1 ) {
35
+ caseAgnosticResults . push ( item ) ;
36
+ }
37
+ } ) ;
38
+
39
+ return [
40
+ ...caseSensitiveResults . sort ( ( item1 , item2 ) => {
41
+ return item1 . name . search ( searchQuery ) > item2 . name . search ( searchQuery )
42
+ ? 1
43
+ : - 1 ;
44
+ } ) ,
45
+ ...caseAgnosticResults . sort ( ( item1 , item2 ) => {
46
+ return item1 . name . toLowerCase ( ) . search ( searchQuery . toLowerCase ( ) ) >
47
+ item2 . name . toLowerCase ( ) . search ( searchQuery . toLowerCase ( ) )
48
+ ? 1
49
+ : - 1 ;
50
+ } ) ,
51
+ ] ;
52
+ } ;
53
+
28
54
type LeafItemsViewProps = {
29
55
item : SourceItem ;
30
56
currentSource : string ;
@@ -130,6 +156,7 @@ type SchemaItemsViewProps = {
130
156
setActiveSchema : ( value : string ) => void ;
131
157
pathname : string ;
132
158
databaseLoading : boolean ;
159
+ schemaLoading : boolean ;
133
160
} ;
134
161
const SchemaItemsView : React . FC < SchemaItemsViewProps > = ( {
135
162
item,
@@ -138,14 +165,28 @@ const SchemaItemsView: React.FC<SchemaItemsViewProps> = ({
138
165
setActiveSchema,
139
166
pathname,
140
167
databaseLoading,
168
+ schemaLoading,
141
169
} ) => {
142
170
const [ isOpen , setIsOpen ] = useState ( false ) ;
171
+
172
+ const [ search , setSearch ] = React . useState ( '' ) ;
173
+ const onSearchChange = React . useCallback (
174
+ ( e : React . ChangeEvent < HTMLInputElement > ) => {
175
+ setSearch ( e . target . value ) ;
176
+ } ,
177
+ [ search ]
178
+ ) ;
179
+
143
180
const showActiveStyle =
144
181
pathname === `/data/${ currentSource } /schema/${ item . name } ` ;
145
182
useEffect ( ( ) => {
146
183
setIsOpen ( isActive ) ;
147
184
} , [ isActive ] ) ;
148
185
186
+ const itemSearchResults = search
187
+ ? filterItemsBySearch ( search , item . children || [ ] )
188
+ : item . children ;
189
+
149
190
return (
150
191
< >
151
192
< div
@@ -169,32 +210,50 @@ const SchemaItemsView: React.FC<SchemaItemsViewProps> = ({
169
210
{ item . name }
170
211
</ span >
171
212
</ div >
172
- < ul className = { styles . reducedChildPadding } >
173
- { isOpen && item . children ? (
174
- ! databaseLoading ? (
175
- item . children . map ( ( child , key ) => (
176
- < li key = { key } >
177
- < LeafItemsView
178
- item = { child }
179
- currentSource = { currentSource }
180
- currentSchema = { item . name }
181
- key = { key }
182
- pathname = { pathname }
213
+ { isOpen && itemSearchResults ? (
214
+ ! ( databaseLoading || schemaLoading ) ? (
215
+ item . children ?. length ? (
216
+ < >
217
+ < div className = "my-1 px-sm" >
218
+ < input
219
+ type = "text"
220
+ onChange = { onSearchChange }
221
+ className = "form-control"
222
+ placeholder = { `Search tables in ${ item . name } ....` }
223
+ data-test = "search-tables"
183
224
/>
184
- </ li >
185
- ) )
225
+ </ div >
226
+ < ul className = { styles . reducedChildPadding } >
227
+ { itemSearchResults . map ( ( child , key ) => (
228
+ < li key = { key } >
229
+ < LeafItemsView
230
+ item = { child }
231
+ currentSource = { currentSource }
232
+ currentSchema = { item . name }
233
+ key = { key }
234
+ pathname = { pathname }
235
+ />
236
+ </ li >
237
+ ) ) }
238
+ </ ul >
239
+ </ >
186
240
) : (
187
- < li >
188
- < span
189
- className = { `${ styles . sidebarTablePadding } ${ styles . padd_bottom_small } ` }
190
- >
191
- < i className = "fa fa-table" />
192
- < span className = { styles . loaderBar } />
193
- </ span >
241
+ < li
242
+ className = "font-normal px-sm"
243
+ data-test = "table-sidebar-no-tables"
244
+ >
245
+ < i > No tables or views in this schema</ i >
194
246
</ li >
195
247
)
196
- ) : null }
197
- </ ul >
248
+ ) : (
249
+ < span
250
+ className = { `${ styles . sidebarTablePadding } ${ styles . padd_bottom_small } ` }
251
+ >
252
+ < i className = "fa fa-table" />
253
+ < span className = { styles . loaderBar } />
254
+ </ span >
255
+ )
256
+ ) : null }
198
257
</ >
199
258
) ;
200
259
} ;
@@ -207,6 +266,7 @@ type DatabaseItemsViewProps = {
207
266
currentSchema : string ;
208
267
pathname : string ;
209
268
databaseLoading : boolean ;
269
+ schemaLoading : boolean ;
210
270
} ;
211
271
const DatabaseItemsView : React . FC < DatabaseItemsViewProps > = ( {
212
272
item,
@@ -216,6 +276,7 @@ const DatabaseItemsView: React.FC<DatabaseItemsViewProps> = ({
216
276
currentSchema,
217
277
pathname,
218
278
databaseLoading,
279
+ schemaLoading,
219
280
} ) => {
220
281
const [ isOpen , setIsOpen ] = useState ( false ) ;
221
282
const showActiveStyle = [
@@ -265,6 +326,7 @@ const DatabaseItemsView: React.FC<DatabaseItemsViewProps> = ({
265
326
key = { key }
266
327
pathname = { pathname }
267
328
databaseLoading = { databaseLoading }
329
+ schemaLoading = { schemaLoading }
268
330
/>
269
331
</ li >
270
332
) )
@@ -291,6 +353,7 @@ type TreeViewProps = {
291
353
currentSchema : string ;
292
354
pathname : string ;
293
355
databaseLoading : boolean ;
356
+ schemaLoading : boolean ;
294
357
preLoadState : boolean ;
295
358
} ;
296
359
const TreeView : React . FC < TreeViewProps > = ( {
@@ -301,6 +364,7 @@ const TreeView: React.FC<TreeViewProps> = ({
301
364
currentSchema,
302
365
pathname,
303
366
databaseLoading,
367
+ schemaLoading,
304
368
preLoadState,
305
369
} ) => {
306
370
const handleSelectDataSource = ( dataSource : string ) => {
@@ -348,6 +412,7 @@ const TreeView: React.FC<TreeViewProps> = ({
348
412
currentSchema = { currentSchema }
349
413
pathname = { pathname }
350
414
databaseLoading = { databaseLoading }
415
+ schemaLoading = { schemaLoading }
351
416
/>
352
417
) ) }
353
418
</ div >
0 commit comments