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'; 58import { useI18n } from 'vue-i18n'; 59 60export default { 61 name: 'TableFilter', 62 components: { IconFilter }, 63 props: { 64 filters: { 65 type: Array, 66 default: () => [], 67 validator: (prop) => { 68 return prop.every( 69 (filter) => 70 'label' in filter && 'values' in filter && 'key' in filter, 71 ); 72 }, 73 }, 74 }, 75 data() { 76 return { 77 $t: useI18n().t, 78 dropdownVisible: false, 79 tags: [], 80 }; 81 }, 82 watch: { 83 tags: { 84 handler() { 85 this.emitChange(); 86 }, 87 deep: true, 88 }, 89 }, 90 methods: { 91 removeTag(removedTag) { 92 this.tags = this.tags.filter((tag) => tag !== removedTag); 93 }, 94 clearAllTags() { 95 this.tags = []; 96 }, 97 emitChange() { 98 const activeFilters = this.filters.map(({ key, values }) => { 99 const activeValues = values.filter( 100 (value) => this.tags.indexOf(value) !== -1, 101 ); 102 return { 103 key, 104 values: activeValues, 105 }; 106 }); 107 this.$emit('filter-change', { activeFilters }); 108 }, 109 }, 110}; 111</script> 112 113<style lang="scss" scoped> 114@import '@/assets/styles/bmc/helpers/_index.scss'; 115@import '@/assets/styles/bootstrap/_helpers.scss'; 116 117@import 'bootstrap/dist/css/bootstrap.css'; 118 119.badge { 120 margin-right: $spacer / 2; 121} 122</style> 123