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                  @input="$v.form.newPassword.$touch()"
48                />
49                <b-form-invalid-feedback role="alert">
50                  <template
51                    v-if="
52                      !$v.form.newPassword.minLength ||
53                        !$v.form.newPassword.maxLength
54                    "
55                  >
56                    {{
57                      $t('pageProfileSettings.newPassLabelTextInfo', {
58                        min: passwordRequirements.minLength,
59                        max: passwordRequirements.maxLength
60                      })
61                    }}
62                  </template>
63                </b-form-invalid-feedback>
64              </input-password-toggle>
65            </b-form-group>
66            <b-form-group
67              id="input-group-2"
68              :label="$t('pageProfileSettings.confirmPassword')"
69              label-for="input-2"
70            >
71              <input-password-toggle>
72                <b-form-input
73                  id="password-confirmation"
74                  v-model="form.confirmPassword"
75                  type="password"
76                  :state="getValidationState($v.form.confirmPassword)"
77                  data-test-id="profileSettings-input-confirmPassword"
78                  @input="$v.form.confirmPassword.$touch()"
79                />
80                <b-form-invalid-feedback role="alert">
81                  <template v-if="!$v.form.confirmPassword.sameAsPassword">
82                    {{ $t('pageProfileSettings.passwordsDoNotMatch') }}
83                  </template>
84                </b-form-invalid-feedback>
85              </input-password-toggle>
86            </b-form-group>
87          </page-section>
88        </b-col>
89      </b-row>
90      <page-section :section-title="$t('pageProfileSettings.timezoneDisplay')">
91        <p>{{ $t('pageProfileSettings.timezoneDisplayDesc') }}</p>
92        <b-row>
93          <b-col md="9" lg="8" xl="9">
94            <b-form-group :label="$t('pageProfileSettings.timezone')">
95              <b-form-radio
96                v-model="form.isUtcDisplay"
97                :value="true"
98                data-test-id="profileSettings-radio-defaultUTC"
99                @change="$v.form.isUtcDisplay.$touch()"
100              >
101                {{ $t('pageProfileSettings.defaultUTC') }}
102              </b-form-radio>
103              <b-form-radio
104                v-model="form.isUtcDisplay"
105                :value="false"
106                data-test-id="profileSettings-radio-browserOffset"
107                @change="$v.form.isUtcDisplay.$touch()"
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 {
135  maxLength,
136  minLength,
137  required,
138  sameAs
139} from 'vuelidate/lib/validators';
140import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
141import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin';
142import PageTitle from '@/components/Global/PageTitle';
143import PageSection from '@/components/Global/PageSection';
144import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
145
146export default {
147  name: 'ProfileSettings',
148  components: { InputPasswordToggle, PageSection, PageTitle },
149  mixins: [
150    BVToastMixin,
151    LocalTimezoneLabelMixin,
152    LoadingBarMixin,
153    VuelidateMixin
154  ],
155  data() {
156    return {
157      form: {
158        newPassword: '',
159        confirmPassword: '',
160        isUtcDisplay: this.$store.getters['global/isUtcDisplay']
161      }
162    };
163  },
164  computed: {
165    username() {
166      return this.$store.getters['global/username'];
167    },
168    passwordRequirements() {
169      return this.$store.getters['localUsers/accountPasswordRequirements'];
170    },
171    timezone() {
172      return this.localOffset();
173    }
174  },
175  created() {
176    this.startLoader();
177    this.$store
178      .dispatch('localUsers/getAccountSettings')
179      .finally(() => this.endLoader());
180  },
181  validations() {
182    return {
183      form: {
184        isUtcDisplay: { required },
185        newPassword: {
186          minLength: minLength(this.passwordRequirements.minLength),
187          maxLength: maxLength(this.passwordRequirements.maxLength)
188        },
189        confirmPassword: {
190          sameAsPassword: sameAs('newPassword')
191        }
192      }
193    };
194  },
195  methods: {
196    saveNewPasswordInputData() {
197      this.$v.form.confirmPassword.$touch();
198      this.$v.form.newPassword.$touch();
199      if (this.$v.$invalid) return;
200      let userData = {
201        originalUsername: this.username,
202        password: this.form.newPassword
203      };
204
205      this.$store
206        .dispatch('localUsers/updateUser', userData)
207        .then(message => {
208          (this.form.newPassword = ''), (this.form.confirmPassword = '');
209          this.$v.$reset();
210          this.successToast(message);
211        })
212        .catch(({ message }) => this.errorToast(message));
213    },
214    saveTimeZonePrefrenceData() {
215      localStorage.setItem('storedUtcDisplay', this.form.isUtcDisplay);
216      this.$store.commit('global/setUtcTime', this.form.isUtcDisplay);
217      this.successToast(
218        i18n.t('pageProfileSettings.toast.successSaveSettings')
219      );
220    },
221    submitForm() {
222      if (this.form.confirmPassword || this.form.newPassword) {
223        this.saveNewPasswordInputData();
224      }
225      if (this.$v.form.isUtcDisplay.$anyDirty) {
226        this.saveTimeZonePrefrenceData();
227      }
228    }
229  }
230};
231</script>
232