diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee
index c39e2b0a..913c2e4b 100644
--- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee
+++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee
@@ -24,7 +24,7 @@ class UserTimelineItemTitle
if user.get('is_profile_visible')
title_attr = @translate.instant('COMMON.SEE_USER_PROFILE', {username: user.get('username')})
- url = "user-profile:username=vm.timeline.getIn(['data', 'user', 'username'])"
+ url = "user-profile:username=timeline.getIn(['data', 'user', 'username'])"
return @._getLink(url, user.get('name'), title_attr)
else
@@ -36,7 +36,7 @@ class UserTimelineItemTitle
return @translate.instant(@._fieldTranslationKey[field_name])
project_name: (timeline, event) ->
- url = "project:project=vm.timeline.getIn(['data', 'project', 'slug'])"
+ url = "project:project=timeline.getIn(['data', 'project', 'slug'])"
return @._getLink(url, timeline.getIn(["data", "project", "name"]))
@@ -53,7 +53,7 @@ class UserTimelineItemTitle
return timeline.getIn(["data", "value_diff", "value"]).first().get(1)
sprint_name: (timeline, event) ->
- url = "project-taskboard:project=vm.timeline.getIn(['data', 'project', 'slug']),sprint=vm.timeline.getIn(['data', 'milestone', 'slug'])"
+ url = "project-taskboard:project=timeline.getIn(['data', 'project', 'slug']),sprint=timeline.getIn(['data', 'milestone', 'slug'])"
return @._getLink(url, timeline.getIn(['data', 'milestone', 'name']))
@@ -95,12 +95,12 @@ class UserTimelineItemTitle
_getDetailObjUrl: (event) ->
url = {
- "issue": ["project-issues-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"],
- "wikipage": ["project-wiki-page", ":project=vm.timeline.getIn(['data', 'project', 'slug']),slug=vm.timeline.getIn(['obj', 'ref'])"],
- "task": ["project-tasks-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"],
- "userstory": ["project-userstories-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"],
- "parent_userstory": ["project-userstories-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'userstory', 'ref'])"],
- "milestone": ["project-taskboard", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"]
+ "issue": ["project-issues-detail", ":project=timeline.getIn(['data', 'project', 'slug']),ref=timeline.getIn(['obj', 'ref'])"],
+ "wikipage": ["project-wiki-page", ":project=timeline.getIn(['data', 'project', 'slug']),slug=timeline.getIn(['obj', 'slug'])"],
+ "task": ["project-tasks-detail", ":project=timeline.getIn(['data', 'project', 'slug']),ref=timeline.getIn(['obj', 'ref'])"],
+ "userstory": ["project-userstories-detail", ":project=timeline.getIn(['data', 'project', 'slug']),ref=timeline.getIn(['obj', 'ref'])"],
+ "parent_userstory": ["project-userstories-detail", ":project=timeline.getIn(['data', 'project', 'slug']),ref=timeline.getIn(['obj', 'userstory', 'ref'])"],
+ "milestone": ["project-taskboard", ":project=timeline.getIn(['data', 'project', 'slug']),sprint=timeline.getIn(['obj', 'slug'])"]
}
return url[event.obj][0] + url[event.obj][1]
diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee
index 4f09c32e..39f35dd2 100644
--- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee
+++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee
@@ -54,7 +54,7 @@ describe "tgUserTimelineItemTitle", ->
.returns('user-param')
usernamelink = sinon.match ((value) ->
- return value.username == 'oo'
+ return value.username == 'oo'
), "usernamelink"
mockTranslate.instant
@@ -173,7 +173,7 @@ describe "tgUserTimelineItemTitle", ->
}
projectparam = sinon.match ((value) ->
- return value.project_name == 'project_name'
+ return value.project_name == 'project_name'
), "projectparam"
mockTranslate.instant
@@ -201,7 +201,7 @@ describe "tgUserTimelineItemTitle", ->
}
milestoneparam = sinon.match ((value) ->
- return value.sprint_name == 'milestone_name'
+ return value.sprint_name == 'milestone_name'
), "milestoneparam"
mockTranslate.instant
@@ -232,7 +232,7 @@ describe "tgUserTimelineItemTitle", ->
}
objparam = sinon.match ((value) ->
- return value.obj_name == '#123 subject'
+ return value.obj_name == '#123 subject'
), "objparam"
mockTranslate.instant
@@ -262,7 +262,7 @@ describe "tgUserTimelineItemTitle", ->
}
objparam = sinon.match ((value) ->
- return value.obj_name == 'Slug wiki'
+ return value.obj_name == 'Slug wiki'
), "objparam"
mockTranslate.instant
@@ -292,7 +292,7 @@ describe "tgUserTimelineItemTitle", ->
}
objparam = sinon.match ((value) ->
- return value.obj_name == 'milestone_name'
+ return value.obj_name == 'milestone_name'
), "objparam"
mockTranslate.instant
@@ -326,7 +326,7 @@ describe "tgUserTimelineItemTitle", ->
}
objparam = sinon.match ((value) ->
- return value.us_name == '#2 subject'
+ return value.us_name == '#2 subject'
), "objparam"
mockTranslate.instant
diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee
deleted file mode 100644
index f73b1545..00000000
--- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee
+++ /dev/null
@@ -1,41 +0,0 @@
-class UserTimelineItemController
- @.$inject = [
- "tgUserTimelineItemType",
- "tgUserTimelineItemTitle"
- ]
-
- constructor: (@userTimelineItemType, @userTimelineItemTitle) ->
- event = @.parseEventType(@.timeline.get('event_type'))
- type = @userTimelineItemType.getType(@.timeline, event)
-
- title = @userTimelineItemTitle.getTitle(@.timeline, event, type)
-
- @.timeline = @.timeline.set('title_html', title)
-
- @.timeline = @.timeline.set('obj', @.getObject(@.timeline, event))
-
- if type.description
- @.timeline = @.timeline.set('description', type.description(@.timeline))
-
- if type.member
- @.timeline = @.timeline.set('member', type.member(@.timeline))
-
- if @.timeline.getIn(['data', 'value_diff', 'key']) == 'attachments' &&
- @.timeline.hasIn(['data', 'value_diff', 'value', 'new'])
- @.timeline = @.timeline.set('attachments', @.timeline.getIn(['data', 'value_diff', 'value', 'new']))
-
- getObject: (timeline, event) ->
- if timeline.get('data').get(event.obj)
- return timeline.get('data').get(event.obj)
-
- parseEventType: (event_type) ->
- event_type = event_type.split(".")
-
- return {
- section: event_type[0],
- obj: event_type[1],
- type: event_type[2]
- }
-
-angular.module("taigaUserTimeline")
- .controller("UserTimelineItem", UserTimelineItemController)
diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee
deleted file mode 100644
index bbad8f5b..00000000
--- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee
+++ /dev/null
@@ -1,95 +0,0 @@
-describe "UserTimelineItemController", ->
- controller = scope = provide = null
- timeline = event = null
- mockTgUserTimelineItemType = null
- mockTgUserTimelineItemTitle = null
- mockType = null
-
- _mockTgUserTimelineItemType = () ->
- mockTgUserTimelineItemType = {
- getType: sinon.stub()
- }
-
- mockType = {
- description: sinon.stub(),
- member: sinon.stub()
- }
-
- mockTgUserTimelineItemType.getType.withArgs(timeline).returns(mockType)
-
- provide.value "tgUserTimelineItemType", mockTgUserTimelineItemType
-
- _mockTgUserTimelineItemTitle = () ->
- mockTgUserTimelineItemTitle = {
- getTitle: sinon.stub()
- }
-
- mockTgUserTimelineItemTitle.getTitle.withArgs(timeline, event, mockType).returns("fakeTitle")
-
- provide.value "tgUserTimelineItemTitle", mockTgUserTimelineItemTitle
-
- _mocks = () ->
- module ($provide) ->
- provide = $provide
- _mockTgUserTimelineItemType()
- _mockTgUserTimelineItemTitle()
-
- return null
-
- _setup = () ->
- event = {
- section: 'issues',
- obj: 'issue',
- type: 'created'
- }
-
- timeline = Immutable.fromJS({
- event_type: 'issues.issue.created',
- data: {
- user: 'user_fake',
- project: 'project_fake',
- milestone: 'milestone_fake',
- created: new Date().getTime(),
- issue: {
- id: 2
- },
- value_diff: {
- key: 'attachments',
- value: {
- new: "fakeAttachment"
- }
- }
- }
- })
-
- scope = {
- vm: {
- timeline: timeline
- }
- }
-
- beforeEach ->
- module "taigaUserTimeline"
-
- _setup()
- _mocks()
-
- inject ($controller) ->
- controller = $controller
-
- it "all activity fields filled", () ->
- timeline = scope.vm.timeline
-
- description = "fakeDescription"
- member = "fakeMember"
-
- mockType.description.returns(description)
- mockType.member.returns(member)
-
- myCtrl = controller("UserTimelineItem", {$scope: scope}, {timeline: timeline})
-
- expect(myCtrl.timeline.get('title_html')).to.be.equal("fakeTitle")
- expect(myCtrl.timeline.get('obj')).to.be.equal(myCtrl.timeline.getIn(["data", "issue"]))
- expect(myCtrl.timeline.get("description")).to.be.equal(description)
- expect(myCtrl.timeline.get("member")).to.be.equal(member)
- expect(myCtrl.timeline.get("attachments")).to.be.equal("fakeAttachment")
diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.directive.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.directive.coffee
index 15daf833..89881de3 100644
--- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.directive.coffee
+++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.directive.coffee
@@ -1,8 +1,5 @@
UserTimelineItemDirective = () ->
return {
- controllerAs: "vm"
- controller: "UserTimelineItem"
- bindToController: true
templateUrl: "user-timeline/user-timeline-item/user-timeline-item.html"
scope: {
timeline: "=tgUserTimelineItem"
diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade
index f549c8a2..e37c1dca 100644
--- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade
+++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade
@@ -1,29 +1,29 @@
div.activity-item
- span.activity-date {{::vm.timeline.get('created') | momentFromNow}}
+ span.activity-date {{::timeline.get('created') | momentFromNow}}
- div.activity-info(tg-user-timeline-title="vm.timeline")
+ div.activity-info(tg-user-timeline-title="timeline")
div.activity-info
// profile image with url
- div.profile-contact-picture(ng-if="vm.timeline.getIn(['data', 'user', 'is_profile_visible'])")
- a(tg-nav="user-profile:username=vm.timeline.getIn(['data', 'user', 'username'])", title="{{::vm.timeline.getIn(['data', 'user', 'name']) }}")
- img(ng-src="{{::vm.timeline.getIn(['data', 'user', 'photo']) || '/images/user-noimage.png'}}", alt="{{::vm.timeline.getIn(['data', 'user', 'name'])}}")
+ div.profile-contact-picture(ng-if="timeline.getIn(['data', 'user', 'is_profile_visible'])")
+ a(tg-nav="user-profile:username=timeline.getIn(['data', 'user', 'username'])", title="{{::timeline.getIn(['data', 'user', 'name']) }}")
+ img(ng-src="{{::timeline.getIn(['data', 'user', 'photo']) || '/images/user-noimage.png'}}", alt="{{::timeline.getIn(['data', 'user', 'name'])}}")
// profile image without url
- div.profile-contact-picture(ng-if="!vm.timeline.getIn(['data', 'user', 'is_profile_visible'])")
- img(ng-src="{{::vm.timeline.getIn(['data', 'user', 'photo']) || '/images/user-noimage.png'}}", alt="{{::vm.timeline.getIn(['data', 'user', 'name'])}}")
+ div.profile-contact-picture(ng-if="!timeline.getIn(['data', 'user', 'is_profile_visible'])")
+ img(ng-src="{{::timeline.getIn(['data', 'user', 'photo']) || '/images/user-noimage.png'}}", alt="{{::timeline.getIn(['data', 'user', 'name'])}}")
- p(tg-compile-html="vm.timeline.get('title_html')")
+ p(tg-compile-html="timeline.get('title_html')")
- blockquote.activity-comment-quote(ng-if="::vm.timeline.get('description')")
- | {{::vm.timeline.get('description') | limitTo:300}}
+ blockquote.activity-comment-quote(ng-if="::timeline.get('description')")
+ | {{::timeline.get('description') | limitTo:300}}
- .activity-member-view(ng-if="::vm.timeline.has('member')")
- a.profile-member-picture(tg-nav="user-profile:username=vm.timeline.getIn(['member', 'user', 'username'])", title="{{::vm.timeline.getIn(['member', 'user', 'name'])}}")
- img(ng-src="{{::vm.timeline.getIn(['member', 'user', 'photo'])}}", alt="{{::vm.timeline.getIn(['member','user', 'name'])}}")
+ .activity-member-view(ng-if="::timeline.has('member')")
+ a.profile-member-picture(tg-nav="user-profile:username=timeline.getIn(['member', 'user', 'username'])", title="{{::timeline.getIn(['member', 'user', 'name'])}}")
+ img(ng-src="{{::timeline.getIn(['member', 'user', 'photo'])}}", alt="{{::timeline.getIn(['member','user', 'name'])}}")
.activity-member-info
- a(tg-nav="user-profile:username=vm.timeline.getIn(['member', 'user', 'username'])", title="{{::vm.timeline.getIn(['member','user', 'name'])}}")
- span {{::vm.timeline.getIn(['member','user', 'name'])}}
- p {{::vm.timeline.getIn(['member','role', 'name'])}}
+ a(tg-nav="user-profile:username=timeline.getIn(['member', 'user', 'username'])", title="{{::timeline.getIn(['member','user', 'name'])}}")
+ span {{::timeline.getIn(['member','user', 'name'])}}
+ p {{::timeline.getIn(['member','role', 'name'])}}
- div(tg-repeat="attachment in vm.timeline.get('attachments')")
+ div(tg-repeat="attachment in timeline.get('attachments')")
div(tg-user-timeline-attachment="attachment")
diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee
index 5ba77b7b..6f4b4c52 100644
--- a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee
+++ b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee
@@ -1,9 +1,14 @@
taiga = @.taiga
class UserTimelineService extends taiga.Service
- @.$inject = ["tgResources", "tgUserTimelinePaginationSequenceService"]
+ @.$inject = [
+ "tgResources",
+ "tgUserTimelinePaginationSequenceService",
+ "tgUserTimelineItemType",
+ "tgUserTimelineItemTitle"
+ ]
- constructor: (@rs, @userTimelinePaginationSequenceService) ->
+ constructor: (@rs, @userTimelinePaginationSequenceService, @userTimelineItemType, @userTimelineItemTitle) ->
_valid_fields: [
'status',
@@ -75,12 +80,46 @@ class UserTimelineService extends taiga.Service
return _.some @._invalid, (invalid) =>
return invalid.check.call(this, timeline)
- # create a entry per every item in the values_diff
- _splitChanges: (response) ->
+ _parseEventType: (event_type) ->
+ event_type = event_type.split(".")
+
+ return {
+ section: event_type[0],
+ obj: event_type[1],
+ type: event_type[2]
+ }
+
+ _getTimelineObject: (timeline, event) ->
+ if timeline.get('data').get(event.obj)
+ return timeline.get('data').get(event.obj)
+
+ _attachExtraInfoToTimelineEntry: (timeline, event, type) ->
+ title = @userTimelineItemTitle.getTitle(timeline, event, type)
+
+ timeline = timeline.set('title_html', title)
+
+ timeline = timeline.set('obj', @._getTimelineObject(timeline, event))
+
+ if type.description
+ timeline = timeline.set('description', type.description(timeline))
+
+ if type.member
+ timeline = timeline.set('member', type.member(timeline))
+
+ if timeline.getIn(['data', 'value_diff', 'key']) == 'attachments' &&
+ timeline.hasIn(['data', 'value_diff', 'value', 'new'])
+ timeline = timeline.set('attachments', timeline.getIn(['data', 'value_diff', 'value', 'new']))
+
+ return timeline
+
+ # - create a entry per every item in the values_diff
+ # - add extra attributes to each entry
+ _parseTimeline: (response) ->
newdata = Immutable.List()
- response.get('data').forEach (item) ->
- event_type = item.get('event_type').split(".")
+ response.get('data').forEach (item) =>
+ event = @._parseEventType(item.get('event_type'))
+ type = @userTimelineItemType.getType(item, event)
data = item.get('data')
values_diff = data.get('values_diff')
@@ -92,10 +131,10 @@ class UserTimelineService extends taiga.Service
if values_diff.has('milestone')
values_diff = Immutable.Map({'moveInBacklog': values_diff})
- else if event_type[1] == 'milestone'
+ else if event.obj == 'milestone'
values_diff = Immutable.Map({'milestone': values_diff})
- values_diff.forEach (value, key) ->
+ values_diff.forEach (value, key) =>
obj = Immutable.Map({
key: key,
value: value
@@ -103,9 +142,11 @@ class UserTimelineService extends taiga.Service
newItem = item.setIn(['data', 'value_diff'], obj)
newItem = newItem.deleteIn(['data', 'values_diff'])
+ newItem = @._attachExtraInfoToTimelineEntry(newItem, event, type)
newdata = newdata.push(newItem)
else
newItem = item.deleteIn(['data', 'values_diff'])
+ newItem = @._attachExtraInfoToTimelineEntry(newItem, event, type)
newdata = newdata.push(newItem)
return response.set('data', newdata)
@@ -116,7 +157,7 @@ class UserTimelineService extends taiga.Service
config.fetch = (page) =>
return @rs.users.getProfileTimeline(userId, page)
.then (response) =>
- return @._splitChanges(response)
+ return @._parseTimeline(response)
config.filter = (items) =>
return items.filterNot (item) => @._isInValidTimeline(item)
@@ -129,7 +170,7 @@ class UserTimelineService extends taiga.Service
config.fetch = (page) =>
return @rs.users.getUserTimeline(userId, page)
.then (response) =>
- return @._splitChanges(response)
+ return @._parseTimeline(response)
config.filter = (items) =>
return items.filterNot (item) => @._isInValidTimeline(item)
@@ -141,7 +182,7 @@ class UserTimelineService extends taiga.Service
config.fetch = (page) =>
return @rs.projects.getTimeline(projectId, page)
- .then (response) => return @._splitChanges(response)
+ .then (response) => return @._parseTimeline(response)
config.filter = (items) =>
return items.filterNot (item) => @._isInValidTimeline(item)
diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee
index 11aae951..80b41000 100644
--- a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee
+++ b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee
@@ -23,11 +23,34 @@ describe "tgUserTimelineService", ->
provide.value "tgUserTimelinePaginationSequenceService", mocks.userTimelinePaginationSequence
+ _mockTgUserTimelineItemType = () ->
+ mocks.userTimelineItemType = {
+ getType: sinon.stub()
+ }
+
+ mocks.getType = {
+ description: sinon.stub(),
+ member: sinon.stub()
+ }
+
+ mocks.userTimelineItemType.getType.returns(mocks.getType)
+
+ provide.value "tgUserTimelineItemType", mocks.userTimelineItemType
+
+ _mockTgUserTimelineItemTitle = () ->
+ mocks.userTimelineItemTitle = {
+ getTitle: sinon.stub()
+ }
+
+ provide.value "tgUserTimelineItemTitle", mocks.userTimelineItemTitle
+
_mocks = () ->
module ($provide) ->
provide = $provide
_mockResources()
_mockUserTimelinePaginationSequence()
+ _mockTgUserTimelineItemType()
+ _mockTgUserTimelineItemTitle()
return null
@@ -211,3 +234,38 @@ describe "tgUserTimelineService", ->
result = userTimelineService.getProjectTimeline(userId)
expect(result).to.be.eventually.true
+
+ it "all timeline extra fields filled", () ->
+ timeline = Immutable.fromJS({
+ data: [{
+ event_type: 'issues.issue.created',
+ data: {
+ user: 'user_fake',
+ project: 'project_fake',
+ milestone: 'milestone_fake',
+ created: new Date().getTime(),
+ issue: {
+ id: 2
+ },
+ value_diff: {
+ key: 'attachments',
+ value: {
+ new: "fakeAttachment"
+ }
+ }
+ }
+ }]
+ })
+
+ mocks.userTimelineItemTitle.getTitle.returns("fakeTitle")
+ mocks.getType.description.returns("fakeDescription")
+ mocks.getType.member.returns("fakeMember")
+
+ timeline = userTimelineService._parseTimeline(timeline)
+ timelineEntry = timeline.get('data').get(0)
+
+ expect(timelineEntry.get('title_html')).to.be.equal("fakeTitle")
+ expect(timelineEntry.get('obj')).to.be.equal(timelineEntry.getIn(["data", "issue"]))
+ expect(timelineEntry.get("description")).to.be.equal("fakeDescription")
+ expect(timelineEntry.get("member")).to.be.equal("fakeMember")
+ expect(timelineEntry.get("attachments")).to.be.equal("fakeAttachment")