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 {{ value }} 39 </b-form-checkbox> 40 </b-form-checkbox-group> 41 </b-form-group> 42 </b-dropdown-form> 43 <b-dropdown-item-button 44 variant="primary" 45 data-test-id="tableFilter-button-clearAll" 46 @click="clearAllTags" 47 > 48 {{ $t('global.action.clearAll') }} 49 </b-dropdown-item-button> 50 </b-dropdown> 51 </div> 52</template> 53 54<script> 55import IconFilter from '@carbon/icons-vue/es/settings--adjust/20'; 56 57export default { 58 name: 'TableFilter', 59 components: { IconFilter }, 60 props: { 61 filters: { 62 type: Array, 63 default: () => [], 64 validator: (prop) => { 65 return prop.every( 66 (filter) => 'label' in filter && 'values' in filter && 'key' in filter 67 ); 68 }, 69 }, 70 }, 71 data() { 72 return { 73 dropdownVisible: false, 74 tags: [], 75 }; 76 }, 77 watch: { 78 tags: { 79 handler() { 80 this.emitChange(); 81 }, 82 deep: true, 83 }, 84 }, 85 methods: { 86 removeTag(removedTag) { 87 this.tags = this.tags.filter((tag) => tag !== removedTag); 88 }, 89 clearAllTags() { 90 this.tags = []; 91 }, 92 emitChange() { 93 const activeFilters = this.filters.map(({ key, values }) => { 94 const activeValues = values.filter( 95 (value) => this.tags.indexOf(value) !== -1 96 ); 97 return { 98 key, 99 values: activeValues, 100 }; 101 }); 102 this.$emit('filter-change', { activeFilters }); 103 }, 104 }, 105}; 106</script> 107 108<style lang="scss" scoped> 109.badge { 110 margin-right: $spacer / 2; 111} 112</style> 113