1<template> 2 <b-container fluid="xl"> 3 <page-title /> 4 5 <b-row> 6 <b-col md="8" lg="8" xl="6"> 7 <page-section 8 :section-title="$t('pageProfileSettings.profileInfoTitle')" 9 > 10 <dl> 11 <dt>{{ $t('pageProfileSettings.username') }}</dt> 12 <dd> 13 {{ username }} 14 </dd> 15 </dl> 16 </page-section> 17 </b-col> 18 </b-row> 19 20 <b-form @submit.prevent="submitForm"> 21 <b-row> 22 <b-col sm="8" md="6" xl="3"> 23 <page-section 24 :section-title="$t('pageProfileSettings.changePassword')" 25 > 26 <b-form-group 27 id="input-group-1" 28 :label="$t('pageProfileSettings.newPassword')" 29 label-for="input-1" 30 > 31 <b-form-text id="password-help-block"> 32 {{ 33 $t('pageLocalUserManagement.modal.passwordMustBeBetween', { 34 min: passwordRequirements.minLength, 35 max: passwordRequirements.maxLength, 36 }) 37 }} 38 </b-form-text> 39 <input-password-toggle> 40 <b-form-input 41 id="password" 42 v-model="form.newPassword" 43 type="password" 44 aria-describedby="password-help-block" 45 :state="getValidationState($v.form.newPassword)" 46 data-test-id="profileSettings-input-newPassword" 47 class="form-control-with-button" 48 @input="$v.form.newPassword.$touch()" 49 /> 50 <b-form-invalid-feedback role="alert"> 51 <template 52 v-if=" 53 !$v.form.newPassword.minLength || 54 !$v.form.newPassword.maxLength 55 " 56 > 57 {{ 58 $t('pageProfileSettings.newPassLabelTextInfo', { 59 min: passwordRequirements.minLength, 60 max: passwordRequirements.maxLength, 61 }) 62 }} 63 </template> 64 </b-form-invalid-feedback> 65 </input-password-toggle> 66 </b-form-group> 67 <b-form-group 68 id="input-group-2" 69 :label="$t('pageProfileSettings.confirmPassword')" 70 label-for="input-2" 71 > 72 <input-password-toggle> 73 <b-form-input 74 id="password-confirmation" 75 v-model="form.confirmPassword" 76 type="password" 77 :state="getValidationState($v.form.confirmPassword)" 78 data-test-id="profileSettings-input-confirmPassword" 79 class="form-control-with-button" 80 @input="$v.form.confirmPassword.$touch()" 81 /> 82 <b-form-invalid-feedback role="alert"> 83 <template v-if="!$v.form.confirmPassword.sameAsPassword"> 84 {{ $t('pageProfileSettings.passwordsDoNotMatch') }} 85 </template> 86 </b-form-invalid-feedback> 87 </input-password-toggle> 88 </b-form-group> 89 </page-section> 90 </b-col> 91 </b-row> 92 <page-section :section-title="$t('pageProfileSettings.timezoneDisplay')"> 93 <p>{{ $t('pageProfileSettings.timezoneDisplayDesc') }}</p> 94 <b-row> 95 <b-col md="9" lg="8" xl="9"> 96 <b-form-group :label="$t('pageProfileSettings.timezone')"> 97 <b-form-radio 98 v-model="form.isUtcDisplay" 99 :value="true" 100 data-test-id="profileSettings-radio-defaultUTC" 101 > 102 {{ $t('pageProfileSettings.defaultUTC') }} 103 </b-form-radio> 104 <b-form-radio 105 v-model="form.isUtcDisplay" 106 :value="false" 107 data-test-id="profileSettings-radio-browserOffset" 108 > 109 {{ 110 $t('pageProfileSettings.browserOffset', { 111 timezone, 112 }) 113 }} 114 </b-form-radio> 115 </b-form-group> 116 </b-col> 117 </b-row> 118 </page-section> 119 <b-button 120 variant="primary" 121 type="submit" 122 data-test-id="profileSettings-button-saveSettings" 123 > 124 {{ $t('global.action.saveSettings') }} 125 </b-button> 126 </b-form> 127 </b-container> 128</template> 129 130<script> 131import BVToastMixin from '@/components/Mixins/BVToastMixin'; 132import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; 133import { maxLength, minLength, sameAs } from 'vuelidate/lib/validators'; 134import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; 135import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin'; 136import PageTitle from '@/components/Global/PageTitle'; 137import PageSection from '@/components/Global/PageSection'; 138import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; 139 140export default { 141 name: 'ProfileSettings', 142 components: { InputPasswordToggle, PageSection, PageTitle }, 143 mixins: [ 144 BVToastMixin, 145 LocalTimezoneLabelMixin, 146 LoadingBarMixin, 147 VuelidateMixin, 148 ], 149 data() { 150 return { 151 form: { 152 newPassword: '', 153 confirmPassword: '', 154 isUtcDisplay: this.$store.getters['global/isUtcDisplay'], 155 }, 156 }; 157 }, 158 computed: { 159 username() { 160 return this.$store.getters['global/username']; 161 }, 162 passwordRequirements() { 163 return this.$store.getters['localUsers/accountPasswordRequirements']; 164 }, 165 timezone() { 166 return this.localOffset(); 167 }, 168 }, 169 created() { 170 this.startLoader(); 171 this.$store 172 .dispatch('localUsers/getAccountSettings') 173 .finally(() => this.endLoader()); 174 }, 175 validations() { 176 return { 177 form: { 178 newPassword: { 179 minLength: minLength(this.passwordRequirements.minLength), 180 maxLength: maxLength(this.passwordRequirements.maxLength), 181 }, 182 confirmPassword: { 183 sameAsPassword: sameAs('newPassword'), 184 }, 185 }, 186 }; 187 }, 188 methods: { 189 saveNewPasswordInputData() { 190 this.$v.form.confirmPassword.$touch(); 191 this.$v.form.newPassword.$touch(); 192 if (this.$v.$invalid) return; 193 let userData = { 194 originalUsername: this.username, 195 password: this.form.newPassword, 196 }; 197 198 this.$store 199 .dispatch('localUsers/updateUser', userData) 200 .then((message) => { 201 (this.form.newPassword = ''), (this.form.confirmPassword = ''); 202 this.$v.$reset(); 203 this.successToast(message); 204 }) 205 .catch(({ message }) => this.errorToast(message)); 206 }, 207 saveTimeZonePrefrenceData() { 208 localStorage.setItem('storedUtcDisplay', this.form.isUtcDisplay); 209 this.$store.commit('global/setUtcTime', this.form.isUtcDisplay); 210 this.successToast( 211 this.$t('pageProfileSettings.toast.successSaveSettings') 212 ); 213 }, 214 submitForm() { 215 if (this.form.confirmPassword || this.form.newPassword) { 216 this.saveNewPasswordInputData(); 217 } 218 this.saveTimeZonePrefrenceData(); 219 }, 220 }, 221}; 222</script> 223