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 i18n from '@/i18n'; 132import BVToastMixin from '@/components/Mixins/BVToastMixin'; 133import InputPasswordToggle from '@/components/Global/InputPasswordToggle'; 134import { maxLength, minLength, sameAs } from 'vuelidate/lib/validators'; 135import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; 136import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin'; 137import PageTitle from '@/components/Global/PageTitle'; 138import PageSection from '@/components/Global/PageSection'; 139import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; 140 141export default { 142 name: 'ProfileSettings', 143 components: { InputPasswordToggle, PageSection, PageTitle }, 144 mixins: [ 145 BVToastMixin, 146 LocalTimezoneLabelMixin, 147 LoadingBarMixin, 148 VuelidateMixin, 149 ], 150 data() { 151 return { 152 form: { 153 newPassword: '', 154 confirmPassword: '', 155 isUtcDisplay: this.$store.getters['global/isUtcDisplay'], 156 }, 157 }; 158 }, 159 computed: { 160 username() { 161 return this.$store.getters['global/username']; 162 }, 163 passwordRequirements() { 164 return this.$store.getters['localUsers/accountPasswordRequirements']; 165 }, 166 timezone() { 167 return this.localOffset(); 168 }, 169 }, 170 created() { 171 this.startLoader(); 172 this.$store 173 .dispatch('localUsers/getAccountSettings') 174 .finally(() => this.endLoader()); 175 }, 176 validations() { 177 return { 178 form: { 179 newPassword: { 180 minLength: minLength(this.passwordRequirements.minLength), 181 maxLength: maxLength(this.passwordRequirements.maxLength), 182 }, 183 confirmPassword: { 184 sameAsPassword: sameAs('newPassword'), 185 }, 186 }, 187 }; 188 }, 189 methods: { 190 saveNewPasswordInputData() { 191 this.$v.form.confirmPassword.$touch(); 192 this.$v.form.newPassword.$touch(); 193 if (this.$v.$invalid) return; 194 let userData = { 195 originalUsername: this.username, 196 password: this.form.newPassword, 197 }; 198 199 this.$store 200 .dispatch('localUsers/updateUser', userData) 201 .then((message) => { 202 (this.form.newPassword = ''), (this.form.confirmPassword = ''); 203 this.$v.$reset(); 204 this.successToast(message); 205 }) 206 .catch(({ message }) => this.errorToast(message)); 207 }, 208 saveTimeZonePrefrenceData() { 209 localStorage.setItem('storedUtcDisplay', this.form.isUtcDisplay); 210 this.$store.commit('global/setUtcTime', this.form.isUtcDisplay); 211 this.successToast( 212 i18n.t('pageProfileSettings.toast.successSaveSettings') 213 ); 214 }, 215 submitForm() { 216 if (this.form.confirmPassword || this.form.newPassword) { 217 this.saveNewPasswordInputData(); 218 } 219 this.saveTimeZonePrefrenceData(); 220 }, 221 }, 222}; 223</script> 224