mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 21:34:25 +00:00
Merge branch 'user_filter_tasks' into 'master'
Filter on user within task list See merge request Chill-Projet/chill-bundles!569
This commit is contained in:
commit
aea6796ba1
5
.changes/unreleased/Feature-20230705-140336.yaml
Normal file
5
.changes/unreleased/Feature-20230705-140336.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Allow filtering on the basis of a user within general tasks list
|
||||||
|
time: 2023-07-05T14:03:36.664880092+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\MainBundle\Form\Type\Listing;
|
namespace Chill\MainBundle\Form\Type\Listing;
|
||||||
|
|
||||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
|
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
@ -114,6 +115,28 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
|
|||||||
|
|
||||||
$builder->add($singleCheckBoxBuilder);
|
$builder->add($singleCheckBoxBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ([] !== $helper->getUserPickers()) {
|
||||||
|
$userPickersBuilder = $builder->create('user_pickers', null, ['compound' => true]);
|
||||||
|
|
||||||
|
foreach ($helper->getUserPickers() as $name => [
|
||||||
|
'label' => $label, 'options' => $opts
|
||||||
|
]) {
|
||||||
|
|
||||||
|
$userPickersBuilder->add(
|
||||||
|
$name,
|
||||||
|
PickUserDynamicType::class,
|
||||||
|
[
|
||||||
|
'multiple' => true,
|
||||||
|
'label' => $label,
|
||||||
|
...$opts,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->add($userPickersBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function buildCheckboxChoices(array $choices, array $trans = []): array
|
public static function buildCheckboxChoices(array $choices, array $trans = []): array
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if form.dateRanges is defined %}
|
{% if form.dateRanges is defined %}
|
||||||
{% set btnSubmit = 1 %}
|
{% set btnSubmit = 1 %}
|
||||||
{% if form.dateRanges|length > 0 %}
|
{% if form.dateRanges|length > 0 %}
|
||||||
@ -40,6 +41,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if form.checkboxes is defined %}
|
{% if form.checkboxes is defined %}
|
||||||
{% set btnSubmit = 1 %}
|
{% set btnSubmit = 1 %}
|
||||||
{% if form.checkboxes|length > 0 %}
|
{% if form.checkboxes|length > 0 %}
|
||||||
@ -56,6 +58,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if form.entity_choices is defined %}
|
{% if form.entity_choices is defined %}
|
||||||
{% set btnSubmit = 1 %}
|
{% set btnSubmit = 1 %}
|
||||||
{% if form.entity_choices |length > 0 %}
|
{% if form.entity_choices |length > 0 %}
|
||||||
@ -74,6 +77,25 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if form.user_pickers is defined %}
|
||||||
|
{% set btnSubmit = 1 %}
|
||||||
|
{% if form.user_pickers.children|length > 0 %}
|
||||||
|
{% for name, options in form.user_pickers %}
|
||||||
|
<div class="row my-2">
|
||||||
|
{% if form.user_pickers[name].vars.label is not same as(false) %}
|
||||||
|
{{ form_label(form.user_pickers[name]) }}
|
||||||
|
{% else %}
|
||||||
|
{{ form_label(form.user_pickers[name].vars.label) }}
|
||||||
|
{% endif %}
|
||||||
|
<div class="col-sm-8 pt-2">
|
||||||
|
{{ form_widget(form.user_pickers[name]) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if form.single_checkboxes is defined %}
|
{% if form.single_checkboxes is defined %}
|
||||||
{% set btnSubmit = 1 %}
|
{% set btnSubmit = 1 %}
|
||||||
{% for name, _o in form.single_checkboxes %}
|
{% for name, _o in form.single_checkboxes %}
|
||||||
@ -91,8 +113,10 @@
|
|||||||
<button type="submit" class="btn btn-sm btn-misc"><i class="fa fa-fw fa-filter"></i>{{ 'Filter'|trans }}</button>
|
<button type="submit" class="btn btn-sm btn-misc"><i class="fa fa-fw fa-filter"></i>{{ 'Filter'|trans }}</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if active|length > 0 %}
|
{% if active|length > 0 %}
|
||||||
<div class="activeFilters mt-3">
|
<div class="activeFilters mt-3">
|
||||||
{% for f in active %}
|
{% for f in active %}
|
||||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Templating\Listing;
|
namespace Chill\MainBundle\Templating\Listing;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
use Symfony\Component\PropertyAccess\PropertyPathInterface;
|
use Symfony\Component\PropertyAccess\PropertyPathInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
@ -20,6 +21,7 @@ final readonly class FilterOrderGetActiveFilterHelper
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
private TranslatorInterface $translator,
|
private TranslatorInterface $translator,
|
||||||
private PropertyAccessorInterface $propertyAccessor,
|
private PropertyAccessorInterface $propertyAccessor,
|
||||||
|
private UserRender $userRender,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +75,12 @@ final readonly class FilterOrderGetActiveFilterHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($filterOrderHelper->getUserPickers() as $name => ['label' => $label, 'options' => $options]) {
|
||||||
|
foreach ($filterOrderHelper->getUserPickerData($name) as $user) {
|
||||||
|
$result[] = ['value' => $this->userRender->renderString($user, []), 'label' => (string) $label, 'position' => FilterOrderPositionEnum::UserPicker->value, 'name' => $name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($filterOrderHelper->getSingleCheckbox() as $name => ['label' => $label]) {
|
foreach ($filterOrderHelper->getSingleCheckbox() as $name => ['label' => $label]) {
|
||||||
if (true === $filterOrderHelper->getSingleCheckboxData($name)) {
|
if (true === $filterOrderHelper->getSingleCheckboxData($name)) {
|
||||||
$result[] = ['label' => '', 'value' => $this->translator->trans($label), 'position' => FilterOrderPositionEnum::SingleCheckbox->value, 'name' => $name];
|
$result[] = ['label' => '', 'value' => $this->translator->trans($label), 'position' => FilterOrderPositionEnum::SingleCheckbox->value, 'name' => $name];
|
||||||
|
@ -11,8 +11,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\MainBundle\Templating\Listing;
|
namespace Chill\MainBundle\Templating\Listing;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Form\Type\Listing\FilterOrderType;
|
use Chill\MainBundle\Form\Type\Listing\FilterOrderType;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\HttpFoundation\RequestStack;
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
@ -52,6 +55,11 @@ final class FilterOrderHelper
|
|||||||
private array $entityChoices = [];
|
private array $entityChoices = [];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, array{label: string, options: array}>
|
||||||
|
*/
|
||||||
|
private array $userPickers = [];
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly FormFactoryInterface $formFactory,
|
private readonly FormFactoryInterface $formFactory,
|
||||||
private readonly RequestStack $requestStack,
|
private readonly RequestStack $requestStack,
|
||||||
@ -80,6 +88,14 @@ final class FilterOrderHelper
|
|||||||
return $this->entityChoices;
|
return $this->entityChoices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addUserPicker(string $name, ?string $label = null, array $options = []): self
|
||||||
|
{
|
||||||
|
$this->userPickers[$name] = ['label' => $label, 'options' => $options];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self
|
public function addCheckbox(string $name, array $choices, ?array $default = [], ?array $trans = [], array $options = []): self
|
||||||
{
|
{
|
||||||
if ([] === $trans) {
|
if ([] === $trans) {
|
||||||
@ -114,6 +130,19 @@ final class FilterOrderHelper
|
|||||||
->handleRequest($this->requestStack->getCurrentRequest());
|
->handleRequest($this->requestStack->getCurrentRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUserPickers(): array
|
||||||
|
{
|
||||||
|
return $this->userPickers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<User>
|
||||||
|
*/
|
||||||
|
public function getUserPickerData(string $name): array
|
||||||
|
{
|
||||||
|
return $this->getFormData()['user_pickers'][$name];
|
||||||
|
}
|
||||||
|
|
||||||
public function hasCheckboxData(string $name): bool
|
public function hasCheckboxData(string $name): bool
|
||||||
{
|
{
|
||||||
return array_key_exists($name, $this->checkboxes);
|
return array_key_exists($name, $this->checkboxes);
|
||||||
@ -203,7 +232,8 @@ final class FilterOrderHelper
|
|||||||
'checkboxes' => [],
|
'checkboxes' => [],
|
||||||
'dateRanges' => [],
|
'dateRanges' => [],
|
||||||
'single_checkboxes' => [],
|
'single_checkboxes' => [],
|
||||||
'entity_choices' => []
|
'entity_choices' => [],
|
||||||
|
'user_pickers' => []
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->hasSearchBox()) {
|
if ($this->hasSearchBox()) {
|
||||||
@ -227,6 +257,10 @@ final class FilterOrderHelper
|
|||||||
$r['entity_choices'][$name] = ($c['options']['multiple'] ?? true) ? [] : null;
|
$r['entity_choices'][$name] = ($c['options']['multiple'] ?? true) ? [] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->userPickers as $name => $u) {
|
||||||
|
$r['user_pickers'][$name] = ($u['options']['multiple'] ?? true) ? [] : null;
|
||||||
|
}
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,11 @@ class FilterOrderHelperBuilder
|
|||||||
*/
|
*/
|
||||||
private array $entityChoices = [];
|
private array $entityChoices = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, array{label: string, options: array}>
|
||||||
|
*/
|
||||||
|
private array $userPickers = [];
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
FormFactoryInterface $formFactory,
|
FormFactoryInterface $formFactory,
|
||||||
RequestStack $requestStack,
|
RequestStack $requestStack,
|
||||||
@ -85,6 +90,13 @@ class FilterOrderHelperBuilder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addUserPicker(string $name, ?string $label = null, ?array $options = []): self
|
||||||
|
{
|
||||||
|
$this->userPickers[$name] = ['label' => $label, 'options' => $options];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function build(): FilterOrderHelper
|
public function build(): FilterOrderHelper
|
||||||
{
|
{
|
||||||
$helper = new FilterOrderHelper(
|
$helper = new FilterOrderHelper(
|
||||||
@ -126,6 +138,17 @@ class FilterOrderHelperBuilder
|
|||||||
$helper->addDateRange($name, $label, $from, $to);
|
$helper->addDateRange($name, $label, $from, $to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (
|
||||||
|
$this->userPickers as $name => [
|
||||||
|
'label' => $label,
|
||||||
|
'options' => $options
|
||||||
|
]
|
||||||
|
) {
|
||||||
|
$helper->addUserPicker($name, $label, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $helper;
|
return $helper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,4 +18,5 @@ enum FilterOrderPositionEnum: string
|
|||||||
case DateRange = 'date_range';
|
case DateRange = 'date_range';
|
||||||
case EntityChoice = 'entity_choice';
|
case EntityChoice = 'entity_choice';
|
||||||
case SingleCheckbox = 'single_checkbox';
|
case SingleCheckbox = 'single_checkbox';
|
||||||
|
case UserPicker = 'user_picker';
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ use Chill\TaskBundle\Event\TaskEvent;
|
|||||||
use Chill\TaskBundle\Event\UI\UIEvent;
|
use Chill\TaskBundle\Event\UI\UIEvent;
|
||||||
use Chill\TaskBundle\Form\SingleTaskType;
|
use Chill\TaskBundle\Form\SingleTaskType;
|
||||||
use Chill\TaskBundle\Repository\SingleTaskAclAwareRepositoryInterface;
|
use Chill\TaskBundle\Repository\SingleTaskAclAwareRepositoryInterface;
|
||||||
|
use Chill\TaskBundle\Repository\SingleTaskStateRepository;
|
||||||
use Chill\TaskBundle\Security\Authorization\TaskVoter;
|
use Chill\TaskBundle\Security\Authorization\TaskVoter;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@ -71,7 +72,8 @@ final class SingleTaskController extends AbstractController
|
|||||||
EventDispatcherInterface $eventDispatcher,
|
EventDispatcherInterface $eventDispatcher,
|
||||||
TimelineBuilder $timelineBuilder,
|
TimelineBuilder $timelineBuilder,
|
||||||
LoggerInterface $logger,
|
LoggerInterface $logger,
|
||||||
FilterOrderHelperFactoryInterface $filterOrderHelperFactory
|
FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
|
||||||
|
private SingleTaskStateRepository $singleTaskStateRepository
|
||||||
) {
|
) {
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->timelineBuilder = $timelineBuilder;
|
$this->timelineBuilder = $timelineBuilder;
|
||||||
@ -299,13 +301,17 @@ final class SingleTaskController extends AbstractController
|
|||||||
$this->denyAccessUnlessGranted(TaskVoter::SHOW, null);
|
$this->denyAccessUnlessGranted(TaskVoter::SHOW, null);
|
||||||
|
|
||||||
$filterOrder = $this->buildFilterOrder();
|
$filterOrder = $this->buildFilterOrder();
|
||||||
|
|
||||||
|
$filteredUsers = $filterOrder->getUserPickerData('userPicker');
|
||||||
|
|
||||||
$flags = array_merge(
|
$flags = array_merge(
|
||||||
$filterOrder->getCheckboxData('status'),
|
$filterOrder->getCheckboxData('status'),
|
||||||
array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states'))
|
array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states'))
|
||||||
);
|
);
|
||||||
$nb = $this->singleTaskAclAwareRepository->countByAllViewable(
|
$nb = $this->singleTaskAclAwareRepository->countByAllViewable(
|
||||||
$filterOrder->getQueryString(),
|
$filterOrder->getQueryString(),
|
||||||
$flags
|
$flags,
|
||||||
|
$filteredUsers
|
||||||
);
|
);
|
||||||
$paginator = $this->paginatorFactory->create($nb);
|
$paginator = $this->paginatorFactory->create($nb);
|
||||||
|
|
||||||
@ -313,6 +319,7 @@ final class SingleTaskController extends AbstractController
|
|||||||
$tasks = $this->singleTaskAclAwareRepository->findByAllViewable(
|
$tasks = $this->singleTaskAclAwareRepository->findByAllViewable(
|
||||||
$filterOrder->getQueryString(),
|
$filterOrder->getQueryString(),
|
||||||
$flags,
|
$flags,
|
||||||
|
$filteredUsers,
|
||||||
$paginator->getCurrentPageFirstItemNumber(),
|
$paginator->getCurrentPageFirstItemNumber(),
|
||||||
$paginator->getItemsPerPage(),
|
$paginator->getItemsPerPage(),
|
||||||
[
|
[
|
||||||
@ -447,7 +454,7 @@ final class SingleTaskController extends AbstractController
|
|||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||||
|
|
||||||
$filterOrder = $this->buildFilterOrder();
|
$filterOrder = $this->buildFilterOrder(false);
|
||||||
$flags = array_merge(
|
$flags = array_merge(
|
||||||
$filterOrder->getCheckboxData('status'),
|
$filterOrder->getCheckboxData('status'),
|
||||||
array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states'))
|
array_map(static fn ($i) => 'state_' . $i, $filterOrder->getCheckboxData('states'))
|
||||||
@ -662,7 +669,7 @@ final class SingleTaskController extends AbstractController
|
|||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildFilterOrder(): FilterOrderHelper
|
private function buildFilterOrder($includeFilterByUser = true): FilterOrderHelper
|
||||||
{
|
{
|
||||||
$statuses = ['no-alert', 'warning', 'alert'];
|
$statuses = ['no-alert', 'warning', 'alert'];
|
||||||
$statusTrans = [
|
$statusTrans = [
|
||||||
@ -670,17 +677,22 @@ final class SingleTaskController extends AbstractController
|
|||||||
'Tasks near deadline',
|
'Tasks near deadline',
|
||||||
'Tasks over deadline',
|
'Tasks over deadline',
|
||||||
];
|
];
|
||||||
$states = [
|
$states = $this->singleTaskStateRepository->findAllExistingStates();
|
||||||
// todo: get a list of possible states dynamically
|
$checked = array_values(array_filter($states, fn (string $state) => !in_array($state, ['closed', 'canceled', 'validated'], true)));
|
||||||
'new', 'in_progress', 'closed', 'canceled',
|
|
||||||
];
|
|
||||||
|
|
||||||
return $this->filterOrderHelperFactory
|
$filterBuilder = $this->filterOrderHelperFactory
|
||||||
->create(self::class)
|
->create(self::class)
|
||||||
->addSearchBox()
|
->addSearchBox()
|
||||||
->addCheckbox('status', $statuses, $statuses, $statusTrans)
|
->addCheckbox('status', $statuses, $statuses, $statusTrans)
|
||||||
->addCheckbox('states', $states, ['new', 'in_progress'])
|
->addCheckbox('states', $states, $checked)
|
||||||
->build();
|
;
|
||||||
|
|
||||||
|
if ($includeFilterByUser) {
|
||||||
|
$filterBuilder
|
||||||
|
->addUserPicker('userPicker', 'Filter by user', ['multiple' => true, 'required' => false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filterBuilder->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +51,8 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
|
|||||||
|
|
||||||
public function buildBaseQuery(
|
public function buildBaseQuery(
|
||||||
?string $pattern = null,
|
?string $pattern = null,
|
||||||
?array $flags = []
|
?array $flags = [],
|
||||||
|
?array $users = []
|
||||||
): QueryBuilder {
|
): QueryBuilder {
|
||||||
$qb = $this->em->createQueryBuilder();
|
$qb = $this->em->createQueryBuilder();
|
||||||
$qb
|
$qb
|
||||||
@ -62,6 +63,24 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
|
|||||||
->setParameter('pattern', '%' . $pattern . '%');
|
->setParameter('pattern', '%' . $pattern . '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count($users) > 0) {
|
||||||
|
$orXUser = $qb->expr()->orX();
|
||||||
|
|
||||||
|
foreach ($users as $key => $user) {
|
||||||
|
$orXUser->add(
|
||||||
|
$qb->expr()->eq('t.assignee', ':user_' . $key)
|
||||||
|
);
|
||||||
|
|
||||||
|
$qb->setParameter('user_' . $key, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($orXUser->count() > 0) {
|
||||||
|
$qb->andWhere($orXUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
if (count($flags) > 0) {
|
if (count($flags) > 0) {
|
||||||
$orXDate = $qb->expr()->orX();
|
$orXDate = $qb->expr()->orX();
|
||||||
$orXState = $qb->expr()->orX();
|
$orXState = $qb->expr()->orX();
|
||||||
@ -183,9 +202,10 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
|
|||||||
|
|
||||||
public function countByAllViewable(
|
public function countByAllViewable(
|
||||||
?string $pattern = null,
|
?string $pattern = null,
|
||||||
?array $flags = []
|
?array $flags = [],
|
||||||
|
?array $users = []
|
||||||
): int {
|
): int {
|
||||||
$qb = $this->buildBaseQuery($pattern, $flags);
|
$qb = $this->buildBaseQuery($pattern, $flags, $users);
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->addACLGlobal($qb)
|
->addACLGlobal($qb)
|
||||||
@ -231,11 +251,12 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
|
|||||||
public function findByAllViewable(
|
public function findByAllViewable(
|
||||||
?string $pattern = null,
|
?string $pattern = null,
|
||||||
?array $flags = [],
|
?array $flags = [],
|
||||||
|
?array $users = [],
|
||||||
?int $start = 0,
|
?int $start = 0,
|
||||||
?int $limit = 50,
|
?int $limit = 50,
|
||||||
?array $orderBy = []
|
?array $orderBy = []
|
||||||
): array {
|
): array {
|
||||||
$qb = $this->buildBaseQuery($pattern, $flags);
|
$qb = $this->buildBaseQuery($pattern, $flags, $users);
|
||||||
$qb = $this->addACLGlobal($qb);
|
$qb = $this->addACLGlobal($qb);
|
||||||
|
|
||||||
return $this->getResult($qb, $start, $limit, $orderBy);
|
return $this->getResult($qb, $start, $limit, $orderBy);
|
||||||
|
@ -18,7 +18,8 @@ interface SingleTaskAclAwareRepositoryInterface
|
|||||||
{
|
{
|
||||||
public function countByAllViewable(
|
public function countByAllViewable(
|
||||||
?string $pattern = null,
|
?string $pattern = null,
|
||||||
?array $flags = []
|
?array $flags = [],
|
||||||
|
?array $users = []
|
||||||
): int;
|
): int;
|
||||||
|
|
||||||
public function countByCourse(
|
public function countByCourse(
|
||||||
@ -38,6 +39,7 @@ interface SingleTaskAclAwareRepositoryInterface
|
|||||||
public function findByAllViewable(
|
public function findByAllViewable(
|
||||||
?string $pattern = null,
|
?string $pattern = null,
|
||||||
?array $flags = [],
|
?array $flags = [],
|
||||||
|
?array $users = [],
|
||||||
?int $start = 0,
|
?int $start = 0,
|
||||||
?int $limit = 50,
|
?int $limit = 50,
|
||||||
?array $orderBy = []
|
?array $orderBy = []
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\TaskBundle\Repository;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\Exception;
|
||||||
|
|
||||||
|
class SingleTaskStateRepository
|
||||||
|
{
|
||||||
|
private const FIND_ALL_STATES = <<<'SQL'
|
||||||
|
SELECT DISTINCT jsonb_array_elements_text(current_states) FROM chill_task.single_task
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private Connection $connection
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of all states associated to at least one single task in the database
|
||||||
|
*
|
||||||
|
* @return list<string>
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function findAllExistingStates(): array
|
||||||
|
{
|
||||||
|
$states = [];
|
||||||
|
|
||||||
|
foreach ($this->connection->fetchAllNumeric(self::FIND_ALL_STATES) as $row) {
|
||||||
|
if ('' !== $row[0] && null !== $row[0]) {
|
||||||
|
$states[] = $row[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $states;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,8 +27,10 @@
|
|||||||
{% block css %}
|
{% block css %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{{ encore_entry_link_tags('page_task_list') }}
|
{{ encore_entry_link_tags('page_task_list') }}
|
||||||
|
{{ encore_entry_link_tags('mod_pickentity_type') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{{ encore_entry_script_tags('page_task_list') }}
|
{{ encore_entry_script_tags('page_task_list') }}
|
||||||
|
{{ encore_entry_script_tags('mod_pickentity_type') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
services:
|
services:
|
||||||
|
_defaults:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
|
||||||
chill_task.single_task_repository:
|
chill_task.single_task_repository:
|
||||||
class: Chill\TaskBundle\Repository\SingleTaskRepository
|
class: Chill\TaskBundle\Repository\SingleTaskRepository
|
||||||
factory: ['@doctrine.orm.entity_manager', getRepository]
|
factory: ['@doctrine.orm.entity_manager', getRepository]
|
||||||
@ -10,8 +14,8 @@ services:
|
|||||||
- "@chill.main.security.authorization.helper"
|
- "@chill.main.security.authorization.helper"
|
||||||
Chill\TaskBundle\Repository\SingleTaskRepository: '@chill_task.single_task_repository'
|
Chill\TaskBundle\Repository\SingleTaskRepository: '@chill_task.single_task_repository'
|
||||||
|
|
||||||
Chill\TaskBundle\Repository\SingleTaskAclAwareRepository:
|
Chill\TaskBundle\Repository\SingleTaskAclAwareRepository: ~
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
|
|
||||||
Chill\TaskBundle\Repository\SingleTaskAclAwareRepositoryInterface: '@Chill\TaskBundle\Repository\SingleTaskAclAwareRepository'
|
Chill\TaskBundle\Repository\SingleTaskAclAwareRepositoryInterface: '@Chill\TaskBundle\Repository\SingleTaskAclAwareRepository'
|
||||||
|
|
||||||
|
Chill\TaskBundle\Repository\SingleTaskStateRepository: ~
|
||||||
|
@ -65,6 +65,7 @@ Not assigned: Aucun utilisateur assigné
|
|||||||
For person: Pour
|
For person: Pour
|
||||||
By: Par
|
By: Par
|
||||||
Any tasks: Aucune tâche
|
Any tasks: Aucune tâche
|
||||||
|
Filter by user: Filtrer par utilisateur(s)
|
||||||
|
|
||||||
# transitions - default task definition
|
# transitions - default task definition
|
||||||
"new": "nouvelle"
|
"new": "nouvelle"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user