Add suggest menu for task ID
This commit is contained in:
@@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
38
app/Filter/TaskStartsWithIdFilter.php
Normal file
38
app/Filter/TaskStartsWithIdFilter.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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'];
|
||||
|
||||
63
app/Formatter/TaskSuggestMenuFormatter.php
Normal file
63
app/Formatter/TaskSuggestMenuFormatter.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>';
|
||||
|
||||
@@ -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)) ?>
|
||||
@@ -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)) ?>
|
||||
|
||||
@@ -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)) ?>
|
||||
@@ -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)) ?>
|
||||
@@ -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)) ?>
|
||||
@@ -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)) ?>
|
||||
@@ -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)) ?>
|
||||
@@ -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)) ?>
|
||||
@@ -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 ?>
|
||||
Reference in New Issue
Block a user