diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/public/api/pickTemplate.js b/src/Bundle/ChillDocGeneratorBundle/Resources/public/api/pickTemplate.js new file mode 100644 index 000000000..a668fe29d --- /dev/null +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/public/api/pickTemplate.js @@ -0,0 +1,10 @@ +import { fetchResults } from "ChillMainAssets/lib/api/apiMethods.js"; + +const fetchTemplates = (entityClass) => { + let fqdnEntityClass = encodeURI(entityClass); + return fetchResults(`/api/1.0/docgen/templates/by-entity/${fqdnEntityClass}`); +} + +export { + fetchTemplates +}; diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/public/module/PickTemplate/index.js b/src/Bundle/ChillDocGeneratorBundle/Resources/public/module/PickTemplate/index.js index 8b450a7e1..9d26d1009 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Resources/public/module/PickTemplate/index.js +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/public/module/PickTemplate/index.js @@ -1,24 +1,27 @@ import {createApp} from 'vue'; import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue'; +import {fetchTemplates} from 'ChillDocGeneratorAssets/api/pickTemplate.js'; import {_createI18n} from 'ChillMainAssets/vuejs/_js/i18n'; const i18n = _createI18n({}); document.querySelectorAll('div[data-docgen-template-picker]').forEach(el => { - let - picker = { - template: '', - components: { - PickTemplate, - }, - data() { - return { - entityClass: el.dataset.entityClass, - entityId: el.dataset.entityId, - } - }, - } - ; + fetchTemplates(el.dataset.entityClass).then(templates => { + let + picker = { + template: '', + components: { + PickTemplate, + }, + data() { + return { + templates: templates, + entityId: el.dataset.entityId, + } + }, + } + ; + createApp(picker).use(i18n).mount(el); + }) - createApp(picker).use(i18n).mount(el); }); diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue b/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue index bb8f6008a..1052fe75f 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/public/vuejs/_components/PickTemplate.vue @@ -20,7 +20,6 @@ diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodWorkEvaluationApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodWorkEvaluationApiController.php new file mode 100644 index 000000000..29b00cf4f --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodWorkEvaluationApiController.php @@ -0,0 +1,74 @@ +docGeneratorTemplateRepository = $docGeneratorTemplateRepository; + $this->serializer = $serializer; + $this->paginatorFactory = $paginatorFactory; + } + + /** + * @Route("/api/1.0/person/docgen/template/by-evaluation/{id}.{_format}", + * requirements={"format": "json"}) + */ + public function listTemplateByEvaluation(Evaluation $evaluation, string $_format): JsonResponse + { + if ('json' !== $_format) { + throw new BadRequestHttpException("format not supported"); + } + + $evaluations = + array_filter( + $this->docGeneratorTemplateRepository + ->findByEntity(AccompanyingPeriodWorkEvaluation::class), + function (DocGeneratorTemplate $t) use ($evaluation) { + $ids = $t->getOptions()['evaluations'] ?? []; + return in_array($evaluation->getId(), $ids); + } + ); + + $paginator = $this->paginatorFactory->create(count($evaluations)); + $paginator->setItemsPerPage(count($evaluations)); + + return new JsonResponse($this->serializer->serialize( + new Collection($evaluations, $paginator), 'json', [ + AbstractNormalizer::GROUPS => ['read'] + ] + ), JsonResponse::HTTP_OK, [], true); + } +} diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php index afcfc4228..ec22e806e 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/Origin.php @@ -54,8 +54,6 @@ class Origin public function getLabel() { - dump($this->label); - return $this->label; } diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue index 58675b54d..b7a137de2 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/App.vue @@ -196,7 +196,8 @@ @@ -329,6 +330,7 @@ export default { 'thirdParties', 'isPosting', 'errors', + 'templatesAvailablesForAction', ]), ...mapGetters([ 'hasResultsForAction', @@ -397,7 +399,7 @@ export default { this.$store.commit('removeGoal', g); }, addEvaluation(e) { - this.$store.commit('addEvaluation', e); + this.$store.dispatch('addEvaluation', e); }, toggleAddEvaluation() { this.showAddEvaluation = !this.showAddEvaluation; diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue index 33436f222..7ea4dfc16 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue @@ -61,21 +61,18 @@ - - {{ $t('evaluation_generate_a_document') }} - - - - {{ $t('evaluation_choose_a_template') }} - - {{ t.name.fr }} - - - - - - - + + + + {{ $t('evaluation_generate_a_document') }} + + + @@ -85,6 +82,7 @@ import {dateToISO, ISOToDate, ISOToDatetime} from 'ChillMainAssets/chill/js/date import CKEditor from '@ckeditor/ckeditor5-vue'; import ClassicEditor from 'ChillMainAssets/module/ckeditor5/index.js'; import { mapGetters, mapState } from 'vuex'; +import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue'; const i18n = { messages: { @@ -111,6 +109,7 @@ export default { props: ['evaluation'], components: { ckeditor: CKEditor.component, + PickTemplate, }, i18n, data() { @@ -120,12 +119,12 @@ export default { } }, computed: { - ...mapGetters([ - 'getTemplatesAvailaibleForEvaluation' - ]), ...mapState([ 'isPosting' ]), + getTemplatesAvailables() { + return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation); + }, canGenerate() { return !this.$store.state.isPosting && this.template !== null; }, @@ -176,13 +175,14 @@ export default { }) ; }, - generateDocument() { - console.log('template picked', this.template); - this.$store.dispatch('generateDocument', { key: this.evaluation.key, templateId: this.template}) + submitBeforeGenerate() { + const callback = (data) => { + let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id; + return Promise.resolve({entityId: evaluationId}); + }; + + return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; }); } }, - mounted() { - //this.listAllStatus(); - } } diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js index 22218f04f..92ee414a7 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js @@ -2,6 +2,8 @@ import { createStore } from 'vuex'; import { datetimeToISO, ISOToDatetime, intervalDaysToISO, intervalISOToDays } from 'ChillMainAssets/chill/js/date.js'; import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js'; import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js'; +import { fetchResults, makeFetch } from 'ChillMainAssets/lib/api/apiMethods.js'; +import { fetchTemplates } from 'ChillDocGeneratorAssets/api/pickTemplate.js'; const debug = process.env.NODE_ENV !== 'production'; const evalFQDN = encodeURIComponent("Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation"); @@ -20,20 +22,10 @@ const store = createStore({ resultsPicked: window.accompanyingCourseWork.results, resultsForAction: [], resultsForGoal: [], - evaluationsPicked: window.accompanyingCourseWork.accompanyingPeriodWorkEvaluations.map((e, index) => { - var k = Object.assign(e, { - key: index, - editEvaluation: false, - startDate: e.startDate !== null ? ISOToDatetime(e.startDate.datetime) : null, - endDate: e.endDate !== null ? ISOToDatetime(e.endDate.datetime) : null, - maxDate: e.maxDate !== null ? ISOToDatetime(e.maxDate.datetime) : null, - warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null, - }); - - return k; - }), + evaluationsPicked: [], evaluationsForAction: [], - templatesAvailableForEvaluation: [], + templatesAvailablesForAction: [], + templatesAvailablesForEvaluation: new Map([]), personsPicked: window.accompanyingCourseWork.persons, personsReachables: window.accompanyingCourseWork.accompanyingPeriod.participations.filter(p => p.endDate == null) .map(p => p.person), @@ -65,8 +57,8 @@ const store = createStore({ hasThirdParties(state) { return state.thirdParties.length > 0; }, - getTemplatesAvailaibleForEvaluation(state) { - return state.templatesAvailableForEvaluation; + getTemplatesAvailablesForEvaluation: (state) => (evaluation) => { + return state.templatesAvailablesForEvaluation.get(evaluation.id) || []; }, buildPayload(state) { return { @@ -125,6 +117,20 @@ const store = createStore({ } }, mutations: { + setEvaluationsPicked(state, evaluations) { + state.evaluationsPicked = evaluations.map((e, index) => { + var k = Object.assign(e, { + key: index, + editEvaluation: false, + startDate: e.startDate !== null ? ISOToDatetime(e.startDate.datetime) : null, + endDate: e.endDate !== null ? ISOToDatetime(e.endDate.datetime) : null, + maxDate: e.maxDate !== null ? ISOToDatetime(e.maxDate.datetime) : null, + warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null, + }); + + return k; + }); + }, setStartDate(state, date) { state.startDate = date; }, @@ -222,10 +228,11 @@ const store = createStore({ let evaluation = state.evaluationsPicked.find(e => e.key === key); evaluation.editEvaluation = !evaluation.editEvaluation; }, - setTemplatesAvailableForEvaluation(state, templates) { - for (let i in templates) { - state.templatesAvailableForEvaluation.push(templates[i]); - } + setTemplatesForEvaluation(state, {templates, evaluation}) { + state.templatesAvailablesForEvaluation.set(evaluation.id, templates); + }, + setTemplatesAvailablesForAction(state, templates) { + state.templatesAvailablesForAction = templates; }, setPersonsPickedIds(state, ids) { state.personsPicked = state.personsReachables @@ -328,36 +335,19 @@ const store = createStore({ commit('setEvaluationsForAction', data.results); }); }, - getReachableTemplatesForEvaluation({commit}) { - const - url = `/fr/doc/gen/templates/for/${evalFQDN}` - ; - window.fetch(url).then(r => { - if (r.ok) { - return r.json(); - } - throw new Error("not possible to load templates for evaluations") - }).then(data => { - commit('setTemplatesAvailableForEvaluation', data.results); - }).catch(e => { - console.error(e); - }) + addEvaluation({commit, dispatch}, evaluation) { + commit('addEvaluation', evaluation); + dispatch('fetchTemplatesAvailablesForEvaluation', evaluation); }, - generateDocument({ dispatch }, {key, templateId}) { - const callback = function(data) { - // get the evaluation id from the data - const - evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === key).id, - returnPath = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash), - url = `/fr/doc/gen/generate/from/${templateId}/for/${evalFQDN}/${evaluationId}?returnPath=${returnPath}` - ; - //http://localhost:8001/fr/doc/gen/generate/from/12/for/Chill%5CPersonBundle%5CEntity%5CAccompanyingPeriod%5CAccompanyingPeriodWorkEvaluation/41 - - console.log('I will generate your doc at', url); - window.location.assign(url); - }; - - dispatch('submit', callback); + fetchTemplatesAvailablesForEvaluation({commit, state}, evaluation) { + if (!state.templatesAvailablesForEvaluation.has(evaluation.id)) { + // commit an empty array to avoid parallel fetching for same evaluation id + commit('setTemplatesForEvaluation', {templates: [], evaluation}); + fetchResults(`/api/1.0/person/docgen/template/by-evaluation/${evaluation.id}.json`) + .then(templates => { + commit('setTemplatesForEvaluation', {templates, evaluation}); + }); + } }, submit({ getters, state, commit }, callback) { let @@ -368,47 +358,36 @@ const store = createStore({ commit('setIsPosting', true); - window.fetch(url, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(payload) - }).then(response => { - if (response.ok || response.status === 422) { - return response.json().then(data => ({data, status: response.status})); - } - - throw new Error(response.status); - }).then(({data, status}) => { - if (status === 422) { - for (let i in data.violations) { - errors.push(data.violations[i].title); + return makeFetch('PUT', url, payload) + .then(data => { + console.log('data received', data); + if (typeof(callback) !== 'undefined') { + return callback(data); + } else { + console.info('nothing to do here, bye bye');window.location.assign(`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`); } - commit('setErrors', errors); + }).catch(error => { + console.log('error on submit', error); commit('setIsPosting', false); - } else if (typeof(callback) !== 'undefined') { - callback(data); - } else { - console.info('nothing to do here, bye bye'); - window.location.assign(`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`); - } - }).catch(e => { - commit('setErrors', [ - 'Erreur serveur ou réseau: veuillez ré-essayer. Code erreur: ' + e - ]); - commit('setIsPosting', false); - }); - }, - initAsync({ dispatch }) { - dispatch('getReachablesResultsForAction'); - dispatch('getReachablesGoalsForAction'); - dispatch('getReachablesEvaluationsForAction'); - dispatch('getReachableTemplatesForEvaluation'); + commit('setErrors', error.violations); + }); }, } }); -store.dispatch('initAsync'); +store.commit('setEvaluationsPicked', window.accompanyingCourseWork.accompanyingPeriodWorkEvaluations); +store.dispatch('getReachablesResultsForAction'); +store.dispatch('getReachablesGoalsForAction'); +store.dispatch('getReachablesEvaluationsForAction'); + +store.state.evaluationsPicked.forEach(evaluation => { + store.dispatch('fetchTemplatesAvailablesForEvaluation', evaluation.evaluation) +}); + +fetchTemplates('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork') + .then(templates => { + store.commit('setTemplatesAvailablesForAction', templates); + } +) export { store };