diff --git a/app/Controller/Search.php b/app/Controller/Search.php
new file mode 100644
index 000000000..519f9ce46
--- /dev/null
+++ b/app/Controller/Search.php
@@ -0,0 +1,51 @@
+projectPermission->getAllowedProjects($this->userSession->getId());
+ $search = $this->request->getStringParam('search');
+ $nb_tasks = 0;
+
+ $paginator = $this->paginator
+ ->setUrl('search', 'index', array('search' => $search))
+ ->setMax(30)
+ ->setOrder('tasks.id')
+ ->setDirection('DESC');
+
+ if ($search !== '') {
+
+ $query = $this
+ ->taskFilter
+ ->search($search)
+ ->filterByProjects(array_keys($projects))
+ ->getQuery();
+
+ $paginator
+ ->setQuery($query)
+ ->calculate();
+
+ $nb_tasks = $paginator->getTotal();
+ }
+
+ $this->response->html($this->template->layout('search/index', array(
+ 'board_selector' => $projects,
+ 'values' => array(
+ 'search' => $search,
+ 'controller' => 'search',
+ 'action' => 'index',
+ ),
+ 'paginator' => $paginator,
+ 'title' => t('Search tasks').($nb_tasks > 0 ? ' ('.$nb_tasks.')' : '')
+ )));
+ }
+}
diff --git a/app/Model/Color.php b/app/Model/Color.php
index a35aff8f1..1fd81b85c 100644
--- a/app/Model/Color.php
+++ b/app/Model/Color.php
@@ -193,11 +193,11 @@ class Color extends Base
$buffer = '';
foreach ($this->default_colors as $color => $values) {
- $buffer .= 'td.color-'.$color.',';
$buffer .= 'div.color-'.$color.' {';
$buffer .= 'background-color: '.$values['background'].';';
$buffer .= 'border-color: '.$values['border'];
$buffer .= '}';
+ $buffer .= 'td.color-'.$color.' { background-color: '.$values['background'].'}';
}
return $buffer;
diff --git a/app/Model/TaskFilter.php b/app/Model/TaskFilter.php
index b14dad0aa..4a0860786 100644
--- a/app/Model/TaskFilter.php
+++ b/app/Model/TaskFilter.php
@@ -214,7 +214,6 @@ class TaskFilter extends Base
*/
public function filterByCategoryName(array $values)
{
- $this->query->join(Category::TABLE, 'id', 'category_id');
$this->query->beginOr();
foreach ($values as $category) {
diff --git a/app/Model/TaskFinder.php b/app/Model/TaskFinder.php
index e007187fd..181ff3600 100644
--- a/app/Model/TaskFinder.php
+++ b/app/Model/TaskFinder.php
@@ -97,10 +97,16 @@ class TaskFinder extends Base
'tasks.recurrence_parent',
'tasks.recurrence_child',
'tasks.time_estimated',
- 'users.username AS assignee_username',
- 'users.name AS assignee_name'
+ User::TABLE.'.username AS assignee_username',
+ User::TABLE.'.name AS assignee_name',
+ Category::TABLE.'.name AS category_name',
+ Board::TABLE.'.title AS column_name',
+ Project::TABLE.'.name AS project_name'
)
- ->join(User::TABLE, 'id', 'owner_id');
+ ->join(User::TABLE, 'id', 'owner_id', Task::TABLE)
+ ->join(Category::TABLE, 'id', 'category_id', Task::TABLE)
+ ->join(Board::TABLE, 'id', 'column_id', Task::TABLE)
+ ->join(Project::TABLE, 'id', 'project_id', Task::TABLE);
}
/**
@@ -115,11 +121,11 @@ class TaskFinder extends Base
public function getTasksByColumnAndSwimlane($project_id, $column_id, $swimlane_id = 0)
{
return $this->getExtendedQuery()
- ->eq('project_id', $project_id)
- ->eq('column_id', $column_id)
- ->eq('swimlane_id', $swimlane_id)
- ->eq('is_active', Task::STATUS_OPEN)
- ->asc('tasks.position')
+ ->eq(Task::TABLE.'.project_id', $project_id)
+ ->eq(Task::TABLE.'.column_id', $column_id)
+ ->eq(Task::TABLE.'.swimlane_id', $swimlane_id)
+ ->eq(Task::TABLE.'.is_active', Task::STATUS_OPEN)
+ ->asc(Task::TABLE.'.position')
->findAll();
}
diff --git a/app/Template/app/layout.php b/app/Template/app/layout.php
index d2d63f25b..4a307a198 100644
--- a/app/Template/app/layout.php
+++ b/app/Template/app/layout.php
@@ -2,13 +2,32 @@
diff --git a/app/Template/app/projects.php b/app/Template/app/projects.php
index 22e0cc479..61839ceee 100644
--- a/app/Template/app/projects.php
+++ b/app/Template/app/projects.php
@@ -4,7 +4,7 @@
isEmpty()): ?>
= t('Your are not member of any project.') ?>
-
+
| = $paginator->order('Id', 'id') ?> |
= $paginator->order(t('Project'), 'name') ?> |
diff --git a/app/Template/app/subtasks.php b/app/Template/app/subtasks.php
index 67f2d04f5..ad7402bdc 100644
--- a/app/Template/app/subtasks.php
+++ b/app/Template/app/subtasks.php
@@ -4,7 +4,7 @@
isEmpty()): ?>
= t('There is nothing assigned to you.') ?>
-
+
| = $paginator->order('Id', 'tasks.id') ?> |
= $paginator->order(t('Project'), 'project_name') ?> |
diff --git a/app/Template/app/tasks.php b/app/Template/app/tasks.php
index 8e7fe74a5..3712750bb 100644
--- a/app/Template/app/tasks.php
+++ b/app/Template/app/tasks.php
@@ -4,7 +4,7 @@
isEmpty()): ?>
= t('There is nothing assigned to you.') ?>
-
+
| = $paginator->order('Id', 'tasks.id') ?> |
= $paginator->order(t('Project'), 'project_name') ?> |
diff --git a/app/Template/search/index.php b/app/Template/search/index.php
new file mode 100644
index 000000000..058f428d5
--- /dev/null
+++ b/app/Template/search/index.php
@@ -0,0 +1,26 @@
+
+
+
+
+
+ isEmpty()): ?>
+ = t('Nothing found.') ?>
+ isEmpty()): ?>
+ = $this->render('search/results', array(
+ 'paginator' => $paginator,
+ )) ?>
+
+
+
\ No newline at end of file
diff --git a/app/Template/search/results.php b/app/Template/search/results.php
new file mode 100644
index 000000000..1d8cc6e22
--- /dev/null
+++ b/app/Template/search/results.php
@@ -0,0 +1,60 @@
+
+
+ | = $paginator->order(t('Project'), 'tasks.project_id') ?> |
+ = $paginator->order(t('Id'), 'tasks.id') ?> |
+ = $paginator->order(t('Column'), 'tasks.column_id') ?> |
+ = $paginator->order(t('Category'), 'tasks.category_id') ?> |
+ = $paginator->order(t('Title'), 'tasks.title') ?> |
+ = $paginator->order(t('Assignee'), 'users.username') ?> |
+ = $paginator->order(t('Due date'), 'tasks.date_due') ?> |
+ = $paginator->order(t('Date created'), 'tasks.date_creation') ?> |
+ = $paginator->order(t('Date completed'), 'tasks.date_completed') ?> |
+ = $paginator->order(t('Status'), 'tasks.is_active') ?> |
+
+ getCollection() as $task): ?>
+
+ |
+ = $this->url->link($this->e($task['project_name']), 'board', 'show', array('project_id' => $task['project_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->e($task['column_name']) ?>
+ |
+
+ = $this->e($task['category_name']) ?>
+ |
+
+ = $this->url->link($this->e($task['title']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
+ |
+
+
+ = $this->e($task['assignee_name'] ?: $task['assignee_username']) ?>
+
+ = t('Unassigned') ?>
+
+ |
+
+ = dt('%B %e, %Y', $task['date_due']) ?>
+ |
+
+ = dt('%B %e, %Y', $task['date_creation']) ?>
+ |
+
+
+ = dt('%B %e, %Y', $task['date_completed']) ?>
+
+ |
+
+
+ = t('Open') ?>
+
+ = t('Closed') ?>
+
+ |
+
+
+
+
+= $paginator ?>
diff --git a/assets/css/app.css b/assets/css/app.css
index 03f95c6b8..0e546b9fd 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -347,7 +347,7 @@ input.form-date {
}
input.form-input-large {
- width: 400px;
+ width: 450px;
}
.form-row {
@@ -1404,10 +1404,6 @@ span.task-board-date-overdue {
.dashboard-table-link:hover {
color: #999;
}
-
-#dashboard .sidebar-content {
- font-size: 0.9em;
-}
/* datepicker */
#ui-datepicker-div {
font-size: 0.8em;
diff --git a/assets/css/src/dashboard.css b/assets/css/src/dashboard.css
index 5fd797037..4cd4d4d9c 100644
--- a/assets/css/src/dashboard.css
+++ b/assets/css/src/dashboard.css
@@ -19,7 +19,3 @@
.dashboard-table-link:hover {
color: #999;
}
-
-#dashboard .sidebar-content {
- font-size: 0.9em;
-}
diff --git a/assets/css/src/form.css b/assets/css/src/form.css
index 1c1b8ed21..903bd24e8 100644
--- a/assets/css/src/form.css
+++ b/assets/css/src/form.css
@@ -142,7 +142,7 @@ input.form-date {
}
input.form-input-large {
- width: 400px;
+ width: 450px;
}
.form-row {
diff --git a/tests/units/TaskFilterTest.php b/tests/units/TaskFilterTest.php
index cec303940..33e1792e2 100644
--- a/tests/units/TaskFilterTest.php
+++ b/tests/units/TaskFilterTest.php
@@ -94,25 +94,30 @@ class TaskFilterTest extends Base
$this->assertNotEmpty($tasks);
$this->assertCount(1, $tasks);
$this->assertEquals('task2', $tasks[0]['title']);
+ $this->assertEquals('Feature request', $tasks[0]['category_name']);
$tf->search('category:"hé hé"');
$tasks = $tf->findAll();
$this->assertNotEmpty($tasks);
$this->assertCount(1, $tasks);
$this->assertEquals('task3', $tasks[0]['title']);
+ $this->assertEquals('hé hé', $tasks[0]['category_name']);
$tf->search('category:"Feature request" category:"hé hé"');
$tasks = $tf->findAll();
$this->assertNotEmpty($tasks);
$this->assertCount(2, $tasks);
$this->assertEquals('task2', $tasks[0]['title']);
+ $this->assertEquals('Feature request', $tasks[0]['category_name']);
$this->assertEquals('task3', $tasks[1]['title']);
+ $this->assertEquals('hé hé', $tasks[1]['category_name']);
$tf->search('category:none');
$tasks = $tf->findAll();
$this->assertNotEmpty($tasks);
$this->assertCount(1, $tasks);
$this->assertEquals('task1', $tasks[0]['title']);
+ $this->assertEquals('', $tasks[0]['category_name']);
$tf->search('category:"not found"');
$tasks = $tf->findAll();