diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee
index 2629df74..5ead6633 100644
--- a/app/coffee/modules/userstories/detail.coffee
+++ b/app/coffee/modules/userstories/detail.coffee
@@ -23,6 +23,7 @@ taiga = @.taiga
mixOf = @.taiga.mixOf
groupBy = @.taiga.groupBy
+bindOnce = @.taiga.bindOnce
module = angular.module("taigaUserStories")
@@ -53,7 +54,7 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
loadProject: ->
return @rs.projects.get(@scope.projectId).then (project) =>
@scope.project = project
- @scope.statusList = project.issue_statuses
+ @scope.statusList = project.us_statuses
@scope.statusById = groupBy(project.us_statuses, (x) -> x.id)
@scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id)
@scope.membersById = groupBy(project.memberships, (x) -> x.user)
@@ -69,13 +70,8 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.nextUrl = "/project/#{@scope.project.slug}/us/#{@scope.us.neighbors.next.ref}" if @scope.us.neighbors.next.id?
loadTasks: ->
- # http://localhost:8000/api/v1/tasks?user_story=6
return @rs.tasks.list(@scope.projectId, null, @scope.usId).then (tasks) =>
@scope.tasks = tasks
- @scope.totalTasks = tasks.length
- closedTasks = _.filter(tasks, (task) => @scope.taskStatusById[task.status].is_closed)
- @scope.totalClosedTasks = closedTasks.length
- @scope.usProgress = 100 * @scope.totalClosedTasks / @scope.totalTasks
loadHistory: ->
return @rs.userstories.history(@scope.usId).then (history) =>
@@ -128,6 +124,22 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
return "Made #{size} changes"
+ block: ->
+ @rootscope.$broadcast("block", @scope.us)
+
+ unblock: ->
+ @rootscope.$broadcast("unblock", @scope.us)
+
+
+ delete: ->
+ #TODO: i18n
+ title = "Delete User Story"
+ subtitle = @scope.us.subject
+
+ @confirm.ask(title, subtitle).then =>
+ @.repo.remove(@scope.us).then =>
+ @location.path("/project/#{@scope.project.slug}/backlog")
+
module.controller("UserStoryDetailController", UserStoryDetailController)
@@ -176,8 +188,28 @@ UsStatusDetailDirective = () ->
<% } else { %>
Open
<% } %>
-
@@ -187,29 +219,69 @@ UsStatusDetailDirective = () ->
""")
selectionStatusTemplate = _.template("""
-
+
+ """)
+ selectionPointsTemplate = _.template("""
+
""")
link = ($scope, $el, $attrs, $model) ->
editable = $attrs.editable?
+ updatingSelectedRoleId = null
+
+ showSelectPoints = () ->
+ us = $model.$modelValue
+ $el.find(".pop-points-open").remove()
+ $el.find(".points-per-role").append(selectionPointsTemplate({ "points": $scope.project.points }))
+ $el.find(".pop-points-open a[data-point-id='#{us.points[updatingSelectedRoleId]}']").addClass("active")
+ # If not showing role selection let's move to the left
+ $el.find(".pop-points-open").show()
+
+ calculateTotalPoints = (us)->
+ values = _.map(us.points, (v, k) -> $scope.pointsById[v].value)
+ values = _.filter(values, (num) -> num?)
+ if values.length == 0
+ return "?"
+
+ return _.reduce(values, (acc, num) -> acc + num)
renderUsstatus = (us) ->
status = $scope.statusById[us.status]
+ rolePoints = _.clone(_.filter($scope.project.roles, "computable"), true)
+ _.map rolePoints, (v, k) ->
+ val = $scope.pointsById[us.points[v.id]].value
+ val = "?" if not val?
+ v.points = val
+
+ totalTasks = $scope.tasks.length
+ totalClosedTasks = _.filter($scope.tasks, (task) => $scope.taskStatusById[task.status].is_closed).length
html = template({
editable: editable
status: status
+ totalPoints: us.total_points
+ rolePoints: rolePoints
+ totalTasks: totalTasks
+ totalClosedTasks: totalClosedTasks
+ usProgress: 100 * totalClosedTasks / totalTasks
})
$el.html(html)
$el.find(".status-data").append(selectionStatusTemplate({statuses:$scope.statusList}))
- $scope.$watch $attrs.ngModel, (us) ->
- if us?
- renderUsstatus(us)
+ bindOnce $scope, "tasks", (tasks) ->
+ $scope.$watch $attrs.ngModel, (us) ->
+ if us?
+ renderUsstatus(us)
if editable
$el.on "click", ".status-data", (event) ->
@@ -228,66 +300,31 @@ UsStatusDetailDirective = () ->
renderUsstatus($model.$modelValue)
$el.find(".popover").hide()
+ $el.on "click", ".total.clickable", (event) ->
+ event.preventDefault()
+ event.stopPropagation()
+ target = angular.element(event.currentTarget)
+ updatingSelectedRoleId = target.data("role-id")
+ showSelectPoints()
+ body = angular.element("body")
+ body.one "click", (event) ->
+ $el.find(".popover").hide()
+
+ $el.on "click", ".point", (event) ->
+ event.preventDefault()
+ event.stopPropagation()
+
+ target = angular.element(event.currentTarget)
+ $el.find(".popover").hide()
+
+ $scope.$apply () ->
+ us = $model.$modelValue
+ usPoints = _.clone(us.points, true)
+ usPoints[updatingSelectedRoleId] = target.data("point-id")
+ us.points = usPoints
+ us.total_points = calculateTotalPoints(us)
+ renderUsstatus(us)
+
return {link:link, require:"ngModel"}
module.directive("tgUsStatusDetail", UsStatusDetailDirective)
-
-
-
-
-
-
-
-
-
-
-
-
-#############################################################################
-## User story points detail directive
-#############################################################################
-
-USPointsDetailDirective = () ->
- #TODO: i18n
- template = _.template("""
-
- -
- <%- totalPoints %>
- total
-
- <% _.each(rolePoints, function(rolePoint) { %>
- -
- <%- rolePoint.points %>
- <%- rolePoint.name %>
- <% }); %>
-
- """)
-
- link = ($scope, $el, $attrs, $model) ->
- editable = $attrs.editable?
-
- renderUsPointsDetail = (us) ->
-
- rolePoints = _.clone(_.filter($scope.project.roles, "computable"), true)
- _.map rolePoints, (v, k) ->
- val = $scope.pointsById[us.points[v.id]].value
- val = "?" if not val?
- v.points = val
-
- html = template({
- editable: editable
- totalPoints: us.total_points
- rolePoints: rolePoints
- })
- $el.html(html)
-
- $scope.$watch $attrs.ngModel, (us) ->
- if us?
- renderUsPointsDetail(us)
-
- if editable
- console.log "TODO"
-
- return {link:link, require:"ngModel"}
-
-module.directive("tgUsPointsDetail", USPointsDetailDirective)
diff --git a/app/partials/issues-detail-edit.jade b/app/partials/issues-detail-edit.jade
index 7cdb6484..13612d5b 100644
--- a/app/partials/issues-detail-edit.jade
+++ b/app/partials/issues-detail-edit.jade
@@ -24,7 +24,6 @@ block content
div.user-story-tags(tg-tag-line, editable="true", ng-model="issue.tags")
section.us-content
- // TODO Placeholder should be a WYSIWYG with issue.description
textarea(placeholder="Write a description of your issue", ng-model="issue.description", tg-markitup)
// include views/modules/attachments
@@ -36,14 +35,6 @@ block content
section.watchers(tg-watchers, ng-model="issue.watchers", editable="true")
section.us-detail-settings
- //TODO: remove commented from issues-detail when copied to user-story-detail
- //fieldset
- // label.clickable.button.button-green(for="client-requirement", ng-class="{true:'active', false:''}[issue.client_requirement]") Client requirement
- // input(ng-model="issue.client_requirement", type="checkbox", id="client-requirement", name="client-requirement")
- //fieldset
- // label.clickable.button.button-green(for="team-requirement", ng-class="{true:'active', false:''}[issue.team_requirement]") Team requirement
- // input(ng-model="issue.team_requirement", type="checkbox", id="team-requirement", name="team-requirement")
-
a.button.button-gray.clickable(ng-show="!issue.is_blocked", ng-click="ctrl.block()") Block
a.button.button-red(ng-click="ctrl.delete()", href="") Delete
diff --git a/app/partials/us-detail.jade b/app/partials/us-detail.jade
index a15197f3..e6db0aad 100644
--- a/app/partials/us-detail.jade
+++ b/app/partials/us-detail.jade
@@ -46,12 +46,6 @@ block content
sidebar.menu-secondary.sidebar
section.us-status(tg-us-status-detail, ng-model="us")
-
- div.us-detail-progress-bar
- div.current-progress(style="width:{{ usProgress }}%")
- span.tasks-completed {{ totalClosedTasks }}/{{ totalTasks}} tasks completed
- ul.points-per-role(tg-us-points-detail, ng-model="us")
-
section.us-assigned-to(tg-assigned-to, ng-model="us")
section.watchers(tg-watchers, ng-model="us.watchers")
diff --git a/app/styles/components/buttons.scss b/app/styles/components/buttons.scss
index ded99d77..dfa694ea 100755
--- a/app/styles/components/buttons.scss
+++ b/app/styles/components/buttons.scss
@@ -32,7 +32,8 @@
.button-green {
background: $green-taiga;
vertical-align: middle;
- &:hover {
+ &:hover,
+ &.active {
background: $fresh-taiga;
}
span {
diff --git a/app/styles/layout/us-detail.scss b/app/styles/layout/us-detail.scss
index 5fa9f463..618e7b8d 100644
--- a/app/styles/layout/us-detail.scss
+++ b/app/styles/layout/us-detail.scss
@@ -166,6 +166,7 @@
}
.points-per-role {
+ position: relative;
li {
border-right: 1px solid $grayer;
display: inline-block;
@@ -194,6 +195,9 @@
text-overflow: ellipsis;
white-space: nowrap;
}
+ .pop-points-open {
+ @include popover(150px, '', 30px, '', '');
+ }
}
.issue-data {