diff options
-rw-r--r-- | app/Action/TaskAssignColorSwimlane.php | 99 | ||||
-rw-r--r-- | app/Action/TaskAssignPrioritySwimlane.php | 99 | ||||
-rw-r--r-- | app/Controller/ActionController.php | 1 | ||||
-rw-r--r-- | app/Controller/ActionCreationController.php | 1 | ||||
-rw-r--r-- | app/Core/Event/EventManager.php | 1 | ||||
-rw-r--r-- | app/Model/ActionParameterModel.php | 5 | ||||
-rw-r--r-- | app/ServiceProvider/ActionProvider.php | 4 | ||||
-rw-r--r-- | app/Template/action/index.php | 2 | ||||
-rw-r--r-- | app/Template/action_creation/params.php | 7 | ||||
-rw-r--r-- | tests/units/Action/TaskAssignColorSwimlaneTest.php | 70 | ||||
-rw-r--r-- | tests/units/Action/TaskAssignPrioritySwimlaneTest.php | 46 |
11 files changed, 332 insertions, 3 deletions
diff --git a/app/Action/TaskAssignColorSwimlane.php b/app/Action/TaskAssignColorSwimlane.php new file mode 100644 index 00000000..31f2d25a --- /dev/null +++ b/app/Action/TaskAssignColorSwimlane.php @@ -0,0 +1,99 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\TaskModel; + +/** + * Assign a color to a task based on Swimlane + * + * @package Kanboard\Action + * @author Dave Almond + */ +class TaskAssignColorSwimlane extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a color when the task is moved to a specific swimlane'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + TaskModel::EVENT_CREATE, + TaskModel::EVENT_MOVE_SWIMLANE, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'swimlane_id' => t('Swimlane'), + 'color_id' => t('Color'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'task' => array( + 'project_id', + 'swimlane_id', + ), + ); + } + + /** + * Execute the action (set the task color) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $values = array( + 'id' => $data['task_id'], + 'color_id' => $this->getParam('color_id'), + ); + + return $this->taskModificationModel->update($values, false); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['task']['swimlane_id'] == $this->getParam('swimlane_id'); + } +} diff --git a/app/Action/TaskAssignPrioritySwimlane.php b/app/Action/TaskAssignPrioritySwimlane.php new file mode 100644 index 00000000..7eaca7c8 --- /dev/null +++ b/app/Action/TaskAssignPrioritySwimlane.php @@ -0,0 +1,99 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\TaskModel; + +/** + * Set a priority automatically according to the Swimlane + * + * @package Kanboard\Action + * @author Dave Almond + */ +class TaskAssignPrioritySwimlane extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a priority when the task is moved to a specific swimlane'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + TaskModel::EVENT_CREATE, + TaskModel::EVENT_MOVE_SWIMLANE, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'swimlane_id' => t('Swimlane'), + 'priority' => t('Priority'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'task' => array( + 'project_id', + 'swimlane_id', + ), + ); + } + + /** + * Execute the action (set the priority) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $values = array( + 'id' => $data['task_id'], + 'priority' => $this->getParam('priority'), + ); + + return $this->taskModificationModel->update($values); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['task']['swimlane_id'] == $this->getParam('swimlane_id'); + } +} diff --git a/app/Controller/ActionController.php b/app/Controller/ActionController.php index 097640f6..c935125a 100644 --- a/app/Controller/ActionController.php +++ b/app/Controller/ActionController.php @@ -33,6 +33,7 @@ class ActionController extends BaseController 'colors_list' => $this->colorModel->getList(), 'categories_list' => $this->categoryModel->getList($project['id']), 'links_list' => $this->linkModel->getList(0, false), + 'swimlane_list' => $this->swimlaneModel->getList($project['id']), 'title' => t('Automatic actions') ))); } diff --git a/app/Controller/ActionCreationController.php b/app/Controller/ActionCreationController.php index 9b228f28..1629e68f 100644 --- a/app/Controller/ActionCreationController.php +++ b/app/Controller/ActionCreationController.php @@ -84,6 +84,7 @@ class ActionCreationController extends BaseController 'priorities_list' => $this->projectTaskPriorityModel->getPriorities($project), 'project' => $project, 'available_actions' => $this->actionManager->getAvailableActions(), + 'swimlane_list' => $this->swimlaneModel->getList($project['id']), 'events' => $this->actionManager->getCompatibleEvents($values['action_name']), ))); } diff --git a/app/Core/Event/EventManager.php b/app/Core/Event/EventManager.php index 9ae43170..68e81a9e 100644 --- a/app/Core/Event/EventManager.php +++ b/app/Core/Event/EventManager.php @@ -53,6 +53,7 @@ class EventManager TaskModel::EVENT_CREATE_UPDATE => t('Task creation or modification'), TaskModel::EVENT_ASSIGNEE_CHANGE => t('Task assignee change'), TaskModel::EVENT_DAILY_CRONJOB => t('Daily background job for tasks'), + TaskModel::EVENT_MOVE_SWIMLANE => t('Move a task to another swimlane'), ); $events = array_merge($events, $this->events); diff --git a/app/Model/ActionParameterModel.php b/app/Model/ActionParameterModel.php index 9895da0f..d4d45178 100644 --- a/app/Model/ActionParameterModel.php +++ b/app/Model/ActionParameterModel.php @@ -157,7 +157,10 @@ class ActionParameterModel extends Base case 'user_id': case 'owner_id': return $this->projectPermissionModel->isAssignable($project_id, $value) ? $value : false; - default: + case 'swimlane_id': + $column = $this->swimlaneModel->getById($value); + return empty($column) ? false : $this->swimlaneModel->getIdByName($project_id, $column['name']) ?: false; + default: return $value; } } diff --git a/app/ServiceProvider/ActionProvider.php b/app/ServiceProvider/ActionProvider.php index 946fbf41..d46562b7 100644 --- a/app/ServiceProvider/ActionProvider.php +++ b/app/ServiceProvider/ActionProvider.php @@ -36,6 +36,8 @@ use Kanboard\Action\TaskOpen; use Kanboard\Action\TaskUpdateStartDate; use Kanboard\Action\TaskCloseNoActivity; use Kanboard\Action\TaskCloseNoActivityColumn; +use Kanboard\Action\TaskAssignColorSwimlane; +use Kanboard\Action\TaskAssignPrioritySwimlane; /** * Action Provider @@ -86,6 +88,8 @@ class ActionProvider implements ServiceProviderInterface $container['actionManager']->register(new TaskOpen($container)); $container['actionManager']->register(new TaskUpdateStartDate($container)); $container['actionManager']->register(new TaskAssignDueDateOnCreation($container)); + $container['actionManager']->register(new TaskAssignColorSwimlane($container)); + $container['actionManager']->register(new TaskAssignPrioritySwimlane($container)); return $container; } diff --git a/app/Template/action/index.php b/app/Template/action/index.php index 085ea3ad..7768a0b6 100644 --- a/app/Template/action/index.php +++ b/app/Template/action/index.php @@ -54,6 +54,8 @@ <?= $this->text->in($param_value, $categories_list) ?> <?php elseif ($this->text->contains($param_name, 'link_id')): ?> <?= $this->text->in($param_value, $links_list) ?> + <?php elseif ($this->text->contains($param_name, 'swimlane_id')): ?> + <?= $this->text->in($param_value, $swimlane_list) ?> <?php else: ?> <?= $this->text->e($param_value) ?> <?php endif ?> diff --git a/app/Template/action_creation/params.php b/app/Template/action_creation/params.php index fa892177..bcf863d7 100644 --- a/app/Template/action_creation/params.php +++ b/app/Template/action_creation/params.php @@ -41,10 +41,13 @@ <?php elseif ($this->text->contains($param_name, 'duration')): ?> <?= $this->form->label($param_desc, $param_name) ?> <?= $this->form->number('params['.$param_name.']', $values) ?> - <?php else: ?> + <?php elseif ($this->text->contains($param_name, 'swimlane_id')): ?> + <?= $this->form->label($param_desc, $param_name) ?> + <?= $this->form->select('params['.$param_name.']', $swimlane_list, $values) ?> + <?php else: ?> <?= $this->form->label($param_desc, $param_name) ?> <?= $this->form->text('params['.$param_name.']', $values) ?> - <?php endif ?> + <?php endif ?> <?php endforeach ?> <div class="form-actions"> diff --git a/tests/units/Action/TaskAssignColorSwimlaneTest.php b/tests/units/Action/TaskAssignColorSwimlaneTest.php new file mode 100644 index 00000000..811ffac3 --- /dev/null +++ b/tests/units/Action/TaskAssignColorSwimlaneTest.php @@ -0,0 +1,70 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\TaskEvent; +use Kanboard\Model\TaskCreationModel; +use Kanboard\Model\TaskFinderModel; +use Kanboard\Model\ProjectModel; +use Kanboard\Model\TaskModel; +use Kanboard\Action\TaskAssignColorSwimlane; + +class TaskAssignColorSwimlaneTest extends Base +{ + public function testChangeSwimlane() + { + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new TaskEvent(array( + 'task_id' => 1, + 'task' => array( + 'project_id' => 1, + 'swimlane_id' => 2, + ) + )); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertNotEquals('red', $task['color_id']); + + $action = new TaskAssignColorSwimlane($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('swimlane_id', 2); + + $this->assertTrue($action->execute($event, TaskModel::EVENT_MOVE_SWIMLANE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('red', $task['color_id']); + } + + public function testWithWrongSwimlane() + { + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = new TaskEvent(array( + 'task_id' => 1, + 'task' => array( + 'project_id' => 1, + 'swimlane_id' => 3, + ) + )); + + $action = new TaskAssignColorSwimlane($this->container); + $action->setProjectId(1); + $action->setParam('color_id', 'red'); + $action->setParam('swimlane_id', 2); + + $this->assertFalse($action->execute($event, TaskModel::EVENT_MOVE_SWIMLANE)); + } +} diff --git a/tests/units/Action/TaskAssignPrioritySwimlaneTest.php b/tests/units/Action/TaskAssignPrioritySwimlaneTest.php new file mode 100644 index 00000000..39c833bf --- /dev/null +++ b/tests/units/Action/TaskAssignPrioritySwimlaneTest.php @@ -0,0 +1,46 @@ +<?php + +require_once __DIR__.'/../Base.php'; + +use Kanboard\Event\TaskEvent; +use Kanboard\Model\TaskCreationModel; +use Kanboard\Model\TaskFinderModel; +use Kanboard\Model\ProjectModel; +use Kanboard\Model\TaskModel; +use Kanboard\Action\TaskAssignPrioritySwimlane; + +class TaskAssignPrioritySwimlaneTest extends Base +{ + public function testChangeSwimlane() + { + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'priority' => 1))); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['priority']); + + $event = new TaskEvent(array( + 'task_id' => 1, + 'task' => array( + 'project_id' => 1, + 'swimlane_id' => 2, + ) + )); + + $action = new TaskAssignPrioritySwimlane($this->container); + $action->setProjectId(1); + $action->setParam('priority', 2); + $action->setParam('swimlane_id', 2); + + $this->assertTrue($action->execute($event, TaskModel::EVENT_MOVE_SWIMLANE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(2, $task['priority']); + } +} |