From 23d862aef8891130bc7eaeaa25513a9895b44c95 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sat, 3 Dec 2016 12:56:12 -0500 Subject: Add suggest menu for task ID --- app/Controller/TaskAjaxController.php | 25 ++++++++- app/Controller/UserAjaxController.php | 2 +- app/Core/Markdown.php | 7 ++- app/Filter/TaskStartsWithIdFilter.php | 38 +++++++++++++ app/Formatter/TaskAutoCompleteFormatter.php | 28 ++++++++-- app/Formatter/TaskSuggestMenuFormatter.php | 63 ++++++++++++++++++++++ app/Helper/FormHelper.php | 9 +++- app/Template/notification/comment_create.php | 2 +- app/Template/notification/comment_delete.php | 2 +- app/Template/notification/comment_update.php | 2 +- app/Template/notification/comment_user_mention.php | 2 +- app/Template/notification/task_assignee_change.php | 2 +- app/Template/notification/task_create.php | 2 +- app/Template/notification/task_update.php | 2 +- app/Template/notification/task_user_mention.php | 2 +- app/Template/task/changes.php | 6 ++- 16 files changed, 174 insertions(+), 20 deletions(-) create mode 100644 app/Filter/TaskStartsWithIdFilter.php create mode 100644 app/Formatter/TaskSuggestMenuFormatter.php (limited to 'app') 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 @@ +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 @@ +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 .= ''.$this->helper->text->e($task['project_name']).''; + + $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 = '
'; 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 @@

-text->markdown($comment['comment']) ?> +text->markdown($comment['comment'], true) ?> 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 @@

-text->markdown($comment['comment']) ?> +text->markdown($comment['comment'], true) ?> 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 @@

-text->markdown($comment['comment']) ?> +text->markdown($comment['comment'], true) ?> 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 @@

text->e($task['title']) ?>

-text->markdown($comment['comment']) ?> +text->markdown($comment['comment'], true) ?> 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 @@

- text->markdown($task['description']) ?: t('There is no description.') ?> + text->markdown($task['description'], true) ?: t('There is no description.') ?> 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 @@

- text->markdown($task['description']) ?> + text->markdown($task['description'], true) ?> 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 @@

text->e($task['title']) ?> (#)

-render('task/changes', array('changes' => $changes, 'task' => $task)) ?> +render('task/changes', array('changes' => $changes, 'task' => $task, 'public' => true)) ?> 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 @@

text->e($task['title']) ?>

-text->markdown($task['description']) ?> +text->markdown($task['description'], true) ?> 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 @@

-
text->markdown($task['description']) ?>
+ +
text->markdown($task['description'], true) ?>
+ +
text->markdown($task['description']) ?>
+ \ No newline at end of file -- cgit v1.2.3