Improve activity stream/notification for task update events and add new notification for swimlane change
This commit is contained in:
@@ -37,6 +37,11 @@ class Task extends \Core\Base
|
|||||||
return t('%dd', ($now - $timestamp) / 86400);
|
return t('%dd', ($now - $timestamp) / 86400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getColors()
|
||||||
|
{
|
||||||
|
return $this->color->getList();
|
||||||
|
}
|
||||||
|
|
||||||
public function recurrenceTriggers()
|
public function recurrenceTriggers()
|
||||||
{
|
{
|
||||||
return $this->task->getRecurrenceTriggerList();
|
return $this->task->getRecurrenceTriggerList();
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ class Notification extends Base
|
|||||||
{
|
{
|
||||||
return $this->template->render(
|
return $this->template->render(
|
||||||
'notification/'.str_replace('.', '_', $event_name),
|
'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);
|
$subject = $this->getStandardMailSubject(e('Task opened'), $event_data);
|
||||||
break;
|
break;
|
||||||
case Task::EVENT_MOVE_COLUMN:
|
case Task::EVENT_MOVE_COLUMN:
|
||||||
$subject = $this->getStandardMailSubject(e('Column Change'), $event_data);
|
$subject = $this->getStandardMailSubject(e('Column change'), $event_data);
|
||||||
break;
|
break;
|
||||||
case Task::EVENT_MOVE_POSITION:
|
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;
|
break;
|
||||||
case Task::EVENT_ASSIGNEE_CHANGE:
|
case Task::EVENT_ASSIGNEE_CHANGE:
|
||||||
$subject = $this->getStandardMailSubject(e('Assignee Change'), $event_data);
|
$subject = $this->getStandardMailSubject(e('Assignee change'), $event_data);
|
||||||
break;
|
break;
|
||||||
case Task::EVENT_OVERDUE:
|
case Task::EVENT_OVERDUE:
|
||||||
$subject = e('[%s] Overdue tasks', $event_data['project_name']);
|
$subject = e('[%s] Overdue tasks', $event_data['project_name']);
|
||||||
|
|||||||
@@ -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']);
|
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:
|
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']);
|
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:
|
case Subtask::EVENT_UPDATE:
|
||||||
return t('%s updated a subtask for the task #%d', $event['author'], $event['task']['id']);
|
return t('%s updated a subtask for the task #%d', $event['author'], $event['task']['id']);
|
||||||
case Subtask::EVENT_CREATE:
|
case Subtask::EVENT_CREATE:
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ class TaskFinder extends Base
|
|||||||
tasks.recurrence_parent,
|
tasks.recurrence_parent,
|
||||||
tasks.recurrence_child,
|
tasks.recurrence_child,
|
||||||
project_has_categories.name AS category_name,
|
project_has_categories.name AS category_name,
|
||||||
|
swimlanes.name AS swimlane_name,
|
||||||
projects.name AS project_name,
|
projects.name AS project_name,
|
||||||
columns.title AS column_title,
|
columns.title AS column_title,
|
||||||
users.username AS assignee_username,
|
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 project_has_categories ON project_has_categories.id = tasks.category_id
|
||||||
LEFT JOIN projects ON projects.id = tasks.project_id
|
LEFT JOIN projects ON projects.id = tasks.project_id
|
||||||
LEFT JOIN columns ON columns.id = tasks.column_id
|
LEFT JOIN columns ON columns.id = tasks.column_id
|
||||||
|
LEFT JOIN swimlanes ON swimlanes.id = tasks.swimlane_id
|
||||||
WHERE tasks.id = ?
|
WHERE tasks.id = ?
|
||||||
';
|
';
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class NotificationSubscriber extends \Core\Base implements EventSubscriberInterf
|
|||||||
Task::EVENT_OPEN => array('execute', 0),
|
Task::EVENT_OPEN => array('execute', 0),
|
||||||
Task::EVENT_MOVE_COLUMN => array('execute', 0),
|
Task::EVENT_MOVE_COLUMN => array('execute', 0),
|
||||||
Task::EVENT_MOVE_POSITION => array('execute', 0),
|
Task::EVENT_MOVE_POSITION => array('execute', 0),
|
||||||
|
Task::EVENT_MOVE_SWIMLANE => array('execute', 0),
|
||||||
Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0),
|
Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0),
|
||||||
Subtask::EVENT_CREATE => array('execute', 0),
|
Subtask::EVENT_CREATE => array('execute', 0),
|
||||||
Subtask::EVENT_UPDATE => array('execute', 0),
|
Subtask::EVENT_UPDATE => array('execute', 0),
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class ProjectActivitySubscriber extends \Core\Base implements EventSubscriberInt
|
|||||||
Task::EVENT_OPEN => array('execute', 0),
|
Task::EVENT_OPEN => array('execute', 0),
|
||||||
Task::EVENT_MOVE_COLUMN => array('execute', 0),
|
Task::EVENT_MOVE_COLUMN => array('execute', 0),
|
||||||
Task::EVENT_MOVE_POSITION => 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_UPDATE => array('execute', 0),
|
||||||
Comment::EVENT_CREATE => array('execute', 0),
|
Comment::EVENT_CREATE => array('execute', 0),
|
||||||
Subtask::EVENT_UPDATE => array('execute', 0),
|
Subtask::EVENT_UPDATE => array('execute', 0),
|
||||||
@@ -58,6 +59,7 @@ class ProjectActivitySubscriber extends \Core\Base implements EventSubscriberInt
|
|||||||
{
|
{
|
||||||
$values = array();
|
$values = array();
|
||||||
$values['task'] = $this->taskFinder->getDetails($event['task_id']);
|
$values['task'] = $this->taskFinder->getDetails($event['task_id']);
|
||||||
|
$values['changes'] = isset($event['changes']) ? $event['changes'] : array();
|
||||||
|
|
||||||
switch (get_class($event)) {
|
switch (get_class($event)) {
|
||||||
case 'Event\SubtaskEvent':
|
case 'Event\SubtaskEvent':
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
<p class="activity-datetime">
|
<p class="activity-datetime">
|
||||||
<?php if ($this->text->contains($event['event_name'], 'subtask')): ?>
|
<?php if ($this->text->contains($event['event_name'], 'subtask')): ?>
|
||||||
<i class="fa fa-tasks"></i>
|
<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')): ?>
|
<?php elseif ($this->text->contains($event['event_name'], 'task')): ?>
|
||||||
<i class="fa fa-newspaper-o"></i>
|
<i class="fa fa-newspaper-o"></i>
|
||||||
<?php elseif ($this->text->contains($event['event_name'], 'comment')): ?>
|
<?php elseif ($this->text->contains($event['event_name'], 'comment')): ?>
|
||||||
|
|||||||
19
app/Template/event/task_move_swimlane.php
Normal file
19
app/Template/event/task_move_swimlane.php
Normal file
@@ -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>
|
||||||
@@ -8,4 +8,9 @@
|
|||||||
</p>
|
</p>
|
||||||
<p class="activity-description">
|
<p class="activity-description">
|
||||||
<em><?= $this->e($task['title']) ?></em>
|
<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>
|
</p>
|
||||||
19
app/Template/notification/task_move_swimlane.php
Normal file
19
app/Template/notification/task_move_swimlane.php
Normal file
@@ -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)) ?>
|
||||||
@@ -1,65 +1,4 @@
|
|||||||
<h2><?= $this->e($task['title']) ?> (#<?= $task['id'] ?>)</h2>
|
<h2><?= $this->e($task['title']) ?> (#<?= $task['id'] ?>)</h2>
|
||||||
|
|
||||||
<?= t('The task have been updated.') ?>
|
<?= $this->render('task/changes', array('changes' => $changes, 'task' => $task)) ?>
|
||||||
|
|
||||||
<?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('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?>
|
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?>
|
||||||
78
app/Template/task/changes.php
Normal file
78
app/Template/task/changes.php
Normal file
@@ -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 ?>
|
||||||
@@ -264,7 +264,6 @@ select {
|
|||||||
|
|
||||||
select:focus {
|
select:focus {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-input-placeholder {
|
::-webkit-input-placeholder {
|
||||||
@@ -1369,7 +1368,17 @@ span.task-board-date-overdue {
|
|||||||
.activity-description .markdown {
|
.activity-description .markdown {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
color: #555;
|
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) {
|
@media only screen and (min-width: 1280px) {
|
||||||
|
|
||||||
|
|||||||
@@ -40,3 +40,12 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.activity-changes {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-changes ul {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ select {
|
|||||||
|
|
||||||
select:focus {
|
select:focus {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-input-placeholder {
|
::-webkit-input-placeholder {
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ class NotificationTest extends Base
|
|||||||
$this->assertNotEmpty($file);
|
$this->assertNotEmpty($file);
|
||||||
|
|
||||||
foreach (Subscriber\NotificationSubscriber::getSubscribedEvents() as $event => $values) {
|
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())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user