diff --git a/ChangeLog b/ChangeLog index 31b089b08..ae7919bf5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ Version 1.0.26 (unreleased) New features: -* Add subtasks drag and drop +* Add drag and drop to change subtasks and columns positions * Add file drag and drop and asynchronous upload * Enable/Disable users * Add setting option to disable private projects diff --git a/Makefile b/Makefile index 3e05f29c9..a62c105a1 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CSS_APP = $(addprefix assets/css/src/, $(addsuffix .css, base links title table CSS_PRINT = $(addprefix assets/css/src/, $(addsuffix .css, print links table board task comment subtask markdown)) CSS_VENDOR = $(addprefix assets/css/vendor/, $(addsuffix .css, jquery-ui.min jquery-ui-timepicker-addon.min chosen.min fullcalendar.min font-awesome.min c3.min)) -JS_APP = $(addprefix assets/js/src/, $(addsuffix .js, Popover Dropdown Tooltip Markdown Search App Screenshot FileUpload Calendar Board Swimlane Gantt Task Project Subtask TaskRepartitionChart UserRepartitionChart CumulativeFlowDiagram BurndownChart AvgTimeColumnChart TaskTimeColumnChart LeadCycleTimeChart CompareHoursColumnChart Router)) +JS_APP = $(addprefix assets/js/src/, $(addsuffix .js, Popover Dropdown Tooltip Markdown Search App Screenshot FileUpload Calendar Board Column Swimlane Gantt Task Project Subtask TaskRepartitionChart UserRepartitionChart CumulativeFlowDiagram BurndownChart AvgTimeColumnChart TaskTimeColumnChart LeadCycleTimeChart CompareHoursColumnChart Router)) JS_VENDOR = $(addprefix assets/js/vendor/, $(addsuffix .js, jquery-1.11.3.min jquery-ui.min jquery-ui-timepicker-addon.min jquery.ui.touch-punch.min chosen.jquery.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min jquery.textcomplete)) JS_LANG = $(addprefix assets/js/vendor/lang/, $(addsuffix .js, cs da de es el fi fr hu id it ja nl nb pl pt pt-br ru sv sr th tr zh-cn)) diff --git a/app/Controller/Column.php b/app/Controller/Column.php index 772041649..2e028e0ed 100644 --- a/app/Controller/Column.php +++ b/app/Controller/Column.php @@ -117,22 +117,21 @@ class Column extends Base } /** - * Move a column up or down + * Move column position * * @access public */ public function move() { - $this->checkCSRFParam(); $project = $this->getProject(); - $column_id = $this->request->getIntegerParam('column_id'); - $direction = $this->request->getStringParam('direction'); + $values = $this->request->getJson(); - if ($direction === 'up' || $direction === 'down') { - $this->board->{'move'.$direction}($project['id'], $column_id); + if (! empty($values)) { + $result = $this->column->changePosition($project['id'], $values['column_id'], $values['position']); + return $this->response->json(array('result' => $result)); } - $this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id']))); + $this->forbidden(); } /** diff --git a/app/Controller/Subtask.php b/app/Controller/Subtask.php index a0a3eb669..8ca0ce92d 100644 --- a/app/Controller/Subtask.php +++ b/app/Controller/Subtask.php @@ -174,7 +174,7 @@ class Subtask extends Base if (! empty($values) && $this->helper->user->hasProjectAccess('Subtask', 'movePosition', $project_id)) { $result = $this->subtask->changePosition($task_id, $values['subtask_id'], $values['position']); - $this->response->json(array('result' => $result)); + return $this->response->json(array('result' => $result)); } $this->forbidden(); diff --git a/app/Model/Column.php b/app/Model/Column.php new file mode 100644 index 000000000..286b6140f --- /dev/null +++ b/app/Model/Column.php @@ -0,0 +1,64 @@ +db->table(self::TABLE)->eq('project_id', $project_id)->asc('position')->findAll(); + } + + /** + * Change column position + * + * @access public + * @param integer $project_id + * @param integer $column_id + * @param integer $position + * @return boolean + */ + public function changePosition($project_id, $column_id, $position) + { + if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('project_id', $project_id)->count()) { + return false; + } + + $column_ids = $this->db->table(self::TABLE)->eq('project_id', $project_id)->neq('id', $column_id)->asc('position')->findAllByColumn('id'); + $offset = 1; + $results = array(); + + foreach ($column_ids as $current_column_id) { + if ($offset == $position) { + $offset++; + } + + $results[] = $this->db->table(self::TABLE)->eq('id', $current_column_id)->update(array('position' => $offset)); + $offset++; + } + + $results[] = $this->db->table(self::TABLE)->eq('id', $column_id)->update(array('position' => $position)); + + return !in_array(false, $results, true); + } +} diff --git a/app/Model/Subtask.php b/app/Model/Subtask.php index 3707af138..b5898fcf3 100644 --- a/app/Model/Subtask.php +++ b/app/Model/Subtask.php @@ -262,27 +262,6 @@ class Subtask extends Base return $this->db->table(self::TABLE)->eq('task_id', $task_id)->update(array('status' => self::STATUS_DONE)); } - /** - * Get subtasks with consecutive positions - * - * If you remove a subtask, the positions are not anymore consecutives - * - * @access public - * @param integer $task_id - * @return array - */ - public function getNormalizedPositions($task_id) - { - $subtasks = $this->db->hashtable(self::TABLE)->eq('task_id', $task_id)->asc('position')->getAll('id', 'position'); - $position = 1; - - foreach ($subtasks as $subtask_id => $subtask_position) { - $subtasks[$subtask_id] = $position++; - } - - return $subtasks; - } - /** * Save subtask position * diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index a4fa1ff26..0f2fbab5d 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -27,6 +27,7 @@ class ClassProvider implements ServiceProviderInterface 'Board', 'Category', 'Color', + 'Column', 'Comment', 'Config', 'Currency', diff --git a/app/Template/column/index.php b/app/Template/column/index.php index 8d95dd487..c6a6e85be 100644 --- a/app/Template/column/index.php +++ b/app/Template/column/index.php @@ -8,28 +8,34 @@ - - - - - -