mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-28 02:23:51 +00:00
301 lines
10 KiB
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>
|