diff --git a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php
index 3bbd6b9ae..564b08596 100644
--- a/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php
+++ b/src/Bundle/ChillMainBundle/Form/Type/Listing/FilterOrderType.php
@@ -32,6 +32,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
]);
}
+ $checkboxesBuilder = $builder->create('checkboxes', null, [ 'compound' => true ]);
foreach ($helper->getCheckboxes() as $name => $c) {
$choices = \array_combine(
@@ -42,17 +43,21 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
$c['choices']
);
- $builder->add('c_'.$name, ChoiceType::class, [
+ $checkboxesBuilder->add($name, ChoiceType::class, [
'choices' => $choices,
'expanded' => true,
'multiple' => true,
]);
}
+ if (0 < count($helper->getCheckboxes())) {
+ $builder->add($checkboxesBuilder);
+ }
+
foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) {
switch($key) {
case 'q':
- case 'c_'.$key:
+ case 'checkboxes'.$key:
break;
case 'page':
$builder->add($key, HiddenType::class, [
@@ -75,7 +80,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
$view->vars['has_search_box'] = $helper->hasSearchBox();
$view->vars['checkboxes'] = [];
foreach ($helper->getCheckboxes() as $name => $c) {
- $view->vars['checkboxes']['c_'.$name] = [];
+ $view->vars['checkboxes'][$name] = [];
}
}
diff --git a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig
index 8358d0e9b..3457c883a 100644
--- a/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig
+++ b/src/Bundle/ChillMainBundle/Resources/views/FilterOrder/base.html.twig
@@ -10,17 +10,30 @@
{% endif %}
- {% for checkbox_name, options in form.vars.checkboxes %}
-
-
- {{ form_widget(form[checkbox_name]) }}
+ {% if form.checkboxes|length > 0 %}
+ {% for checkbox_name, options in form.checkboxes %}
+
+
+ {% for c in form['checkboxes'][checkbox_name].children %}
+
+ {{ form_widget(c) }}
+ {{ form_label(c) }}
+
+ {% endfor %}
+
{% if loop.last %}
-
-
-
+
{% endif %}
-
- {% endfor %}
+ {% endfor %}
+ {% endif %}
{{ form_end(form) }}
diff --git a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php
index ffd601b91..0a28d39ca 100644
--- a/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php
+++ b/src/Bundle/ChillMainBundle/Templating/Listing/FilterOrderHelper.php
@@ -13,6 +13,11 @@ class FilterOrderHelper
private RequestStack $requestStack;
private ?array $searchBoxFields = null;
private array $checkboxes = [];
+ private ?array $submitted = null;
+ private ?string $formName = 'filter';
+ private string $formType = FilterOrderType::class;
+ private array $formOptions = [];
+
public function __construct(
FormFactoryInterface $formFactory,
@@ -45,10 +50,9 @@ class FilterOrderHelper
return $this;
}
- public function getCheckbox(string $name): array
+ public function getCheckboxData(string $name): array
{
- return $this->requestStack->getCurrentRequest()
- ->query->get('c_'.$name, $this->checkboxes[$name]['default']);
+ return $this->getFormData()['checkboxes'][$name];
}
public function getCheckboxes(): array
@@ -63,12 +67,23 @@ class FilterOrderHelper
private function getFormData(): array
{
- $r = [
- 'q' => $this->getQueryString(),
- ];
+ if (NULL === $this->submitted) {
+ $this->submitted = $this->buildForm()
+ ->getData();
+ }
+ return $this->submitted;
+ }
+
+ private function getDefaultData(): array
+ {
+ $r = [];
+
+ if ($this->hasSearchBox()) {
+ $r['q'] = '';
+ }
foreach ($this->checkboxes as $name => $c) {
- $r[$name] = $this->getCheckbox($name);
+ $r['checkboxes'][$name] = $c['default'];
}
return $r;
@@ -76,21 +91,17 @@ class FilterOrderHelper
public function getQueryString(): ?string
{
- $q = $this->requestStack->getCurrentRequest()
- ->query->get('q', null);
-
- return empty($q) ? NULL : $q;
+ return $this->getFormData()['q'];
}
- public function buildForm($name = null, string $type = FilterOrderType::class, array $options = []): FormInterface
+ public function buildForm(): FormInterface
{
- $form = $this->formFactory
- ->createNamed($name, $type, $this->getFormData(), \array_merge([
+ return $this->formFactory
+ ->createNamed($this->formName, $this->formType, $this->getDefaultData(), \array_merge([
'helper' => $this,
'method' => 'GET',
'csrf_protection' => false,
- ], $options));
-
- return $form;
+ ], $this->formOptions))
+ ->handleRequest($this->requestStack->getCurrentRequest());
}
}
diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php
index 90dbe4744..359dc8909 100644
--- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php
+++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php
@@ -532,14 +532,18 @@ final class SingleTaskController extends AbstractController
$this->denyAccessUnlessGranted('ROLE_USER');
$filterOrder = $this->buildFilterOrder();
+ $flags = \array_merge(
+ $filterOrder->getCheckboxData('status'),
+ \array_map(fn ($i) => 'state_'.$i, $filterOrder->getCheckboxData('states'))
+ );
$nb = $this->singleTaskAclAwareRepository->countByCurrentUsersTasks(
$filterOrder->getQueryString(),
- $filterOrder->getCheckbox('status')
+ $flags
);
$paginator = $this->paginatorFactory->create($nb);
$tasks = $this->singleTaskAclAwareRepository->findByCurrentUsersTasks(
$filterOrder->getQueryString(),
- $filterOrder->getCheckbox('status'),
+ $flags,
$paginator->getCurrentPageFirstItemNumber(),
$paginator->getItemsPerPage()
);
@@ -555,14 +559,19 @@ final class SingleTaskController extends AbstractController
{
$statuses = ['no-alert', 'warning', 'alert'];
$statusTrans = [
+ 'Tasks without alert',
'Tasks near deadline',
'Tasks over deadline',
- 'Tasks without alert',
+ ];
+ $states = [
+ // todo: get a list of possible states dynamically
+ 'new', 'in_progress', 'closed', 'canceled'
];
return $this->filterOrderHelperFactory
->create(self::class)
->addSearchBox()
->addCheckbox('status', $statuses, $statuses, $statusTrans)
+ ->addCheckbox('states', $states, ['new', 'in_progress'])
->build()
;
}
diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php
index b034bf973..2e5b8d803 100644
--- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php
+++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php
@@ -63,64 +63,74 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
if (!empty($pattern)) {
$qb->andWhere($qb->expr()->like('LOWER(UNACCENT(t.title))', 'LOWER(UNACCENT(:pattern))'))
- ->setParameter('pattern', $pattern)
+ ->setParameter('pattern', '%'.$pattern.'%')
;
}
if (count($flags) > 0) {
- $orX = $qb->expr()->orX();
+ $orXDate = $qb->expr()->orX();
+ $orXState = $qb->expr()->orX();
$now = new \DateTime();
- if (\in_array('no-alert', $flags)) {
- $orX
- ->add(
- $qb->expr()->orX(
- $qb->expr()->isNull('t.endDate'),
- $qb->expr()->gte('t.endDate - COALESCE(t.warningInterval, :intervalBlank)', ':now')
- )
- );
- $qb
- ->setParameter('intervalBlank', new \DateInterval('P0D'))
- ->setParameter('now', $now)
- ;
+ foreach ($flags as $key => $flag) {
+ switch ($flag) {
+ case 'no-alert':
+ $orXDate
+ ->add(
+ $qb->expr()->orX(
+ $qb->expr()->isNull('t.endDate'),
+ $qb->expr()->gte('t.endDate - COALESCE(t.warningInterval, :intervalBlank)', ':now')
+ )
+ );
+ $qb
+ ->setParameter('intervalBlank', new \DateInterval('P0D'))
+ ->setParameter('now', $now);
+ break;
+ case 'warning':
+ $orXDate
+ ->add(
+ $qb->expr()->andX(
+ $qb->expr()->not($qb->expr()->isNull('t.endDate')),
+ $qb->expr()->not($qb->expr()->isNull('t.warningInterval')),
+ $qb->expr()->gte('t.endDate - t.warningInterval', ':now'),
+ $qb->expr()->lt('t.endDate', ':now')
+ )
+ );
+ $qb
+ ->setParameter('now', $now);
+ break;
+ case 'alert':
+ $orXDate
+ ->add(
+ $qb->expr()->andX(
+ $qb->expr()->not($qb->expr()->isNull('t.endDate')),
+ $qb->expr()->lte('t.endDate', ':now')
+ )
+ );
+ $qb
+ ->setParameter('now', $now);
+ break;
+ case \substr($flag, 0, 6) === 'state_':
+ $state = \substr($flag, 6);
+ $orXState
+ ->add(
+ "JSONB_EXISTS_IN_ARRAY(t.currentStates, :state_$key) = 'TRUE'"
+ );
+ $qb->setParameter("state_$key", $state);
+ break;
+ default:
+ throw new \LogicException("this flag is not supported: $flag");
+ }
}
- if (\in_array('warning', $flags)) {
- $orX
- ->add(
- $qb->expr()->andX(
- $qb->expr()->eq('t.closed', "'FALSE'"),
- $qb->expr()->not($qb->expr()->isNull('t.endDate')),
- $qb->expr()->not($qb->expr()->isNull('t.warningInterval')),
- $qb->expr()->lte('t.endDate - t.warningInterval', ':now')
- )
- )
- ;
- $qb
- ->setParameter('now', $now)
- ;
+ if ($orXDate->count() > 0) {
+ $qb->andWhere($orXDate);
}
-
- if (\in_array('alert', $flags)) {
- $orX
- ->add(
- $qb->expr()->andX(
- $qb->expr()->eq('t.closed', "'FALSE'"),
- $qb->expr()->not($qb->expr()->isNull('t.endDate')),
- $qb->expr()->lte('t.endDate', ':now')
- )
- )
- ;
- $qb
- ->setParameter('now', $now)
- ;
+ if ($orXState->count() > 0) {
+ $qb->andWhere($orXState);
}
-
- $qb->andWhere($orX);
}
-
-
return $qb;
}
diff --git a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml
index 0b9ef6251..5633c0219 100644
--- a/src/Bundle/ChillTaskBundle/translations/messages.fr.yml
+++ b/src/Bundle/ChillTaskBundle/translations/messages.fr.yml
@@ -99,7 +99,7 @@ Are you sure you want to start this task ?: Êtes-vous sûrs de vouloir démarre
Tasks near deadline: Tâches à échéance proche
Tasks over deadline: Tâches à échéance dépassée
-Tasks without alert: Tâches sans alerte
+Tasks without alert: Tâches à échéance future ou sans échéance
#title
My tasks near deadline: Mes tâches à échéance proche