summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--app/Api/Procedure/MeProcedure.php15
-rw-r--r--app/Controller/ActivityController.php2
-rw-r--r--app/Controller/DashboardController.php58
-rw-r--r--app/Core/Base.php5
-rw-r--r--app/Formatter/TaskListSubtaskAssigneeFormatter.php43
-rw-r--r--app/Helper/LayoutHelper.php13
-rw-r--r--app/Model/ProjectModel.php21
-rw-r--r--app/Model/SubtaskModel.php67
-rw-r--r--app/Model/TaskFinderModel.php24
-rw-r--r--app/Pagination/DashboardPagination.php50
-rw-r--r--app/Pagination/ProjectPagination.php35
-rw-r--r--app/Pagination/SubtaskPagination.php39
-rw-r--r--app/Pagination/TaskPagination.php38
-rw-r--r--app/Pagination/UserPagination.php2
-rw-r--r--app/ServiceProvider/ClassProvider.php4
-rw-r--r--app/ServiceProvider/FormatterProvider.php1
-rw-r--r--app/Template/dashboard/layout.php31
-rw-r--r--app/Template/dashboard/projects.php55
-rw-r--r--app/Template/dashboard/show.php70
-rw-r--r--app/Template/dashboard/sidebar.php17
-rw-r--r--app/Template/dashboard/subtasks.php45
-rw-r--r--app/Template/dashboard/tasks.php53
-rw-r--r--app/Template/task_list/listing.php64
-rw-r--r--doc/en_US/plugin-hooks.markdown3
-rw-r--r--tests/integration/MeProcedureTest.php6
-rw-r--r--tests/units/Model/SubtaskModelTest.php29
-rw-r--r--tests/units/Pagination/DashboardPaginationTest.php121
-rw-r--r--tests/units/Pagination/ProjectPaginationTest.php35
-rw-r--r--tests/units/Pagination/SubtaskPaginationTest.php53
-rw-r--r--tests/units/Pagination/TaskPaginationTest.php30
31 files changed, 380 insertions, 650 deletions
diff --git a/ChangeLog b/ChangeLog
index 2264ab98..2d68c864 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@ New features:
Improvements:
+* Simplify dashboard to use new tasks list view
* Move notifications outside of dashboard
* Render QR code for TwoFactor authentication without Google Chart API
* Add toggle button to show/hide subtasks in task list view
diff --git a/app/Api/Procedure/MeProcedure.php b/app/Api/Procedure/MeProcedure.php
index 71d5555b..3ba73fdd 100644
--- a/app/Api/Procedure/MeProcedure.php
+++ b/app/Api/Procedure/MeProcedure.php
@@ -2,8 +2,6 @@
namespace Kanboard\Api\Procedure;
-use Kanboard\Model\SubtaskModel;
-
/**
* Me API controller
*
@@ -19,15 +17,12 @@ class MeProcedure extends BaseProcedure
public function getMyDashboard()
{
- $user_id = $this->userSession->getId();
- $projects = $this->projectModel->getQueryColumnStats($this->projectPermissionModel->getActiveProjectIds($user_id))->findAll();
- $tasks = $this->taskFinderModel->getUserQuery($user_id)->findAll();
+ $userId = $this->userSession->getId();
- return array(
- 'projects' => $this->formatProjects($projects),
- 'tasks' => $this->formatTasks($tasks),
- 'subtasks' => $this->subtaskModel->getUserQuery($user_id, array(SubtaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS))->findAll(),
- );
+ return $this->taskListSubtaskAssigneeFormatter
+ ->withQuery($this->taskFinderModel->getUserQuery($userId))
+ ->withUserId($userId)
+ ->format();
}
public function getMyActivityStream()
diff --git a/app/Controller/ActivityController.php b/app/Controller/ActivityController.php
index a1734af1..7a58e670 100644
--- a/app/Controller/ActivityController.php
+++ b/app/Controller/ActivityController.php
@@ -19,7 +19,7 @@ class ActivityController extends BaseController
{
$user = $this->getUser();
- $this->response->html($this->helper->layout->dashboard('activity/user', array(
+ $this->response->html($this->template->render('activity/user', array(
'title' => t('Activity stream for %s', $this->helper->user->getFullname($user)),
'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermissionModel->getActiveProjectIds($user['id']), 100),
'user' => $user,
diff --git a/app/Controller/DashboardController.php b/app/Controller/DashboardController.php
index 7fdc53ff..ef7d8772 100644
--- a/app/Controller/DashboardController.php
+++ b/app/Controller/DashboardController.php
@@ -19,60 +19,10 @@ class DashboardController extends BaseController
{
$user = $this->getUser();
- $this->response->html($this->helper->layout->dashboard('dashboard/show', array(
- 'title' => t('Dashboard for %s', $this->helper->user->getFullname($user)),
- 'project_paginator' => $this->projectPagination->getDashboardPaginator($user['id'], 'show', 10),
- 'task_paginator' => $this->taskPagination->getDashboardPaginator($user['id'], 'show', 10),
- 'subtask_paginator' => $this->subtaskPagination->getDashboardPaginator($user['id'], 'show', 10),
- 'user' => $user,
- )));
- }
-
- /**
- * My tasks
- *
- * @access public
- */
- public function tasks()
- {
- $user = $this->getUser();
-
- $this->response->html($this->helper->layout->dashboard('dashboard/tasks', array(
- 'title' => t('Tasks overview for %s', $this->helper->user->getFullname($user)),
- 'paginator' => $this->taskPagination->getDashboardPaginator($user['id'], 'tasks', 50),
- 'user' => $user,
- )));
- }
-
- /**
- * My subtasks
- *
- * @access public
- */
- public function subtasks()
- {
- $user = $this->getUser();
-
- $this->response->html($this->helper->layout->dashboard('dashboard/subtasks', array(
- 'title' => t('Subtasks overview for %s', $this->helper->user->getFullname($user)),
- 'paginator' => $this->subtaskPagination->getDashboardPaginator($user['id'], 'subtasks', 50),
- 'user' => $user,
- )));
- }
-
- /**
- * My projects
- *
- * @access public
- */
- public function projects()
- {
- $user = $this->getUser();
-
- $this->response->html($this->helper->layout->dashboard('dashboard/projects', array(
- 'title' => t('Projects overview for %s', $this->helper->user->getFullname($user)),
- 'paginator' => $this->projectPagination->getDashboardPaginator($user['id'], 'projects', 25),
- 'user' => $user,
+ $this->response->html($this->helper->layout->app('dashboard/show', array(
+ 'title' => t('Dashboard for %s', $this->helper->user->getFullname($user)),
+ 'user' => $user,
+ 'results' => $this->dashboardPagination->getOverview($user['id']),
)));
}
}
diff --git a/app/Core/Base.php b/app/Core/Base.php
index 28bbd534..b9cdf5ad 100644
--- a/app/Core/Base.php
+++ b/app/Core/Base.php
@@ -77,6 +77,7 @@ use Pimple\Container;
* @property \Kanboard\Formatter\TaskICalFormatter $taskICalFormatter
* @property \Kanboard\Formatter\TaskListFormatter $taskListFormatter
* @property \Kanboard\Formatter\TaskListSubtaskFormatter $taskListSubtaskFormatter
+ * @property \Kanboard\Formatter\TaskListSubtaskAssigneeFormatter $taskListSubtaskAssigneeFormatter
* @property \Kanboard\Formatter\TaskSuggestMenuFormatter $taskSuggestMenuFormatter
* @property \Kanboard\Formatter\UserAutoCompleteFormatter $userAutoCompleteFormatter
* @property \Kanboard\Formatter\UserMentionFormatter $userMentionFormatter
@@ -151,9 +152,7 @@ use Pimple\Container;
* @property \Kanboard\Model\UserNotificationFilterModel $userNotificationFilterModel
* @property \Kanboard\Model\UserUnreadNotificationModel $userUnreadNotificationModel
* @property \Kanboard\Model\UserMetadataModel $userMetadataModel
- * @property \Kanboard\Pagination\TaskPagination $taskPagination
- * @property \Kanboard\Pagination\SubtaskPagination $subtaskPagination
- * @property \Kanboard\Pagination\ProjectPagination $projectPagination
+ * @property \Kanboard\Pagination\DashboardPagination $dashboardPagination
* @property \Kanboard\Pagination\UserPagination $userPagination
* @property \Kanboard\Validator\ActionValidator $actionValidator
* @property \Kanboard\Validator\AuthValidator $authValidator
diff --git a/app/Formatter/TaskListSubtaskAssigneeFormatter.php b/app/Formatter/TaskListSubtaskAssigneeFormatter.php
new file mode 100644
index 00000000..50b08cd8
--- /dev/null
+++ b/app/Formatter/TaskListSubtaskAssigneeFormatter.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Kanboard\Formatter;
+
+/**
+ * Class TaskListSubtaskAssigneeFormatter
+ *
+ * @package Kanboard\Formatter
+ * @author Frederic Guillot
+ */
+class TaskListSubtaskAssigneeFormatter extends TaskListFormatter
+{
+ protected $userId = 0;
+
+ /**
+ * Set assignee
+ *
+ * @param integer $userId
+ * @return $this
+ */
+ public function withUserId($userId)
+ {
+ $this->userId = $userId;
+ return $this;
+ }
+
+ /**
+ * Apply formatter
+ *
+ * @access public
+ * @return array
+ */
+ public function format()
+ {
+ $tasks = parent::format();
+ $taskIds = array_column($tasks, 'id');
+ $subtasks = $this->subtaskModel->getAllByTaskIdsAndAssignee($taskIds, $this->userId);
+ $subtasks = array_column_index($subtasks, 'task_id');
+ array_merge_relation($tasks, $subtasks, 'subtasks', 'id');
+
+ return $tasks;
+ }
+}
diff --git a/app/Helper/LayoutHelper.php b/app/Helper/LayoutHelper.php
index 91745f58..52c83fec 100644
--- a/app/Helper/LayoutHelper.php
+++ b/app/Helper/LayoutHelper.php
@@ -141,19 +141,6 @@ class LayoutHelper extends Base
}
/**
- * Common layout for dashboard views
- *
- * @access public
- * @param string $template
- * @param array $params
- * @return string
- */
- public function dashboard($template, array $params)
- {
- return $this->subLayout('dashboard/layout', 'dashboard/sidebar', $template, $params);
- }
-
- /**
* Common layout for analytic views
*
* @access public
diff --git a/app/Model/ProjectModel.php b/app/Model/ProjectModel.php
index aa7c002d..f59cae85 100644
--- a/app/Model/ProjectModel.php
+++ b/app/Model/ProjectModel.php
@@ -297,27 +297,6 @@ class ProjectModel extends Base
}
/**
- * Get project summary for a list of project
- *
- * @access public
- * @param array $project_ids List of project id
- * @return \PicoDb\Table
- */
- public function getQueryColumnStats(array $project_ids)
- {
- if (empty($project_ids)) {
- return $this->db->table(ProjectModel::TABLE)->eq(ProjectModel::TABLE.'.id', 0);
- }
-
- return $this->db
- ->table(ProjectModel::TABLE)
- ->columns(self::TABLE.'.*', UserModel::TABLE.'.username AS owner_username', UserModel::TABLE.'.name AS owner_name')
- ->join(UserModel::TABLE, 'id', 'owner_id')
- ->in(self::TABLE.'.id', $project_ids)
- ->callback(array($this, 'applyColumnStats'));
- }
-
- /**
* Get query for list of project without column statistics
*
* @access public
diff --git a/app/Model/SubtaskModel.php b/app/Model/SubtaskModel.php
index c62ddb53..9d047d90 100644
--- a/app/Model/SubtaskModel.php
+++ b/app/Model/SubtaskModel.php
@@ -70,35 +70,6 @@ class SubtaskModel extends Base
}
/**
- * Get the query to fetch subtasks assigned to a user
- *
- * @access public
- * @param integer $userId
- * @param array $status
- * @return \PicoDb\Table
- */
- public function getUserQuery($userId, array $status)
- {
- return $this->db->table(SubtaskModel::TABLE)
- ->columns(
- SubtaskModel::TABLE.'.*',
- TaskModel::TABLE.'.project_id',
- TaskModel::TABLE.'.color_id',
- TaskModel::TABLE.'.title AS task_name',
- ProjectModel::TABLE.'.name AS project_name'
- )
- ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($userId), 'timer_start_date')
- ->eq('user_id', $userId)
- ->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE)
- ->eq(ColumnModel::TABLE.'.hide_in_dashboard', 0)
- ->in(SubtaskModel::TABLE.'.status', $status)
- ->join(TaskModel::TABLE, 'id', 'task_id')
- ->join(ProjectModel::TABLE, 'id', 'project_id', TaskModel::TABLE)
- ->join(ColumnModel::TABLE, 'id', 'column_id', TaskModel::TABLE)
- ->callback(array($this, 'addStatusName'));
- }
-
- /**
* Get common query
*
* @return \PicoDb\Table
@@ -149,6 +120,24 @@ class SubtaskModel extends Base
}
/**
+ * Get subtasks for a list of tasks and a given assignee
+ *
+ * @param array $taskIds
+ * @param integer $userId
+ * @return array
+ */
+ public function getAllByTaskIdsAndAssignee(array $taskIds, $userId)
+ {
+ if (empty($taskIds)) {
+ return array();
+ }
+
+ return $this->subtaskListFormatter
+ ->withQuery($this->getQuery()->in('task_id', $taskIds)->eq(self::TABLE.'.user_id', $userId))
+ ->format();
+ }
+
+ /**
* Get a subtask by the id
*
* @access public
@@ -310,24 +299,4 @@ class SubtaskModel extends Base
$values['user_id'] = isset($values['user_id']) ? $values['user_id'] : 0;
$this->hook->reference('model:subtask:creation:prepare', $values);
}
-
- /**
- * Add subtask status status to the resultset
- *
- * @access public
- * @param array $subtasks Subtasks
- * @return array
- */
- public function addStatusName(array $subtasks)
- {
- $status = $this->getStatusList();
-
- foreach ($subtasks as &$subtask) {
- $subtask['status_name'] = $status[$subtask['status']];
- $subtask['timer_start_date'] = isset($subtask['timer_start_date']) ? $subtask['timer_start_date'] : 0;
- $subtask['is_timer_started'] = ! empty($subtask['timer_start_date']);
- }
-
- return $subtasks;
- }
}
diff --git a/app/Model/TaskFinderModel.php b/app/Model/TaskFinderModel.php
index b610a371..09193a41 100644
--- a/app/Model/TaskFinderModel.php
+++ b/app/Model/TaskFinderModel.php
@@ -59,27 +59,11 @@ class TaskFinderModel extends Base
*/
public function getUserQuery($user_id)
{
- return $this->db
- ->table(TaskModel::TABLE)
- ->columns(
- TaskModel::TABLE.'.id',
- TaskModel::TABLE.'.title',
- TaskModel::TABLE.'.date_due',
- TaskModel::TABLE.'.date_creation',
- TaskModel::TABLE.'.project_id',
- TaskModel::TABLE.'.column_id',
- TaskModel::TABLE.'.color_id',
- TaskModel::TABLE.'.priority',
- TaskModel::TABLE.'.time_spent',
- TaskModel::TABLE.'.time_estimated',
- TaskModel::TABLE.'.is_active',
- TaskModel::TABLE.'.creator_id',
- ProjectModel::TABLE.'.name AS project_name',
- ColumnModel::TABLE.'.title AS column_title'
- )
- ->join(ProjectModel::TABLE, 'id', 'project_id')
- ->join(ColumnModel::TABLE, 'id', 'column_id')
+ return $this->getExtendedQuery()
+ ->beginOr()
->eq(TaskModel::TABLE.'.owner_id', $user_id)
+ ->addCondition(TaskModel::TABLE.".id IN (SELECT task_id FROM ".SubtaskModel::TABLE." WHERE ".SubtaskModel::TABLE.".user_id='$user_id')")
+ ->closeOr()
->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_OPEN)
->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE)
->eq(ColumnModel::TABLE.'.hide_in_dashboard', 0);
diff --git a/app/Pagination/DashboardPagination.php b/app/Pagination/DashboardPagination.php
new file mode 100644
index 00000000..b8fc4434
--- /dev/null
+++ b/app/Pagination/DashboardPagination.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Kanboard\Pagination;
+
+use Kanboard\Core\Base;
+use Kanboard\Model\ProjectModel;
+use Kanboard\Model\TaskModel;
+
+/**
+ * Class DashboardPagination
+ *
+ * @package Kanboard\Pagination
+ * @author Frederic Guillot
+ */
+class DashboardPagination extends Base
+{
+ /**
+ * Get user listing pagination
+ *
+ * @access public
+ * @param integer $userId
+ * @return array
+ */
+ public function getOverview($userId)
+ {
+ $paginators = array();
+ $projects = $this->projectUserRoleModel->getActiveProjectsByUser($userId);
+
+ foreach ($projects as $projectId => $projectName) {
+ $paginator = $this->paginator
+ ->setUrl('DashboardController', 'show', array('user_id' => $userId))
+ ->setMax(50)
+ ->setOrder(TaskModel::TABLE.'.priority')
+ ->setDirection('DESC')
+ ->setFormatter($this->taskListSubtaskAssigneeFormatter->withUserId($userId))
+ ->setQuery($this->taskFinderModel->getUserQuery($userId)->eq(ProjectModel::TABLE.'.id', $projectId))
+ ->calculate();
+
+ if ($paginator->getTotal() > 0) {
+ $paginators[] = array(
+ 'project_id' => $projectId,
+ 'project_name' => $projectName,
+ 'paginator' => $paginator,
+ );
+ }
+ }
+
+ return $paginators;
+ }
+}
diff --git a/app/Pagination/ProjectPagination.php b/app/Pagination/ProjectPagination.php
deleted file mode 100644
index 8f1fa87c..00000000
--- a/app/Pagination/ProjectPagination.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-namespace Kanboard\Pagination;
-
-use Kanboard\Core\Base;
-use Kanboard\Core\Paginator;
-use Kanboard\Model\ProjectModel;
-
-/**
- * Class ProjectPagination
- *
- * @package Kanboard\Pagination
- * @author Frederic Guillot
- */
-class ProjectPagination extends Base
-{
- /**
- * Get dashboard pagination
- *
- * @access public
- * @param integer $user_id
- * @param string $method
- * @param integer $max
- * @return Paginator
- */
- public function getDashboardPaginator($user_id, $method, $max)
- {
- return $this->paginator
- ->setUrl('DashboardController', $method, array('pagination' => 'projects', 'user_id' => $user_id))
- ->setMax($max)
- ->setOrder(ProjectModel::TABLE.'.name')
- ->setQuery($this->projectModel->getQueryColumnStats($this->projectPermissionModel->getActiveProjectIds($user_id)))
- ->calculateOnlyIf($this->request->getStringParam('pagination') === 'projects');
- }
-}
diff --git a/app/Pagination/SubtaskPagination.php b/app/Pagination/SubtaskPagination.php
deleted file mode 100644
index c55d0fb4..00000000
--- a/app/Pagination/SubtaskPagination.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-namespace Kanboard\Pagination;
-
-use Kanboard\Core\Base;
-use Kanboard\Core\Paginator;
-use Kanboard\Model\SubtaskModel;
-use Kanboard\Model\TaskModel;
-
-/**
- * Class SubtaskPagination
- *
- * @package Kanboard\Pagination
- * @author Frederic Guillot
- */
-class SubtaskPagination extends Base
-{
- /**
- * Get dashboard pagination
- *
- * @access public
- * @param integer $user_id
- * @param string $method
- * @param integer $max
- * @return Paginator
- */
- public function getDashboardPaginator($user_id, $method, $max)
- {
- $query = $this->subtaskModel->getUserQuery($user_id, array(SubtaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS));
- $this->hook->reference('pagination:dashboard:subtask:query', $query);
-
- return $this->paginator
- ->setUrl('DashboardController', $method, array('pagination' => 'subtasks', 'user_id' => $user_id))
- ->setMax($max)
- ->setOrder(TaskModel::TABLE.'.id')
- ->setQuery($query)
- ->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks');
- }
-}
diff --git a/app/Pagination/TaskPagination.php b/app/Pagination/TaskPagination.php
deleted file mode 100644
index 5fe986e7..00000000
--- a/app/Pagination/TaskPagination.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-namespace Kanboard\Pagination;
-
-use Kanboard\Core\Base;
-use Kanboard\Core\Paginator;
-use Kanboard\Model\TaskModel;
-
-/**
- * Class TaskPagination
- *
- * @package Kanboard\Pagination
- * @author Frederic Guillot
- */
-class TaskPagination extends Base
-{
- /**
- * Get dashboard pagination
- *
- * @access public
- * @param integer $user_id
- * @param string $method
- * @param integer $max
- * @return Paginator
- */
- public function getDashboardPaginator($user_id, $method, $max)
- {
- $query = $this->taskFinderModel->getUserQuery($user_id);
- $this->hook->reference('pagination:dashboard:task:query', $query);
-
- return $this->paginator
- ->setUrl('DashboardController', $method, array('pagination' => 'tasks', 'user_id' => $user_id))
- ->setMax($max)
- ->setOrder(TaskModel::TABLE.'.id')
- ->setQuery($query)
- ->calculateOnlyIf($this->request->getStringParam('pagination') === 'tasks');
- }
-}
diff --git a/app/Pagination/UserPagination.php b/app/Pagination/UserPagination.php
index 430b7d2f..87688573 100644
--- a/app/Pagination/UserPagination.php
+++ b/app/Pagination/UserPagination.php
@@ -15,7 +15,7 @@ use Kanboard\Model\UserModel;
class UserPagination extends Base
{
/**
- * Get user listing paginator
+ * Get user listing pagination
*
* @access public
* @return Paginator
diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php
index d66794df..f510b80b 100644
--- a/app/ServiceProvider/ClassProvider.php
+++ b/app/ServiceProvider/ClassProvider.php
@@ -129,9 +129,7 @@ class ClassProvider implements ServiceProviderInterface
'TransitionExport',
),
'Pagination' => array(
- 'TaskPagination',
- 'SubtaskPagination',
- 'ProjectPagination',
+ 'DashboardPagination',
'UserPagination',
),
'Core' => array(
diff --git a/app/ServiceProvider/FormatterProvider.php b/app/ServiceProvider/FormatterProvider.php
index feaa597f..8af5f9fa 100644
--- a/app/ServiceProvider/FormatterProvider.php
+++ b/app/ServiceProvider/FormatterProvider.php
@@ -31,6 +31,7 @@ class FormatterProvider implements ServiceProviderInterface
'TaskICalFormatter',
'TaskListFormatter',
'TaskListSubtaskFormatter',
+ 'TaskListSubtaskAssigneeFormatter',
'TaskSuggestMenuFormatter',
'UserAutoCompleteFormatter',
'UserMentionFormatter',
diff --git a/app/Template/dashboard/layout.php b/app/Template/dashboard/layout.php
deleted file mode 100644
index dbd16886..00000000
--- a/app/Template/dashboard/layout.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<section id="main">
- <div class="page-header">
- <ul>
- <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
- <li>
- <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
- </li>
- <?php endif ?>
- <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
- <li>
- <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
- </li>
- <?php endif ?>
- <li>
- <?= $this->url->icon('folder', t('Project management'), 'ProjectListController', 'show') ?>
- </li>
- <li>
- <?= $this->modal->medium('dashboard', t('My activity stream'), 'ActivityController', 'user') ?>
- </li>
- <li>
- <?= $this->modal->medium('calendar', t('My calendar'), 'CalendarController', 'user') ?>
- </li>
- </ul>
- </div>
- <section class="sidebar-container" id="dashboard">
- <?= $this->render($sidebar_template, array('user' => $user)) ?>
- <div class="sidebar-content">
- <?= $content_for_sublayout ?>
- </div>
- </section>
-</section>
diff --git a/app/Template/dashboard/projects.php b/app/Template/dashboard/projects.php
deleted file mode 100644
index 7e35b059..00000000
--- a/app/Template/dashboard/projects.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<div class="page-header">
- <h2><?= $this->url->link(t('My projects'), 'DashboardController', 'projects', array('user_id' => $user['id'])) ?> (<?= $paginator->getTotal() ?>)</h2>
-</div>
-<?php if ($paginator->isEmpty()): ?>
- <p class="alert"><?= t('Your are not member of any project.') ?></p>
-<?php else: ?>
- <table class="table-striped table-small table-scrolling">
- <tr>
- <th class="column-5"><?= $paginator->order('Id', \Kanboard\Model\ProjectModel::TABLE.'.id') ?></th>
- <th class="column-3"><?= $paginator->order('<i class="fa fa-lock fa-fw" title="'.t('Private project').'"></i>', \Kanboard\Model\ProjectModel::TABLE.'.is_private') ?></th>
- <th class="column-25"><?= $paginator->order(t('Project'), \Kanboard\Model\ProjectModel::TABLE.'.name') ?></th>
- <th class="column-10"><?= t('Tasks') ?></th>
- <th><?= t('Columns') ?></th>
- </tr>
- <?php foreach ($paginator->getCollection() as $project): ?>
- <tr>
- <td>
- <?= $this->render('project/dropdown', array('project' => $project)) ?>
- </td>
- <td>
- <?php if ($project['is_private']): ?>
- <i class="fa fa-lock fa-fw" title="<?= t('Private project') ?>"></i>
- <?php endif ?>
- </td>
- <td>
- <?php if ($this->user->hasProjectAccess('TaskGanttController', 'show', $project['id'])): ?>
- <?= $this->url->link('<i class="fa fa-sliders fa-fw"></i>', 'TaskGanttController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Gantt chart')) ?>
- <?php endif ?>
-
- <?= $this->url->link('<i class="fa fa-list"></i>', 'TaskListController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('List')) ?>&nbsp;
- <?= $this->url->link('<i class="fa fa-calendar"></i>', 'CalendarController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Calendar')) ?>&nbsp;
-
- <?= $this->url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?>
- <?php if (! empty($project['description'])): ?>
- <span class="tooltip" title="<?= $this->text->markdownAttribute($project['description']) ?>">
- <i class="fa fa-info-circle"></i>
- </span>
- <?php endif ?>
- </td>
- <td>
- <?= $project['nb_active_tasks'] ?>
- </td>
- <td class="dashboard-project-stats">
- <?php foreach ($project['columns'] as $column): ?>
- <strong title="<?= t('Task count') ?>"><?= $column['nb_open_tasks'] ?></strong>
- <small><?= $this->text->e($column['title']) ?></small>
- <?php endforeach ?>
- </td>
-
- </tr>
- <?php endforeach ?>
- </table>
-
- <?= $paginator ?>
-<?php endif ?>
diff --git a/app/Template/dashboard/show.php b/app/Template/dashboard/show.php
index b1d877cf..df5b03e0 100644
--- a/app/Template/dashboard/show.php
+++ b/app/Template/dashboard/show.php
@@ -1,3 +1,27 @@
+<div class="page-header">
+ <ul>
+ <?php if ($this->user->hasAccess('ProjectCreationController', 'create')): ?>
+ <li>
+ <?= $this->modal->medium('plus', t('New project'), 'ProjectCreationController', 'create') ?>
+ </li>
+ <?php endif ?>
+ <?php if ($this->app->config('disable_private_project', 0) == 0): ?>
+ <li>
+ <?= $this->modal->medium('lock', t('New private project'), 'ProjectCreationController', 'createPrivate') ?>
+ </li>
+ <?php endif ?>
+ <li>
+ <?= $this->url->icon('folder', t('Project management'), 'ProjectListController', 'show') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('dashboard', t('My activity stream'), 'ActivityController', 'user') ?>
+ </li>
+ <li>
+ <?= $this->modal->medium('calendar', t('My calendar'), 'CalendarController', 'user') ?>
+ </li>
+ </ul>
+</div>
+
<div class="filter-box margin-bottom">
<form method="get" action="<?= $this->url->dir() ?>" class="search">
<?= $this->form->hidden('controller', array('controller' => 'SearchController')) ?>
@@ -12,8 +36,48 @@
</form>
</div>
-<?= $this->render('dashboard/projects', array('paginator' => $project_paginator, 'user' => $user)) ?>
-<?= $this->render('dashboard/tasks', array('paginator' => $task_paginator, 'user' => $user)) ?>
-<?= $this->render('dashboard/subtasks', array('paginator' => $subtask_paginator, 'user' => $user)) ?>
+<?php if (empty($results)): ?>
+ <p class="alert"><?= t('There is nothing assigned to you.') ?></p>
+<?php else: ?>
+ <?php foreach ($results as $result): ?>
+ <?php if (! $result['paginator']->isEmpty()): ?>
+ <div class="page-header">
+ <h2><?= $this->url->link($this->text->e($result['project_name']), 'BoardViewController', 'show', array('project_id' => $result['project_id'])) ?></h2>
+ </div>
+
+ <div class="table-list">
+ <?= $this->render('task_list/header', array(
+ 'paginator' => $result['paginator'],
+ )) ?>
+
+ <?php foreach ($result['paginator']->getCollection() as $task): ?>
+ <div class="table-list-row color-<?= $task['color_id'] ?>">
+ <?= $this->render('task_list/task_title', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_details', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_avatars', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_icons', array(
+ 'task' => $task,
+ )) ?>
+
+ <?= $this->render('task_list/task_subtasks', array(
+ 'task' => $task,
+ )) ?>
+ </div>
+ <?php endforeach ?>
+ </div>
+
+ <?= $result['paginator'] ?>
+ <?php endif ?>
+ <?php endforeach ?>
+<?php endif ?>
<?= $this->hook->render('template:dashboard:show', array('user' => $user)) ?>
diff --git a/app/Template/dashboard/sidebar.php b/app/Template/dashboard/sidebar.php
deleted file mode 100644
index 7507b00d..00000000
--- a/app/Template/dashboard/sidebar.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<div class="sidebar">
- <ul>
- <li <?= $this->app->checkMenuSelection('DashboardController', 'show') ?>>
- <?= $this->url->link(t('Overview'), 'DashboardController', 'show', array('user_id' => $user['id'])) ?>
- </li>
- <li <?= $this->app->checkMenuSelection('DashboardController', 'projects') ?>>
- <?= $this->url->link(t('My projects'), 'DashboardController', 'projects', array('user_id' => $user['id'])) ?>
- </li>
- <li <?= $this->app->checkMenuSelection('DashboardController', 'tasks') ?>>
- <?= $this->url->link(t('My tasks'), 'DashboardController', 'tasks', array('user_id' => $user['id'])) ?>
- </li>
- <li <?= $this->app->checkMenuSelection('DashboardController', 'subtasks') ?>>
- <?= $this->url->link(t('My subtasks'), 'DashboardController', 'subtasks', array('user_id' => $user['id'])) ?>
- </li>
- <?= $this->hook->render('template:dashboard:sidebar', array('user' => $user)) ?>
- </ul>
-</div>
diff --git a/app/Template/dashboard/subtasks.php b/app/Template/dashboard/subtasks.php
deleted file mode 100644
index d86b1ef9..00000000
--- a/app/Template/dashboard/subtasks.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<div class="page-header">
- <h2><?= $this->url->link(t('My subtasks'), 'DashboardController', 'subtasks', array('user_id' => $user['id'])) ?> (<?= $paginator->getTotal() ?>)</h2>
-</div>
-<?php if ($paginator->isEmpty()): ?>
- <p class="alert"><?= t('There is nothing assigned to you.') ?></p>
-<?php else: ?>
- <table class="table-striped table-small table-scrolling">
- <tr>
- <th class="column-5"><?= $paginator->order('Id', \Kanboard\Model\TaskModel::TABLE.'.id') ?></th>
- <th class="column-20"><?= $paginator->order(t('Project'), 'project_name') ?></th>
- <th><?= $paginator->order(t('Task'), 'task_name') ?></th>
- <th><?= $paginator->order(t('Subtask'), \Kanboard\Model\SubtaskModel::TABLE.'.title') ?></th>
- <?= $this->hook->render('template:dashboard:subtasks:header:before-timetracking', array('paginator' => $paginator)) ?>
- <th class="column-20"><?= t('Time tracking') ?></th>
- </tr>
- <?php foreach ($paginator->getCollection() as $subtask): ?>
- <tr>
- <td class="task-table color-<?= $subtask['color_id'] ?>">
- <?= $this->render('task/dropdown', array('task' => array('id' => $subtask['task_id'], 'project_id' => $subtask['project_id']))) ?>
- </td>
- <td>
- <?= $this->url->link($this->text->e($subtask['project_name']), 'BoardViewController', 'show', array('project_id' => $subtask['project_id'])) ?>
- </td>
- <td>
- <?= $this->url->link($this->text->e($subtask['task_name']), 'TaskViewController', 'show', array('task_id' => $subtask['task_id'], 'project_id' => $subtask['project_id'])) ?>
- </td>
- <td>
- <?= $this->subtask->renderToggleStatus(array('project_id' => $subtask['project_id']), $subtask) ?>
- </td>
- <?= $this->hook->render('template:dashboard:subtasks:rows', array('subtask' => $subtask)) ?>
- <td>
- <?php if (! empty($subtask['time_spent'])): ?>
- <strong><?= $this->text->e($subtask['time_spent']).'h' ?></strong> <?= t('spent') ?>
- <?php endif ?>
-
- <?php if (! empty($subtask['time_estimated'])): ?>
- <strong><?= $this->text->e($subtask['time_estimated']).'h' ?></strong> <?= t('estimated') ?>
- <?php endif ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
-
- <?= $paginator ?>
-<?php endif ?>
diff --git a/app/Template/dashboard/tasks.php b/app/Template/dashboard/tasks.php
deleted file mode 100644
index 427b903d..00000000
--- a/app/Template/dashboard/tasks.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<div class="page-header">
- <h2><?= $this->url->link(t('My tasks'), 'DashboardController', 'tasks', array('user_id' => $user['id'])) ?> (<?= $paginator->getTotal() ?>)</h2>
-</div>
-<?php if ($paginator->isEmpty()): ?>
- <p class="alert"><?= t('There is nothing assigned to you.') ?></p>
-<?php else: ?>
- <table class="table-striped table-small table-scrolling">
- <tr>
- <th class="column-5"><?= $paginator->order('Id', \Kanboard\Model\TaskModel::TABLE.'.id') ?></th>
- <th class="column-20"><?= $paginator->order(t('Project'), 'project_name') ?></th>
- <th><?= $paginator->order(t('Task'), \Kanboard\Model\TaskModel::TABLE.'.title') ?></th>
- <th class="column-8"><?= $paginator->order(t('Priority'), \Kanboard\Model\TaskModel::TABLE.'.priority') ?></th>
- <th class="column-20"><?= t('Time tracking') ?></th>
- <th class="column-10"><?= $paginator->order(t('Due date'), \Kanboard\Model\TaskModel::TABLE.'.date_due') ?></th>
- <th class="column-10"><?= $paginator->order(t('Column'), 'column_title') ?></th>
- </tr>
- <?php foreach ($paginator->getCollection() as $task): ?>
- <tr>
- <td class="task-table color-<?= $task['color_id'] ?>">
- <?= $this->render('task/dropdown', array('task' => $task)) ?>
- </td>
- <td>
- <?= $this->url->link($this->text->e($task['project_name']), 'BoardViewController', 'show', array('project_id' => $task['project_id'])) ?>
- </td>
- <td>
- <?= $this->url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
- </td>
- <td>
- <?php if ($task['priority'] >= 0): ?>
- P<?= $this->text->e($task['priority'])?>
- <?php endif?>
- </td>
- <td>
- <?php if (! empty($task['time_spent'])): ?>
- <strong><?= $this->text->e($task['time_spent']).'h' ?></strong> <?= t('spent') ?>
- <?php endif ?>
-
- <?php if (! empty($task['time_estimated'])): ?>
- <strong><?= $this->text->e($task['time_estimated']).'h' ?></strong> <?= t('estimated') ?>
- <?php endif ?>
- </td>
- <td>
- <?= $this->dt->date($task['date_due']) ?>
- </td>
- <td>
- <?= $this->text->e($task['column_title']) ?>
- </td>
- </tr>
- <?php endforeach ?>
- </table>
-
- <?= $paginator ?>
-<?php endif ?>
diff --git a/app/Template/task_list/listing.php b/app/Template/task_list/listing.php
index b3c66aa6..97393972 100644
--- a/app/Template/task_list/listing.php
+++ b/app/Template/task_list/listing.php
@@ -1,40 +1,38 @@
-<section id="main">
- <?= $this->projectHeader->render($project, 'TaskListController', 'show') ?>
+<?= $this->projectHeader->render($project, 'TaskListController', 'show') ?>
- <?php if ($paginator->isEmpty()): ?>
- <p class="alert"><?= t('No tasks found.') ?></p>
- <?php elseif (! $paginator->isEmpty()): ?>
- <div class="table-list">
- <?= $this->render('task_list/header', array(
- 'paginator' => $paginator,
- 'project' => $project,
- )) ?>
+<?php if ($paginator->isEmpty()): ?>
+ <p class="alert"><?= t('No tasks found.') ?></p>
+<?php elseif (! $paginator->isEmpty()): ?>
+ <div class="table-list">
+ <?= $this->render('task_list/header', array(
+ 'paginator' => $paginator,
+ 'project' => $project,
+ )) ?>
- <?php foreach ($paginator->getCollection() as $task): ?>
- <div class="table-list-row color-<?= $task['color_id'] ?>">
- <?= $this->render('task_list/task_title', array(
- 'task' => $task,
- )) ?>
+ <?php foreach ($paginator->getCollection() as $task): ?>
+ <div class="table-list-row color-<?= $task['color_id'] ?>">
+ <?= $this->render('task_list/task_title', array(
+ 'task' => $task,
+ )) ?>
- <?= $this->render('task_list/task_details', array(
- 'task' => $task,
- )) ?>
+ <?= $this->render('task_list/task_details', array(
+ 'task' => $task,
+ )) ?>
- <?= $this->render('task_list/task_avatars', array(
- 'task' => $task,
- )) ?>
+ <?= $this->render('task_list/task_avatars', array(
+ 'task' => $task,
+ )) ?>
- <?= $this->render('task_list/task_icons', array(
- 'task' => $task,
- )) ?>
+ <?= $this->render('task_list/task_icons', array(
+ 'task' => $task,
+ )) ?>
- <?= $this->render('task_list/task_subtasks', array(
- 'task' => $task,
- )) ?>
- </div>
- <?php endforeach ?>
- </div>
+ <?= $this->render('task_list/task_subtasks', array(
+ 'task' => $task,
+ )) ?>
+ </div>
+ <?php endforeach ?>
+ </div>
- <?= $paginator ?>
- <?php endif ?>
-</section>
+ <?= $paginator ?>
+<?php endif ?>
diff --git a/doc/en_US/plugin-hooks.markdown b/doc/en_US/plugin-hooks.markdown
index dedea934..ec971bfa 100644
--- a/doc/en_US/plugin-hooks.markdown
+++ b/doc/en_US/plugin-hooks.markdown
@@ -211,10 +211,7 @@ List of template hooks:
| `template:config:application ` | Application settings form |
| `template:config:email` | Email settings page |
| `template:config:integrations` | Integration page in global settings |
-| `template:dashboard:sidebar` | Sidebar on dashboard page |
| `template:dashboard:show` | Main page of the dashboard |
-| `template:dashboard:subtasks:header:before-timetracking` | Header of Subtask table before Time Tracking |
-| `template:dashboard:subtasks:rows` | Column on row of Subtask table of the dashboard |
| `template:header:dropdown` | Page header dropdown menu (user avatar icon) |
| `template:header:creation-dropdown` | Page header dropdown menu (plus icon) |
| `template:layout:head` | Page layout `<head/>` tag |
diff --git a/tests/integration/MeProcedureTest.php b/tests/integration/MeProcedureTest.php
index 2106419c..5d30b61b 100644
--- a/tests/integration/MeProcedureTest.php
+++ b/tests/integration/MeProcedureTest.php
@@ -53,11 +53,7 @@ class MeProcedureTest extends BaseProcedureTest
{
$dashboard = $this->user->getMyDashboard();
$this->assertNotEmpty($dashboard);
- $this->assertArrayHasKey('projects', $dashboard);
- $this->assertArrayHasKey('tasks', $dashboard);
- $this->assertArrayHasKey('subtasks', $dashboard);
- $this->assertNotEmpty($dashboard['projects']);
- $this->assertNotEmpty($dashboard['tasks']);
+ $this->assertEquals($this->userUserId, $dashboard[0]['owner_id']);
}
public function assertGetMyActivityStream()
diff --git a/tests/units/Model/SubtaskModelTest.php b/tests/units/Model/SubtaskModelTest.php
index eed37cf3..8ad054d1 100644
--- a/tests/units/Model/SubtaskModelTest.php
+++ b/tests/units/Model/SubtaskModelTest.php
@@ -172,4 +172,33 @@ class SubtaskModelTest extends Base
$this->assertEquals(1, $subtaskModel->getProjectId(1));
$this->assertEquals(0, $subtaskModel->getProjectId(2));
}
+
+ public function testGetAllByTaskIds()
+ {
+ $taskCreationModel = new TaskCreationModel($this->container);
+ $subtaskModel = new SubtaskModel($this->container);
+ $projectModel = new ProjectModel($this->container);
+
+ $this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
+ $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
+ $this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
+
+ $this->assertCount(0, $subtaskModel->getAllByTaskIds(array()));
+ $this->assertCount(1, $subtaskModel->getAllByTaskIds(array(1)));
+ }
+
+ public function testGetAllByTaskIdsAndAssignee()
+ {
+ $taskCreationModel = new TaskCreationModel($this->container);
+ $subtaskModel = new SubtaskModel($this->container);
+ $projectModel = new ProjectModel($this->container);
+
+ $this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
+ $this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
+ $this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1, 'user_id' => 1)));
+
+ $this->assertCount(0, $subtaskModel->getAllByTaskIdsAndAssignee(array(), 1));
+ $this->assertCount(0, $subtaskModel->getAllByTaskIdsAndAssignee(array(1), 2));
+ $this->assertCount(1, $subtaskModel->getAllByTaskIdsAndAssignee(array(1), 1));
+ }
}
diff --git a/tests/units/Pagination/DashboardPaginationTest.php b/tests/units/Pagination/DashboardPaginationTest.php
new file mode 100644
index 00000000..92b5ac6f
--- /dev/null
+++ b/tests/units/Pagination/DashboardPaginationTest.php
@@ -0,0 +1,121 @@
+<?php
+
+use Kanboard\Core\Security\Role;
+use Kanboard\Model\ColumnModel;
+use Kanboard\Model\ProjectModel;
+use Kanboard\Model\ProjectUserRoleModel;
+use Kanboard\Model\SubtaskModel;
+use Kanboard\Model\TaskCreationModel;
+use Kanboard\Model\UserModel;
+use Kanboard\Pagination\DashboardPagination;
+
+require_once __DIR__.'/../Base.php';
+
+class DashboardPaginationTest extends Base
+{
+ public function testDashboardPagination()
+ {
+ $projectModel = new ProjectModel($this->container);
+ $projectUserRoleModel = new ProjectUserRoleModel($this->container);
+ $taskCreationModel = new TaskCreationModel($this->container);
+ $subtaskModel = new SubtaskModel($this->container);
+ $dashboardPagination = new DashboardPagination($this->container);
+
+ $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
+ $this->assertEquals(2, $projectModel->create(array('name' => 'Project #2')));
+
+ $this->assertTrue($projectUserRoleModel->addUser(1, 1, Role::PROJECT_MEMBER));
+
+ $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 2)));
+ $this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #2', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 1)));
+
+ $this->assertEquals(1, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask A', 'user_id' => 1)));
+ $this->assertEquals(2, $subtaskModel->create(array('task_id' => 2, 'title' => 'subtask B', 'user_id' => 1)));
+ $this->assertEquals(3, $subtaskModel->create(array('task_id' => 2, 'title' => 'subtask C')));
+
+ $dashboard = $dashboardPagination->getOverview(1);
+ $this->assertCount(1, $dashboard);
+ $this->assertEquals(1, $dashboard[0]['project_id']);
+ $this->assertEquals('Project #1', $dashboard[0]['project_name']);
+ $this->assertEquals(1, $dashboard[0]['paginator']->getTotal());
+
+ $tasks = $dashboard[0]['paginator']->getCollection();
+ $this->assertCount(1, $tasks);
+ $this->assertCount(1, $tasks[0]['subtasks']);
+ $this->assertEquals('subtask B', $tasks[0]['subtasks'][0]['title']);
+ }
+
+ public function testWhenUserIsNotAssignedToTask()
+ {
+ $userModel = new UserModel($this->container);
+ $projectModel = new ProjectModel($this->container);
+ $projectUserRoleModel = new ProjectUserRoleModel($this->container);
+ $taskCreationModel = new TaskCreationModel($this->container);
+ $subtaskModel = new SubtaskModel($this->container);
+ $dashboardPagination = new DashboardPagination($this->container);
+
+ $this->assertEquals(2, $userModel->create(array('username' => 'user1')));
+
+ $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
+ $this->assertEquals(2, $projectModel->create(array('name' => 'Project #2')));
+
+ $this->assertTrue($projectUserRoleModel->addUser(1, 1, Role::PROJECT_MEMBER));
+ $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MEMBER));
+ $this->assertTrue($projectUserRoleModel->addUser(2, 2, Role::PROJECT_MEMBER));
+
+ $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 2)));
+ $this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #2', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 2)));
+ $this->assertEquals(3, $taskCreationModel->create(array('title' => 'Task #3', 'project_id' => 2, 'owner_id' => 2)));
+
+ $this->assertEquals(1, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask A', 'user_id' => 2)));
+ $this->assertEquals(2, $subtaskModel->create(array('task_id' => 2, 'title' => 'subtask B', 'user_id' => 1)));
+ $this->assertEquals(3, $subtaskModel->create(array('task_id' => 2, 'title' => 'subtask C')));
+
+ $dashboard = $dashboardPagination->getOverview(1);
+ $this->assertCount(1, $dashboard);
+ $this->assertEquals(1, $dashboard[0]['project_id']);
+ $this->assertEquals('Project #1', $dashboard[0]['project_name']);
+ $this->assertEquals(1, $dashboard[0]['paginator']->getTotal());
+
+ $tasks = $dashboard[0]['paginator']->getCollection();
+ $this->assertCount(1, $tasks);
+ $this->assertCount(1, $tasks[0]['subtasks']);
+ $this->assertEquals('subtask B', $tasks[0]['subtasks'][0]['title']);
+
+ $dashboard = $dashboardPagination->getOverview(2);
+ $this->assertCount(2, $dashboard);
+ $this->assertEquals('Project #1', $dashboard[0]['project_name']);
+ $this->assertEquals('Project #2', $dashboard[1]['project_name']);
+ $this->assertEquals(1, $dashboard[0]['paginator']->getTotal());
+
+ $tasks = $dashboard[0]['paginator']->getCollection();
+ $this->assertCount(1, $tasks);
+ $this->assertCount(0, $tasks[0]['subtasks']);
+
+ $tasks = $dashboard[1]['paginator']->getCollection();
+ $this->assertCount(2, $tasks);
+ $this->assertCount(1, $tasks[0]['subtasks']);
+ $this->assertEquals('subtask A', $tasks[0]['subtasks'][0]['title']);
+ }
+
+ public function testWhenColumnIsHidden()
+ {
+ $projectModel = new ProjectModel($this->container);
+ $projectUserRoleModel = new ProjectUserRoleModel($this->container);
+ $columnModel = new ColumnModel($this->container);
+ $taskCreationModel = new TaskCreationModel($this->container);
+ $subtaskModel = new SubtaskModel($this->container);
+ $dashboardPagination = new DashboardPagination($this->container);
+
+ $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
+ $this->assertTrue($projectUserRoleModel->addUser(1, 1, Role::PROJECT_MEMBER));
+
+ $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'column_id' => 1)));
+ $this->assertEquals(1, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask #1', 'user_id' => 1)));
+
+ $this->assertCount(1, $dashboardPagination->getOverview(1));
+
+ $this->assertTrue($columnModel->update(1, 'test', 0, '', 1));
+ $this->assertCount(0, $dashboardPagination->getOverview(1));
+ }
+}
diff --git a/tests/units/Pagination/ProjectPaginationTest.php b/tests/units/Pagination/ProjectPaginationTest.php
deleted file mode 100644
index 35532d0d..00000000
--- a/tests/units/Pagination/ProjectPaginationTest.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-use Kanboard\Core\Security\Role;
-use Kanboard\Model\ProjectModel;
-use Kanboard\Model\ProjectUserRoleModel;
-use Kanboard\Model\UserModel;
-use Kanboard\Pagination\ProjectPagination;
-
-require_once __DIR__.'/../Base.php';
-
-class ProjectPaginationTest extends Base
-{
- public function testDashboardPagination()
- {
- $projectModel = new ProjectModel($this->container);
- $projectUserRoleModel = new ProjectUserRoleModel($this->container);
- $userModel = new UserModel($this->container);
- $projectPagination = new ProjectPagination($this->container);
-
- $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
- $this->assertEquals(2, $projectModel->create(array('name' => 'Project #2', 'is_private' => 1)));
- $this->assertEquals(3, $projectModel->create(array('name' => 'Project #3')));
- $this->assertEquals(4, $projectModel->create(array('name' => 'Project #4', 'is_private' => 1)));
-
- $this->assertEquals(2, $userModel->create(array('username' => 'test')));
- $this->assertTrue($projectUserRoleModel->addUser(1, 2, Role::PROJECT_MANAGER));
- $this->assertTrue($projectUserRoleModel->addUser(2, 2, Role::PROJECT_MANAGER));
-
- $this->assertCount(2, $projectPagination->getDashboardPaginator(2, 'projects', 5)->getCollection());
- $this->assertCount(0, $projectPagination->getDashboardPaginator(3, 'projects', 5)->getCollection());
- $this->assertCount(2, $projectPagination->getDashboardPaginator(2, 'projects', 5)->setOrder(ProjectModel::TABLE.'.id')->getCollection());
- $this->assertCount(2, $projectPagination->getDashboardPaginator(2, 'projects', 5)->setOrder(ProjectModel::TABLE.'.is_private')->getCollection());
- $this->assertCount(2, $projectPagination->getDashboardPaginator(2, 'projects', 5)->setOrder(ProjectModel::TABLE.'.name')->getCollection());
- }
-}
diff --git a/tests/units/Pagination/SubtaskPaginationTest.php b/tests/units/Pagination/SubtaskPaginationTest.php
deleted file mode 100644
index 1e16c985..00000000
--- a/tests/units/Pagination/SubtaskPaginationTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-use Kanboard\Model\ColumnModel;
-use Kanboard\Model\ProjectModel;
-use Kanboard\Model\SubtaskModel;
-use Kanboard\Model\TaskCreationModel;
-use Kanboard\Model\TaskModel;
-use Kanboard\Pagination\SubtaskPagination;
-
-require_once __DIR__.'/../Base.php';
-
-class SubtaskPaginationTest extends Base
-{
- public function testDashboardPagination()
- {
- $taskCreationModel = new TaskCreationModel($this->container);
- $projectModel = new ProjectModel($this->container);
- $subtaskModel = new SubtaskModel($this->container);
- $subtaskPagination = new SubtaskPagination($this->container);
-
- $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
- $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1)));
- $this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #2', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 1)));
- $this->assertEquals(1, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask #1', 'user_id' => 1)));
- $this->assertEquals(2, $subtaskModel->create(array('task_id' => 2, 'title' => 'subtask #1', 'user_id' => 1)));
- $this->assertEquals(3, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask #1', 'user_id' => 1)));
- $this->assertEquals(4, $subtaskModel->create(array('task_id' => 2, 'title' => 'subtask #1')));
- $this->assertEquals(5, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask #1')));
-
- $this->assertCount(3, $subtaskPagination->getDashboardPaginator(1, 'subtasks', 5)->getCollection());
- $this->assertCount(0, $subtaskPagination->getDashboardPaginator(2, 'subtasks', 5)->getCollection());
- $this->assertCount(3, $subtaskPagination->getDashboardPaginator(1, 'subtasks', 5)->setOrder(TaskModel::TABLE.'.id')->getCollection());
- $this->assertCount(3, $subtaskPagination->getDashboardPaginator(1, 'subtasks', 5)->setOrder('project_name')->getCollection());
- $this->assertCount(3, $subtaskPagination->getDashboardPaginator(1, 'subtasks', 5)->setOrder('task_name')->getCollection());
- $this->assertCount(3, $subtaskPagination->getDashboardPaginator(1, 'subtasks', 5)->setOrder(SubtaskModel::TABLE.'.title')->getCollection());
- }
-
- public function testWhenColumnIsHidden()
- {
- $columnModel = new ColumnModel($this->container);
- $taskCreationModel = new TaskCreationModel($this->container);
- $projectModel = new ProjectModel($this->container);
- $subtaskModel = new SubtaskModel($this->container);
- $subtaskPagination = new SubtaskPagination($this->container);
-
- $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
- $this->assertTrue($columnModel->update(1, 'test', 0, '', 1));
- $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'column_id' => 1)));
- $this->assertEquals(1, $subtaskModel->create(array('task_id' => 1, 'title' => 'subtask #1', 'user_id' => 1)));
-
- $this->assertCount(0, $subtaskPagination->getDashboardPaginator(1, 'subtasks', 5)->getCollection());
- }
-}
diff --git a/tests/units/Pagination/TaskPaginationTest.php b/tests/units/Pagination/TaskPaginationTest.php
deleted file mode 100644
index 027212e2..00000000
--- a/tests/units/Pagination/TaskPaginationTest.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-use Kanboard\Model\ProjectModel;
-use Kanboard\Model\TaskCreationModel;
-use Kanboard\Model\TaskModel;
-use Kanboard\Pagination\TaskPagination;
-
-require_once __DIR__.'/../Base.php';
-
-class TaskPaginationTest extends Base
-{
- public function testDashboardPagination()
- {
- $taskCreationModel = new TaskCreationModel($this->container);
- $projectModel = new ProjectModel($this->container);
- $taskPagination = new TaskPagination($this->container);
-
- $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
- $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1)));
- $this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #2', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 1)));
-
- $this->assertCount(1, $taskPagination->getDashboardPaginator(1, 'tasks', 5)->getCollection());
- $this->assertCount(0, $taskPagination->getDashboardPaginator(2, 'tasks', 5)->getCollection());
- $this->assertCount(1, $taskPagination->getDashboardPaginator(1, 'tasks', 5)->setOrder(TaskModel::TABLE.'.id')->getCollection());
- $this->assertCount(1, $taskPagination->getDashboardPaginator(1, 'tasks', 5)->setOrder('project_name')->getCollection());
- $this->assertCount(1, $taskPagination->getDashboardPaginator(1, 'tasks', 5)->setOrder(TaskModel::TABLE.'.title')->getCollection());
- $this->assertCount(1, $taskPagination->getDashboardPaginator(1, 'tasks', 5)->setOrder(TaskModel::TABLE.'.priority')->getCollection());
- $this->assertCount(1, $taskPagination->getDashboardPaginator(1, 'tasks', 5)->setOrder(TaskModel::TABLE.'.date_due')->getCollection());
- }
-}