Add new search attribute for swimlane
This commit is contained in:
@@ -33,6 +33,7 @@ class Lexer
|
|||||||
"/^(category:)/" => 'T_CATEGORY',
|
"/^(category:)/" => 'T_CATEGORY',
|
||||||
"/^(column:)/" => 'T_COLUMN',
|
"/^(column:)/" => 'T_COLUMN',
|
||||||
"/^(project:)/" => 'T_PROJECT',
|
"/^(project:)/" => 'T_PROJECT',
|
||||||
|
"/^(swimlane:)/" => 'T_SWIMLANE',
|
||||||
"/^(ref:)/" => 'T_REFERENCE',
|
"/^(ref:)/" => 'T_REFERENCE',
|
||||||
"/^(reference:)/" => 'T_REFERENCE',
|
"/^(reference:)/" => 'T_REFERENCE',
|
||||||
"/^(\s+)/" => 'T_WHITESPACE',
|
"/^(\s+)/" => 'T_WHITESPACE',
|
||||||
@@ -116,6 +117,7 @@ class Lexer
|
|||||||
case 'T_CATEGORY':
|
case 'T_CATEGORY':
|
||||||
case 'T_COLUMN':
|
case 'T_COLUMN':
|
||||||
case 'T_PROJECT':
|
case 'T_PROJECT':
|
||||||
|
case 'T_SWIMLANE':
|
||||||
$next = next($tokens);
|
$next = next($tokens);
|
||||||
|
|
||||||
if ($next !== false && $next['token'] === 'T_STRING') {
|
if ($next !== false && $next['token'] === 'T_STRING') {
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ class TaskFilter extends Base
|
|||||||
case 'T_REFERENCE':
|
case 'T_REFERENCE':
|
||||||
$this->filterByReference($value);
|
$this->filterByReference($value);
|
||||||
break;
|
break;
|
||||||
|
case 'T_SWIMLANE':
|
||||||
|
$this->filterBySwimlaneName($value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +249,30 @@ class TaskFilter extends Base
|
|||||||
$this->query->closeOr();
|
$this->query->closeOr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by swimlane name
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param array $values List of swimlane name
|
||||||
|
* @return TaskFilter
|
||||||
|
*/
|
||||||
|
public function filterBySwimlaneName(array $values)
|
||||||
|
{
|
||||||
|
$this->query->beginOr();
|
||||||
|
|
||||||
|
foreach ($values as $swimlane) {
|
||||||
|
if ($swimlane === 'default') {
|
||||||
|
$this->query->eq(Task::TABLE.'.swimlane_id', 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->query->ilike(Swimlane::TABLE.'.name', $swimlane);
|
||||||
|
$this->query->addCondition(Task::TABLE.'.swimlane_id=0 AND '.Project::TABLE.'.default_swimlane '.$this->db->getDriver()->getOperator('ILIKE')." '$swimlane'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->query->closeOr();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter by category id
|
* Filter by category id
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -88,11 +88,14 @@ class TaskFinder extends Base
|
|||||||
Category::TABLE.'.name AS category_name',
|
Category::TABLE.'.name AS category_name',
|
||||||
Category::TABLE.'.description AS category_description',
|
Category::TABLE.'.description AS category_description',
|
||||||
Board::TABLE.'.title AS column_name',
|
Board::TABLE.'.title AS column_name',
|
||||||
|
Swimlane::TABLE.'.name AS swimlane_name',
|
||||||
|
Project::TABLE.'.default_swimlane',
|
||||||
Project::TABLE.'.name AS project_name'
|
Project::TABLE.'.name AS project_name'
|
||||||
)
|
)
|
||||||
->join(User::TABLE, 'id', 'owner_id', Task::TABLE)
|
->join(User::TABLE, 'id', 'owner_id', Task::TABLE)
|
||||||
->join(Category::TABLE, 'id', 'category_id', Task::TABLE)
|
->join(Category::TABLE, 'id', 'category_id', Task::TABLE)
|
||||||
->join(Board::TABLE, 'id', 'column_id', Task::TABLE)
|
->join(Board::TABLE, 'id', 'column_id', Task::TABLE)
|
||||||
|
->join(Swimlane::TABLE, 'id', 'swimlane_id', Task::TABLE)
|
||||||
->join(Project::TABLE, 'id', 'project_id', Task::TABLE);
|
->join(Project::TABLE, 'id', 'project_id', Task::TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,12 @@
|
|||||||
<table class="table-fixed table-small">
|
<table class="table-fixed table-small">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
||||||
<th class="column-8"><?= $paginator->order(t('Column'), 'tasks.column_id') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Swimlane'), 'tasks.swimlane_id') ?></th>
|
||||||
<th class="column-8"><?= $paginator->order(t('Category'), 'tasks.category_id') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Column'), 'tasks.column_id') ?></th>
|
||||||
|
<th class="column-10"><?= $paginator->order(t('Category'), 'tasks.category_id') ?></th>
|
||||||
<th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
|
<th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
|
||||||
<th class="column-10"><?= $paginator->order(t('Assignee'), 'users.username') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Assignee'), 'users.username') ?></th>
|
||||||
<th class="column-10"><?= $paginator->order(t('Due date'), 'tasks.date_due') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Due date'), 'tasks.date_due') ?></th>
|
||||||
<th class="column-10"><?= $paginator->order(t('Date created'), 'tasks.date_creation') ?></th>
|
|
||||||
<th class="column-10"><?= $paginator->order(t('Date completed'), 'tasks.date_completed') ?></th>
|
|
||||||
<th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
|
<th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
|
||||||
</tr>
|
</tr>
|
||||||
<?php foreach ($paginator->getCollection() as $task): ?>
|
<?php foreach ($paginator->getCollection() as $task): ?>
|
||||||
@@ -24,6 +23,9 @@
|
|||||||
<td class="task-table color-<?= $task['color_id'] ?>">
|
<td class="task-table color-<?= $task['color_id'] ?>">
|
||||||
<?= $this->url->link('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
|
<?= $this->url->link('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<?= $this->e($task['swimlane_name'] ?: $task['default_swimlane']) ?>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?= $this->e($task['column_name']) ?>
|
<?= $this->e($task['column_name']) ?>
|
||||||
</td>
|
</td>
|
||||||
@@ -43,14 +45,6 @@
|
|||||||
<td>
|
<td>
|
||||||
<?= dt('%B %e, %Y', $task['date_due']) ?>
|
<?= dt('%B %e, %Y', $task['date_due']) ?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
<?= dt('%B %e, %Y', $task['date_creation']) ?>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php if ($task['date_completed']): ?>
|
|
||||||
<?= dt('%B %e, %Y', $task['date_completed']) ?>
|
|
||||||
<?php endif ?>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<?php if ($task['is_active'] == \Model\Task::STATUS_OPEN): ?>
|
<?php if ($task['is_active'] == \Model\Task::STATUS_OPEN): ?>
|
||||||
<?= t('Open') ?>
|
<?= t('Open') ?>
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
<table class="table-fixed table-small">
|
<table class="table-fixed table-small">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="column-8"><?= $paginator->order(t('Project'), 'tasks.project_id') ?></th>
|
<th class="column-8"><?= $paginator->order(t('Project'), 'tasks.project_id') ?></th>
|
||||||
<th class="column-8"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
||||||
<th class="column-8"><?= $paginator->order(t('Column'), 'tasks.column_id') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Swimlane'), 'tasks.swimlane_id') ?></th>
|
||||||
<th class="column-8"><?= $paginator->order(t('Category'), 'tasks.category_id') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Column'), 'tasks.column_id') ?></th>
|
||||||
|
<th class="column-10"><?= $paginator->order(t('Category'), 'tasks.category_id') ?></th>
|
||||||
<th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
|
<th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
|
||||||
<th class="column-10"><?= $paginator->order(t('Assignee'), 'users.username') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Assignee'), 'users.username') ?></th>
|
||||||
<th class="column-10"><?= $paginator->order(t('Due date'), 'tasks.date_due') ?></th>
|
<th class="column-10"><?= $paginator->order(t('Due date'), 'tasks.date_due') ?></th>
|
||||||
<th class="column-10"><?= $paginator->order(t('Date created'), 'tasks.date_creation') ?></th>
|
|
||||||
<th class="column-10"><?= $paginator->order(t('Date completed'), 'tasks.date_completed') ?></th>
|
|
||||||
<th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
|
<th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
|
||||||
</tr>
|
</tr>
|
||||||
<?php foreach ($paginator->getCollection() as $task): ?>
|
<?php foreach ($paginator->getCollection() as $task): ?>
|
||||||
@@ -19,6 +18,9 @@
|
|||||||
<td class="task-table color-<?= $task['color_id'] ?>">
|
<td class="task-table color-<?= $task['color_id'] ?>">
|
||||||
<?= $this->url->link('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
|
<?= $this->url->link('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<?= $this->e($task['swimlane_name'] ?: $task['default_swimlane']) ?>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?= $this->e($task['column_name']) ?>
|
<?= $this->e($task['column_name']) ?>
|
||||||
</td>
|
</td>
|
||||||
@@ -38,14 +40,6 @@
|
|||||||
<td>
|
<td>
|
||||||
<?= dt('%B %e, %Y', $task['date_due']) ?>
|
<?= dt('%B %e, %Y', $task['date_due']) ?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
<?= dt('%B %e, %Y', $task['date_creation']) ?>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php if ($task['date_completed']): ?>
|
|
||||||
<?= dt('%B %e, %Y', $task['date_completed']) ?>
|
|
||||||
<?php endif ?>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<?php if ($task['is_active'] == \Model\Task::STATUS_OPEN): ?>
|
<?php if ($task['is_active'] == \Model\Task::STATUS_OPEN): ?>
|
||||||
<?= t('Open') ?>
|
<?= t('Open') ?>
|
||||||
|
|||||||
@@ -151,6 +151,15 @@ Attribute: **column**
|
|||||||
- Find tasks by column name: `column:"Work in progress"`
|
- Find tasks by column name: `column:"Work in progress"`
|
||||||
- Find tasks for several columns: `column:"Backlog" column:ready`
|
- Find tasks for several columns: `column:"Backlog" column:ready`
|
||||||
|
|
||||||
|
Search by swimlane
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Attribute: **swimlane**
|
||||||
|
|
||||||
|
- Find tasks by swimlane: `swimlane:"Version 42"`
|
||||||
|
- Find tasks in the default swimlane: `swimlane:default`
|
||||||
|
- Find tasks into several swimlanes: `swimlane:"Version 1.2" swimlane:"Version 1.3"`
|
||||||
|
|
||||||
Search by external reference
|
Search by external reference
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,31 @@ use Core\Lexer;
|
|||||||
|
|
||||||
class LexerTest extends Base
|
class LexerTest extends Base
|
||||||
{
|
{
|
||||||
|
public function testSwimlaneQuery()
|
||||||
|
{
|
||||||
|
$lexer = new Lexer;
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(array('match' => 'swimlane:', 'token' => 'T_SWIMLANE'), array('match' => 'Version 42', 'token' => 'T_STRING')),
|
||||||
|
$lexer->tokenize('swimlane:"Version 42"')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(array('match' => 'swimlane:', 'token' => 'T_SWIMLANE'), array('match' => 'v3', 'token' => 'T_STRING')),
|
||||||
|
$lexer->tokenize('swimlane:v3')
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array('T_SWIMLANE' => array('v3')),
|
||||||
|
$lexer->map($lexer->tokenize('swimlane:v3'))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array('T_SWIMLANE' => array('Version 42', 'v3')),
|
||||||
|
$lexer->map($lexer->tokenize('swimlane:"Version 42" swimlane:v3'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testAssigneeQuery()
|
public function testAssigneeQuery()
|
||||||
{
|
{
|
||||||
$lexer = new Lexer;
|
$lexer = new Lexer;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use Model\TaskCreation;
|
|||||||
use Model\DateParser;
|
use Model\DateParser;
|
||||||
use Model\Category;
|
use Model\Category;
|
||||||
use Model\Config;
|
use Model\Config;
|
||||||
|
use Model\Swimlane;
|
||||||
|
|
||||||
class TaskFilterTest extends Base
|
class TaskFilterTest extends Base
|
||||||
{
|
{
|
||||||
@@ -286,6 +287,64 @@ class TaskFilterTest extends Base
|
|||||||
$this->assertEmpty($tasks);
|
$this->assertEmpty($tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSearchWithSwimlane()
|
||||||
|
{
|
||||||
|
$p = new Project($this->container);
|
||||||
|
$tc = new TaskCreation($this->container);
|
||||||
|
$tf = new TaskFilter($this->container);
|
||||||
|
$s = new Swimlane($this->container);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $p->create(array('name' => 'My project A')));
|
||||||
|
$this->assertEquals(1, $s->create(1, 'Version 1.1'));
|
||||||
|
$this->assertEquals(2, $s->create(1, 'Version 1.2'));
|
||||||
|
$this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task1', 'swimlane_id' => 1)));
|
||||||
|
$this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task2', 'swimlane_id' => 2)));
|
||||||
|
$this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task3', 'swimlane_id' => 0)));
|
||||||
|
|
||||||
|
$tf->search('swimlane:"Version 1.1"');
|
||||||
|
$tasks = $tf->findAll();
|
||||||
|
$this->assertNotEmpty($tasks);
|
||||||
|
$this->assertCount(1, $tasks);
|
||||||
|
$this->assertEquals('task1', $tasks[0]['title']);
|
||||||
|
$this->assertEquals('Version 1.1', $tasks[0]['swimlane_name']);
|
||||||
|
|
||||||
|
$tf->search('swimlane:"versioN 1.2"');
|
||||||
|
$tasks = $tf->findAll();
|
||||||
|
$this->assertNotEmpty($tasks);
|
||||||
|
$this->assertCount(1, $tasks);
|
||||||
|
$this->assertEquals('task2', $tasks[0]['title']);
|
||||||
|
$this->assertEquals('Version 1.2', $tasks[0]['swimlane_name']);
|
||||||
|
|
||||||
|
$tf->search('swimlane:"Default swimlane"');
|
||||||
|
$tasks = $tf->findAll();
|
||||||
|
$this->assertNotEmpty($tasks);
|
||||||
|
$this->assertCount(1, $tasks);
|
||||||
|
$this->assertEquals('task3', $tasks[0]['title']);
|
||||||
|
$this->assertEquals('Default swimlane', $tasks[0]['default_swimlane']);
|
||||||
|
$this->assertEquals('', $tasks[0]['swimlane_name']);
|
||||||
|
|
||||||
|
$tf->search('swimlane:default');
|
||||||
|
$tasks = $tf->findAll();
|
||||||
|
$this->assertNotEmpty($tasks);
|
||||||
|
$this->assertCount(1, $tasks);
|
||||||
|
$this->assertEquals('task3', $tasks[0]['title']);
|
||||||
|
$this->assertEquals('Default swimlane', $tasks[0]['default_swimlane']);
|
||||||
|
$this->assertEquals('', $tasks[0]['swimlane_name']);
|
||||||
|
|
||||||
|
$tf->search('swimlane:"Version 1.1" swimlane:"Version 1.2"');
|
||||||
|
$tasks = $tf->findAll();
|
||||||
|
$this->assertNotEmpty($tasks);
|
||||||
|
$this->assertCount(2, $tasks);
|
||||||
|
$this->assertEquals('task1', $tasks[0]['title']);
|
||||||
|
$this->assertEquals('Version 1.1', $tasks[0]['swimlane_name']);
|
||||||
|
$this->assertEquals('task2', $tasks[1]['title']);
|
||||||
|
$this->assertEquals('Version 1.2', $tasks[1]['swimlane_name']);
|
||||||
|
|
||||||
|
$tf->search('swimlane:"not found"');
|
||||||
|
$tasks = $tf->findAll();
|
||||||
|
$this->assertEmpty($tasks);
|
||||||
|
}
|
||||||
|
|
||||||
public function testSearchWithColumn()
|
public function testSearchWithColumn()
|
||||||
{
|
{
|
||||||
$p = new Project($this->container);
|
$p = new Project($this->container);
|
||||||
|
|||||||
Reference in New Issue
Block a user