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