From 9b34631135f29480dda3ed2df463fbb5aab7c9e4 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 12 Mar 2017 21:36:52 -0400 Subject: Simplify dashboard to use new tasks list view --- ChangeLog | 1 + app/Api/Procedure/MeProcedure.php | 15 +-- app/Controller/ActivityController.php | 2 +- app/Controller/DashboardController.php | 58 +--------- app/Core/Base.php | 5 +- app/Formatter/TaskListSubtaskAssigneeFormatter.php | 43 ++++++++ app/Helper/LayoutHelper.php | 13 --- app/Model/ProjectModel.php | 21 ---- app/Model/SubtaskModel.php | 67 +++--------- app/Model/TaskFinderModel.php | 24 +--- app/Pagination/DashboardPagination.php | 50 +++++++++ app/Pagination/ProjectPagination.php | 35 ------ app/Pagination/SubtaskPagination.php | 39 ------- app/Pagination/TaskPagination.php | 38 ------- app/Pagination/UserPagination.php | 2 +- app/ServiceProvider/ClassProvider.php | 4 +- app/ServiceProvider/FormatterProvider.php | 1 + app/Template/dashboard/layout.php | 31 ------ app/Template/dashboard/projects.php | 55 ---------- app/Template/dashboard/show.php | 70 +++++++++++- app/Template/dashboard/sidebar.php | 17 --- app/Template/dashboard/subtasks.php | 45 -------- app/Template/dashboard/tasks.php | 53 --------- app/Template/task_list/listing.php | 64 ++++++----- doc/en_US/plugin-hooks.markdown | 3 - tests/integration/MeProcedureTest.php | 6 +- tests/units/Model/SubtaskModelTest.php | 29 +++++ tests/units/Pagination/DashboardPaginationTest.php | 121 +++++++++++++++++++++ tests/units/Pagination/ProjectPaginationTest.php | 35 ------ tests/units/Pagination/SubtaskPaginationTest.php | 53 --------- tests/units/Pagination/TaskPaginationTest.php | 30 ----- 31 files changed, 380 insertions(+), 650 deletions(-) create mode 100644 app/Formatter/TaskListSubtaskAssigneeFormatter.php create mode 100644 app/Pagination/DashboardPagination.php delete mode 100644 app/Pagination/ProjectPagination.php delete mode 100644 app/Pagination/SubtaskPagination.php delete mode 100644 app/Pagination/TaskPagination.php delete mode 100644 app/Template/dashboard/layout.php delete mode 100644 app/Template/dashboard/projects.php delete mode 100644 app/Template/dashboard/sidebar.php delete mode 100644 app/Template/dashboard/subtasks.php delete mode 100644 app/Template/dashboard/tasks.php create mode 100644 tests/units/Pagination/DashboardPaginationTest.php delete mode 100644 tests/units/Pagination/ProjectPaginationTest.php delete mode 100644 tests/units/Pagination/SubtaskPaginationTest.php delete mode 100644 tests/units/Pagination/TaskPaginationTest.php 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 @@ +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 @@ -140,19 +140,6 @@ class LayoutHelper extends Base return $this->subLayout('plugin/layout', 'plugin/sidebar', $template, $params); } - /** - * 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 * 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 @@ -296,27 +296,6 @@ class ProjectModel extends Base return $projects; } - /** - * 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 * 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 @@ -69,35 +69,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 * @@ -148,6 +119,24 @@ class SubtaskModel extends Base ->format(); } + /** + * 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 * @@ -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 @@ +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 @@ -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 @@ -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 @@ -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 @@ -
- - -
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 @@ - -isEmpty()): ?> -

- - - - - - - - - - getCollection() as $project): ?> - - - - - - - - - -
order('Id', \Kanboard\Model\ProjectModel::TABLE.'.id') ?>order('', \Kanboard\Model\ProjectModel::TABLE.'.is_private') ?>order(t('Project'), \Kanboard\Model\ProjectModel::TABLE.'.name') ?>
- render('project/dropdown', array('project' => $project)) ?> - - - - - - user->hasProjectAccess('TaskGanttController', 'show', $project['id'])): ?> - url->link('', 'TaskGanttController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Gantt chart')) ?> - - - url->link('', 'TaskListController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('List')) ?>  - url->link('', 'CalendarController', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Calendar')) ?>  - - url->link($this->text->e($project['name']), 'BoardViewController', 'show', array('project_id' => $project['id'])) ?> - - - - - - - - - - - text->e($column['title']) ?> - -
- - - 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 @@ + +
-render('dashboard/projects', array('paginator' => $project_paginator, 'user' => $user)) ?> -render('dashboard/tasks', array('paginator' => $task_paginator, 'user' => $user)) ?> -render('dashboard/subtasks', array('paginator' => $subtask_paginator, 'user' => $user)) ?> + +

+ + + isEmpty()): ?> + + +
+ render('task_list/header', array( + 'paginator' => $result['paginator'], + )) ?> + + getCollection() as $task): ?> +
+ render('task_list/task_title', array( + 'task' => $task, + )) ?> + + render('task_list/task_details', array( + 'task' => $task, + )) ?> + + render('task_list/task_avatars', array( + 'task' => $task, + )) ?> + + render('task_list/task_icons', array( + 'task' => $task, + )) ?> + + render('task_list/task_subtasks', array( + 'task' => $task, + )) ?> +
+ +
+ + + + + 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 @@ - 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 @@ - -isEmpty()): ?> -

- - - - - - - - hook->render('template:dashboard:subtasks:header:before-timetracking', array('paginator' => $paginator)) ?> - - - getCollection() as $subtask): ?> - - - - - - hook->render('template:dashboard:subtasks:rows', array('subtask' => $subtask)) ?> - - - -
order('Id', \Kanboard\Model\TaskModel::TABLE.'.id') ?>order(t('Project'), 'project_name') ?>order(t('Task'), 'task_name') ?>order(t('Subtask'), \Kanboard\Model\SubtaskModel::TABLE.'.title') ?>
- render('task/dropdown', array('task' => array('id' => $subtask['task_id'], 'project_id' => $subtask['project_id']))) ?> - - url->link($this->text->e($subtask['project_name']), 'BoardViewController', 'show', array('project_id' => $subtask['project_id'])) ?> - - url->link($this->text->e($subtask['task_name']), 'TaskViewController', 'show', array('task_id' => $subtask['task_id'], 'project_id' => $subtask['project_id'])) ?> - - subtask->renderToggleStatus(array('project_id' => $subtask['project_id']), $subtask) ?> - - - text->e($subtask['time_spent']).'h' ?> - - - - text->e($subtask['time_estimated']).'h' ?> - -
- - - 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 @@ - -isEmpty()): ?> -

- - - - - - - - - - - - getCollection() as $task): ?> - - - - - - - - - - -
order('Id', \Kanboard\Model\TaskModel::TABLE.'.id') ?>order(t('Project'), 'project_name') ?>order(t('Task'), \Kanboard\Model\TaskModel::TABLE.'.title') ?>order(t('Priority'), \Kanboard\Model\TaskModel::TABLE.'.priority') ?>order(t('Due date'), \Kanboard\Model\TaskModel::TABLE.'.date_due') ?>order(t('Column'), 'column_title') ?>
- render('task/dropdown', array('task' => $task)) ?> - - url->link($this->text->e($task['project_name']), 'BoardViewController', 'show', array('project_id' => $task['project_id'])) ?> - - url->link($this->text->e($task['title']), 'TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> - - = 0): ?> - Ptext->e($task['priority'])?> - - - - text->e($task['time_spent']).'h' ?> - - - - text->e($task['time_estimated']).'h' ?> - - - dt->date($task['date_due']) ?> - - text->e($task['column_title']) ?> -
- - - 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 @@ -
- projectHeader->render($project, 'TaskListController', 'show') ?> +projectHeader->render($project, 'TaskListController', 'show') ?> - isEmpty()): ?> -

- isEmpty()): ?> -
- render('task_list/header', array( - 'paginator' => $paginator, - 'project' => $project, - )) ?> +isEmpty()): ?> +

+isEmpty()): ?> +
+ render('task_list/header', array( + 'paginator' => $paginator, + 'project' => $project, + )) ?> - getCollection() as $task): ?> -
- render('task_list/task_title', array( - 'task' => $task, - )) ?> + getCollection() as $task): ?> +
+ render('task_list/task_title', array( + 'task' => $task, + )) ?> - render('task_list/task_details', array( - 'task' => $task, - )) ?> + render('task_list/task_details', array( + 'task' => $task, + )) ?> - render('task_list/task_avatars', array( - 'task' => $task, - )) ?> + render('task_list/task_avatars', array( + 'task' => $task, + )) ?> - render('task_list/task_icons', array( - 'task' => $task, - )) ?> + render('task_list/task_icons', array( + 'task' => $task, + )) ?> - render('task_list/task_subtasks', array( - 'task' => $task, - )) ?> -
- -
+ render('task_list/task_subtasks', array( + 'task' => $task, + )) ?> +
+ +
- - -
+ + 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 `` 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 @@ +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 @@ -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 @@ -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 @@ -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()); - } -} -- cgit v1.2.3