@@ -37,64 +37,55 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
37
37
id =" c-gscan-search-workflows"
38
38
/>
39
39
<v-menu
40
- v-model =" showFilterTooltip "
40
+ v-model =" showFilterMenu "
41
41
:close-on-content-click =" false"
42
42
offset-x
43
43
>
44
- <!-- button to activate the filters tooltip -->
44
+ <!-- button to activate the filters menu -->
45
45
<template v-slot :activator =" { on , attrs } " >
46
- <v-btn
47
- v-bind =" attrs"
48
- v-on =" on"
49
- link
50
- icon
51
- class =" flex-grow-0 flex-column"
52
- id =" c-gscan-filter-tooltip-btn"
53
- @click =" showFilterTooltip = !showFilterTooltip"
46
+ <v-badge
47
+ :content =" numFilters"
48
+ :value =" numFilters"
49
+ overlap
54
50
>
55
- <v-icon >{{ svgPaths.filter }}</v-icon >
56
- </v-btn >
51
+ <v-btn
52
+ v-bind =" attrs"
53
+ v-on =" on"
54
+ link
55
+ icon
56
+ id =" c-gscan-filter-menu-btn"
57
+ @click =" showFilterMenu = !showFilterMenu"
58
+ >
59
+ <v-icon >{{ $options.icons.mdiFilter }}</v-icon >
60
+ </v-btn >
61
+ </v-badge >
57
62
</template >
58
- <!-- filters tooltip -->
59
- <v-card
60
- max-height =" 250px"
61
- >
62
- <v-list
63
- dense
64
- >
63
+ <!-- filters menu -->
64
+ <v-card width =" 500px" >
65
+ <v-list dense >
65
66
<div
66
- v-for =" filter in filters"
67
- :key =" filter. title"
67
+ v-for =" (items, title) in filters"
68
+ :key =" title"
68
69
>
69
- <v-list-item dense >
70
+ <v-list-item >
70
71
<v-list-item-content ma-0 >
71
- <v-list-item-title >
72
- <v-checkbox
73
- :label =" filter.title"
74
- :input-value =" allItemsSelected(filter.items)"
75
- value
76
- dense
77
- hide-details
78
- hint =" Toggle all"
79
- @click =" toggleItemsValues(filter.items)"
80
- ></v-checkbox >
81
- </v-list-item-title >
82
- </v-list-item-content >
83
- </v-list-item >
84
- <v-divider />
85
- <v-list-item
86
- v-for =" item in filter.items"
87
- :key =" `${filter.title}-${item.text}`"
88
- dense
89
- >
90
- <v-list-item-action >
91
- <v-checkbox
92
- :label =" item.text"
93
- v-model =" item.model"
72
+ <span class =" mb-2" >Filter by {{ title }}</span >
73
+ <v-autocomplete
74
+ v-model =" filters[title]"
75
+ :items =" $options.allStates[title]"
76
+ outlined
77
+ chips
78
+ deletable-chips
79
+ small-chips
80
+ clearable
81
+ multiple
94
82
dense
95
- height =" 20"
96
- ></v-checkbox >
97
- </v-list-item-action >
83
+ hide-details
84
+ :menu-props =" { closeOnClick: true }"
85
+ :clear-icon =" $options.icons.mdiClose"
86
+ :data-cy =" `filter ${title}`"
87
+ />
88
+ </v-list-item-content >
98
89
</v-list-item >
99
90
</div >
100
91
</v-list >
@@ -200,9 +191,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
200
191
</template >
201
192
202
193
<script >
203
- import { mdiFilter } from ' @mdi/js'
204
- import uniq from ' lodash/uniq'
205
- import TaskState from ' @/model/TaskState.model'
194
+ import { mdiClose , mdiFilter } from ' @mdi/js'
195
+ import TaskState , { TaskStateUserOrder } from ' @/model/TaskState.model'
206
196
import { WorkflowState } from ' @/model/WorkflowState.model'
207
197
import Job from ' @/components/cylc/Job'
208
198
import Tree from ' @/components/cylc/tree/Tree'
@@ -233,9 +223,6 @@ export default {
233
223
data () {
234
224
return {
235
225
maximumTasksDisplayed: 5 ,
236
- svgPaths: {
237
- filter: mdiFilter
238
- },
239
226
/**
240
227
* The filtered workflows. This is the result of applying the filters
241
228
* on the workflows prop.
@@ -248,68 +235,20 @@ export default {
248
235
*/
249
236
searchWorkflows: ' ' ,
250
237
/**
251
- * Variable to control whether the filters tooltip (a menu actually)
252
- * is displayed or not (i.e. v-model=this).
238
+ * Whether the filters menu is displayed (i.e. v-model=this).
253
239
* @type {boolean}
254
240
*/
255
- showFilterTooltip : false ,
241
+ showFilterMenu : false ,
256
242
/**
257
- * List of filters to be displayed by the template, so that the user
258
- * can filter the list of workflows.
259
- *
260
- * Each entry contains a title and a list of items. Each item contains
261
- * the text attribute, which is used as display value in the template.
262
- * The value attribute, which may be used if necessary, as it contains
263
- * the original value (e.g. an Enum, while title would be some formatted
264
- * string). Finally, the model is bound via v-model, and keeps the
265
- * value selected in the UI (i.e. if the user checks the "running"
266
- * checkbox, the model here will be true, if the user unchecks it,
267
- * then it will be false).
268
- *
269
- * @type {[
270
- * {
271
- * title: string,
272
- * items: [{
273
- * text: string,
274
- * value: object,
275
- * model: boolean
276
- * }]
277
- * }
278
- * ]}
243
+ * List of filters selected by the user.
244
+ * @type {{string: string[]}}
279
245
*/
280
- filters: [
281
- {
282
- title: ' workflow state' ,
283
- items: WorkflowState .enumValues
284
- .map (state => {
285
- return {
286
- text: state .name ,
287
- value: state,
288
- model: true
289
- }
290
- })
291
- },
292
- {
293
- title: ' task state' ,
294
- items: TaskState .enumValues .map (state => {
295
- return {
296
- text: state .name ,
297
- value: state,
298
- model: false
299
- }
300
- }).sort ((left , right ) => {
301
- return left .text .localeCompare (right .text )
302
- })
303
- }
304
- // {
305
- // title: 'workflow host',
306
- // items: [] // TODO: will it be in state totals?
307
- // },
308
- // {
309
- // title: 'cylc version',
310
- // items: [] // TODO: will it be in state totals?
311
- // }
312
- ]
246
+ filters: {
247
+ ' workflow state' : [],
248
+ ' task state' : []
249
+ // 'workflow host': [], // TODO: will it be in state totals?
250
+ // 'cylc version': [] // TODO: will it be in state totals?
251
+ }
313
252
}
314
253
},
315
254
computed: {
@@ -320,23 +259,8 @@ export default {
320
259
}
321
260
return sortedWorkflowTree (this .workflowTree )
322
261
},
323
- /**
324
- * @return {Array<String>}
325
- */
326
- workflowStates () {
327
- return this .filters [0 ]
328
- .items
329
- .filter (item => item .model )
330
- .map (item => item .value .name )
331
- },
332
- /**
333
- * @return {Array<String>}
334
- */
335
- taskStates () {
336
- return uniq (this .filters [1 ]
337
- .items
338
- .filter (item => item .model )
339
- .map (item => item .value .name ))
262
+ numFilters () {
263
+ return Object .values (this .filters ).flat ().length
340
264
}
341
265
},
342
266
watch: {
@@ -347,25 +271,19 @@ export default {
347
271
filters: {
348
272
deep: true ,
349
273
immediate: false ,
350
- handler : function (newVal ) {
351
- this .filteredWorkflows = this .filterHierarchically (this .workflows , this .searchWorkflows , this .workflowStates , this .taskStates )
352
- }
274
+ handler: ' filterWorkflows'
353
275
},
354
276
/**
355
277
* If the user changes the workflow name to search/filter,
356
278
* then we apply the filters to the list of workflows.
357
279
*/
358
280
searchWorkflows: {
359
281
immediate: false ,
360
- handler : function (newVal ) {
361
- this .filteredWorkflows = this .filterHierarchically (this .workflows , newVal, this .workflowStates , this .taskStates )
362
- }
282
+ handler: ' filterWorkflows'
363
283
},
364
284
workflows: {
365
285
immediate: true ,
366
- handler : function () {
367
- this .filteredWorkflows = this .filterHierarchically (this .workflows , this .searchWorkflows , this .workflowStates , this .taskStates )
368
- }
286
+ handler: ' filterWorkflows'
369
287
},
370
288
filteredWorkflows: {
371
289
immediate: true ,
@@ -396,7 +314,14 @@ export default {
396
314
}
397
315
},
398
316
methods: {
399
- filterHierarchically,
317
+ filterWorkflows () {
318
+ this .filteredWorkflows = filterHierarchically (
319
+ this .workflows ,
320
+ this .searchWorkflows ,
321
+ this .filters [' workflow state' ],
322
+ this .filters [' task state' ]
323
+ )
324
+ },
400
325
401
326
/**
402
327
* Return `true` iff all the items have been selected. `false` otherwise.
@@ -470,6 +395,20 @@ export default {
470
395
return validValues .includes (entry[0 ])
471
396
})
472
397
}
398
+ },
399
+
400
+ // Misc options
401
+ icons: {
402
+ mdiClose,
403
+ mdiFilter
404
+ },
405
+ /**
406
+ * Lists of all the possible workflow and task states
407
+ * @type {{string: string[]}}
408
+ */
409
+ allStates: {
410
+ ' workflow state' : WorkflowState .enumValues .map (x => x .name ),
411
+ ' task state' : TaskStateUserOrder .map (x => x .name )
473
412
}
474
413
}
475
414
< / script>
0 commit comments