diff options
author | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-02-12 22:30:49 +0300 |
---|---|---|
committer | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-02-22 00:32:15 +0300 |
commit | 183c27548046e12b94354aa598b5bcf956d31103 (patch) | |
tree | 4168e439d3554427648b7898a706d8a7aed84e10 /src/components | |
parent | c11d38945b8a51e4181142c2b8852ffcb30338d9 (diff) | |
download | webui-vue-183c27548046e12b94354aa598b5bcf956d31103.tar.xz |
Add batch actions to local user table
- Create TableToolbar component for table batch actions
- Added Toast warning type and toast title message translations
- Update vue-i18n package to latest v8.15.3 to use improved
pluarlization features
Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I455beba4f56b8209b1201bbc5ff3f616e960d189
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/Global/TableToolbar.vue | 119 | ||||
-rw-r--r-- | src/components/Mixins/BVTableSelectableMixin.js | 44 | ||||
-rw-r--r-- | src/components/Mixins/BVToastMixin.js | 19 |
3 files changed, 178 insertions, 4 deletions
diff --git a/src/components/Global/TableToolbar.vue b/src/components/Global/TableToolbar.vue new file mode 100644 index 00000000..fc3736db --- /dev/null +++ b/src/components/Global/TableToolbar.vue @@ -0,0 +1,119 @@ +<template> + <transition name="slide"> + <div v-if="isToolbarActive" class="toolbar-container"> + <div class="toolbar-content"> + <p class="toolbar-selected"> + {{ selectedItemsCount }} {{ $t('global.actions.selected') }} + </p> + <div class="toolbar-actions d-flex"> + <b-button + v-for="(action, index) in actions" + :key="index" + variant="primary" + class="d-block" + @click="$emit('batchAction', action.value)" + > + {{ $t(action.labelKey) }} + </b-button> + <b-button + variant="primary" + class="d-block" + @click="$emit('clearSelected')" + > + {{ $t('global.actions.cancel') }} + </b-button> + </div> + </div> + </div> + </transition> +</template> + +<script> +export default { + name: 'TableToolbar', + props: { + selectedItemsCount: { + type: Number, + required: true + }, + actions: { + type: Array, + required: true, + validator: prop => { + return prop.every(action => { + return ( + action.hasOwnProperty('value') && action.hasOwnProperty('labelKey') + ); + }); + } + } + }, + data() { + return { + isToolbarActive: false + }; + }, + watch: { + selectedItemsCount: function(selectedItemsCount) { + if (selectedItemsCount > 0) { + this.isToolbarActive = true; + } else { + this.isToolbarActive = false; + } + } + } +}; +</script> + +<style lang="scss" scoped> +$toolbar-height: 46px; + +.toolbar-container { + width: 100%; + position: relative; +} + +.toolbar-content { + height: $toolbar-height; + background-color: $primary; + color: $white; + position: absolute; + left: 0; + right: 0; + top: -$toolbar-height; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.toolbar-actions { + > :last-child { + position: relative; + &::before { + content: ''; + position: absolute; + height: $toolbar-height / 2; + border-left: 2px solid $white; + left: -2px; + top: $toolbar-height / 4; + } + } +} + +.toolbar-selected { + line-height: $toolbar-height; + margin: 0; + padding: 0 $spacer; +} + +.slide-enter-active { + transition: transform $duration--moderate-02 $entrance-easing--productive; +} +.slide-leave-active { + transition: transform $duration--moderate-02 $exit-easing--productive; +} +.slide-enter, +.slide-leave-to { + transform: translateY($toolbar-height); +} +</style> diff --git a/src/components/Mixins/BVTableSelectableMixin.js b/src/components/Mixins/BVTableSelectableMixin.js new file mode 100644 index 00000000..fba2f2b8 --- /dev/null +++ b/src/components/Mixins/BVTableSelectableMixin.js @@ -0,0 +1,44 @@ +const BVTableSelectableMixin = { + data() { + return { + tableHeaderCheckboxModel: false, + tableHeaderCheckboxIndeterminate: false, + selectedRows: [] + }; + }, + methods: { + clearSelectedRows(tableRef) { + if (tableRef) tableRef.clearSelected(); + }, + toggleSelectRow(tableRef, rowIndex) { + if (tableRef && rowIndex !== undefined) { + tableRef.isRowSelected(rowIndex) + ? tableRef.unselectRow(rowIndex) + : tableRef.selectRow(rowIndex); + } + }, + onRowSelected(selectedRows, totalRowsCount) { + if (selectedRows && totalRowsCount !== undefined) { + this.selectedRows = selectedRows; + if (selectedRows.length === 0) { + this.tableHeaderCheckboxIndeterminate = false; + this.tableHeaderCheckboxModel = false; + } else if (selectedRows.length === totalRowsCount) { + this.tableHeaderCheckboxIndeterminate = false; + this.tableHeaderCheckboxModel = true; + } else { + this.tableHeaderCheckboxIndeterminate = true; + this.tableHeaderCheckboxModel = false; + } + } + }, + onChangeHeaderCheckbox(tableRef) { + if (tableRef) { + if (this.tableHeaderCheckboxModel) tableRef.clearSelected(); + else tableRef.selectAllRows(); + } + } + } +}; + +export default BVTableSelectableMixin; diff --git a/src/components/Mixins/BVToastMixin.js b/src/components/Mixins/BVToastMixin.js index 489173c9..a46f5e50 100644 --- a/src/components/Mixins/BVToastMixin.js +++ b/src/components/Mixins/BVToastMixin.js @@ -1,22 +1,33 @@ +import i18n from '../../i18n'; + const BVToastMixin = { methods: { - successToast(message) { + successToast(message, title = i18n.t('global.response.success')) { this.$root.$bvToast.toast(message, { - title: 'Success', + title, variant: 'success', autoHideDelay: 10000, //auto hide in milliseconds isStatus: true, solid: true }); }, - errorToast(message) { + errorToast(message, title = i18n.t('global.response.error')) { this.$root.$bvToast.toast(message, { - title: 'Error', + title, variant: 'danger', noAutoHide: true, isStatus: true, solid: true }); + }, + warningToast(message, title = i18n.t('global.response.warning')) { + this.$root.$bvToast.toast(message, { + title, + variant: 'warning', + noAutoHide: true, + isStatus: true, + solid: true + }); } } }; |