Browse Source

ajoute le tri des tâches sur la page projet

master
vincent 4 months ago
parent
commit
3ce3c47a2e
11 changed files with 345 additions and 15 deletions
  1. +1
    -0
      composer.json
  2. +256
    -1
      composer.lock
  3. +1
    -0
      config/bundles.php
  4. +3
    -0
      config/packages/knp_paginator.yaml
  5. +7
    -0
      config/packages/translation.yaml
  6. +7
    -6
      src/Controller/ProjectController.php
  7. +27
    -2
      src/Repository/TaskRepository.php
  8. +16
    -0
      symfony.lock
  9. +20
    -0
      templates/macro.html.twig
  10. +7
    -6
      templates/project/show.html.twig
  11. +0
    -0
      translations/.gitignore

+ 1
- 0
composer.json View File

@ -12,6 +12,7 @@
"doctrine/doctrine-migrations-bundle": "^3.3", "doctrine/doctrine-migrations-bundle": "^3.3",
"doctrine/orm": "^3.2", "doctrine/orm": "^3.2",
"jmikola/geojson": "^1.0", "jmikola/geojson": "^1.0",
"knplabs/knp-paginator-bundle": "^6.4",
"league/commonmark": "^2.4", "league/commonmark": "^2.4",
"league/html-to-markdown": "^5.1", "league/html-to-markdown": "^5.1",
"stof/doctrine-extensions-bundle": "^1.12", "stof/doctrine-extensions-bundle": "^1.12",


+ 256
- 1
composer.lock View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "ed07bf1e98cc998eddcf49958cb2835f",
"content-hash": "ca829d8e7eed95a138ef3f7742eaa728",
"packages": [ "packages": [
{ {
"name": "behat/transliterator", "name": "behat/transliterator",
@ -1714,6 +1714,167 @@
"time": "2023-12-04T17:19:43+00:00" "time": "2023-12-04T17:19:43+00:00"
}, },
{ {
"name": "knplabs/knp-components",
"version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/KnpLabs/knp-components.git",
"reference": "59ef316e34e814449d8718d7151946bdbb5e553f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/KnpLabs/knp-components/zipball/59ef316e34e814449d8718d7151946bdbb5e553f",
"reference": "59ef316e34e814449d8718d7151946bdbb5e553f",
"shasum": ""
},
"require": {
"php": "^8.0",
"symfony/event-dispatcher-contracts": "^3.0"
},
"conflict": {
"doctrine/dbal": "<3.8"
},
"require-dev": {
"doctrine/dbal": "^3.8 || ^4.0",
"doctrine/mongodb-odm": "^2.5.5",
"doctrine/orm": "^2.13 || ^3.0",
"doctrine/phpcr-odm": "^1.8 || ^2.0",
"ext-pdo_sqlite": "*",
"jackalope/jackalope-doctrine-dbal": "^1.12 || ^2.0",
"phpunit/phpunit": "^9.6",
"propel/propel1": "^1.7",
"ruflin/elastica": "^7.0",
"solarium/solarium": "^6.0",
"symfony/http-foundation": "^5.4.38 || ^6.4.4 || ^7.0",
"symfony/http-kernel": "^5.4.38 || ^6.4.4 || ^7.0",
"symfony/property-access": "^5.4.38 || ^6.4.4 || ^7.0"
},
"suggest": {
"doctrine/common": "to allow usage pagination with Doctrine ArrayCollection",
"doctrine/mongodb-odm": "to allow usage pagination with Doctrine ODM MongoDB",
"doctrine/orm": "to allow usage pagination with Doctrine ORM",
"doctrine/phpcr-odm": "to allow usage pagination with Doctrine ODM PHPCR",
"propel/propel1": "to allow usage pagination with Propel ORM",
"ruflin/elastica": "to allow usage pagination with ElasticSearch Client",
"solarium/solarium": "to allow usage pagination with Solarium Client",
"symfony/http-foundation": "to retrieve arguments from Request",
"symfony/property-access": "to allow sorting arrays"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.x-dev"
}
},
"autoload": {
"psr-4": {
"Knp\\Component\\": "src/Knp/Component"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "KnpLabs Team",
"homepage": "https://knplabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://github.com/KnpLabs/knp-components/contributors"
}
],
"description": "Knplabs component library",
"homepage": "https://github.com/KnpLabs/knp-components",
"keywords": [
"components",
"knp",
"knplabs",
"pager",
"paginator"
],
"support": {
"issues": "https://github.com/KnpLabs/knp-components/issues",
"source": "https://github.com/KnpLabs/knp-components/tree/v4.4.0"
},
"time": "2024-04-23T07:05:01+00:00"
},
{
"name": "knplabs/knp-paginator-bundle",
"version": "v6.4.0",
"source": {
"type": "git",
"url": "https://github.com/KnpLabs/KnpPaginatorBundle.git",
"reference": "a9cbcb3c6be5868a2e16a599c7438149c40b4bda"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/KnpLabs/KnpPaginatorBundle/zipball/a9cbcb3c6be5868a2e16a599c7438149c40b4bda",
"reference": "a9cbcb3c6be5868a2e16a599c7438149c40b4bda",
"shasum": ""
},
"require": {
"knplabs/knp-components": "^4.1",
"php": "^8.1",
"symfony/config": "^6.4 || ^7.0",
"symfony/dependency-injection": "^6.4 || ^7.0",
"symfony/event-dispatcher": "^6.4 || ^7.0",
"symfony/http-foundation": "^6.4 || ^7.0",
"symfony/http-kernel": "^6.4 || ^7.0",
"symfony/routing": "^6.4 || ^7.0",
"symfony/translation": "^6.4 || ^7.0",
"twig/twig": "^3.0"
},
"require-dev": {
"phpstan/phpstan": "^1.11",
"phpunit/phpunit": "^9.6",
"symfony/expression-language": "^6.4 || ^7.0",
"symfony/templating": "^6.4 || ^7.0"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
}
},
"autoload": {
"psr-4": {
"Knp\\Bundle\\PaginatorBundle\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "KnpLabs Team",
"homepage": "https://knplabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://github.com/KnpLabs/KnpPaginatorBundle/contributors"
}
],
"description": "Paginator bundle for Symfony to automate pagination and simplify sorting and other features",
"homepage": "https://github.com/KnpLabs/KnpPaginatorBundle",
"keywords": [
"bundle",
"knp",
"knplabs",
"pager",
"pagination",
"paginator",
"symfony"
],
"support": {
"issues": "https://github.com/KnpLabs/KnpPaginatorBundle/issues",
"source": "https://github.com/KnpLabs/KnpPaginatorBundle/tree/v6.4.0"
},
"time": "2024-05-21T16:15:16+00:00"
},
{
"name": "league/commonmark", "name": "league/commonmark",
"version": "2.4.2", "version": "2.4.2",
"source": { "source": {
@ -5493,6 +5654,100 @@
"time": "2024-06-28T09:27:18+00:00" "time": "2024-06-28T09:27:18+00:00"
}, },
{ {
"name": "symfony/translation",
"version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "cf5ae136e124fc7681b34ce9fac9d5b9ae8ceee3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/cf5ae136e124fc7681b34ce9fac9d5b9ae8ceee3",
"reference": "cf5ae136e124fc7681b34ce9fac9d5b9ae8ceee3",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/polyfill-mbstring": "~1.0",
"symfony/translation-contracts": "^2.5|^3.0"
},
"conflict": {
"symfony/config": "<6.4",
"symfony/console": "<6.4",
"symfony/dependency-injection": "<6.4",
"symfony/http-client-contracts": "<2.5",
"symfony/http-kernel": "<6.4",
"symfony/service-contracts": "<2.5",
"symfony/twig-bundle": "<6.4",
"symfony/yaml": "<6.4"
},
"provide": {
"symfony/translation-implementation": "2.3|3.0"
},
"require-dev": {
"nikic/php-parser": "^4.18|^5.0",
"psr/log": "^1|^2|^3",
"symfony/config": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0",
"symfony/dependency-injection": "^6.4|^7.0",
"symfony/finder": "^6.4|^7.0",
"symfony/http-client-contracts": "^2.5|^3.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/intl": "^6.4|^7.0",
"symfony/polyfill-intl-icu": "^1.21",
"symfony/routing": "^6.4|^7.0",
"symfony/service-contracts": "^2.5|^3",
"symfony/yaml": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"files": [
"Resources/functions.php"
],
"psr-4": {
"Symfony\\Component\\Translation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/translation/tree/v7.1.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-05-31T14:57:53+00:00"
},
{
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
"version": "v3.5.0", "version": "v3.5.0",
"source": { "source": {


+ 1
- 0
config/bundles.php View File

@ -12,4 +12,5 @@ return [
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true],
]; ];

+ 3
- 0
config/packages/knp_paginator.yaml View File

@ -0,0 +1,3 @@
knp_paginator:
template:
pagination: @KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig

+ 7
- 0
config/packages/translation.yaml View File

@ -0,0 +1,7 @@
framework:
default_locale: en
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
providers:

+ 7
- 6
src/Controller/ProjectController.php View File

@ -3,6 +3,7 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Project; use App\Entity\Project;
use App\Entity\Task;
use App\Form\ProjectType; use App\Form\ProjectType;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -18,8 +19,7 @@ class ProjectController extends AbstractController
#[Route('/', name: 'app_project')] #[Route('/', name: 'app_project')]
public function index(EntityManagerInterface $entityManager): Response public function index(EntityManagerInterface $entityManager): Response
{ {
$repository = $entityManager->getRepository(Project::class);
$projects = $repository->findAll();
$projects = $entityManager->getRepository(Project::class)->findAll();
$this->addFlash( $this->addFlash(
'info', 'info',
@ -70,8 +70,8 @@ class ProjectController extends AbstractController
#[Route('/show/{projectSlug}', name: 'app_project_show')] #[Route('/show/{projectSlug}', name: 'app_project_show')]
public function show(EntityManagerInterface $entityManager, $projectSlug): Response public function show(EntityManagerInterface $entityManager, $projectSlug): Response
{ {
$repository = $entityManager->getRepository(Project::class);
$project = $repository->findOneBySlug($projectSlug);
$project = $entityManager->getRepository(Project::class)->findOneBySlug($projectSlug);
$tasks = $entityManager->getRepository(Task::class)->findByProjectPaginated($project);
if (!$project) { if (!$project) {
$this->addFlash( $this->addFlash(
@ -82,14 +82,15 @@ class ProjectController extends AbstractController
return $this->redirectToRoute('app_project'); return $this->redirectToRoute('app_project');
} }
$tasks = count($project->getTasks());
$count = count($project->getTasks());
$this->addFlash( $this->addFlash(
'info', 'info',
sprintf('%s tâche%s trouvée%s', $tasks, ($tasks > 1 ? 's' : ''), ($tasks > 1 ? 's' : ''))
sprintf('%s tâche%s trouvée%s', $count, ($count > 1 ? 's' : ''), ($count > 1 ? 's' : ''))
); );
return $this->render('project/show.html.twig', [ return $this->render('project/show.html.twig', [
'project' => $project, 'project' => $project,
'tasks' => $tasks,
]); ]);
} }


+ 27
- 2
src/Repository/TaskRepository.php View File

@ -2,18 +2,28 @@
namespace App\Repository; namespace App\Repository;
use App\Entity\Project;
use App\Entity\Task; use App\Entity\Task;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/** /**
* @extends ServiceEntityRepository<Task> * @extends ServiceEntityRepository<Task>
*/ */
class TaskRepository extends ServiceEntityRepository class TaskRepository extends ServiceEntityRepository
{ {
public function __construct(ManagerRegistry $registry)
protected PaginatorInterface $paginator;
protected Request $request;
public function __construct(ManagerRegistry $registry, PaginatorInterface $paginator, RequestStack $requestStack)
{ {
parent::__construct($registry, Task::class); parent::__construct($registry, Task::class);
$this->paginator = $paginator;
$this->request = $requestStack->getCurrentRequest();
} }
// /** // /**
@ -40,4 +50,19 @@ class TaskRepository extends ServiceEntityRepository
// ->getOneOrNullResult() // ->getOneOrNullResult()
// ; // ;
// } // }
public function findByProjectPaginated(Project $project)
{
$query = $this->createQueryBuilder('t')
->andWhere('t.project = :project')
->setParameter('project', $project)
->getQuery();
return $this->paginator->paginate(
$query,
$this->request->query->getInt('page', 1),
100
);
}
} }

+ 16
- 0
symfony.lock View File

@ -38,6 +38,9 @@
"migrations/.gitignore" "migrations/.gitignore"
] ]
}, },
"knplabs/knp-paginator-bundle": {
"version": "v6.4.0"
},
"stof/doctrine-extensions-bundle": { "stof/doctrine-extensions-bundle": {
"version": "1.12", "version": "1.12",
"recipe": { "recipe": {
@ -156,6 +159,19 @@
"assets/controllers/hello_controller.js" "assets/controllers/hello_controller.js"
] ]
}, },
"symfony/translation": {
"version": "7.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.3",
"ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b"
},
"files": [
"config/packages/translation.yaml",
"translations/.gitignore"
]
},
"symfony/twig-bundle": { "symfony/twig-bundle": {
"version": "7.1", "version": "7.1",
"recipe": { "recipe": {


+ 20
- 0
templates/macro.html.twig View File

@ -0,0 +1,20 @@
{% macro paginated(entities, title, column) %}
{{ knp_pagination_sortable(entities, title, column) }}
{% if entities.isSorted(column) %}
<span class="badge text-bg-secondary">
{% if entities.params.direction == 'asc' %}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sort-alpha-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10.082 5.629 9.664 7H8.598l1.789-5.332h1.234L13.402 7h-1.12l-.419-1.371zm1.57-.785L11 2.687h-.047l-.652 2.157z"/>
<path d="M12.96 14H9.028v-.691l2.579-3.72v-.054H9.098v-.867h3.785v.691l-2.567 3.72v.054h2.645zM4.5 2.5a.5.5 0 0 0-1 0v9.793l-1.146-1.147a.5.5 0 0 0-.708.708l2 1.999.007.007a.497.497 0 0 0 .7-.006l2-2a.5.5 0 0 0-.707-.708L4.5 12.293z"/>
</svg>
{% endif %}
{% if entities.params.direction == 'desc' %}
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sort-alpha-down-alt" viewBox="0 0 16 16">
<path d="M12.96 7H9.028v-.691l2.579-3.72v-.054H9.098v-.867h3.785v.691l-2.567 3.72v.054h2.645z"/>
<path fill-rule="evenodd" d="M10.082 12.629 9.664 14H8.598l1.789-5.332h1.234L13.402 14h-1.12l-.419-1.371zm1.57-.785L11 9.688h-.047l-.652 2.156z"/>
<path d="M4.5 2.5a.5.5 0 0 0-1 0v9.793l-1.146-1.147a.5.5 0 0 0-.708.708l2 1.999.007.007a.497.497 0 0 0 .7-.006l2-2a.5.5 0 0 0-.707-.708L4.5 12.293z"/>
</svg>
{% endif %}
</span>
{% endif %}
{% endmacro %}

+ 7
- 6
templates/project/show.html.twig View File

@ -1,4 +1,5 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% import 'macro.html.twig' as macro %}
{% block breadcrumb %} {% block breadcrumb %}
<li class="breadcrumb-item"><a href="{{ path('app_project') }}">Projets</a></li> <li class="breadcrumb-item"><a href="{{ path('app_project') }}">Projets</a></li>
@ -54,15 +55,15 @@
<table class="table table-sm table-hover"> <table class="table table-sm table-hover">
<thead> <thead>
<tr> <tr>
<th scope="col">Identifiant</th>
<th scope="col">Nom</th>
<th scope="col">État</th>
<th scope="col">Importance</th>
<th scope="col">Urgence</th>
<th scope="col">{{ macro.paginated(tasks, 'Identifiant', 't.id') }}</th>
<th scope="col">{{ macro.paginated(tasks, 'Nom', 't.name') }}</th>
<th scope="col">{{ macro.paginated(tasks, 'État', 't.status') }}</th>
<th scope="col">{{ macro.paginated(tasks, 'Importance', 't.important') }}</th>
<th scope="col">{{ macro.paginated(tasks, 'Urgence', 't.urgent') }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for task in project.tasks %}
{% for task in tasks %}
<tr class="{{ 'table-' ~ workflow_metadata(task, 'color', task.status) }}"> <tr class="{{ 'table-' ~ workflow_metadata(task, 'color', task.status) }}">
<th scope="row">{{ task.id }}</th> <th scope="row">{{ task.id }}</th>
<td><a href="{{ path('app_task_show', {'projectSlug': project.slug, 'taskSlug': task.slug}) }}">{{ task.name }}</a></td> <td><a href="{{ path('app_task_show', {'projectSlug': project.slug, 'taskSlug': task.slug}) }}">{{ task.name }}</a></td>


+ 0
- 0
translations/.gitignore View File


Loading…
Cancel
Save