Merge remote-tracking branch 'origin/master' into features/docgen-widget-generate-template

This commit is contained in:
2021-11-30 16:38:36 +01:00
1055 changed files with 5050 additions and 2165 deletions

View File

@@ -48,9 +48,7 @@ export default {
persons: this.persons.filter(p => p.current_household_id === h)
})
})
console.log(personsByHousehold)
//console.log(personsByHousehold)
return personsByHousehold
},
householdExists(id) {

View File

@@ -21,6 +21,7 @@
<script>
import { mapState } from 'vuex';
export default {
name: "ToggleFlags",
computed: {
@@ -28,6 +29,7 @@ export default {
intensity: state => state.accompanyingCourse.intensity,
emergency: state => state.accompanyingCourse.emergency,
confidential: state => state.accompanyingCourse.confidential,
permissions: state => state.permissions,
}),
isRegular() {
return (this.intensity === 'regular') ? true : false;
@@ -37,7 +39,7 @@ export default {
},
isConfidential() {
return (this.confidential) ? true : false;
}
},
},
methods: {
toggleIntensity() {
@@ -73,16 +75,22 @@ export default {
});
},
toggleConfidential() {
this.$store.dispatch('toggleConfidential', (!this.isConfidential))
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
}
}
this.$store.dispatch('fetchPermissions').then(() => {
if (!this.$store.getters.canTogglePermission) {
this.$toast.open({message: "Seul le référent peut modifier la confidentialité"});
return Promise.resolve();
} else {
return this.$store.dispatch('toggleConfidential', (!this.isConfidential));
}
}).catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
},
},
}
</script>

View File

@@ -47,6 +47,14 @@
</participation-item>
</div>
<div v-if="suggestedPersons.length > 0">
<ul class="list-suggest add-items">
<li v-for="p in suggestedPersons" :key="p.id" @click="addSuggestedPerson(p)">
<span>{{ p.text }}</span>
</li>
</ul>
</div>
<div>
<add-persons
buttonTitle="persons_associated.add_persons"
@@ -90,7 +98,28 @@ export default {
computed: {
...mapState({
courseId: state => state.accompanyingCourse.id,
participations: state => state.accompanyingCourse.participations
participations: state => state.accompanyingCourse.participations,
suggestedPersons: state => [
state.accompanyingCourse.requestor,
...state.accompanyingCourse.resources.map(r => r.resource)
]
.filter((e) => e !== null)
.filter((e) => e.type === 'person')
.filter(
(p) => !state.accompanyingCourse.participations.filter(pa => pa.endDate === null).map((pa) => pa.person.id).includes(p.id)
)
// filter persons appearing twice in requestor and resources
.filter(
(e, index, suggested) => {
for (let i = 0; i < suggested.length; i = i+1) {
if (i < index && e.id === suggested[i].id) {
return false
}
}
return true;
}
)
}),
...mapGetters([
'isParticipationValid'
@@ -106,7 +135,7 @@ export default {
},
getReturnPath() {
return window.location.pathname + window.location.search + window.location.hash;
}
},
},
methods: {
removeParticipation(item) {
@@ -143,7 +172,17 @@ export default {
);
this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false;
}
},
addSuggestedPerson(person) {
this.$store.dispatch('addParticipation', { result: person, type: 'person' })
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
})
},
}
}
</script>

View File

@@ -20,10 +20,9 @@
</VueMultiselect>
<template v-if="referrersSuggested.length > 0">
<ul class="list-unstyled">
<ul class="list-suggest add-items">
<li v-for="u in referrersSuggested" @click="updateReferrer(u)">
<span class="badge bg-primary" style="cursor: pointer">
<i class="fa fa-plus fa-fw text-success"></i>
<span>
<user-render-box-badge :user="u"></user-render-box-badge>
</span>
</li>

View File

@@ -32,7 +32,7 @@
</third-party-render-box>
</template>
</confidential>
<confidential v-else-if="accompanyingCourse.requestor.type === 'person'">
<template v-slot:confidential-content>
<person-render-box render="bloc"
@@ -133,6 +133,14 @@
<label class="chill-no-data-statement">{{ $t('requestor.counter') }}</label>
</div>
<div v-if="accompanyingCourse.requestor === null && suggestedEntities.length > 0">
<ul class="list-suggest add-items">
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
<span>{{ p.text }}</span>
</li>
</ul>
</div>
<div>
<add-persons v-if="accompanyingCourse.requestor === null"
buttonTitle="requestor.add_requestor"
@@ -153,6 +161,7 @@ import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue';
import PersonRenderBox from '../../_components/Entity/PersonRenderBox.vue';
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue';
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
import { mapState } from 'vuex';
export default {
name: 'Requestor',
@@ -177,12 +186,30 @@ export default {
}
},
computed: {
...mapState({
suggestedEntities: state => {
return [
...state.accompanyingCourse.participations.map(p => p.person),
...state.accompanyingCourse.resources.map(r => r.resource)
]
.filter((e) => e !== null)
// filter for same entity appearing twice
.filter((e, index, suggested) => {
for (let i = 0; i < suggested.length; i = i+1) {
if (i < index && e.id === suggested[i].id && e.type === suggested[i].type) {
return false
}
}
return true;
})
}
}),
accompanyingCourse() {
return this.$store.state.accompanyingCourse
},
isAnonymous: {
set(value) {
//console.log('requestorIsAnonymous value',value);
this.$store.dispatch('requestorIsAnonymous', value);
},
get() {
@@ -227,6 +254,19 @@ export default {
this.$toast.open({message: 'An error occurred'})
}
});
},
addSuggestedEntity(e) {
this.$store.dispatch('addRequestor', { result: e, type: e.type })
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
})
},
uniqueId(e) {
return `${e.type}-${e.id}`;
}
}
}

View File

@@ -18,6 +18,15 @@
@remove="removeResource">
</resource-item>
</div>
<div v-if="suggestedEntities.length > 0">
<ul class="list-suggest add-items">
<li v-for="p in suggestedEntities" :key="uniqueId(p)" @click="addSuggestedEntity(p)">
<span>{{ p.text }}</span>
</li>
</ul>
</div>
<div>
<add-persons
buttonTitle="resources.add_resources"
@@ -57,7 +66,38 @@ export default {
},
computed: mapState({
resources: state => state.accompanyingCourse.resources,
counter: state => state.accompanyingCourse.resources.length
counter: state => state.accompanyingCourse.resources.length,
suggestedEntities: state => [
state.accompanyingCourse.requestor,
...state.accompanyingCourse.participations.map(p => p.person),
]
.filter((e) => e !== null)
.filter(
(e) => {
if (e.type === 'person') {
return !state.accompanyingCourse.resources
.filter((r) => r.resource.type === 'person')
.map((r) => r.resource.id).includes(e.id)
}
if (e.type === 'thirdparty') {
return !state.accompanyingCourse.resources
.filter((r) => r.resource.type === 'thirdparty')
.map((r) => r.resource.id).includes(e.id)
}
}
)
// filter persons appearing twice in requestor and resources
.filter(
(e, index, suggested) => {
for (let i = 0; i < suggested.length; i = i+1) {
if (i < index && e.id === suggested[i].id) {
return false
}
}
return true;
}
)
}),
methods: {
removeResource(item) {
@@ -86,6 +126,19 @@ export default {
);
this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false;
},
addSuggestedEntity(e) {
this.$store.dispatch('addResource', { result: e, type: e.type})
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
})
},
uniqueId(e) {
return `${e.type}-${e.id}`;
}
}
}

View File

@@ -35,7 +35,7 @@ const appMessages = {
title: "Origine de la demande",
label: "Origine de la demande",
placeholder: "Renseignez l'origine de la demande",
not_valid: "Indiquez une origine de la demande",
not_valid: "Indiquez une origine à la demande",
},
persons_associated: {
title: "Usagers concernés",
@@ -126,7 +126,7 @@ const appMessages = {
participation_not_valid: "sélectionnez au minimum 1 usager",
socialIssue_not_valid: "sélectionnez au minimum une problématique sociale",
location_not_valid: "indiquez au minimum une localisation temporaire du parcours",
origin_not_valid: "indiquez une origine de la demande",
origin_not_valid: "Indiquez une origine à la demande",
set_a_scope: "indiquez au moins un service",
sure: "Êtes-vous sûr ?",
sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !",

View File

@@ -37,6 +37,7 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
referrersSuggested: [],
// all the users available
users: [],
permissions: {}
},
getters: {
isParticipationValid(state) {
@@ -70,7 +71,14 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
return true;
}
return false;
}
},
canTogglePermission(state) {
if (state.permissions.roles) {
return state.permissions.roles['CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL'];
}
return false;
},
},
mutations: {
catchError(state, error) {
@@ -201,6 +209,10 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
return u;
});
},
setPermissions(state, permissions) {
state.permissions = permissions;
// console.log('permissions', state.permissions);
},
updateLocation(state, r) {
//console.log('### mutation: set location attributes', r);
state.accompanyingCourse.locationStatus = r.locationStatus;
@@ -625,6 +637,33 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
let users = await getUsers();
commit('setUsers', users);
},
/**
* By adding more roles to body['roles'], more permissions can be checked.
*/
fetchPermissions({commit}) {
const url = '/api/1.0/main/permissions/info.json';
const body = {
"object": {
"type": "accompanying_period",
"id": id
},
"class": "Chill\\PersonBundle\\Entity\\AccompanyingPeriod",
"roles": [
"CHILL_PERSON_ACCOMPANYING_PERIOD_TOGGLE_CONFIDENTIAL"
]
}
return makeFetch('POST', url, body)
.then((response) => {
commit('setPermissions', response);
return Promise.resolve();
})
.catch((error) => {
commit('catchError', error);
throw error;
})
},
updateLocation({ commit, dispatch }, payload) {
//console.log('## action: updateLocation', payload.locationStatusTo);
const url = `/api/1.0/person/accompanying-course/${payload.targetId}.json`;
@@ -642,12 +681,12 @@ let initPromise = Promise.all([scopesPromise, accompanyingCoursePromise])
Object.assign(body, location);
makeFetch('PATCH', url, body)
.then((response) => {
commit('updateLocation', {
location: response.location,
locationStatus: response.locationStatus,
personLocation: response.personLocation
});
dispatch('fetchReferrersSuggested');
commit('updateLocation', {
location: response.location,
locationStatus: response.locationStatus,
personLocation: response.personLocation
});
dispatch('fetchReferrersSuggested');
})
.catch((error) => {
commit('catchError', error);

View File

@@ -44,9 +44,9 @@
<!-- results which **are** attached to an objective -->
<div v-for="g in goalsPicked">
<div>
<div class="item-title" @click="removeGoal(g)">
<i class="fa fa-times"></i>
<div class="item-title">
{{ g.goal.title.fr }}
<a @click="removeGoal(g)"></a>
</div>
</div>
<div>
@@ -61,10 +61,9 @@
<p>{{ $t('available_goals_text') }}</p>
<ul class="list-objectives">
<li v-for="g in availableForCheckGoal" class="badge bg-primary" @click="addGoal(g)">
<i class="fa fa-plus"></i>
{{ g.title.fr }}
<ul class="list-suggest add-items">
<li v-for="g in availableForCheckGoal" @click="addGoal(g)">
<span>{{ g.title.fr }}</span>
</li>
</ul>
</div>
@@ -98,10 +97,9 @@
<div class="add_evaluation">
<div v-if="showAddEvaluation">
<p>{{ $t('available_evaluations_text') }}</p>
<ul class="list-evaluations">
<li v-for="e in evaluationsForAction" class="badge bg-primary" @click="addEvaluation(e)">
<i class="fa fa-plus"></i>
{{ e.title.fr }}
<ul class="list-suggest add-items">
<li v-for="e in evaluationsForAction" @click="addEvaluation(e)">
<span>{{ e.title.fr }}</span>
</li>
</ul>
</div>
@@ -512,8 +510,8 @@ div#workEditor {
& > div.results_without_objective {
background: repeating-linear-gradient(
45deg,
$gray-500,
$gray-500 10px,
$gray-200,
$gray-200 10px,
$gray-100 10px,
$gray-100 20px
);
@@ -552,31 +550,11 @@ div#workEditor {
font-size: 85%;
}
ul.list-evaluations,
ul.list-objectives,
ul.list-results {
list-style-type: none;
padding: 0;
li {
margin: 0.5rem;
&.badge {
padding-bottom: 0;
padding-top: 0;
padding-left: 0;
}
}
}
i.fa {
padding: 0.25rem;
color: $white;
&.fa-plus { background-color: $green; }
&.fa-times { background-color: $red; }
&.fa-pencil { background-color: $orange; }
&.fa-times { color: $red; }
}
}

View File

@@ -1,9 +1,10 @@
<template>
<div>
<div class="item-title" @click="removeEvaluation(evaluation)">
<i class="fa fa-fw fa-times"></i>
<div class="item-title">
{{ evaluation.evaluation.title.fr }}
<a @click="removeEvaluation(evaluation)"></a>
</div>
<div v-if="!evaluation.editEvaluation">
<dl class="item-details definition-inline">

View File

@@ -1,33 +1,57 @@
<template>
<div v-if="hasResult" class="addResult">
<p v-if="pickedResults.length ===0" class="chill-no-data-statement">
Aucun résultat associé
</p>
<ul class="list-results">
<li v-for="r in pickedResults" class="badge bg-primary" @click="removeResult(r)">
<i class="fa fa-times"></i>
{{ r.title.fr }}
</li>
<template v-if="isExpanded">
<li v-for="r in availableForCheckResults" class="badge bg-primary" @click="addResult(r)">
<i class="fa fa-plus"></i>
<ul class="list-suggest remove-items">
<li v-for="r in pickedResults">
<span>
{{ r.title.fr }}
</li>
</template>
</ul>
<ul class="record_actions">
<li v-if="isExpanded">
<button class="btn btn-hide" @click="toggleSelect">
<i class="fa fa-eye-slash"></i>
Masquer résultats et orientations disponibles
</button>
</li>
<li v-else>
<button class="btn btn-show" @click="toggleSelect">
Afficher résultats et orientations disponibles
</button>
<a @click="removeResult(r)"></a>
</span>
</li>
</ul>
<div class="accordion" id="expandedSuggestions">
<div class="accordion-item">
<h2 class="accordion-header" id="heading_expanded_suggestions">
<button v-if="isExpanded"
class="accordion-button"
type="button"
data-bs-toggle="collapse"
aria-expanded="true"
@click="toggleSelect">
Masquer résultats et orientations disponibles
</button>
<button v-else
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
aria-expanded="false"
@click="toggleSelect">
Afficher résultats et orientations disponibles
</button>
</h2>
<div class="accordion-collapse" id="collapse_expanded_suggestions"
aria-labelledby="heading_expanded_suggestions" data-bs-parent="#expandedSuggestions">
<template v-if="isExpanded">
<ul class="list-suggest add-items">
<li v-for="r in availableForCheckResults" @click="addResult(r)">
<span>{{ r.title.fr }}</span>
</li>
</ul>
</template>
</div>
</div>
</div>
</div>
<div v-if="!hasResult" class="noResult">
<div class="chill-no-data-statement">