Files
chill-bundles/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated.vue

301 lines
10 KiB
Vue

<template>
<div class="vue-component">
<h2><a id="section-10" />{{ $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" />
<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"
name="persons[]"
checked="checked"
:id="p.person.id"
:value="p.person.id"
/>
<label class="form-check-label">
<person-text :person="p.person" />
</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"
:participation="participation"
:key="participation.id"
@remove="removeParticipation"
@close="closeParticipation"
/>
</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" />
</li>
</ul>
</div>
<div>
<ul class="record_actions">
<li class="add-persons">
<add-persons
button-title="persons_associated.add_persons"
modal-title="add_persons.title"
:key="addPersons.key"
:options="addPersons.options"
@add-new-persons="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>