diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 3c413fb9..529c5b27 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -59,6 +59,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.sectionName = "Backlog" @showTags = false @activeFilters = false + @excludeClosedSprints = true @.initializeEventHandlers() @@ -109,6 +110,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.$on("sprint:us:moved", @.loadSprints) @scope.$on("sprint:us:moved", @.loadProjectStats) + @scope.$on("backlog:toggle-closed-sprints-visualization", @.toggleClosedSprintsVisualization) + initializeSubscription: -> routingKey1 = "changes.project.#{@scope.projectId}.userstories" @events.subscribe @scope, routingKey1, (message) => @@ -143,12 +146,18 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.project.tags_colors = tags_colors loadSprints: -> - return @rs.sprints.list(@scope.projectId).then (sprints) => + params = {} + if @excludeClosedSprints + params["closed"] = false + + return @rs.sprints.list(@scope.projectId, params).then (sprints) => # NOTE: Fix order of USs because the filter orderBy does not work propertly in partials files for sprint in sprints sprint.user_stories = _.sortBy(sprint.user_stories, "sprint_order") @scope.sprints = sprints + @scope.openSprints = _.filter(sprints, (sprint) => not sprint.closed) + @scope.closedSprints = _.filter(sprints, (sprint) => sprint.closed) @scope.sprintsCounter = sprints.length @scope.sprintsById = groupBy(sprints, (x) -> x.id) @rootscope.$broadcast("sprints:loaded", sprints) @@ -218,6 +227,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F return promise.then(=> @.loadBacklog()) + toggleClosedSprintsVisualization: -> + @excludeClosedSprints = not @excludeClosedSprints + @.loadSprints() + filterVisibleUserstories: -> @scope.visibleUserstories = [] diff --git a/app/coffee/modules/backlog/sprints.coffee b/app/coffee/modules/backlog/sprints.coffee index cba3840f..acc40593 100644 --- a/app/coffee/modules/backlog/sprints.coffee +++ b/app/coffee/modules/backlog/sprints.coffee @@ -158,3 +158,33 @@ BacklogSprintHeaderDirective = ($navUrls) -> } module.directive("tgBacklogSprintHeader", ["$tgNavUrls", "$tgRepo", "$rootScope", BacklogSprintHeaderDirective]) + +############################################################################# +## Toggle Closed Sprints Directive +############################################################################# + +ToggleExcludeClosedSprintsVisualization = ($rootscope, $loading) -> + excludeClosedSprints = false + + link = ($scope, $el, $attrs) -> + # Event Handlers + $el.on "click", "", (event) -> + $loading.start($el.siblings('.load')) + $rootscope.$broadcast("backlog:toggle-closed-sprints-visualization") + + $scope.$on "$destroy", -> + $el.off() + + $scope.$on "sprints:loaded", (ctx, sprints) => + closedSprints = _.filter(sprints, (sprint) -> sprint.closed) + $loading.finish($el.siblings('.load')) + + #TODO: i18n + if closedSprints.length > 0 + $el.text("Hide closed sprints") + else + $el.text("Show closed sprints") + + return {link: link} + +module.directive("tgBacklogToggleClosedSprintsVisualization", ["$rootScope", "$tgLoading", ToggleExcludeClosedSprintsVisualization]) diff --git a/app/coffee/modules/resources/sprints.coffee b/app/coffee/modules/resources/sprints.coffee index 8ddc9855..517ee15f 100644 --- a/app/coffee/modules/resources/sprints.coffee +++ b/app/coffee/modules/resources/sprints.coffee @@ -38,8 +38,9 @@ resourceProvider = ($repo, $model, $storage) -> service.stats = (projectId, sprintId) -> return $repo.queryOneRaw("milestones", "#{sprintId}/stats") - service.list = (projectId) -> + service.list = (projectId, filters) -> params = {"project": projectId} + params = _.extend({}, params, filters or {}) return $repo.queryMany("milestones", params).then (milestones) => for m in milestones uses = m.user_stories diff --git a/app/partials/views/modules/sprint.jade b/app/partials/views/modules/sprint.jade new file mode 100644 index 00000000..95979f31 --- /dev/null +++ b/app/partials/views/modules/sprint.jade @@ -0,0 +1,19 @@ +header(tg-backlog-sprint-header, ng-model="sprint") + +div.sprint-progress-bar(tg-progress-bar="100 * sprint.closed_points / sprint.total_points") + +div.sprint-table(tg-sprint-sortable) + div.row.milestone-us-item-row(ng-repeat="us in sprint.user_stories track by us.id") + div.column-us + a.us-name.clickable(tg-nav="project-userstories-detail:project=project.slug,ref=us.ref", + tg-bo-title="'#' + us.ref + ' ' + us.subject", + ng-class="{closed: us.is_closed, blocked: us.is_blocked}") + span(tg-bo-ref="us.ref") + span(tg-bo-bind="us.subject") + div.column-points.width-1(tg-bo-bind="us.total_points", ng-class="{closed: us.is_closed, blocked: us.is_blocked}") + +a.button.button-gray(tg-bo-title="'Go to Taskboard of ' + sprint.name", + tg-nav="project-taskboard:project=project.slug,sprint=sprint.slug", + tg-check-permission="view_milestones") + + span Sprint Taskboard diff --git a/app/partials/views/modules/sprints.jade b/app/partials/views/modules/sprints.jade index c4700108..1b0493f1 100644 --- a/app/partials/views/modules/sprints.jade +++ b/app/partials/views/modules/sprints.jade @@ -4,7 +4,7 @@ section.sprints div.summary ul li - span.number(ng-bind="sprintsCounter") -- + span.number(ng-bind="project.total_milestones") -- span.description
sprints div.new-sprint a.button.button-green(href="", title="Add New sprint", @@ -12,23 +12,13 @@ section.sprints tg-check-permission="add_milestone") span.text + New sprint - section.sprint(ng-repeat="sprint in sprints track by sprint.id" tg-backlog-sprint="sprint") - header(tg-backlog-sprint-header, ng-model="sprint") + div.sprint.sprint-open(ng-repeat="sprint in openSprints track by sprint.id" tg-backlog-sprint="sprint") + include sprint - div.sprint-progress-bar(tg-progress-bar="100 * sprint.closed_points / sprint.total_points") + a.filter-closed-sprints(href="", ng-show="project.total_closed_milestones") + span.icon.icon-archive + span(tg-backlog-toggle-closed-sprints-visualization="ctrl.excludeClosedSprints") Show closed sprints + span.load - div.sprint-table(tg-sprint-sortable) - div.row.milestone-us-item-row(ng-repeat="us in sprint.user_stories track by us.id") - div.column-us - a.us-name.clickable(tg-nav="project-userstories-detail:project=project.slug,ref=us.ref", - tg-bo-title="'#' + us.ref + ' ' + us.subject", - ng-class="{closed: us.is_closed, blocked: us.is_blocked}") - span(tg-bo-ref="us.ref") - span(tg-bo-bind="us.subject") - div.column-points.width-1(tg-bo-bind="us.total_points", ng-class="{closed: us.is_closed, blocked: us.is_blocked}") - - a.button.button-gray(tg-bo-title="'Go to Taskboard of ' + sprint.name", - tg-nav="project-taskboard:project=project.slug,sprint=sprint.slug", - tg-check-permission="view_milestones") - - span Sprint Taskboard + div.sprint.sprint-closed(ng-repeat="sprint in closedSprints track by sprint.id" tg-backlog-sprint="sprint") + include sprint diff --git a/app/styles/modules/backlog/sprints.scss b/app/styles/modules/backlog/sprints.scss index bb36518d..e56b4e64 100644 --- a/app/styles/modules/backlog/sprints.scss +++ b/app/styles/modules/backlog/sprints.scss @@ -15,6 +15,21 @@ padding: .5rem 1.5rem; } } + .filter-closed-sprints { + @extend %small; + display: block; + padding-bottom: 1rem; + text-align: center; + .icon-kanban { + margin-right: .3rem; + vertical-align: middle; + } + .load { + display: inline-block; + margin-left: .3rem; + vertical-align: middle; + } + } .sprint-name { a { @extend %large;