Add pagination/column sorting for search and completed tasks
This commit is contained in:
parent
deeebd8e72
commit
b7060b33ef
|
|
@ -30,6 +30,7 @@ use Model\LastLogin;
|
|||
* @property \Model\Task $task
|
||||
* @property \Model\TaskHistory $taskHistory
|
||||
* @property \Model\TaskExport $taskExport
|
||||
* @property \Model\TaskFinder $taskFinder
|
||||
* @property \Model\TaskPermission $taskPermission
|
||||
* @property \Model\TaskValidator $taskValidator
|
||||
* @property \Model\CommentHistory $commentHistory
|
||||
|
|
|
|||
|
|
@ -395,26 +395,31 @@ class Project extends Base
|
|||
{
|
||||
$project = $this->getProject();
|
||||
$search = $this->request->getStringParam('search');
|
||||
$direction = $this->request->getStringParam('direction', 'DESC');
|
||||
$order = $this->request->getStringParam('order', 'tasks.id');
|
||||
$offset = $this->request->getIntegerParam('offset', 0);
|
||||
$tasks = array();
|
||||
$nb_tasks = 0;
|
||||
$limit = 25;
|
||||
|
||||
if ($search !== '') {
|
||||
|
||||
$filters = array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => $project['id']),
|
||||
'or' => array(
|
||||
array('column' => 'title', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
//array('column' => 'description', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
)
|
||||
);
|
||||
|
||||
$tasks = $this->task->find($filters);
|
||||
$nb_tasks = count($tasks);
|
||||
$tasks = $this->taskFinder->search($project['id'], $search, $offset, $limit, $order, $direction);
|
||||
$nb_tasks = $this->taskFinder->countSearch($project['id'], $search);
|
||||
}
|
||||
|
||||
$this->response->html($this->template->layout('project_search', array(
|
||||
'tasks' => $tasks,
|
||||
'nb_tasks' => $nb_tasks,
|
||||
'pagination' => array(
|
||||
'controller' => 'project',
|
||||
'action' => 'search',
|
||||
'params' => array('search' => $search, 'project_id' => $project['id']),
|
||||
'direction' => $direction,
|
||||
'order' => $order,
|
||||
'total' => $nb_tasks,
|
||||
'offset' => $offset,
|
||||
'limit' => $limit,
|
||||
),
|
||||
'values' => array(
|
||||
'search' => $search,
|
||||
'controller' => 'project',
|
||||
|
|
@ -436,16 +441,25 @@ class Project extends Base
|
|||
public function tasks()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$direction = $this->request->getStringParam('direction', 'DESC');
|
||||
$order = $this->request->getStringParam('order', 'tasks.date_completed');
|
||||
$offset = $this->request->getIntegerParam('offset', 0);
|
||||
$limit = 25;
|
||||
|
||||
$filters = array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => $project['id']),
|
||||
array('column' => 'is_active', 'operator' => 'eq', 'value' => TaskModel::STATUS_CLOSED),
|
||||
);
|
||||
|
||||
$tasks = $this->task->find($filters);
|
||||
$nb_tasks = count($tasks);
|
||||
$tasks = $this->taskFinder->getClosedTasks($project['id'], $offset, $limit, $order, $direction);
|
||||
$nb_tasks = $this->task->countByProjectId($project['id'], array(TaskModel::STATUS_CLOSED));
|
||||
|
||||
$this->response->html($this->template->layout('project_tasks', array(
|
||||
'pagination' => array(
|
||||
'controller' => 'project',
|
||||
'action' => 'tasks',
|
||||
'params' => array('project_id' => $project['id']),
|
||||
'direction' => $direction,
|
||||
'order' => $order,
|
||||
'total' => $nb_tasks,
|
||||
'offset' => $offset,
|
||||
'limit' => $limit,
|
||||
),
|
||||
'project' => $project,
|
||||
'columns' => $this->board->getColumnsList($project['id']),
|
||||
'categories' => $this->category->getList($project['id'], false),
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ class Task extends Base
|
|||
if ($this->request->getStringParam('confirmation') === 'yes') {
|
||||
|
||||
$this->checkCSRFParam();
|
||||
$task_id = $this->task->duplicateSameProject($task);
|
||||
$task_id = $this->task->duplicateToSameProject($task);
|
||||
|
||||
if ($task_id) {
|
||||
$this->session->flash(t('Task created successfully.'));
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ use PicoDb\Database;
|
|||
* @property \Model\SubtaskHistory $subtaskHistory
|
||||
* @property \Model\Task $task
|
||||
* @property \Model\TaskExport $taskExport
|
||||
* @property \Model\TaskFinder $taskFinder
|
||||
* @property \Model\TaskHistory $taskHistory
|
||||
* @property \Model\TaskValidator $taskValidator
|
||||
* @property \Model\TimeTracking $timeTracking
|
||||
|
|
|
|||
|
|
@ -234,14 +234,8 @@ class Board extends Base
|
|||
*/
|
||||
public function get($project_id, array $filters = array())
|
||||
{
|
||||
$this->db->startTransaction();
|
||||
|
||||
$columns = $this->getColumns($project_id);
|
||||
|
||||
$filters[] = array('column' => 'project_id', 'operator' => 'eq', 'value' => $project_id);
|
||||
$filters[] = array('column' => 'is_active', 'operator' => 'eq', 'value' => Task::STATUS_OPEN);
|
||||
|
||||
$tasks = $this->task->find($filters);
|
||||
$tasks = $this->taskFinder->getOpenTasks($project_id);
|
||||
|
||||
foreach ($columns as &$column) {
|
||||
|
||||
|
|
@ -254,8 +248,6 @@ class Board extends Base
|
|||
}
|
||||
}
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class Task extends Base
|
|||
}
|
||||
|
||||
/**
|
||||
* Count all tasks for a given project and status
|
||||
* Get all tasks for a given project and status
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Project id
|
||||
|
|
@ -198,166 +198,6 @@ class Task extends Base
|
|||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tasks that match defined filters
|
||||
*
|
||||
* @access public
|
||||
* @param array $filters Filters: [ ['column' => '...', 'operator' => '...', 'value' => '...'], ... ]
|
||||
* @param array $sorting Sorting: [ 'column' => 'date_creation', 'direction' => 'asc']
|
||||
* @return array
|
||||
*/
|
||||
public function find(array $filters, array $sorting = array())
|
||||
{
|
||||
$table = $this->db
|
||||
->table(self::TABLE)
|
||||
->columns(
|
||||
'(SELECT count(*) FROM comments WHERE task_id=tasks.id) AS nb_comments',
|
||||
'(SELECT count(*) FROM task_has_files WHERE task_id=tasks.id) AS nb_files',
|
||||
'(SELECT count(*) FROM task_has_subtasks WHERE task_id=tasks.id) AS nb_subtasks',
|
||||
'(SELECT count(*) FROM task_has_subtasks WHERE task_id=tasks.id AND status=2) AS nb_completed_subtasks',
|
||||
'tasks.id',
|
||||
'tasks.reference',
|
||||
'tasks.title',
|
||||
'tasks.description',
|
||||
'tasks.date_creation',
|
||||
'tasks.date_modification',
|
||||
'tasks.date_completed',
|
||||
'tasks.date_due',
|
||||
'tasks.color_id',
|
||||
'tasks.project_id',
|
||||
'tasks.column_id',
|
||||
'tasks.owner_id',
|
||||
'tasks.creator_id',
|
||||
'tasks.position',
|
||||
'tasks.is_active',
|
||||
'tasks.score',
|
||||
'tasks.category_id',
|
||||
'users.username AS assignee_username',
|
||||
'users.name AS assignee_name'
|
||||
)
|
||||
->join(User::TABLE, 'id', 'owner_id');
|
||||
|
||||
foreach ($filters as $key => $filter) {
|
||||
|
||||
if ($key === 'or') {
|
||||
|
||||
$table->beginOr();
|
||||
|
||||
foreach ($filter as $subfilter) {
|
||||
$table->$subfilter['operator']($subfilter['column'], $subfilter['value']);
|
||||
}
|
||||
|
||||
$table->closeOr();
|
||||
}
|
||||
else if (isset($filter['operator']) && isset($filter['column']) && isset($filter['value'])) {
|
||||
$table->$filter['operator']($filter['column'], $filter['value']);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($sorting)) {
|
||||
$table->orderBy('tasks.position', 'ASC');
|
||||
}
|
||||
else {
|
||||
$table->orderBy($sorting['column'], $sorting['direction']);
|
||||
}
|
||||
|
||||
return $table->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to duplicate a task
|
||||
*
|
||||
* @access public
|
||||
* @param array $task Task data
|
||||
* @param array $override Task properties to override
|
||||
* @return integer|boolean
|
||||
*/
|
||||
public function copy(array $task, array $override = array())
|
||||
{
|
||||
// Values to override
|
||||
if (! empty($override)) {
|
||||
$task = $override + $task;
|
||||
}
|
||||
|
||||
$this->db->startTransaction();
|
||||
|
||||
// Assign new values
|
||||
$values = array();
|
||||
$values['title'] = $task['title'];
|
||||
$values['description'] = $task['description'];
|
||||
$values['date_creation'] = time();
|
||||
$values['date_modification'] = $values['date_creation'];
|
||||
$values['date_due'] = $task['date_due'];
|
||||
$values['color_id'] = $task['color_id'];
|
||||
$values['project_id'] = $task['project_id'];
|
||||
$values['column_id'] = $task['column_id'];
|
||||
$values['owner_id'] = 0;
|
||||
$values['creator_id'] = $task['creator_id'];
|
||||
$values['position'] = $this->countByColumnId($values['project_id'], $values['column_id']) + 1;
|
||||
$values['score'] = $task['score'];
|
||||
$values['category_id'] = 0;
|
||||
|
||||
// Check if the assigned user is allowed for the new project
|
||||
if ($task['owner_id'] && $this->projectPermission->isUserAllowed($values['project_id'], $task['owner_id'])) {
|
||||
$values['owner_id'] = $task['owner_id'];
|
||||
}
|
||||
|
||||
// Check if the category exists
|
||||
if ($task['category_id'] && $this->category->exists($task['category_id'], $task['project_id'])) {
|
||||
$values['category_id'] = $task['category_id'];
|
||||
}
|
||||
|
||||
// Save task
|
||||
if (! $this->db->table(self::TABLE)->save($values)) {
|
||||
$this->db->cancelTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
$task_id = $this->db->getConnection()->getLastId();
|
||||
|
||||
// Duplicate subtasks
|
||||
if (! $this->subTask->duplicate($task['id'], $task_id)) {
|
||||
$this->db->cancelTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
// Trigger events
|
||||
$this->event->trigger(self::EVENT_CREATE_UPDATE, array('task_id' => $task_id) + $values);
|
||||
$this->event->trigger(self::EVENT_CREATE, array('task_id' => $task_id) + $values);
|
||||
|
||||
return $task_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a task to the same project
|
||||
*
|
||||
* @access public
|
||||
* @param array $task Task data
|
||||
* @return integer|boolean
|
||||
*/
|
||||
public function duplicateSameProject($task)
|
||||
{
|
||||
return $this->copy($task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a task to another project (always copy to the first column)
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Destination project id
|
||||
* @param array $task Task data
|
||||
* @return integer|boolean
|
||||
*/
|
||||
public function duplicateToAnotherProject($project_id, array $task)
|
||||
{
|
||||
return $this->copy($task, array(
|
||||
'project_id' => $project_id,
|
||||
'column_id' => $this->board->getFirstColumn($project_id),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare data before task creation or modification
|
||||
*
|
||||
|
|
@ -714,6 +554,100 @@ class Task extends Base
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to duplicate a task
|
||||
*
|
||||
* @access public
|
||||
* @param array $task Task data
|
||||
* @param array $override Task properties to override
|
||||
* @return integer|boolean
|
||||
*/
|
||||
public function copy(array $task, array $override = array())
|
||||
{
|
||||
// Values to override
|
||||
if (! empty($override)) {
|
||||
$task = $override + $task;
|
||||
}
|
||||
|
||||
$this->db->startTransaction();
|
||||
|
||||
// Assign new values
|
||||
$values = array();
|
||||
$values['title'] = $task['title'];
|
||||
$values['description'] = $task['description'];
|
||||
$values['date_creation'] = time();
|
||||
$values['date_modification'] = $values['date_creation'];
|
||||
$values['date_due'] = $task['date_due'];
|
||||
$values['color_id'] = $task['color_id'];
|
||||
$values['project_id'] = $task['project_id'];
|
||||
$values['column_id'] = $task['column_id'];
|
||||
$values['owner_id'] = 0;
|
||||
$values['creator_id'] = $task['creator_id'];
|
||||
$values['position'] = $this->countByColumnId($values['project_id'], $values['column_id']) + 1;
|
||||
$values['score'] = $task['score'];
|
||||
$values['category_id'] = 0;
|
||||
|
||||
// Check if the assigned user is allowed for the new project
|
||||
if ($task['owner_id'] && $this->projectPermission->isUserAllowed($values['project_id'], $task['owner_id'])) {
|
||||
$values['owner_id'] = $task['owner_id'];
|
||||
}
|
||||
|
||||
// Check if the category exists
|
||||
if ($task['category_id'] && $this->category->exists($task['category_id'], $task['project_id'])) {
|
||||
$values['category_id'] = $task['category_id'];
|
||||
}
|
||||
|
||||
// Save task
|
||||
if (! $this->db->table(Task::TABLE)->save($values)) {
|
||||
$this->db->cancelTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
$task_id = $this->db->getConnection()->getLastId();
|
||||
|
||||
// Duplicate subtasks
|
||||
if (! $this->subTask->duplicate($task['id'], $task_id)) {
|
||||
$this->db->cancelTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->db->closeTransaction();
|
||||
|
||||
// Trigger events
|
||||
$this->event->trigger(Task::EVENT_CREATE_UPDATE, array('task_id' => $task_id) + $values);
|
||||
$this->event->trigger(Task::EVENT_CREATE, array('task_id' => $task_id) + $values);
|
||||
|
||||
return $task_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a task to the same project
|
||||
*
|
||||
* @access public
|
||||
* @param array $task Task data
|
||||
* @return integer|boolean
|
||||
*/
|
||||
public function duplicateToSameProject($task)
|
||||
{
|
||||
return $this->copy($task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a task to another project (always copy to the first column)
|
||||
*
|
||||
* @access public
|
||||
* @param integer $project_id Destination project id
|
||||
* @param array $task Task data
|
||||
* @return integer|boolean
|
||||
*/
|
||||
public function duplicateToAnotherProject($project_id, array $task)
|
||||
{
|
||||
return $this->copy($task, array(
|
||||
'project_id' => $project_id,
|
||||
'column_id' => $this->board->getFirstColumn($project_id),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a the task id from a text
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Model;
|
||||
|
||||
/**
|
||||
* Task Finder model
|
||||
*
|
||||
* @package model
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskFinder extends Base
|
||||
{
|
||||
private function prepareRequest()
|
||||
{
|
||||
return $this->db
|
||||
->table(Task::TABLE)
|
||||
->columns(
|
||||
'(SELECT count(*) FROM comments WHERE task_id=tasks.id) AS nb_comments',
|
||||
'(SELECT count(*) FROM task_has_files WHERE task_id=tasks.id) AS nb_files',
|
||||
'(SELECT count(*) FROM task_has_subtasks WHERE task_id=tasks.id) AS nb_subtasks',
|
||||
'(SELECT count(*) FROM task_has_subtasks WHERE task_id=tasks.id AND status=2) AS nb_completed_subtasks',
|
||||
'tasks.id',
|
||||
'tasks.reference',
|
||||
'tasks.title',
|
||||
'tasks.description',
|
||||
'tasks.date_creation',
|
||||
'tasks.date_modification',
|
||||
'tasks.date_completed',
|
||||
'tasks.date_due',
|
||||
'tasks.color_id',
|
||||
'tasks.project_id',
|
||||
'tasks.column_id',
|
||||
'tasks.owner_id',
|
||||
'tasks.creator_id',
|
||||
'tasks.position',
|
||||
'tasks.is_active',
|
||||
'tasks.score',
|
||||
'tasks.category_id',
|
||||
'users.username AS assignee_username',
|
||||
'users.name AS assignee_name'
|
||||
)
|
||||
->join(User::TABLE, 'id', 'owner_id');
|
||||
}
|
||||
|
||||
public function search($project_id, $search, $offset = 0, $limit = 25, $column = 'tasks.id', $direction = 'DESC')
|
||||
{
|
||||
return $this->prepareRequest()
|
||||
->eq('project_id', $project_id)
|
||||
->like('title', '%'.$search.'%')
|
||||
->offset($offset)
|
||||
->limit($limit)
|
||||
->orderBy($column, $direction)
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function countSearch($project_id, $search)
|
||||
{
|
||||
return $this->db->table(Task::TABLE)
|
||||
->eq('project_id', $project_id)
|
||||
->like('title', '%'.$search.'%')
|
||||
->count();
|
||||
}
|
||||
|
||||
public function getClosedTasks($project_id, $offset = 0, $limit = 25, $column = 'tasks.date_completed', $direction = 'DESC')
|
||||
{
|
||||
return $this->prepareRequest()
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', Task::STATUS_CLOSED)
|
||||
->offset($offset)
|
||||
->limit($limit)
|
||||
->orderBy($column, $direction)
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function getOpenTasks($project_id, $column = 'tasks.position', $direction = 'ASC')
|
||||
{
|
||||
return $this->prepareRequest()
|
||||
->eq('project_id', $project_id)
|
||||
->eq('is_active', Task::STATUS_OPEN)
|
||||
->orderBy($column, $direction)
|
||||
->findAll();
|
||||
}
|
||||
}
|
||||
|
|
@ -7,10 +7,10 @@
|
|||
<?php endif ?>
|
||||
</h2>
|
||||
<ul>
|
||||
<li><a href="?controller=board&action=show&project_id=<?= $project['id'] ?>"><?= t('Back to the board') ?></a></li>
|
||||
<li><a href="?controller=project&action=tasks&project_id=<?= $project['id'] ?>"><?= t('Completed tasks') ?></a></li>
|
||||
<li><a href="?controller=project&action=activity&project_id=<?= $project['id'] ?>"><?= t('Activity') ?></a></li>
|
||||
<li><a href="?controller=project&action=index"><?= t('List of projects') ?></a></li>
|
||||
<li><?= Helper\a(t('Back to the board'), 'board', 'show', array('project_id' => $project['id'])) ?></li>
|
||||
<li><?= Helper\a(t('Completed tasks'), 'project', 'tasks', array('project_id' => $project['id'])) ?></li>
|
||||
<li><?= Helper\a(t('Activity'), 'project', 'activity', array('project_id' => $project['id'])) ?></li>
|
||||
<li><?= Helper\a(t('List of projects'), 'project', 'index') ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<section>
|
||||
|
|
@ -25,7 +25,12 @@
|
|||
<?php if (empty($tasks) && ! empty($values['search'])): ?>
|
||||
<p class="alert"><?= t('Nothing found.') ?></p>
|
||||
<?php elseif (! empty($tasks)): ?>
|
||||
<?= Helper\template('task_table', array('tasks' => $tasks, 'categories' => $categories, 'columns' => $columns)) ?>
|
||||
<?= Helper\template('task_table', array(
|
||||
'tasks' => $tasks,
|
||||
'categories' => $categories,
|
||||
'columns' => $columns,
|
||||
'pagination' => $pagination,
|
||||
)) ?>
|
||||
<?php endif ?>
|
||||
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@
|
|||
<?php if (empty($tasks)): ?>
|
||||
<p class="alert"><?= t('No task') ?></p>
|
||||
<?php else: ?>
|
||||
<?= Helper\template('task_table', array('tasks' => $tasks, 'categories' => $categories, 'columns' => $columns)) ?>
|
||||
<?= Helper\template('task_table', array(
|
||||
'tasks' => $tasks,
|
||||
'categories' => $categories,
|
||||
'columns' => $columns,
|
||||
'pagination' => $pagination,
|
||||
)) ?>
|
||||
<?php endif ?>
|
||||
</section>
|
||||
</section>
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
<table>
|
||||
<tr>
|
||||
<th><?= t('Id') ?></th>
|
||||
<th><?= t('Column') ?></th>
|
||||
<th><?= t('Category') ?></th>
|
||||
<th><?= t('Title') ?></th>
|
||||
<th><?= t('Assignee') ?></th>
|
||||
<th><?= t('Due date') ?></th>
|
||||
<th><?= t('Date created') ?></th>
|
||||
<th><?= t('Date completed') ?></th>
|
||||
<th><?= t('Status') ?></th>
|
||||
<th><?= Helper\order(t('Id'), 'tasks.id', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Column'), 'tasks.column_id', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Category'), 'tasks.category_id', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Title'), 'tasks.title', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Assignee'), 'users.username', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Due date'), 'tasks.date_due', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Date created'), 'tasks.date_creation', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Date completed'), 'tasks.date_completed', $pagination) ?></th>
|
||||
<th><?= Helper\order(t('Status'), 'tasks.is_active', $pagination) ?></th>
|
||||
</tr>
|
||||
<?php foreach ($tasks as $task): ?>
|
||||
<tr>
|
||||
|
|
@ -51,4 +51,6 @@
|
|||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
<?= Helper\paginate($pagination) ?>
|
||||
|
|
|
|||
|
|
@ -590,3 +590,65 @@ function u($controller, $action, array $params = array(), $csrf = false)
|
|||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pagination links
|
||||
*
|
||||
* @param array $pagination Pagination information
|
||||
* @return string
|
||||
*/
|
||||
function paginate(array $pagination)
|
||||
{
|
||||
extract($pagination);
|
||||
|
||||
$html = '<div id="pagination">';
|
||||
$html .= '<span id="pagination-previous">';
|
||||
|
||||
if ($pagination['offset'] > 0) {
|
||||
$offset = $pagination['offset'] - $limit;
|
||||
$html .= a('← '.t('Previous'), $controller, $action, $params + compact('offset', 'order', 'direction'));
|
||||
}
|
||||
else {
|
||||
$html .= '← '.t('Previous');
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
$html .= '<span id="pagination-next">';
|
||||
|
||||
if (($total - $pagination['offset']) > $limit) {
|
||||
$offset = $pagination['offset'] + $limit;
|
||||
$html .= a(t('Next').' →', $controller, $action, $params + compact('offset', 'order', 'direction'));
|
||||
}
|
||||
else {
|
||||
$html .= t('Next').' →';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Column sorting (work with pagination)
|
||||
*
|
||||
* @param string $label Column title
|
||||
* @param string $column SQL column name
|
||||
* @param array $pagination Pagination information
|
||||
* @return string
|
||||
*/
|
||||
function order($label, $column, array $pagination)
|
||||
{
|
||||
extract($pagination);
|
||||
|
||||
$prefix = '';
|
||||
|
||||
if ($order === $column) {
|
||||
$prefix = $direction === 'DESC' ? '▼ ' : '▲ ';
|
||||
$direction = $direction === 'DESC' ? 'ASC' : 'DESC';
|
||||
}
|
||||
|
||||
$order = $column;
|
||||
|
||||
return $prefix.a($label, $controller, $action, $params + compact('offset', 'order', 'direction'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,16 @@ td li {
|
|||
background: rgb(219, 235, 255)
|
||||
}
|
||||
|
||||
th a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
th a:focus,
|
||||
th a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* forms */
|
||||
form {
|
||||
padding: 10px;
|
||||
|
|
@ -1129,6 +1139,19 @@ tr td.task-orange,
|
|||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/* pagination */
|
||||
#pagination {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#pagination-next {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#pagination-previous {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* responsive design */
|
||||
@media only screen and (min-width : 768px) and (max-width : 1024px) {
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ foreach (array(1, 2, 3, 4) as $column_id) {
|
|||
'owner_id' => rand(0, 1),
|
||||
'color_id' => rand(0, 1) === 0 ? 'green' : 'purple',
|
||||
'score' => rand(0, 21),
|
||||
'is_active' => rand(0, 1),
|
||||
);
|
||||
|
||||
$taskModel->create($task);
|
||||
|
|
|
|||
|
|
@ -493,75 +493,6 @@ class TaskTest extends Base
|
|||
$this->assertEquals($task_per_column + 1, $t->countByColumnId(1, 4));
|
||||
}
|
||||
|
||||
public function testFilter()
|
||||
{
|
||||
$t = new Task($this->registry);
|
||||
$p = new Project($this->registry);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $t->create(array('title' => 'test a', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1, 'description' => 'biloute')));
|
||||
$this->assertEquals(2, $t->create(array('title' => 'test b', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 2, 'description' => 'toto et titi sont dans un bateau')));
|
||||
|
||||
$tasks = $t->find(array(array('column' => 'project_id', 'operator' => 'eq', 'value' => '1')));
|
||||
$this->assertNotFalse($tasks);
|
||||
$this->assertEquals(2, count($tasks));
|
||||
$this->assertEquals(1, $tasks[0]['id']);
|
||||
$this->assertEquals(2, $tasks[1]['id']);
|
||||
|
||||
$tasks = $t->find(array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => '1'),
|
||||
array('column' => 'owner_id', 'operator' => 'eq', 'value' => '2'),
|
||||
));
|
||||
$this->assertEquals(1, count($tasks));
|
||||
$this->assertEquals(2, $tasks[0]['id']);
|
||||
|
||||
$tasks = $t->find(array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => '1'),
|
||||
array('column' => 'title', 'operator' => 'like', 'value' => '%b%'),
|
||||
));
|
||||
$this->assertEquals(1, count($tasks));
|
||||
$this->assertEquals(2, $tasks[0]['id']);
|
||||
|
||||
// Condition with OR
|
||||
$search = 'bateau';
|
||||
$filters = array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => 1),
|
||||
'or' => array(
|
||||
array('column' => 'title', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
array('column' => 'description', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
)
|
||||
);
|
||||
|
||||
$tasks = $t->find($filters);
|
||||
$this->assertEquals(1, count($tasks));
|
||||
$this->assertEquals(2, $tasks[0]['id']);
|
||||
|
||||
$search = 'toto et titi';
|
||||
$filters = array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => 1),
|
||||
'or' => array(
|
||||
array('column' => 'title', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
array('column' => 'description', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
)
|
||||
);
|
||||
|
||||
$tasks = $t->find($filters);
|
||||
$this->assertEquals(1, count($tasks));
|
||||
$this->assertEquals(2, $tasks[0]['id']);
|
||||
|
||||
$search = 'john';
|
||||
$filters = array(
|
||||
array('column' => 'project_id', 'operator' => 'eq', 'value' => 1),
|
||||
'or' => array(
|
||||
array('column' => 'title', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
array('column' => 'description', 'operator' => 'like', 'value' => '%'.$search.'%'),
|
||||
)
|
||||
);
|
||||
|
||||
$tasks = $t->find($filters);
|
||||
$this->assertEquals(0, count($tasks));
|
||||
}
|
||||
|
||||
public function testDuplicateToTheSameProject()
|
||||
{
|
||||
$t = new Task($this->registry);
|
||||
|
|
@ -584,7 +515,7 @@ class TaskTest extends Base
|
|||
$this->assertEquals(1, $task['position']);
|
||||
|
||||
// We duplicate our task
|
||||
$this->assertEquals(2, $t->duplicateSameProject($task));
|
||||
$this->assertEquals(2, $t->duplicateToSameProject($task));
|
||||
$this->assertTrue($this->registry->shared('event')->isEventTriggered(Task::EVENT_CREATE));
|
||||
|
||||
// Check the values of the duplicated task
|
||||
|
|
|
|||
Loading…
Reference in New Issue