Add suggest menu for user mentions in text editor
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Kanboard\Controller;
|
||||
|
||||
use Kanboard\Filter\UserNameFilter;
|
||||
use Kanboard\Formatter\UserAutoCompleteFormatter;
|
||||
use Kanboard\Formatter\UserMentionFormatter;
|
||||
use Kanboard\Model\UserModel;
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,12 @@ class UserAjaxController extends BaseController
|
||||
$project_id = $this->request->getStringParam('project_id');
|
||||
$query = $this->request->getStringParam('q');
|
||||
$users = $this->projectPermissionModel->findUsernames($project_id, $query);
|
||||
$this->response->json($users);
|
||||
|
||||
$this->response->json(
|
||||
UserMentionFormatter::getInstance($this->container)
|
||||
->withUsers($users)
|
||||
->format()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ use Pimple\Container;
|
||||
*
|
||||
* @property \Kanboard\Helper\AppHelper $app
|
||||
* @property \Kanboard\Helper\AssetHelper $asset
|
||||
* @property \Kanboard\Helper\AvatarHelper $avatar
|
||||
* @property \Kanboard\Helper\BoardHelper $board
|
||||
* @property \Kanboard\Helper\CalendarHelper $calendar
|
||||
* @property \Kanboard\Helper\DateHelper $dt
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Kanboard\Formatter;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use PicoDb\Table;
|
||||
use Pimple\Container;
|
||||
|
||||
/**
|
||||
* Class BaseFormatter
|
||||
@@ -22,19 +21,6 @@ abstract class BaseFormatter extends Base
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Get object instance
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param Container $container
|
||||
* @return static
|
||||
*/
|
||||
public static function getInstance(Container $container)
|
||||
{
|
||||
return new static($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set query
|
||||
*
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Kanboard\Formatter;
|
||||
|
||||
use Kanboard\Core\Filter\FormatterInterface;
|
||||
|
||||
/**
|
||||
* Common class to handle calendar events
|
||||
*
|
||||
@@ -34,7 +32,7 @@ abstract class BaseTaskCalendarFormatter extends BaseFormatter
|
||||
* @access public
|
||||
* @param string $start_column Column name for the start date
|
||||
* @param string $end_column Column name for the end date
|
||||
* @return FormatterInterface
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumns($start_column, $end_column = '')
|
||||
{
|
||||
|
||||
60
app/Formatter/UserMentionFormatter.php
Normal file
60
app/Formatter/UserMentionFormatter.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Formatter;
|
||||
|
||||
/**
|
||||
* Class UserMentionFormatter
|
||||
*
|
||||
* @package Kanboard\Formatter
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserMentionFormatter extends BaseFormatter
|
||||
{
|
||||
protected $users = array();
|
||||
|
||||
/**
|
||||
* Set users
|
||||
*
|
||||
* @param array $users
|
||||
* @return $this
|
||||
*/
|
||||
public function withUsers(array $users) {
|
||||
$this->users = $users;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply formatter
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function format()
|
||||
{
|
||||
$result = array();
|
||||
|
||||
foreach ($this->users as $user) {
|
||||
$html = $this->helper->avatar->small(
|
||||
$user['id'],
|
||||
$user['username'],
|
||||
$user['name'],
|
||||
$user['email'],
|
||||
$user['avatar_path'],
|
||||
'avatar-inline'
|
||||
);
|
||||
|
||||
$html .= ' '.$this->helper->text->e($user['username']);
|
||||
|
||||
if (! empty($user['name'])) {
|
||||
$html .= ' <small>'.$this->helper->text->e($user['name']).'</small>';
|
||||
}
|
||||
|
||||
$result[] = array(
|
||||
'value' => $user['username'],
|
||||
'html' => $html,
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,10 @@ class FormHelper extends Base
|
||||
'placeholder' => t('Write your text in Markdown'),
|
||||
);
|
||||
|
||||
if (isset($values['project_id'])) {
|
||||
$params['mentionUrl'] = $this->helper->url->to('UserAjaxController', 'mention', array('project_id' => $values['project_id']));
|
||||
}
|
||||
|
||||
$html = '<div class="js-text-editor" data-params=\''.json_encode($params, JSON_HEX_APOS).'\'></div>';
|
||||
$html .= $this->errorList($errors, $name);
|
||||
|
||||
|
||||
@@ -62,17 +62,33 @@ class ProjectPermissionModel extends Base
|
||||
->withFilter(new ProjectUserRoleProjectFilter($project_id))
|
||||
->withFilter(new ProjectUserRoleUsernameFilter($input))
|
||||
->getQuery()
|
||||
->findAllByColumn('username');
|
||||
->columns(
|
||||
UserModel::TABLE.'.id',
|
||||
UserModel::TABLE.'.username',
|
||||
UserModel::TABLE.'.name',
|
||||
UserModel::TABLE.'.email',
|
||||
UserModel::TABLE.'.avatar_path'
|
||||
)
|
||||
->findAll();
|
||||
|
||||
$groupMembers = $this->projectGroupRoleQuery
|
||||
->withFilter(new ProjectGroupRoleProjectFilter($project_id))
|
||||
->withFilter(new ProjectGroupRoleUsernameFilter($input))
|
||||
->getQuery()
|
||||
->findAllByColumn('username');
|
||||
->columns(
|
||||
UserModel::TABLE.'.id',
|
||||
UserModel::TABLE.'.username',
|
||||
UserModel::TABLE.'.name',
|
||||
UserModel::TABLE.'.email',
|
||||
UserModel::TABLE.'.avatar_path'
|
||||
)
|
||||
->findAll();
|
||||
|
||||
$members = array_unique(array_merge($userMembers, $groupMembers));
|
||||
$userMembers = array_column_index_unique($userMembers, 'username');
|
||||
$groupMembers = array_column_index_unique($groupMembers, 'username');
|
||||
$members = array_merge($userMembers, $groupMembers);
|
||||
|
||||
sort($members);
|
||||
ksort($members);
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,37 @@ function array_column_index(array &$input, $column)
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create indexed array from a list of dict with unique values
|
||||
*
|
||||
* $input = [
|
||||
* ['k1' => 1, 'k2' => 2], ['k1' => 3, 'k2' => 4], ['k1' => 1, 'k2' => 5]
|
||||
* ]
|
||||
*
|
||||
* array_column_index_unique($input, 'k1') will returns:
|
||||
*
|
||||
* [
|
||||
* 1 => ['k1' => 1, 'k2' => 2],
|
||||
* 3 => ['k1' => 3, 'k2' => 4],
|
||||
* ]
|
||||
*
|
||||
* @param array $input
|
||||
* @param string $column
|
||||
* @return array
|
||||
*/
|
||||
function array_column_index_unique(array &$input, $column)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
foreach ($input as &$row) {
|
||||
if (isset($row[$column]) && ! isset($result[$row[$column]])) {
|
||||
$result[$row[$column]] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum all values from a single column in the input array
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user