diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index 1e94fe92..6da90974 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -363,3 +363,129 @@ UsStatusDetailDirective = () -> return {link:link, require:"ngModel"} module.directive("tgUsStatusDetail", UsStatusDetailDirective) + +############################################################################# +## User story estimation directive +############################################################################# + +UsEstimationDirective = ($log) -> + mainTemplate = _.template(""" + + """) + + pointsTemplate = _.template(""" + + """) + + link = ($scope, $el, $attrs) -> + render = (us) -> + totalPoints = us.total_points or 0 + computableRoles = _.filter($scope.project.roles, "computable") + + roles = _.map computableRoles, (role) -> + pointId = us.points[role.id] + pointObj = $scope.pointsById[pointId] + + role = _.clone(role, true) + role.points = if pointObj? and pointObj.name? then pointObj.name else "?" + return role + + html = mainTemplate({totalPoints: totalPoints, roles: roles}) + $el.html(html) + + renderPoints = (us, roleId) -> + points = _.map $scope.project.points, (point) -> + point = _.clone(point, true) + point.selected = if us.points[roleId] == point.id then false else true + return point + + html = pointsTemplate({"points": points, roleId: roleId}) + + # Remove any prevous state + $el.find(".popover").popover().close() + $el.find(".pop-points-open").remove() + + # If not showing role selection let's move to the left + if not $el.find(".pop-role:visible").css("left")? + $el.find(".pop-points-open").css("left", "110px") + + $el.find(".pop-points-open").remove() + + # Render into DOM and show the new created element + $el.find(".points-per-role").append(html) + + $el.find(".pop-points-open").popover().open(-> $(this).removeClass("active")) + $el.find(".pop-points-open").show() + + calculateTotalPoints = (us) -> + values = _.map(us.points, (v, k) -> $scope.pointsById[v]?.value or 0) + if values.length == 0 + return "0" + return _.reduce(values, (acc, num) -> acc + num) + + $scope.$watch $attrs.ngModel, (us) -> + render(us) if us + + $scope.$on "$destroy", -> + $el.off() + + $el.on "click", ".total.clickable", (event) -> + event.preventDefault() + event.stopPropagation() + target = angular.element(event.currentTarget) + roleId = target.data("role-id") + + us = $scope.$eval($attrs.ngModel) + renderPoints(us, roleId) + + target.siblings().removeClass('active') + target.addClass('active') + + $el.on "click", ".point", (event) -> + event.preventDefault() + event.stopPropagation() + + us = $scope.$eval($attrs.ngModel) + + target = angular.element(event.currentTarget) + roleId = target.data("role-id") + pointId = target.data("point-id") + + $el.find(".popover").popover().close() + + points = _.clone(us.points, true) + points[roleId] = pointId + + $scope.$apply -> + us.points = points + us.total_points = calculateTotalPoints(us) + render(us) + + return { + link: link + restrict: "EA" + } + +module.directive("tgUsEstimation", UsEstimationDirective) diff --git a/app/partials/views/modules/lightbox-us-create-edit.jade b/app/partials/views/modules/lightbox-us-create-edit.jade index 9e189700..17af9326 100644 --- a/app/partials/views/modules/lightbox-us-create-edit.jade +++ b/app/partials/views/modules/lightbox-us-create-edit.jade @@ -7,7 +7,8 @@ form data-required="true", data-maxlength="500") fieldset.estimation - //- Render by tg-lb-create-edit-userstory + tg-us-estimation(ng-model="us") + //- Render by tg-lb-create-edit-userstory fieldset select(name="status", ng-model="us.status", ng-options="s.id as s.name for s in usStatusList",