summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-06-14 11:50:31 -0400
committerFrederic Guillot <fred@kanboard.net>2015-06-14 11:50:31 -0400
commit9b399951f430b26379a2bf8b13ace99290227e61 (patch)
tree4dd694985dc9f27782ad365d376dc5a37f1e987e
parenta785810f2d11ad14ab3497a51ca10a6780b758ad (diff)
Improve activity stream/notification for task update events and add new notification for swimlane change
-rw-r--r--app/Helper/Task.php5
-rw-r--r--app/Model/Notification.php11
-rw-r--r--app/Model/ProjectActivity.php5
-rw-r--r--app/Model/TaskFinder.php2
-rw-r--r--app/Subscriber/NotificationSubscriber.php1
-rw-r--r--app/Subscriber/ProjectActivitySubscriber.php2
-rw-r--r--app/Template/event/events.php2
-rw-r--r--app/Template/event/task_move_swimlane.php19
-rw-r--r--app/Template/event/task_update.php5
-rw-r--r--app/Template/notification/task_move_swimlane.php19
-rw-r--r--app/Template/notification/task_update.php63
-rw-r--r--app/Template/task/changes.php78
-rw-r--r--assets/css/app.css13
-rw-r--r--assets/css/src/activity.css11
-rw-r--r--assets/css/src/form.css1
-rw-r--r--tests/units/NotificationTest.php2
16 files changed, 168 insertions, 71 deletions
diff --git a/app/Helper/Task.php b/app/Helper/Task.php
index b3931cdb..13bdb07a 100644
--- a/app/Helper/Task.php
+++ b/app/Helper/Task.php
@@ -37,6 +37,11 @@ class Task extends \Core\Base
return t('%dd', ($now - $timestamp) / 86400);
}
+ public function getColors()
+ {
+ return $this->color->getList();
+ }
+
public function recurrenceTriggers()
{
return $this->task->getRecurrenceTriggerList();
diff --git a/app/Model/Notification.php b/app/Model/Notification.php
index 1ef6a88f..d18e7642 100644
--- a/app/Model/Notification.php
+++ b/app/Model/Notification.php
@@ -268,7 +268,7 @@ class Notification extends Base
{
return $this->template->render(
'notification/'.str_replace('.', '_', $event_name),
- $event_data + array('application_url' => $this->config->get('application_url'), 'colors_list' => $this->color->getList())
+ $event_data + array('application_url' => $this->config->get('application_url'))
);
}
@@ -311,13 +311,16 @@ class Notification extends Base
$subject = $this->getStandardMailSubject(e('Task opened'), $event_data);
break;
case Task::EVENT_MOVE_COLUMN:
- $subject = $this->getStandardMailSubject(e('Column Change'), $event_data);
+ $subject = $this->getStandardMailSubject(e('Column change'), $event_data);
break;
case Task::EVENT_MOVE_POSITION:
- $subject = $this->getStandardMailSubject(e('Position Change'), $event_data);
+ $subject = $this->getStandardMailSubject(e('Position change'), $event_data);
+ break;
+ case Task::EVENT_MOVE_SWIMLANE:
+ $subject = $this->getStandardMailSubject(e('Swimlane change'), $event_data);
break;
case Task::EVENT_ASSIGNEE_CHANGE:
- $subject = $this->getStandardMailSubject(e('Assignee Change'), $event_data);
+ $subject = $this->getStandardMailSubject(e('Assignee change'), $event_data);
break;
case Task::EVENT_OVERDUE:
$subject = e('[%s] Overdue tasks', $event_data['project_name']);
diff --git a/app/Model/ProjectActivity.php b/app/Model/ProjectActivity.php
index 27f1cfcd..a9222fcc 100644
--- a/app/Model/ProjectActivity.php
+++ b/app/Model/ProjectActivity.php
@@ -227,6 +227,11 @@ class ProjectActivity extends Base
return t('%s moved the task #%d to the column "%s"', $event['author'], $event['task']['id'], $event['task']['column_title']);
case Task::EVENT_MOVE_POSITION:
return t('%s moved the task #%d to the position %d in the column "%s"', $event['author'], $event['task']['id'], $event['task']['position'], $event['task']['column_title']);
+ case Task::EVENT_MOVE_SWIMLANE:
+ if ($event['task']['swimlane_id'] == 0) {
+ return t('%s moved the task #%d to the first swimlane', $event['author'], $event['task']['id']);
+ }
+ return t('%s moved the task #%d to the swimlane "%s"', $event['author'], $event['task']['id'], $event['task']['swimlane_name']);
case Subtask::EVENT_UPDATE:
return t('%s updated a subtask for the task #%d', $event['author'], $event['task']['id']);
case Subtask::EVENT_CREATE:
diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php
index 5a1d33c6..327b480f 100644
--- a/app/Model/TaskFinder.php
+++ b/app/Model/TaskFinder.php
@@ -263,6 +263,7 @@ class TaskFinder extends Base
tasks.recurrence_parent,
tasks.recurrence_child,
project_has_categories.name AS category_name,
+ swimlanes.name AS swimlane_name,
projects.name AS project_name,
columns.title AS column_title,
users.username AS assignee_username,
@@ -275,6 +276,7 @@ class TaskFinder extends Base
LEFT JOIN project_has_categories ON project_has_categories.id = tasks.category_id
LEFT JOIN projects ON projects.id = tasks.project_id
LEFT JOIN columns ON columns.id = tasks.column_id
+ LEFT JOIN swimlanes ON swimlanes.id = tasks.swimlane_id
WHERE tasks.id = ?
';
diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php
index d605c9f3..b99c2945 100644
--- a/app/Subscriber/NotificationSubscriber.php
+++ b/app/Subscriber/NotificationSubscriber.php
@@ -20,6 +20,7 @@ class NotificationSubscriber extends \Core\Base implements EventSubscriberInterf
Task::EVENT_OPEN => array('execute', 0),
Task::EVENT_MOVE_COLUMN => array('execute', 0),
Task::EVENT_MOVE_POSITION => array('execute', 0),
+ Task::EVENT_MOVE_SWIMLANE => array('execute', 0),
Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0),
Subtask::EVENT_CREATE => array('execute', 0),
Subtask::EVENT_UPDATE => array('execute', 0),
diff --git a/app/Subscriber/ProjectActivitySubscriber.php b/app/Subscriber/ProjectActivitySubscriber.php
index 31f771f8..82b13d8e 100644
--- a/app/Subscriber/ProjectActivitySubscriber.php
+++ b/app/Subscriber/ProjectActivitySubscriber.php
@@ -20,6 +20,7 @@ class ProjectActivitySubscriber extends \Core\Base implements EventSubscriberInt
Task::EVENT_OPEN => array('execute', 0),
Task::EVENT_MOVE_COLUMN => array('execute', 0),
Task::EVENT_MOVE_POSITION => array('execute', 0),
+ Task::EVENT_MOVE_SWIMLANE => array('execute', 0),
Comment::EVENT_UPDATE => array('execute', 0),
Comment::EVENT_CREATE => array('execute', 0),
Subtask::EVENT_UPDATE => array('execute', 0),
@@ -58,6 +59,7 @@ class ProjectActivitySubscriber extends \Core\Base implements EventSubscriberInt
{
$values = array();
$values['task'] = $this->taskFinder->getDetails($event['task_id']);
+ $values['changes'] = isset($event['changes']) ? $event['changes'] : array();
switch (get_class($event)) {
case 'Event\SubtaskEvent':
diff --git a/app/Template/event/events.php b/app/Template/event/events.php
index 2dc79871..971f6587 100644
--- a/app/Template/event/events.php
+++ b/app/Template/event/events.php
@@ -7,6 +7,8 @@
<p class="activity-datetime">
<?php if ($this->text->contains($event['event_name'], 'subtask')): ?>
<i class="fa fa-tasks"></i>
+ <?php elseif ($this->text->contains($event['event_name'], 'task.move')): ?>
+ <i class="fa fa-arrows-alt"></i>
<?php elseif ($this->text->contains($event['event_name'], 'task')): ?>
<i class="fa fa-newspaper-o"></i>
<?php elseif ($this->text->contains($event['event_name'], 'comment')): ?>
diff --git a/app/Template/event/task_move_swimlane.php b/app/Template/event/task_move_swimlane.php
new file mode 100644
index 00000000..ca440dbf
--- /dev/null
+++ b/app/Template/event/task_move_swimlane.php
@@ -0,0 +1,19 @@
+<?= $this->user->avatar($email, $author) ?>
+
+<p class="activity-title">
+ <?php if ($task['swimlane_id'] == 0): ?>
+ <?= e('%s moved the task %s to the first swimlane',
+ $this->e($author),
+ $this->url->link(t('#%d', $task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))
+ ) ?>
+ <?php else: ?>
+ <?= e('%s moved the task %s to the swimlane "%s"',
+ $this->e($author),
+ $this->url->link(t('#%d', $task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])),
+ $this->e($task['swimlane_name'])
+ ) ?>
+ <?php endif ?>
+</p>
+<p class="activity-description">
+ <em><?= $this->e($task['title']) ?></em>
+</p> \ No newline at end of file
diff --git a/app/Template/event/task_update.php b/app/Template/event/task_update.php
index 7d036d43..e8254bcb 100644
--- a/app/Template/event/task_update.php
+++ b/app/Template/event/task_update.php
@@ -8,4 +8,9 @@
</p>
<p class="activity-description">
<em><?= $this->e($task['title']) ?></em>
+ <?php if (isset($changes)): ?>
+ <div class="activity-changes">
+ <?= $this->render('task/changes', array('changes' => $changes, 'task' => $task)) ?>
+ </div>
+ <?php endif ?>
</p> \ No newline at end of file
diff --git a/app/Template/notification/task_move_swimlane.php b/app/Template/notification/task_move_swimlane.php
new file mode 100644
index 00000000..04de7cc6
--- /dev/null
+++ b/app/Template/notification/task_move_swimlane.php
@@ -0,0 +1,19 @@
+<h2><?= $this->e($task['title']) ?> (#<?= $task['id'] ?>)</h2>
+
+<ul>
+ <li>
+ <?php if ($task['swimlane_id'] == 0): ?>
+ <?= t('The task have been moved to the first swimlane') ?>
+ <?php else: ?>
+ <?= t('The task have been moved to another swimlane:') ?>
+ <strong><?= $this->e($task['swimlane_name']) ?></strong>
+ <?php endif ?>
+ </li>
+ <li>
+ <?= t('Column on the board:') ?>
+ <strong><?= $this->e($task['column_title']) ?></strong>
+ </li>
+ <li><?= t('Task position:').' '.$this->e($task['position']) ?></li>
+</ul>
+
+<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_update.php b/app/Template/notification/task_update.php
index 0352788b..54f5c6d1 100644
--- a/app/Template/notification/task_update.php
+++ b/app/Template/notification/task_update.php
@@ -1,65 +1,4 @@
<h2><?= $this->e($task['title']) ?> (#<?= $task['id'] ?>)</h2>
-<?= t('The task have been updated.') ?>
-
-<?php if (! empty($changes)): ?>
- <h2><?= t('List of changes') ?></h2>
- <ul>
- <?php
-
- foreach ($changes as $field => $value) {
-
- switch ($field) {
- case 'title':
- echo '<li>'.t('New title: %s', $task['title']).'</li>';
- break;
- case 'owner_id':
- if (empty($task['owner_id'])) {
- echo '<li>'.t('The task is not assigned anymore').'</li>';
- }
- else {
- echo '<li>'.t('New assignee: %s', $task['assignee_name'] ?: $task['assignee_username']).'</li>';
- }
- break;
- case 'category_id':
- if (empty($task['category_id'])) {
- echo '<li>'.t('There is no category now').'</li>';
- }
- else {
- echo '<li>'.t('New category: %s', $task['category_name']).'</li>';
- }
- break;
- case 'color_id':
- echo '<li>'.t('New color: %s', $this->text->in($task['color_id'], $colors_list)).'</li>';
- break;
- case 'score':
- echo '<li>'.t('New complexity: %d', $task['score']).'</li>';
- break;
- case 'date_due':
- if (empty($task['date_due'])) {
- echo '<li>'.t('The due date have been removed').'</li>';
- }
- else {
- echo '<li>'.dt('New due date: %B %e, %Y', $task['date_due']).'</li>';
- }
- break;
- case 'description':
- if (empty($task['description'])) {
- echo '<li>'.t('There is no description anymore').'</li>';
- }
- break;
- default:
- echo '<li>'.t('The field "%s" have been updated', $field).'</li>';
- }
- }
-
- ?>
- </ul>
-
- <?php if (! empty($changes['description'])): ?>
- <h3><?= t('New description') ?></h3>
- <?= $this->text->markdown($task['description']) ?>
- <?php endif ?>
-<?php endif ?>
-
+<?= $this->render('task/changes', array('changes' => $changes, 'task' => $task)) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/task/changes.php b/app/Template/task/changes.php
new file mode 100644
index 00000000..c7fc0d52
--- /dev/null
+++ b/app/Template/task/changes.php
@@ -0,0 +1,78 @@
+<?php if (! empty($changes)): ?>
+ <ul>
+ <?php
+
+ foreach ($changes as $field => $value) {
+
+ switch ($field) {
+ case 'title':
+ echo '<li>'.t('New title: %s', $task['title']).'</li>';
+ break;
+ case 'owner_id':
+ if (empty($task['owner_id'])) {
+ echo '<li>'.t('The task is not assigned anymore').'</li>';
+ }
+ else {
+ echo '<li>'.t('New assignee: %s', $task['assignee_name'] ?: $task['assignee_username']).'</li>';
+ }
+ break;
+ case 'category_id':
+ if (empty($task['category_id'])) {
+ echo '<li>'.t('There is no category now').'</li>';
+ }
+ else {
+ echo '<li>'.t('New category: %s', $task['category_name']).'</li>';
+ }
+ break;
+ case 'color_id':
+ echo '<li>'.t('New color: %s', $this->text->in($task['color_id'], $this->task->getColors())).'</li>';
+ break;
+ case 'score':
+ echo '<li>'.t('New complexity: %d', $task['score']).'</li>';
+ break;
+ case 'date_due':
+ if (empty($task['date_due'])) {
+ echo '<li>'.t('The due date have been removed').'</li>';
+ }
+ else {
+ echo '<li>'.dt('New due date: %B %e, %Y', $task['date_due']).'</li>';
+ }
+ break;
+ case 'description':
+ if (empty($task['description'])) {
+ echo '<li>'.t('There is no description anymore').'</li>';
+ }
+ break;
+ case 'recurrence_status':
+ case 'recurrence_trigger':
+ case 'recurrence_factor':
+ case 'recurrence_timeframe':
+ case 'recurrence_basedate':
+ case 'recurrence_parent':
+ case 'recurrence_child':
+ echo '<li>'.t('Recurrence settings have been modified').'</li>';
+ break;
+ case 'time_spent':
+ echo '<li>'.t('Time spent changed: %sh', $task['time_spent']).'</li>';
+ break;
+ case 'time_estimated':
+ echo '<li>'.t('Time estimated changed: %sh', $task['time_estimated']).'</li>';
+ break;
+ case 'date_started':
+ if ($value != 0) {
+ echo '<li>'.dt('Start date changed: %B %e, %Y', $task['date_started']).'</li>';
+ }
+ break;
+ default:
+ echo '<li>'.t('The field "%s" have been updated', $field).'</li>';
+ }
+ }
+
+ ?>
+ </ul>
+
+ <?php if (! empty($changes['description'])): ?>
+ <p><?= t('The description have been modified') ?></p>
+ <div class="markdown"><?= $this->text->markdown($task['description']) ?></div>
+ <?php endif ?>
+<?php endif ?> \ No newline at end of file
diff --git a/assets/css/app.css b/assets/css/app.css
index 6a031510..73df92fc 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -264,7 +264,6 @@ select {
select:focus {
outline: 0;
- font-weight: bold;
}
::-webkit-input-placeholder {
@@ -1369,7 +1368,17 @@ span.task-board-date-overdue {
.activity-description .markdown {
margin-top: 10px;
color: #555;
-}/* dashboard */
+}
+
+.activity-changes {
+ margin-top: 10px;
+ font-size: 0.85em;
+}
+
+.activity-changes ul {
+ margin-left: 25px;
+}
+/* dashboard */
@media only screen and (min-width: 1280px) {
diff --git a/assets/css/src/activity.css b/assets/css/src/activity.css
index 2d44aa5d..3dd18a9d 100644
--- a/assets/css/src/activity.css
+++ b/assets/css/src/activity.css
@@ -39,4 +39,13 @@
.activity-description .markdown {
margin-top: 10px;
color: #555;
-} \ No newline at end of file
+}
+
+.activity-changes {
+ margin-top: 10px;
+ font-size: 0.85em;
+}
+
+.activity-changes ul {
+ margin-left: 25px;
+}
diff --git a/assets/css/src/form.css b/assets/css/src/form.css
index 606cdd70..dc101163 100644
--- a/assets/css/src/form.css
+++ b/assets/css/src/form.css
@@ -59,7 +59,6 @@ select {
select:focus {
outline: 0;
- font-weight: bold;
}
::-webkit-input-placeholder {
diff --git a/tests/units/NotificationTest.php b/tests/units/NotificationTest.php
index f86d02e1..92b839c4 100644
--- a/tests/units/NotificationTest.php
+++ b/tests/units/NotificationTest.php
@@ -260,7 +260,7 @@ class NotificationTest extends Base
$this->assertNotEmpty($file);
foreach (Subscriber\NotificationSubscriber::getSubscribedEvents() as $event => $values) {
- $this->assertNotEmpty($n->getMailContent($event, array('task' => $task, 'comment' => $comment, 'subtask' => $subtask, 'file' => $file)));
+ $this->assertNotEmpty($n->getMailContent($event, array('task' => $task, 'comment' => $comment, 'subtask' => $subtask, 'file' => $file, 'changes' => array())));
}
}