diff --git a/src/Controller/TaskController.php b/src/Controller/TaskController.php index fcffc0a..1fef477 100644 --- a/src/Controller/TaskController.php +++ b/src/Controller/TaskController.php @@ -11,6 +11,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Generator\UrlGenerator; +use App\Form\Task\TaskFilterForm; class TaskController extends AbstractExtendedController { @@ -84,13 +85,19 @@ } } - // Get tasks - $tasks = $taskRepository->findAll(); + // Filter + /** @var TaskFilterForm $taskFilterForm */ + $taskFilterForm = $this->createNamedGetCustomForm('taskFilter', TaskFilterForm::class, [ + 'actors' => $actors, + ]); + $taskFilterForm->handleRequest($request); + $tasks = $taskFilterForm->getTasks($taskRepository); return $this->render('task/tasks.html.twig', [ 'tasks' => $tasks, 'taskAddForm' => $taskAddForm, 'taskDeleteForm' => $taskDeleteForm, + 'taskFilterForm' => $taskFilterForm, ]); } diff --git a/src/Form/Activity/ActivityFilterForm.php b/src/Form/Activity/ActivityFilterForm.php index f736ce1..222c02a 100644 --- a/src/Form/Activity/ActivityFilterForm.php +++ b/src/Form/Activity/ActivityFilterForm.php @@ -45,7 +45,7 @@ } /** - * Create query builder + * Get activities * * @param ActivityRepository $activityRepository * @return array diff --git a/src/Form/Task/TaskFilterForm.php b/src/Form/Task/TaskFilterForm.php new file mode 100644 index 0000000..5458ab9 --- /dev/null +++ b/src/Form/Task/TaskFilterForm.php @@ -0,0 +1,171 @@ +actors = $data['actors']; + $formBuilder->setData([ + 'actor' => null, + 'unassigned' => false, + 'followed' => false, + + 'status' => null, + 'active' => false, + 'notClosed' => true, + + 'doneAfter' => null, + 'doneBefore' => null, + ]); + parent::__construct($formBuilder, $data, $usesToken); + } + + /** + * Get tasks + * + * @param TaskRepository $taskRepository + * @return array + */ + public function getTasks(TaskRepository $taskRepository): array + { + $data = $this->getData(); + + // Create query + $query = $taskRepository->createQueryBuilder('task'); + + // Create filter + $criteria = new Criteria(); + + // Filter actors + if ($data['followed']) { + $query->join(ActorEntity::class, 'actor', Join::WITH, 'task.actor = actor'); + $criteria->andWhere($criteria->expr() + ->eq('actor.followed', true)); + } + if (!is_null($data['actor'])) { + $criteria->andWhere($criteria->expr() + ->eq('task.actor', $data['actor'])); + } + if ($data['unassigned']) { + $criteria->andWhere($criteria->expr() + ->isNull('task.actor')); + } + + // Filter status + if (!is_null($data['status'])) { + $criteria->andWhere($criteria->expr() + ->eq('task.status', $data['status'])); + } + if ($data['active']) { + $criteria->andWhere($criteria->expr() + ->in('task.status', StatusEnum::ACTIVE_STATUS)); + } + if ($data['notClosed']) { + $criteria->andWhere($criteria->expr() + ->notIn('task.status', StatusEnum::CLOSED_STATUS)); + } + + // Filter dates + if (!is_null($data['doneAfter'])) { + $criteria->andWhere($criteria->expr() + ->gt('task.executionDate', $data['doneAfter'])); + } + if (!is_null($data['doneBefore'])) { + $criteria->andWhere($criteria->expr() + ->lt('task.executionDate', $data['doneBefore'])); + } + + $query->addCriteria($criteria); + + return $query->getQuery()->execute([], Query::HYDRATE_OBJECT); + } + + /** + * {@inheritdoc} + */ + public function getTemplate(): string + { + return '_includes/html/form/task/filter.html.twig'; + } + + /** + * {@inheritdoc} + */ + protected function addFields($formBuilder, $options): void + { + // Actor filters + $formBuilder->add('actor', EntityType::class, [ + 'class' => ActorEntity::class, + 'choices' => $this->actors, + 'group_by' => function (ActorEntity $choice) { + if ($choice->getFollowed()) { + return 'Suivi'; + } + if ($choice->getActive()) { + return 'Actif'; + } + + return 'Inactif'; + }, + 'choice_label' => 'displayName', + 'required' => false, + ]) + ->add('unassigned', CheckboxType::class, [ + 'required' => false, + ]) + ->add('followed', CheckboxType::class, [ + 'required' => false, + ]); + + // Status filters + $formBuilder->add('status', ChoiceType::class, [ + 'required' => false, + 'choices' => TaskEntity::VALID_STATUS, + 'choice_label' => function ($choice, $key, $value) { + return StatusEnum::STATUS_NAME[$choice]; + }, + ]) + ->add('active', CheckboxType::class, [ + 'required' => false, + ]) + ->add('notClosed', CheckboxType::class, [ + 'required' => false, + ]); + + // Date filters + $formBuilder->add('doneAfter', DateType::class, [ + 'required' => false, + 'widget' => 'single_text', + ])->add('doneBefore', DateType::class, [ + 'required' => false, + 'widget' => 'single_text', + ]); + + // Submit + $formBuilder->add('submit', SubmitType::class)->add('reset', ResetType::class); + } +} \ No newline at end of file diff --git a/templates/_includes/html/form/task/filter.html.twig b/templates/_includes/html/form/task/filter.html.twig new file mode 100644 index 0000000..ef95855 --- /dev/null +++ b/templates/_includes/html/form/task/filter.html.twig @@ -0,0 +1,56 @@ +{{ form_start(form)}} +
+
+
+ {{ form_label(form.actor, 'Acteur', {label_attr: {class: 'input-text-label'}}) }} + {{ form_widget(form.actor, {attr: {class: 'w-100'}}) }} +
+
+ {{ form_widget(form.unassigned) }} + {{ form_label(form.unassigned, 'Non assigné') }} +
+
+ {{ form_widget(form.followed) }} + {{ form_label(form.followed, 'Acteur suivi') }} +
+
+
+
+ {{ form_label(form.status, 'Status', {label_attr: {class: 'input-text-label'}}) }} + {{ form_widget(form.status, {attr: {class: 'w-100'}}) }} +
+
+ {{ form_widget(form.active) }} + {{ form_label(form.active, 'Actif') }} +
+
+ {{ form_widget(form.notClosed) }} + {{ form_label(form.notClosed, 'Non clos') }} +
+
+
+
+ {{ form_label(form.doneAfter, 'Fait après', {label_attr: {class: 'input-text-label'}}) }} + {{ form_widget(form.doneAfter, {attr: {class: 'w-100'}}) }} +
+
+ {{ form_label(form.doneBefore, 'Fait avant', {label_attr: {class: 'input-text-label'}}) }} + {{ form_widget(form.doneBefore, {attr: {class: 'w-100'}}) }} +
+
+
+
+
+
+ {{ form_widget(form.submit, {attr: {class: 'w-100'}, label: 'Filtrer'}) }} +
+
+
+
+ {{ form_widget(form.reset, {attr: {class: 'w-100'}, label: 'Réinitialiser'}) }} +
+
+
+

+

+{{ form_end(form) }} \ No newline at end of file diff --git a/templates/task/tasks.html.twig b/templates/task/tasks.html.twig index decb68b..2aa3b0a 100644 --- a/templates/task/tasks.html.twig +++ b/templates/task/tasks.html.twig @@ -10,6 +10,7 @@

Tâches

+ {% include '_includes/html/genericForm.html.twig' with {form: taskFilterForm} only %} {% include "_includes/html/arrays/task.html.twig" with {tasks: tasks, taskDeleteForm: taskDeleteForm} only %}