From 79e87ecdbe4f303fbf66960ceb6eb0d5d9105b9e Mon Sep 17 00:00:00 2001 From: Kevin Papst Date: Sun, 7 Jan 2018 21:42:27 +0100 Subject: [PATCH] added toolbar to customer screen #28 (#49) * fixed filter query #28 * fixed annotation #28 * merge message files #28 * added page size type #28 * added visibility type #28 * added filter toolbar to customer screen #28 --- app/Resources/translations/messages.de.xliff | 48 +++++++++++++ src/AppBundle/Form/Type/PageSizeType.php | 44 ++++++++++++ src/AppBundle/Form/Type/VisibilityType.php | 48 +++++++++++++ src/AppBundle/Repository/Query/BaseQuery.php | 10 +-- .../Repository/Query/VisibilityTrait.php | 6 +- .../Controller/Admin/CustomerController.php | 54 +++++++++++++-- src/TimesheetBundle/Form/ActivityEditForm.php | 4 +- src/TimesheetBundle/Form/CustomerEditForm.php | 4 +- .../Form/CustomerToolbarForm.php | 67 +++++++++++++++++++ src/TimesheetBundle/Form/ProjectEditForm.php | 4 +- .../Form/TimesheetToolbarForm.php | 5 +- .../Repository/ActivityRepository.php | 4 +- .../Repository/CustomerRepository.php | 4 +- .../Repository/ProjectRepository.php | 4 +- .../Resources/translations/messages.de.xliff | 60 ----------------- .../Resources/views/admin/customer.html.twig | 3 +- web/js/toolbar.js | 7 ++ 17 files changed, 289 insertions(+), 87 deletions(-) create mode 100644 src/AppBundle/Form/Type/PageSizeType.php create mode 100644 src/AppBundle/Form/Type/VisibilityType.php create mode 100644 src/TimesheetBundle/Form/CustomerToolbarForm.php delete mode 100644 src/TimesheetBundle/Resources/translations/messages.de.xliff create mode 100644 web/js/toolbar.js diff --git a/app/Resources/translations/messages.de.xliff b/app/Resources/translations/messages.de.xliff index 737607d4..bf20c365 100644 --- a/app/Resources/translations/messages.de.xliff +++ b/app/Resources/translations/messages.de.xliff @@ -639,6 +639,54 @@ Neue Zeitmessung starten + + + label.pageSize + Anzahl Einträge + + + label.entryState + Zeiten + + + entryState.all + Alle + + + entryState.running + Laufende + + + entryState.stopped + Beendete + + + 0 + 0 + + + 10 + 10 + + + 25 + 25 + + + 50 + 50 + + + 75 + 75 + + + 100 + 100 + + diff --git a/src/AppBundle/Form/Type/PageSizeType.php b/src/AppBundle/Form/Type/PageSizeType.php new file mode 100644 index 00000000..333f244b --- /dev/null +++ b/src/AppBundle/Form/Type/PageSizeType.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace AppBundle\Form\Type; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Custom form field type to select a page size. + * + * @author Kevin Papst + */ +class PageSizeType extends AbstractType +{ + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'label' => 'label.pageSize', + 'choices' => [10 => 10, 25 => 25, 50 => 50, 75 => 75, 100 => 100], + ]); + } + + /** + * {@inheritdoc} + */ + public function getParent() + { + return ChoiceType::class; + } +} diff --git a/src/AppBundle/Form/Type/VisibilityType.php b/src/AppBundle/Form/Type/VisibilityType.php new file mode 100644 index 00000000..06dcce8e --- /dev/null +++ b/src/AppBundle/Form/Type/VisibilityType.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace AppBundle\Form\Type; + +use AppBundle\Repository\Query\VisibilityInterface; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * Custom form field type to select a visibility. + * + * @author Kevin Papst + */ +class VisibilityType extends AbstractType +{ + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'label' => 'label.visible', + 'choices' => [ + 'yes' => VisibilityInterface::SHOW_VISIBLE, + 'no' => VisibilityInterface::SHOW_HIDDEN, + ], + ]); + } + + /** + * {@inheritdoc} + */ + public function getParent() + { + return ChoiceType::class; + } +} diff --git a/src/AppBundle/Repository/Query/BaseQuery.php b/src/AppBundle/Repository/Query/BaseQuery.php index 37a39c92..4c6acc25 100644 --- a/src/AppBundle/Repository/Query/BaseQuery.php +++ b/src/AppBundle/Repository/Query/BaseQuery.php @@ -59,7 +59,7 @@ class BaseQuery /** * @param int $page - * @return BaseQuery + * @return $this */ public function setPage($page) { @@ -77,7 +77,7 @@ class BaseQuery /** * @param int $pageSize - * @return BaseQuery + * @return $this */ public function setPageSize($pageSize) { @@ -99,7 +99,7 @@ class BaseQuery * You need to validate carefully if this value is used from a user-input. * * @param string $orderBy - * @return BaseQuery + * @return $this */ public function setOrderBy($orderBy) { @@ -117,7 +117,7 @@ class BaseQuery /** * @param string $order - * @return BaseQuery + * @return $this */ public function setOrder($order) { @@ -137,7 +137,7 @@ class BaseQuery /** * @param string $resultType - * @return BaseQuery + * @return $this */ public function setResultType($resultType) { diff --git a/src/AppBundle/Repository/Query/VisibilityTrait.php b/src/AppBundle/Repository/Query/VisibilityTrait.php index 88c42947..4bf413f3 100644 --- a/src/AppBundle/Repository/Query/VisibilityTrait.php +++ b/src/AppBundle/Repository/Query/VisibilityTrait.php @@ -30,11 +30,13 @@ trait VisibilityTrait /** * @param int $visibility - * @return ProjectQuery + * @return self */ public function setVisibility($visibility) { - $this->visibility = $visibility; + if (in_array($visibility, [self::SHOW_BOTH, self::SHOW_VISIBLE, self::SHOW_HIDDEN])) { + $this->visibility = $visibility; + } return $this; } } diff --git a/src/TimesheetBundle/Controller/Admin/CustomerController.php b/src/TimesheetBundle/Controller/Admin/CustomerController.php index 80096ab9..4354b99e 100644 --- a/src/TimesheetBundle/Controller/Admin/CustomerController.php +++ b/src/TimesheetBundle/Controller/Admin/CustomerController.php @@ -20,6 +20,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; use TimesheetBundle\Form\CustomerEditForm; +use TimesheetBundle\Form\CustomerToolbarForm; use TimesheetBundle\Repository\Query\CustomerQuery; /** @@ -32,22 +33,49 @@ use TimesheetBundle\Repository\Query\CustomerQuery; */ class CustomerController extends AbstractController { + + /** + * @param Request $request + * @return CustomerQuery + */ + protected function getQueryForRequest(Request $request) + { + $visibility = $request->get('visibility'); + if (strlen($visibility) == 0 || (int)$visibility != $visibility) { + $visibility = CustomerQuery::SHOW_BOTH; + } + $pageSize = (int) $request->get('pageSize'); + + $query = new CustomerQuery(); + $query + ->setPageSize($pageSize) + ->setVisibility($visibility); + + return $query ; + } + /** * @Route("/", defaults={"page": 1}, name="admin_customer") * @Route("/page/{page}", requirements={"page": "[1-9]\d*"}, name="admin_customer_paginated") * @Method("GET") * @Cache(smaxage="10") */ - public function indexAction($page) + public function indexAction($page, Request $request) { - $query = new CustomerQuery(); - $query->setVisibility(CustomerQuery::SHOW_BOTH); + $query = $this->getQueryForRequest($request); $query->setPage($page); /* @var $entries Pagerfanta */ $entries = $this->getDoctrine()->getRepository(Customer::class)->findByQuery($query); - return $this->render('TimesheetBundle:admin:customer.html.twig', ['entries' => $entries]); + return $this->render( + 'TimesheetBundle:admin:customer.html.twig', + [ + 'entries' => $entries, + 'query' => $query, + 'toolbarForm' => $this->getToolbarForm($query)->createView(), + ] + ); } /** @@ -99,6 +127,24 @@ class CustomerController extends AbstractController ); } + /** + * @param CustomerQuery $query + * @return \Symfony\Component\Form\FormInterface + */ + protected function getToolbarForm(CustomerQuery $query) + { + return $this->createForm( + CustomerToolbarForm::class, + $query, + [ + 'action' => $this->generateUrl('admin_customer_paginated', [ + 'page' => $query->getPage(), + ]), + 'method' => 'GET', + ] + ); + } + /** * @param Customer $customer * @return \Symfony\Component\Form\FormInterface diff --git a/src/TimesheetBundle/Form/ActivityEditForm.php b/src/TimesheetBundle/Form/ActivityEditForm.php index 14df5c7d..8a7343a1 100644 --- a/src/TimesheetBundle/Form/ActivityEditForm.php +++ b/src/TimesheetBundle/Form/ActivityEditForm.php @@ -11,7 +11,7 @@ namespace TimesheetBundle\Form; -use AppBundle\Form\Type\YesNoType; +use AppBundle\Form\Type\VisibilityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -48,7 +48,7 @@ class ActivityEditForm extends AbstractType 'label' => 'label.project', ]) // boolean - ->add('visible', YesNoType::class, [ + ->add('visible', VisibilityType::class, [ 'label' => 'label.visible', ]) ; diff --git a/src/TimesheetBundle/Form/CustomerEditForm.php b/src/TimesheetBundle/Form/CustomerEditForm.php index 49e4c2cd..fef96cd6 100644 --- a/src/TimesheetBundle/Form/CustomerEditForm.php +++ b/src/TimesheetBundle/Form/CustomerEditForm.php @@ -11,7 +11,7 @@ namespace TimesheetBundle\Form; -use AppBundle\Form\Type\YesNoType; +use AppBundle\Form\Type\VisibilityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CountryType; use Symfony\Component\Form\Extension\Core\Type\CurrencyType; @@ -61,7 +61,7 @@ class CustomerEditForm extends AbstractType ]) */ // boolean - ->add('visible', YesNoType::class, [ + ->add('visible', VisibilityType::class, [ 'label' => 'label.visible', ]) // string - length 255 diff --git a/src/TimesheetBundle/Form/CustomerToolbarForm.php b/src/TimesheetBundle/Form/CustomerToolbarForm.php new file mode 100644 index 00000000..8ec43b35 --- /dev/null +++ b/src/TimesheetBundle/Form/CustomerToolbarForm.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace TimesheetBundle\Form; + +use AppBundle\Form\Type\PageSizeType; +use AppBundle\Form\Type\VisibilityType; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use TimesheetBundle\Repository\Query\CustomerQuery; + +/** + * Defines the form used for filtering the customer. + * + * @author Kevin Papst + */ +class CustomerToolbarForm extends AbstractType +{ + /** + * Dirty hack to enable easy handling of GET form in controller and javascript. + *Cleans up the name of all form elents (and unfortunately of the form itself). + * + * @return null|string + */ + public function getBlockPrefix() + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + /** @var CustomerQuery $query */ + $query = $options['data']; + + $builder + ->add('pageSize', PageSizeType::class, [ + 'required' => false, + ]) + ->add('visibility', VisibilityType::class, [ + 'required' => false, + ]) + ; + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => CustomerQuery::class, + 'csrf_protection' => false, + ]); + } +} diff --git a/src/TimesheetBundle/Form/ProjectEditForm.php b/src/TimesheetBundle/Form/ProjectEditForm.php index 7d82589b..3422d21a 100644 --- a/src/TimesheetBundle/Form/ProjectEditForm.php +++ b/src/TimesheetBundle/Form/ProjectEditForm.php @@ -11,7 +11,7 @@ namespace TimesheetBundle\Form; -use AppBundle\Form\Type\YesNoType; +use AppBundle\Form\Type\VisibilityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; @@ -49,7 +49,7 @@ class ProjectEditForm extends AbstractType 'label' => 'label.customer', ]) // boolean - ->add('visible', YesNoType::class, [ + ->add('visible', VisibilityType::class, [ 'label' => 'label.visible', ]) // string diff --git a/src/TimesheetBundle/Form/TimesheetToolbarForm.php b/src/TimesheetBundle/Form/TimesheetToolbarForm.php index df62845d..c93c4b4c 100644 --- a/src/TimesheetBundle/Form/TimesheetToolbarForm.php +++ b/src/TimesheetBundle/Form/TimesheetToolbarForm.php @@ -11,6 +11,7 @@ namespace TimesheetBundle\Form; +use AppBundle\Form\Type\PageSizeType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; @@ -47,9 +48,7 @@ class TimesheetToolbarForm extends AbstractType $query = $options['data']; $builder - ->add('pageSize', ChoiceType::class, [ - 'label' => 'label.pageSize', - 'choices' => [10 => 10, 25 => 25, 50 => 50, 75 => 75, 100 => 100], + ->add('pageSize', PageSizeType::class, [ 'required' => false, ]) ->add('state', ChoiceType::class, [ diff --git a/src/TimesheetBundle/Repository/ActivityRepository.php b/src/TimesheetBundle/Repository/ActivityRepository.php index d749de5a..c8ca6689 100644 --- a/src/TimesheetBundle/Repository/ActivityRepository.php +++ b/src/TimesheetBundle/Repository/ActivityRepository.php @@ -107,10 +107,10 @@ class ActivityRepository extends AbstractRepository ->join('p.customer', 'c') ->orderBy('a.' . $query->getOrderBy(), $query->getOrder()); - if ($query->getVisibility() === ActivityQuery::SHOW_VISIBLE) { + if ($query->getVisibility() == ActivityQuery::SHOW_VISIBLE) { $qb->andWhere('a.visible = 1'); // TODO check for visibility of customer and project - } elseif ($query->getVisibility() === ActivityQuery::SHOW_HIDDEN) { + } elseif ($query->getVisibility() == ActivityQuery::SHOW_HIDDEN) { $qb->andWhere('a.visible = 0'); // TODO check for visibility of customer and project } diff --git a/src/TimesheetBundle/Repository/CustomerRepository.php b/src/TimesheetBundle/Repository/CustomerRepository.php index f717009c..648a4a83 100644 --- a/src/TimesheetBundle/Repository/CustomerRepository.php +++ b/src/TimesheetBundle/Repository/CustomerRepository.php @@ -62,9 +62,9 @@ class CustomerRepository extends AbstractRepository ->from('TimesheetBundle:Customer', 'c') ->orderBy('c.' . $query->getOrderBy(), $query->getOrder()); - if ($query->getVisibility() === CustomerQuery::SHOW_VISIBLE) { + if ($query->getVisibility() == CustomerQuery::SHOW_VISIBLE) { $qb->andWhere('c.visible = 1'); - } elseif ($query->getVisibility() === CustomerQuery::SHOW_HIDDEN) { + } elseif ($query->getVisibility() == CustomerQuery::SHOW_HIDDEN) { $qb->andWhere('c.visible = 0'); } diff --git a/src/TimesheetBundle/Repository/ProjectRepository.php b/src/TimesheetBundle/Repository/ProjectRepository.php index 2a576eca..444441ea 100644 --- a/src/TimesheetBundle/Repository/ProjectRepository.php +++ b/src/TimesheetBundle/Repository/ProjectRepository.php @@ -65,10 +65,10 @@ class ProjectRepository extends AbstractRepository ->join('p.customer', 'c') ->orderBy('p.' . $query->getOrderBy(), $query->getOrder()); - if ($query->getVisibility() === ProjectQuery::SHOW_VISIBLE) { + if ($query->getVisibility() == ProjectQuery::SHOW_VISIBLE) { $qb->andWhere('p.visible = 1'); // TODO check for visibility of customer - } elseif ($query->getVisibility() === ProjectQuery::SHOW_HIDDEN) { + } elseif ($query->getVisibility() == ProjectQuery::SHOW_HIDDEN) { $qb->andWhere('p.visible = 0'); // TODO check for visibility of customer } diff --git a/src/TimesheetBundle/Resources/translations/messages.de.xliff b/src/TimesheetBundle/Resources/translations/messages.de.xliff deleted file mode 100644 index 35606a5a..00000000 --- a/src/TimesheetBundle/Resources/translations/messages.de.xliff +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - label.pageSize - Anzahl Einträge - - - timesheet.toolbar.submit - Einträge filtern - - - label.entryState - Zeiten - - - entryState.all - Alle - - - entryState.running - Laufende - - - entryState.stopped - Beendete - - - 0 - 0 - - - 10 - 10 - - - 25 - 25 - - - 50 - 50 - - - 75 - 75 - - - 100 - 100 - - - - - diff --git a/src/TimesheetBundle/Resources/views/admin/customer.html.twig b/src/TimesheetBundle/Resources/views/admin/customer.html.twig index c43113d7..6bb7657c 100644 --- a/src/TimesheetBundle/Resources/views/admin/customer.html.twig +++ b/src/TimesheetBundle/Resources/views/admin/customer.html.twig @@ -4,6 +4,7 @@ {% block page_title %}{{ 'admin_customer.title'|trans }}{% endblock %} {% block page_subtitle %}{{ 'admin_customer.subtitle'|trans }} {{ 'subtitle.amount'|trans({'%count%': entries.count}) }}{% endblock %} +{% block javascript_imports %}{% endblock %} {% block main %} {% if entries.count == 0 %} @@ -21,7 +22,7 @@ 'label.currency': 'hidden-xs', 'label.visible': '', 'label.actions': '', - }, null, {'plus-square': path('admin_customer_create')}) }} + }, toolbarForm, {'plus-square': path('admin_customer_create')}) }} {% for entry in entries %} diff --git a/web/js/toolbar.js b/web/js/toolbar.js new file mode 100644 index 00000000..24a98719 --- /dev/null +++ b/web/js/toolbar.js @@ -0,0 +1,7 @@ +$(document).ready(function () { + + $('.toolbar form select').change(function (event) { + $('.toolbar form').submit(); + }); + +});