diff --git a/app/Controller/Board.php b/app/Controller/Board.php index f43527ead..e2c10f585 100644 --- a/app/Controller/Board.php +++ b/app/Controller/Board.php @@ -51,39 +51,27 @@ class Board extends Base * * @access public */ - public function assign() + public function changeAssignee() { - $task = $this->task->getById($this->request->getIntegerParam('task_id')); + $task = $this->getTask(); $project = $this->project->getById($task['project_id']); - $projects = $this->project->getListByStatus(ProjectModel::ACTIVE); - - if ($this->acl->isRegularUser()) { - $projects = $this->project->filterListByAccess($projects, $this->acl->getUserId()); - } - - if (! $project) $this->notfound(); - $this->checkProjectPermissions($project['id']); + $projects = $this->project->getAvailableList($this->acl->getUserId()); + $params = array( + 'errors' => array(), + 'values' => $task, + 'users_list' => $this->project->getUsersList($project['id']), + 'projects' => $projects, + 'current_project_id' => $project['id'], + 'current_project_name' => $project['name'], + ); if ($this->request->isAjax()) { - $this->response->html($this->template->load('board_assign', array( - 'errors' => array(), - 'values' => $task, - 'users_list' => $this->project->getUsersList($project['id']), - 'projects' => $projects, - 'current_project_id' => $project['id'], - 'current_project_name' => $project['name'], - ))); + $this->response->html($this->template->load('board_assignee', $params)); } else { - $this->response->html($this->template->layout('board_assign', array( - 'errors' => array(), - 'values' => $task, - 'users_list' => $this->project->getUsersList($project['id']), - 'projects' => $projects, - 'current_project_id' => $project['id'], - 'current_project_name' => $project['name'], + $this->response->html($this->template->layout('board_assignee', $params + array( 'menu' => 'boards', 'title' => t('Change assignee').' - '.$task['title'], ))); @@ -95,7 +83,7 @@ class Board extends Base * * @access public */ - public function assignTask() + public function updateAssignee() { $values = $this->request->getValues(); $this->checkProjectPermissions($values['project_id']); @@ -112,6 +100,60 @@ class Board extends Base $this->response->redirect('?controller=board&action=show&project_id='.$values['project_id']); } + /** + * Change a task category directly from the board + * + * @access public + */ + public function changeCategory() + { + $task = $this->getTask(); + $project = $this->project->getById($task['project_id']); + $projects = $this->project->getAvailableList($this->acl->getUserId()); + $params = array( + 'errors' => array(), + 'values' => $task, + 'categories_list' => $this->category->getList($project['id']), + 'projects' => $projects, + 'current_project_id' => $project['id'], + 'current_project_name' => $project['name'], + ); + + if ($this->request->isAjax()) { + + $this->response->html($this->template->load('board_category', $params)); + } + else { + + $this->response->html($this->template->layout('board_category', $params + array( + 'menu' => 'boards', + 'title' => t('Change category').' - '.$task['title'], + ))); + } + } + + /** + * Validate a category modification + * + * @access public + */ + public function updateCategory() + { + $values = $this->request->getValues(); + $this->checkProjectPermissions($values['project_id']); + + list($valid,) = $this->task->validateCategoryModification($values); + + if ($valid && $this->task->update($values)) { + $this->session->flash(t('Task updated successfully.')); + } + else { + $this->session->flashError(t('Unable to update your task.')); + } + + $this->response->redirect('?controller=board&action=show&project_id='.$values['project_id']); + } + /** * Display the public version of a board * Access checked by a simple token, no user login, read only, auto-refresh diff --git a/app/Locales/de_DE/translations.php b/app/Locales/de_DE/translations.php index 006efe849..ad3b2ff89 100644 --- a/app/Locales/de_DE/translations.php +++ b/app/Locales/de_DE/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/es_ES/translations.php b/app/Locales/es_ES/translations.php index 295d64649..a853718c8 100644 --- a/app/Locales/es_ES/translations.php +++ b/app/Locales/es_ES/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/fi_FI/translations.php b/app/Locales/fi_FI/translations.php index d7e929ce2..809be56dc 100644 --- a/app/Locales/fi_FI/translations.php +++ b/app/Locales/fi_FI/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/fr_FR/translations.php b/app/Locales/fr_FR/translations.php index 230e51dbb..96fb3a519 100644 --- a/app/Locales/fr_FR/translations.php +++ b/app/Locales/fr_FR/translations.php @@ -466,4 +466,6 @@ return array( 'No external authentication enabled.' => 'Aucune authentication externe activée.', 'Password modified successfully.' => 'Mot de passe changé avec succès.', 'Unable to change the password.' => 'Impossible de changer le mot de passe.', + 'Change category for the task "%s"' => 'Changer la catégorie pour la tâche « %s »', + 'Change category' => 'Changer de catégorie', ); diff --git a/app/Locales/it_IT/translations.php b/app/Locales/it_IT/translations.php index 3c5e3ae8e..33ad358f0 100644 --- a/app/Locales/it_IT/translations.php +++ b/app/Locales/it_IT/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/pl_PL/translations.php b/app/Locales/pl_PL/translations.php index f12ec080a..34d4a7046 100644 --- a/app/Locales/pl_PL/translations.php +++ b/app/Locales/pl_PL/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/pt_BR/translations.php b/app/Locales/pt_BR/translations.php index ec67c90aa..cd337939b 100644 --- a/app/Locales/pt_BR/translations.php +++ b/app/Locales/pt_BR/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/sv_SE/translations.php b/app/Locales/sv_SE/translations.php index 55878da5e..a2ce90168 100644 --- a/app/Locales/sv_SE/translations.php +++ b/app/Locales/sv_SE/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Locales/zh_CN/translations.php b/app/Locales/zh_CN/translations.php index 91d5ff493..8a4b8836f 100644 --- a/app/Locales/zh_CN/translations.php +++ b/app/Locales/zh_CN/translations.php @@ -466,4 +466,6 @@ return array( // 'No external authentication enabled.' => '', // 'Password modified successfully.' => '', // 'Unable to change the password.' => '', + // 'Change category for the task "%s"' => '', + // 'Change category' => '', ); diff --git a/app/Model/Acl.php b/app/Model/Acl.php index a76207317..21c763294 100644 --- a/app/Model/Acl.php +++ b/app/Model/Acl.php @@ -30,7 +30,7 @@ class Acl extends Base */ private $user_actions = array( 'app' => array('index'), - 'board' => array('index', 'show', 'assign', 'assigntask', 'save', 'check'), + 'board' => array('index', 'show', 'save', 'check', 'changeassignee', 'updateassignee', 'changecategory', 'updatecategory'), 'project' => array('tasks', 'index', 'forbidden', 'search', 'export', 'show'), 'user' => array('index', 'edit', 'forbidden', 'logout', 'index', 'show', 'external', 'unlinkgoogle', 'unlinkgithub', 'sessions', 'removesession', 'last', 'notifications', 'password'), 'comment' => array('create', 'save', 'confirm', 'remove', 'update', 'edit', 'forbidden'), diff --git a/app/Model/Task.php b/app/Model/Task.php index 6a20f4d0f..df6e44263 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -704,6 +704,30 @@ class Task extends Base ); } + /** + * Validate category change + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateCategoryModification(array $values) + { + $v = new Validator($values, array( + new Validators\Required('id', t('The id is required')), + new Validators\Integer('id', t('This value must be an integer')), + new Validators\Required('project_id', t('The project is required')), + new Validators\Integer('project_id', t('This value must be an integer')), + new Validators\Required('category_id', t('This value is required')), + new Validators\Integer('category_id', t('This value must be an integer')), + )); + + return array( + $v->execute(), + $v->getErrors() + ); + } + /** * Validate project modification * diff --git a/app/Templates/board_assign.php b/app/Templates/board_assignee.php similarity index 86% rename from app/Templates/board_assign.php rename to app/Templates/board_assignee.php index 45cb4b4fc..41ede32b0 100644 --- a/app/Templates/board_assign.php +++ b/app/Templates/board_assignee.php @@ -1,14 +1,12 @@

-
+ diff --git a/app/Templates/board_category.php b/app/Templates/board_category.php new file mode 100644 index 000000000..36126a1de --- /dev/null +++ b/app/Templates/board_category.php @@ -0,0 +1,24 @@ +
+ + + +
+

+ + + + + + +
+ +
+ + +
+ +
+ +
\ No newline at end of file diff --git a/app/Templates/board_task.php b/app/Templates/board_task.php index 4370558b6..40590a653 100644 --- a/app/Templates/board_task.php +++ b/app/Templates/board_task.php @@ -23,11 +23,13 @@ # - - - - - - + + + + + + + @@ -44,7 +46,9 @@
- + + +
diff --git a/assets/js/app.js b/assets/js/app.js index 68da5fcb0..70e2ca380 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -92,6 +92,9 @@ Kanboard.Board = (function() { // Assignee change $(".assignee-popover").click(Kanboard.Popover); + // Category change + $(".category-popover").click(Kanboard.Popover); + // Task edit popover $(".task-edit-popover").click(function(e) { Kanboard.Popover(e, Kanboard.Task.Init);