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("""
+
+
+ """)
+ standardChangeFromToTemplate = _.template("""
+
+
+ <%- name %>
+
+
+
+ from
+ <%= from %>
+
+
+ to
+ <%= to %>
+
+
+
+ """)
+ descriptionChangeTemplate = _.template("""
+
+ """)
+ 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("""
+
+
+ """)
+ standardChangeFromToTemplate = _.template("""
+
+
+ <%- name %>
+
+
+
+ from
+ <%= from %>
+
+
+ to
+ <%= to %>
+
+
+
+ """)
+ descriptionChangeTemplate = _.template("""
+
+ """)
+ 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