diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 1d4864e4..64dd2d8a 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -61,6 +61,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.$on("sprintform:remove:success", @.loadProjectStats) @scope.$on("usform:new:success", @.loadUserstories) @scope.$on("usform:edit:success", @.loadUserstories) + @scope.$on("sprint:us:move", @.moveUs) loadProjectStats: -> return @rs.projects.stats(@scope.projectId).then (stats) => @@ -73,6 +74,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F return @rs.sprints.list(@scope.projectId).then (sprints) => @scope.sprints = sprints @scope.sprintsCounter = sprints.length + @scope.sprintsById = groupBy(sprints, (x) -> x.id) return sprints loadUserstories: -> @@ -140,6 +142,125 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F res = _.find(selectedStatuses, (x) -> x == taiga.toString(us.status)) return not res + prepareBulkUpdateData: (uses) -> + return _.map(uses, (x) -> [x.id, x.order]) + + resortUserStories: (uses) -> + items = [] + for item, index in uses + item.order = index + if item.isModified() + items.push(item) + + return items + + moveUs: (ctx, us, newUsIndex, newSprintId) -> + oldSprintId = us.milestone + + # In the same sprint or in the backlog + if newSprintId == oldSprintId + items = null + userstories = null + + if newSprintId == null + userstories = @scope.userstories + else + userstories = @scope.sprintsById[newSprintId].user_stories + + @scope.$apply -> + r = userstories.indexOf(us) + userstories.splice(r, 1) + userstories.splice(newUsIndex, 0, us) + + # Rehash userstories order field + items = @.resortUserStories(userstories) + data = @.prepareBulkUpdateData(items) + + # Persist in bulk all affected + # userstories with order change + promise = @rs.userstories.bulkUpdateOrder(us.project, data) + promise.then null, -> + console.log "FAIL" + + return promise + + # From sprint to backlog + if newSprintId == null + us.milestone = null + + @scope.$apply => + # Add new us to backlog userstories list + @scope.userstories.splice(newUsIndex, 0, us) + @scope.visibleUserstories.splice(newUsIndex, 0, us) + + # Execute the prefiltering of user stories + @.filterVisibleUserstories() + + # Remove the us from the sprint list. + sprint = @scope.sprintsById[oldSprintId] + r = sprint.user_stories.indexOf(us) + sprint.user_stories.splice(r, 1) + + # Persist the milestone change of userstory + promise = @repo.save(us) + + # Rehash userstories order field + # and persist in bulk all changes. + promise = promise.then => + items = @.resortUserStories(@scope.userstories) + data = @.prepareBulkUpdateData(items) + return @rs.userstories.bulkUpdateOrder(us.project, data) + + promise.then null, -> + # TODO + console.log "FAIL" + + return promise + + # From backlog to sprint + newSprint = @scope.sprintsById[newSprintId] + if us.milestone == null + us.milestone = newSprintId + + @scope.$apply => + # Add moving us to sprint user stories list + newSprint.user_stories.splice(newUsIndex, 0, us) + + # Remove moving us from backlog userstories lists. + r = @scope.visibleUserstories.indexOf(us) + @scope.visibleUserstories.splice(r, 1) + r = @scope.userstories.indexOf(us) + @scope.userstories.splice(r, 1) + + # From sprint to sprint + else + us.milestone = newSprintId + + @scope.$apply => + # Add new us to backlog userstories list + newSprint.user_stories.splice(newUsIndex, 0, us) + + # Remove the us from the sprint list. + oldSprint = @scope.sprintsById[oldSprintId] + r = oldSprint.user_stories.indexOf(us) + oldSprint.user_stories.splice(r, 1) + + # Persist the milestone change of userstory + promise = @repo.save(us) + + # Rehash userstories order field + # and persist in bulk all changes. + promise = promise.then => + items = @.resortUserStories(newSprint.user_stories) + data = @.prepareBulkUpdateData(items) + return @rs.userstories.bulkUpdateOrder(us.project, data) + + promise.then null, -> + # TODO + console.log "FAIL" + + return promise + getUrlFilters: -> return _.pick(@location.search(), "statuses", "tags") @@ -169,7 +290,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.filters.statuses = _.map _.countBy(plainStatuses), (v, k) => obj = {id:k, type:"statuses", name: @scope.usStatusById[k].name, count:v} obj.selected = true if isSelected("statuses", obj.id) - console.log "statuses", obj return obj return @scope.filters diff --git a/app/coffee/modules/backlog/sortable.coffee b/app/coffee/modules/backlog/sortable.coffee index c32379fb..dcb5460c 100644 --- a/app/coffee/modules/backlog/sortable.coffee +++ b/app/coffee/modules/backlog/sortable.coffee @@ -42,17 +42,17 @@ BacklogSortableDirective = ($repo, $rs, $rootscope) -> # http://stackoverflow.com/questions/5791886/jquery-draggable-shows- # helper-in-wrong-place-when-scrolled-down-page - resort = (uses) -> - items = [] - for item, index in uses - item.order = index - if item.isModified() - items.push(item) + # resort = (uses) -> + # items = [] + # for item, index in uses + # item.order = index + # if item.isModified() + # items.push(item) + # + # return items - return items - - prepareBulkUpdateData = (uses) -> - return _.map(uses, (x) -> [x.id, x.order]) + # prepareBulkUpdateData = (uses) -> + # return _.map(uses, (x) -> [x.id, x.order]) linkSortable = ($scope, $el, $attrs, $ctrl) -> # State @@ -61,6 +61,13 @@ BacklogSortableDirective = ($repo, $rs, $rootscope) -> itemEl = null tdom = $el + deleteElement = (itemEl) -> + # Completelly remove item and its scope from dom + itemEl.scope().$destroy() + itemEl.off() + itemEl.remove() + + tdom.sortable({ # handle: ".icon-drag-v", items: "div.sprint-table > div.row, .backlog-table-body > div.row" @@ -68,6 +75,7 @@ BacklogSortableDirective = ($repo, $rs, $rootscope) -> tdom.on "sortstop", (event, ui) -> # Common state for stop event handler + parentEl = ui.item.parent() itemEl = ui.item itemUs = itemEl.scope().us @@ -75,131 +83,19 @@ BacklogSortableDirective = ($repo, $rs, $rootscope) -> newParentScope = parentEl.scope() if itemEl.is(".milestone-us-item-row") and parentEl.is(".backlog-table-body") - itemUs.milestone = null - - # Completelly remove item and its scope from dom - itemEl.scope().$destroy() - itemEl.off() - itemEl.remove() - - $scope.$apply -> - # Add new us to backlog userstories list - newParentScope.userstories.splice(itemIndex, 0, itemUs) - newParentScope.visibleUserstories.splice(itemIndex, 0, itemUs) - - # Execute the prefiltering of user stories - $ctrl.filterVisibleUserstories() - - # Remove the us from the sprint list. - r = oldParentScope.sprint.user_stories.indexOf(itemUs) - oldParentScope.sprint.user_stories.splice(r, 1) - - # Persist the milestone change of userstory - promise = $repo.save(itemUs) - - # Rehash userstories order field - # and persist in bulk all changes. - promise = promise.then -> - projectId = $scope.projectId - - items = resort(newParentScope.userstories) - data = prepareBulkUpdateData(items) - - return $rs.userstories.bulkUpdateOrder(projectId, data) - - promise.then null, -> - # TODO - console.log "FAIL" + deleteElement(itemEl) + $scope.$broadcast("sprint:us:move", itemUs, itemIndex, null) else if itemEl.is(".us-item-row") and parentEl.is(".sprint-table") - - # Completelly remove item and its scope from dom - itemEl.scope().$destroy() - itemEl.off() - itemEl.remove() - - itemUs.milestone = newParentScope.sprint.id - - $scope.$apply -> - # Add moving us to sprint user stories list - newParentScope.sprint.user_stories.splice(itemIndex, 0, itemUs) - - # Remove moving us from backlog userstories lists. - r = oldParentScope.visibleUserstories.indexOf(itemUs) - oldParentScope.visibleUserstories.splice(r, 1) - r = oldParentScope.userstories.indexOf(itemUs) - oldParentScope.userstories.splice(r, 1) - - # Persist the milestone change of userstory - promise = $repo.save(itemUs) - - # Rehash userstories order field - # and persist in bulk all changes. - promise = promise.then -> - projectId = $scope.projectId - items = resort(newParentScope.sprint.user_stories) - data = prepareBulkUpdateData(items) - return $rs.userstories.bulkUpdateOrder(projectId, data) - - # TODO: handle properly the error - promise.then null, -> - console.log "FAIL" + deleteElement(itemEl) + $scope.$broadcast("sprint:us:move", itemUs, itemIndex, newParentScope.sprint.id) else if parentEl.is(".sprint-table") and newParentScope.sprint.id != oldParentScope.sprint.id - itemUs.milestone = newParentScope.sprint.id - - # Completelly remove item and its scope from dom - itemEl.scope().$destroy() - itemEl.off() - itemEl.remove() - - $scope.$apply -> - # Add new us to backlog userstories list - newParentScope.sprint.user_stories.splice(itemIndex, 0, itemUs) - - # Remove the us from the sprint list. - r = oldParentScope.sprint.user_stories.indexOf(itemUs) - oldParentScope.sprint.user_stories.splice(r, 1) - - # Persist the milestone change of userstory - promise = $repo.save(itemUs) - - # Rehash userstories order field - # and persist in bulk all changes. - promise = promise.then -> - projectId = $scope.projectId - - items = resort(newParentScope.sprint.user_stories) - data = prepareBulkUpdateData(items) - return $rs.userstories.bulkUpdateOrder(projectId, data) - - promise.then null, -> - # TODO - console.log "FAIL" + deleteElement(itemEl) + $scope.$broadcast("sprint:us:move", itemUs, itemIndex, newParentScope.sprint.id) else - items = null - userstories = null - - if parentEl.is(".backlog-table-body") - userstories = newParentScope.userstories - else - userstories = newParentScope.sprint.user_stories - - $scope.$apply -> - r = userstories.indexOf(itemUs) - userstories.splice(r, 1) - userstories.splice(itemIndex, 0, itemUs) - - # Rehash userstories order field - items = resort(userstories) - data = prepareBulkUpdateData(items) - - # Persist in bulk all affected - # userstories with order change - promise = $rs.userstories.bulkUpdateOrder($scope.projectId, data) - promise.then null, -> - console.log "FAIL" + $scope.$broadcast("sprint:us:move", itemUs, itemIndex, itemUs.milestone) tdom.on "sortstart", (event, ui) -> oldParentScope = ui.item.parent().scope()