1<template> 2 <div class="table-filter d-inline-block"> 3 <p class="d-inline-block mb-0"> 4 <b-badge v-for="(tag, index) in tags" :key="index" pill> 5 {{ tag }} 6 <b-button-close 7 :disabled="dropdownVisible" 8 :aria-hidden="true" 9 @click="removeTag(tag)" 10 /> 11 </b-badge> 12 </p> 13 <b-dropdown 14 variant="link" 15 no-caret 16 right 17 data-test-id="tableFilter-dropdown-options" 18 @hide="dropdownVisible = false" 19 @show="dropdownVisible = true" 20 > 21 <template #button-content> 22 <icon-filter /> 23 {{ $t('global.action.filter') }} 24 </template> 25 <b-dropdown-form> 26 <b-form-group 27 v-for="(filter, index) of filters" 28 :key="index" 29 :label="filter.label" 30 > 31 <b-form-checkbox-group v-model="tags"> 32 <b-form-checkbox 33 v-for="value in filter.values" 34 :key="value" 35 :value="value" 36 :data-test-id="`tableFilter-checkbox-${value}`" 37 > 38 <b-dropdown-item> 39 {{ value }} 40 </b-dropdown-item> 41 </b-form-checkbox> 42 </b-form-checkbox-group> 43 </b-form-group> 44 </b-dropdown-form> 45 <b-dropdown-item-button 46 variant="primary" 47 data-test-id="tableFilter-button-clearAll" 48 @click="clearAllTags" 49 > 50 {{ $t('global.action.clearAll') }} 51 </b-dropdown-item-button> 52 </b-dropdown> 53 </div> 54</template> 55 56<script> 57import IconFilter from '@carbon/icons-vue/es/settings--adjust/20'; 58 59export default { 60 name: 'TableFilter', 61 components: { IconFilter }, 62 props: { 63 filters: { 64 type: Array, 65 default: () => [], 66 validator: (prop) => { 67 return prop.every( 68 (filter) => 'label' in filter && 'values' in filter && 'key' in filter 69 ); 70 }, 71 }, 72 }, 73 data() { 74 return { 75 dropdownVisible: false, 76 tags: [], 77 }; 78 }, 79 watch: { 80 tags: { 81 handler() { 82 this.emitChange(); 83 }, 84 deep: true, 85 }, 86 }, 87 methods: { 88 removeTag(removedTag) { 89 this.tags = this.tags.filter((tag) => tag !== removedTag); 90 }, 91 clearAllTags() { 92 this.tags = []; 93 }, 94 emitChange() { 95 const activeFilters = this.filters.map(({ key, values }) => { 96 const activeValues = values.filter( 97 (value) => this.tags.indexOf(value) !== -1 98 ); 99 return { 100 key, 101 values: activeValues, 102 }; 103 }); 104 this.$emit('filter-change', { activeFilters }); 105 }, 106 }, 107}; 108</script> 109 110<style lang="scss" scoped> 111.badge { 112 margin-right: $spacer / 2; 113} 114</style> 115