summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Controller/TaskAjaxController.php25
-rw-r--r--app/Controller/UserAjaxController.php2
-rw-r--r--app/Core/Markdown.php7
-rw-r--r--app/Filter/TaskStartsWithIdFilter.php38
-rw-r--r--app/Formatter/TaskAutoCompleteFormatter.php28
-rw-r--r--app/Formatter/TaskSuggestMenuFormatter.php63
-rw-r--r--app/Helper/FormHelper.php9
-rw-r--r--app/Template/notification/comment_create.php2
-rw-r--r--app/Template/notification/comment_delete.php2
-rw-r--r--app/Template/notification/comment_update.php2
-rw-r--r--app/Template/notification/comment_user_mention.php2
-rw-r--r--app/Template/notification/task_assignee_change.php2
-rw-r--r--app/Template/notification/task_create.php2
-rw-r--r--app/Template/notification/task_update.php2
-rw-r--r--app/Template/notification/task_user_mention.php2
-rw-r--r--app/Template/task/changes.php6
16 files changed, 174 insertions, 20 deletions
diff --git a/app/Controller/TaskAjaxController.php b/app/Controller/TaskAjaxController.php
index f9feff15..609dd23c 100644
--- a/app/Controller/TaskAjaxController.php
+++ b/app/Controller/TaskAjaxController.php
@@ -5,8 +5,12 @@ namespace Kanboard\Controller;
use Kanboard\Filter\TaskIdExclusionFilter;
use Kanboard\Filter\TaskIdFilter;
use Kanboard\Filter\TaskProjectsFilter;
+use Kanboard\Filter\TaskStartsWithIdFilter;
+use Kanboard\Filter\TaskStatusFilter;
use Kanboard\Filter\TaskTitleFilter;
use Kanboard\Formatter\TaskAutoCompleteFormatter;
+use Kanboard\Formatter\TaskSuggestMenuFormatter;
+use Kanboard\Model\TaskModel;
/**
* Task Ajax Controller
@@ -19,7 +23,6 @@ class TaskAjaxController extends BaseController
/**
* Task auto-completion (Ajax)
*
- * @access public
*/
public function autocomplete()
{
@@ -46,4 +49,24 @@ class TaskAjaxController extends BaseController
$this->response->json($filter->format(new TaskAutoCompleteFormatter($this->container)));
}
}
+
+ /**
+ * Task ID suggest menu
+ */
+ public function suggest()
+ {
+ $taskId = $this->request->getIntegerParam('search');
+ $projectIds = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId());
+
+ if (empty($projectIds)) {
+ $this->response->json(array());
+ } else {
+ $filter = $this->taskQuery
+ ->withFilter(new TaskProjectsFilter($projectIds))
+ ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
+ ->withFilter(new TaskStartsWithIdFilter($taskId));
+
+ $this->response->json($filter->format(new TaskSuggestMenuFormatter($this->container)));
+ }
+ }
}
diff --git a/app/Controller/UserAjaxController.php b/app/Controller/UserAjaxController.php
index 0e654333..d93bfe9a 100644
--- a/app/Controller/UserAjaxController.php
+++ b/app/Controller/UserAjaxController.php
@@ -36,7 +36,7 @@ class UserAjaxController extends BaseController
public function mention()
{
$project_id = $this->request->getStringParam('project_id');
- $query = $this->request->getStringParam('q');
+ $query = $this->request->getStringParam('search');
$users = $this->projectPermissionModel->findUsernames($project_id, $query);
$this->response->json(
diff --git a/app/Core/Markdown.php b/app/Core/Markdown.php
index b4208e9a..799aefb4 100644
--- a/app/Core/Markdown.php
+++ b/app/Core/Markdown.php
@@ -90,7 +90,7 @@ class Markdown extends Parsedown
$user_id = $this->container['userModel']->getIdByUsername($matches[1]);
if (! empty($user_id)) {
- $url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user_id), false, '', true);
+ $url = $this->container['helper']->url->href('UserViewController', 'profile', array('user_id' => $user_id));
return array(
'extent' => strlen($matches[0]),
@@ -125,7 +125,10 @@ class Markdown extends Parsedown
array(
'token' => $token,
'task_id' => $task_id,
- )
+ ),
+ false,
+ '',
+ true
);
}
diff --git a/app/Filter/TaskStartsWithIdFilter.php b/app/Filter/TaskStartsWithIdFilter.php
new file mode 100644
index 00000000..8b7cc678
--- /dev/null
+++ b/app/Filter/TaskStartsWithIdFilter.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Kanboard\Filter;
+
+use Kanboard\Core\Filter\FilterInterface;
+use Kanboard\Model\TaskModel;
+
+/**
+ * Class TaskIdSearchFilter
+ *
+ * @package Kanboard\Filter
+ * @author Frederic Guillot
+ */
+class TaskStartsWithIdFilter extends BaseFilter implements FilterInterface
+{
+ /**
+ * Get search attribute
+ *
+ * @access public
+ * @return string[]
+ */
+ public function getAttributes()
+ {
+ return array('starts_with_id');
+ }
+
+ /**
+ * Apply filter
+ *
+ * @access public
+ * @return FilterInterface
+ */
+ public function apply()
+ {
+ $this->query->ilike('CAST('.TaskModel::TABLE.'.id AS CHAR(8))', $this->value.'%');
+ return $this;
+ }
+}
diff --git a/app/Formatter/TaskAutoCompleteFormatter.php b/app/Formatter/TaskAutoCompleteFormatter.php
index 2d9f7341..3a4f1e1a 100644
--- a/app/Formatter/TaskAutoCompleteFormatter.php
+++ b/app/Formatter/TaskAutoCompleteFormatter.php
@@ -14,6 +14,20 @@ use Kanboard\Model\TaskModel;
*/
class TaskAutoCompleteFormatter extends BaseFormatter implements FormatterInterface
{
+ protected $limit = 25;
+
+ /**
+ * Limit number of results
+ *
+ * @param $limit
+ * @return $this
+ */
+ public function withLimit($limit)
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+
/**
* Apply formatter
*
@@ -22,11 +36,15 @@ class TaskAutoCompleteFormatter extends BaseFormatter implements FormatterInterf
*/
public function format()
{
- $tasks = $this->query->columns(
- TaskModel::TABLE.'.id',
- TaskModel::TABLE.'.title',
- ProjectModel::TABLE.'.name AS project_name'
- )->asc(TaskModel::TABLE.'.id')->findAll();
+ $tasks = $this->query
+ ->columns(
+ TaskModel::TABLE.'.id',
+ TaskModel::TABLE.'.title',
+ ProjectModel::TABLE.'.name AS project_name'
+ )
+ ->asc(TaskModel::TABLE.'.id')
+ ->limit($this->limit)
+ ->findAll();
foreach ($tasks as &$task) {
$task['value'] = $task['title'];
diff --git a/app/Formatter/TaskSuggestMenuFormatter.php b/app/Formatter/TaskSuggestMenuFormatter.php
new file mode 100644
index 00000000..518f99e6
--- /dev/null
+++ b/app/Formatter/TaskSuggestMenuFormatter.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Kanboard\Formatter;
+
+use Kanboard\Core\Filter\FormatterInterface;
+use Kanboard\Model\ProjectModel;
+use Kanboard\Model\TaskModel;
+
+/**
+ * Class TaskSuggestMenuFormatter
+ *
+ * @package Kanboard\Formatter
+ * @author Frederic Guillot
+ */
+class TaskSuggestMenuFormatter extends BaseFormatter implements FormatterInterface
+{
+ protected $limit = 25;
+
+ /**
+ * Limit number of results
+ *
+ * @param $limit
+ * @return $this
+ */
+ public function withLimit($limit)
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+
+ /**
+ * Apply formatter
+ *
+ * @access public
+ * @return mixed
+ */
+ public function format()
+ {
+ $result = array();
+ $tasks = $this->query
+ ->columns(
+ TaskModel::TABLE.'.id',
+ TaskModel::TABLE.'.title',
+ ProjectModel::TABLE.'.name AS project_name'
+ )
+ ->asc(TaskModel::TABLE.'.id')
+ ->limit($this->limit)
+ ->findAll();
+
+ foreach ($tasks as $task) {
+ $html = '#'.$task['id'].' ';
+ $html .= $this->helper->text->e($task['title']).' ';
+ $html .= '<small>'.$this->helper->text->e($task['project_name']).'</small>';
+
+ $result[] = array(
+ 'value' => (string) $task['id'],
+ 'html' => $html,
+ );
+ }
+
+ return $result;
+ }
+}
diff --git a/app/Helper/FormHelper.php b/app/Helper/FormHelper.php
index 8c9ca332..57094688 100644
--- a/app/Helper/FormHelper.php
+++ b/app/Helper/FormHelper.php
@@ -220,11 +220,16 @@ class FormHelper extends Base
'labelPreview' => t('Preview'),
'labelWrite' => t('Write'),
'placeholder' => t('Write your text in Markdown'),
- 'autofocus' => isset($attributes['autofocus']) && $attributes['autofocus']
+ 'autofocus' => isset($attributes['autofocus']) && $attributes['autofocus'],
+ 'suggestOptions' => array(
+ 'triggers' => array(
+ '#' => $this->helper->url->to('TaskAjaxController', 'suggest', array('search' => 'SEARCH_TERM')),
+ )
+ ),
);
if (isset($values['project_id'])) {
- $params['mentionUrl'] = $this->helper->url->to('UserAjaxController', 'mention', array('project_id' => $values['project_id']));
+ $params['suggestOptions']['triggers']['@'] = $this->helper->url->to('UserAjaxController', 'mention', array('project_id' => $values['project_id'], 'search' => 'SEARCH_TERM'));
}
$html = '<div class="js-text-editor" data-params=\''.json_encode($params, JSON_HEX_APOS).'\'></div>';
diff --git a/app/Template/notification/comment_create.php b/app/Template/notification/comment_create.php
index fefc8ba1..41262a7e 100644
--- a/app/Template/notification/comment_create.php
+++ b/app/Template/notification/comment_create.php
@@ -6,6 +6,6 @@
<h3><?= t('New comment') ?></h3>
<?php endif ?>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/comment_delete.php b/app/Template/notification/comment_delete.php
index 928623ec..14babbd9 100644
--- a/app/Template/notification/comment_delete.php
+++ b/app/Template/notification/comment_delete.php
@@ -2,6 +2,6 @@
<h3><?= t('Comment removed') ?></h3>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?>
diff --git a/app/Template/notification/comment_update.php b/app/Template/notification/comment_update.php
index 2477d8b3..f1cffae6 100644
--- a/app/Template/notification/comment_update.php
+++ b/app/Template/notification/comment_update.php
@@ -2,6 +2,6 @@
<h3><?= t('Comment updated') ?></h3>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/comment_user_mention.php b/app/Template/notification/comment_user_mention.php
index 372183df..0990e7ab 100644
--- a/app/Template/notification/comment_user_mention.php
+++ b/app/Template/notification/comment_user_mention.php
@@ -2,6 +2,6 @@
<p><?= $this->text->e($task['title']) ?></p>
-<?= $this->text->markdown($comment['comment']) ?>
+<?= $this->text->markdown($comment['comment'], true) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_assignee_change.php b/app/Template/notification/task_assignee_change.php
index 53f7c5c1..f075fdbf 100644
--- a/app/Template/notification/task_assignee_change.php
+++ b/app/Template/notification/task_assignee_change.php
@@ -14,7 +14,7 @@
<?php if (! empty($task['description'])): ?>
<h2><?= t('Description') ?></h2>
- <?= $this->text->markdown($task['description']) ?: t('There is no description.') ?>
+ <?= $this->text->markdown($task['description'], true) ?: t('There is no description.') ?>
<?php endif ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_create.php b/app/Template/notification/task_create.php
index 3cd68ac0..3439e357 100644
--- a/app/Template/notification/task_create.php
+++ b/app/Template/notification/task_create.php
@@ -37,7 +37,7 @@
<?php if (! empty($task['description'])): ?>
<h2><?= t('Description') ?></h2>
- <?= $this->text->markdown($task['description']) ?>
+ <?= $this->text->markdown($task['description'], true) ?>
<?php endif ?>
<?= $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 8adb2553..9abe8e0a 100644
--- a/app/Template/notification/task_update.php
+++ b/app/Template/notification/task_update.php
@@ -1,4 +1,4 @@
<h2><?= $this->text->e($task['title']) ?> (#<?= $task['id'] ?>)</h2>
-<?= $this->render('task/changes', array('changes' => $changes, 'task' => $task)) ?>
+<?= $this->render('task/changes', array('changes' => $changes, 'task' => $task, 'public' => true)) ?>
<?= $this->render('notification/footer', array('task' => $task, 'application_url' => $application_url)) ?> \ No newline at end of file
diff --git a/app/Template/notification/task_user_mention.php b/app/Template/notification/task_user_mention.php
index 3d8c8e95..71ad348b 100644
--- a/app/Template/notification/task_user_mention.php
+++ b/app/Template/notification/task_user_mention.php
@@ -2,6 +2,6 @@
<p><?= $this->text->e($task['title']) ?></p>
<h2><?= t('Description') ?></h2>
-<?= $this->text->markdown($task['description']) ?>
+<?= $this->text->markdown($task['description'], true) ?>
<?= $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
index 9d36f09f..2c2bf267 100644
--- a/app/Template/task/changes.php
+++ b/app/Template/task/changes.php
@@ -69,6 +69,10 @@
<?php if (! empty($changes['description'])): ?>
<p><strong><?= t('The description has been modified:') ?></strong></p>
- <div class="markdown"><?= $this->text->markdown($task['description']) ?></div>
+ <?php if (isset($public)): ?>
+ <div class="markdown"><?= $this->text->markdown($task['description'], true) ?></div>
+ <?php else: ?>
+ <div class="markdown"><?= $this->text->markdown($task['description']) ?></div>
+ <?php endif ?>
<?php endif ?>
<?php endif ?> \ No newline at end of file