@@ -16,6 +16,7 @@ import {
16
16
EmptyStateFilter ,
17
17
EmptyStateNoData ,
18
18
EmptyStateUnauthorized ,
19
+ FilterOption ,
19
20
LoadingPageSpinner ,
20
21
Main ,
21
22
Pagination ,
@@ -43,6 +44,7 @@ interface IState<T> {
43
44
alerts : AlertType [ ] ;
44
45
unauthorised : boolean ;
45
46
inputText : string ;
47
+ selectedFilter : string ;
46
48
}
47
49
48
50
// states:
@@ -76,16 +78,13 @@ export type LocalizedSortHeaders = {
76
78
className ?: string ;
77
79
} [ ] ;
78
80
79
- interface ListPageParams < T , ExtraState > {
81
+ interface ListPageParams < T > {
80
82
condition : PermissionContextType ;
81
83
defaultPageSize : number ;
82
84
defaultSort ?: string ;
83
- didMount ?: ( { context, addAlert } ) => void ;
84
85
displayName : string ;
85
86
errorTitle : MessageDescriptor ;
86
- extraState ?: ExtraState ;
87
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
- filterConfig : any [ ] ; // FilterOption[] but { title: MessageDescriptor }
87
+ filterConfig : ( { state } ) => FilterOption [ ] ;
89
88
headerActions ?: ActionType [ ] ;
90
89
listItemActions ?: ActionType [ ] ;
91
90
noDataButton ?: ( item , actionContext ) => React . ReactNode ;
@@ -96,13 +95,12 @@ interface ListPageParams<T, ExtraState> {
96
95
renderTableRow : RenderTableRow < T > ;
97
96
sortHeaders : SortHeaders ;
98
97
title : MessageDescriptor ;
98
+ typeaheadQuery ?: ( { inputText, selectedFilter, setState } ) => void ;
99
99
}
100
100
101
- export const ListPage = function < T , ExtraState = Record < string , never > > ( {
101
+ export const ListPage = function < T > ( {
102
102
// { featureFlags, settings, user } => bool
103
103
condition,
104
- // extra code to run on mount
105
- didMount,
106
104
// component name for debugging
107
105
displayName,
108
106
// initial page size
@@ -111,8 +109,6 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
111
109
defaultSort,
112
110
// alert on query failure
113
111
errorTitle,
114
- // extra initial state
115
- extraState,
116
112
// filters
117
113
filterConfig,
118
114
// displayed after filters
@@ -133,7 +129,9 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
133
129
sortHeaders,
134
130
// container title
135
131
title,
136
- } : ListPageParams < T , ExtraState > ) {
132
+ // for typeahed filters
133
+ typeaheadQuery,
134
+ } : ListPageParams < T > ) {
137
135
renderModals ||= function ( actionContext ) {
138
136
return (
139
137
< >
@@ -180,8 +178,8 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
180
178
items : [ ] ,
181
179
loading : true ,
182
180
params,
181
+ selectedFilter : null ,
183
182
unauthorised : false ,
184
- ...extraState ,
185
183
} ;
186
184
}
187
185
@@ -194,26 +192,13 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
194
192
195
193
this . setState ( { alerts : this . context . alerts || [ ] } ) ;
196
194
this . context . setAlerts ( [ ] ) ;
197
-
198
- if ( didMount ) {
199
- didMount ( {
200
- context : this . context ,
201
- addAlert : ( alert ) => this . addAlert ( alert ) ,
202
- } ) ;
203
- }
204
195
}
205
196
206
197
render ( ) {
207
198
const { alerts, itemCount, items, loading, params, unauthorised } =
208
199
this . state ;
209
200
210
- const localizedFilterConfig = ( filterConfig || [ ] )
211
- . map ( translateTitle )
212
- . map ( ( { options, ...rest } ) => ( {
213
- ...rest ,
214
- options : options ?. map ( translateTitle ) ,
215
- } ) ) ;
216
-
201
+ const localizedFilterConfig = filterConfig ( { state : this . state } ) || [ ] ;
217
202
const knownFilters = localizedFilterConfig . map ( ( { id } ) => id ) ;
218
203
const noData = items . length === 0 && ! filterIsSet ( params , knownFilters ) ;
219
204
@@ -225,11 +210,11 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
225
210
226
211
const niceValues = { } ;
227
212
localizedFilterConfig
228
- . filter ( ( filter ) => filter [ ' options' ] && filter [ 'options' ] . length > 0 )
229
- . forEach ( ( item ) => {
230
- const obj = ( niceValues [ item [ 'id' ] ] = { } ) ;
231
- item [ ' options' ] . forEach ( ( option ) => {
232
- obj [ option . id ] = option . title ;
213
+ . filter ( ( { options } ) => options ? .length )
214
+ . forEach ( ( { id : filterId , options } ) => {
215
+ const obj = ( niceValues [ filterId ] = { } ) ;
216
+ options . forEach ( ( { id : optionId , title } ) => {
217
+ obj [ optionId ] = title ;
233
218
} ) ;
234
219
} ) ;
235
220
@@ -245,6 +230,12 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
245
230
user : this . context . user ,
246
231
} ;
247
232
233
+ const resetCompoundFilter = ( ) =>
234
+ this . setState ( {
235
+ inputText : '' ,
236
+ selectedFilter : localizedFilterConfig [ 0 ] . id ,
237
+ } ) ;
238
+
248
239
return (
249
240
< React . Fragment >
250
241
< AlertList alerts = { alerts } closeAlert = { ( i ) => this . closeAlert ( i ) } />
@@ -271,12 +262,34 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
271
262
< ToolbarItem >
272
263
< CompoundFilter
273
264
inputText = { this . state . inputText }
274
- onChange = { ( inputText ) =>
275
- this . setState ( { inputText } )
276
- }
277
- updateParams = { updateParams }
265
+ onChange = { ( inputText ) => {
266
+ this . setState ( { inputText } ) ;
267
+
268
+ if ( typeaheadQuery ) {
269
+ typeaheadQuery ( {
270
+ inputText,
271
+ selectedFilter : this . state . selectedFilter ,
272
+ setState : ( s ) => this . setState ( s ) ,
273
+ } ) ;
274
+ }
275
+ } }
276
+ updateParams = { ( p ) => {
277
+ resetCompoundFilter ( ) ;
278
+ updateParams ( p ) ;
279
+ } }
278
280
params = { params }
279
281
filterConfig = { localizedFilterConfig }
282
+ selectFilter = { ( selectedFilter ) => {
283
+ this . setState ( { selectedFilter } ) ;
284
+
285
+ if ( typeaheadQuery ) {
286
+ typeaheadQuery ( {
287
+ inputText : '' ,
288
+ selectedFilter,
289
+ setState : ( s ) => this . setState ( s ) ,
290
+ } ) ;
291
+ }
292
+ } }
280
293
/>
281
294
</ ToolbarItem >
282
295
{ headerActions ?. length &&
@@ -299,8 +312,8 @@ export const ListPage = function <T, ExtraState = Record<string, never>>({
299
312
< div >
300
313
< AppliedFilters
301
314
updateParams = { ( p ) => {
315
+ resetCompoundFilter ( ) ;
302
316
updateParams ( p ) ;
303
- this . setState ( { inputText : '' } ) ;
304
317
} }
305
318
params = { params }
306
319
ignoredParams = { [ 'page_size' , 'page' , 'sort' , 'ordering' ] }
0 commit comments