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