diff options
author | Frederic Guillot <fred@kanboard.net> | 2017-02-18 13:38:51 -0500 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2017-02-18 13:38:51 -0500 |
commit | 49c8e5c1be15b9732023703473bb7e15864770f6 (patch) | |
tree | a4dcf83e0601fd734d44ad67e36299921959c3c2 | |
parent | 948b7fbaaa58c0a825938f7e8bda9a07ec39239b (diff) |
Prevent people to remove swimlanes that contains tasks
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | app/Controller/ColumnController.php | 2 | ||||
-rw-r--r-- | app/Controller/ProjectOverviewController.php | 2 | ||||
-rw-r--r-- | app/Controller/ProjectViewController.php | 2 | ||||
-rw-r--r-- | app/Controller/SwimlaneController.php | 5 | ||||
-rw-r--r-- | app/Model/ColumnModel.php | 4 | ||||
-rw-r--r-- | app/Model/ProjectModel.php | 2 | ||||
-rw-r--r-- | app/Model/SwimlaneModel.php | 34 | ||||
-rw-r--r-- | app/Template/column/index.php | 39 | ||||
-rw-r--r-- | app/Template/swimlane/index.php | 2 | ||||
-rw-r--r-- | app/Template/swimlane/table.php | 50 | ||||
-rw-r--r-- | tests/units/Model/ColumnModelTest.php | 2 | ||||
-rw-r--r-- | tests/units/Model/SwimlaneModelTest.php | 36 |
13 files changed, 132 insertions, 54 deletions
@@ -7,12 +7,14 @@ New features: Improvements: +* Prevent people to remove swimlanes that contains tasks +* Show task count in swimlane table * Use contextual menu instead of action column in users management Breaking changes: -* The concept of "default swimlane" is removed -* Previous default swimlanes are migrated to an independent swimlane +* The concept of "default swimlane" has been removed +* Previous default swimlanes are migrated to an independent swimlanes * Columns "default_swimlane" and "show_default_swimlane" from "projects" table are not used anymore * Remove API method "getDefaultSwimlane()" * Add mandatory argument "project_id" to API method "updateSwimlane()" diff --git a/app/Controller/ColumnController.php b/app/Controller/ColumnController.php index 3facbebc..7047d30e 100644 --- a/app/Controller/ColumnController.php +++ b/app/Controller/ColumnController.php @@ -20,7 +20,7 @@ class ColumnController extends BaseController public function index() { $project = $this->getProject(); - $columns = $this->columnModel->getAllWithTasksCount($project['id']); + $columns = $this->columnModel->getAllWithTaskCount($project['id']); $this->response->html($this->helper->layout->project('column/index', array( 'columns' => $columns, diff --git a/app/Controller/ProjectOverviewController.php b/app/Controller/ProjectOverviewController.php index 33bec078..477c1dd5 100644 --- a/app/Controller/ProjectOverviewController.php +++ b/app/Controller/ProjectOverviewController.php @@ -16,7 +16,7 @@ class ProjectOverviewController extends BaseController public function show() { $project = $this->getProject(); - $columns = $this->columnModel->getAllWithTasksCount($project['id']); + $columns = $this->columnModel->getAllWithTaskCount($project['id']); $this->response->html($this->helper->layout->app('project_overview/show', array( 'project' => $project, diff --git a/app/Controller/ProjectViewController.php b/app/Controller/ProjectViewController.php index 8ccf36ab..8ff79343 100644 --- a/app/Controller/ProjectViewController.php +++ b/app/Controller/ProjectViewController.php @@ -18,7 +18,7 @@ class ProjectViewController extends BaseController public function show() { $project = $this->getProject(); - $columns = $this->columnModel->getAllWithTasksCount($project['id']); + $columns = $this->columnModel->getAllWithTaskCount($project['id']); $this->response->html($this->helper->layout->project('project_view/show', array( 'project' => $project, diff --git a/app/Controller/SwimlaneController.php b/app/Controller/SwimlaneController.php index d99cfa7a..0d81d83c 100644 --- a/app/Controller/SwimlaneController.php +++ b/app/Controller/SwimlaneController.php @@ -40,10 +40,11 @@ class SwimlaneController extends BaseController public function index() { $project = $this->getProject(); + $swimlanes = $this->swimlaneModel->getAllWithTaskCount($project['id']); $this->response->html($this->helper->layout->project('swimlane/index', array( - 'active_swimlanes' => $this->swimlaneModel->getAllByStatus($project['id'], SwimlaneModel::ACTIVE), - 'inactive_swimlanes' => $this->swimlaneModel->getAllByStatus($project['id'], SwimlaneModel::INACTIVE), + 'active_swimlanes' => $swimlanes['active'], + 'inactive_swimlanes' => $swimlanes['inactive'], 'project' => $project, 'title' => t('Swimlanes') ))); diff --git a/app/Model/ColumnModel.php b/app/Model/ColumnModel.php index da5ea856..05f76fb9 100644 --- a/app/Model/ColumnModel.php +++ b/app/Model/ColumnModel.php @@ -121,13 +121,13 @@ class ColumnModel extends Base } /** - * Get all columns with tasks count + * Get all columns with task count * * @access public * @param integer $project_id Project id * @return array */ - public function getAllWithTasksCount($project_id) + public function getAllWithTaskCount($project_id) { return $this->db->table(self::TABLE) ->columns('id', 'title', 'position', 'task_limit', 'description', 'hide_in_dashboard', 'project_id') diff --git a/app/Model/ProjectModel.php b/app/Model/ProjectModel.php index a4d75a0b..b88a8c8b 100644 --- a/app/Model/ProjectModel.php +++ b/app/Model/ProjectModel.php @@ -270,7 +270,7 @@ class ProjectModel extends Base */ public function getColumnStats(array &$project) { - $project['columns'] = $this->columnModel->getAllWithTasksCount($project['id']); + $project['columns'] = $this->columnModel->getAllWithTaskCount($project['id']); $project['nb_active_tasks'] = 0; foreach ($project['columns'] as $column) { diff --git a/app/Model/SwimlaneModel.php b/app/Model/SwimlaneModel.php index 30012096..2b3be912 100644 --- a/app/Model/SwimlaneModel.php +++ b/app/Model/SwimlaneModel.php @@ -164,6 +164,40 @@ class SwimlaneModel extends Base } /** + * Get all swimlanes with task count + * + * @access public + * @param integer $project_id Project id + * @return array + */ + public function getAllWithTaskCount($project_id) + { + $result = array( + 'active' => array(), + 'inactive' => array(), + ); + + $swimlanes = $this->db->table(self::TABLE) + ->columns('id', 'name', 'description', 'project_id', 'position', 'is_active') + ->subquery("SELECT COUNT(*) FROM ".TaskModel::TABLE." WHERE swimlane_id=".self::TABLE.".id AND is_active='1'", 'nb_open_tasks') + ->subquery("SELECT COUNT(*) FROM ".TaskModel::TABLE." WHERE swimlane_id=".self::TABLE.".id AND is_active='0'", 'nb_closed_tasks') + ->eq('project_id', $project_id) + ->asc('position') + ->asc('name') + ->findAll(); + + foreach ($swimlanes as $swimlane) { + if ($swimlane['is_active']) { + $result['active'][] = $swimlane; + } else { + $result['inactive'][] = $swimlane; + } + } + + return $result; + } + + /** * Get list of all swimlanes * * @access public diff --git a/app/Template/column/index.php b/app/Template/column/index.php index 6108661b..3c60d021 100644 --- a/app/Template/column/index.php +++ b/app/Template/column/index.php @@ -15,19 +15,31 @@ data-save-position-url="<?= $this->url->href('ColumnController', 'move', array('project_id' => $project['id'])) ?>"> <thead> <tr> - <th class="column-40"><?= t('Column') ?></th> + <th><?= t('Column') ?></th> <th class="column-10"><?= t('Task limit') ?></th> - <th class="column-20"><?= t('Visible on dashboard') ?></th> - <th class="column-10"><?= t('Open tasks') ?></th> - <th class="column-10"><?= t('Closed tasks') ?></th> - <th><?= t('Actions') ?></th> + <th class="column-15"><?= t('Visible on dashboard') ?></th> + <th class="column-12"><?= t('Open tasks') ?></th> + <th class="column-12"><?= t('Closed tasks') ?></th> </tr> </thead> <tbody> <?php foreach ($columns as $column): ?> <tr data-column-id="<?= $column['id'] ?>"> <td> - <i class="fa fa-arrows-alt draggable-row-handle" title="<?= t('Change column position') ?>"></i> + <i class="fa fa-arrows-alt draggable-row-handle" title="<?= t('Change column position') ?>"></i> + <div class="dropdown"> + <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> + <?= $this->modal->medium('edit', t('Edit'), 'ColumnController', 'edit', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?> + </li> + <?php if ($column['nb_open_tasks'] == 0 && $column['nb_closed_tasks'] == 0): ?> + <li> + <?= $this->modal->confirm('trash-o', t('Remove'), 'ColumnController', 'confirm', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?> + </li> + <?php endif ?> + </ul> + </div> <?= $this->text->e($column['title']) ?> <?php if (! empty($column['description'])): ?> <span class="tooltip" title="<?= $this->text->markdownAttribute($column['description']) ?>"> @@ -47,21 +59,6 @@ <td> <?= $column['nb_closed_tasks'] ?> </td> - <td> - <div class="dropdown"> - <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> - <?= $this->modal->medium('edit', t('Edit'), 'ColumnController', 'edit', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?> - </li> - <?php if ($column['nb_open_tasks'] == 0 && $column['nb_closed_tasks'] == 0): ?> - <li> - <?= $this->modal->confirm('trash-o', t('Remove'), 'ColumnController', 'confirm', array('project_id' => $project['id'], 'column_id' => $column['id'])) ?> - </li> - <?php endif ?> - </ul> - </div> - </td> </tr> <?php endforeach ?> </tbody> diff --git a/app/Template/swimlane/index.php b/app/Template/swimlane/index.php index 35bbb589..59133db3 100644 --- a/app/Template/swimlane/index.php +++ b/app/Template/swimlane/index.php @@ -23,6 +23,6 @@ <?= $this->render('swimlane/table', array( 'swimlanes' => $inactive_swimlanes, 'project' => $project, - 'disable_handler' => true, + 'disable_handle' => true, )) ?> <?php endif ?> diff --git a/app/Template/swimlane/table.php b/app/Template/swimlane/table.php index 4f87924d..708b67f5 100644 --- a/app/Template/swimlane/table.php +++ b/app/Template/swimlane/table.php @@ -4,17 +4,39 @@ <thead> <tr> <th><?= t('Name') ?></th> - <th class="column-8"><?= t('Actions') ?></th> + <th class="column-15"><?= t('Open tasks') ?></th> + <th class="column-15"><?= t('Closed tasks') ?></th> </tr> </thead> <tbody> <?php foreach ($swimlanes as $swimlane): ?> <tr data-swimlane-id="<?= $swimlane['id'] ?>"> <td> - <?php if (! isset($disable_handler)): ?> - <i class="fa fa-arrows-alt draggable-row-handle" title="<?= t('Change column position') ?>"></i> + <?php if (! isset($disable_handle)): ?> + <i class="fa fa-arrows-alt draggable-row-handle" title="<?= t('Change column position') ?>"></i> <?php endif ?> + <div class="dropdown"> + <a href="#" class="dropdown-menu dropdown-menu-link-icon"><i class="fa fa-cog"></i><i class="fa fa-caret-down"></i></a> + <ul> + <li> + <?= $this->modal->medium('edit', t('Edit'), 'SwimlaneController', 'edit', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])) ?> + </li> + <li> + <?php if ($swimlane['is_active']): ?> + <?= $this->url->icon('toggle-off', t('Disable'), 'SwimlaneController', 'disable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?> + <?php else: ?> + <?= $this->url->icon('toggle-on', t('Enable'), 'SwimlaneController', 'enable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?> + <?php endif ?> + </li> + <?php if ($swimlane['nb_open_tasks'] == 0 && $swimlane['nb_closed_tasks'] == 0): ?> + <li> + <?= $this->modal->confirm('trash-o', t('Remove'), 'SwimlaneController', 'confirm', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])) ?> + </li> + <?php endif ?> + </ul> + </div> + <?= $this->text->e($swimlane['name']) ?> <?php if (! empty($swimlane['description'])): ?> @@ -24,24 +46,10 @@ <?php endif ?> </td> <td> - <div class="dropdown"> - <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> - <?= $this->modal->medium('edit', t('Edit'), 'SwimlaneController', 'edit', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])) ?> - </li> - <li> - <?php if ($swimlane['is_active']): ?> - <?= $this->url->icon('toggle-off', t('Disable'), 'SwimlaneController', 'disable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?> - <?php else: ?> - <?= $this->url->icon('toggle-on', t('Enable'), 'SwimlaneController', 'enable', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id']), true) ?> - <?php endif ?> - </li> - <li> - <?= $this->modal->confirm('trash-o', t('Remove'), 'SwimlaneController', 'confirm', array('project_id' => $project['id'], 'swimlane_id' => $swimlane['id'])) ?> - </li> - </ul> - </div> + <?= $swimlane['nb_open_tasks'] ?> + </td> + <td> + <?= $swimlane['nb_closed_tasks'] ?> </td> </tr> <?php endforeach ?> diff --git a/tests/units/Model/ColumnModelTest.php b/tests/units/Model/ColumnModelTest.php index 75d1da20..9f2a4d9e 100644 --- a/tests/units/Model/ColumnModelTest.php +++ b/tests/units/Model/ColumnModelTest.php @@ -105,7 +105,7 @@ class ColumnModelTest extends Base $this->assertEquals(1, $taskCreationModel->create(array('title' => 'UnitTest', 'project_id' => 1, 'column_id' => 1))); $this->assertEquals(2, $taskCreationModel->create(array('title' => 'UnitTest', 'project_id' => 1, 'column_id' => 2, 'is_active' => 0))); - $columns = $columnModel->getAllWithTasksCount(1); + $columns = $columnModel->getAllWithTaskCount(1); $this->assertCount(4, $columns); $this->assertEquals(1, $columns[0]['id']); diff --git a/tests/units/Model/SwimlaneModelTest.php b/tests/units/Model/SwimlaneModelTest.php index 7da93f9c..6bcc3bbf 100644 --- a/tests/units/Model/SwimlaneModelTest.php +++ b/tests/units/Model/SwimlaneModelTest.php @@ -324,4 +324,40 @@ class SwimlaneModelTest extends Base $this->assertEquals(2, $swimlanes[1]['position']); $this->assertEquals(1, $swimlanes[1]['id']); } + + public function testGetAllWithTaskCount() + { + $projectModel = new ProjectModel($this->container); + $swimlaneModel = new SwimlaneModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'Project #1'))); + $this->assertEquals(2, $swimlaneModel->create(1, 'Swimlane #1')); + $this->assertEquals(3, $swimlaneModel->create(1, 'Swimlane #2')); + $this->assertEquals(4, $swimlaneModel->create(1, 'Swimlane #3')); + $this->assertEquals(5, $swimlaneModel->create(1, 'Swimlane #4')); + + $this->assertEquals(1, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'swimlane_id' => 2))); + $this->assertEquals(2, $taskCreationModel->create(array('title' => 'Task #1', 'project_id' => 1, 'swimlane_id' => 3, 'is_active' => 0))); + + $this->assertTrue($swimlaneModel->disable(1, 2)); + $this->assertTrue($swimlaneModel->disable(1, 4)); + + $swimlanes = $swimlaneModel->getAllWithTaskCount(1); + $this->assertCount(3, $swimlanes['active']); + $this->assertCount(2, $swimlanes['inactive']); + + $this->assertEquals('Default swimlane', $swimlanes['active'][0]['name']); + $this->assertEquals('Swimlane #2', $swimlanes['active'][1]['name']); + $this->assertEquals('Swimlane #4', $swimlanes['active'][2]['name']); + + $this->assertEquals(0, $swimlanes['active'][1]['nb_open_tasks']); + $this->assertEquals(1, $swimlanes['active'][1]['nb_closed_tasks']); + + $this->assertEquals('Swimlane #1', $swimlanes['inactive'][0]['name']); + $this->assertEquals('Swimlane #3', $swimlanes['inactive'][1]['name']); + + $this->assertEquals(1, $swimlanes['inactive'][0]['nb_open_tasks']); + $this->assertEquals(0, $swimlanes['inactive'][0]['nb_closed_tasks']); + } } |