refactor pickTemplate and adapt existing usage

This commit is contained in:
Julien Fastré 2022-02-01 15:49:23 +01:00
parent 5d2cb8c712
commit c6373a075d
9 changed files with 126 additions and 60 deletions

View File

@ -34,6 +34,7 @@ use Psr\Log\LoggerInterface;
use RuntimeException; use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -393,9 +394,25 @@ final class ActivityController extends AbstractController
'role' => new Role('CHILL_ACTIVITY_CREATE'), 'role' => new Role('CHILL_ACTIVITY_CREATE'),
'activityType' => $entity->getActivityType(), 'activityType' => $entity->getActivityType(),
'accompanyingPeriod' => $accompanyingPeriod, 'accompanyingPeriod' => $accompanyingPeriod,
])->handleRequest($request); ]);
if ($form->has('documents')) {
$form->add('gendocTemplateId', HiddenType::class, [
'mapped' => false,
'data' => null,
'attr' => [
// required for js
'data-template-id' => 'data-template-id',
],
]);
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { if ($form->isSubmitted() && $form->isValid()) {
if ($form->has('gendocTemplateId')) {
dd($form->get('gendocTemplateId')->getData());
}
$this->entityManager->persist($entity); $this->entityManager->persist($entity);
$this->entityManager->flush(); $this->entityManager->flush();

View File

@ -2,11 +2,15 @@ import { createApp } from 'vue';
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n' import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
import { activityMessages } from './i18n' import { activityMessages } from './i18n'
import store from './store' import store from './store'
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
import {fetchTemplates} from 'ChillDocGeneratorAssets/api/pickTemplate.js';
import App from './App.vue'; import App from './App.vue';
const i18n = _createI18n(activityMessages); const i18n = _createI18n(activityMessages);
// app for activity
const hasSocialIssues = document.querySelector('#social-issues-acc') !== null; const hasSocialIssues = document.querySelector('#social-issues-acc') !== null;
const hasLocation = document.querySelector('#location') !== null; const hasLocation = document.querySelector('#location') !== null;
const hasPerson = document.querySelector('#add-persons') !== null; const hasPerson = document.querySelector('#add-persons') !== null;
@ -29,3 +33,57 @@ const app = createApp({
.use(i18n) .use(i18n)
.component('app', App) .component('app', App)
.mount('#activity'); .mount('#activity');
// app for picking template
const i18nGendoc = _createI18n({});
document.querySelectorAll('div[data-docgen-template-picker]').forEach(el => {
fetchTemplates(el.dataset.entityClass).then(templates => {
let
picker = {
template: '<pick-template :templates="this.templates" :entityId="this.entityId" @generate="generateDoc" :entityClass="faked"></pick-template>',
components: {
PickTemplate,
},
data() {
return {
templates: templates,
entityId: el.dataset.entityId,
}
},
methods: {
generateDoc({event, link, template}) {
console.log('generateDoc');
console.log('link', link);
console.log('template', template);
event.preventDefault();
let hiddenInput = document.querySelector("input[data-template-id]");
if (hiddenInput === null) {
console.error('hidden input not found');
return;
}
hiddenInput.value = template;
let form = document.querySelect('form[name="chill_activitybundle_activity"');
if (form === null) {
console.error('form not found');
return;
}
console.log('subbmitting formt');
form.submit();
}
}
}
;
createApp(picker).use(i18nGendoc).mount(el);
})
});

View File

@ -89,9 +89,9 @@
{%- if edit_form.documents is defined -%} {%- if edit_form.documents is defined -%}
{{ form_row(edit_form.documents) }} {{ form_row(edit_form.documents) }}
<div data-docgen-template-picker="data-docgen-template-picker" data-entity-class="Chill\ActivityBundle\Entity\Activity" data-entity-id="{{ entity.id }}"></div>
{% endif %} {% endif %}
<div data-docgen-template-picker="data-docgen-template-picker" data-entity-class="Chill\ActivityBundle\Entity\Activity" data-entity-id="{{ entity.id }}"></div>
{% set person_id = null %} {% set person_id = null %}
{% if entity.person %} {% if entity.person %}

View File

@ -87,6 +87,7 @@
{%- if form.documents is defined -%} {%- if form.documents is defined -%}
{{ form_row(form.documents) }} {{ form_row(form.documents) }}
<div data-docgen-template-picker="data-docgen-template-picker" data-entity-class="Chill\ActivityBundle\Entity\Activity" data-entity-id="{{ entity.id }}"></div>
{% endif %} {% endif %}
{%- if form.attendee is defined -%} {%- if form.attendee is defined -%}

View File

@ -17,18 +17,16 @@
{{ parent() }} {{ parent() }}
{{ encore_entry_script_tags('mod_async_upload') }} {{ encore_entry_script_tags('mod_async_upload') }}
<script type="text/javascript"> <script type="text/javascript">
window.addEventListener('DOMContentLoaded', function (e) {
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]',
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
});
window.activity = {{ activity_json|json_encode|raw }}; window.activity = {{ activity_json|json_encode|raw }};
{% if default_location is not null %}window.default_location_id = {{ default_location.id }}{% endif %}; {% if default_location is not null %}window.default_location_id = {{ default_location.id }}{% endif %};
</script> </script>
{{ encore_entry_script_tags('vue_activity') }} {{ encore_entry_script_tags('vue_activity') }}
{{ encore_entry_script_tags('mod_docgen_picktemplate') }}
{% endblock %} {% endblock %}
{% block css %} {% block css %}
{{ parent() }} {{ parent() }}
{{ encore_entry_link_tags('mod_async_upload') }} {{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('vue_activity') }} {{ encore_entry_link_tags('vue_activity') }}
{{ encore_entry_link_tags('mod_docgen_picktemplate') }}
{% endblock %} {% endblock %}

View File

@ -23,9 +23,11 @@
window.activity = {{ activity_json|json_encode|raw }}; window.activity = {{ activity_json|json_encode|raw }};
</script> </script>
{{ encore_entry_script_tags('vue_activity') }} {{ encore_entry_script_tags('vue_activity') }}
{{ encore_entry_script_tags('mod_docgen_picktemplate') }}
{% endblock %} {% endblock %}
{% block css %} {% block css %}
{{ encore_entry_link_tags('mod_async_upload') }} {{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('vue_activity') }} {{ encore_entry_link_tags('vue_activity') }}
{{ encore_entry_link_tags('mod_docgen_picktemplate') }}
{% endblock %} {% endblock %}

View File

@ -0,0 +1,13 @@
const buildLink = function(templateId, entityId, entityClass) {
const
entityIdEncoded = encodeURI(entityId),
returnPath = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash),
entityClassEncoded = encodeURI(entityClass),
url = `/fr/doc/gen/generate/from/${templateId}/for/${entityClassEncoded}/${entityIdEncoded}?returnPath=${returnPath}`
;
console.log('computed Url');
return url;
};
export {buildLink};

View File

@ -20,8 +20,8 @@
<option v-bind:value="t.id">{{ t.name.fr || 'Aucun nom défini' }}</option> <option v-bind:value="t.id">{{ t.name.fr || 'Aucun nom défini' }}</option>
</template> </template>
</select> </select>
<button v-if="canGenerate" class="btn btn-update btn-sm change-icon" type="button" @click="generateDocument"><i class="fa fa-fw fa-cog"></i></button> <a v-if="canGenerate" class="btn btn-update btn-sm change-icon" :href="buildUrlGenerate" @click.prevent="clickGenerate($event, buildUrlGenerate)"><i class="fa fa-fw fa-cog"></i></a>
<button v-else class="btn btn-update btn-sm change-icon" type="button" disabled ><i class="fa fa-fw fa-cog"></i></button> <a v-else class="btn btn-update btn-sm change-icon" href="#" disabled ><i class="fa fa-fw fa-cog"></i></a>
</div> </div>
</div> </div>
</div> </div>
@ -39,24 +39,27 @@
<script> <script>
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
export default { export default {
name: "PickTemplate", name: "PickTemplate",
props: { props: {
entityId: [String, Number], entityId: [String, Number],
entityClass: { entityClass: {
type: String, type: String,
required: true, required: false,
}, },
templates: { templates: {
type: Array, type: Array,
required: true, required: true,
}, },
// beforeMove execute "something" before preventDefaultMoveToGenerate: {
beforeMove: { type: Boolean,
type: Function,
required: false, required: false,
default: false,
} }
}, },
emits: ['goToGenerateDocument'],
data() { data() {
return { return {
template: null, template: null,
@ -74,66 +77,37 @@ export default {
return true; return true;
}, },
getDescription() { getDescription() {
if (null === this.template) {
return '';
}
let desc = this.templates.find(t => t.id === this.template); let desc = this.templates.find(t => t.id === this.template);
if (null === desc) { if (null === desc) {
return ''; return '';
} }
return desc.description || ''; return desc.description || '';
}, },
buildUrlGenerate() {
if (null === this.template) {
return '#';
}
return buildLink(this.template, this.entityId, this.entityClass);
}
}, },
methods: { methods: {
generateDocument() { clickGenerate(event, link) {
console.log('generateDocument'); if (!this.preventDefaultMoveToGenerate) {
console.log('beforeMove', this.beforeMove); window.location.assign(link);
if (this.beforeMove != null) {
console.log('execute before move');
let r = this.beforeMove();
if (r instanceof Promise) {
r.then((obj) => this.goToGenerate(obj));
} else {
this.goToGenerate();
}
} else {
this.goToGenerate();
}
},
goToGenerate(obj) {
console.log('goToGenerate');
console.log('obj', obj);
console.log('entityId', this.entityId);
let
realId = this.entityId,
realEntityClass = this.entityClass
;
if (obj !== undefined) {
if (obj.entityId !== undefined) {
realId = obj.entityId;
}
if (obj.entityClass !== undefined) {
realEntityClass = obj.entityClass;
}
} }
console.log('realId', realId); this.$emit('goToGenerateDocument', {event, link, template: this.template});
console.log('realEntityClass', realEntityClass);
const
entityId = encodeURI(realId),
returnPath = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash),
fqdnEntityClass = encodeURI(realEntityClass),
url = `/fr/doc/gen/generate/from/${this.template}/for/${fqdnEntityClass}/${entityId}?returnPath=${returnPath}`
;
console.log('I will generate your doc at', url);
window.location.assign(url);
}, },
}, },
i18n: { i18n: {
messages: { messages: {
fr: { fr: {
generate_document: 'Générer un document', generate_document: 'Générer un document',
select_a_template: 'Choisir un gabarit', select_a_template: 'Choisir un modèle',
choose_a_template: 'Choisir', choose_a_template: 'Choisir',
} }
} }

View File

@ -92,7 +92,8 @@
entityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation" entityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation"
:id="evaluation.id" :id="evaluation.id"
:templates="getTemplatesAvailables" :templates="getTemplatesAvailables"
:beforeMove="submitBeforeGenerate" :preventDefaultMoveToGenerate="true"
@go-to-generate-document="submitBeforeGenerate"
> >
<template v-slot:title> <template v-slot:title>
<label class="col-sm-4 col-form-label">{{ $t('evaluation_generate_a_document') }}</label> <label class="col-sm-4 col-form-label">{{ $t('evaluation_generate_a_document') }}</label>
@ -109,6 +110,7 @@ import CKEditor from '@ckeditor/ckeditor5-vue';
import ClassicEditor from 'ChillMainAssets/module/ckeditor5/index.js'; import ClassicEditor from 'ChillMainAssets/module/ckeditor5/index.js';
import { mapGetters, mapState } from 'vuex'; import { mapGetters, mapState } from 'vuex';
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue'; import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue';
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator';
const i18n = { const i18n = {
messages: { messages: {
@ -123,7 +125,7 @@ const i18n = {
evaluation_public_comment: "Note publique", evaluation_public_comment: "Note publique",
evaluation_comment_placeholder: "Commencez à écrire ...", evaluation_comment_placeholder: "Commencez à écrire ...",
evaluation_generate_a_document: "Générer un document", evaluation_generate_a_document: "Générer un document",
evaluation_choose_a_template: "Choisir un gabarit", evaluation_choose_a_template: "Choisir un modèle",
evaluation_add_a_document: "Ajouter un document", evaluation_add_a_document: "Ajouter un document",
evaluation_add: "Ajouter une évaluation", evaluation_add: "Ajouter une évaluation",
Documents: "Documents", Documents: "Documents",
@ -207,10 +209,11 @@ export default {
return `/wopi/edit/${storedObject.uuid}?returnPath=` + encodeURIComponent( return `/wopi/edit/${storedObject.uuid}?returnPath=` + encodeURIComponent(
window.location.pathname + window.location.search + window.location.hash); window.location.pathname + window.location.search + window.location.hash);
}, },
submitBeforeGenerate() { submitBeforeGenerate({template}) {
const callback = (data) => { const callback = (data) => {
let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id; let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id;
return Promise.resolve({entityId: evaluationId});
window.location.assign(buildLink(template, evaluationId, 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation'));
}; };
return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; }); return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; });