diff --git a/app/coffee/modules/issues/detail.coffee b/app/coffee/modules/issues/detail.coffee index 5cbfac06..19b2bdfb 100644 --- a/app/coffee/modules/issues/detail.coffee +++ b/app/coffee/modules/issues/detail.coffee @@ -27,6 +27,7 @@ toString = @.taiga.toString joinStr = @.taiga.joinStr groupBy = @.taiga.groupBy bindOnce = @.taiga.bindOnce +typeIsArray = @.taiga.typeIsArray module = angular.module("taigaIssues") @@ -112,27 +113,6 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin, tai .then(=> @.loadAttachments(@scope.issueId)) .then(=> @.loadHistory()) - getUserFullName: (userId) -> - return @scope.usersById[userId]?.full_name_display - - getUserAvatar: (userId) -> - return @scope.usersById[userId]?.photo - - countChanges: (comment) -> - return _.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.issue) @@ -401,12 +381,186 @@ IssueStatusDirective = () -> module.directive("tgIssueStatus", IssueStatusDirective) + ############################################################################# ## Comment directive ############################################################################# CommentDirective = -> + # TODO: i18n + commentBaseTemplate = _.template(""" +
+ + <%- userFullName %> + +
+
+ + <%- userFullName %> + + <% if(hasChanges){ %> +
+ + + <%- changesText %> + + + + +
+ <% } %> + +

+ <%- comment %> +

+

+ <%- creationDate %> +

+
+ """) + standardChangeFromToTemplate = _.template(""" +
+
+ <%- name %> +
+
+

+ from
+ <%= from %> +

+

+ to
+ <%= to %> +

+
+
+ """) + descriptionChangeTemplate = _.template(""" +
+
+ <%- name %> +
+
+

+ <%= diff %> +

+
+
+ """) + pointsChangeTemplate = _.template(""" + <% _.each(points, function(point, name) { %> +
+
+ <%- name %> points +
+
+

+ from
+ <%= point[0] %> +

+

+ to
+ <%= point[1] %> +

+
+
+ <% }); %> + """) + attachmentTemplate = _.template(""" +
+
+ <%- name %> +
+
+ <%- description %> +
+
+ """) link = ($scope, $el, $attrs, $model) -> + countChanges = (comment) -> + return _.keys(comment.values_diff).length + + buildChangesText = (comment) -> + size = countChanges(comment) + # TODO: i18n + if size == 1 + return "Made #{size} change" + return "Made #{size} changes" + + renderComment = (comment) -> + html = commentBaseTemplate({ + avatar: getUserAvatar(comment.user.pk) + userFullName: getUserFullName(comment.user.pk) + creationDate: moment(comment.created_at).format("YYYY/MM/DD") + comment: comment.comment + changesText: buildChangesText(comment) + hasChanges: countChanges(comment) > 0 + }) + + $el.html(html) + activityContentDom = $el.find(".comment-content .us-activity") + _.each comment.values_diff, (modification, name) -> + if name == "description" + activityContentDom.append(descriptionChangeTemplate({ + name: name + diff: modification[1] + })) + else if name == "points" + activityContentDom.append(pointsChangeTemplate({ + points: modification + })) + else if name == "attachments" + _.each modification, (attachmentChanges, attachmentType) -> + if attachmentType == "new" + _.each attachmentChanges, (attachmentChange) -> + activityContentDom.append(attachmentTemplate({ + name: "New attachment" + description: attachmentChange.filename + })) + else if attachmentType == "deleted" + _.each attachmentChanges, (attachmentChange) -> + activityContentDom.append(attachmentTemplate({ + name: "Deleted attachment" + description: attachmentChange.filename + })) + else + name = "Updated attachment" + _.each attachmentChanges, (attachmentChange) -> + activityContentDom.append(attachmentTemplate({ + name: "Updated attachment" + description: attachmentChange[0].filename + })) + + else + activityContentDom.append(standardChangeFromToTemplate({ + name: name + from: prettyPrintModification(modification[0]) + to: prettyPrintModification(modification[1]) + })) + + getUserFullName = (userId) -> + return $scope.usersById[userId]?.full_name_display + + getUserAvatar = (userId) -> + return $scope.usersById[userId]?.photo + + prettyPrintModification = (value) -> + if typeIsArray(value) + if value.length == 0 + #TODO i18n + return "None" + else + return value.join(", ") + + if value == "" + return "None" + + return value + + $scope.$watch $attrs.ngModel, (comment) -> + if comment? + renderComment(comment) + $el.on "click", ".activity-title", (event) -> event.preventDefault() $el.find(".activity-inner").toggleClass("active") @@ -414,6 +568,167 @@ CommentDirective = -> $scope.$on "$destroy", -> $el.off() - return {link:link} + return {link:link, require:"ngModel"} module.directive("tgComment", CommentDirective) + + +############################################################################# +## Change directive +############################################################################# + +ChangeDirective = -> + # TODO: i18n + changeBaseTemplate = _.template(""" +
+ + <%- userFullName %> + +
+
+
+ + <%- userFullName %> + + + <%- creationDate %> + +
+
+ """) + standardChangeFromToTemplate = _.template(""" +
+
+ <%- name %> +
+
+

+ from
+ <%= from %> +

+

+ to
+ <%= to %> +

+
+
+ """) + descriptionChangeTemplate = _.template(""" +
+
+ <%- name %> +
+
+

+ <%= diff %> +

+
+
+ """) + pointsChangeTemplate = _.template(""" + <% _.each(points, function(point, name) { %> +
+
+ <%- name %> points +
+
+

+ from
+ <%= point[0] %> +

+

+ to
+ <%= point[1] %> +

+
+
+ <% }); %> + """) + attachmentTemplate = _.template(""" +
+
+ <%- name %> +
+
+ <%- description %> +
+
+ """) + link = ($scope, $el, $attrs, $model) -> + renderChange = (change) -> + html = changeBaseTemplate({ + avatar: getUserAvatar(change.user.pk) + userFullName: getUserFullName(change.user.pk) + creationDate: moment(change.created_at).format("YYYY/MM/DD") + }) + + $el.html(html) + activityContentDom = $el.find(".activity-content") + _.each change.values_diff, (modification, name) -> + if name == "description" + activityContentDom.append(descriptionChangeTemplate({ + name: name + diff: modification[1] + })) + else if name == "points" + activityContentDom.append(pointsChangeTemplate({ + points: modification + })) + else if name == "attachments" + _.each modification, (attachmentChanges, attachmentType) -> + if attachmentType == "new" + _.each attachmentChanges, (attachmentChange) -> + activityContentDom.append(attachmentTemplate({ + name: "New attachment" + description: attachmentChange.filename + })) + else if attachmentType == "deleted" + _.each attachmentChanges, (attachmentChange) -> + activityContentDom.append(attachmentTemplate({ + name: "Deleted attachment" + description: attachmentChange.filename + })) + else + name = "Updated attachment" + _.each attachmentChanges, (attachmentChange) -> + activityContentDom.append(attachmentTemplate({ + name: "Updated attachment" + description: attachmentChange[0].filename + })) + + else + activityContentDom.append(standardChangeFromToTemplate({ + name: name + from: prettyPrintModification(modification[0]) + to: prettyPrintModification(modification[1]) + })) + + getUserFullName = (userId) -> + return $scope.usersById[userId]?.full_name_display + + getUserAvatar = (userId) -> + return $scope.usersById[userId]?.photo + + prettyPrintModification = (value) -> + if typeIsArray(value) + if value.length == 0 + #TODO i18n + return "None" + else + return value.join(", ") + + if value == "" + return "None" + + return value + + $scope.$watch $attrs.ngModel, (change) -> + if change? + renderChange(change) + + $scope.$on "$destroy", -> + $el.off() + + return {link:link, require:"ngModel"} + +module.directive("tgChange", ChangeDirective) diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index 70fa9990..94fcbd27 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -82,7 +82,7 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin, _.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 + historyResult.values_diff.description = historyResult.values_diff.description_diff if historyResult.values_diff.client_requirement historyResult.values_diff.client_requirement = _.map(historyResult.values_diff.client_requirement, (v) -> {true: 'Yes', false: 'No'}[v]) diff --git a/app/coffee/utils.coffee b/app/coffee/utils.coffee index ba3d6a6f..be2d2e9e 100644 --- a/app/coffee/utils.coffee +++ b/app/coffee/utils.coffee @@ -121,6 +121,8 @@ sizeFormat = (input, precision=1) -> return "#{size} #{units[number]}" +typeIsArray = Array.isArray || ( value ) -> return {}.toString.call( value ) is '[object Array]' + taiga = @.taiga taiga.bindOnce = bindOnce taiga.mixOf = mixOf @@ -137,3 +139,4 @@ taiga.joinStr = joinStr taiga.debounce = debounce taiga.startswith = startswith taiga.sizeFormat = sizeFormat +taiga.typeIsArray = typeIsArray diff --git a/app/partials/views/modules/activity.jade b/app/partials/views/modules/activity.jade index c89a0e3f..eb4caa1e 100644 --- a/app/partials/views/modules/activity.jade +++ b/app/partials/views/modules/activity.jade @@ -1,24 +1,5 @@ section.us-activity.hidden - div.activity-single(tg-comment, ng-repeat="change in history") - div.activity-user - a.avatar(href="", tg-bo-title="ctrl.getUserFullName(change.user.pk)") - img(tg-bo-src="ctrl.getUserAvatar(change.user.pk)", tg-bo-alt="ctrl.getUserFullName(change.user.pk)") - - div.activity-content - div.activity-username - a.username(href="TODO", tg-bo-title="ctrl.getUserFullName(change.user.pk)" tg-bo-bind="ctrl.getUserFullName(change.user.pk)") - span.date {{ change.created_at | date:'yyyy-MM-dd HH:mm' }} - - div.activity-inner(ng-repeat="(key, change) in change.values_diff") - div.activity-changed - span(tg-bo-bind="key") - div.activity-fromto - p - strong from
- span(tg-bo-bind="ctrl.getChangeText(change[0])") - p - strong to
- span(tg-bo-bind="ctrl.getChangeText(change[1])") + div.activity-single(tg-change, ng-model="change", ng-repeat="change in history") //a.more-activity(href="", title="show more comments") // span show previous activity diff --git a/app/partials/views/modules/comment-activity.jade b/app/partials/views/modules/comment-activity.jade index 45e8f601..352c1669 100644 --- a/app/partials/views/modules/comment-activity.jade +++ b/app/partials/views/modules/comment-activity.jade @@ -1,5 +1,4 @@ div.us-activity - a.activity-title(ng-show="ctrl.countChanges(comment)", href="", title="Show activity") span(tg-bo-bind="ctrl.buildChangesText(comment)") span.icon.icon-arrow-up diff --git a/app/partials/views/modules/comments.jade b/app/partials/views/modules/comments.jade index 1dc99587..445df9b1 100644 --- a/app/partials/views/modules/comments.jade +++ b/app/partials/views/modules/comments.jade @@ -3,18 +3,7 @@ section.us-comments textarea(placeholder="Write here a new commet", ng-model="commentModel.comment") a.button.button-green(href="", title="Comment") Comment div.comment-list - div.comment-single(tg-comment, ng-repeat="comment in comments") - div.comment-user - a.avatar(href="", tg-bo-title="ctrl.getUserFullName(comment.user.pk)") - img(tg-bo-src="ctrl.getUserAvatar(comment.user.pk)", tg-bo-alt="ctrl.getUserFullName(comment.user.pk)") - div.comment-content - a.username(href="TODO", tg-bo-title="ctrl.getUserFullName(comment.user.pk)" tg-bo-bind="ctrl.getUserFullName(comment.user.pk)") - //- includes module activity - include comment-activity - p.comment {{ comment.comment }} - p.date {{ comment.created_at | date:'yyyy-MM-dd HH:mm' }} - - //a.delete-comment.icon.icon-delete(href="", title="delete comment") + div.comment-single(tg-comment, ng-model="comment", ng-repeat="comment in comments") //a.more-comments(href="", title="show more comments") //span show previous comments