summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Task.php15
-rw-r--r--app/Locale/da_DK/translations.php3
-rw-r--r--app/Locale/de_DE/translations.php3
-rw-r--r--app/Locale/es_ES/translations.php3
-rw-r--r--app/Locale/fi_FI/translations.php3
-rw-r--r--app/Locale/fr_FR/translations.php3
-rw-r--r--app/Locale/hu_HU/translations.php3
-rw-r--r--app/Locale/it_IT/translations.php3
-rw-r--r--app/Locale/ja_JP/translations.php3
-rw-r--r--app/Locale/nl_NL/translations.php3
-rw-r--r--app/Locale/pl_PL/translations.php3
-rw-r--r--app/Locale/pt_BR/translations.php3
-rw-r--r--app/Locale/ru_RU/translations.php3
-rw-r--r--app/Locale/sr_Latn_RS/translations.php3
-rw-r--r--app/Locale/sv_SE/translations.php3
-rw-r--r--app/Locale/th_TH/translations.php3
-rw-r--r--app/Locale/tr_TR/translations.php3
-rw-r--r--app/Locale/zh_CN/translations.php3
-rw-r--r--app/Model/TaskPosition.php3
-rw-r--r--app/Model/Transition.php67
-rw-r--r--app/Schema/Mysql.php26
-rw-r--r--app/Schema/Postgres.php25
-rw-r--r--app/Schema/Sqlite.php25
-rw-r--r--app/ServiceProvider/ClassProvider.php1
-rw-r--r--app/ServiceProvider/EventDispatcherProvider.php2
-rw-r--r--app/Subscriber/TransitionSubscriber.php26
-rw-r--r--app/Template/task/sidebar.php3
-rw-r--r--app/Template/task/transitions.php26
28 files changed, 267 insertions, 3 deletions
diff --git a/app/Controller/Task.php b/app/Controller/Task.php
index ace40a01..64017582 100644
--- a/app/Controller/Task.php
+++ b/app/Controller/Task.php
@@ -526,4 +526,19 @@ class Task extends Base
'subtask_paginator' => $subtask_paginator,
)));
}
+
+ /**
+ * Display the task transitions
+ *
+ * @access public
+ */
+ public function transitions()
+ {
+ $task = $this->getTask();
+
+ $this->response->html($this->taskLayout('task/transitions', array(
+ 'task' => $task,
+ 'transitions' => $this->transition->getAllByTask($task['id']),
+ )));
+ }
}
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index f9fe1bab..8263cbb9 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index 9898e7f3..6202cd1b 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 0f576376..edd49a33 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index a5c76cd1..9a62bf54 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index 7a88669c..6baca123 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -811,4 +811,7 @@ return array(
'Move the task to another column when assignee is cleared' => 'Déplacer la tâche dans une autre colonne lorsque celle-ci n\'est plus assignée',
'Source column' => 'Colonne d\'origine',
'Show subtask estimates in the user calendar' => 'Afficher le temps estimé des sous-tâches dans le calendrier utilisateur',
+ 'Transitions' => 'Transitions',
+ 'Executer' => 'Exécutant',
+ 'Time spent in the column' => 'Temps passé dans la colonne',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index c6bf929f..42252f2b 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -809,4 +809,7 @@ return array(
'Move the task to another column when assignee is cleared' => 'Feladat másik oszlopba helyezése felhasználóhoz rendélés törlésekor',
'Source column' => 'Forrás oszlop',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index 08444549..33072967 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index aa6c51f0..cbc40254 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index 1a22bc30..bf6c3665 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 983b42a8..da4bd8ac 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index 79856921..dae703ea 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 181b035c..bd26ea53 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 0f7df233..bfd9352d 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index 4da013bb..31c5bf91 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index c478c9ba..228b5e3c 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index 93638f89..9d7cfdd2 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index aa679327..8859cd17 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -809,4 +809,7 @@ return array(
// 'Move the task to another column when assignee is cleared' => '',
// 'Source column' => '',
// 'Show subtask estimates in the user calendar' => '',
+ // 'Transitions' => '',
+ // 'Executer' => '',
+ // 'Time spent in the column' => '',
);
diff --git a/app/Model/TaskPosition.php b/app/Model/TaskPosition.php
index 6dd10b02..ab5fe43b 100644
--- a/app/Model/TaskPosition.php
+++ b/app/Model/TaskPosition.php
@@ -143,6 +143,9 @@ class TaskPosition extends Base
'position' => $new_position,
'column_id' => $new_column_id,
'swimlane_id' => $new_swimlane_id,
+ 'src_column_id' => $task['column_id'],
+ 'dst_column_id' => $new_column_id,
+ 'date_moved' => $task['date_moved'],
);
if ($task['swimlane_id'] != $new_swimlane_id) {
diff --git a/app/Model/Transition.php b/app/Model/Transition.php
new file mode 100644
index 00000000..583d3aca
--- /dev/null
+++ b/app/Model/Transition.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Model;
+
+/**
+ * Transition model
+ *
+ * @package model
+ * @author Frederic Guillot
+ */
+class Transition extends Base
+{
+ /**
+ * SQL table name
+ *
+ * @var string
+ */
+ const TABLE = 'transitions';
+
+ /**
+ * Save transition event
+ *
+ * @access public
+ * @param integer $user_id
+ * @param array $task
+ * @return boolean
+ */
+ public function save($user_id, array $task)
+ {
+ return $this->db->table(self::TABLE)->insert(array(
+ 'user_id' => $user_id,
+ 'project_id' => $task['project_id'],
+ 'task_id' => $task['task_id'],
+ 'src_column_id' => $task['src_column_id'],
+ 'dst_column_id' => $task['dst_column_id'],
+ 'date' => time(),
+ 'time_spent' => time() - $task['date_moved']
+ ));
+ }
+
+ /**
+ * Get all transitions by task
+ *
+ * @access public
+ * @param integer $task_id
+ * @return array
+ */
+ public function getAllByTask($task_id)
+ {
+ return $this->db->table(self::TABLE)
+ ->columns(
+ 'src.title as src_column',
+ 'dst.title as dst_column',
+ User::TABLE.'.name',
+ User::TABLE.'.username',
+ self::TABLE.'.user_id',
+ self::TABLE.'.date',
+ self::TABLE.'.time_spent'
+ )
+ ->eq('task_id', $task_id)
+ ->desc('date')
+ ->join(User::TABLE, 'id', 'user_id')
+ ->join(Board::TABLE.' as src', 'id', 'src_column_id', self::TABLE, 'src')
+ ->join(Board::TABLE.' as dst', 'id', 'dst_column_id', self::TABLE, 'dst')
+ ->findAll();
+ }
+}
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 3669a647..30fccbfa 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -6,7 +6,31 @@ use PDO;
use Core\Security;
use Model\Link;
-const VERSION = 55;
+const VERSION = 56;
+
+function version_56($pdo)
+{
+ $pdo->exec('CREATE TABLE transitions (
+ `id` INT NOT NULL AUTO_INCREMENT,
+ `user_id` INT NOT NULL,
+ `project_id` INT NOT NULL,
+ `task_id` INT NOT NULL,
+ `src_column_id` INT NOT NULL,
+ `dst_column_id` INT NOT NULL,
+ `date` INT NOT NULL,
+ `time_spent` INT DEFAULT 0,
+ FOREIGN KEY(src_column_id) REFERENCES columns(id) ON DELETE CASCADE,
+ FOREIGN KEY(dst_column_id) REFERENCES columns(id) ON DELETE CASCADE,
+ FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
+ FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
+ FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE,
+ PRIMARY KEY(id)
+ ) ENGINE=InnoDB CHARSET=utf8');
+
+ $pdo->exec("CREATE INDEX transitions_task_index ON transitions(task_id)");
+ $pdo->exec("CREATE INDEX transitions_project_index ON transitions(project_id)");
+ $pdo->exec("CREATE INDEX transitions_user_index ON transitions(user_id)");
+}
function version_55($pdo)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index b60e441b..ecf8664d 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -6,7 +6,30 @@ use PDO;
use Core\Security;
use Model\Link;
-const VERSION = 36;
+const VERSION = 37;
+
+function version_37($pdo)
+{
+ $pdo->exec('CREATE TABLE transitions (
+ "id" SERIAL PRIMARY KEY,
+ "user_id" INTEGER NOT NULL,
+ "project_id" INTEGER NOT NULL,
+ "task_id" INTEGER NOT NULL,
+ "src_column_id" INTEGER NOT NULL,
+ "dst_column_id" INTEGER NOT NULL,
+ "date" INTEGER NOT NULL,
+ "time_spent" INTEGER DEFAULT 0,
+ FOREIGN KEY(src_column_id) REFERENCES columns(id) ON DELETE CASCADE,
+ FOREIGN KEY(dst_column_id) REFERENCES columns(id) ON DELETE CASCADE,
+ FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
+ FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
+ FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE
+ )');
+
+ $pdo->exec("CREATE INDEX transitions_task_index ON transitions(task_id)");
+ $pdo->exec("CREATE INDEX transitions_project_index ON transitions(project_id)");
+ $pdo->exec("CREATE INDEX transitions_user_index ON transitions(user_id)");
+}
function version_36($pdo)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index 34ac2c6f..19af5dd3 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -6,7 +6,30 @@ use Core\Security;
use PDO;
use Model\Link;
-const VERSION = 54;
+const VERSION = 55;
+
+function version_55($pdo)
+{
+ $pdo->exec('CREATE TABLE transitions (
+ "id" INTEGER PRIMARY KEY,
+ "user_id" INTEGER NOT NULL,
+ "project_id" INTEGER NOT NULL,
+ "task_id" INTEGER NOT NULL,
+ "src_column_id" INTEGER NOT NULL,
+ "dst_column_id" INTEGER NOT NULL,
+ "date" INTEGER NOT NULL,
+ "time_spent" INTEGER DEFAULT 0,
+ FOREIGN KEY(src_column_id) REFERENCES columns(id) ON DELETE CASCADE,
+ FOREIGN KEY(dst_column_id) REFERENCES columns(id) ON DELETE CASCADE,
+ FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
+ FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
+ FOREIGN KEY(task_id) REFERENCES tasks(id) ON DELETE CASCADE
+ )');
+
+ $pdo->exec("CREATE INDEX transitions_task_index ON transitions(task_id)");
+ $pdo->exec("CREATE INDEX transitions_project_index ON transitions(project_id)");
+ $pdo->exec("CREATE INDEX transitions_user_index ON transitions(user_id)");
+}
function version_54($pdo)
{
diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php
index 2373ab01..c25ceb62 100644
--- a/app/ServiceProvider/ClassProvider.php
+++ b/app/ServiceProvider/ClassProvider.php
@@ -56,6 +56,7 @@ class ClassProvider implements ServiceProviderInterface
'TimetableWeek',
'TimetableOff',
'TimetableExtra',
+ 'Transition',
'User',
'UserSession',
'Webhook',
diff --git a/app/ServiceProvider/EventDispatcherProvider.php b/app/ServiceProvider/EventDispatcherProvider.php
index ec382206..f002db74 100644
--- a/app/ServiceProvider/EventDispatcherProvider.php
+++ b/app/ServiceProvider/EventDispatcherProvider.php
@@ -14,6 +14,7 @@ use Subscriber\ProjectModificationDateSubscriber;
use Subscriber\WebhookSubscriber;
use Subscriber\SubtaskTimesheetSubscriber;
use Subscriber\TaskMovedDateSubscriber;
+use Subscriber\TransitionSubscriber;
class EventDispatcherProvider implements ServiceProviderInterface
{
@@ -29,6 +30,7 @@ class EventDispatcherProvider implements ServiceProviderInterface
$container['dispatcher']->addSubscriber(new NotificationSubscriber($container));
$container['dispatcher']->addSubscriber(new SubtaskTimesheetSubscriber($container));
$container['dispatcher']->addSubscriber(new TaskMovedDateSubscriber($container));
+ $container['dispatcher']->addSubscriber(new TransitionSubscriber($container));
// Automatic actions
$container['action']->attachEvents();
diff --git a/app/Subscriber/TransitionSubscriber.php b/app/Subscriber/TransitionSubscriber.php
new file mode 100644
index 00000000..347dd37d
--- /dev/null
+++ b/app/Subscriber/TransitionSubscriber.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Subscriber;
+
+use Event\TaskEvent;
+use Model\Task;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class TransitionSubscriber extends Base implements EventSubscriberInterface
+{
+ public static function getSubscribedEvents()
+ {
+ return array(
+ Task::EVENT_MOVE_COLUMN => array('execute', 0),
+ );
+ }
+
+ public function execute(TaskEvent $event)
+ {
+ $user_id = $this->userSession->getId();
+
+ if (! empty($user_id)) {
+ $this->transition->save($user_id, $event->getAll());
+ }
+ }
+} \ No newline at end of file
diff --git a/app/Template/task/sidebar.php b/app/Template/task/sidebar.php
index f41be14d..cb3b3c69 100644
--- a/app/Template/task/sidebar.php
+++ b/app/Template/task/sidebar.php
@@ -4,6 +4,9 @@
<li>
<?= $this->a(t('Summary'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
+ <li>
+ <?= $this->a(t('Transitions'), 'task', 'transitions', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ </li>
<?php if ($task['time_estimated'] > 0 || $task['time_spent'] > 0): ?>
<li>
<?= $this->a(t('Time tracking'), 'task', 'timesheet', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
diff --git a/app/Template/task/transitions.php b/app/Template/task/transitions.php
new file mode 100644
index 00000000..2f45eb39
--- /dev/null
+++ b/app/Template/task/transitions.php
@@ -0,0 +1,26 @@
+<div class="page-header">
+ <h2><?= t('Transitions') ?></h2>
+</div>
+
+<?php if (empty($transitions)): ?>
+ <p class="alert"><?= t('There is nothing to show.') ?></p>
+<?php else: ?>
+ <table class="table-stripped">
+ <tr>
+ <th><?= t('Date') ?></th>
+ <th><?= t('Source column') ?></th>
+ <th><?= t('Destination column') ?></th>
+ <th><?= t('Executer') ?></th>
+ <th><?= t('Time spent in the column') ?></th>
+ </tr>
+ <?php foreach ($transitions as $transition): ?>
+ <tr>
+ <td><?= dt('%B %e, %Y at %k:%M %p', $transition['date']) ?></td>
+ <td><?= $this->e($transition['src_column']) ?></td>
+ <td><?= $this->e($transition['dst_column']) ?></td>
+ <td><?= $this->a($this->e($transition['name'] ?: $transition['username']), 'user', 'show', array('user_id' => $transition['user_id'])) ?></td>
+ <td><?= n(round($transition['time_spent'] / 3600, 2)).' '.t('hours') ?></td>
+ </tr>
+ <?php endforeach ?>
+ </table>
+<?php endif ?> \ No newline at end of file