mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
improve task list
This commit is contained in:
parent
9dfa39ff07
commit
196fc2c38f
@ -9,29 +9,68 @@ use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\TaskBundle\Entity\SingleTask;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Chill\TaskBundle\Repository\SingleTaskRepository;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class TaskController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/{_locale}/task/task/list/{personId}")
|
||||
* @Route(
|
||||
* "/{_locale}/task/task/list/{personId}",
|
||||
* name="chill_task_task_list"
|
||||
* )
|
||||
*/
|
||||
public function listAction(Request $request, Person $personId)
|
||||
{
|
||||
$person = $personId;
|
||||
$em = $this->getDoctrine()
|
||||
->getManager();
|
||||
// collect parameters for filter
|
||||
$params = [];
|
||||
/* @var $taskRepository SingleTaskRepository */
|
||||
$taskRepository = $this->get('chill_task.single_task_repository');
|
||||
/* @var $paginatorFactory \Chill\MainBundle\Pagination\PaginatorFactory */
|
||||
$paginatorFactory = $this->get('chill_main.paginator_factory');
|
||||
/* @var $viewParams array The parameters for the view */
|
||||
$viewParams['person'] = $person;
|
||||
|
||||
// collect parameters for filter
|
||||
$params['person'] = $person;
|
||||
|
||||
$singleTasks = $this->get('chill_task.single_task_repository')
|
||||
->findByParameters($params, $this->getUser());
|
||||
if ($request->query->has('date_status')) {
|
||||
$statuses = $request->query->get('date_status');
|
||||
$singleStatus = count($statuses) === 1;
|
||||
// check for invalid parameters
|
||||
$diff = \array_diff(
|
||||
$statuses,
|
||||
SingleTaskRepository::DATE_STATUSES)
|
||||
;
|
||||
|
||||
if (count($diff) > 0) {
|
||||
return new Response(
|
||||
'date_status not allowed: '. \implode(', ', $diff),
|
||||
Response::HTTP_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(SingleTaskRepository::DATE_STATUSES as $type) {
|
||||
if($request->query->has('date_status')
|
||||
&& FALSE === \in_array($type, $statuses ?? [])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params['date_status'] = $type;
|
||||
$count = $taskRepository
|
||||
->countByParameters($params, $this->getUser())
|
||||
;
|
||||
$paginator = $paginatorFactory->create($count);
|
||||
$viewParams['single_task_'.$type.'_count'] = $count;
|
||||
$viewParams['single_task_'.$type.'_paginator'] = $paginator;
|
||||
$viewParams['single_task_'.$type.'_tasks'] = $taskRepository
|
||||
->findByParameters($params, $this->getUser(),
|
||||
$singleStatus ? $paginator->getCurrentPage()->getFirstItemNumber() : 0,
|
||||
$singleStatus ? $paginator->getItemsPerPage() : 10)
|
||||
;
|
||||
}
|
||||
|
||||
return $this->render('ChillTaskBundle:Task:index.html.twig', [
|
||||
'single_tasks' => $singleTasks,
|
||||
'person' => $person
|
||||
]);
|
||||
return $this->render('ChillTaskBundle:Task:index.html.twig', $viewParams);
|
||||
}
|
||||
|
||||
protected function getPersonParam(Request $request, EntityManagerInterface $em)
|
||||
|
@ -7,12 +7,26 @@ use Doctrine\ORM\QueryBuilder;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Chill\TaskBundle\Security\Authorization\TaskVoter;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* SingleTaskRepository
|
||||
*/
|
||||
class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
|
||||
{
|
||||
|
||||
const DATE_STATUS_ENDED = 'ended';
|
||||
const DATE_STATUS_WARNING = 'warning';
|
||||
const DATE_STATUS_CURRENT = 'current';
|
||||
const DATE_STATUS_NOT_STARTED = 'not_started';
|
||||
|
||||
const DATE_STATUSES = [
|
||||
self::DATE_STATUS_ENDED,
|
||||
self::DATE_STATUS_WARNING,
|
||||
self::DATE_STATUS_CURRENT,
|
||||
self::DATE_STATUS_NOT_STARTED
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var AuthorizationHelper
|
||||
@ -24,6 +38,42 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the tasks for given parameters.
|
||||
*
|
||||
* The parameters are describe in @see SingleTaskRepository::filterByParameters.
|
||||
*
|
||||
* @see SingleTaskRepository::filterByParameters
|
||||
* @param array $params
|
||||
* @param User $currentUser
|
||||
* @return int
|
||||
*/
|
||||
public function countByParameters($params, User $currentUser)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('st')
|
||||
->select('COUNT(st)');
|
||||
|
||||
$this->buildQuery($qb, $params, $currentUser);
|
||||
|
||||
return (int) $qb
|
||||
->getQuery()
|
||||
->getSingleScalarResult()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find task for given parameters.
|
||||
*
|
||||
* Available parameters:
|
||||
*
|
||||
* - `person` : filter by person associated with the task ;
|
||||
* - `date_status`: type of task. To choose between :
|
||||
* `ended`, `warning`, `current`, `not_started`
|
||||
*
|
||||
* @param type $params
|
||||
* @param User $currentUser
|
||||
* @return type
|
||||
*/
|
||||
public function findByParameters($params, User $currentUser)
|
||||
{
|
||||
$qb = $this->createQueryBuilder('st');
|
||||
@ -44,8 +94,110 @@ class SingleTaskRepository extends \Doctrine\ORM\EntityRepository
|
||||
$qb->andWhere($qb->expr()->eq('st.person', ':person'));
|
||||
$qb->setParameter('person', $params['person']);
|
||||
}
|
||||
|
||||
if (\array_key_exists('date_status', $params)) {
|
||||
$this->addTypeFilter($qb, $params);
|
||||
}
|
||||
}
|
||||
|
||||
protected function addTypeFilter(QueryBuilder $qb, $params)
|
||||
{
|
||||
$andWhere = $qb->expr()->andX();
|
||||
|
||||
switch ($params['date_status']) {
|
||||
case self::DATE_STATUS_ENDED:
|
||||
$andWhere->add($this->buildNowIsAfterEndDate($qb));
|
||||
break;
|
||||
|
||||
case self::DATE_STATUS_WARNING:
|
||||
$andWhere
|
||||
->add($this->buildNowIsAfterEndDate($qb, true))
|
||||
->add($this->buildNowIsAfterWarningDate($qb))
|
||||
;
|
||||
break;
|
||||
|
||||
case self::DATE_STATUS_CURRENT:
|
||||
// st.endDate is NULL or (st.endDate is not null and st.endDate < now))
|
||||
$andWhere
|
||||
->add($this->buildNowIsAfterEndDate($qb, true))
|
||||
->add($this->buildNowIsAfterWarningDate($qb, true))
|
||||
->add($this->buildNowIsAfterStartDate($qb, false))
|
||||
;
|
||||
break;
|
||||
|
||||
case self::DATE_STATUS_NOT_STARTED:
|
||||
$andWhere
|
||||
->add($this->buildNowIsAfterEndDate($qb, true))
|
||||
->add($this->buildNowIsAfterWarningDate($qb, true))
|
||||
->add($this->buildNowIsAfterStartDate($qb, true))
|
||||
;
|
||||
}
|
||||
$qb->setParameter('now', new \DateTime('today'), Type::DATE);
|
||||
$qb->andWhere($andWhere);
|
||||
}
|
||||
|
||||
private function buildNowIsAfterEndDate(QueryBuilder $qb, $negative = false)
|
||||
{
|
||||
if ($negative === false) {
|
||||
return $qb->expr()->andX()
|
||||
->add($qb->expr()->isNotNull('st.endDate'))
|
||||
->add($qb->expr()->lt('st.endDate', ':now'))
|
||||
;
|
||||
} else {
|
||||
return $qb->expr()->orX()
|
||||
->add(
|
||||
$qb->expr()->andX()
|
||||
->add($qb->expr()->isNotNull('st.endDate'))
|
||||
->add($qb->expr()->gt('st.endDate', ':now'))
|
||||
)
|
||||
->add($qb->expr()->isNull('st.endDate'))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
private function buildNowIsAfterWarningDate(QueryBuilder $qb, $negative = false)
|
||||
{
|
||||
if ($negative === false) {
|
||||
return $qb->expr()->andX()
|
||||
->add($qb->expr()->lt(
|
||||
$qb->expr()->diff('st.endDate', 'st.warningInterval'), ':now'
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return $qb->expr()->orX()
|
||||
->add(
|
||||
$qb->expr()->andX()
|
||||
->add($qb->expr()->isNotNull('st.endDate'))
|
||||
->add($qb->expr()->isNotNull('st.warningInterval'))
|
||||
->add($qb->expr()->gt(
|
||||
$qb->expr()->diff('st.endDate', 'st.warningInterval'),
|
||||
':now'
|
||||
)
|
||||
)
|
||||
)
|
||||
->add($qb->expr()->isNull('st.endDate'))
|
||||
->add($qb->expr()->isNull('st.warningInterval'))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
private function buildNowIsAfterStartDate(QueryBuilder $qb, $negative = false)
|
||||
{
|
||||
if ($negative === false) {
|
||||
return $qb->expr()->orX()
|
||||
->add($qb->expr()->lt('st.startDate', ':now'))
|
||||
->add($qb->expr()->isNull('st.startDate'))
|
||||
;
|
||||
} else {
|
||||
return
|
||||
$qb->expr()->andX()
|
||||
->add($qb->expr()->gt('st.startDate', ':now'))
|
||||
->add($qb->expr()->isNotNull('st.startDate'))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function buildACLQuery(QueryBuilder $qb, User $currentUser)
|
||||
{
|
||||
if (NULL === $this->authorizationHelper) {
|
||||
|
@ -21,85 +21,70 @@
|
||||
{% block title %}{{ 'Task list'|trans }}{% endblock %}
|
||||
|
||||
{% macro thead() %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'Title'|trans }}</th>
|
||||
<th>{{ 'Task type'|trans }}</th>
|
||||
<th>{{ 'Task status'|trans }}</th>
|
||||
<th>{{ 'Task start date'|trans }}</th>
|
||||
<th>{{ 'Task warning date'|trans }}</th>
|
||||
<th>{{ 'Task end date'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
{% endmacro %}
|
||||
|
||||
{% macro row(task) %}
|
||||
<tr>
|
||||
<td>{{ task.title }}</td>
|
||||
<td>{{ task.type }}</td>
|
||||
<td>todo</td>
|
||||
<td>{{ task.startDate|localizeddate('medium', 'none') }}</td>
|
||||
<td>{{ task.warningDate|localizeddate('medium', 'none') }}</td>
|
||||
<td>{{ task.endDate|localizeddate('medium', 'none') }}</td>
|
||||
</tr>
|
||||
|
||||
{% endmacro %}
|
||||
|
||||
{% macro date_status(title, tasks, count, paginator) %}
|
||||
{% if tasks|length > 0 %}
|
||||
<h2>{{ title|trans }}</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'Title'|trans }}</th>
|
||||
<th>{{ 'Task type'|trans }}</th>
|
||||
<th>{{ 'Task status'|trans }}</th>
|
||||
<th>{{ 'Task start date'|trans }}</th>
|
||||
<th>{{ 'Task warning date'|trans }}</th>
|
||||
<th>{{ 'Task end date'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for task in tasks %}
|
||||
<tr>
|
||||
<td>{{ task.title }}</td>
|
||||
<td>{{ task.type }}</td>
|
||||
<td>todo</td>
|
||||
<td>{% if task.startDate is not null %}{{ task.startDate|localizeddate('medium', 'none') }}{% endif %}</td>
|
||||
<td>{% if task.warningDate is not null %}{{ task.warningDate|localizeddate('medium', 'none') }}{% endif %}</td>
|
||||
<td>{% if task.endDate is not null %}{{ task.endDate|localizeddate('medium', 'none') }}{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% if tasks|length > paginator.getTotalItems %}
|
||||
{{ chill_pagination(paginator) }}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as helper %}
|
||||
|
||||
{# filter tasks #}
|
||||
|
||||
{% set ended_tasks = [] %}
|
||||
{% for task in single_tasks if (task.endDate|date("U") > 'now'|date("U")) %}
|
||||
{% set ended_tasks = ended_tasks|merge([ task ]) %}
|
||||
{% endfor %}
|
||||
|
||||
{% set warning_tasks = [] %}
|
||||
{% for task in single_tasks if (task.warningDate|date('U') > 'now'|date("U") and task not in ended_tasks) %}
|
||||
{% set warning_tasks = warning_tasks|merge([ task ]) %}
|
||||
{% endfor %}
|
||||
|
||||
{% set rest_tasks = [] %}
|
||||
{% for task in single_tasks if (task not in ended_tasks and task not in warning_tasks) %}
|
||||
{% set rest_tasks = rest_tasks|merge([ task ]) %}
|
||||
{% endfor %}
|
||||
|
||||
{% block personcontent %}
|
||||
<h1>{{ 'Task list'|trans }}</h1>
|
||||
|
||||
{% if ended_tasks|length > 0 %}
|
||||
<h2>{{ 'Task with expired deadline'|trans }}</h2>
|
||||
<table>
|
||||
{{ helper.thead() }}
|
||||
<tbody>
|
||||
{% for task in ended_tasks %}
|
||||
{{ helper.row(task) }}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if single_task_ended_tasks is defined %}
|
||||
{{ helper.date_status('Tasks with expired deadline', single_task_ended_tasks, single_task_ended_count, single_task_ended_paginator) }}
|
||||
{% endif %}
|
||||
|
||||
{% if warning_tasks|length > 0 %}
|
||||
<h2>{{ 'Task with warning'|trans }}</h2>
|
||||
<table>
|
||||
{{ helper.thead() }}
|
||||
<tbody>
|
||||
{% for task in warning_tasks %}
|
||||
{{ helper.row(task) }}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if single_task_warning_tasks is defined %}
|
||||
{{ helper.date_status('Tasks with warning deadline reached', single_task_warning_tasks, single_task_warning_count, single_task_warning_paginator) }}
|
||||
{% endif %}
|
||||
|
||||
{% if rest_tasks|length > 0 %}
|
||||
<h2>{{ 'Task '|trans }}</h2>
|
||||
<table>
|
||||
{{ helper.thead() }}
|
||||
<tbody>
|
||||
{% for task in rest_tasks %}
|
||||
{{ helper.row(task) }}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if single_task_current_tasks is defined %}
|
||||
{{ helper.date_status('Current tasks', single_task_current_tasks, single_task_current_count, single_task_current_paginator) }}
|
||||
{% endif %}
|
||||
|
||||
{% if single_task_not_started_tasks is defined %}
|
||||
{{ helper.date_status('Tasks not started', single_task_not_started_tasks, single_task_not_started_count, single_task_not_started_paginator) }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\TaskBundle\Tests\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
class DefaultControllerTest extends WebTestCase
|
||||
{
|
||||
public function testIndex()
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
$crawler = $client->request('GET', '/');
|
||||
|
||||
$this->assertContains('Hello World', $client->getResponse()->getContent());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user