fix "impossible to confirm a course"

In some case, the "confirm" button for the form AccompanyingCourse was
disable, due to wrong condition.

This commit also fixes the filtering for users, and allow to remove a
user associated with an accompanyingCourse.
This commit is contained in:
Julien Fastré 2022-02-07 17:44:03 +01:00
parent f9b514c869
commit 03007370bc
5 changed files with 189 additions and 160 deletions

View File

@ -91,8 +91,8 @@ export const multiSelectMessages = {
multiselect: { multiselect: {
placeholder: 'Choisir', placeholder: 'Choisir',
tag_placeholder: 'Créer un nouvel élément', tag_placeholder: 'Créer un nouvel élément',
select_label: 'Appuyer sur "Entrée" pour sélectionner', select_label: '"Entrée" ou cliquez pour sélectionner',
deselect_label: 'Appuyer sur "Entrée" pour désélectionner', deselect_label: '"Entrée" ou cliquez pour désélectionner',
select_group_label: 'Appuyer sur "Entrée" pour sélectionner ce groupe', select_group_label: 'Appuyer sur "Entrée" pour sélectionner ce groupe',
deselect_group_label: 'Appuyer sur "Entrée" pour désélectionner ce groupe', deselect_group_label: 'Appuyer sur "Entrée" pour désélectionner ce groupe',
selected_label: 'Sélectionné' selected_label: 'Sélectionné'

View File

@ -60,14 +60,14 @@
<template v-slot:body> <template v-slot:body>
<p>{{ $t('confirm.sure_description') }}</p> <p>{{ $t('confirm.sure_description') }}</p>
<div v-if="accompanyingCourse.user === null"> <div v-if="accompanyingCourse.user === null">
<div v-if="filteredReferrersSuggested.length === 0"> <div v-if="usersSuggestedFilteredByJob.length === 0">
<p class="alert alert-warning">{{ $t('confirm.no_suggested_referrer') }}</p> <p class="alert alert-warning">{{ $t('confirm.no_suggested_referrer') }}</p>
</div> </div>
<div v-if="filteredReferrersSuggested.length === 1" class="alert alert-info"> <div v-if="usersSuggestedFilteredByJob.length === 1" class="alert alert-info">
<p>{{ $t('confirm.one_suggested_referrer') }}:</p> <p>{{ $t('confirm.one_suggested_referrer') }}:</p>
<ul class="list-suggest add-items inline"> <ul class="list-suggest add-items inline">
<li> <li>
<user-render-box-badge :user="filteredReferrersSuggested[0]"></user-render-box-badge> <user-render-box-badge :user="usersSuggestedFilteredByJob[0]"></user-render-box-badge>
</li> </li>
</ul> </ul>
<p>{{ $t('confirm.choose_suggested_referrer') }}</p> <p>{{ $t('confirm.choose_suggested_referrer') }}</p>
@ -150,7 +150,6 @@ export default {
computed: { computed: {
...mapState({ ...mapState({
accompanyingCourse: state => state.accompanyingCourse, accompanyingCourse: state => state.accompanyingCourse,
filteredReferrersSuggested: state => state.filteredReferrersSuggested
}), }),
...mapGetters([ ...mapGetters([
'isParticipationValid', 'isParticipationValid',
@ -160,15 +159,16 @@ export default {
'isLocationValid', 'isLocationValid',
'isJobValid', 'isJobValid',
'validationKeys', 'validationKeys',
'isValidToBeConfirmed' 'isValidToBeConfirmed',
'usersSuggestedFilteredByJob',
]), ]),
deleteLink() { deleteLink() {
return `/fr/parcours/${this.accompanyingCourse.id}/delete`; //TODO locale return `/fr/parcours/${this.accompanyingCourse.id}/delete`; //TODO locale
}, },
disableConfirm() { disableConfirm() {
return this.clickedDoNotChooseReferrer return (this.accompanyingCourse.user === null
? (this.accompanyingCourse.user === null && this.filteredReferrersSuggested.length === 0) && this.usersSuggestedFilteredByJob.length === 1
: (this.accompanyingCourse.user === null && this.filteredReferrersSuggested.length === 0) || (this.filteredReferrersSuggested.length === 1); && this.clickedDoNotChooseReferrer === false);
} }
}, },
methods: { methods: {
@ -183,7 +183,7 @@ export default {
}); });
}, },
chooseSuggestedReferrer() { chooseSuggestedReferrer() {
this.$store.dispatch('updateReferrer', this.filteredReferrersSuggested[0]) this.$store.dispatch('updateReferrer', this.usersSuggestedFilteredByJob[0])
.catch(({name, violations}) => { .catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') { if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation})); violations.forEach((violation) => this.$toast.open({message: violation}));

View File

@ -21,8 +21,7 @@
:select-label="$t('multiselect.select_label')" :select-label="$t('multiselect.select_label')"
:deselect-label="$t('multiselect.deselect_label')" :deselect-label="$t('multiselect.deselect_label')"
:selected-label="$t('multiselect.selected_label')" :selected-label="$t('multiselect.selected_label')"
@select="updateJob"> ></VueMultiselect>
</VueMultiselect>
<label class="col-form-label" for="selectReferrer"> <label class="col-form-label" for="selectReferrer">
{{ $t('referrer.label') }} {{ $t('referrer.label') }}
@ -40,12 +39,11 @@
:select-label="$t('multiselect.select_label')" :select-label="$t('multiselect.select_label')"
:deselect-label="$t('multiselect.deselect_label')" :deselect-label="$t('multiselect.deselect_label')"
:selected-label="$t('multiselect.selected_label')" :selected-label="$t('multiselect.selected_label')"
@select="updateReferrer"> ></VueMultiselect>
</VueMultiselect>
<template v-if="filteredReferrersSuggested.length > 0"> <template v-if="usersSuggestedFilteredByJob.length > 0">
<ul class="list-suggest add-items inline"> <ul class="list-suggest add-items inline">
<li v-for="(u, i) in filteredReferrersSuggested" @click="updateReferrer(u)" :key="`referrer-${i}`"> <li v-for="(u, i) in usersSuggestedFilteredByJob" @click="updateReferrer(u)" :key="`referrer-${i}`">
<span> <span>
<user-render-box-badge :user="u"></user-render-box-badge> <user-render-box-badge :user="u"></user-render-box-badge>
</span> </span>
@ -94,26 +92,44 @@ export default {
}, },
computed: { computed: {
...mapState({ ...mapState({
value: state => state.accompanyingCourse.user,
valueJob: state => state.accompanyingCourse.job, valueJob: state => state.accompanyingCourse.job,
users: state => state.users.filter(u => { }),
if (u.user_job && state.accompanyingCourse.job) { ...mapGetters(['isJobValid', 'usersSuggestedFilteredByJob']),
return u.user_job.id === state.accompanyingCourse.job.id; users: function () {
} else { let users = this.$store.getters.usersFilteredByJob;
return false;
console.log('users filtered by job', users);
// ensure that the selected user is in the list. add it if necessary
if (this.$store.state.accompanyingCourse.user !== null && users.find(u => this.$store.state.accompanyingCourse.user.id === u.id) === undefined) {
console.log('add user to users');
users.push(this.$store.state.accompanyingCourse.user);
} }
}),
filteredReferrersSuggested: state => state.filteredReferrersSuggested, console.log('users to return', users);
}), return users;
...mapGetters([
'isJobValid'
])
}, },
mounted() { valueJob: {
this.getJobs(); get() {
return this.$store.state.accompanyingCourse.job;
}, },
methods: { set(value) {
updateReferrer(value) { this.$store.dispatch('updateJob', value)
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
}
},
value: {
get() {
return this.$store.state.accompanyingCourse.user;
},
set(value) {
console.log('set referrer', value);
this.$store.dispatch('updateReferrer', value) this.$store.dispatch('updateReferrer', value)
.catch(({name, violations}) => { .catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') { if (name === 'ValidationException' || name === 'AccessException') {
@ -122,6 +138,15 @@ export default {
this.$toast.open({message: 'An error occurred'}) this.$toast.open({message: 'An error occurred'})
} }
}); });
}
},
},
mounted() {
this.getJobs();
},
methods: {
updateReferrer(value) {
this.value = value;
}, },
getJobs() { getJobs() {
const url = '/api/1.0/main/user-job.json'; const url = '/api/1.0/main/user-job.json';
@ -133,30 +158,19 @@ export default {
this.$toast.open({message: error.txt}) this.$toast.open({message: error.txt})
}) })
}, },
updateJob(value) {
this.$store.dispatch('updateJob', value)
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
},
customJobLabel(value) { customJobLabel(value) {
return value.label.fr; return value.label.fr;
}, },
assignMe() { assignMe() {
const url = `/api/1.0/main/whoami.json`; const url = `/api/1.0/main/whoami.json`;
makeFetch('GET', url) makeFetch('GET', url)
.then(response => { .then(user => {
this.$store.dispatch('updateReferrer', response); this.value = user
return response;
}) })
.catch((error) => { /*.catch((error) => {
commit('catchError', error); commit('catchError', error);
this.$toast.open({message: error.body}) this.$toast.open({message: error.body})
}) })*/
} }
} }
} }

View File

@ -140,7 +140,7 @@ const appMessages = {
sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !", sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !",
ok: "Confirmer le parcours", ok: "Confirmer le parcours",
delete: "Supprimer le parcours", delete: "Supprimer le parcours",
no_suggested_referrer: "Il n'y a aucun référent qui puisse être désigné pour ce parcours. Vérifiez la localisation du parcours, les métiers et service indiqués. Si le problème persiste, contactez l'administrateur du logiciel.", no_suggested_referrer: "Il n'y a aucun référent qui puisse être suggéré pour ce parcours. Vérifiez la localisation du parcours, les métiers et service indiqués. Si les données sont correctes, vous pouvez confirmer ce parcours.",
one_suggested_referrer: "Un unique référent peut être suggéré pour ce parcours", one_suggested_referrer: "Un unique référent peut être suggéré pour ce parcours",
choose_suggested_referrer: "Voulez-vous le désigner directement ?", choose_suggested_referrer: "Voulez-vous le désigner directement ?",
choose_button: "Désigner", choose_button: "Désigner",

View File

@ -40,7 +40,6 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
scopesAtBackend: accompanyingCourse.scopes.map(scope => scope), scopesAtBackend: accompanyingCourse.scopes.map(scope => scope),
// the users which are available for referrer // the users which are available for referrer
referrersSuggested: [], referrersSuggested: [],
filteredReferrersSuggested: [],
// all the users available // all the users available
users: [], users: [],
permissions: {} permissions: {}
@ -93,6 +92,30 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
return false; return false;
}, },
usersFilteredByJob(state) {
return state.users.filter(u => {
if (null !== state.accompanyingCourse.job) {
return (u.user_job === null ? null : u.user_job.id) === state.accompanyingCourse.job.id;
} else {
return true;
}
});
},
usersSuggestedFilteredByJob(state) {
return state.referrersSuggested.filter(u => {
if (null !== state.accompanyingCourse.job) {
return (u.user_job === null ? null : u.user_job.id) === state.accompanyingCourse.job.id;
} else {
return true;
}
}).filter(u => {
if (null !== state.accompanyingCourse.user) {
return u.id !== state.accompanyingCourse.user.id;
}
return true;
});
},
}, },
mutations: { mutations: {
catchError(state, error) { catchError(state, error) {
@ -216,22 +239,6 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
return u; return u;
}); });
}, },
setFilteredReferrersSuggested(state) {
state.filteredReferrersSuggested = state.referrersSuggested.filter(u => {
if (u.user_job && state.accompanyingCourse.job && state.accompanyingCourse.user) {
return u.user_job.id === state.accompanyingCourse.job.id && state.accompanyingCourse.user.id !== u.id
} else {
if (null === state.accompanyingCourse.user) {
if (u.user_job && state.accompanyingCourse.job) {
return u.user_job.id === state.accompanyingCourse.job.id
} else {
return true;
}
}
return state.accompanyingCourse.user.id !== u.id;
}
})
},
confirmAccompanyingCourse(state, response) { confirmAccompanyingCourse(state, response) {
//console.log('### mutation: confirmAccompanyingCourse: response', response); //console.log('### mutation: confirmAccompanyingCourse: response', response);
state.accompanyingCourse.step = response.step; state.accompanyingCourse.step = response.step;
@ -689,8 +696,14 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
}) })
}, },
updateReferrer({ commit }, payload) { updateReferrer({ commit }, payload) {
console.log('update referrer', payload);
console.log('payload !== null', payload !== null);
const url = `/api/1.0/person/accompanying-course/${id}.json`; const url = `/api/1.0/person/accompanying-course/${id}.json`;
const body = { type: "accompanying_period", user: { id: payload.id, type: payload.type }}; let body = { type: "accompanying_period", user: null };
if (payload !== null) {
body = { type: "accompanying_period", user: { id: payload.id, type: payload.type } };
}
return makeFetch('PATCH', url, body) return makeFetch('PATCH', url, body)
.then((response) => { .then((response) => {
@ -704,12 +717,15 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
}, },
updateJob({ commit }, payload) { updateJob({ commit }, payload) {
const url = `/api/1.0/person/accompanying-course/${id}.json`; const url = `/api/1.0/person/accompanying-course/${id}.json`;
const body = { type: "accompanying_period", job: { id: payload.id, type: payload.type }}; let body = { type: "accompanying_period", job: null };
if (payload !== null) {
body = { type: "accompanying_period", job: { id: payload.id, type: payload.type } };
}
return makeFetch('PATCH', url, body) return makeFetch('PATCH', url, body)
.then((response) => { .then((response) => {
commit('updateJob', response.job); commit('updateJob', response.job);
commit('setFilteredReferrersSuggested');
}) })
.catch((error) => { .catch((error) => {
commit('catchError', error); commit('catchError', error);
@ -734,7 +750,6 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
async fetchReferrersSuggested({ state, commit}) { async fetchReferrersSuggested({ state, commit}) {
let users = await getReferrersSuggested(state.accompanyingCourse); let users = await getReferrersSuggested(state.accompanyingCourse);
commit('setReferrersSuggested', users); commit('setReferrersSuggested', users);
commit('setFilteredReferrersSuggested');
if ( if (
null === state.accompanyingCourse.user null === state.accompanyingCourse.user
&& !state.accompanyingCourse.confidential && !state.accompanyingCourse.confidential