Add subtasks drag and drop
This commit is contained in:
parent
270e0835b2
commit
de4519fa2c
|
|
@ -3,6 +3,7 @@ Version 1.0.26 (unreleased)
|
|||
|
||||
New features:
|
||||
|
||||
* Add subtasks drag and drop
|
||||
* Add file drag and drop and asynchronous upload
|
||||
* Enable/Disable users
|
||||
* Add setting option to disable private projects
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
$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'));
|
||||
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->forbidden();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,68 +284,36 @@ class Subtask extends Base
|
|||
}
|
||||
|
||||
/**
|
||||
* Save the new positions for a set of subtasks
|
||||
* Save subtask position
|
||||
*
|
||||
* @access public
|
||||
* @param array $subtasks Hashmap of column_id/column_position
|
||||
* @param integer $task_id
|
||||
* @param integer $subtask_id
|
||||
* @param integer $position
|
||||
* @return boolean
|
||||
*/
|
||||
public function savePositions(array $subtasks)
|
||||
public function changePosition($task_id, $subtask_id, $position)
|
||||
{
|
||||
return $this->db->transaction(function (Database $db) use ($subtasks) {
|
||||
if ($position < 1 || $position > $this->db->table(self::TABLE)->eq('task_id', $task_id)->count()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($subtasks as $subtask_id => $position) {
|
||||
if (! $db->table(Subtask::TABLE)->eq('id', $subtask_id)->update(array('position' => $position))) {
|
||||
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();
|
||||
|
||||
foreach ($subtask_ids as $current_subtask_id) {
|
||||
if ($offset == $position) {
|
||||
$offset++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a subtask down, increment the position value
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_id
|
||||
* @param integer $subtask_id
|
||||
* @return boolean
|
||||
*/
|
||||
public function moveDown($task_id, $subtask_id)
|
||||
{
|
||||
$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);
|
||||
$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));
|
||||
|
||||
/**
|
||||
* 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]]++;
|
||||
|
||||
return $this->savePositions($subtasks);
|
||||
}
|
||||
|
||||
return false;
|
||||
return !in_array(false, $results, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
'project' => $project,
|
||||
'users_list' => isset($users_list) ? $users_list : array(),
|
||||
'editable' => true,
|
||||
'redirect' => 'task',
|
||||
)) ?>
|
||||
|
||||
<?= $this->render('tasklink/show', array(
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -62,7 +62,7 @@ th a:hover {
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.table-stripped tr:nth-child(odd) td {
|
||||
.table-stripped tr:nth-child(odd) {
|
||||
background: #fefefe;
|
||||
}
|
||||
|
||||
|
|
@ -124,4 +124,38 @@ th a:hover {
|
|||
|
||||
.column-70 {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
|
||||
.draggable-row-handle {
|
||||
cursor: move;
|
||||
color: #dedede;
|
||||
}
|
||||
|
||||
.draggable-row-handle:hover {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
tr.draggable-item-selected {
|
||||
background: #fff;
|
||||
border: 2px solid #666;
|
||||
box-shadow: 4px 2px 10px -4px rgba(0,0,0,0.55);
|
||||
}
|
||||
|
||||
tr.draggable-item-selected td {
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
tr.draggable-item-selected td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
tr.draggable-item-selected td:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.table-stripped tr.draggable-item-hover,
|
||||
tr.draggable-item-hover {
|
||||
background: #FEFFF2;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,7 @@ function App() {
|
|||
this.popover = new Popover(this);
|
||||
this.task = new Task();
|
||||
this.project = new Project();
|
||||
this.subtask = new Subtask();
|
||||
this.subtask = new Subtask(this);
|
||||
this.file = new FileUpload(this);
|
||||
this.keyboardShortcuts();
|
||||
this.chosen();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
function Subtask() {
|
||||
function Subtask(app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
Subtask.prototype.listen = function() {
|
||||
var self = this;
|
||||
|
||||
this.dragAndDrop();
|
||||
|
||||
$(document).on("click", ".subtask-toggle-status", function(e) {
|
||||
e.preventDefault();
|
||||
var el = $(this);
|
||||
|
|
@ -15,6 +20,8 @@ Subtask.prototype.listen = function() {
|
|||
} else {
|
||||
el.replaceWith(data);
|
||||
}
|
||||
|
||||
self.dragAndDrop();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -28,7 +35,60 @@ Subtask.prototype.listen = function() {
|
|||
url: el.attr("href"),
|
||||
success: function(data) {
|
||||
$(".subtasks-table").replaceWith(data);
|
||||
self.dragAndDrop();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Subtask.prototype.dragAndDrop = function() {
|
||||
var self = this;
|
||||
|
||||
$(".draggable-row-handle").mouseenter(function() {
|
||||
$(this).parent().parent().addClass("draggable-item-hover");
|
||||
}).mouseleave(function() {
|
||||
$(this).parent().parent().removeClass("draggable-item-hover");
|
||||
});
|
||||
|
||||
$(".subtasks-table tbody").sortable({
|
||||
forcePlaceholderSize: true,
|
||||
handle: "td:first i",
|
||||
helper: function(e, ui) {
|
||||
ui.children().each(function() {
|
||||
$(this).width($(this).width());
|
||||
});
|
||||
|
||||
return ui;
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
var subtask = ui.item;
|
||||
subtask.removeClass("draggable-item-selected");
|
||||
self.savePosition(subtask.data("subtask-id"), subtask.index() + 1);
|
||||
},
|
||||
start: function(event, ui) {
|
||||
ui.item.addClass("draggable-item-selected");
|
||||
}
|
||||
}).disableSelection();
|
||||
};
|
||||
|
||||
Subtask.prototype.savePosition = function(subtaskId, position) {
|
||||
var url = $(".subtasks-table").data("save-position-url");
|
||||
var self = this;
|
||||
|
||||
this.app.showLoadingIcon();
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
url: url,
|
||||
contentType: "application/json",
|
||||
type: "POST",
|
||||
processData: false,
|
||||
data: JSON.stringify({
|
||||
"subtask_id": subtaskId,
|
||||
"position": position
|
||||
}),
|
||||
complete: function() {
|
||||
self.app.hideLoadingIcon();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
"eluceo/ical": "0.8.0",
|
||||
"erusev/parsedown" : "1.6.0",
|
||||
"fguillot/json-rpc" : "1.0.3",
|
||||
"fguillot/picodb" : "1.0.4",
|
||||
"fguillot/picodb" : "1.0.5",
|
||||
"fguillot/simpleLogger" : "1.0.0",
|
||||
"fguillot/simple-validator" : "1.0.0",
|
||||
"paragonie/random_compat": "@stable",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "99f199c3dac5c68390036cf0330ceb3a",
|
||||
"content-hash": "ce69cdbd50f2d27eca033e98ae7ff1e4",
|
||||
"hash": "0e754e4bc3eec85b3d14c748f1ed857a",
|
||||
"content-hash": "c7f7baadd60fdcf8fb9e2e3a7214357f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "christian-riesen/base32",
|
||||
|
|
@ -239,16 +239,16 @@
|
|||
},
|
||||
{
|
||||
"name": "fguillot/picodb",
|
||||
"version": "v1.0.4",
|
||||
"version": "v1.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fguillot/picoDb.git",
|
||||
"reference": "9ed4ee0c412dc9259d45bbc52e55c74150f7fb99"
|
||||
"reference": "3b388ef12f8c57f3bca85d278a53cf6fa2d832b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/9ed4ee0c412dc9259d45bbc52e55c74150f7fb99",
|
||||
"reference": "9ed4ee0c412dc9259d45bbc52e55c74150f7fb99",
|
||||
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/3b388ef12f8c57f3bca85d278a53cf6fa2d832b8",
|
||||
"reference": "3b388ef12f8c57f3bca85d278a53cf6fa2d832b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -272,7 +272,7 @@
|
|||
],
|
||||
"description": "Minimalist database query builder",
|
||||
"homepage": "https://github.com/fguillot/picoDb",
|
||||
"time": "2015-12-24 11:39:04"
|
||||
"time": "2016-02-20 02:56:11"
|
||||
},
|
||||
{
|
||||
"name": "fguillot/simple-validator",
|
||||
|
|
@ -397,16 +397,16 @@
|
|||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "1.1.6",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "e6f80ab77885151908d0ec743689ca700886e8b0"
|
||||
"reference": "b0e69d10852716b2ccbdff69c75c477637220790"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/e6f80ab77885151908d0ec743689ca700886e8b0",
|
||||
"reference": "e6f80ab77885151908d0ec743689ca700886e8b0",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/b0e69d10852716b2ccbdff69c75c477637220790",
|
||||
"reference": "b0e69d10852716b2ccbdff69c75c477637220790",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -441,7 +441,7 @@
|
|||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2016-01-29 16:19:52"
|
||||
"time": "2016-02-06 03:52:05"
|
||||
},
|
||||
{
|
||||
"name": "pimple/pimple",
|
||||
|
|
|
|||
|
|
@ -252,117 +252,6 @@ class SubtaskTest extends Base
|
|||
}
|
||||
}
|
||||
|
||||
public function testMoveUp()
|
||||
{
|
||||
$tc = new TaskCreation($this->container);
|
||||
$s = new Subtask($this->container);
|
||||
$p = new Project($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1)));
|
||||
$this->assertEquals(3, $s->create(array('title' => 'subtask #3', 'task_id' => 1)));
|
||||
|
||||
// Check positions
|
||||
$subtask = $s->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(2);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(2, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(3);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(3, $subtask['position']);
|
||||
|
||||
// Move up
|
||||
$this->assertTrue($s->moveUp(1, 2));
|
||||
|
||||
// Check positions
|
||||
$subtask = $s->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(2, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(2);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(3);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(3, $subtask['position']);
|
||||
|
||||
// We can't move up #2
|
||||
$this->assertFalse($s->moveUp(1, 2));
|
||||
|
||||
// Test remove
|
||||
$this->assertTrue($s->remove(1));
|
||||
$this->assertTrue($s->moveUp(1, 3));
|
||||
|
||||
// Check positions
|
||||
$subtask = $s->getById(1);
|
||||
$this->assertEmpty($subtask);
|
||||
|
||||
$subtask = $s->getById(2);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(2, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(3);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['position']);
|
||||
}
|
||||
|
||||
public function testMoveDown()
|
||||
{
|
||||
$tc = new TaskCreation($this->container);
|
||||
$s = new Subtask($this->container);
|
||||
$p = new Project($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1)));
|
||||
$this->assertEquals(3, $s->create(array('title' => 'subtask #3', 'task_id' => 1)));
|
||||
|
||||
// Move down #1
|
||||
$this->assertTrue($s->moveDown(1, 1));
|
||||
|
||||
// Check positions
|
||||
$subtask = $s->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(2, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(2);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(3);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(3, $subtask['position']);
|
||||
|
||||
// We can't move down #3
|
||||
$this->assertFalse($s->moveDown(1, 3));
|
||||
|
||||
// Test remove
|
||||
$this->assertTrue($s->remove(1));
|
||||
$this->assertTrue($s->moveDown(1, 2));
|
||||
|
||||
// Check positions
|
||||
$subtask = $s->getById(1);
|
||||
$this->assertEmpty($subtask);
|
||||
|
||||
$subtask = $s->getById(2);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(2, $subtask['position']);
|
||||
|
||||
$subtask = $s->getById(3);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['position']);
|
||||
}
|
||||
|
||||
public function testDuplicate()
|
||||
{
|
||||
$tc = new TaskCreation($this->container);
|
||||
|
|
@ -409,4 +298,69 @@ class SubtaskTest extends Base
|
|||
$this->assertEquals(1, $subtasks[0]['position']);
|
||||
$this->assertEquals(2, $subtasks[1]['position']);
|
||||
}
|
||||
|
||||
public function testChangePosition()
|
||||
{
|
||||
$taskCreationModel = new TaskCreation($this->container);
|
||||
$subtaskModel = new Subtask($this->container);
|
||||
$projectModel = new Project($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(2, $subtaskModel->create(array('title' => 'subtask #2', 'task_id' => 1)));
|
||||
$this->assertEquals(3, $subtaskModel->create(array('title' => 'subtask #3', 'task_id' => 1)));
|
||||
|
||||
$subtasks = $subtaskModel->getAll(1);
|
||||
$this->assertEquals(1, $subtasks[0]['position']);
|
||||
$this->assertEquals(1, $subtasks[0]['id']);
|
||||
$this->assertEquals(2, $subtasks[1]['position']);
|
||||
$this->assertEquals(2, $subtasks[1]['id']);
|
||||
$this->assertEquals(3, $subtasks[2]['position']);
|
||||
$this->assertEquals(3, $subtasks[2]['id']);
|
||||
|
||||
$this->assertTrue($subtaskModel->changePosition(1, 3, 2));
|
||||
|
||||
$subtasks = $subtaskModel->getAll(1);
|
||||
$this->assertEquals(1, $subtasks[0]['position']);
|
||||
$this->assertEquals(1, $subtasks[0]['id']);
|
||||
$this->assertEquals(2, $subtasks[1]['position']);
|
||||
$this->assertEquals(3, $subtasks[1]['id']);
|
||||
$this->assertEquals(3, $subtasks[2]['position']);
|
||||
$this->assertEquals(2, $subtasks[2]['id']);
|
||||
|
||||
$this->assertTrue($subtaskModel->changePosition(1, 2, 1));
|
||||
|
||||
$subtasks = $subtaskModel->getAll(1);
|
||||
$this->assertEquals(1, $subtasks[0]['position']);
|
||||
$this->assertEquals(2, $subtasks[0]['id']);
|
||||
$this->assertEquals(2, $subtasks[1]['position']);
|
||||
$this->assertEquals(1, $subtasks[1]['id']);
|
||||
$this->assertEquals(3, $subtasks[2]['position']);
|
||||
$this->assertEquals(3, $subtasks[2]['id']);
|
||||
|
||||
$this->assertTrue($subtaskModel->changePosition(1, 2, 2));
|
||||
|
||||
$subtasks = $subtaskModel->getAll(1);
|
||||
$this->assertEquals(1, $subtasks[0]['position']);
|
||||
$this->assertEquals(1, $subtasks[0]['id']);
|
||||
$this->assertEquals(2, $subtasks[1]['position']);
|
||||
$this->assertEquals(2, $subtasks[1]['id']);
|
||||
$this->assertEquals(3, $subtasks[2]['position']);
|
||||
$this->assertEquals(3, $subtasks[2]['id']);
|
||||
|
||||
$this->assertTrue($subtaskModel->changePosition(1, 1, 3));
|
||||
|
||||
$subtasks = $subtaskModel->getAll(1);
|
||||
$this->assertEquals(1, $subtasks[0]['position']);
|
||||
$this->assertEquals(2, $subtasks[0]['id']);
|
||||
$this->assertEquals(2, $subtasks[1]['position']);
|
||||
$this->assertEquals(3, $subtasks[1]['id']);
|
||||
$this->assertEquals(3, $subtasks[2]['position']);
|
||||
$this->assertEquals(1, $subtasks[2]['id']);
|
||||
|
||||
$this->assertFalse($subtaskModel->changePosition(1, 2, 0));
|
||||
$this->assertFalse($subtaskModel->changePosition(1, 2, 4));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue