From 0e5f1b4ab9c7d8e693332d42709841249e68a0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 23 Jun 2023 12:44:54 +0200 Subject: [PATCH] Feature: [activity list] add pagination --- .../unreleased/Feature-20230623-124438.yaml | 5 +++ .../Controller/ActivityController.php | 18 +++++--- .../Repository/ActivityACLAwareRepository.php | 43 ++++++++++++++++++- .../ActivityACLAwareRepositoryInterface.php | 10 +++++ .../Resources/views/Activity/list.html.twig | 6 ++- 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 .changes/unreleased/Feature-20230623-124438.yaml diff --git a/.changes/unreleased/Feature-20230623-124438.yaml b/.changes/unreleased/Feature-20230623-124438.yaml new file mode 100644 index 000000000..bc199d3bb --- /dev/null +++ b/.changes/unreleased/Feature-20230623-124438.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: '[activity list] add pagination to the list of activities' +time: 2023-06-23T12:44:38.879098862+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 07e4fcf62..63639c149 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -22,6 +22,7 @@ use Chill\ActivityBundle\Repository\ActivityUserJobRepository; use Chill\ActivityBundle\Security\Authorization\ActivityVoter; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\UserJob; +use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; @@ -70,6 +71,7 @@ final class ActivityController extends AbstractController private readonly TranslatorInterface $translator, private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly PaginatorFactory $paginatorFactory, ) { } @@ -251,7 +253,6 @@ final class ActivityController extends AbstractController { $view = null; $activities = []; - // TODO: add pagination [$person, $accompanyingPeriod] = $this->getEntity($request); $filter = $this->buildFilterOrder($person ?? $accompanyingPeriod); @@ -266,12 +267,14 @@ final class ActivityController extends AbstractController if ($person instanceof Person) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $person); + $count = $this->activityACLAwareRepository->countByPerson($person, ActivityVoter::SEE, $filterArgs); + $paginator = $this->paginatorFactory->create($count); $activities = $this->activityACLAwareRepository ->findByPerson( $person, ActivityVoter::SEE, - 0, - null, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage(), ['date' => 'DESC', 'id' => 'DESC'], $filterArgs ); @@ -286,17 +289,21 @@ final class ActivityController extends AbstractController } elseif ($accompanyingPeriod instanceof AccompanyingPeriod) { $this->denyAccessUnlessGranted(ActivityVoter::SEE, $accompanyingPeriod); + $count = $this->activityACLAwareRepository->countByAccompanyingPeriod($accompanyingPeriod, ActivityVoter::SEE, $filterArgs); + $paginator = $this->paginatorFactory->create($count); $activities = $this->activityACLAwareRepository ->findByAccompanyingPeriod( $accompanyingPeriod, ActivityVoter::SEE, - 0, - null, + $paginator->getCurrentPageFirstItemNumber(), + $paginator->getItemsPerPage(), ['date' => 'DESC', 'id' => 'DESC'], $filterArgs ); $view = 'ChillActivityBundle:Activity:listAccompanyingCourse.html.twig'; + } else { + throw new \LogicException("Unsupported"); } return $this->render( @@ -306,6 +313,7 @@ final class ActivityController extends AbstractController 'person' => $person, 'accompanyingCourse' => $accompanyingPeriod, 'filter' => $filter, + 'paginator' => $paginator, ] ); } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php index 1fd0a57d6..1544dd764 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php @@ -27,6 +27,8 @@ use Chill\PersonBundle\Entity\Person; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\NonUniqueResultException; +use Doctrine\ORM\NoResultException; use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\ResultSetMappingBuilder; use Doctrine\ORM\QueryBuilder; @@ -48,6 +50,33 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos ) { } + /** + * @throws NonUniqueResultException + * @throws NoResultException + */ + public function countByAccompanyingPeriod(AccompanyingPeriod $period, string $role, array $filters = []): int + { + $qb = $this->buildBaseQuery($filters); + + $qb + ->select('COUNT(a)') + ->andWhere('a.accompanyingPeriod = :period')->setParameter('period', $period); + + return $qb->getQuery()->getSingleScalarResult(); + } + + public function countByPerson(Person $person, string $role, array $filters = []): int + { + $qb = $this->buildBaseQuery($filters); + + $qb = $this->filterBaseQueryByPerson($qb, $person, $role); + + $qb->select('COUNT(a)'); + + return $qb->getQuery()->getSingleScalarResult(); + } + + public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array { $qb = $this->buildBaseQuery($filters); @@ -58,7 +87,12 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $qb->addOrderBy('a.' . $field, $order); } - $qb->setFirstResult(0)->setMaxResults(1000); + if (null !== $start) { + $qb->setFirstResult($start); + } + if (null !== $limit) { + $qb->setMaxResults($limit); + } return $qb->getQuery()->getResult(); } @@ -261,6 +295,13 @@ final readonly class ActivityACLAwareRepository implements ActivityACLAwareRepos $qb->addOrderBy('a.' . $field, $direction); } + if (null !== $start) { + $qb->setFirstResult($start); + } + if (null !== $limit) { + $qb->setMaxResults($limit); + } + return $qb->getQuery()->getResult(); } diff --git a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php index a046ad218..474d8ad16 100644 --- a/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepositoryInterface.php @@ -28,6 +28,16 @@ interface ActivityACLAwareRepositoryInterface */ public function findByAccompanyingPeriod(AccompanyingPeriod $period, string $role, ?int $start = 0, ?int $limit = 1000, array $orderBy = ['date' => 'DESC'], array $filters = []): array; + /** + * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + */ + public function countByAccompanyingPeriod(AccompanyingPeriod $period, string $role, array $filters = []): int; + + /** + * @param array{my_activities?: bool, types?: array, jobs?: array, after?: \DateTimeImmutable|null, before?: \DateTimeImmutable|null} $filters + */ + public function countByPerson(Person $person, string $role, array $filters = []): int; + /** * Return a list of activities, simplified as array (not object). * diff --git a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig index 17ae0598b..dd78c9396 100644 --- a/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig +++ b/src/Bundle/ChillActivityBundle/Resources/views/Activity/list.html.twig @@ -80,6 +80,8 @@
+ {{ filter|chill_render_filter_order_helper }} + {% if activities|length == 0 %}

{{ "There isn't any activities."|trans }} @@ -87,8 +89,6 @@ {% else %} - {{ filter|chill_render_filter_order_helper }} -

{% for activity in activities %} {% include 'ChillActivityBundle:Activity:_list_item.html.twig' with { @@ -99,4 +99,6 @@
{% endif %} + {{ chill_pagination(paginator) }} +