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