### # 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/tasks/detail.coffee ### taiga = @.taiga mixOf = @.taiga.mixOf groupBy = @.taiga.groupBy module = angular.module("taigaTasks") ############################################################################# ## Task Detail Controller ############################################################################# class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @.$inject = [ "$scope", "$rootScope", "$tgRepo", "$tgConfirm", "$tgResources", "$routeParams", "$q", "$location" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location) -> @scope.taskRef = @params.taskref @scope.sectionName = "Backlog" promise = @.loadInitialData() promise.then null, -> console.log "FAIL" #TODO loadProject: -> return @rs.projects.get(@scope.projectId).then (project) => @scope.project = project @scope.statusList = project.task_statuses @scope.statusById = groupBy(project.task_statuses, (x) -> x.id) @scope.membersById = groupBy(project.memberships, (x) -> x.user) return project loadTask: -> return @rs.tasks.get(@scope.projectId, @scope.taskId).then (task) => @scope.task = task @scope.commentModel = task # @scope.previousUrl = "/project/#{@scope.project.slug}/tasks/#{@scope.task.neighbors.previous.ref}" if @scope.task.neighbors.previous.id? # @scope.nextUrl = "/project/#{@scope.project.slug}/tasks/#{@scope.task.neighbors.next.ref}" if @scope.task.neighbors.next.id? loadHistory: -> return @rs.tasks.history(@scope.taskId).then (history) => _.each history.results, (historyResult) -> #If description was modified take only the description_html field if historyResult.values_diff.description? historyResult.values_diff.description = historyResult.values_diff.description_html if historyResult.values_diff.is_iocaine historyResult.values_diff.is_iocaine = _.map(historyResult.values_diff.is_iocaine, (v) -> {true: 'Yes', false: 'No'}[v]) delete historyResult.values_diff.description_html delete historyResult.values_diff.description_diff @scope.history = history.results @scope.comments = _.filter(history.results, (historyEntry) -> historyEntry.comment != "") loadInitialData: -> params = { pslug: @params.pslug taskref: @params.taskref } promise = @repo.resolve(params).then (data) => @scope.projectId = data.project @scope.taskId = data.task return data return promise.then(=> @.loadProject()) .then(=> @.loadUsersAndRoles()) .then(=> @.loadTask()) .then(=> @.loadHistory()) getUserFullName: (userId) -> return @scope.usersById[userId]?.full_name_display getUserAvatar: (userId) -> return @scope.usersById[userId]?.photo countChanges: (comment) -> return Object.keys(comment.values_diff).length getChangeText: (change) -> if _.isArray(change) return change.join(", ") return change buildChangesText: (comment) -> size = @.countChanges(comment) #TODO: i18n if size == 1 return "Made #{size} change" return "Made #{size} changes" block: -> @rootscope.$broadcast("block", @scope.task) unblock: -> @rootscope.$broadcast("unblock", @scope.task) delete: -> #TODO: i18n title = "Delete Task" subtitle = @scope.task.subject @confirm.ask(title, subtitle).then => @.repo.remove(@scope.task).then => @location.path("/project/#{@scope.project.slug}/backlog") module.controller("TaskDetailController", TaskDetailController) ############################################################################# ## Task Main Directive ############################################################################# TaskDirective = ($tgrepo, $log, $location, $confirm) -> linkSidebar = ($scope, $el, $attrs, $ctrl) -> link = ($scope, $el, $attrs) -> $ctrl = $el.controller() linkSidebar($scope, $el, $attrs, $ctrl) $el.on "click", ".save-task", (event) -> $tgrepo.save($scope.task).then -> $confirm.notify("success") $location.path("/project/#{$scope.project.slug}/tasks/#{$scope.task.ref}") $el.on "click", ".add-comment a.button-green", (event) -> event.preventDefault() $tgrepo.save($scope.task).then -> $ctrl.loadHistory() $el.on "focus", ".add-comment textarea", (event) -> $(this).addClass('active') $el.on "click", ".us-activity-tabs li a", (event) -> $el.find(".us-activity-tabs li a").toggleClass("active") $el.find(".us-activity section").toggleClass("hidden") return {link:link} module.directive("tgTaskDetail", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", TaskDirective]) ############################################################################# ## Task status directive ############################################################################# TaskStatusDirective = () -> #TODO: i18n template = _.template("""

<% if (status.is_closed) { %> Closed <% } else { %> Open <% } %> <%= status.name %>

<%= status.name %> status
""") selectionStatusTemplate = _.template(""" """) link = ($scope, $el, $attrs, $model) -> editable = $attrs.editable? renderTaskstatus = (task) -> status = $scope.statusById[task.status] html = template({ editable: editable status: status }) $el.html(html) $el.find(".status-data").append(selectionStatusTemplate({statuses:$scope.statusList})) $scope.$watch $attrs.ngModel, (task) -> if task? renderTaskstatus(task) if editable $el.on "click", ".status-data", (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) $model.$modelValue.status = target.data("status-id") renderTaskstatus($model.$modelValue) $el.find(".popover").hide() return {link:link, require:"ngModel"} module.directive("tgTaskStatus", TaskStatusDirective)