From 648ec68cfb6358eba6a6328572f0cf8a396f7521 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 1 Sep 2022 12:28:54 +0200 Subject: [PATCH] export SocialWorkTypeFilter: create dynamic Form Action-goal-result - initiate new Vue component - cleaning buildForm in Filter - add HiddenType with ModelTransformer - use ObjectToIdTransformer in HiddenType fields - setting mount() and teleport - list fetch url in api.js - html/bootstrap form structure - add Multiselect actionType - i18n import - add multiselect for goals and results - add and remove options in multiselect (wip) - fix basic vue add/remove element from data store - vue cleaning - add ids in value hiddenFields - adapt Filter in AlterQuery (wip) - improve code lisibility --- .../public/vuejs/FormActionGoalResult/App.vue | 295 ++++++++++++++++++ .../public/vuejs/FormActionGoalResult/api.js | 41 +++ .../vuejs/FormActionGoalResult/index.js | 13 + .../Resources/views/Export/new.html.twig | 3 + .../ChillMainBundle/chill.webpack.config.js | 1 + .../SocialWorkTypeFilter.php | 143 +++++---- 6 files changed, 442 insertions(+), 54 deletions(-) create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js create mode 100644 src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue new file mode 100644 index 000000000..39a7c023a --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/App.vue @@ -0,0 +1,295 @@ + + + + + \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js new file mode 100644 index 000000000..afcece4f4 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/api.js @@ -0,0 +1,41 @@ +import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods'; + +const getSocialActions = () => fetchResults( + '/api/1.0/person/social/social-action.json', { + item_per_page: 200 + } +); + +const getGoalByAction = (id) => { + let url = `/api/1.0/person/social-work/goal/by-social-action/${id}.json`; + return fetch(url) + .then(response => { + if (response.ok) { return response.json(); } + throw Error('Error with request resource response'); + }); +}; + +const getResultByAction = (id) => { + let url = `/api/1.0/person/social-work/result/by-social-action/${id}.json`; + return fetch(url) + .then(response => { + if (response.ok) { return response.json(); } + throw Error('Error with request resource response'); + }); +}; + +const getResultByGoal = (id) => { + let url = `/api/1.0/person/social-work/result/by-goal/${id}.json`; + return fetch(url) + .then(response => { + if (response.ok) { return response.json(); } + throw Error('Error with request resource response'); + }); +}; + +export { + getSocialActions, + getGoalByAction, + getResultByAction, + getResultByGoal, +} \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js new file mode 100644 index 000000000..d838fb0be --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/FormActionGoalResult/index.js @@ -0,0 +1,13 @@ +import { createApp } from "vue"; +import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'; +import App from './App.vue'; + +const i18n = _createI18n({}); + +const app = createApp({ + template: ``, +}) +.use(i18n) +.component('app', App) +.mount('#export_export') +; \ No newline at end of file diff --git a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig index 8aac6c253..a8b5e8ea8 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/Export/new.html.twig @@ -22,6 +22,9 @@ {% block js %} {{ encore_entry_script_tags('page_export') }} + {% if export_alias == 'count_social_work_actions' %} + {{ encore_entry_script_tags('vue_form_action_goal_result') }} + {% endif %} {% endblock js %} {% block content %} diff --git a/src/Bundle/ChillMainBundle/chill.webpack.config.js b/src/Bundle/ChillMainBundle/chill.webpack.config.js index 628f04ba5..c4c445d31 100644 --- a/src/Bundle/ChillMainBundle/chill.webpack.config.js +++ b/src/Bundle/ChillMainBundle/chill.webpack.config.js @@ -74,4 +74,5 @@ module.exports = function(encore, entries) // Vue entrypoints encore.addEntry('vue_address', __dirname + '/Resources/public/vuejs/Address/index.js'); encore.addEntry('vue_onthefly', __dirname + '/Resources/public/vuejs/OnTheFly/index.js'); + encore.addEntry('vue_form_action_goal_result', __dirname + '/Resources/public/vuejs/FormActionGoalResult/index.js'); }; diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php index 3e5889cb0..ac584ea40 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/SocialWorkFilters/SocialWorkTypeFilter.php @@ -1,27 +1,22 @@ socialActionRender = $socialActionRender; $this->translatableStringHelper = $translatableStringHelper; - $this->socialActionRepository = $socialActionRepository; + $this->em = $em; } public function buildForm(FormBuilderInterface $builder) { - $socialActions = $this->socialActionRepository->findAll(); - - $builder->add('actionType', ChoiceType::class, [ - 'choices' => $socialActions, - 'choice_label' => function (SocialAction $sa) { - return $this->socialActionRender->renderString($sa, []); - }, - 'multiple' => true, - 'expanded' => true - ]); - - /* - $refreshGoals = function (FormInterface $form, SocialAction $actionType = null) { - - $goals = null === $actionType ? [] : $actionType->getGoals(); - - $form->add('goal', ChoiceType::class, [ - 'placeholder' => '', - 'choices' => $goals, - 'choice_label' => function (Goal $g) { - return $this->translatableStringHelper->localize($g->getTitle()); + $builder + ->add('actionType', HiddenType::class) + ->get('actionType') + ->addModelTransformer(new CallbackTransformer( + static function (?iterable $actionsAsIterable): string { + if (null === $actionsAsIterable) { return ''; } + $actionIds = []; + foreach ($actionsAsIterable as $value) { + $actionIds[] = $value->getId(); + } + return implode(',', $actionIds); }, - ]); - }; + function (?string $actionsAsString): array { + if (null === $actionsAsString) { return []; } + return array_map( + fn (string $id): ?SocialAction + => $this->socialActionRepository->findOneBy(['id' => (int) $id]), + explode(',', $actionsAsString) + ); + } + )) + ; - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($refreshGoals) { - $data = $event->getData(); - dump($data); + $builder + ->add('goal', HiddenType::class) + ->get('goal') + ->addModelTransformer(new CallbackTransformer( + static function (?iterable $goalsAsIterable): string { + if (null === $goalsAsIterable) { return ''; } + $goalIds = []; + foreach ($goalsAsIterable as $value) { + $goalIds[] = $value->getId(); + } + return implode(',', $goalIds); + }, + function (?string $goalsAsString): array { + if (null === $goalsAsString) { return []; } + return array_map( + fn (string $id): ?Goal + => $this->socialActionRepository->findOneBy(['id' => (int) $id]), + explode(',', $goalsAsString) + ); + } + )) + ; - $refreshGoals($event->getForm(), $data); - }); + $builder + ->add('result', HiddenType::class) + ->get('result') + ->addModelTransformer(new CallbackTransformer( + static function (?iterable $resultsAsIterable): string { + if (null === $resultsAsIterable) { return ''; } + $resultIds = []; + foreach ($resultsAsIterable as $value) { + $resultIds[] = $value->getId(); + } + return implode(',', $resultIds); + }, + function (?string $resultsAsString): array { + if (null === $resultsAsString) { return []; } + return array_map( + fn (string $id): ?Result + => $this->socialActionRepository->findOneBy(['id' => (int) $id]), + explode(',', $resultsAsString) + ); + } + )) + ; - $builder->get('actionType')->addEventListener( - FormEvents::POST_SUBMIT, - function (FormEvent $event) use ($refreshGoals) { - $actionType = $event->getForm()->getData(); - dump($actionType); - $refreshGoals($event->getForm()->getParent(), $actionType); - } - ); - */ } public function getTitle(): string @@ -122,7 +145,15 @@ class SocialWorkTypeFilter implements FilterInterface public function alterQuery(QueryBuilder $qb, $data) { $where = $qb->getDQLPart('where'); - $clause = $qb->expr()->in('r', ':referrers'); + $clause = $qb->expr()->eq('acpw.socialAction',':actionType'); + + /* + if (!empty($data['goal'])) { + $clause + $qb->expr()->in('acpw.goals', ':goals'); + } + $qb->expr()->in('acpw.results', ':results'); + */ if ($where instanceof Andx) { $where->add($clause); @@ -131,7 +162,11 @@ class SocialWorkTypeFilter implements FilterInterface } $qb->add('where', $where); - $qb->setParameter('referrers', $data['referrers']); + $qb->setParameters([ + 'actionType' => $data['actionType'], + 'goal' => $data['goal'], + 'result' => $data['result'], + ]); } public function applyOn(): string