diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-05-17 22:08:57 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-05-17 22:08:57 -0400 |
commit | 996997a12d1b435956a96640eb6cf39045f6ef46 (patch) | |
tree | 1512126636270a97b22a7ace83657289fc55a4c4 | |
parent | d8472d17bd1cd0aa996b6f19288e5e799a78ad65 (diff) |
Added the possibility to convert a subtask to a task
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | app/Controller/SubtaskConverterController.php | 39 | ||||
-rw-r--r-- | app/Model/Subtask.php | 27 | ||||
-rw-r--r-- | app/Template/subtask/menu.php | 6 | ||||
-rw-r--r-- | app/Template/subtask/remove.php | 13 | ||||
-rw-r--r-- | app/Template/subtask_converter/show.php | 20 | ||||
-rw-r--r-- | tests/units/Model/SubtaskTest.php | 25 |
7 files changed, 126 insertions, 5 deletions
@@ -3,6 +3,7 @@ Version 1.0.29 (unreleased) New features: +* Added the possibility to convert a subtask to a task * Added menu entry to add tasks from all project views * Add tasks in bulk from the board * Add dropdown for projects diff --git a/app/Controller/SubtaskConverterController.php b/app/Controller/SubtaskConverterController.php new file mode 100644 index 00000000..829b937a --- /dev/null +++ b/app/Controller/SubtaskConverterController.php @@ -0,0 +1,39 @@ +<?php + +namespace Kanboard\Controller; + +/** + * Class SubtaskConverterController + * + * @package Kanboard\Controller + * @author Frederic Guillot + */ +class SubtaskConverterController extends BaseController +{ + public function show() + { + $task = $this->getTask(); + $subtask = $this->getSubtask(); + + $this->response->html($this->template->render('subtask_converter/show', array( + 'subtask' => $subtask, + 'task' => $task, + ))); + } + + public function save() + { + $project = $this->getProject(); + $subtask = $this->getSubtask(); + + $task_id = $this->subtask->convertToTask($project['id'], $subtask['id']); + + if ($task_id !== false) { + $this->flash->success(t('Subtask converted to task successfully.')); + } else { + $this->flash->failure(t('Unable to convert the subtask.')); + } + + $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $project['id'], 'task_id' => $task_id)), true); + } +} diff --git a/app/Model/Subtask.php b/app/Model/Subtask.php index 3f5cfe83..e56796a0 100644 --- a/app/Model/Subtask.php +++ b/app/Model/Subtask.php @@ -397,4 +397,31 @@ class Subtask extends Base } }); } + + /** + * Convert a subtask to a task + * + * @access public + * @param integer $project_id + * @param integer $subtask_id + * @return integer + */ + public function convertToTask($project_id, $subtask_id) + { + $subtask = $this->getById($subtask_id); + + $task_id = $this->taskCreation->create(array( + 'project_id' => $project_id, + 'title' => $subtask['title'], + 'time_estimated' => $subtask['time_estimated'], + 'time_spent' => $subtask['time_spent'], + 'owner_id' => $subtask['user_id'], + )); + + if ($task_id !== false) { + $this->remove($subtask_id); + } + + return $task_id; + } } diff --git a/app/Template/subtask/menu.php b/app/Template/subtask/menu.php index 6c98b951..aa7b9a53 100644 --- a/app/Template/subtask/menu.php +++ b/app/Template/subtask/menu.php @@ -2,10 +2,16 @@ <a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog fa-fw"></i><i class="fa fa-caret-down"></i></a> <ul> <li> + <i class="fa fa-pencil-square-o" aria-hidden="true"></i> <?= $this->url->link(t('Edit'), 'subtask', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?> </li> <li> + <i class="fa fa-trash-o" aria-hidden="true"></i> <?= $this->url->link(t('Remove'), 'subtask', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?> </li> + <li> + <i class="fa fa-clone" aria-hidden="true"></i> + <?= $this->url->link(t('Convert to task'), 'SubtaskConverterController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?> + </li> </ul> </div> diff --git a/app/Template/subtask/remove.php b/app/Template/subtask/remove.php index 374256fd..7ea43555 100644 --- a/app/Template/subtask/remove.php +++ b/app/Template/subtask/remove.php @@ -3,15 +3,18 @@ </div> <div class="confirm"> - <p class="alert alert-info"> + <div class="alert alert-info"> <?= t('Do you really want to remove this sub-task?') ?> - </p> - - <p><strong><?= $this->text->e($subtask['title']) ?></strong></p> + <ul> + <li> + <strong><?= $this->text->e($subtask['title']) ?></strong> + </li> + </ul> + </div> <div class="form-actions"> <?= $this->url->link(t('Yes'), 'subtask', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?> <?= t('or') ?> <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> </div> -</div>
\ No newline at end of file +</div> diff --git a/app/Template/subtask_converter/show.php b/app/Template/subtask_converter/show.php new file mode 100644 index 00000000..af8af49e --- /dev/null +++ b/app/Template/subtask_converter/show.php @@ -0,0 +1,20 @@ +<div class="page-header"> + <h2><?= t('Convert sub-task to task') ?></h2> +</div> + +<div class="confirm"> + <div class="alert alert-info"> + <?= t('Do you really want to convert this sub-task to a task?') ?> + <ul> + <li> + <strong><?= $this->text->e($subtask['title']) ?></strong> + </li> + </ul> + </div> + + <div class="form-actions"> + <?= $this->url->link(t('Yes'), 'SubtaskConverterController', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?> + <?= t('or') ?> + <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?> + </div> +</div> diff --git a/tests/units/Model/SubtaskTest.php b/tests/units/Model/SubtaskTest.php index eb9747d4..20186452 100644 --- a/tests/units/Model/SubtaskTest.php +++ b/tests/units/Model/SubtaskTest.php @@ -6,6 +6,7 @@ use Kanboard\Model\TaskCreation; use Kanboard\Model\Subtask; use Kanboard\Model\Project; use Kanboard\Core\User\UserSession; +use Kanboard\Model\TaskFinder; class SubtaskTest extends Base { @@ -360,4 +361,28 @@ class SubtaskTest extends Base $this->assertFalse($subtaskModel->changePosition(1, 2, 0)); $this->assertFalse($subtaskModel->changePosition(1, 2, 4)); } + + public function testConvertToTask() + { + $taskCreationModel = new TaskCreation($this->container); + $taskFinderModel = new TaskFinder($this->container); + $subtaskModel = new Subtask($this->container); + $projectModel = new Project($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, 'time_spent' => 2, 'time_estimated' => 3))); + $task_id = $subtaskModel->convertToTask(1, 1); + + $this->assertNotFalse($task_id); + $this->assertEmpty($subtaskModel->getById(1)); + + $task = $taskFinderModel->getById($task_id); + $this->assertEquals('subtask #1', $task['title']); + $this->assertEquals(1, $task['project_id']); + $this->assertEquals(1, $task['owner_id']); + $this->assertEquals(2, $task['time_spent']); + $this->assertEquals(3, $task['time_estimated']); + } } |