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-0"
28              :label="$t('pageProfileSettings.currentPassword')"
29              label-for="input-0"
30            >
31              <input-password-toggle>
32                <b-form-input
33                  id="old-password"
34                  v-model="form.currentPassword"
35                  type="password"
36                  data-test-id="profileSettings-input-ocurrentPassword"
37                  class="form-control-with-button"
38                />
39              </input-password-toggle>
40            </b-form-group>
41            <b-form-group
42              id="input-group-1"
43              :label="$t('pageProfileSettings.newPassword')"
44              label-for="input-1"
45            >
46              <b-form-text id="password-help-block">
47                {{
48                  $t('pageUserManagement.modal.passwordMustBeBetween', {
49                    min: passwordRequirements.minLength,
50                    max: passwordRequirements.maxLength,
51                  })
52                }}
53              </b-form-text>
54              <input-password-toggle>
55                <b-form-input
56                  id="password"
57                  v-model="form.newPassword"
58                  type="password"
59                  aria-describedby="password-help-block"
60                  :state="getValidationState($v.form.newPassword)"
61                  data-test-id="profileSettings-input-newPassword"
62                  class="form-control-with-button"
63                  @input="$v.form.newPassword.$touch()"
64                />
65                <b-form-invalid-feedback role="alert">
66                  <template
67                    v-if="
68                      !$v.form.newPassword.minLength ||
69                      !$v.form.newPassword.maxLength
70                    "
71                  >
72                    {{
73                      $t('pageProfileSettings.newPassLabelTextInfo', {
74                        min: passwordRequirements.minLength,
75                        max: passwordRequirements.maxLength,
76                      })
77                    }}
78                  </template>
79                </b-form-invalid-feedback>
80              </input-password-toggle>
81            </b-form-group>
82            <b-form-group
83              id="input-group-2"
84              :label="$t('pageProfileSettings.confirmPassword')"
85              label-for="input-2"
86            >
87              <input-password-toggle>
88                <b-form-input
89                  id="password-confirmation"
90                  v-model="form.confirmPassword"
91                  type="password"
92                  :state="getValidationState($v.form.confirmPassword)"
93                  data-test-id="profileSettings-input-confirmPassword"
94                  class="form-control-with-button"
95                  @input="$v.form.confirmPassword.$touch()"
96                />
97                <b-form-invalid-feedback role="alert">
98                  <template v-if="!$v.form.confirmPassword.sameAsPassword">
99                    {{ $t('pageProfileSettings.passwordsDoNotMatch') }}
100                  </template>
101                </b-form-invalid-feedback>
102              </input-password-toggle>
103            </b-form-group>
104          </page-section>
105        </b-col>
106      </b-row>
107      <page-section :section-title="$t('pageProfileSettings.timezoneDisplay')">
108        <p>{{ $t('pageProfileSettings.timezoneDisplayDesc') }}</p>
109        <b-row>
110          <b-col md="9" lg="8" xl="9">
111            <b-form-group :label="$t('pageProfileSettings.timezone')">
112              <b-form-radio
113                v-model="form.isUtcDisplay"
114                :value="true"
115                data-test-id="profileSettings-radio-defaultUTC"
116              >
117                {{ $t('pageProfileSettings.defaultUTC') }}
118              </b-form-radio>
119              <b-form-radio
120                v-model="form.isUtcDisplay"
121                :value="false"
122                data-test-id="profileSettings-radio-browserOffset"
123              >
124                {{
125                  $t('pageProfileSettings.browserOffset', {
126                    timezone,
127                  })
128                }}
129              </b-form-radio>
130            </b-form-group>
131          </b-col>
132        </b-row>
133      </page-section>
134      <b-button
135        variant="primary"
136        type="submit"
137        data-test-id="profileSettings-button-saveSettings"
138      >
139        {{ $t('global.action.saveSettings') }}
140      </b-button>
141    </b-form>
142  </b-container>
143</template>
144
145<script>
146import BVToastMixin from '@/components/Mixins/BVToastMixin';
147import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
148import { maxLength, minLength, sameAs } from 'vuelidate/lib/validators';
149import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
150import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin';
151import PageTitle from '@/components/Global/PageTitle';
152import PageSection from '@/components/Global/PageSection';
153import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
154
155export default {
156  name: 'ProfileSettings',
157  components: { InputPasswordToggle, PageSection, PageTitle },
158  mixins: [
159    BVToastMixin,
160    LocalTimezoneLabelMixin,
161    LoadingBarMixin,
162    VuelidateMixin,
163  ],
164  data() {
165    return {
166      form: {
167        newPassword: '',
168        confirmPassword: '',
169        currentPassword: '',
170        isUtcDisplay: this.$store.getters['global/isUtcDisplay'],
171      },
172    };
173  },
174  computed: {
175    username() {
176      return this.$store.getters['global/username'];
177    },
178    passwordRequirements() {
179      return this.$store.getters['userManagement/accountPasswordRequirements'];
180    },
181    timezone() {
182      return this.localOffset();
183    },
184  },
185  created() {
186    this.startLoader();
187    this.$store
188      .dispatch('userManagement/getAccountSettings')
189      .finally(() => this.endLoader());
190  },
191  validations() {
192    return {
193      form: {
194        newPassword: {
195          minLength: minLength(this.passwordRequirements.minLength),
196          maxLength: maxLength(this.passwordRequirements.maxLength),
197        },
198        confirmPassword: {
199          sameAsPassword: sameAs('newPassword'),
200        },
201      },
202    };
203  },
204  methods: {
205    saveNewPasswordInputData() {
206      this.$v.form.confirmPassword.$touch();
207      this.$v.form.newPassword.$touch();
208      if (this.$v.$invalid) return;
209      let userData = {
210        originalUsername: this.username,
211        password: this.form.newPassword,
212      };
213
214      this.$store
215        .dispatch('userManagement/updateUser', userData)
216        .then((message) => {
217          (this.form.newPassword = ''),
218            (this.form.confirmPassword = ''),
219            (this.form.currentPassword = '');
220          this.$v.$reset();
221          this.successToast(message);
222          this.$store.dispatch('authentication/logout');
223        })
224        .catch(({ message }) => this.errorToast(message));
225    },
226    saveTimeZonePrefrenceData() {
227      localStorage.setItem('storedUtcDisplay', this.form.isUtcDisplay);
228      this.$store.commit('global/setUtcTime', this.form.isUtcDisplay);
229      this.successToast(
230        this.$t('pageProfileSettings.toast.successUpdatingTimeZone')
231      );
232    },
233    submitForm() {
234      if (
235        this.form.confirmPassword &&
236        this.form.newPassword &&
237        this.form.currentPassword
238      ) {
239        this.confirmAuthenticate();
240      }
241      if (
242        this.$store.getters['global/isUtcDisplay'] != this.form.isUtcDisplay
243      ) {
244        this.saveTimeZonePrefrenceData();
245      }
246    },
247    confirmAuthenticate() {
248      this.$v.form.newPassword.$touch();
249      if (this.$v.$invalid) return;
250
251      const username = this.username;
252      const password = this.form.currentPassword;
253
254      this.$store
255        .dispatch('authentication/login', { username, password })
256        .then(() => {
257          this.saveNewPasswordInputData();
258        })
259        .catch(() => {
260          this.$v.$reset();
261          this.errorToast(
262            this.$t('pageProfileSettings.toast.wrongCredentials')
263          );
264        });
265    },
266  },
267};
268</script>
269