diff --git a/Controller/SingleTaskController.php b/Controller/SingleTaskController.php
index 8456e0e5b..f163b57d0 100644
--- a/Controller/SingleTaskController.php
+++ b/Controller/SingleTaskController.php
@@ -75,7 +75,7 @@ class SingleTaskController extends Controller
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($task);
-
+
$dispatcher->dispatch(TaskEvent::PERSIST, new TaskEvent($task));
$em->flush();
@@ -133,8 +133,12 @@ class SingleTaskController extends Controller
throw $this->createNotFoundException('Unable to find Task entity.');
}
+ $timeline = $this->get('chill.main.timeline_builder')
+ ->getTimelineHTML('task', array('task' => $task));
+
return $this->render('ChillTaskBundle:SingleTask:show.html.twig', array(
'task' => $task,
+ 'timeline' => $timeline
));
}
@@ -146,8 +150,8 @@ class SingleTaskController extends Controller
* )
*/
public function editAction(
- Request $request,
- $id,
+ Request $request,
+ $id,
TranslatorInterface $translator
) {
/* @var $taskRepository SingleTaskRepository */
@@ -213,7 +217,7 @@ class SingleTaskController extends Controller
* )
*/
public function deleteAction(
- Request $request,
+ Request $request,
$id,
TranslatorInterface $translator
) {
@@ -221,7 +225,7 @@ class SingleTaskController extends Controller
$taskRepository = $this->get('chill_task.single_task_repository');
$task = $taskRepository->find($id);
-
+
if (!$task) {
throw $this->createNotFoundException('Unable to find Task entity.');
}
@@ -321,18 +325,18 @@ class SingleTaskController extends Controller
}
/**
- *
+ *
* Arguments:
* - user_id
* - scope_id
* - person_id
* - hide_form (hide the form to filter the tasks)
* - status: date state, amongst SingleTaskRepository::DATE_STATUSES, or 'closed'
- *
+ *
* @Route(
* "/{_locale}/task/singletask/list",
* name="chill_task_singletask_list",
- * options={ "menus": {
+ * options={ "menus": {
* "person" : { "order": 400, "label": "Associated tasks" } ,
* "section": { "order": 400, "label": "Tasks", "icons": "tasks" }
* }}
@@ -354,7 +358,7 @@ class SingleTaskController extends Controller
$params['user'] = null;
$viewParams['center'] = null;
$params['center'] = null;
-
+
// Get parameters from url
if (!empty($request->query->get('person_id', NULL))) {
$personId = $request->query->getInt('person_id');
@@ -469,7 +473,7 @@ class SingleTaskController extends Controller
$form->handleRequest($request);
- return $this->render('ChillTaskBundle:SingleTask:index.html.twig',
+ return $this->render('ChillTaskBundle:SingleTask:index.html.twig',
\array_merge($viewParams, [ 'form' => $form->createView() ]));
}
diff --git a/Resources/config/services/timeline.yml b/Resources/config/services/timeline.yml
index 50187f14b..4903dc2cb 100644
--- a/Resources/config/services/timeline.yml
+++ b/Resources/config/services/timeline.yml
@@ -5,4 +5,9 @@ services:
$registry: '@Symfony\Component\Workflow\Registry'
tags:
- { name: 'chill.timeline', context: 'person' }
-
\ No newline at end of file
+ Chill\TaskBundle\Timeline\SingleTaskTaskLifeCycleEventTimelineProvider:
+ arguments:
+ $em: '@Doctrine\ORM\EntityManagerInterface'
+ $registry: '@Symfony\Component\Workflow\Registry'
+ tags:
+ - { name: 'chill.timeline', context: 'task' }
diff --git a/Resources/views/SingleTask/show.html.twig b/Resources/views/SingleTask/show.html.twig
index 11667a4e9..805c01887 100644
--- a/Resources/views/SingleTask/show.html.twig
+++ b/Resources/views/SingleTask/show.html.twig
@@ -81,6 +81,11 @@
{% endif %}
+ {% if timeline is not null %}
+
{{"Timeline"|trans}}
+ {{ timeline|raw }}
+ {% endif %}
+
-
{% endblock %}
diff --git a/Resources/views/Timeline/single_task_transition_task_context.html.twig b/Resources/views/Timeline/single_task_transition_task_context.html.twig
new file mode 100644
index 000000000..57b48aa16
--- /dev/null
+++ b/Resources/views/Timeline/single_task_transition_task_context.html.twig
@@ -0,0 +1,13 @@
+
+
+ {{ event.datetime|localizeddate('long', 'short') }}
+ / {{ 'Task'|trans }} /
+ {% if transition is not null %}
+ {{ task_workflow_metadata(event.task, 'transition.sentence', transition)|trans({ '%user%': event.author.username }) }}
+ "{{ event.task.title }}"
+ {% else %}
+ {{ '%user% has created the task'|trans({ '%user%': event.author.username }) }}
+ "{{ event.task.title }}"
+ {% endif %}
+
+
diff --git a/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php b/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php
new file mode 100644
index 000000000..4f107f1cd
--- /dev/null
+++ b/Timeline/SingleTaskTaskLifeCycleEventTimelineProvider.php
@@ -0,0 +1,132 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+namespace Chill\TaskBundle\Timeline;
+
+use Chill\MainBundle\Timeline\TimelineProviderInterface;
+use Doctrine\ORM\EntityManagerInterface;
+use Chill\TaskBundle\Entity\Task\SingleTaskPlaceEvent;
+use Chill\TaskBundle\Entity\SingleTask;
+use Symfony\Component\Workflow\Registry;
+use Symfony\Component\Workflow\Workflow;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class SingleTaskTaskLifeCycleEventTimelineProvider implements TimelineProviderInterface
+{
+ /**
+ *
+ * @var EntityManagerInterface
+ */
+ protected $em;
+
+ /**
+ *
+ * @var Registry
+ */
+ protected $registry;
+
+ const TYPE = 'chill_task.transition';
+
+ public function __construct(EntityManagerInterface $em, Registry $registry)
+ {
+ $this->em = $em;
+ $this->registry = $registry;
+ }
+
+ public function fetchQuery($context, $args)
+ {
+ if ($context !== 'task') {
+ throw new \LogicException(sprintf('%s is not able '
+ . 'to render context %s', self::class, $context));
+ }
+
+ $metadata = $this->em
+ ->getClassMetadata(SingleTaskPlaceEvent::class);
+ $singleTaskMetadata = $this->em
+ ->getClassMetadata(SingleTask::class);
+
+ return [
+ 'id' => sprintf('%s.%s.%s', $metadata->getSchemaName(), $metadata->getTableName(), $metadata->getColumnName('id')),
+ 'type' => self::TYPE,
+ 'date' => $metadata->getColumnName('datetime'),
+ 'FROM' => sprintf('%s JOIN %s ON %s = %s',
+ sprintf('%s.%s', $metadata->getSchemaName(), $metadata->getTableName()),
+ sprintf('%s.%s', $singleTaskMetadata->getSchemaName(), $singleTaskMetadata->getTableName()),
+ $metadata->getAssociationMapping('task')['joinColumns'][0]['name'],
+ sprintf('%s.%s.%s', $singleTaskMetadata->getSchemaName(), $singleTaskMetadata->getTableName(), $singleTaskMetadata->getColumnName('id'))
+ ),
+ 'WHERE' => sprintf('%s.%s = %d',
+ sprintf('%s.%s', $singleTaskMetadata->getSchemaName(), $singleTaskMetadata->getTableName()),
+ $singleTaskMetadata->getColumnName('id'),
+ $args['task']->getId()
+ )
+ ];
+
+ }
+
+ public function getEntities(array $ids)
+ {
+ $events = $this->em
+ ->getRepository(SingleTaskPlaceEvent::class)
+ ->findBy([ 'id' => $ids ])
+ ;
+
+ return \array_combine(
+ \array_map(function($e) { return $e->getId(); }, $events ),
+ $events
+ );
+ }
+
+ public function getEntityTemplate($entity, $context, array $args)
+ {
+ $workflow = $this->registry->get($entity->getTask(), $entity->getData['workflow']);
+ $transition = $this->getTransitionByName($entity->getTransition(), $workflow);
+
+ return [
+ 'template' => 'ChillTaskBundle:Timeline:single_task_transition_task_context.html.twig',
+ 'template_data' => [
+ 'task' => $args['task'],
+ 'event' => $entity,
+ 'transition' => $transition
+ ]
+ ];
+ }
+
+ /**
+ *
+ * @param string $name
+ * @param Workflow $workflow
+ * @return \Symfony\Component\Workflow\Transition
+ */
+ protected function getTransitionByName($name, Workflow $workflow)
+ {
+ foreach ($workflow->getDefinition()->getTransitions() as $transition) {
+ if ($transition->getName() === $name) {
+ return $transition;
+ }
+ }
+ }
+
+ public function supportsType($type): bool
+ {
+ return $type === self::TYPE;
+ }
+}