diff --git a/ChangeLog b/ChangeLog index 7e4bdad69..7a95ae1b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ New features: Improvements: +* Do not refresh the whole page when changing subtask status (work in progress) * Add dropdown menu with inline popup for all task actions * Change sidebar style * Change task summary layout diff --git a/app/Controller/Base.php b/app/Controller/Base.php index a80b3528f..c55ad9ad7 100644 --- a/app/Controller/Base.php +++ b/app/Controller/Base.php @@ -214,8 +214,7 @@ abstract class Base extends \Kanboard\Core\Base $project = $this->project->getByIdWithOwner($project_id); if (empty($project)) { - $this->flash->failure(t('Project not found.')); - $this->response->redirect($this->helper->url->to('project', 'index')); + $this->notfound(); } return $project; @@ -242,6 +241,23 @@ abstract class Base extends \Kanboard\Core\Base return $user; } + /** + * Get the current subtask + * + * @access protected + * @return array + */ + protected function getSubtask() + { + $subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id')); + + if (empty($subtask)) { + $this->notfound(); + } + + return $subtask; + } + /** * Common method to get project filters * diff --git a/app/Controller/Comment.php b/app/Controller/Comment.php index 2ad3f379c..da3213e07 100644 --- a/app/Controller/Comment.php +++ b/app/Controller/Comment.php @@ -107,7 +107,7 @@ class Comment extends Base public function update() { $task = $this->getTask(); - $comment = $this->getComment(); + $this->getComment(); $values = $this->request->getValues(); list($valid, $errors) = $this->commentValidator->validateModification($values); diff --git a/app/Controller/Subtask.php b/app/Controller/Subtask.php index 9fe15c9de..f87989063 100644 --- a/app/Controller/Subtask.php +++ b/app/Controller/Subtask.php @@ -2,8 +2,6 @@ namespace Kanboard\Controller; -use Kanboard\Model\Subtask as SubtaskModel; - /** * Subtask controller * @@ -12,23 +10,6 @@ use Kanboard\Model\Subtask as SubtaskModel; */ class Subtask extends Base { - /** - * Get the current subtask - * - * @access private - * @return array - */ - private function getSubtask() - { - $subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id')); - - if (empty($subtask)) { - $this->notfound(); - } - - return $subtask; - } - /** * Show list of subtasks */ @@ -181,98 +162,6 @@ class Subtask extends Base $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); } - /** - * Change status to the next status: Toto -> In Progress -> Done - * - * @access public - */ - public function toggleStatus() - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - $redirect = $this->request->getStringParam('redirect', 'task'); - - $this->subtask->toggleStatus($subtask['id']); - - if ($redirect === 'board') { - $this->sessionStorage->hasSubtaskInProgress = $this->subtask->hasSubtaskInProgress($this->userSession->getId()); - - $this->response->html($this->template->render('board/tooltip_subtasks', array( - 'subtasks' => $this->subtask->getAll($task['id']), - 'task' => $task, - ))); - } - - $this->toggleRedirect($task, $redirect); - } - - /** - * Handle subtask restriction (popover) - * - * @access public - */ - public function subtaskRestriction() - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - - $this->response->html($this->template->render('subtask/restriction_change_status', array( - 'status_list' => array( - SubtaskModel::STATUS_TODO => t('Todo'), - SubtaskModel::STATUS_DONE => t('Done'), - ), - 'subtask_inprogress' => $this->subtask->getSubtaskInProgress($this->userSession->getId()), - 'subtask' => $subtask, - 'task' => $task, - 'redirect' => $this->request->getStringParam('redirect'), - ))); - } - - /** - * Change status of the in progress subtask and the other subtask - * - * @access public - */ - public function changeRestrictionStatus() - { - $task = $this->getTask(); - $subtask = $this->getSubtask(); - $values = $this->request->getValues(); - - // Change status of the previous in progress subtask - $this->subtask->update(array( - 'id' => $values['id'], - 'status' => $values['status'], - )); - - // Set the current subtask to in pogress - $this->subtask->update(array( - 'id' => $subtask['id'], - 'status' => SubtaskModel::STATUS_INPROGRESS, - )); - - $this->toggleRedirect($task, $values['redirect']); - } - - /** - * Redirect to the right page - * - * @access private - */ - private function toggleRedirect(array $task, $redirect) - { - switch ($redirect) { - case 'board': - $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id']))); - case 'dashboard': - $this->response->redirect($this->helper->url->to('app', 'index')); - case 'subtask': - $this->response->redirect($this->helper->url->to('subtask', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); - default: - $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'subtasks')); - } - } - /** * Move subtask position * diff --git a/app/Controller/SubtaskRestriction.php b/app/Controller/SubtaskRestriction.php new file mode 100644 index 000000000..56024867a --- /dev/null +++ b/app/Controller/SubtaskRestriction.php @@ -0,0 +1,61 @@ +getTask(); + $subtask = $this->getSubtask(); + + $this->response->html($this->template->render('subtask_restriction/popover', array( + 'status_list' => array( + SubtaskModel::STATUS_TODO => t('Todo'), + SubtaskModel::STATUS_DONE => t('Done'), + ), + 'subtask_inprogress' => $this->subtask->getSubtaskInProgress($this->userSession->getId()), + 'subtask' => $subtask, + 'task' => $task, + ))); + } + + /** + * Change status of the in progress subtask and the other subtask + * + * @access public + */ + public function update() + { + $task = $this->getTask(); + $subtask = $this->getSubtask(); + $values = $this->request->getValues(); + + // Change status of the previous "in progress" subtask + $this->subtask->update(array( + 'id' => $values['id'], + 'status' => $values['status'], + )); + + // Set the current subtask to "in progress" + $this->subtask->update(array( + 'id' => $subtask['id'], + 'status' => SubtaskModel::STATUS_INPROGRESS, + )); + + $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); + } +} diff --git a/app/Controller/SubtaskStatus.php b/app/Controller/SubtaskStatus.php new file mode 100644 index 000000000..efe8a9745 --- /dev/null +++ b/app/Controller/SubtaskStatus.php @@ -0,0 +1,28 @@ + In Progress -> Done + * + * @access public + */ + public function change() + { + $task = $this->getTask(); + $subtask = $this->getSubtask(); + + $status = $this->subtask->toggleStatus($subtask['id']); + $subtask['status'] = $status; + + $this->response->html($this->helper->subtask->toggleStatus($subtask, $task['project_id'])); + } +} diff --git a/app/Helper/Subtask.php b/app/Helper/Subtask.php index 5b8d7d90b..38074b78c 100644 --- a/app/Helper/Subtask.php +++ b/app/Helper/Subtask.php @@ -10,38 +10,40 @@ namespace Kanboard\Helper; */ class Subtask extends \Kanboard\Core\Base { + public function getTitle(array $subtask) + { + if ($subtask['status'] == 0) { + $html = ''; + } elseif ($subtask['status'] == 1) { + $html = ''; + } else { + $html = ''; + } + + return $html.$this->helper->e($subtask['title']); + } + /** * Get the link to toggle subtask status * * @access public * @param array $subtask - * @param string $redirect * @param integer $project_id * @return string */ - public function toggleStatus(array $subtask, $redirect, $project_id = 0) + public function toggleStatus(array $subtask, $project_id) { - if ($project_id > 0 && ! $this->helper->user->hasProjectAccess('subtask', 'edit', $project_id)) { - return trim($this->template->render('subtask/icons', array('subtask' => $subtask))) . $this->helper->e($subtask['title']); + if (! $this->helper->user->hasProjectAccess('subtask', 'edit', $project_id)) { + return $this->getTitle($subtask); } + $params = array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']); + if ($subtask['status'] == 0 && isset($this->sessionStorage->hasSubtaskInProgress) && $this->sessionStorage->hasSubtaskInProgress) { - return $this->helper->url->link( - trim($this->template->render('subtask/icons', array('subtask' => $subtask))) . $this->helper->e($subtask['title']), - 'subtask', - 'subtaskRestriction', - array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'redirect' => $redirect), - false, - 'popover task-board-popover' - ); + return $this->helper->url->link($this->getTitle($subtask), 'SubtaskRestriction', 'popover', $params, false, 'popover'); } - return $this->helper->url->link( - trim($this->template->render('subtask/icons', array('subtask' => $subtask))) . $this->helper->e($subtask['title']), - 'subtask', - 'toggleStatus', - array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'redirect' => $redirect) - ); + return $this->helper->url->link($this->getTitle($subtask), 'SubtaskStatus', 'change', $params, false, 'ajax-replace'); } public function selectTitle(array $values, array $errors = array(), array $attributes = array()) diff --git a/app/Model/Subtask.php b/app/Model/Subtask.php index 1e989ad54..14853941f 100644 --- a/app/Model/Subtask.php +++ b/app/Model/Subtask.php @@ -353,15 +353,16 @@ class Subtask extends Base * * @access public * @param integer $subtask_id - * @return bool + * @return boolean|integer */ public function toggleStatus($subtask_id) { $subtask = $this->getById($subtask_id); + $status = ($subtask['status'] + 1) % 3; $values = array( 'id' => $subtask['id'], - 'status' => ($subtask['status'] + 1) % 3, + 'status' => $status, 'task_id' => $subtask['task_id'], ); @@ -369,7 +370,7 @@ class Subtask extends Base $values['user_id'] = $this->userSession->getId(); } - return $this->update($values); + return $this->update($values) ? $status : false; } /** diff --git a/app/ServiceProvider/AuthenticationProvider.php b/app/ServiceProvider/AuthenticationProvider.php index dac731607..4196a4702 100644 --- a/app/ServiceProvider/AuthenticationProvider.php +++ b/app/ServiceProvider/AuthenticationProvider.php @@ -83,6 +83,8 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->add('ProjectEdit', '*', Role::PROJECT_MANAGER); $acl->add('Projectuser', '*', Role::PROJECT_MANAGER); $acl->add('Subtask', '*', Role::PROJECT_MEMBER); + $acl->add('SubtaskRestriction', '*', Role::PROJECT_MEMBER); + $acl->add('SubtaskStatus', '*', Role::PROJECT_MEMBER); $acl->add('Swimlane', '*', Role::PROJECT_MANAGER); $acl->add('Task', 'remove', Role::PROJECT_MEMBER); $acl->add('Taskcreation', '*', Role::PROJECT_MEMBER); diff --git a/app/Template/app/subtasks.php b/app/Template/app/subtasks.php index b4c87bab1..f72f21fb9 100644 --- a/app/Template/app/subtasks.php +++ b/app/Template/app/subtasks.php @@ -24,7 +24,7 @@ = $this->url->link($this->e($subtask['task_name']), 'task', 'show', array('task_id' => $subtask['task_id'], 'project_id' => $subtask['project_id'])) ?>
| + = $this->subtask->toggleStatus($subtask, $task['project_id']) ?> + | ++ = $this->e($subtask['username'] ?: $this->user->getFullname($subtask)) ?> + | +
| = t('Title') ?> | -= t('Assignee') ?> | -= t('Time tracking') ?> | - -- - |
|---|---|---|---|
| - - = $this->subtask->toggleStatus($subtask, $redirect) ?> - - = $this->render('subtask/icons', array('subtask' => $subtask)) . $this->e($subtask['title']) ?> - - | -- - - = $this->url->link($this->e($subtask['name'] ?: $subtask['username']), 'user', 'show', array('user_id' => $subtask['user_id'])) ?> - - = $this->e($subtask['name'] ?: $subtask['username']) ?> - - - | -
-
|
-
- - = $this->render('subtask/menu', array( - 'project' => $project, - 'task' => $task, - 'subtask' => $subtask, - 'redirect' => $redirect, - 'first_position' => $first_position, - 'last_position' => $last_position, - )) ?> - | - -
= t('There is no subtask at the moment.') ?>
- + = $this->render('subtask/table', array('subtasks' => $subtasks, 'task' => $task, 'editable' => $editable)) ?> user->hasProjectAccess('subtask', 'save', $task['project_id'])): ?>