1<template> 2 <b-container fluid="xl"> 3 <page-title /> 4 <b-row> 5 <b-col xl="9" class="text-right"> 6 <b-button variant="link" @click="initModalSettings"> 7 <icon-settings /> 8 {{ $t('pageUserManagement.accountPolicySettings') }} 9 </b-button> 10 <b-button 11 variant="primary" 12 data-test-id="userManagement-button-addUser" 13 @click="initModalUser(null)" 14 > 15 <icon-add /> 16 {{ $t('pageUserManagement.addUser') }} 17 </b-button> 18 </b-col> 19 </b-row> 20 <b-row> 21 <b-col xl="9"> 22 <table-toolbar 23 ref="toolbar" 24 :selected-items-count="selectedRows.length" 25 :actions="tableToolbarActions" 26 @clear-selected="clearSelectedRows($refs.table)" 27 @batch-action="onBatchAction" 28 /> 29 <b-table 30 ref="table" 31 responsive="md" 32 selectable 33 show-empty 34 no-select-on-click 35 hover 36 :busy="isBusy" 37 :fields="fields" 38 :items="tableItems" 39 :empty-text="$t('global.table.emptyMessage')" 40 @row-selected="onRowSelected($event, tableItems.length)" 41 > 42 <!-- Checkbox column --> 43 <template #head(checkbox)> 44 <b-form-checkbox 45 v-model="tableHeaderCheckboxModel" 46 data-test-id="userManagement-checkbox-tableHeaderCheckbox" 47 :indeterminate="tableHeaderCheckboxIndeterminate" 48 @change="onChangeHeaderCheckbox($refs.table)" 49 > 50 <span class="sr-only">{{ $t('global.table.selectAll') }}</span> 51 </b-form-checkbox> 52 </template> 53 <template #cell(checkbox)="row"> 54 <b-form-checkbox 55 v-model="row.rowSelected" 56 data-test-id="userManagement-checkbox-toggleSelectRow" 57 @change="toggleSelectRow($refs.table, row.index)" 58 > 59 <span class="sr-only">{{ $t('global.table.selectItem') }}</span> 60 </b-form-checkbox> 61 </template> 62 63 <!-- table actions column --> 64 <template #cell(actions)="{ item }"> 65 <table-row-action 66 v-for="(action, index) in item.actions" 67 :key="index" 68 :value="action.value" 69 :enabled="action.enabled" 70 :title="action.title" 71 @click-table-action="onTableRowAction($event, item)" 72 > 73 <template #icon> 74 <icon-edit 75 v-if="action.value === 'edit'" 76 :data-test-id="`userManagement-tableRowAction-edit-${index}`" 77 /> 78 <icon-trashcan 79 v-if="action.value === 'delete'" 80 :data-test-id="`userManagement-tableRowAction-delete-${index}`" 81 /> 82 </template> 83 </table-row-action> 84 </template> 85 </b-table> 86 </b-col> 87 </b-row> 88 <b-row> 89 <b-col xl="8"> 90 <b-button 91 v-b-toggle.collapse-role-table 92 data-test-id="userManagement-button-viewPrivilegeRoleDescriptions" 93 variant="link" 94 class="mt-3" 95 > 96 <icon-chevron /> 97 {{ $t('pageUserManagement.viewPrivilegeRoleDescriptions') }} 98 </b-button> 99 <b-collapse id="collapse-role-table" class="mt-3"> 100 <table-roles /> 101 </b-collapse> 102 </b-col> 103 </b-row> 104 <!-- Modals --> 105 <modal-settings :settings="setting" @ok="saveAccountSettings" /> 106 <modal-user 107 :user="activeUser" 108 :password-requirements="passwordRequirements" 109 @ok="saveUser" 110 @hidden="activeUser = null" 111 /> 112 </b-container> 113</template> 114 115<script> 116import IconTrashcan from '@carbon/icons-vue/es/trash-can/20'; 117import IconEdit from '@carbon/icons-vue/es/edit/20'; 118import IconAdd from '@carbon/icons-vue/es/add--alt/20'; 119import IconSettings from '@carbon/icons-vue/es/settings/20'; 120import IconChevron from '@carbon/icons-vue/es/chevron--up/20'; 121 122import ModalUser from './ModalUser'; 123import ModalSettings from './ModalSettings'; 124import PageTitle from '@/components/Global/PageTitle'; 125import TableRoles from './TableRoles'; 126import TableToolbar from '@/components/Global/TableToolbar'; 127import TableRowAction from '@/components/Global/TableRowAction'; 128 129import BVTableSelectableMixin, { 130 selectedRows, 131 tableHeaderCheckboxModel, 132 tableHeaderCheckboxIndeterminate, 133} from '@/components/Mixins/BVTableSelectableMixin'; 134import BVToastMixin from '@/components/Mixins/BVToastMixin'; 135import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; 136import { useI18n } from 'vue-i18n'; 137import i18n from '@/i18n'; 138 139export default { 140 name: 'UserManagement', 141 components: { 142 IconAdd, 143 IconChevron, 144 IconEdit, 145 IconSettings, 146 IconTrashcan, 147 ModalSettings, 148 ModalUser, 149 PageTitle, 150 TableRoles, 151 TableRowAction, 152 TableToolbar, 153 }, 154 mixins: [BVTableSelectableMixin, BVToastMixin, LoadingBarMixin], 155 beforeRouteLeave(to, from, next) { 156 this.hideLoader(); 157 next(); 158 }, 159 data() { 160 return { 161 $t: useI18n().t, 162 isBusy: true, 163 activeUser: null, 164 setting: {}, 165 fields: [ 166 { 167 key: 'checkbox', 168 }, 169 { 170 key: 'username', 171 label: i18n.global.t('pageUserManagement.table.username'), 172 }, 173 { 174 key: 'privilege', 175 label: i18n.global.t('pageUserManagement.table.privilege'), 176 }, 177 { 178 key: 'status', 179 label: i18n.global.t('pageUserManagement.table.status'), 180 }, 181 { 182 key: 'actions', 183 label: '', 184 tdClass: 'text-right text-nowrap', 185 }, 186 ], 187 tableToolbarActions: [ 188 { 189 value: 'delete', 190 label: i18n.global.t('global.action.delete'), 191 }, 192 { 193 value: 'enable', 194 label: i18n.global.t('global.action.enable'), 195 }, 196 { 197 value: 'disable', 198 label: i18n.global.t('global.action.disable'), 199 }, 200 ], 201 selectedRows: selectedRows, 202 tableHeaderCheckboxModel: tableHeaderCheckboxModel, 203 tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate, 204 }; 205 }, 206 computed: { 207 allUsers() { 208 return this.$store.getters['userManagement/allUsers']; 209 }, 210 tableItems() { 211 // transform user data to table data 212 return this.allUsers.map((user) => { 213 return { 214 username: user.UserName, 215 privilege: user.RoleId, 216 status: user.Locked 217 ? 'Locked' 218 : user.Enabled 219 ? 'Enabled' 220 : 'Disabled', 221 actions: [ 222 { 223 value: 'edit', 224 enabled: this.editEnable(user), 225 title: i18n.global.t('pageUserManagement.editUser'), 226 }, 227 { 228 value: 'delete', 229 enabled: 230 user.UserName === this.$store.getters['global/username'] 231 ? false 232 : true && user.UserName === 'root' 233 ? false 234 : true, 235 title: i18n.global.t('pageUserManagement.deleteUser'), 236 }, 237 ], 238 ...user, 239 }; 240 }); 241 }, 242 settings() { 243 return this.$store.getters['userManagement/accountSettings']; 244 }, 245 passwordRequirements() { 246 return this.$store.getters['userManagement/accountPasswordRequirements']; 247 }, 248 }, 249 created() { 250 this.startLoader(); 251 this.$store.dispatch('userManagement/getUsers').finally(() => { 252 this.endLoader(); 253 this.isBusy = false; 254 }); 255 this.$store.dispatch('userManagement/getAccountSettings'); 256 this.$store.dispatch('userManagement/getAccountRoles'); 257 }, 258 methods: { 259 editEnable(user) { 260 if ('root' === this.$store.getters['global/username']) { 261 return true; 262 } else { 263 return user.UserName === 'root' ? false : true; 264 } 265 }, 266 initModalUser(user) { 267 this.activeUser = user; 268 this.$bvModal.show('modal-user'); 269 }, 270 initModalDelete(user) { 271 this.$bvModal 272 .msgBoxConfirm( 273 i18n.global.t('pageUserManagement.modal.deleteConfirmMessage', { 274 user: user.username, 275 }), 276 { 277 title: i18n.global.t('pageUserManagement.deleteUser'), 278 okTitle: i18n.global.t('pageUserManagement.deleteUser'), 279 cancelTitle: i18n.global.t('global.action.cancel'), 280 autoFocusButton: 'ok', 281 }, 282 ) 283 .then((deleteConfirmed) => { 284 if (deleteConfirmed) { 285 this.deleteUser(user); 286 } 287 }); 288 }, 289 initModalSettings() { 290 this.setting = this.settings; 291 this.$bvModal.show('modal-settings'); 292 }, 293 saveUser({ isNewUser, userData }) { 294 this.startLoader(); 295 if (isNewUser) { 296 this.$store 297 .dispatch('userManagement/createUser', userData) 298 .then((success) => this.successToast(success)) 299 .catch(({ message }) => this.errorToast(message)) 300 .finally(() => this.endLoader()); 301 } else { 302 this.$store 303 .dispatch('userManagement/updateUser', userData) 304 .then((success) => this.successToast(success)) 305 .catch(({ message }) => this.errorToast(message)) 306 .finally(() => this.endLoader()); 307 } 308 }, 309 deleteUser({ username }) { 310 this.startLoader(); 311 this.$store 312 .dispatch('userManagement/deleteUser', username) 313 .then((success) => this.successToast(success)) 314 .catch(({ message }) => this.errorToast(message)) 315 .finally(() => this.endLoader()); 316 }, 317 onBatchAction(action) { 318 switch (action) { 319 case 'delete': 320 this.$bvModal 321 .msgBoxConfirm( 322 i18n.global.t( 323 'pageUserManagement.modal.batchDeleteConfirmMessage', 324 this.selectedRows.length, 325 ), 326 { 327 title: i18n.global.t( 328 'pageUserManagement.deleteUser', 329 this.selectedRows.length, 330 ), 331 okTitle: i18n.global.t( 332 'pageUserManagement.deleteUser', 333 this.selectedRows.length, 334 ), 335 cancelTitle: i18n.global.t('global.action.cancel'), 336 autoFocusButton: 'ok', 337 }, 338 ) 339 .then((deleteConfirmed) => { 340 if (deleteConfirmed) { 341 this.startLoader(); 342 this.$store 343 .dispatch('userManagement/deleteUsers', this.selectedRows) 344 .then((messages) => { 345 messages.forEach(({ type, message }) => { 346 if (type === 'success') this.successToast(message); 347 if (type === 'error') this.errorToast(message); 348 }); 349 }) 350 .finally(() => this.endLoader()); 351 } 352 }); 353 break; 354 case 'enable': 355 this.startLoader(); 356 this.$store 357 .dispatch('userManagement/enableUsers', this.selectedRows) 358 .then((messages) => { 359 messages.forEach(({ type, message }) => { 360 if (type === 'success') this.successToast(message); 361 if (type === 'error') this.errorToast(message); 362 }); 363 }) 364 .finally(() => this.endLoader()); 365 break; 366 case 'disable': 367 this.$bvModal 368 .msgBoxConfirm( 369 this.$tc( 370 'pageUserManagement.modal.batchDisableConfirmMessage', 371 this.selectedRows.length, 372 ), 373 { 374 title: this.$tc( 375 'pageUserManagement.disableUser', 376 this.selectedRows.length, 377 ), 378 okTitle: this.$tc( 379 'pageUserManagement.disableUser', 380 this.selectedRows.length, 381 ), 382 cancelTitle: this.$t('global.action.cancel'), 383 autoFocusButton: 'ok', 384 }, 385 ) 386 .then((disableConfirmed) => { 387 if (disableConfirmed) { 388 this.startLoader(); 389 this.$store 390 .dispatch('userManagement/disableUsers', this.selectedRows) 391 .then((messages) => { 392 messages.forEach(({ type, message }) => { 393 if (type === 'success') this.successToast(message); 394 if (type === 'error') this.errorToast(message); 395 }); 396 }) 397 .finally(() => this.endLoader()); 398 } 399 }); 400 break; 401 } 402 }, 403 onTableRowAction(action, row) { 404 switch (action) { 405 case 'edit': 406 this.initModalUser(row); 407 break; 408 case 'delete': 409 this.initModalDelete(row); 410 break; 411 default: 412 break; 413 } 414 }, 415 saveAccountSettings(settings) { 416 this.startLoader(); 417 this.$store 418 .dispatch('userManagement/saveAccountSettings', settings) 419 .then((message) => this.successToast(message)) 420 .catch(({ message }) => this.errorToast(message)) 421 .finally(() => this.endLoader()); 422 }, 423 }, 424}; 425</script> 426 427<style lang="scss" scoped> 428@import '@/assets/styles/bmc/helpers/_index.scss'; 429@import '@/assets/styles/bootstrap/_helpers.scss'; 430 431.btn.collapsed { 432 svg { 433 transform: rotate(180deg); 434 } 435} 436</style> 437