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
This commit is contained in:
Kevin Papst
2018-01-07 21:42:27 +01:00
committed by GitHub
parent c5c9f37de7
commit 79e87ecdbe
17 changed files with 289 additions and 87 deletions

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* 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 <kevin@kevinpapst.de>
*/
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;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* 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 <kevin@kevinpapst.de>
*/
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;
}
}

View File

@@ -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)
{

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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',
])
;

View File

@@ -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

View File

@@ -0,0 +1,67 @@
<?php
/*
* This file is part of the Kimai package.
*
* (c) Kevin Papst <kevin@kevinpapst.de>
*
* 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 <kevin@kevinpapst.de>
*/
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,
]);
}
}

View File

@@ -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

View File

@@ -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, [

View File

@@ -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
}

View File

@@ -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');
}

View File

@@ -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
}

View File

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file date="2016-10-19T21:46:45Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<body>
<!--
TIMESHEET TOOLBAR
-->
<trans-unit id="label.pageSize">
<source>label.pageSize</source>
<target>Anzahl Einträge</target>
</trans-unit>
<trans-unit id="timesheet.toolbar.submit">
<source>timesheet.toolbar.submit</source>
<target>Einträge filtern</target>
</trans-unit>
<trans-unit id="label.entryState">
<source>label.entryState</source>
<target>Zeiten</target>
</trans-unit>
<trans-unit id="entryState.all">
<source>entryState.all</source>
<target>Alle</target>
</trans-unit>
<trans-unit id="entryState.running">
<source>entryState.running</source>
<target>Laufende</target>
</trans-unit>
<trans-unit id="entryState.stopped">
<source>entryState.stopped</source>
<target>Beendete</target>
</trans-unit>
<trans-unit id="0">
<source>0</source>
<target>0</target>
</trans-unit>
<trans-unit id="10">
<source>10</source>
<target>10</target>
</trans-unit>
<trans-unit id="25">
<source>25</source>
<target>25</target>
</trans-unit>
<trans-unit id="50">
<source>50</source>
<target>50</target>
</trans-unit>
<trans-unit id="75">
<source>75</source>
<target>75</target>
</trans-unit>
<trans-unit id="100">
<source>100</source>
<target>100</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -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 %}<script src="{{ asset('js/toolbar.js') }}"></script>{% 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 %}
<tr>