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 @change="$v.form.isUtcDisplay.$touch()" 102 > 103 {{ $t('pageProfileSettings.defaultUTC') }} 104 </b-form-radio> 105 <b-form-radio 106 v-model="form.isUtcDisplay" 107 :value="false" 108 data-test-id="profileSettings-radio-browserOffset" 109 @change="$v.form.isUtcDisplay.$touch()" 110 > 111 {{ 112 $t('pageProfileSettings.browserOffset', { 113 timezone 114 }) 115 }} 116 </b-form-radio> 117 </b-form-group> 118 </b-col> 119 </b-row> 120 </page-section> 121 <b-button 122 variant="primary" 123 type="submit" 124 data-test-id="profileSettings-button-saveSettings" 125 > 126 {{ $t('global.action.saveSettings') }} 127 </b-button> 128 </b-form> 129 </b-container> 130</template> 131 132<script> 133import i18n from '@/i18n'; 134import BVToastMixin from '@/components/Mixins/BVToastMixin'; 135import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; 136import { 137 maxLength, 138 minLength, 139 required, 140 sameAs 141} from 'vuelidate/lib/validators'; 142import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; 143import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin'; 144import PageTitle from '@/components/Global/PageTitle'; 145import PageSection from '@/components/Global/PageSection'; 146import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; 147 148export default { 149 name: 'ProfileSettings', 150 components: { InputPasswordToggle, PageSection, PageTitle }, 151 mixins: [ 152 BVToastMixin, 153 LocalTimezoneLabelMixin, 154 LoadingBarMixin, 155 VuelidateMixin 156 ], 157 data() { 158 return { 159 form: { 160 newPassword: '', 161 confirmPassword: '', 162 isUtcDisplay: this.$store.getters['global/isUtcDisplay'] 163 } 164 }; 165 }, 166 computed: { 167 username() { 168 return this.$store.getters['global/username']; 169 }, 170 passwordRequirements() { 171 return this.$store.getters['localUsers/accountPasswordRequirements']; 172 }, 173 timezone() { 174 return this.localOffset(); 175 } 176 }, 177 created() { 178 this.startLoader(); 179 this.$store 180 .dispatch('localUsers/getAccountSettings') 181 .finally(() => this.endLoader()); 182 }, 183 validations() { 184 return { 185 form: { 186 isUtcDisplay: { required }, 187 newPassword: { 188 minLength: minLength(this.passwordRequirements.minLength), 189 maxLength: maxLength(this.passwordRequirements.maxLength) 190 }, 191 confirmPassword: { 192 sameAsPassword: sameAs('newPassword') 193 } 194 } 195 }; 196 }, 197 methods: { 198 saveNewPasswordInputData() { 199 this.$v.form.confirmPassword.$touch(); 200 this.$v.form.newPassword.$touch(); 201 if (this.$v.$invalid) return; 202 let userData = { 203 originalUsername: this.username, 204 password: this.form.newPassword 205 }; 206 207 this.$store 208 .dispatch('localUsers/updateUser', userData) 209 .then(message => { 210 (this.form.newPassword = ''), (this.form.confirmPassword = ''); 211 this.$v.$reset(); 212 this.successToast(message); 213 }) 214 .catch(({ message }) => this.errorToast(message)); 215 }, 216 saveTimeZonePrefrenceData() { 217 localStorage.setItem('storedUtcDisplay', this.form.isUtcDisplay); 218 this.$store.commit('global/setUtcTime', this.form.isUtcDisplay); 219 this.successToast( 220 i18n.t('pageProfileSettings.toast.successSaveSettings') 221 ); 222 }, 223 submitForm() { 224 if (this.form.confirmPassword || this.form.newPassword) { 225 this.saveNewPasswordInputData(); 226 } 227 if (this.$v.form.isUtcDisplay.$anyDirty) { 228 this.saveTimeZonePrefrenceData(); 229 } 230 } 231 } 232}; 233</script> 234