1<template> 2 <b-modal id="modal-user" ref="modal" @hidden="resetForm"> 3 <template #modal-title> 4 <template v-if="newUser"> 5 {{ $t('pageUserManagement.addUser') }} 6 </template> 7 <template v-else> 8 {{ $t('pageUserManagement.editUser') }} 9 </template> 10 </template> 11 <b-form id="form-user" novalidate @submit.prevent="handleSubmit"> 12 <b-container> 13 <!-- Manual unlock form control --> 14 <b-row v-if="!newUser && manualUnlockPolicy && user.Locked"> 15 <b-col sm="9"> 16 <alert :show="true" variant="warning" small> 17 <template v-if="!$v.form.manualUnlock.$dirty"> 18 {{ $t('pageUserManagement.modal.accountLocked') }} 19 </template> 20 <template v-else> 21 {{ $t('pageUserManagement.modal.clickSaveToUnlockAccount') }} 22 </template> 23 </alert> 24 </b-col> 25 <b-col sm="3"> 26 <input 27 v-model="form.manualUnlock" 28 data-test-id="userManagement-input-manualUnlock" 29 type="hidden" 30 value="false" 31 /> 32 <b-button 33 variant="primary" 34 :disabled="$v.form.manualUnlock.$dirty" 35 data-test-id="userManagement-button-manualUnlock" 36 @click="$v.form.manualUnlock.$touch()" 37 > 38 {{ $t('pageUserManagement.modal.unlock') }} 39 </b-button> 40 </b-col> 41 </b-row> 42 <b-row> 43 <b-col> 44 <b-form-group :label="$t('pageUserManagement.modal.accountStatus')"> 45 <b-form-radio 46 v-model="form.status" 47 name="user-status" 48 :value="true" 49 data-test-id="userManagement-radioButton-statusEnabled" 50 @input="$v.form.status.$touch()" 51 > 52 {{ $t('global.status.enabled') }} 53 </b-form-radio> 54 <b-form-radio 55 v-model="form.status" 56 name="user-status" 57 data-test-id="userManagement-radioButton-statusDisabled" 58 :value="false" 59 :disabled="!newUser && originalUsername === disabled" 60 @input="$v.form.status.$touch()" 61 > 62 {{ $t('global.status.disabled') }} 63 </b-form-radio> 64 </b-form-group> 65 <b-form-group 66 :label="$t('pageUserManagement.modal.username')" 67 label-for="username" 68 > 69 <b-form-text id="username-help-block"> 70 {{ $t('pageUserManagement.modal.cannotStartWithANumber') }} 71 <br /> 72 {{ 73 $t( 74 'pageUserManagement.modal.noSpecialCharactersExceptUnderscore' 75 ) 76 }} 77 </b-form-text> 78 <b-form-input 79 id="username" 80 v-model="form.username" 81 type="text" 82 aria-describedby="username-help-block" 83 data-test-id="userManagement-input-username" 84 :state="getValidationState($v.form.username)" 85 :disabled="!newUser && originalUsername === disabled" 86 @input="$v.form.username.$touch()" 87 /> 88 <b-form-invalid-feedback role="alert"> 89 <template v-if="!$v.form.username.required"> 90 {{ $t('global.form.fieldRequired') }} 91 </template> 92 <template v-else-if="!$v.form.username.maxLength"> 93 {{ 94 $t('global.form.lengthMustBeBetween', { min: 1, max: 16 }) 95 }} 96 </template> 97 <template v-else-if="!$v.form.username.pattern"> 98 {{ $t('global.form.invalidFormat') }} 99 </template> 100 </b-form-invalid-feedback> 101 </b-form-group> 102 <b-form-group 103 :label="$t('pageUserManagement.modal.privilege')" 104 label-for="privilege" 105 > 106 <b-form-select 107 id="privilege" 108 v-model="form.privilege" 109 :options="privilegeTypes" 110 data-test-id="userManagement-select-privilege" 111 :state="getValidationState($v.form.privilege)" 112 @input="$v.form.privilege.$touch()" 113 > 114 <template #first> 115 <b-form-select-option :value="null" disabled> 116 {{ $t('global.form.selectAnOption') }} 117 </b-form-select-option> 118 </template> 119 </b-form-select> 120 <b-form-invalid-feedback role="alert"> 121 <template v-if="!$v.form.privilege.required"> 122 {{ $t('global.form.fieldRequired') }} 123 </template> 124 </b-form-invalid-feedback> 125 </b-form-group> 126 </b-col> 127 <b-col> 128 <b-form-group 129 :label="$t('pageUserManagement.modal.userPassword')" 130 label-for="password" 131 > 132 <b-form-text id="password-help-block"> 133 {{ 134 $t('pageUserManagement.modal.passwordMustBeBetween', { 135 min: passwordRequirements.minLength, 136 max: passwordRequirements.maxLength, 137 }) 138 }} 139 </b-form-text> 140 <input-password-toggle> 141 <b-form-input 142 id="password" 143 v-model="form.password" 144 type="password" 145 data-test-id="userManagement-input-password" 146 aria-describedby="password-help-block" 147 :state="getValidationState($v.form.password)" 148 class="form-control-with-button" 149 @input="$v.form.password.$touch()" 150 /> 151 <b-form-invalid-feedback role="alert"> 152 <template v-if="!$v.form.password.required"> 153 {{ $t('global.form.fieldRequired') }} 154 </template> 155 <template 156 v-if=" 157 !$v.form.password.minLength || !$v.form.password.maxLength 158 " 159 > 160 {{ 161 $t('pageUserManagement.modal.passwordMustBeBetween', { 162 min: passwordRequirements.minLength, 163 max: passwordRequirements.maxLength, 164 }) 165 }} 166 </template> 167 </b-form-invalid-feedback> 168 </input-password-toggle> 169 </b-form-group> 170 <b-form-group 171 :label="$t('pageUserManagement.modal.confirmUserPassword')" 172 label-for="password-confirmation" 173 > 174 <input-password-toggle> 175 <b-form-input 176 id="password-confirmation" 177 v-model="form.passwordConfirmation" 178 data-test-id="userManagement-input-passwordConfirmation" 179 type="password" 180 :state="getValidationState($v.form.passwordConfirmation)" 181 class="form-control-with-button" 182 @input="$v.form.passwordConfirmation.$touch()" 183 /> 184 <b-form-invalid-feedback role="alert"> 185 <template v-if="!$v.form.passwordConfirmation.required"> 186 {{ $t('global.form.fieldRequired') }} 187 </template> 188 <template 189 v-else-if="!$v.form.passwordConfirmation.sameAsPassword" 190 > 191 {{ $t('pageUserManagement.modal.passwordsDoNotMatch') }} 192 </template> 193 </b-form-invalid-feedback> 194 </input-password-toggle> 195 </b-form-group> 196 </b-col> 197 </b-row> 198 </b-container> 199 </b-form> 200 <template #modal-footer="{ cancel }"> 201 <b-button 202 variant="secondary" 203 data-test-id="userManagement-button-cancel" 204 @click="cancel()" 205 > 206 {{ $t('global.action.cancel') }} 207 </b-button> 208 <b-button 209 form="form-user" 210 data-test-id="userManagement-button-submit" 211 type="submit" 212 variant="primary" 213 @click="onOk" 214 > 215 <template v-if="newUser"> 216 {{ $t('pageUserManagement.addUser') }} 217 </template> 218 <template v-else> 219 {{ $t('global.action.save') }} 220 </template> 221 </b-button> 222 </template> 223 </b-modal> 224</template> 225 226<script> 227import { 228 required, 229 maxLength, 230 minLength, 231 sameAs, 232 helpers, 233 requiredIf, 234} from 'vuelidate/lib/validators'; 235import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; 236import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; 237import Alert from '@/components/Global/Alert'; 238 239export default { 240 components: { Alert, InputPasswordToggle }, 241 mixins: [VuelidateMixin], 242 props: { 243 user: { 244 type: Object, 245 default: null, 246 }, 247 passwordRequirements: { 248 type: Object, 249 required: true, 250 }, 251 }, 252 data() { 253 return { 254 originalUsername: '', 255 form: { 256 status: true, 257 username: '', 258 privilege: null, 259 password: '', 260 passwordConfirmation: '', 261 manualUnlock: false, 262 }, 263 disabled: this.$store.getters['global/username'], 264 }; 265 }, 266 computed: { 267 newUser() { 268 return this.user ? false : true; 269 }, 270 accountSettings() { 271 return this.$store.getters['userManagement/accountSettings']; 272 }, 273 manualUnlockPolicy() { 274 return !this.accountSettings.accountLockoutDuration; 275 }, 276 privilegeTypes() { 277 return this.$store.getters['userManagement/accountRoles']; 278 }, 279 }, 280 watch: { 281 user: function (value) { 282 if (value === null) return; 283 this.originalUsername = value.username; 284 this.form.username = value.username; 285 this.form.status = value.Enabled; 286 this.form.privilege = value.privilege; 287 }, 288 }, 289 validations() { 290 return { 291 form: { 292 status: { 293 required, 294 }, 295 username: { 296 required, 297 maxLength: maxLength(16), 298 pattern: helpers.regex('pattern', /^([a-zA-Z_][a-zA-Z0-9_]*)/), 299 }, 300 privilege: { 301 required, 302 }, 303 password: { 304 required: requiredIf(function () { 305 return this.requirePassword(); 306 }), 307 minLength: minLength(this.passwordRequirements.minLength), 308 maxLength: maxLength(this.passwordRequirements.maxLength), 309 }, 310 passwordConfirmation: { 311 required: requiredIf(function () { 312 return this.requirePassword(); 313 }), 314 sameAsPassword: sameAs('password'), 315 }, 316 manualUnlock: {}, 317 }, 318 }; 319 }, 320 methods: { 321 handleSubmit() { 322 let userData = {}; 323 324 if (this.newUser) { 325 this.$v.$touch(); 326 if (this.$v.$invalid) return; 327 userData.username = this.form.username; 328 userData.status = this.form.status; 329 userData.privilege = this.form.privilege; 330 userData.password = this.form.password; 331 } else { 332 if (this.$v.$invalid) return; 333 userData.originalUsername = this.originalUsername; 334 if (this.$v.form.status.$dirty) { 335 userData.status = this.form.status; 336 } 337 if (this.$v.form.username.$dirty) { 338 userData.username = this.form.username; 339 } 340 if (this.$v.form.privilege.$dirty) { 341 userData.privilege = this.form.privilege; 342 } 343 if (this.$v.form.password.$dirty) { 344 userData.password = this.form.password; 345 } 346 if (this.$v.form.manualUnlock.$dirty) { 347 // If form manualUnlock control $dirty then 348 // set user Locked property to false 349 userData.locked = false; 350 } 351 if (Object.entries(userData).length === 1) { 352 this.closeModal(); 353 return; 354 } 355 } 356 357 this.$emit('ok', { isNewUser: this.newUser, userData }); 358 this.closeModal(); 359 }, 360 closeModal() { 361 this.$nextTick(() => { 362 this.$refs.modal.hide(); 363 }); 364 }, 365 resetForm() { 366 this.form.originalUsername = ''; 367 this.form.status = true; 368 this.form.username = ''; 369 this.form.privilege = null; 370 this.form.password = ''; 371 this.form.passwordConfirmation = ''; 372 this.$v.$reset(); 373 this.$emit('hidden'); 374 }, 375 requirePassword() { 376 if (this.newUser) return true; 377 if (this.$v.form.password.$dirty) return true; 378 if (this.$v.form.passwordConfirmation.$dirty) return true; 379 return false; 380 }, 381 onOk(bvModalEvt) { 382 // prevent modal close 383 bvModalEvt.preventDefault(); 384 this.handleSubmit(); 385 }, 386 }, 387}; 388</script> 389