| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- <template>
- <navigation v-model="show" :options="navOption">
- <div class="page" v-show="show == 'benevole'">
- <data-table
- class="data-table"
- title="Liste des bénévoles"
- :data="data"
- :clickable="true"
- :loadingAnimation="loading"
- :exportable="false"
- locale="fr"
- @row-click="onRowClick"
- :customButtons="customButton"
- ></data-table>
- <editeur-benevole
- :benevole="currentBenevole"
- @create="createBenevole"
- @delete="deleteBenevole"
- />
- <input type="file" ref="loadcsv" @change="importBenevoleTemplate" style="display: none" />
- </div>
- <editeur-questionnaire
- v-if="show == 'questionnaire'"
- :competences="competenceList"
- :uuid="uuid"
- />
- <manage-registration v-if="show == 'inscriptions'" />
- <filter-panel
- ref="filter"
- :data="benevoleForFilter"
- title="Filtrer les bénévoles"
- @filterChange="updateList($event)"
- :filters="filters"
- />
- </navigation>
- </template>
- <script lang="ts">
- import Competence from "@/models/Competence";
- import EditeurBenevole from "@/components/EditeurBenevole.vue";
- import FilterPanel, { FilterParam } from "@/components/Utils/FilteringPanel.vue";
- import EditeurQuestionnaire from "@/components/EditeurQuestionnaire.vue";
- import ManageRegistration from "@/components/Utils/ManageRegistration.vue";
- import Navigation from "@/components/Utils/NavigationPanel.vue";
- import DataTable, {
- CustomButton,
- DataTableColumn,
- DataTableData,
- } from "@/components/Utils/DataTable.vue";
- import { defineComponent } from "vue";
- import { MutationTypes } from "@/store/Mutations";
- import Benevole from "@/models/Benevole";
- import csv from "@/utils/csv";
- import dayjs from "dayjs";
- import Toast from "@/utils/Toast";
- const csvDefaultcolumn = "id,prenom,nom,telephone,email,commentaire";
- const navOption = [
- { id: "benevole", title: "Bénévoles" },
- { id: "questionnaire", title: "Gestion du questionnaire" },
- { id: "inscriptions", title: "Validations des inscriptions" },
- ];
- const filters: Array<FilterParam> = [
- {
- name: "Préference & compétences",
- type: "category",
- key: "competenceIdList",
- placeholder: "Selectionner une compétence",
- },
- ];
- type filterObject = {
- id: number;
- competenceIdList: Array<string>;
- };
- type BenevoleTableObject = {
- id: number;
- name: string;
- surname: string;
- fanfare: string;
- creneauLength: number;
- };
- const columns: Array<DataTableColumn<BenevoleTableObject>> = [
- {
- label: "Prénom",
- field: "name",
- numeric: false,
- html: false,
- class: "overflow-cell",
- },
- {
- label: "Nom",
- field: "surname",
- numeric: false,
- html: false,
- class: "overflow-cell",
- },
- {
- label: "Fanfare",
- field: "fanfare",
- numeric: false,
- html: false,
- class: "fitwidth",
- export: "fanfare",
- },
- {
- label: "Duree créneau(h)",
- field: "creneauLength",
- numeric: true,
- html: false,
- class: "fitwidth",
- export: "creneauLength",
- },
- ];
- export default defineComponent({
- name: "EditeurCreneau",
- components: {
- DataTable,
- EditeurBenevole,
- ManageRegistration,
- EditeurQuestionnaire,
- Navigation,
- FilterPanel,
- },
- data: () => ({
- navOption,
- show: "benevole",
- columns,
- currentBenevole: undefined as Benevole | undefined,
- loading: true,
- customButton: [] as Array<CustomButton>,
- benevoleList: [] as Array<Benevole>,
- filters,
- }),
- computed: {
- uuid(): string {
- return this.$store.state.evenement.uuid;
- },
- csvInputElt(): HTMLInputElement {
- return this.$refs.loadcsv as HTMLInputElement;
- },
- competenceList(): Array<Competence> {
- return this.$store.state.competenceList;
- },
- fanfareList(): Array<Competence> {
- return this.competenceList.filter((o) => o.name.startsWith("Fanfare"));
- },
- rawBenevoleList(): Array<Benevole> {
- return this.$store.state.benevoleList;
- },
- benevoleForFilter(): Array<filterObject> {
- return this.rawBenevoleList.map((b: Benevole) => {
- return {
- id: b.id,
- competenceIdList: b.competenceIdList.map(
- (id) => this.competenceList.find((o) => o.id == id)?.name ?? ""
- ),
- };
- });
- },
- data(): DataTableData<BenevoleTableObject> {
- return {
- items: this.benevoleList.map((b) => {
- return {
- id: b.id,
- name: b.name,
- surname: b.surname,
- fanfare: this.getFanfareForBenevole(b),
- creneauLength: this.getBenevoleTotalLength(b),
- };
- }),
- columns: this.columns,
- };
- },
- },
- watch: {
- rawBenevoleList() {
- this.benevoleList = this.rawBenevoleList;
- (this.$refs.filter as typeof FilterPanel).reset();
- },
- },
- methods: {
- openFilter() {
- (this.$refs.filter as typeof FilterPanel).open();
- },
- updateList(l: Array<filterObject>) {
- const ids = l.map((o) => o.id);
- this.benevoleList = this.rawBenevoleList.filter((b) => ids.includes(b.id));
- },
- getFanfareForBenevole(benevole: Benevole): string {
- if (benevole.competenceIdList.length == 0) {
- return "Exte";
- } else {
- const fanfare = this.fanfareList
- .filter((o) => benevole.competenceIdList.indexOf(o.id) > -1)
- .map((o) => o.name.substring(8))
- .join(", ");
- return fanfare ? fanfare : "Exte";
- }
- },
- getBenevoleTotalLength(benevole: Benevole): number {
- return this.$store.state.creneauList
- .filter((c) => c.benevoleIdList.indexOf(benevole.id) > -1)
- .reduce((acc, creneau) => acc + creneau.durationH, 0);
- },
- createBenevole() {
- const temp = Benevole.fromObject({ name: "Benevole i", surname: "" });
- this.$store.commit(MutationTypes.addBenevole, temp);
- this.currentBenevole = temp;
- },
- deleteBenevole(payload: Benevole) {
- this.$store.commit(MutationTypes.removeBenevole, payload.id);
- this.currentBenevole = undefined;
- },
- onRowClick(row: { id: number }) {
- this.currentBenevole = this.$store.getters.getBenevoleById(row.id);
- },
- getImportTemplate() {
- const competences = this.$store.state.competenceList;
- let csvContent = `${csvDefaultcolumn},${competences.map((c) => c.name).join(",")}\r\n`;
- this.benevoleList.forEach(
- (b) =>
- (csvContent +=
- [
- b.id,
- b.name,
- b.surname,
- b.phone,
- b.email,
- b.comment,
- ...competences.map((c) => (b.competenceIdList.includes(c.id) ? "X" : "")),
- ].join(",") + "\r\n")
- );
- const dummy = document.createElement("a");
- dummy.href = "data:text/csv;charset=utf-8, " + encodeURI(csvContent);
- dummy.download = "Benevole-import" + dayjs().format("-YYYY-MM-DD-hh-mm-ss[.csv]");
- document.body.appendChild(dummy);
- dummy.click();
- },
- importBenevoleTemplate() {
- const fs = this.csvInputElt.files;
- if (fs && fs.length > 0) {
- let reader = new FileReader();
- reader.readAsText(fs[0]);
- reader.onload = () => {
- let csvtxt = reader.result as string;
- const arr = csv.toArray(csvtxt);
- const defaultKey = csvDefaultcolumn.split(",");
- const competencesMap: { [k: string]: Competence } = {};
- for (let key of arr[0]) {
- if (!defaultKey.includes(key)) {
- key = key.trim();
- // check if a competence exist with this name
- let c = this.competenceList.find((c) => c.name == key);
- if (c == undefined) {
- Toast({ html: "Compétence inconnue: " + key, classes: "warning" });
- c = Competence.fromObject({ name: key, description: "" });
- this.$store.commit(MutationTypes.addConstraint, c);
- }
- if (c) {
- competencesMap[key] = c;
- }
- }
- }
- const objectList = csv.toObject(csvtxt);
- for (let item of objectList) {
- const id = parseInt(item.id);
- let b: Benevole | undefined = undefined;
- if (id) b = this.$store.getters.getBenevoleById(id);
- if (b == undefined) {
- b = Benevole.fromObject({
- id: id ?? undefined,
- name: item.prenom,
- surname: item.nom,
- phone: item.telephone,
- email: item.email,
- comment: item.commentaire,
- });
- this.$store.commit(MutationTypes.addBenevole, b);
- } else {
- let map: Array<{ k: string; v: keyof Benevole }> = [
- { k: "prenom", v: "name" },
- { k: "nom", v: "surname" },
- { k: "telephone", v: "phone" },
- { k: "commentaire", v: "comment" },
- { k: "email", v: "email" },
- ];
- map.forEach((o) =>
- this.$store.commit(MutationTypes.editBenevole, {
- id: (b as Benevole).id,
- field: o.v,
- value: item[o.k],
- })
- );
- }
- const competenceIdList = [];
- for (let key in competencesMap) {
- if (item[key].trim() == "X") {
- competenceIdList.push(competencesMap[key].id);
- }
- }
- this.$store.commit(MutationTypes.editBenevole, {
- id: b.id,
- field: "competenceIdList",
- value: competenceIdList,
- });
- }
- };
- }
- },
- },
- mounted() {
- this.loading = false;
- this.customButton.push({ icon: "filter_alt", hide: false, onclick: this.openFilter });
- this.customButton.push({ icon: "file_download", hide: false, onclick: this.getImportTemplate });
- this.customButton.push({
- icon: "file_upload",
- hide: false,
- onclick: () => {
- this.csvInputElt.click();
- },
- });
- this.benevoleList = this.rawBenevoleList;
- },
- });
- </script>
- <style scoped>
- .page {
- display: flex;
- flex-direction: column;
- width: 100%;
- max-width: 1100px;
- gap: 16px;
- }
- .data-table {
- width: 100%;
- height: min-content;
- }
- @media (min-width: 600px) {
- .page {
- flex-direction: row;
- }
- .data-table {
- width: calc(100% - 432px);
- }
- }
- @media (min-width: 1200px) {
- .page {
- margin-top: 8px;
- }
- }
- </style>
|