summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2016-02-19 22:59:47 -0500
committerFrederic Guillot <fred@kanboard.net>2016-02-19 22:59:47 -0500
commitde4519fa2c45ca96d4bf0b9ce288cad600d09854 (patch)
tree9e66f936c8c82f32332cf74c24ca235dda5cd47b /app
parent270e0835b2f1b6de2c84d2cb1b7596d5babb6c2f (diff)
Add subtasks drag and drop
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Subtask.php15
-rw-r--r--app/Model/Subtask.php66
-rw-r--r--app/Template/subtask/menu.php10
-rw-r--r--app/Template/subtask/show.php2
-rw-r--r--app/Template/subtask/table.php13
-rw-r--r--app/Template/task/show.php1
6 files changed, 35 insertions, 72 deletions
diff --git a/app/Controller/Subtask.php b/app/Controller/Subtask.php
index f8798906..a0a3eb66 100644
--- a/app/Controller/Subtask.php
+++ b/app/Controller/Subtask.php
@@ -23,7 +23,6 @@ class Subtask extends Base
'project' => $this->getProject(),
'subtasks' => $this->subtask->getAll($task['id']),
'editable' => true,
- 'redirect' => 'subtask',
)));
}
@@ -169,15 +168,15 @@ class Subtask extends Base
*/
public function movePosition()
{
- $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
$task_id = $this->request->getIntegerParam('task_id');
- $subtask_id = $this->request->getIntegerParam('subtask_id');
- $direction = $this->request->getStringParam('direction');
- $method = $direction === 'up' ? 'moveUp' : 'moveDown';
- $redirect = $this->request->getStringParam('redirect', 'task');
+ $values = $this->request->getJson();
+
+ 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));
+ }
- $this->subtask->$method($task_id, $subtask_id);
- $this->response->redirect($this->helper->url->to($redirect, 'show', array('project_id' => $project_id, 'task_id' => $task_id), 'subtasks'));
+ $this->forbidden();
}
}
diff --git a/app/Model/Subtask.php b/app/Model/Subtask.php
index 14853941..3707af13 100644
--- a/app/Model/Subtask.php
+++ b/app/Model/Subtask.php
@@ -284,68 +284,36 @@ class Subtask extends Base
}
/**
- * Save the new positions for a set of subtasks
- *
- * @access public
- * @param array $subtasks Hashmap of column_id/column_position
- * @return boolean
- */
- public function savePositions(array $subtasks)
- {
- return $this->db->transaction(function (Database $db) use ($subtasks) {
-
- foreach ($subtasks as $subtask_id => $position) {
- if (! $db->table(Subtask::TABLE)->eq('id', $subtask_id)->update(array('position' => $position))) {
- return false;
- }
- }
- });
- }
-
- /**
- * Move a subtask down, increment the position value
+ * Save subtask position
*
* @access public
* @param integer $task_id
* @param integer $subtask_id
+ * @param integer $position
* @return boolean
*/
- public function moveDown($task_id, $subtask_id)
+ public function changePosition($task_id, $subtask_id, $position)
{
- $subtasks = $this->getNormalizedPositions($task_id);
- $positions = array_flip($subtasks);
-
- if (isset($subtasks[$subtask_id]) && $subtasks[$subtask_id] < count($subtasks)) {
- $position = ++$subtasks[$subtask_id];
- $subtasks[$positions[$position]]--;
-
- return $this->savePositions($subtasks);
+ if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('task_id', $task_id)->count()) {
+ return false;
}
- return false;
- }
+ $subtask_ids = $this->db->table(self::TABLE)->eq('task_id', $task_id)->neq('id', $subtask_id)->asc('position')->findAllByColumn('id');
+ $offset = 1;
+ $results = array();
- /**
- * Move a subtask up, decrement the position value
- *
- * @access public
- * @param integer $task_id
- * @param integer $subtask_id
- * @return boolean
- */
- public function moveUp($task_id, $subtask_id)
- {
- $subtasks = $this->getNormalizedPositions($task_id);
- $positions = array_flip($subtasks);
-
- if (isset($subtasks[$subtask_id]) && $subtasks[$subtask_id] > 1) {
- $position = --$subtasks[$subtask_id];
- $subtasks[$positions[$position]]++;
+ foreach ($subtask_ids as $current_subtask_id) {
+ if ($offset == $position) {
+ $offset++;
+ }
- return $this->savePositions($subtasks);
+ $results[] = $this->db->table(self::TABLE)->eq('id', $current_subtask_id)->update(array('position' => $offset));
+ $offset++;
}
- return false;
+ $results[] = $this->db->table(self::TABLE)->eq('id', $subtask_id)->update(array('position' => $position));
+
+ return !in_array(false, $results, true);
}
/**
diff --git a/app/Template/subtask/menu.php b/app/Template/subtask/menu.php
index 16174bcf..6c98b951 100644
--- a/app/Template/subtask/menu.php
+++ b/app/Template/subtask/menu.php
@@ -1,16 +1,6 @@
<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>
- <?php if ($subtask['position'] != $first_position): ?>
- <li>
- <?= $this->url->link(t('Move Up'), 'subtask', 'movePosition', array('project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'direction' => 'up', 'redirect' => $redirect), true) ?>
- </li>
- <?php endif ?>
- <?php if ($subtask['position'] != $last_position): ?>
- <li>
- <?= $this->url->link(t('Move Down'), 'subtask', 'movePosition', array('project_id' => $task['project_id'], 'task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id'], 'direction' => 'down', 'redirect' => $redirect), true) ?>
- </li>
- <?php endif ?>
<li>
<?= $this->url->link(t('Edit'), 'subtask', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id']), false, 'popover') ?>
</li>
diff --git a/app/Template/subtask/show.php b/app/Template/subtask/show.php
index bd999496..b0326c48 100644
--- a/app/Template/subtask/show.php
+++ b/app/Template/subtask/show.php
@@ -4,7 +4,7 @@
<div id="subtasks">
- <?= $this->render('subtask/table', array('subtasks' => $subtasks, 'task' => $task, 'editable' => $editable, 'redirect' => $redirect)) ?>
+ <?= $this->render('subtask/table', array('subtasks' => $subtasks, 'task' => $task, 'editable' => $editable)) ?>
<?php if ($editable && $this->user->hasProjectAccess('subtask', 'save', $task['project_id'])): ?>
<form method="post" action="<?= $this->url->href('subtask', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
diff --git a/app/Template/subtask/table.php b/app/Template/subtask/table.php
index 8ad9664c..53902057 100644
--- a/app/Template/subtask/table.php
+++ b/app/Template/subtask/table.php
@@ -3,7 +3,11 @@
<?php $first_position = $subtasks[0]['position']; ?>
<?php $last_position = $subtasks[count($subtasks) - 1]['position']; ?>
- <table class="subtasks-table">
+ <table
+ class="subtasks-table table-stripped"
+ data-save-position-url="<?= $this->url->href('Subtask', 'movePosition', array('project_id' => $task['project_id'], 'task_id' => $task['id'])) ?>"
+ >
+ <thead>
<tr>
<th class="column-40"><?= t('Title') ?></th>
<th><?= t('Assignee') ?></th>
@@ -12,10 +16,13 @@
<th class="column-5"></th>
<?php endif ?>
</tr>
+ </thead>
+ <tbody>
<?php foreach ($subtasks as $subtask): ?>
- <tr>
+ <tr data-subtask-id="<?= $subtask['id'] ?>">
<td>
<?php if ($editable): ?>
+ <i class="fa fa-arrows-alt draggable-row-handle" title="<?= t('Move subtask position') ?>"></i>
<?= $this->subtask->toggleStatus($subtask, $task['project_id'], true) ?>
<?php else: ?>
<?= $this->subtask->getTitle($subtask) ?>
@@ -58,12 +65,12 @@
'subtask' => $subtask,
'first_position' => $first_position,
'last_position' => $last_position,
- 'redirect' => $redirect,
)) ?>
</td>
<?php endif ?>
</tr>
<?php endforeach ?>
+ </tbody>
</table>
<?php else: ?>
<p class="alert"><?= t('There is no subtask at the moment.') ?></p>
diff --git a/app/Template/task/show.php b/app/Template/task/show.php
index a32232ae..0c77f576 100644
--- a/app/Template/task/show.php
+++ b/app/Template/task/show.php
@@ -12,7 +12,6 @@
'project' => $project,
'users_list' => isset($users_list) ? $users_list : array(),
'editable' => true,
- 'redirect' => 'task',
)) ?>
<?= $this->render('tasklink/show', array(