1<template> 2 <transition name="slide"> 3 <div v-if="isToolbarActive" class="toolbar-container"> 4 <div class="toolbar-content"> 5 <p class="toolbar-selected"> 6 {{ selectedItemsCount }} {{ $t('global.action.selected') }} 7 </p> 8 <div class="toolbar-actions d-flex"> 9 <slot name="toolbar-buttons"></slot> 10 <b-button 11 v-for="(action, index) in actions" 12 :key="index" 13 :data-test-id="`table-button-${action.value}Selected`" 14 variant="primary" 15 class="d-block" 16 @click="$emit('batch-action', action.value)" 17 > 18 {{ action.label }} 19 </b-button> 20 <b-button 21 variant="secondary" 22 class="d-block" 23 @click="$emit('clear-selected')" 24 > 25 {{ $t('global.action.cancel') }} 26 </b-button> 27 </div> 28 </div> 29 </div> 30 </transition> 31</template> 32 33<script> 34import { useI18n } from 'vue-i18n'; 35export default { 36 name: 'TableToolbar', 37 props: { 38 selectedItemsCount: { 39 type: Number, 40 required: true, 41 }, 42 actions: { 43 type: Array, 44 default: () => [], 45 validator: (prop) => { 46 return prop.every((action) => { 47 return ( 48 Object.prototype.hasOwnProperty.call(action, 'value') && 49 Object.prototype.hasOwnProperty.call(action, 'label') 50 ); 51 }); 52 }, 53 }, 54 }, 55 data() { 56 return { 57 $t: useI18n().t, 58 isToolbarActive: false, 59 }; 60 }, 61 watch: { 62 selectedItemsCount: function (selectedItemsCount) { 63 if (selectedItemsCount > 0) { 64 this.isToolbarActive = true; 65 } else { 66 this.isToolbarActive = false; 67 } 68 }, 69 }, 70}; 71</script> 72 73<style lang="scss" scoped> 74@import '@/assets/styles/bmc/helpers/_index.scss'; 75@import '@/assets/styles/bootstrap/_helpers.scss'; 76 77@import 'bootstrap/dist/css/bootstrap.css'; 78 79$toolbar-height: 46px; 80 81.toolbar-container { 82 width: 100%; 83 position: relative; 84 //z-index: $zindex-dropdown + 1; 85} 86 87.toolbar-content { 88 height: $toolbar-height; 89 background-color: theme-color('primary'); 90 color: $white; 91 position: absolute; 92 left: 0; 93 right: 0; 94 top: -$toolbar-height; 95 display: flex; 96 flex-direction: row; 97 justify-content: space-between; 98} 99 100.toolbar-selected { 101 line-height: $toolbar-height; 102 margin: 0; 103 padding: 0 $spacer; 104} 105 106// Using v-deep to style export slot child-element 107// depricated and vue-js 3 108.toolbar-actions ::v-deep .btn { 109 position: relative; 110 &:after { 111 content: ''; 112 position: absolute; 113 left: 0; 114 height: 1.5rem; 115 width: 1px; 116 background: rgba($white, 0.6); 117 } 118 &:last-child, 119 &:first-child { 120 &:after { 121 width: 0; 122 } 123 } 124} 125 126.slide-enter-active { 127 transition: transform $duration--moderate-02 $entrance-easing--productive; 128} 129.slide-leave-active { 130 transition: transform $duration--moderate-02 $exit-easing--productive; 131} 132.slide-enter, // Remove this vue2 based only class when switching to vue3 133.slide-enter-from, // This is vue3 based only class modified from 'slide-enter' 134.slide-leave-to { 135 transform: translateY($toolbar-height); 136} 137</style> 138