Skip to content
Snippets Groups Projects
Commit 5f7eb2b6 authored by Petar Hristov's avatar Petar Hristov :speech_balloon:
Browse files

Fix: User profile save button behavior

parent d046f8d8
No related branches found
No related tags found
2 merge requests!115Chore: 1.14.3,!112Fix: User profile save button behavior
......@@ -29,6 +29,7 @@ export default defineComponent({
moduleIsReady(): boolean {
return (
this.userStore.user !== null &&
this.userStore.userProfile.contactChange !== null &&
this.userStore.userProfile.disciplines !== null &&
this.userStore.userProfile.languages !== null &&
this.userStore.userProfile.titles !== null &&
......@@ -44,6 +45,7 @@ export default defineComponent({
methods: {
async initialize() {
await Promise.all([
this.userStore.retrieveContactChange(),
this.userStore.retrieveDisciplines(),
this.userStore.retrieveLanguages(),
this.userStore.retrieveMemberOrganizations(),
......
......@@ -18,7 +18,7 @@
>
<multiselect
id="title"
v-model="$v.form.title.$model"
v-model="v$.form.title.$model"
:options="titles"
:multiple="false"
label="displayName"
......@@ -65,9 +65,9 @@
>
<b-form-input
id="givenname"
v-model="$v.form.givenname.$model"
v-model="v$.form.givenname.$model"
:state="
$v.form.givenname.$dirty ? !$v.form.givenname.$invalid : null
v$.form.givenname.$dirty ? !v$.form.givenname.$invalid : null
"
:placeholder="
$t('page.userprofile.form.personalInformation.givenName')
......@@ -86,8 +86,8 @@
>
<b-form-input
id="surname"
v-model="$v.form.surname.$model"
:state="$v.form.surname.$dirty ? !$v.form.surname.$invalid : null"
v-model="v$.form.surname.$model"
:state="v$.form.surname.$dirty ? !v$.form.surname.$invalid : null"
:placeholder="
$t('page.userprofile.form.personalInformation.surname')
"
......@@ -105,10 +105,10 @@
>
<b-form-input
id="Email"
v-model="$v.form.emailAddress.$model"
v-model="v$.form.emailAddress.$model"
:state="
$v.form.emailAddress.$dirty || !profileForm.form.emailAddress
? !$v.form.emailAddress.$invalid
v$.form.emailAddress.$dirty || !form.emailAddress
? !v$.form.emailAddress.$invalid
: null
"
:placeholder="$t('page.userprofile.form.personalInformation.email')"
......@@ -131,7 +131,7 @@
<multiselect
v-if="externalUser"
id="organization"
v-model="$v.form.organization.$model"
v-model="v$.form.organization.$model"
:options="ror"
:multiple="false"
:loading="loadingOrganizations"
......@@ -182,10 +182,10 @@
<b-form-input
v-if="externalUser"
id="institute"
v-model="$v.form.institute.$model"
v-model="v$.form.institute.$model"
type="text"
:state="
$v.form.institute.$dirty ? !$v.form.institute.$invalid : null
v$.form.institute.$dirty ? !v$.form.institute.$invalid : null
"
:placeholder="
$t('page.userprofile.form.personalInformation.institute')
......@@ -219,7 +219,7 @@
>
<multiselect
id="Discipline"
v-model="$v.form.disciplines.$model"
v-model="v$.form.disciplines.$model"
:options="disciplines"
:multiple="true"
:label="disciplineLabel"
......@@ -266,21 +266,15 @@
id="language"
class="bv-no-focus-ring"
:checked="
profileForm.form.language && profileForm.form.language.id
? profileForm.form.language.id
: false
"
:state="
profileForm.form.language && profileForm.form.language.id
? null
: false
form.language && form.language.id ? form.language.id : false
"
:state="form.language && form.language.id ? null : false"
:options="languages"
name="radios-stacked"
text-field="displayName"
value-field="id"
stacked
@change="($event) => ($v.form.language.$model = { id: $event })"
@change="($event) => (v$.form.language.$model = { id: $event })"
/>
</coscine-form-group>
......@@ -340,7 +334,7 @@
variant="primary"
class="float-right"
name="save"
:disabled="$v.form.$invalid || savingProfile || !$v.form.$anyDirty"
:disabled="v$.form.$invalid || savingProfile || !v$.form.$anyDirty"
@click.prevent="clickSave"
>
{{ $t("buttons.save") }}
......@@ -353,9 +347,9 @@
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue-demi";
import { defineComponent } from "vue-demi";
import { required, email } from "@vuelidate/validators";
import { useVuelidate, Validation } from "@vuelidate/core";
import { useVuelidate } from "@vuelidate/core";
import AccessToken from "./components/AccessToken.vue";
import "@/plugins/deprecated/vue-multiselect";
......@@ -380,11 +374,12 @@ export default defineComponent({
const mainStore = useMainStore();
const userStore = useUserStore();
const notificationStore = useNotificationStore();
/*
Definition of the validation rules and initial state
will enable proper typings in the code
*/
const profileForm = reactive({
const v$ = useVuelidate();
return { mainStore, userStore, notificationStore, v$ };
},
data() {
return {
form: {
title: "",
givenname: "",
......@@ -395,26 +390,6 @@ export default defineComponent({
disciplines: [] as DisciplineObject[],
language: {} as LanguageObject,
} as UserObject,
});
const profileRules = {
form: {
title: {},
givenname: { required },
surname: { required },
emailAddress: { email, required },
organization: { required },
institute: { required },
disciplines: { required },
language: { id: {} },
},
};
const $v = useVuelidate(profileRules, profileForm) as Validation<
typeof profileRules
>;
return { mainStore, userStore, notificationStore, $v, profileForm };
},
data() {
return {
isLoading: false,
savingProfile: false,
currentUserComponent: "UserProfileComponent",
......@@ -432,7 +407,7 @@ export default defineComponent({
return this.userStore.userProfile.disciplines;
},
emailHint(): string {
if (!this.profileForm.form.emailAddress) {
if (!this.form.emailAddress) {
return this.$t(
"page.userprofile.form.personalInformation.emailChange.noAddress"
).toString();
......@@ -510,6 +485,24 @@ export default defineComponent({
return this.userStore.user ? this.userStore.user : {};
},
},
validations() {
const organizationValidator = (value: string) =>
!!value || this.organizations.length > 0;
const instituteValidator = (value: string) =>
!!value || this.institutes.length > 0;
return {
form: {
title: {},
givenname: { required },
surname: { required },
emailAddress: { email, required },
organization: { organizationValidator },
institute: { instituteValidator },
disciplines: { required },
language: { id: {} },
},
};
},
watch: {
user() {
this.cloneUser();
......@@ -526,7 +519,7 @@ export default defineComponent({
methods: {
cloneUser() {
if (this.user !== null) {
Object.assign(this.profileForm.form, this.user);
Object.assign(this.form, this.user);
}
},
async clickConnect(provider: string) {
......@@ -534,21 +527,15 @@ export default defineComponent({
location.href = "/coscine/api/Coscine.Api.STS/account/logout";
},
async clickSave() {
this.$v.form.$touch();
if (!this.$v.form.$invalid && this.$v.form.$anyDirty) {
this.v$.form.$touch();
if (!this.v$.form.$invalid && this.v$.form.$anyDirty) {
this.savingProfile = true;
// SECTION FOR SAVING ANY EMAIL CHANGES
// SIDE EFFECT: NO OTHER FIELD CHANGE CAN BE SAVED TOGETHER WITH A CHANGE OF THE EMAIL ADDRESS
// TODO
if (
this.profileForm.form.emailAddress &&
this.profileForm.form.emailAddress !== this.user.emailAddress
this.form.emailAddress &&
this.form.emailAddress !== this.user.emailAddress
) {
await this.userStore.updateEmail(this.profileForm.form.emailAddress);
await Promise.all([
this.userStore.retrieveContactChange(),
this.userStore.retrieveUser(),
]);
await this.userStore.updateEmail(this.form.emailAddress);
this.notificationStore.postNotification({
title: this.$t(
"page.userprofile.form.personalInformation.emailChange.changedTitle"
......@@ -559,12 +546,10 @@ export default defineComponent({
});
}
// SECTION FOR SAVING THE REST OF THE FIELDS
const updatedUser = await this.userStore.updateUser(
this.profileForm.form
);
const updatedUser = await this.userStore.updateUser(this.form);
if (updatedUser) {
// On Success
this.$v.form.$reset();
this.v$.form.$reset();
this.notificationStore.postNotification({
title: this.$t("toast.onSave.success.title").toString(),
body: this.$t("toast.onSave.success.message").toString(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment