diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index d00b241b2..1c56ccf71 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -608,4 +608,14 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter return $this; } + + /** + * Check if the current object is an instance of User. + * + * @return bool returns true if the current object is an instance of User, false otherwise + */ + public function isUser(): bool + { + return true; + } } diff --git a/src/Bundle/ChillMainBundle/Entity/UserGroup.php b/src/Bundle/ChillMainBundle/Entity/UserGroup.php index b5f3265ed..03da74326 100644 --- a/src/Bundle/ChillMainBundle/Entity/UserGroup.php +++ b/src/Bundle/ChillMainBundle/Entity/UserGroup.php @@ -136,4 +136,16 @@ class UserGroup return $this; } + + /** + * Checks if the current object is an instance of the UserGroup class. + * + * In use in twig template, to discriminate when there an object can be polymorphic. + * + * @return bool returns true if the current object is an instance of UserGroup, false otherwise + */ + public function isUserGroup(): bool + { + return true; + } } diff --git a/src/Bundle/ChillTicketBundle/src/Controller/TicketListController.php b/src/Bundle/ChillTicketBundle/src/Controller/TicketListController.php new file mode 100644 index 000000000..ab335f108 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Controller/TicketListController.php @@ -0,0 +1,84 @@ +security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException('only user can access this page'); + } + + $filter = $this->buildFilter(); + + $tickets = $this->ticketRepository->findAllOrdered(); + + return new Response( + $this->twig->render('@ChillTicket/Ticket/list.html.twig', [ + 'tickets' => $tickets, + 'filter' => $filter, + ]) + ); + } + + private function buildFilter(): FilterOrderHelper + { + // $motives = $this->motiveRepository->findAll(); + + return $this->filterOrderHelperFactory + ->create(__CLASS__) + ->addSingleCheckbox('to_me', 'chill_ticket.list.filter.to_me') + ->addSingleCheckbox('in_alert', 'chill_ticket.list.filter.in_alert') + ->addDateRange('created_between', 'chill_ticket.list.filter.created_between') + /* + ->addEntityChoice('by_motive', 'chill_ticket.list.filter.by_motive', Motive::class, $motives, [ + 'choice_label' => fn (Motive $motive) => $this->translatableStringHelper->localize($motive->getLabel()), + 'expanded' => true, + 'multiple' => true, + 'attr' => ['class' => 'select2'], + ]) + */ + ->build(); + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Menu/SectionMenuBuilder.php b/src/Bundle/ChillTicketBundle/src/Menu/SectionMenuBuilder.php new file mode 100644 index 000000000..554aacc77 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Menu/SectionMenuBuilder.php @@ -0,0 +1,29 @@ +addChild('Tickets', ['route' => 'chill_ticket_ticket_list']) + ->setExtras(['order' => 250]); + } + + public static function getMenuIds(): array + { + return ['section']; + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Repository/MotiveRepository.php b/src/Bundle/ChillTicketBundle/src/Repository/MotiveRepository.php new file mode 100644 index 000000000..0c1174a59 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Repository/MotiveRepository.php @@ -0,0 +1,27 @@ + + */ +class MotiveRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Motive::class); + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Repository/TicketRepository.php b/src/Bundle/ChillTicketBundle/src/Repository/TicketRepository.php index d4301585a..d68598510 100644 --- a/src/Bundle/ChillTicketBundle/src/Repository/TicketRepository.php +++ b/src/Bundle/ChillTicketBundle/src/Repository/TicketRepository.php @@ -19,7 +19,7 @@ final readonly class TicketRepository implements TicketRepositoryInterface { private ObjectRepository $repository; - public function __construct(EntityManagerInterface $objectManager) + public function __construct(private EntityManagerInterface $objectManager) { $this->repository = $objectManager->getRepository($this->getClassName()); } @@ -34,6 +34,14 @@ final readonly class TicketRepository implements TicketRepositoryInterface return $this->repository->findAll(); } + /** + * @return list + */ + public function findAllOrdered(): array + { + return $this->objectManager->createQuery('SELECT t FROM '.$this->getClassName().' t ORDER BY t.id DESC')->getResult(); + } + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array { return $this->repository->findBy($criteria, $orderBy, $limit, $offset); diff --git a/src/Bundle/ChillTicketBundle/src/Repository/TicketRepositoryInterface.php b/src/Bundle/ChillTicketBundle/src/Repository/TicketRepositoryInterface.php index 0b2cb4d66..9dc713e72 100644 --- a/src/Bundle/ChillTicketBundle/src/Repository/TicketRepositoryInterface.php +++ b/src/Bundle/ChillTicketBundle/src/Repository/TicketRepositoryInterface.php @@ -20,4 +20,9 @@ use Doctrine\Persistence\ObjectRepository; interface TicketRepositoryInterface extends ObjectRepository { public function findOneByExternalRef(string $extId): ?Ticket; + + /** + * @return list + */ + public function findAllOrdered(): array; } diff --git a/src/Bundle/ChillTicketBundle/src/Resources/views/Ticket/list.html.twig b/src/Bundle/ChillTicketBundle/src/Resources/views/Ticket/list.html.twig new file mode 100644 index 000000000..6d25c5834 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Resources/views/Ticket/list.html.twig @@ -0,0 +1,97 @@ +{% extends '@ChillMain/layout.html.twig' %} + +{% block title 'chill_ticket.list.title'|trans %} + +{% block content %} +

{{ block('title') }}

+ + {{ filter|chill_render_filter_order_helper }} + + {% if tickets|length == 0 %} +

{{ chill_ticket.list.no_tickets }}

+ {% else %} +
+ {% for ticket in tickets %} +
+
+
+
+
+ {% if ticket.motive is not null %} + + {{ ticket.motive.label|localize_translatable_string }} + + {% else %} + Sans motif + {% endif %} +
+
+

Ouvert

+
+
+
+
+ #{{ ticket.id }} +
+
+ {% if ticket.createdAt is not null %} + {{ ticket.createdAt|ago|capitalize }} + {% endif %} +
+
+
+
+ {% if ticket.persons|length > 0 or ticket.currentAddressee|length > 0 %} +
+
+ {% if ticket.persons|length > 0 %} +
+

Patient concerné

+
+ {% for p in ticket.persons %} + {% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with { + targetEntity: { name: 'person', id: p.id }, + action: 'show', + displayBadge: true, + buttonText: p|chill_entity_render_string, + isDead: p.deathdate is not null + } %} + {% endfor %} +
+
+ {% endif %} + {% if ticket.currentAddressee|length > 0 %} +
+

Destinataires

+
+ {% for d in ticket.currentAddressee %} + {% if d.isUser is defined and d.isUser %} + {{ d|chill_entity_render_box }} + {% elseif d.isUserGroup is defined and d.isUserGroup %} + {{ d|chill_entity_render_box }} + {% endif %} + {% endfor %} +
+
+ {% endif %} +
+
+ {% endif %} +
+
    +
  • + +
  • +
+
+
+ {% endfor %} +
+ {% endif %} + + +{% endblock %} diff --git a/src/Bundle/ChillTicketBundle/src/config/services.yaml b/src/Bundle/ChillTicketBundle/src/config/services.yaml index 35bdf54c9..331e03898 100644 --- a/src/Bundle/ChillTicketBundle/src/config/services.yaml +++ b/src/Bundle/ChillTicketBundle/src/config/services.yaml @@ -17,5 +17,8 @@ services: Chill\TicketBundle\Serializer\: resource: '../Serializer/' + Chill\TicketBundle\Menu\: + resource: '../Menu/' + Chill\TicketBundle\DataFixtures\: resource: '../DataFixtures/' diff --git a/src/Bundle/ChillTicketBundle/src/translations/messages.fr.yml b/src/Bundle/ChillTicketBundle/src/translations/messages.fr.yml new file mode 100644 index 000000000..3cba033a1 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/translations/messages.fr.yml @@ -0,0 +1,9 @@ +chill_ticket: + list: + title: Tickets + filter: + to_me: Tickets qui me sont attribués + in_alert: Tickets en alerte (délai de résolution dépassé) + created_between: Créés entre + +