diff --git a/app/coffee/modules/backlog/filters.coffee b/app/coffee/modules/backlog/filters.coffee index 685e2619..14b33bf0 100644 --- a/app/coffee/modules/backlog/filters.coffee +++ b/app/coffee/modules/backlog/filters.coffee @@ -97,6 +97,8 @@ BacklogFiltersDirective = ($q, $log, $location, $template, $compile) -> reloadUserstories = () -> currentFiltersType = getFiltersType() + $ctrl.resetBacklogPagination() + $q.all([$ctrl.loadUserstories(), $ctrl.generateFilters()]).then () -> currentFilters = $scope.filters[currentFiltersType] renderFilters(_.reject(currentFilters, "selected")) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index f56a0b9c..3031fc8f 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -62,6 +62,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @location, @appMetaService, @navUrls, @events, @analytics, @translate, @loading, @rs2) -> bindMethods(@) + @.page = 1 + @.disablePagination = false + @scope.userstories = [] + @scope.sectionName = @translate.instant("BACKLOG.SECTION_NAME") @showTags = false @activeFilters = false @@ -88,8 +92,13 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F # On Error promise.then null, @.onInitialDataError.bind(@) + resetBacklogPagination: -> + @.page = 1 + @scope.userstories = [] + initializeEventHandlers: -> @scope.$on "usform:bulk:success", => + @.resetBacklogPagination() @.loadUserstories() @.loadProjectStats() @analytics.trackEvent("userstory", "create", "bulk create userstory on backlog", 1) @@ -100,6 +109,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @analytics.trackEvent("sprint", "create", "create sprint on backlog", 1) @scope.$on "usform:new:success", => + @.resetBacklogPagination() @.loadUserstories() @.loadProjectStats() @@ -110,6 +120,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @.loadProjectStats() @scope.$on "sprintform:remove:success", (event, sprint) => + @.resetBacklogPagination() @.loadSprints() @.loadProjectStats() @.loadUserstories() @@ -119,8 +130,12 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @rootscope.$broadcast("filters:update") - @scope.$on "usform:edit:success", => - @.loadUserstories() + @scope.$on "usform:edit:success", (event, data) => + index = _.findIndex @scope.userstories, (us) -> + return us.id == data.id + + @scope.userstories[index] = data + @rootscope.$broadcast("filters:update") @scope.$on("sprint:us:move", @.moveUs) @@ -249,17 +264,30 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @.loadUserstories() loadUserstories: -> + @.loadingUserstories = true + @.disablePagination = true @scope.httpParams = @.getUrlFilters() @rs.userstories.storeQueryParams(@scope.projectId, @scope.httpParams) + @scope.httpParams.page = @.page + promise = @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams) - return promise.then (userstories) => + return promise.then (result) => + userstories = result[0] + header = result[1] + # NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files - @scope.userstories = _.sortBy(userstories, "backlog_order") + @scope.userstories = @scope.userstories.concat(_.sortBy(userstories, "backlog_order")) @.setSearchDataFilters() + @.loadingUserstories = false + + if header('x-pagination-next') + @.disablePagination = false + @.page++ + # The broadcast must be executed when the DOM has been fully reloaded. # We can't assure when this exactly happens so we need a defer scopeDefer @scope, => diff --git a/app/coffee/modules/resources/userstories.coffee b/app/coffee/modules/resources/userstories.coffee index ca40da1e..5e98ca72 100644 --- a/app/coffee/modules/resources/userstories.coffee +++ b/app/coffee/modules/resources/userstories.coffee @@ -51,7 +51,9 @@ resourceProvider = ($repo, $http, $urls, $storage) -> params = {"project": projectId, "milestone": "null"} params = _.extend({}, params, filters or {}) service.storeQueryParams(projectId, params) - return $repo.queryMany("userstories", params) + return $repo.queryMany("userstories", params, { + enablePagination: true + }, true) service.listAll = (projectId, filters) -> params = {"project": projectId} diff --git a/app/partials/includes/modules/backlog-table.jade b/app/partials/includes/modules/backlog-table.jade index d59048ee..63c7268c 100644 --- a/app/partials/includes/modules/backlog-table.jade +++ b/app/partials/includes/modules/backlog-table.jade @@ -8,5 +8,13 @@ div.backlog-table-header span.header-points(translate="COMMON.FIELDS.POINTS") tg-svg(svg-icon="icon-arrow-down") -div.backlog-table-body(tg-backlog-sortable, ng-class="{'show-tags': ctrl.showTags, 'active-filters': ctrl.activeFilters}" ) +div.backlog-table-body( + tg-backlog-sortable, + ng-class="{'show-tags': ctrl.showTags, 'active-filters': ctrl.activeFilters}" + infinite-scroll="ctrl.loadUserstories()" + infinite-scroll-disabled="ctrl.disablePagination" + infinite-scroll-immediate-check='false' +) include ../components/backlog-row + + div(tg-loading="ctrl.loadingUserstories") diff --git a/app/styles/modules/backlog/backlog-table.scss b/app/styles/modules/backlog/backlog-table.scss index b3425e3f..aa0146e9 100644 --- a/app/styles/modules/backlog/backlog-table.scss +++ b/app/styles/modules/backlog/backlog-table.scss @@ -286,6 +286,15 @@ display: inline-block; } } + .loading { + margin: 2% auto; + width: 3rem; + img { + @extend %loading-spinner; + max-height: 3rem; + max-width: 3rem; + } + } } .empty-backlog {