diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee
index c5cb1eec..e5c580c9 100644
--- a/app/coffee/modules/backlog/main.coffee
+++ b/app/coffee/modules/backlog/main.coffee
@@ -63,6 +63,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin)
return @rs.projects.get(@scope.projectId).then (project) =>
@scope.project = project
@scope.points = _.sortBy(project.points, "order")
+ @scope.pointsById = {}
+ for p in @scope.points
+ @scope.pointsById[p.id] = p
+
@scope.statusList = _.sortBy(project.us_statuses, "id")
return project
@@ -192,6 +196,7 @@ BacklogDirective = ($repo) ->
##############################
## Move to current sprint link
##############################
+
linkMoveToCurrentSprint = ($scope, $el, $attrs, $ctrl) ->
moveToCurrentSprint = (selectedUss) ->
@@ -367,14 +372,159 @@ BacklogSprintDirective = ($repo) ->
return {link: link}
-BacklogSummaryDirective = ->
+#############################################################################
+## User story points directive
+#############################################################################
+
+UsRolePointsSelectorDirective = ($rootscope) ->
+ #TODO: i18n
+ selectionTemplate = _.template("""
+
+ """)
link = ($scope, $el, $attrs) ->
- return {link:link}
+ taiga.bindOnce $scope, "project", (project) ->
+ roles = _.filter(project.roles, "computable")
+ $el.append(selectionTemplate({ 'roles': roles }))
+
+ $scope.$on "uspoints:select", (ctx, roleId, roleName) ->
+ $el.find(".popover").hide()
+ $el.find("span").text(roleName)
+
+ $scope.$on "uspoints:clear-selection", (ctx, roleId) ->
+ $el.find(".popover").hide()
+ $el.find("span").text("Points") #TODO: i18n
+
+ $el.on "click", (event) ->
+ target = angular.element(event.target)
+
+ if target.is("span") or target.is("div")
+ event.stopPropagation()
+
+ $el.find(".popover").show()
+ body = angular.element("body")
+ body.one "click", (event) ->
+ $el.find(".popover").hide()
+
+ $el.on "click", ".clear-selection", (event) ->
+ event.preventDefault()
+ event.stopPropagation()
+ $rootscope.$broadcast("uspoints:clear-selection")
+
+ $el.on "click", ".role", (event) ->
+ event.preventDefault()
+ event.stopPropagation()
+ target = angular.element(event.currentTarget)
+ rolScope = target.scope()
+ $rootscope.$broadcast("uspoints:select", target.data("role-id"), target.text())
+
+ $scope.$on "$destroy", ->
+ $el.off()
+
+ return {link: link}
+
+UsPointsDirective = ($repo) ->
+ selectionTemplate = _.template("""
+
+ """)
+ pointsTemplate = _.template("""
+
+ """)
+
+ updatePointsValue = (us, pointsById, pointsDomNode, selectedRoleId) ->
+ if not selectedRoleId?
+ pointsDomNode.text(us.total_points)
+ else
+ selectedPoints = pointsById[us.points[selectedRoleId]]
+ selectedPointsValue = selectedPoints.value
+ selectedPointsValue = '?' if not selectedPointsValue?
+ pointsDomNode.text("#{selectedPointsValue}/#{us.total_points}")
+
+ link = ($scope, $el, $attrs) ->
+ $ctrl = $el.controller()
+ us = $scope.$eval($attrs.tgUsPoints)
+ usPoints = us.points
+ pointsDom = $el.find("a")
+ selectedRoleId = null
+ updatingSelectedRoleId = null
+ pointsById = $scope.pointsById
+ updatePointsValue(us, pointsById, pointsDom, selectedRoleId)
+
+ taiga.bindOnce $scope, "project", (project) ->
+ roles = _.filter(project.roles, "computable")
+ $el.append(selectionTemplate({ 'roles': roles }))
+ $el.append(pointsTemplate({ 'points': project.points }))
+
+ $scope.$on "uspoints:select", (ctx, roleId,roleName) ->
+ selectedRoleId = roleId
+ updatePointsValue(us, pointsById, pointsDom, selectedRoleId)
+
+ $scope.$on "uspoints:clear-selection", (ctx) ->
+ selectedRoleId = null
+ updatePointsValue(us, pointsById, pointsDom, selectedRoleId)
+
+ $el.on "click", "a.us-points", (event) ->
+ event.preventDefault()
+ target = angular.element(event.target)
+
+ if target.is("a")
+ event.stopPropagation()
+
+ if selectedRoleId?
+ updatingSelectedRoleId = selectedRoleId
+ $el.find(".pop-points-open").show()
+ else
+ $el.find(".pop-role").show()
+
+ body = angular.element("body")
+ body.one "click", (event) ->
+ $el.find(".popover").hide()
+
+ $el.on "click", ".role", (event) ->
+ event.preventDefault()
+ event.stopPropagation()
+ target = angular.element(event.currentTarget)
+ updatingSelectedRoleId = target.data("role-id")
+ $el.find(".pop-points-open").show()
+ $el.find(".pop-role").hide()
+
+ $el.on "click", ".point", (event) ->
+ event.preventDefault()
+ event.stopPropagation()
+ target = angular.element(event.currentTarget)
+ $el.find(".pop-points-open").hide()
+ $scope.$apply () ->
+ usPoints[updatingSelectedRoleId] = target.data("point-id")
+ us.points = _.clone(usPoints, false)
+ total = _.reduce(_.map(us.points, (value, key) -> $scope.pointsById[value].value), (memo, num) -> memo + num)
+ us.total_points = total
+ updatePointsValue(us, pointsById, pointsDom, selectedRoleId)
+ $repo.save(us).then ->
+ $ctrl.loadProjectStats()
+
+ $scope.$on "$destroy", ->
+ $el.off()
+
+ return {link: link}
+
module = angular.module("taigaBacklog")
module.directive("tgBacklog", ["$tgRepo", BacklogDirective])
module.directive("tgBacklogSprint", ["$tgRepo", BacklogSprintDirective])
-module.directive("tgBacklogSummary", BacklogSummaryDirective)
+module.directive("tgUsPoints", ["$tgRepo", UsPointsDirective])
+module.directive("tgUsRolePointsSelector", ["$rootScope", UsRolePointsSelectorDirective])
module.controller("BacklogController", [
"$scope",
diff --git a/app/partials/views/components/backlog-row.jade b/app/partials/views/components/backlog-row.jade
index be693ba7..50d8e6e2 100644
--- a/app/partials/views/components/backlog-row.jade
+++ b/app/partials/views/components/backlog-row.jade
@@ -8,7 +8,18 @@ div.row.us-item-row(ng-repeat="us in visibleUserstories track by us.id")
a.icon.icon-delete(href="", ng-click="ctrl.deleteUserStory(us)", title="Delete")
div.user-story-tags
span.tag(ng-repeat="tag in us.tags") {{ tag }}
- div.status Status
- div.points 12
- div.points 54
+
+ div.status.width-2
+ a(href="", title="Status Name") Status Name
+ ul.popover.pop-status
+ li
+ a(href="", title="Status 1") Status 1
+ li
+ a(href="", title="Status 2") Status 2
+ li
+ a(href="", title="Status 3") Status 3
+
+ div.points(tg-us-points="us")
+ a.us-points(href="", title="Points") 0
+
a.icon.icon-drag-v(href="", title="Drag")
diff --git a/app/partials/views/components/summary.jade b/app/partials/views/components/summary.jade
index 178d84f1..7283a2f0 100644
--- a/app/partials/views/components/summary.jade
+++ b/app/partials/views/components/summary.jade
@@ -1,4 +1,4 @@
-div.summary(tg-backlog-summary)
+div.summary
div.summary-progress-bar
div.current-progress
div.data
diff --git a/app/partials/views/modules/backlog-table.jade b/app/partials/views/modules/backlog-table.jade
index b0dde643..ac290bd8 100644
--- a/app/partials/views/modules/backlog-table.jade
+++ b/app/partials/views/modules/backlog-table.jade
@@ -2,13 +2,8 @@ section.backlog-table-header
div.row.backlog-table-title
div.user-stories User Stories
div.status Status
- div.points Points
- div.points
- div.row.backlog-table-subtitle
- div.user-stories.width-4
- div.status.width-2
- div.points.width-1 Front
- div.points.width-1 Total
+ div.points(tg-us-role-points-selector)
+ span Points
section.backlog-table-body
include ../components/backlog-row
diff --git a/app/styles/modules/backlog-table.scss b/app/styles/modules/backlog-table.scss
index 510b7f6c..ef4597c8 100644
--- a/app/styles/modules/backlog-table.scss
+++ b/app/styles/modules/backlog-table.scss
@@ -32,6 +32,9 @@
.points {
position: relative;
}
+ .pop-role {
+ @include popover(150px, '', 30px, 10px, '');
+ }
.pop-status {
@include popover(150px, '', 30px, 10px, '');
}