mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
refactor list by course: use acl aware repository
This commit is contained in:
parent
4da32dc5ca
commit
4017f8db48
@ -472,7 +472,11 @@ final class SingleTaskController extends AbstractController
|
||||
$filterOrder->getQueryString(),
|
||||
$flags,
|
||||
$paginator->getCurrentPageFirstItemNumber(),
|
||||
$paginator->getItemsPerPage()
|
||||
$paginator->getItemsPerPage(),
|
||||
[
|
||||
'startDate' => 'DESC',
|
||||
'endDate' => 'DESC',
|
||||
]
|
||||
);
|
||||
|
||||
return $this->render('@ChillTask/SingleTask/List/index.html.twig', [
|
||||
@ -694,6 +698,7 @@ final class SingleTaskController extends AbstractController
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
protected function getPersonParam(EntityManagerInterface $em)
|
||||
{
|
||||
$person = $em->getRepository(Person::class)
|
||||
@ -722,6 +727,7 @@ final class SingleTaskController extends AbstractController
|
||||
|
||||
return $user;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a form to delete a Task entity by id.
|
||||
@ -750,34 +756,40 @@ final class SingleTaskController extends AbstractController
|
||||
|
||||
public function listCourseTasks(
|
||||
AccompanyingPeriod $course,
|
||||
SingleTaskRepository $taskRepository,
|
||||
FormFactoryInterface $formFactory,
|
||||
Request $request
|
||||
): Response
|
||||
{
|
||||
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$tasks = $taskRepository
|
||||
->findBy(
|
||||
array('course' => $course)
|
||||
);
|
||||
|
||||
$form = $formFactory->createNamed(null, SingleTaskListType::class, null, [
|
||||
'accompanyingCourse' => $course,
|
||||
'method' => Request::METHOD_GET,
|
||||
'csrf_protection' => false,
|
||||
'add_type' => true
|
||||
]);
|
||||
$filterOrder = $this->buildFilterOrder();
|
||||
$flags = \array_merge(
|
||||
$filterOrder->getCheckboxData('status'),
|
||||
\array_map(fn ($i) => 'state_'.$i, $filterOrder->getCheckboxData('states'))
|
||||
);
|
||||
$nb = $this->singleTaskAclAwareRepository->countByCourse(
|
||||
$course,
|
||||
$filterOrder->getQueryString(),
|
||||
$flags
|
||||
);
|
||||
$paginator = $this->paginatorFactory->create($nb);
|
||||
$tasks = $this->singleTaskAclAwareRepository->findByCourse(
|
||||
$course,
|
||||
$filterOrder->getQueryString(),
|
||||
$flags,
|
||||
$paginator->getCurrentPageFirstItemNumber(),
|
||||
$paginator->getItemsPerPage(),
|
||||
[
|
||||
'startDate' => 'DESC',
|
||||
'endDate' => 'DESC',
|
||||
]
|
||||
);
|
||||
|
||||
return $this->render(
|
||||
'@ChillTask/SingleTask/index.html.twig',
|
||||
'@ChillTask/SingleTask/AccompanyingCourse/list.html.twig',
|
||||
[
|
||||
'tasks' => $tasks,
|
||||
'accompanyingCourse' => $course,
|
||||
'layout' => '@ChillPerson/AccompanyingCourse/layout.html.twig',
|
||||
'form' => $form->createView(),
|
||||
'title' => $this->translator->trans('Tasks for this accompanying period')
|
||||
'paginator' => $paginator,
|
||||
'filter_order' => $filterOrder
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -2,20 +2,32 @@
|
||||
|
||||
namespace Chill\TaskBundle\Repository;
|
||||
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\TaskBundle\Entity\SingleTask;
|
||||
use Chill\TaskBundle\Security\Authorization\TaskVoter;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepositoryInterface
|
||||
{
|
||||
private AuthorizationHelperInterface $authorizationHelper;
|
||||
private EntityManagerInterface $em;
|
||||
private Security $security;
|
||||
private CenterResolverDispatcher $centerResolverDispatcher;
|
||||
|
||||
public function __construct(EntityManagerInterface $em, Security $security)
|
||||
{
|
||||
public function __construct(
|
||||
CenterResolverDispatcher $centerResolverDispatcher,
|
||||
EntityManagerInterface $em,
|
||||
Security $security,
|
||||
AuthorizationHelperInterface $authorizationHelper
|
||||
) {
|
||||
$this->centerResolverDispatcher = $centerResolverDispatcher;
|
||||
$this->em = $em;
|
||||
$this->security = $security;
|
||||
$this->authorizationHelper = $authorizationHelper;
|
||||
}
|
||||
|
||||
public function findByCurrentUsersTasks(
|
||||
@ -26,12 +38,83 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
|
||||
?array $orderBy = []
|
||||
): array {
|
||||
$qb = $this->buildQueryMyTasks($pattern, $flags);
|
||||
|
||||
return $this->getResult($qb, $start, $limit, $orderBy);
|
||||
}
|
||||
|
||||
public function countByCurrentUsersTasks(
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
): int {
|
||||
return $this->buildQueryMyTasks($pattern, $flags)
|
||||
->select('COUNT(t)')
|
||||
->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function findByCourse(
|
||||
AccompanyingPeriod $course,
|
||||
?string $pattern = null,
|
||||
?array $flags = [],
|
||||
?int $start = 0,
|
||||
?int $limit = 50,
|
||||
?array $orderBy = []
|
||||
): array {
|
||||
$qb = $this->buildQueryByCourse($course, $pattern, $flags);
|
||||
$qb = $this->addACL($qb, $course);
|
||||
|
||||
return $this->getResult($qb, $start, $limit, $orderBy);
|
||||
}
|
||||
|
||||
public function countByCourse(
|
||||
AccompanyingPeriod $course,
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
): int {
|
||||
$qb = $this->buildQueryByCourse($course, $pattern, $flags);
|
||||
|
||||
return $this
|
||||
->addACL($qb, $course)
|
||||
->select('COUNT(t)')
|
||||
->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
public function buildQueryByCourse(
|
||||
AccompanyingPeriod $course,
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
) : QueryBuilder {
|
||||
$qb = $this->buildBaseQuery($pattern, $flags);
|
||||
|
||||
return $qb
|
||||
->andWhere($qb->expr()->eq('t.course', ':course'))
|
||||
->setParameter('course', $course)
|
||||
;
|
||||
}
|
||||
|
||||
public function buildQueryMyTasks(
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
): QueryBuilder {
|
||||
$qb = $this->buildBaseQuery($pattern, $flags);
|
||||
|
||||
return $qb
|
||||
->andWhere($qb->expr()->eq('t.assignee', ':user'))
|
||||
->setParameter('user', $this->security->getUser())
|
||||
;
|
||||
}
|
||||
|
||||
public function getResult(
|
||||
QueryBuilder $qb,
|
||||
?int $start = 0,
|
||||
?int $limit = 50,
|
||||
?array $orderBy = []
|
||||
): array {
|
||||
$qb->select('t');
|
||||
|
||||
$qb
|
||||
->setFirstResult($start)
|
||||
->setMaxResults($limit)
|
||||
;
|
||||
;
|
||||
|
||||
foreach ($orderBy as $field => $direction) {
|
||||
$qb->addOrderBy('t.'.$field, $direction);
|
||||
@ -40,25 +123,24 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function countByCurrentUsersTasks(
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
): int {
|
||||
$qb = $this->buildQueryMyTasks($pattern, $flags);
|
||||
$qb->select('COUNT(t)');
|
||||
public function addACL(
|
||||
QueryBuilder $qb,
|
||||
$entity
|
||||
): QueryBuilder {
|
||||
$scopes = $this->authorizationHelper->getReachableScopes($this->security->getUser(),
|
||||
TaskVoter::SHOW, $this->centerResolverDispatcher->resolveCenter($entity));
|
||||
|
||||
return $qb->getQuery()->getSingleScalarResult();
|
||||
return $qb->andWhere($qb->expr()->in('t.circle', ':scopes'))
|
||||
->setParameter('scopes', $scopes);
|
||||
}
|
||||
|
||||
public function buildQueryMyTasks(
|
||||
public function buildBaseQuery (
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
): QueryBuilder {
|
||||
$qb = $this->em->createQueryBuilder();
|
||||
$qb
|
||||
->from(SingleTask::class, 't')
|
||||
->where($qb->expr()->eq('t.assignee', ':user'))
|
||||
->setParameter('user', $this->security->getUser())
|
||||
;
|
||||
|
||||
if (!empty($pattern)) {
|
||||
|
@ -2,9 +2,27 @@
|
||||
|
||||
namespace Chill\TaskBundle\Repository;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
interface SingleTaskAclAwareRepositoryInterface
|
||||
{
|
||||
public function findByCurrentUsersTasks(?string $pattern = null, ?array $flags = [], ?int $start = 0, ?int $limit = 50, ?array $orderBy = []): array;
|
||||
|
||||
public function countByCurrentUsersTasks(?string $pattern = null, ?array $flags = []): int;
|
||||
|
||||
public function findByCourse(
|
||||
AccompanyingPeriod $course,
|
||||
?string $pattern = null,
|
||||
?array $flags = [],
|
||||
?int $start = 0,
|
||||
?int $limit = 50,
|
||||
?array $orderBy = []
|
||||
): array;
|
||||
|
||||
public function countByCourse(
|
||||
AccompanyingPeriod $course,
|
||||
?string $pattern = null,
|
||||
?array $flags = []
|
||||
): int;
|
||||
|
||||
}
|
||||
|
@ -1,106 +1,42 @@
|
||||
{% if tasks|length > 0 %}
|
||||
<h3>{{ title|trans }}</h3>
|
||||
{% extends '@ChillPerson/AccompanyingCourse/layout.html.twig' %}
|
||||
|
||||
<table class="table table-bordered border-dark chill-task-list">
|
||||
<tbody>
|
||||
{% for task in tasks %}
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<span class="chill-task-list__row__title">{{ task.title }}</span>
|
||||
</div>
|
||||
{% block title 'Tasks for this accompanying period'|trans %}
|
||||
|
||||
<div>
|
||||
<span class="chill-task-list__row__type">{{ task_workflow_metadata(task, 'definition.name')|trans }}</span>
|
||||
</div>
|
||||
{% block content %}
|
||||
<div class="col-md-10 col-xxl">
|
||||
|
||||
<div>
|
||||
{% for place in workflow_marked_places(task) %}
|
||||
<span class="task-status box type-{{ task.type }} place-{{ place }}">{{ place|trans }}</span>
|
||||
{% endfor %}
|
||||
{% if task.assignee is not null %}
|
||||
<div class="chill-task-list__row__assignee">
|
||||
<span class="chill_task-list__row__assignee_by">{{ 'By'|trans }} :</span>
|
||||
{{ task.assignee.username }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
{% if task.startDate is not null or task.warningDate is not null or task.endDate is not null %}
|
||||
<div class="chill-task-list__row__dates">
|
||||
<ul class="record_actions column">
|
||||
{% if task.startDate is not null %}
|
||||
<li title="{{ 'Start'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-play"></i>
|
||||
{{ task.startDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if task.warningDate is not null %}
|
||||
<li title="{{ 'Warning'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
{{ task.warningDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if task.endDate is not null %}
|
||||
<li title="{{ 'End'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-hourglass-end"></i>
|
||||
{{ task.endDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ filter_order|chill_render_filter_order_helper }}
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<ul class="record_actions">
|
||||
{% if workflow_transitions(task)|length > 0 %}
|
||||
<li>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-task-exchange dropdown-toggle" href="#" role="button" id="taskExchange" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{'Change task status'|trans}}
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="taskExchange">
|
||||
{% for transition in workflow_transitions(task) %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ path('chill_task_task_transition', { 'taskId': task.id, 'transition': transition.name, 'kind': 'single-task', 'list_params': app.request.query.all }) }}" class="{{ task_workflow_metadata(task, 'transition.class', transition)|e('html_attr') }}">
|
||||
{{ task_workflow_metadata(task, 'transition.verb', transition)|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if tasks|length == 0 %}
|
||||
<p class="chill-no-data-statement">{{ 'Any tasks'|trans }}</p>
|
||||
{% else %}
|
||||
<div class="flex-table chill-task-list">
|
||||
{% for task in tasks %}
|
||||
{% include 'ChillTaskBundle:SingleTask/List:index_item.html.twig' with { 'showContext' : false } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<li>
|
||||
<a href="{{ path('chill_task_single_task_show', { 'id': task.id, 'list_params': app.request.query.all }) }}" class="btn btn-show "></a>
|
||||
</li>
|
||||
{{ chill_pagination(paginator) }}
|
||||
|
||||
{# {% if is_granted('CHILL_TASK_TASK_UPDATE', task) %} #}
|
||||
<li>
|
||||
<a href="{{ path('chill_task_single_task_edit', { 'id': task.id, 'list_params': app.request.query.all }) }}" class="btn btn-update "></a>
|
||||
</li>
|
||||
{# {% endif %} #}
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
{% if accompanyingCourse is not null %}
|
||||
<a href="{{ path('chill_task_single_task_new', {'course_id': accompanyingCourse.id}) }}" class="btn btn-create">
|
||||
{{ 'Create' | trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{# {% if is_granted('CHILL_TASK_TASK_DELETE', task) %} #}
|
||||
<li>
|
||||
<a href="{{ path('chill_task_single_task_delete', { 'id': task.id, 'list_params': app.request.query.all } ) }}" class="btn btn-delete "></a>
|
||||
</li>
|
||||
{# {% endif %} #}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
{% if accompanyingCourse is not null %}
|
||||
<a href="{{ path('chill_task_single_task_new', {'course_id': accompanyingCourse.id}) }}" class="btn btn-create">
|
||||
{{ 'Create' | trans }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
{% block css %}
|
||||
{{ encore_entry_link_tags('page_task_list') }}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('page_task_list') }}
|
||||
{% endblock %}
|
||||
|
@ -14,130 +14,7 @@
|
||||
{% else %}
|
||||
<div class="flex-table chill-task-list">
|
||||
{% for task in tasks %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<div class="denomination h2">
|
||||
{{ task.title }}
|
||||
{% for place in workflow_marked_places(task) %}
|
||||
<span class="task-status badge type-{{ task.type }} place-{{ place }}">
|
||||
{{ place|trans }}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if task.type != 'task_default'%}
|
||||
<span class="task-type">
|
||||
{{ task_workflow_metadata(task, 'definition.name')|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
<div>
|
||||
{% if task.person is not null %}
|
||||
<span class="chill-task-list__row__person">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
targetEntity: { name: 'person', id: task.person.id },
|
||||
action: 'show',
|
||||
displayBadge: true,
|
||||
buttonText: task.person|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
{% elseif task.course is not null %}
|
||||
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': task.course.id }) }}"
|
||||
class="btn btn-sm btn-outline-primary" title="{{ 'See accompanying period'|trans }}">
|
||||
<i class="fa fa-random fa-fw"></i>
|
||||
</a>
|
||||
|
||||
{% for part in task.course.currentParticipations %}
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
targetEntity: { name: 'person', id: part.person.id },
|
||||
action: 'show',
|
||||
displayBadge: true,
|
||||
buttonText: part.person|chill_entity_render_string
|
||||
} %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="item-col">
|
||||
<div class="container">
|
||||
{% if task.assignee is not null %}
|
||||
<div class="assignee row">
|
||||
<span class="chill_task-list__row__assignee_by">{{ 'By'|trans }} :</span>
|
||||
<span>{{ task.assignee.username }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.startDate is not null or task.warningDate is not null or task.endDate is not null %}
|
||||
<div class="dates row">
|
||||
<ul class="column">
|
||||
{% if task.startDate is not null %}
|
||||
<li title="{{ 'Start'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-play"></i>
|
||||
{{ task.startDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if task.warningDate is not null %}
|
||||
<li title="{{ 'Warning'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
{{ task.warningDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if task.endDate is not null %}
|
||||
<li title="{{ 'End'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-hourglass-end"></i>
|
||||
{{ task.endDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="item-row separator">
|
||||
<ul class="record_actions">
|
||||
{% if workflow_transitions(task)|length > 0 %}
|
||||
<li>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-task-exchange dropdown-toggle" href="#" role="button" id="taskExchange" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{'Change task status'|trans}}
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="taskExchange">
|
||||
{% for transition in workflow_transitions(task) %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ path('chill_task_task_transition', { 'taskId': task.id, 'transition': transition.name, 'kind': 'single-task', 'list_params': app.request.query.all }) }}" class="{{ task_workflow_metadata(task, 'transition.class', transition)|e('html_attr') }}">
|
||||
{{ task_workflow_metadata(task, 'transition.verb', transition)|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_task_single_task_show', { 'id': task.id }) }}" class="btn btn-show "></a>
|
||||
</li>
|
||||
|
||||
{% if is_granted('CHILL_TASK_TASK_UPDATE', task) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_task_single_task_edit', { 'id': task.id }) }}" class="btn btn-update "></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('CHILL_TASK_TASK_DELETE', task) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_task_single_task_delete', { 'id': task.id } ) }}" class="btn btn-delete "></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% include 'ChillTaskBundle:SingleTask/List:index_item.html.twig' with { 'showContext' : true} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -0,0 +1,125 @@
|
||||
<div class="item-bloc">
|
||||
<div class="item-row">
|
||||
<div class="item-col">
|
||||
<div class="denomination h2">
|
||||
{{ task.title }}
|
||||
{% for place in workflow_marked_places(task) %}
|
||||
<span class="task-status badge type-{{ task.type }} place-{{ place }}">
|
||||
{{ place|trans }}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if task.type != 'task_default'%}
|
||||
<span class="task-type">
|
||||
{{ task_workflow_metadata(task, 'definition.name')|trans }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if showContext %}
|
||||
<div>
|
||||
{% if task.person is not null %}
|
||||
<span class="chill-task-list__row__person">
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
targetEntity: { name: 'person', id: task.person.id },
|
||||
action: 'show',
|
||||
displayBadge: true,
|
||||
buttonText: task.person|chill_entity_render_string
|
||||
} %}
|
||||
</span>
|
||||
{% elseif task.course is not null %}
|
||||
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': task.course.id }) }}"
|
||||
class="btn btn-sm btn-outline-primary" title="{{ 'See accompanying period'|trans }}">
|
||||
<i class="fa fa-random fa-fw"></i>
|
||||
</a>
|
||||
|
||||
{% for part in task.course.currentParticipations %}
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
targetEntity: { name: 'person', id: part.person.id },
|
||||
action: 'show',
|
||||
displayBadge: true,
|
||||
buttonText: part.person|chill_entity_render_string
|
||||
} %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="item-col">
|
||||
<div class="container">
|
||||
{% if task.assignee is not null %}
|
||||
<div class="assignee row">
|
||||
<span>{{ task.assignee|chill_entity_render_box }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.startDate is not null or task.warningDate is not null or task.endDate is not null %}
|
||||
<div class="dates row">
|
||||
<ul class="column">
|
||||
{% if task.startDate is not null %}
|
||||
<li title="{{ 'Start'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-play"></i>
|
||||
{{ task.startDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if task.warningDate is not null %}
|
||||
<li title="{{ 'Warning'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-exclamation-triangle"></i>
|
||||
{{ task.warningDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if task.endDate is not null %}
|
||||
<li title="{{ 'End'|trans|escape('html_attr') }}">
|
||||
<i class="fa fa-hourglass-end"></i>
|
||||
{{ task.endDate|format_date('medium') }}
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="item-row separator">
|
||||
<ul class="record_actions">
|
||||
{% if workflow_transitions(task)|length > 0 %}
|
||||
<li>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-task-exchange dropdown-toggle" href="#" role="button" id="taskExchange" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{'Change task status'|trans}}
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="taskExchange">
|
||||
{% for transition in workflow_transitions(task) %}
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ path('chill_task_task_transition', { 'taskId': task.id, 'transition': transition.name, 'kind': 'single-task', 'list_params': app.request.query.all }) }}" class="{{ task_workflow_metadata(task, 'transition.class', transition)|e('html_attr') }}">
|
||||
{{ task_workflow_metadata(task, 'transition.verb', transition)|trans }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_task_single_task_show', { 'id': task.id }) }}" class="btn btn-show "></a>
|
||||
</li>
|
||||
|
||||
{% if is_granted('CHILL_TASK_TASK_UPDATE', task) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_task_single_task_edit', { 'id': task.id }) }}" class="btn btn-update "></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('CHILL_TASK_TASK_DELETE', task) %}
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_task_single_task_delete', { 'id': task.id } ) }}" class="btn btn-delete "></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user