mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
222 lines
7.6 KiB
Vue
222 lines
7.6 KiB
Vue
<template>
|
|
<div class="vue-component">
|
|
<h2><a id="section-10"></a>{{ $t('persons_associated.title')}}</h2>
|
|
|
|
<div v-if="currentParticipations.length > 0">
|
|
<label class="col-form-label">{{ $tc('persons_associated.counter', counter) }}</label>
|
|
</div>
|
|
<div v-else>
|
|
<label class="chill-no-data-statement">{{ $tc('persons_associated.counter', counter) }}</label>
|
|
</div>
|
|
|
|
<div v-if="participationWithoutHousehold.length > 0" class="alert alert-warning no-household">
|
|
<i class="fa fa-warning fa-2x"></i>
|
|
<form method="GET" action="/fr/person/household/members/editor">
|
|
<div class="float-button bottom"><div class="box">
|
|
<div class="action">
|
|
<button class="btn btn-update" type="submit">{{ $t('persons_associated.update_household') }}</button>
|
|
</div>
|
|
<p class="mb-3">{{ $t('persons_associated.person_without_household_warning') }}</p>
|
|
<div class="form-check" v-for="p in participationWithoutHousehold" :key="p.id">
|
|
<input type="checkbox"
|
|
class="form-check-input"
|
|
v-model="hasNoHousehold"
|
|
name="persons[]"
|
|
checked="checked"
|
|
:id="p.person.id"
|
|
:value="p.person.id"
|
|
/>
|
|
<label class="form-check-label">
|
|
<person-text :person="p.person"></person-text>
|
|
</label>
|
|
</div>
|
|
<input type="hidden" name="expand_suggestions" value="true">
|
|
<input type="hidden" name="returnPath" :value="getReturnPath">
|
|
<input type="hidden" name="accompanying_period_id" :value="courseId">
|
|
</div></div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="flex-table mb-3">
|
|
<participation-item
|
|
v-for="participation in currentParticipations"
|
|
v-bind:participation="participation"
|
|
v-bind:key="participation.id"
|
|
@remove="removeParticipation"
|
|
@close="closeParticipation">
|
|
</participation-item>
|
|
</div>
|
|
|
|
<div v-if="suggestedPersons.length > 0">
|
|
<ul class="list-suggest add-items inline">
|
|
<li v-for="p in suggestedPersons" :key="p.id" @click="addSuggestedPerson(p)">
|
|
<person-text :person="p"></person-text>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div>
|
|
<ul class="record_actions">
|
|
<li class="add-persons">
|
|
<add-persons
|
|
buttonTitle="persons_associated.add_persons"
|
|
modalTitle="add_persons.title"
|
|
v-bind:key="addPersons.key"
|
|
v-bind:options="addPersons.options"
|
|
@addNewPersons="addNewPersons"
|
|
ref="addPersons"> <!-- to cast child method -->
|
|
</add-persons>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div v-if="!isParticipationValid" class="alert alert-warning to-confirm">
|
|
{{ $t('persons_associated.participation_not_valid') }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {mapGetters, mapState} from 'vuex';
|
|
import ParticipationItem from "./PersonsAssociated/ParticipationItem.vue";
|
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
|
|
|
export default {
|
|
name: 'PersonsAssociated',
|
|
components: {
|
|
ParticipationItem,
|
|
AddPersons,
|
|
PersonText
|
|
},
|
|
data() {
|
|
return {
|
|
addPersons: {
|
|
key: 'persons_associated',
|
|
options: {
|
|
type: ['person'],
|
|
priority: null,
|
|
uniq: false,
|
|
}
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
courseId: state => state.accompanyingCourse.id,
|
|
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'
|
|
]),
|
|
currentParticipations() {
|
|
return this.participations.filter(p => p.endDate === null)
|
|
},
|
|
counter() {
|
|
return this.currentParticipations.length;
|
|
},
|
|
participationWithoutHousehold() {
|
|
return this.currentParticipations.filter(p => p.person.current_household_id === null);
|
|
},
|
|
getReturnPath() {
|
|
return window.location.pathname + window.location.search + window.location.hash;
|
|
},
|
|
},
|
|
methods: {
|
|
removeParticipation(item) {
|
|
this.$store.dispatch('removeParticipation', item)
|
|
.catch(({name, violations}) => {
|
|
if (name === 'ValidationException' || name === 'AccessException') {
|
|
violations.forEach((violation) => this.$toast.open({message: violation}));
|
|
} else {
|
|
this.$toast.open({message: 'An error occurred'})
|
|
}
|
|
});
|
|
},
|
|
closeParticipation(item) {
|
|
this.$store.dispatch('closeParticipation', item)
|
|
.catch(({name, violations}) => {
|
|
if (name === 'ValidationException' || name === 'AccessException') {
|
|
violations.forEach((violation) => this.$toast.open({message: violation}));
|
|
} else {
|
|
this.$toast.open({message: 'An error occurred'})
|
|
}
|
|
});
|
|
},
|
|
addNewPersons({ selected, modal }) {
|
|
selected.forEach(function(item) {
|
|
this.$store.dispatch('addParticipation', item)
|
|
.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
|
|
);
|
|
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>
|
|
<style lang="scss" scoped>
|
|
div#accompanying-course {
|
|
div.vue-component {
|
|
& > div.alert.no-household {
|
|
margin: 0 0 -1em;
|
|
}
|
|
div.no-household {
|
|
padding-bottom: 1.5em;
|
|
display: flex;
|
|
flex-direction: row;
|
|
& > i {
|
|
flex-basis: 1.5em; flex-grow: 0; flex-shrink: 0;
|
|
padding-top: 0.2em;
|
|
opacity: 0.75;
|
|
}
|
|
& > form {
|
|
flex-basis: auto;
|
|
div.action {
|
|
button.btn-update {
|
|
margin-right: 2em;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|