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