Merge pull request #151 from nextcloud/sort-stacks
Add stack sorting functionality
This commit is contained in:
@@ -40,6 +40,7 @@ return [
|
||||
['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'],
|
||||
['name' => 'stack#create', 'url' => '/stacks', 'verb' => 'POST'],
|
||||
['name' => 'stack#update', 'url' => '/stacks/{stackId}', 'verb' => 'PUT'],
|
||||
['name' => 'stack#reorder', 'url' => '/stacks/{stackId}/reorder', 'verb' => 'PUT'],
|
||||
['name' => 'stack#delete', 'url' => '/stacks/{stackId}', 'verb' => 'DELETE'],
|
||||
['name' => 'stack#archived', 'url' => '/stacks/{boardId}/archived', 'verb' => 'GET'],
|
||||
|
||||
|
||||
@@ -398,6 +398,11 @@ button:hover {
|
||||
margin: 10px;
|
||||
border: 1px dashed #aaa;
|
||||
}
|
||||
#innerBoard > .as-sortable-placeholder {
|
||||
display: inline-block !important;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding-left: 5px;
|
||||
|
||||
@@ -68,7 +68,7 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
||||
|
||||
|
||||
$scope.stacksData = StackService;
|
||||
$scope.stacks = {};
|
||||
$scope.stacks = [];
|
||||
$scope.$watch('stacksData', function (value) {
|
||||
$scope.refreshData();
|
||||
}, true);
|
||||
@@ -87,7 +87,8 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
||||
$scope.filterData = function (order, text) {
|
||||
if ($scope.stacks === undefined)
|
||||
return;
|
||||
angular.copy(StackService.getAll(), $scope.stacks);
|
||||
angular.copy(StackService.getData(), $scope.stacks);
|
||||
$scope.stacks = $filter('orderBy')($scope.stacks, order);
|
||||
angular.forEach($scope.stacks, function (value, key) {
|
||||
var cards = $filter('cardSearchFilter')(value.cards, text);
|
||||
cards = $filter('orderBy')(cards, order);
|
||||
@@ -192,6 +193,7 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
||||
|
||||
// settings for card sorting
|
||||
$scope.sortOptions = {
|
||||
id: 'card',
|
||||
itemMoved: function (event) {
|
||||
event.source.itemScope.modelValue.status = event.dest.sortableScope.$parent.column;
|
||||
var order = event.dest.index;
|
||||
@@ -202,7 +204,7 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
||||
CardService.update(card);
|
||||
CardService.reorder(card, order).then(function (data) {
|
||||
StackService.addCard(card);
|
||||
StackService.reorder(card, order);
|
||||
StackService.reorderCard(card, order);
|
||||
StackService.removeCard({
|
||||
id: card.id,
|
||||
stackId: oldStack
|
||||
@@ -214,13 +216,14 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
||||
var card = event.source.itemScope.c;
|
||||
var stack = event.dest.sortableScope.$parent.s.id;
|
||||
CardService.reorder(card, order).then(function (data) {
|
||||
StackService.reorder(card, order);
|
||||
StackService.reorderCard(card, order);
|
||||
$scope.refreshData();
|
||||
});
|
||||
},
|
||||
scrollableContainer: '#board',
|
||||
containerPositioning: 'relative',
|
||||
containment: '#board',
|
||||
longTouch: true,
|
||||
// auto scroll on drag
|
||||
dragMove: function (itemPosition, containment, eventObj) {
|
||||
if (eventObj) {
|
||||
@@ -239,6 +242,44 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
|
||||
container.scrollTop(container.scrollTop() + 50);
|
||||
}
|
||||
}
|
||||
},
|
||||
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
|
||||
return sourceItemHandleScope.sortableScope.options.id === 'card';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.sortOptionsStack = {
|
||||
id: 'stack',
|
||||
orderChanged: function (event) {
|
||||
var order = event.dest.index;
|
||||
var stack = event.source.itemScope.s;
|
||||
StackService.reorder(stack, order).then(function (data) {
|
||||
$scope.refreshData();
|
||||
});
|
||||
},
|
||||
scrollableContainer: '#board',
|
||||
containerPositioning: 'relative',
|
||||
containment: '#board',
|
||||
dragMove: function (itemPosition, containment, eventObj) {
|
||||
if (eventObj) {
|
||||
var container = $("#board");
|
||||
var offset = container.offset();
|
||||
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
|
||||
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
|
||||
if (targetX < offset.left) {
|
||||
container.scrollLeft(container.scrollLeft() - 50);
|
||||
} else if (targetX > container.width()) {
|
||||
container.scrollLeft(container.scrollLeft() + 50);
|
||||
}
|
||||
if (targetY < offset.top) {
|
||||
container.scrollTop(container.scrollTop() - 50);
|
||||
} else if (targetY > container.height()) {
|
||||
container.scrollTop(container.scrollTop() + 50);
|
||||
}
|
||||
}
|
||||
},
|
||||
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
|
||||
return sourceItemHandleScope.sortableScope.options.id === 'stack';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -58,7 +58,22 @@ app.factory('StackService', function(ApiService, $http, $q){
|
||||
this.data[entity.stackId].cards.push(entity);
|
||||
};
|
||||
|
||||
StackService.prototype.reorder = function(entity, order) {
|
||||
StackService.prototype.reorder = function(stack, order) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + stack.id + '/reorder', {stackId: stack.id, order: order}).then(function (response) {
|
||||
angular.forEach(response.data, function (value, key) {
|
||||
var id = value.id;
|
||||
self.data[id].order = value.order;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.reorderCard = function(entity, order) {
|
||||
// assign new order
|
||||
for(var i=0, j=0;i<this.data[entity.stackId].cards.length;i++) {
|
||||
if(this.data[entity.stackId].cards[i].id === entity.id) {
|
||||
|
||||
@@ -80,6 +80,16 @@ class StackController extends Controller {
|
||||
return $this->stackService->update($id, $title, $boardId, $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param $stackId
|
||||
* @param $order
|
||||
* @return array
|
||||
*/
|
||||
public function reorder($stackId, $order) {
|
||||
return $this->stackService->reorder($stackId, $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param $stackId
|
||||
|
||||
@@ -102,4 +102,29 @@ class StackService {
|
||||
$stack->setOrder($order);
|
||||
return $this->stackMapper->update($stack);
|
||||
}
|
||||
|
||||
public function reorder($id, $order) {
|
||||
$this->permissionService->checkPermission($this->stackMapper, $id, Acl::PERMISSION_EDIT);
|
||||
$stackToSort = $this->stackMapper->find($id);
|
||||
$stacks = $this->stackMapper->findAll($stackToSort->getBoardId());
|
||||
$result = [];
|
||||
$i = 0;
|
||||
foreach ($stacks as $stack) {
|
||||
if ($stack->id === $id) {
|
||||
$stack->setOrder($order);
|
||||
}
|
||||
|
||||
if ($i === $order) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($stack->id !== $id) {
|
||||
$stack->setOrder($i++);
|
||||
}
|
||||
$this->stackMapper->update($stack);
|
||||
$result[$stack->getOrder()] = $stack;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -42,11 +42,11 @@
|
||||
|
||||
<search on-search="search" class="ng-hide"></search>
|
||||
|
||||
<div id="innerBoard" data-ng-model="stacks">
|
||||
<div class="stack" ng-repeat="s in stacks"
|
||||
<div id="innerBoard" data-ng-model="stacks" data-as-sortable="sortOptionsStack">
|
||||
<div class="stack" ng-repeat="s in stacks" data-as-sortable-item
|
||||
data-columnindex="{{$index}}" id="column{{$index}}"
|
||||
style="">
|
||||
<h2><span ng-show="!s.status.editStack">{{ s.title }}</span>
|
||||
<h2 data-as-sortable-item-handle><span ng-show="!s.status.editStack">{{ s.title }}</span>
|
||||
<form ng-if="s.status.editStack" ng-submit="stackservice.update(s)">
|
||||
<input type="text" placeholder="Add a new stack"
|
||||
ng-blur="stackservice.update(s); s.status.editStack=false" ng-model="s.title"
|
||||
|
||||
@@ -158,7 +158,34 @@ class StackServiceTest extends \PHPUnit_Framework_TestCase {
|
||||
$stack->setOrder(1);
|
||||
$result = $this->stackService->update(123, 'Foo', 2, 1);
|
||||
$this->assertEquals($stack, $result);
|
||||
|
||||
}
|
||||
|
||||
public function testReorder() {
|
||||
$this->permissionService->expects($this->once())->method('checkPermission');
|
||||
$a = $this->createStack(1, 0);
|
||||
$b = $this->createStack(2, 1);
|
||||
$c = $this->createStack(3, 2);
|
||||
$stacks = [$a, $b, $c];
|
||||
$this->stackMapper->expects($this->once())
|
||||
->method('find')
|
||||
->with(1)
|
||||
->willReturn($a);
|
||||
$this->stackMapper->expects($this->once())
|
||||
->method('findAll')
|
||||
->willReturn($stacks);
|
||||
$actual = $this->stackService->reorder(1, 2);
|
||||
$a = $this->createStack(1, 2);
|
||||
$b = $this->createStack(2, 0);
|
||||
$c = $this->createStack(3, 1);
|
||||
$expected = [$b, $c, $a];
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
private function createStack($id, $order) {
|
||||
$stack = new Stack();
|
||||
$stack->setId($id);
|
||||
$stack->setOrder($order);
|
||||
return $stack;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -84,6 +84,14 @@ class StackControllerTest extends \PHPUnit_Framework_TestCase {
|
||||
$this->assertEquals(1, $this->controller->update(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
public function testReorder() {
|
||||
$this->stackService->expects($this->once())
|
||||
->method('reorder')
|
||||
->with(1, 2)
|
||||
->willReturn(1);
|
||||
$this->assertEquals(1, $this->controller->reorder(1, 2));
|
||||
}
|
||||
|
||||
public function testDelete() {
|
||||
$this->stackService->expects($this->once())
|
||||
->method('delete')
|
||||
|
||||
Reference in New Issue
Block a user