### # Copyright (C) 2014 Andrey Antukh # Copyright (C) 2014 Jesús Espino Garcia # Copyright (C) 2014 David Barragán Merino # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # File: modules/taskboard.coffee ### taiga = @.taiga mixOf = @.taiga.mixOf groupBy = @.taiga.groupBy module = angular.module("taigaTaskboard", []) ############################################################################# ## Taskboard Controller ############################################################################# class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin) @.$inject = [ "$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q) -> @scope.sprintId = @params.id promise = @.loadInitialData() promise.then null, -> console.log "FAIL" #TODO loadSprintStats: -> return @rs.sprints.stats(@scope.projectId, @scope.sprintId).then (stats) => totalPointsSum =_.reduce(_.values(stats.total_points), ((res, n) -> res + n), 0) completedPointsSum = _.reduce(_.values(stats.completed_points), ((res, n) -> res + n), 0) remainingPointsSum = totalPointsSum - completedPointsSum remainingTasks = stats.total_tasks - stats.completed_tasks @scope.stats = stats @scope.stats.totalPointsSum = totalPointsSum @scope.stats.completedPointsSum = completedPointsSum @scope.stats.remainingPointsSum = remainingPointsSum @scope.stats.remainingTasks = remainingTasks return stats loadSprint: -> return @rs.sprints.get(@scope.projectId, @scope.sprintId).then (sprint) => @scope.sprint = sprint @scope.userstories = sprint.user_stories return sprint loadTasks: -> return @rs.tasks.list(@scope.projectId, @scope.sprintId).then (tasks) => @scope.tasks = tasks @scope.tasksByStatus = _.groupBy(tasks, "status") return tasks loadProject: -> return @rs.projects.get(@scope.projectId).then (project) => @scope.project = project @scope.points = _.sortBy(project.points, "order") @scope.taskStatusList = _.sortBy(project.task_statuses, "order") @scope.usStatusList = _.sortBy(project.us_statuses, "order") @scope.usStatusById = groupBy(project.us_statuses, (e) -> e.id) return project loadTaskboard: -> return @q.all([ @.loadSprintStats(), @.loadSprint() # @.loadTasks(), ]).then(=> @.loadTasks()) loadInitialData: -> promise = @repo.resolve({pslug: @params.pslug}).then (data) => @scope.projectId = data.project return data return promise.then(=> @.loadProject()) .then(=> @.loadUsersAndRoles()) .then(=> @.loadTaskboard()) module.controller("TaskboardController", TaskboardController) ############################################################################# ## TaskboardDirective ############################################################################# TaskboardDirective = -> ######################### ## Drag & Drop Link ######################### linkSortable = ($scope, $el, $attrs, $ctrl) -> console.log "TaskboardDirective.linkSortable" #TODO link = ($scope, $el, $attrs) -> $ctrl = $el.controller() linkSortable($scope, $el, $attrs, $ctrl) $scope.$on "$destroy", -> $el.off() return {link: link} ############################################################################# ## Task Row Size Fixer Directive ############################################################################# TaskboardRowSizeFixer = -> link = ($scope, $el, $attrs) -> taiga.bindOnce $scope, "taskStatusList", (statuses) -> itemSize = 300 + (10 * statuses.length) size = (1 + statuses.length) * itemSize $el.css("width", size + "px") return {link: link} ############################################################################# ## User story status directive ############################################################################# TaskboardUsStatusDirective = ($repo) -> # NOTE: This directive is similar to backlog.main.UsStatusDirective selectionTemplate = _.template(""" """) updateUsStatus = ($el, us, usStatusById) -> usStatusDom = $el.find(".us-status") usStatusDom.text(usStatusById[us.status].name) usStatusDom.css('color', usStatusById[us.status].color) link = ($scope, $el, $attrs) -> $ctrl = $el.controller() us = $scope.$eval($attrs.tgTaskboardUsStatus) taiga.bindOnce $scope, "project", (project) -> $el.append(selectionTemplate({ 'statuses': project.us_statuses })) updateUsStatus($el, us, $scope.usStatusById) $el.on "click", ".us-status", (event) -> event.preventDefault() event.stopPropagation() $el.find(".pop-status").show() body = angular.element("body") body.one "click", (event) -> $el.find(".popover").hide() $el.on "click", ".status", (event) -> event.preventDefault() event.stopPropagation() target = angular.element(event.currentTarget) us.status = target.data("status-id") $el.find(".pop-status").hide() updateUsStatus($el, us, $scope.usStatusById) $scope.$apply () -> $repo.save(us).then -> $ctrl.loadSprintStats() $scope.$on "$destroy", -> $el.off() return {link: link} ############################################################################# ## User story status directive ############################################################################# TaskboardUsPointsDirective = ($repo) -> module.directive("tgTaskboard", TaskboardDirective) module.directive("tgTaskboardRowSizeFixer", TaskboardRowSizeFixer) module.directive("tgTaskboardUsStatus", ["$tgRepo", TaskboardUsStatusDirective])