mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge remote-tracking branch 'origin/fix-getParticipationsContainsPerson' into fix-person-tests
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
<template>
|
||||
<accompanying-course v-bind:accompanying_course="accompanying_course"/>
|
||||
<persons-associated v-bind:persons_associated="accompanying_course.persons"/>
|
||||
<requestor v-bind:accompanying_course="accompanying_course"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AccompanyingCourse from './components/AccompanyingCourse.vue';
|
||||
import PersonsAssociated from './components/PersonsAssociated.vue';
|
||||
import Requestor from './components/Requestor.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
AccompanyingCourse,
|
||||
PersonsAssociated,
|
||||
Requestor
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
accompanying_course: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
accompanyingCourseId() {
|
||||
return window.accompanyingCourseId;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getAccompanyingCourse() {
|
||||
let data_;
|
||||
return fetch(`/fr/api/parcours/${accompanyingCourseId}/show`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
this.$data.accompanying_course = data;
|
||||
});
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.getAccompanyingCourse();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@@ -1,26 +0,0 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h3>Parcours</h3>
|
||||
<dl>
|
||||
<dt>id</dt>
|
||||
<dd>{{ accompanying_course.id }}</dd>
|
||||
<dt>opening_date</dt>
|
||||
<dd>{{ accompanying_course.opening_date }}</dd>
|
||||
<dt>closing_date</dt>
|
||||
<dd>{{ accompanying_course.closing_date }}</dd>
|
||||
<dt>remark</dt>
|
||||
<dd>{{ accompanying_course.remark }}</dd>
|
||||
<dt>closing_motive</dt>
|
||||
<dd>{{ accompanying_course.closing_motive }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AccompanyingCourse',
|
||||
props: {
|
||||
accompanying_course: Object
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<tr>
|
||||
<td>{{ person.firstname }}</td>
|
||||
<td>{{ person.lastname }}</td>
|
||||
<td>{{ person.startdate }}</td>
|
||||
<td>{{ person.enddate }}</td>
|
||||
<td>
|
||||
<ul class="record_actions">
|
||||
<li><button class="sc-button bt-show"></button></li>
|
||||
<li><button class="sc-button bt-update"></button></li>
|
||||
<li><button class="sc-button bt-delete" @click.prevent="$emit('remove', person)"></button></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PersonItem',
|
||||
props: {
|
||||
person: { type: Object, required: true }
|
||||
},
|
||||
emits: ['remove']
|
||||
}
|
||||
</script>
|
@@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h3>Usagers concernés</h3>
|
||||
|
||||
<label>{{ counter }} usagers</label>
|
||||
|
||||
<table class="rounded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="chill-orange">firstname</th>
|
||||
<th class="chill-orange">lastname</th>
|
||||
<th class="chill-orange">startdate</th>
|
||||
<th class="chill-orange">enddate</th>
|
||||
<th class="chill-orange">actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<person-item
|
||||
v-for="person in persons_associated"
|
||||
v-bind:person="person"
|
||||
v-bind:key="person.id"
|
||||
@remove="removePerson" />
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li><button class="sc-button bt-create" @click="addPerson">Ajouter un usager</button></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PersonItem from "./PersonItem.vue"
|
||||
|
||||
export default {
|
||||
name: 'PersonsAssociated',
|
||||
components: {
|
||||
PersonItem
|
||||
},
|
||||
props: {
|
||||
persons_associated: Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
persons: this.persons_associated
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
async counter() {
|
||||
// Pourquoi je peux pas compter un tableau avec length ???!!!
|
||||
return this.persons_associated.length // <= boum !
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addPerson() {
|
||||
this.persons_associated.push({
|
||||
"firstname": "Lisa",
|
||||
"lastname": "Simpson",
|
||||
"startdate": "1975-09-15",
|
||||
"enddate": "2021-04-20"
|
||||
})
|
||||
},
|
||||
removePerson(item) {
|
||||
this.persons_associated = this.persons_associated.filter(person => person !== item)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,16 +0,0 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h3>Demandeur</h3>
|
||||
{{ accompanying_course.id }}
|
||||
{{ accompanying_course.remark }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Requestor',
|
||||
props: {
|
||||
accompanying_course: Object
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,8 +0,0 @@
|
||||
import App from './App.vue';
|
||||
import { createApp } from 'vue';
|
||||
|
||||
const app = createApp({
|
||||
template: `<app></app>`
|
||||
})
|
||||
.component('app', App)
|
||||
.mount('#accompanying-course');
|
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<accompanying-course></accompanying-course>
|
||||
<persons-associated></persons-associated>
|
||||
<requestor></requestor>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import AccompanyingCourse from './components/AccompanyingCourse.vue';
|
||||
import PersonsAssociated from './components/PersonsAssociated.vue';
|
||||
import Requestor from './components/Requestor.vue';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
AccompanyingCourse,
|
||||
PersonsAssociated,
|
||||
Requestor
|
||||
},
|
||||
computed: mapState([
|
||||
'accompanyingCourse'
|
||||
])
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,49 @@
|
||||
const
|
||||
locale = 'fr',
|
||||
format = 'json'
|
||||
, accompanying_period_id = window.accompanyingCourseId //tmp
|
||||
;
|
||||
|
||||
/*
|
||||
* Endpoint chill_person_accompanying_course_api_show
|
||||
* method GET, get AccompanyingCourse Object
|
||||
*
|
||||
* @accompanying_period_id___ integer
|
||||
* @TODO var is not used but necessary in method signature
|
||||
*/
|
||||
let getAccompanyingCourse = (accompanying_period_id___) => { //tmp
|
||||
const url = `/${locale}/person/api/1.0/accompanying-course/${accompanying_period_id}/show.${format}`;
|
||||
return fetch(url)
|
||||
.then(response => {
|
||||
if (response.ok) { return response.json(); }
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Endpoint chill_person_accompanying_course_api_add_participation,
|
||||
* method POST/DELETE, add/close a participation to the accompanyingCourse
|
||||
*
|
||||
* @accompanying_period_id integer - id of accompanyingCourse
|
||||
* @person_id integer - id of person
|
||||
* @method string - POST or DELETE
|
||||
*/
|
||||
let postParticipation = (accompanying_period_id, person_id, method) => {
|
||||
const url = `/${locale}/person/api/1.0/accompanying-course/${accompanying_period_id}/participation.${format}`
|
||||
return fetch(url, {
|
||||
method: method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8'
|
||||
},
|
||||
body: JSON.stringify({id: person_id})
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) { return response.json(); }
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
};
|
||||
|
||||
export {
|
||||
getAccompanyingCourse,
|
||||
postParticipation
|
||||
};
|
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h3>{{ $t('course.title') }}</h3>
|
||||
<dl>
|
||||
<dt>{{ $t('course.id') }}</dt>
|
||||
<dd>{{ accompanyingCourse.id }}</dd>
|
||||
<dt>{{ $t('course.opening_date') }}</dt>
|
||||
<dd>{{ $d(accompanyingCourse.openingDate.datetime, 'short') }}</dd>
|
||||
<dt>{{ $t('course.closing_date') }}</dt>
|
||||
<dd>{{ $d(accompanyingCourse.closingDate.datetime, 'short') }}</dd>
|
||||
<dt>{{ $t('course.remark') }}</dt>
|
||||
<dd>{{ accompanyingCourse.remark }}</dd>
|
||||
<dt>{{ $t('course.closing_motive') }}</dt>
|
||||
<dd>{{ accompanyingCourse.closing_motive }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AccompanyingCourse',
|
||||
computed: {
|
||||
accompanyingCourse() {
|
||||
return this.$store.state.accompanyingCourse
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<tr>
|
||||
<td>{{ participation.person.firstName }}</td>
|
||||
<td>{{ participation.person.lastName }}</td>
|
||||
<td><span v-if="participation.startDate">
|
||||
{{ $d(participation.startDate.datetime, 'short') }}</span>
|
||||
</td>
|
||||
<td><span v-if="participation.endDate">
|
||||
{{ $d(participation.endDate.datetime, 'short') }}</span>
|
||||
</td>
|
||||
<td>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a class="sc-button bt-show" target="_blank"
|
||||
:href="url.show"
|
||||
:title="$t('action.show')">
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="sc-button bt-update" target="_blank"
|
||||
:href="url.edit"
|
||||
:title="$t('action.edit')">
|
||||
</a>
|
||||
</li>
|
||||
<!--li>
|
||||
<button class="sc-button bt-delete"
|
||||
:title="$t('action.delete')"
|
||||
@click.prevent="$emit('remove', participation)">
|
||||
</button>
|
||||
</li-->
|
||||
<li>
|
||||
<button class="sc-button bt-remove"
|
||||
:title="$t('action.remove')"
|
||||
@click.prevent="$emit('close', participation)">
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PersonItem',
|
||||
props: ['participation'],
|
||||
data() {
|
||||
return {
|
||||
url: {
|
||||
show: '/fr/person/' + this.participation.person.id + '/general',
|
||||
edit: '/fr/person/' + this.participation.person.id + '/general/edit'
|
||||
}
|
||||
}
|
||||
},
|
||||
emits: ['remove', 'close']
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h3>{{ $t('persons_associated.title')}}</h3>
|
||||
<label>{{ $tc('persons_associated.counter', counter) }}</label>
|
||||
<table class="rounded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="chill-orange">{{ $t('persons_associated.firstname') }}</th>
|
||||
<th class="chill-orange">{{ $t('persons_associated.lastname') }}</th>
|
||||
<th class="chill-orange">{{ $t('persons_associated.startdate') }}</th>
|
||||
<th class="chill-orange">{{ $t('persons_associated.enddate') }}</th>
|
||||
<th class="chill-orange">{{ $t('action.actions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<person-item
|
||||
v-for="participation in participations"
|
||||
v-bind:participation="participation"
|
||||
v-bind:key="participation.id"
|
||||
@remove="removeParticipation"
|
||||
@close="closeParticipation">
|
||||
</person-item>
|
||||
</tbody>
|
||||
</table>
|
||||
<add-persons></add-persons>
|
||||
<ul class="record_actions">
|
||||
<!--li>
|
||||
<button class="sc-button orange" @click="savePersons">
|
||||
{{ $t('action.save') }}
|
||||
</button>
|
||||
</li-->
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import PersonItem from "./PersonItem.vue"
|
||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue'
|
||||
|
||||
export default {
|
||||
name: 'PersonsAssociated',
|
||||
components: {
|
||||
PersonItem,
|
||||
AddPersons
|
||||
},
|
||||
computed: mapState({
|
||||
participations: state => state.accompanyingCourse.participations,
|
||||
counter: state => state.accompanyingCourse.participations.length
|
||||
}),
|
||||
methods: {
|
||||
removeParticipation(item) {
|
||||
this.$store.dispatch('removeParticipation', item)
|
||||
},
|
||||
closeParticipation(item) {
|
||||
console.log('@@ CLICK close participation: item', item);
|
||||
this.$store.dispatch('closeParticipation', item)
|
||||
},
|
||||
/*
|
||||
savePersons() {
|
||||
console.log('[wip] saving persons');
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div class="vue-component">
|
||||
<h3>{{ $t('requestor.title') }}</h3>
|
||||
{{ accompanyingCourse.id }}
|
||||
{{ accompanyingCourse.remark }}<br><br>
|
||||
|
||||
<!-- TESTS AREA -->
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button class="sc-button bt-create" @click="modal1.showModal = true">
|
||||
{{ $t('action.show_modal') }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="sc-button bt-create" @click="modal2.showModal = true">
|
||||
Ouvrir une seconde modale
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<teleport to="body">
|
||||
<modal v-if="modal1.showModal" :modalDialogClass="modal1.modalDialogClass" @close="modal1.showModal = false">
|
||||
<template v-slot:header>
|
||||
<h3 class="modal-title">Le titre de ma modale</h3>
|
||||
</template>
|
||||
<template v-slot:body>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus luctus facilisis suscipit. Cras pulvinar, purus sagittis pulvinar porta, enim ex posuere lacus, in pulvinar lectus magna in odio. Nullam iaculis congue lorem ac suscipit. Proin ut rutrum augue. Ut vehicula risus nec hendrerit ullamcorper. Ut volutpat eu mi eget viverra. Morbi dictum placerat suscipit. </p>
|
||||
<p>Quisque non erat tincidunt, lacinia justo ut, pulvinar nisl. Nunc id enim ut sem pretium interdum consectetur eu quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam posuere erat eget augue finibus luctus. Maecenas auctor, tortor non luctus ultrices, neque neque porttitor ex, nec lacinia lorem ligula et elit. Sed tempor nulla vitae lorem sollicitudin dictum. Vestibulum nec arcu eget elit pulvinar pretium. Phasellus facilisis metus sed diam luctus, feugiat scelerisque velit dignissim.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus luctus facilisis suscipit. Cras pulvinar, purus sagittis pulvinar porta, enim ex posuere lacus, in pulvinar lectus magna in odio. Nullam iaculis congue lorem ac suscipit. Proin ut rutrum augue. Ut vehicula risus nec hendrerit ullamcorper. Ut volutpat eu mi eget viverra. Morbi dictum placerat suscipit. </p>
|
||||
<p>Quisque non erat tincidunt, lacinia justo ut, pulvinar nisl. Nunc id enim ut sem pretium interdum consectetur eu quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam posuere erat eget augue finibus luctus. Maecenas auctor, tortor non luctus ultrices, neque neque porttitor ex, nec lacinia lorem ligula et elit. Sed tempor nulla vitae lorem sollicitudin dictum. Vestibulum nec arcu eget elit pulvinar pretium. Phasellus facilisis metus sed diam luctus, feugiat scelerisque velit dignissim.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus luctus facilisis suscipit. Cras pulvinar, purus sagittis pulvinar porta, enim ex posuere lacus, in pulvinar lectus magna in odio. Nullam iaculis congue lorem ac suscipit. Proin ut rutrum augue. Ut vehicula risus nec hendrerit ullamcorper. Ut volutpat eu mi eget viverra. Morbi dictum placerat suscipit. </p>
|
||||
<p>Quisque non erat tincidunt, lacinia justo ut, pulvinar nisl. Nunc id enim ut sem pretium interdum consectetur eu quam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam posuere erat eget augue finibus luctus. Maecenas auctor, tortor non luctus ultrices, neque neque porttitor ex, nec lacinia lorem ligula et elit. Sed tempor nulla vitae lorem sollicitudin dictum. Vestibulum nec arcu eget elit pulvinar pretium. Phasellus facilisis metus sed diam luctus, feugiat scelerisque velit dignissim.</p>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button class="sc-button green" @click="modal1.showModal = false; modal2.showModal = true">
|
||||
{{ $t('action.next')}}</button>
|
||||
</template>
|
||||
</modal>
|
||||
</teleport>
|
||||
|
||||
<teleport to="body">
|
||||
<modal v-if="modal2.showModal" :modalDialogClass="modal2.modalDialogClass" @close="modal2.showModal = false">
|
||||
<template v-slot:header>
|
||||
<h3 class="modal-title">Une autre modale</h3>
|
||||
</template>
|
||||
<template v-slot:body>
|
||||
<p>modal 2</p>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button class="sc-button green" @click="modal2.showModal = false">
|
||||
{{ $t('action.save')}}</button>
|
||||
</template>
|
||||
</modal>
|
||||
</teleport>
|
||||
<!-- END TESTS -->
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal'
|
||||
|
||||
export default {
|
||||
name: 'Requestor',
|
||||
components: {
|
||||
Modal,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modal1: {
|
||||
showModal: false,
|
||||
modalDialogClass: "modal-dialog-scrollable modal-xl" // modal-lg modal-md modal-sm
|
||||
},
|
||||
modal2: {
|
||||
showModal: false,
|
||||
modalDialogClass: "modal-dialog-centered modal-sm" // modal-lg modal-md modal-sm
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
accompanyingCourse() {
|
||||
return this.$store.state.accompanyingCourse
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,23 @@
|
||||
import { createApp } from 'vue'
|
||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
|
||||
import { appMessages } from './js/i18n'
|
||||
import { initPromise } from './store'
|
||||
|
||||
import App from './App.vue';
|
||||
|
||||
initPromise.then(store => {
|
||||
|
||||
//console.log('store in create_store', store);
|
||||
//console.log('store accompanyingCourse', store.state.accompanyingCourse);
|
||||
|
||||
const i18n = _createI18n(appMessages);
|
||||
|
||||
const app = createApp({
|
||||
template: `<app></app>`,
|
||||
})
|
||||
.use(store)
|
||||
.use(i18n)
|
||||
.component('app', App)
|
||||
.mount('#accompanying-course');
|
||||
|
||||
});
|
@@ -0,0 +1,32 @@
|
||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
||||
|
||||
const appMessages = {
|
||||
fr: {
|
||||
course: {
|
||||
id: "id",
|
||||
title: "Parcours",
|
||||
opening_date: "Date d'ouverture",
|
||||
closing_date: "Date de clôture",
|
||||
remark: "Commentaire",
|
||||
closing_motive: "Motif de clôture",
|
||||
},
|
||||
persons_associated: {
|
||||
title: "Usagers concernés",
|
||||
counter: "Pas d'usager | 1 usager | {count} usagers",
|
||||
firstname: "Prénom",
|
||||
lastname: "Nom",
|
||||
startdate: "Date d'entrée",
|
||||
enddate: "Date de sortie",
|
||||
addPerson: "Ajouter un usager",
|
||||
},
|
||||
requestor: {
|
||||
title: "Demandeur",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Object.assign(appMessages.fr, personMessages.fr);
|
||||
|
||||
export {
|
||||
appMessages
|
||||
};
|
@@ -0,0 +1,76 @@
|
||||
import 'es6-promise/auto';
|
||||
import { createStore } from 'vuex';
|
||||
import addPersons from './modules/addPersons'
|
||||
import { getAccompanyingCourse, postParticipation } from '../api';
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const id = window.accompanyingCourseId; //tmp
|
||||
|
||||
let initPromise = getAccompanyingCourse(id)
|
||||
.then(accompanying_course => new Promise((resolve, reject) => {
|
||||
|
||||
const store = createStore({
|
||||
strict: debug,
|
||||
modules: {
|
||||
addPersons
|
||||
},
|
||||
state: {
|
||||
accompanyingCourse: accompanying_course,
|
||||
errorMsg: []
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
mutations: {
|
||||
removeParticipation(state, item) {
|
||||
//console.log('mutation: remove item', item.id);
|
||||
state.accompanyingCourse.participations = state.accompanyingCourse.participations.filter(participation => participation !== item);
|
||||
},
|
||||
closeParticipation(state, { participation, payload }) {
|
||||
console.log('### mutation: close item', { participation, payload });
|
||||
// trouve dans le state le payload et le supprime du state
|
||||
state.accompanyingCourse.participations = state.accompanyingCourse.participations.filter(participation => participation !== payload);
|
||||
// pousse la participation
|
||||
state.accompanyingCourse.participations.push(participation);
|
||||
},
|
||||
addParticipation(state, participation) {
|
||||
//console.log('### mutation: add participation', participation);
|
||||
state.accompanyingCourse.participations.push(participation);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
removeParticipation({ commit }, payload) {
|
||||
commit('removeParticipation', payload);
|
||||
},
|
||||
closeParticipation({ commit }, payload) {
|
||||
//console.log('## action: fetch delete participation: payload', payload.person.id);
|
||||
postParticipation(id, payload.person.id, 'DELETE')
|
||||
.then(participation => new Promise((resolve, reject) => {
|
||||
//console.log('payload', payload);
|
||||
commit('closeParticipation', { participation, payload });
|
||||
resolve();
|
||||
}))
|
||||
.catch((error) => {
|
||||
state.errorMsg.push(error.message);
|
||||
});
|
||||
},
|
||||
addParticipation(addPersons, payload) {
|
||||
//console.log('## action: fetch post participation: payload', payload.id);
|
||||
postParticipation(id, payload.id, 'POST')
|
||||
.then(participation => new Promise((resolve, reject) => {
|
||||
//console.log(participation, payload);
|
||||
addPersons.commit('addParticipation', participation);
|
||||
addPersons.commit('resetState', payload);
|
||||
resolve();
|
||||
}))
|
||||
.catch((error) => {
|
||||
state.errorMsg.push(error.message);
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
//console.log('store object', store.state.accompanyingCourse.id);
|
||||
resolve(store);
|
||||
}));
|
||||
|
||||
export { initPromise };
|
@@ -0,0 +1,76 @@
|
||||
import { searchPersons } from 'ChillPersonAssets/vuejs/_api/AddPersons'
|
||||
import { postParticipation } from '../../api';
|
||||
|
||||
|
||||
// initial state
|
||||
const state = {
|
||||
query: "",
|
||||
suggested: [],
|
||||
selected: []
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
selectedAndSuggested: state => {
|
||||
const uniqBy = (a, key) => [
|
||||
...new Map(
|
||||
a.map(x => [key(x), x])
|
||||
).values()
|
||||
];
|
||||
let union = [...new Set([
|
||||
...state.suggested.slice().reverse(),
|
||||
...state.selected.slice().reverse(),
|
||||
])];
|
||||
return uniqBy(union, k => k.id);
|
||||
}
|
||||
}
|
||||
|
||||
// mutations
|
||||
const mutations = {
|
||||
setQuery(state, query) {
|
||||
//console.log('q=', query);
|
||||
state.query = query;
|
||||
},
|
||||
loadSuggestions(state, suggested) {
|
||||
state.suggested = suggested;
|
||||
},
|
||||
updateSelected(state, value) {
|
||||
state.selected = value;
|
||||
},
|
||||
resetState(state, selected) {
|
||||
//console.log('avant', state.selected);
|
||||
state.selected = state.selected.filter(value => value !== selected);
|
||||
//console.log('après', state.selected);
|
||||
state.query = "";
|
||||
state.suggested = [];
|
||||
}
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
setQuery({ commit }, payload) {
|
||||
//console.log('## action: setquery: payload', payload);
|
||||
commit('setQuery', payload.query);
|
||||
if (payload.query.length >= 3) {
|
||||
searchPersons(payload.query)
|
||||
.then(suggested => new Promise((resolve, reject) => {
|
||||
commit('loadSuggestions', suggested.results);
|
||||
resolve();
|
||||
}));
|
||||
} else {
|
||||
commit('loadSuggestions', []);
|
||||
}
|
||||
},
|
||||
updateSelected({ commit }, payload) {
|
||||
//console.log('## action: update selected values: payload', payload);
|
||||
commit('updateSelected', payload);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
//namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
const
|
||||
locale = 'fr',
|
||||
format = 'json'
|
||||
;
|
||||
|
||||
/*
|
||||
* Endpoint chill_person_search, method GET, get a list of persons
|
||||
*
|
||||
* @query string - the query to search for
|
||||
*/
|
||||
let searchPersons = (query) => {
|
||||
let url = `/${locale}/search.${format}?name=person_regular&q=${query}`;
|
||||
return fetch(url)
|
||||
.then(response => {
|
||||
if (response.ok) { return response.json(); }
|
||||
throw Error('Error with request resource response');
|
||||
});
|
||||
};
|
||||
|
||||
export { searchPersons };
|
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<button class="sc-button bt-create centered mt-4" @click="openModal">
|
||||
{{ $t('add_persons.search_add_others_persons') }}
|
||||
</button>
|
||||
|
||||
<teleport to="body">
|
||||
<modal v-if="modal.showModal"
|
||||
:modalDialogClass="modal.modalDialogClass"
|
||||
@close="modal.showModal = false">
|
||||
|
||||
<template v-slot:header>
|
||||
<h3 class="modal-title">{{ $t('add_persons.title') }}</h3>
|
||||
</template>
|
||||
|
||||
<template v-slot:body-fixed>
|
||||
<div class="search">
|
||||
<label style="float: right;">
|
||||
{{ $tc('add_persons.suggested_counter', suggestedCounter) }}
|
||||
</label>
|
||||
|
||||
<input id="search-persons"
|
||||
name="query"
|
||||
v-model="query"
|
||||
:placeholder="$t('add_persons.search_some_persons')"
|
||||
ref="search" />
|
||||
<i class="fa fa-search fa-lg"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:body>
|
||||
<!--span class="discret">Selection: {{ selected }}</span-->
|
||||
<div class="results">
|
||||
<div class="count">
|
||||
<span>
|
||||
<a v-if="suggestedCounter > 0" href="#">
|
||||
{{ $t('action.check_all')}}</a>
|
||||
<a v-if="selectedCounter > 0" href="#">
|
||||
{{ $t('action.reset')}}</a>
|
||||
</span>
|
||||
<span v-if="selectedCounter > 0">
|
||||
{{ $tc('add_persons.selected_counter', selectedCounter) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<person-suggestion
|
||||
v-for="item in this.selectedAndSuggested.slice().reverse()"
|
||||
v-bind:item="item"
|
||||
v-bind:key="item.id">
|
||||
</person-suggestion>
|
||||
|
||||
<button v-if="query.length >= 3" class="sc-button bt-create ml-5 mt-2" name="createPerson">
|
||||
{{ $t('action.create') }} "{{ query }}"
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:footer>
|
||||
<button class="sc-button green" @click="addNewPersons">
|
||||
<i class="fa fa-plus fa-fw"></i>{{ $t('action.add')}}
|
||||
</button>
|
||||
</template>
|
||||
|
||||
</modal>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
|
||||
import PersonSuggestion from 'ChillPersonAssets/vuejs/_components/PersonSuggestion';
|
||||
|
||||
export default {
|
||||
name: 'AddPersons',
|
||||
components: {
|
||||
Modal,
|
||||
PersonSuggestion,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modal: {
|
||||
showModal: false,
|
||||
modalDialogClass: "modal-dialog-scrollable modal-xl"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
addPersons: state => state.addPersons
|
||||
}),
|
||||
query: {
|
||||
set(query) {
|
||||
this.$store.dispatch('setQuery', { query });
|
||||
},
|
||||
get() {
|
||||
return this.addPersons.query;
|
||||
}
|
||||
},
|
||||
suggested() {
|
||||
return this.addPersons.suggested;
|
||||
},
|
||||
suggestedCounter() {
|
||||
return this.addPersons.suggested.length;
|
||||
},
|
||||
selected() {
|
||||
return this.addPersons.selected;
|
||||
},
|
||||
selectedCounter() {
|
||||
return this.addPersons.selected.length;
|
||||
},
|
||||
selectedAndSuggested() {
|
||||
return this.$store.getters.selectedAndSuggested;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openModal() {
|
||||
this.modal.showModal = true;
|
||||
this.$nextTick(function() {
|
||||
this.$refs.search.focus();
|
||||
})
|
||||
},
|
||||
addNewPersons() {
|
||||
console.log('@@@ CLICK button addPersons')
|
||||
this.selected.forEach(function(item) {
|
||||
//console.log('# dispatch action for each item', item);
|
||||
this.$store.dispatch('addParticipation', item);
|
||||
}, this
|
||||
);
|
||||
this.modal.showModal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="list-item" :class="{ checked: isChecked }">
|
||||
<div class="container">
|
||||
|
||||
<!--a class="discret" target="_blank" :href="url.show">{{ item.id }}</a-->
|
||||
<input class=""
|
||||
type="checkbox"
|
||||
v-model="selected"
|
||||
:value="item" />
|
||||
|
||||
{{ item.text }}
|
||||
|
||||
</div>
|
||||
<div class="right_actions">
|
||||
|
||||
<span class="badge badge-pill badge-secondary" :title="item.id">
|
||||
{{ $t('item.type_person') }}
|
||||
</span>
|
||||
<a class="sc-button bt-show" target="_blank" :title="item.id" :href="url.show"></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'PersonSuggestion',
|
||||
props: ['item'],
|
||||
data() {
|
||||
return {
|
||||
url: {
|
||||
show: '/fr/person/' + this.item.id + '/general',
|
||||
edit: '/fr/person/' + this.item.id + '/general/edit'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selected: {
|
||||
set(value) {
|
||||
this.$store.dispatch('updateSelected', value);
|
||||
},
|
||||
get() {
|
||||
return this.$store.state.addPersons.selected;
|
||||
}
|
||||
},
|
||||
isChecked() {
|
||||
return (this.selected.indexOf(this.item) === -1) ? false : true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,21 @@
|
||||
const personMessages = {
|
||||
fr: {
|
||||
add_persons: {
|
||||
search_add_others_persons: "Rechercher et ajouter d'autres usagers",
|
||||
title: "Ajouter des usagers",
|
||||
suggested_counter: "Pas de résultats | 1 résultat | {count} résultats",
|
||||
selected_counter: " 1 sélectionné | {count} sélectionnés",
|
||||
search_some_persons: "Rechercher des personnes..",
|
||||
},
|
||||
item: {
|
||||
type_person: "Usager",
|
||||
type_tms: "TMS",
|
||||
type_3rdparty: "Tiers",
|
||||
type_menage: "Ménage"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
personMessages
|
||||
};
|
@@ -5,15 +5,13 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
<div id="accompanying-course"></div>
|
||||
{% endblock %}
|
||||
|
||||
{{ encore_entry_script_tags('accompanying_course') }}
|
||||
|
||||
{% block js %}
|
||||
<script type="text/javascript">
|
||||
window.accompanyingCourseId = {{ accompanyingCourse.id|e('js') }};
|
||||
</script>
|
||||
|
||||
{{ encore_entry_script_tags('accompanying_course') }}
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user