Merge pull request #3323 from oliverguenther/feature/repository_activity
[21047] Work package activities also display repository revisonspull/3381/head
commit
96601cdb53
@ -0,0 +1,15 @@ |
||||
<div ng-switch="activityType"> |
||||
<revision-activity work-package="workPackage" |
||||
activity="activity" |
||||
activity-no="activityNo" |
||||
ng-switch-when="Revision"> |
||||
</revision-activity> |
||||
<user-activity work-package="workPackage" |
||||
activity="activity" |
||||
activity-no="activityNo" |
||||
is-initial="isInitial" |
||||
autocomplete-path="{{ autocompletePath }}" |
||||
input-element-id="'add-comment-text'" |
||||
ng-switch-default> |
||||
</user-activity> |
||||
</div> |
@ -0,0 +1,18 @@ |
||||
<div class="work-package-details-activities-activity-contents"> |
||||
<div class="comments-number"> |
||||
<span ui-sref="work-packages.list.details.activity.details({ activity_no: activityNo })"> |
||||
<a name="{{ activityNo }}" |
||||
ng-bind="'#' + activityNo" |
||||
ng-href="#{{ activityNo }}"></a> |
||||
</span> |
||||
</div> |
||||
<div ng-if="userAvatar"> |
||||
<img class="avatar" ng-src="{{ userAvatar }}" alt="Avatar" title="{{userName}}" /> |
||||
</div> |
||||
<span class="user" ng-if="userActive"><a ng-href="{{ userPath(userId) }}" name="{{ currentAnchor }}" ng-bind="userName"></a></span> |
||||
<span class="user" ng-if="!userActive">{{ userName }}</span> |
||||
<span class="revision-activity--revision-link date"></span> |
||||
<span class="user-comment wiki"> |
||||
<span class="message" ng-bind-html="message"/> |
||||
</span> |
||||
</div> |
@ -0,0 +1,47 @@ |
||||
//-- copyright
|
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
module.exports = function() { |
||||
return { |
||||
restrict: 'E', |
||||
replace: true, |
||||
templateUrl: '/templates/work_packages/activities/_entry.html', |
||||
scope: { |
||||
workPackage: '=', |
||||
activity: '=', |
||||
activityNo: '=', |
||||
isInitial: '=', |
||||
inputElementId: '=', |
||||
autocompletePath: '=' |
||||
}, |
||||
link: function(scope) { |
||||
scope.activityType = scope.activity.props._type; |
||||
} |
||||
}; |
||||
}; |
@ -0,0 +1,55 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
angular.module('openproject.workPackages.activities') |
||||
.directive('activityEntry', [ |
||||
require('./activity-entry-directive') |
||||
]) |
||||
.directive('userActivity', [ |
||||
'$uiViewScroll', |
||||
'$timeout', |
||||
'$location', |
||||
'$sce', |
||||
'I18n', |
||||
'PathHelper', |
||||
'ActivityService', |
||||
'UsersHelper', |
||||
'ConfigurationService', |
||||
'AutoCompleteHelper', |
||||
require('./user-activity-directive') |
||||
]) |
||||
.directive('revisionActivity', [ |
||||
'$compile', |
||||
'$sce', |
||||
'I18n', |
||||
'PathHelper', |
||||
'ActivityService', |
||||
'UsersHelper', |
||||
require('./revision-activity-directive') |
||||
]) |
||||
; |
@ -0,0 +1,87 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
module.exports = function($compile, |
||||
$sce, |
||||
I18n, |
||||
PathHelper, |
||||
ActivityService, |
||||
UsersHelper) { |
||||
return { |
||||
restrict: 'E', |
||||
replace: true, |
||||
templateUrl: '/templates/work_packages/activities/_revision.html', |
||||
scope: { |
||||
workPackage: '=', |
||||
activity: '=', |
||||
activityNo: '=', |
||||
}, |
||||
link: function(scope, element) { |
||||
scope.I18n = I18n; |
||||
if (scope.activity.links.author === undefined) { |
||||
scope.userName = scope.activity.props.authorName; |
||||
} else { |
||||
scope.userPath = PathHelper.staticUserPath; |
||||
scope.activity.links.author.fetch().then(function(user) { |
||||
scope.userId = user.props.id; |
||||
scope.userName = user.props.name; |
||||
scope.userAvatar = user.props.avatar; |
||||
scope.userActive = UsersHelper.isActive(user); |
||||
}); |
||||
} |
||||
|
||||
scope.project = scope.workPackage.embedded.project; |
||||
scope.revision = scope.activity.props.identifier; |
||||
scope.formattedRevision = scope.activity.props.formattedIdentifier; |
||||
scope.revisionPath = scope.activity.links.showRevision.href; |
||||
scope.message = $sce.trustAsHtml(scope.activity.props.message.html); |
||||
|
||||
var date = '<op-date-time date-time-value="activity.props.createdAt"/></op-date-time>'; |
||||
var link = [ |
||||
'<a ng-href="{{ revisionPath }}" title="{{ revision }}">', |
||||
'{{ I18n.t("js.label_committed_link", { revision_identifier: formattedRevision }) }}', |
||||
'</a>' |
||||
].join(''); |
||||
|
||||
scope.combinedRevisionLink = I18n.t("js.label_committed_at", |
||||
{ |
||||
committed_revision_link: link, |
||||
date: date |
||||
}); |
||||
|
||||
scope.$watch('combinedRevisionLink', function(html) { |
||||
var span = angular.element(html), |
||||
link = element.find('.revision-activity--revision-link'); |
||||
|
||||
link.append(span); |
||||
$compile(link.contents())(scope); |
||||
}); |
||||
|
||||
} |
||||
}; |
||||
}; |
@ -0,0 +1,39 @@ |
||||
{ |
||||
"_links": { |
||||
"self": { |
||||
"href": "/api/v3/work_packages/820/revisions" |
||||
} |
||||
}, |
||||
"_type": "Collection", |
||||
"total": 1, |
||||
"count": 1, |
||||
"_embedded": { |
||||
"elements": [ |
||||
{ |
||||
"_type": "Revision", |
||||
"_links": { |
||||
"self": { |
||||
"href": "/api/v3/revisions/1" |
||||
}, |
||||
"project": { |
||||
"href": "/api/v3/projects/6", |
||||
"title": "foobar" |
||||
}, |
||||
"showRevision": { |
||||
"href": "/projects/foobar/repository/revision/1cb824244ccb839bfce5a463a58b108cf8fbd4da" |
||||
} |
||||
}, |
||||
"id": 1, |
||||
"identifier": "1cb824244ccb839bfce5a463a58b108cf8fbd4da", |
||||
"formattedIdentifier": "1cb82424", |
||||
"authorName": "Oliver Günther ", |
||||
"message": { |
||||
"format": "plain", |
||||
"raw": "Awesome commit\n\nTotally references #820, really now.", |
||||
"html": "<p>This does something</p>\n\n<p>Totally references <a href=\"/work_packages/820\" class=\"issue work_package status-1 priority-2 created-by-me\" title=\"asdf (new)\">#820</a>, really now</p>" |
||||
}, |
||||
"createdAt": "2015-08-13T11:04:24+00:00" |
||||
} |
||||
] |
||||
} |
||||
} |
@ -0,0 +1,25 @@ |
||||
{ |
||||
"_type": "Revision", |
||||
"_links": { |
||||
"self": { |
||||
"href": "/api/v3/revisions/2355" |
||||
}, |
||||
"project": { |
||||
"href": "/api/v3/projects/6", |
||||
"title": "subrepos1" |
||||
}, |
||||
"showRevision": { |
||||
"href": "/projects/subrepos1/repository/revision/1cb824244ccb839bfce5a463a58b108cf8fbd4da" |
||||
} |
||||
}, |
||||
"id": 2355, |
||||
"identifier": "1cb824244ccb839bfce5a463a58b108cf8fbd4da", |
||||
"formattedIdentifier": "1cb82424", |
||||
"authorName": "Oliver Günther ", |
||||
"message": { |
||||
"format": "plain", |
||||
"raw": "Awesome commit\n\nTotally references #819, really now.", |
||||
"html": "<p>This does something</p>\n\n<p>Totally references <a href=\"/work_packages/819\" class=\"issue work_package status-1 priority-2 created-by-me\" title=\"asdf (new)\">#819</a>, really now</p>" |
||||
}, |
||||
"createdAt": "2015-08-13T11:04:24+00:00" |
||||
} |
@ -0,0 +1,25 @@ |
||||
{ |
||||
"_type": "Revision", |
||||
"_links": { |
||||
"self": { |
||||
"href": "/api/v3/revisions/2" |
||||
}, |
||||
"project": { |
||||
"href": "/api/v3/projects/1", |
||||
"title": "Seeded Project" |
||||
}, |
||||
"showRevision": { |
||||
"href": "/projects/subrepos1/repository/revision/1ea7d580" |
||||
} |
||||
}, |
||||
"id": 2, |
||||
"identifier": "1ea7d580a323f6267752347ef4b23c120445196e", |
||||
"formattedIdentifier": "1ea7d580", |
||||
"authorName": "Oliver G\u00fcnther ", |
||||
"message": { |
||||
"format": "plain", |
||||
"raw": "Totally references #81", |
||||
"html": "<p>Totally references <a href=\"/work_packages/819\" class=\"issue work_package status-1 priority-5 parent created-by-me\" title=\"veritatis voluptas hic qui praesentium tempora illum omnis (new)\">#81</a></p>" |
||||
}, |
||||
"createdAt": "2015-08-07T06:22:49+00:00" |
||||
} |
@ -0,0 +1,52 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
var expect = require('../../../spec_helper.js').expect, |
||||
detailsPaneHelper = require('./details-pane-helper.js'), |
||||
elements = detailsPaneHelper.elements; |
||||
|
||||
/*jshint expr: true*/ |
||||
|
||||
describe('OpenProject', function() { |
||||
describe('activity pane with revisions', function() { |
||||
beforeEach(function() { |
||||
detailsPaneHelper.loadPane(820, 'activity'); |
||||
}); |
||||
|
||||
it('should render all activities and one revision', function() { |
||||
var locator = by.css('.work-package-details-activities-activity'); |
||||
elements.count(locator, 61); |
||||
}); |
||||
|
||||
it('should render one revision at the correct position', function() { |
||||
expect( |
||||
$('.work-package-details-activities-activity:nth-of-type(61) .date').getText() |
||||
).to.eventually.contain('committed revision 1cb82424'); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,133 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See doc/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
/*jshint expr: true*/ |
||||
|
||||
describe('revisionActivity Directive', function() { |
||||
var compile, element, rootScope, scope; |
||||
|
||||
beforeEach(angular.mock.module('openproject.workPackages.activities')); |
||||
beforeEach(function() { |
||||
module( |
||||
'ng-context-menu', |
||||
'openproject.api', |
||||
'openproject.workPackages', |
||||
'openproject.models', |
||||
'openproject.services', |
||||
'openproject.config', |
||||
'openproject.templates' |
||||
); |
||||
}); |
||||
|
||||
beforeEach(inject(function($rootScope, $compile) { |
||||
var html; |
||||
html = '<div exclusive-edit class="exclusive-edit"><revision-activity work-package="workPackage" activity="activity" activity-no="activityNo" is-initial="isInitial"></revision-activity></div>'; |
||||
|
||||
rootScope = $rootScope; |
||||
scope = $rootScope.$new(); |
||||
|
||||
compile = function() { |
||||
element = angular.element(html); |
||||
$compile(element)(scope); |
||||
scope.$digest(); |
||||
}; |
||||
})); |
||||
|
||||
describe('with a valid revision', function(){ |
||||
beforeEach(function() { |
||||
scope.workPackage = { |
||||
links: { |
||||
revisions: true |
||||
}, |
||||
embedded: { } |
||||
}; |
||||
scope.activity = { |
||||
links: { |
||||
showRevision: '/project/foo/repository/revision/1234', |
||||
}, |
||||
props: { |
||||
'id': 1, |
||||
'identifier': '11f4b07dff4f4ce9548a52b7d002daca7cd63ec6', |
||||
'formattedIdentifier': '11f4b07', |
||||
'authorName': 'some developer', |
||||
'message': { |
||||
'format': 'plain', |
||||
'raw': 'This revision provides new features\n\nAn elaborate description', |
||||
'html': '<p>This revision provides new features<br><br>An elaborate description</p>' |
||||
}, |
||||
'createdAt': '2015-07-21T13:36:59Z' |
||||
} |
||||
}; |
||||
compile(); |
||||
}); |
||||
|
||||
it('should not render an image', function() { |
||||
expect(element.find('.avatar')).to.have.length(0); |
||||
}); |
||||
|
||||
it('should have the author name, but no link', function() { |
||||
expect(element.find('.user').html()).to.equal('some developer'); |
||||
expect(element.find('.user > a')).to.have.length(0); |
||||
}); |
||||
|
||||
describe('with linked author', function() { |
||||
beforeEach(function() { |
||||
scope.activity.links.author = { |
||||
fetch: function() { |
||||
return { |
||||
then: function(cb) { |
||||
cb({ |
||||
props: { |
||||
id: 1, |
||||
name: 'Some Dude', |
||||
avatar: 'avatar.png', |
||||
status: 'active' |
||||
} |
||||
}); |
||||
} |
||||
}; |
||||
} |
||||
}; |
||||
compile(); |
||||
}); |
||||
|
||||
it('should render a user profile', function() { |
||||
expect(element.find('.avatar').attr('alt')).to.equal('Avatar'); |
||||
expect(element.find('span.user > a').text()).to.equal('Some Dude'); |
||||
}); |
||||
}); |
||||
|
||||
describe('message', function() { |
||||
it('should render commit message', function() { |
||||
var message = element.find('span.user-comment > span.message').html(); |
||||
|
||||
expect(message).to.eq(scope.activity.props.message.html); |
||||
}); |
||||
}); |
||||
}); |
||||
}); |
Loading…
Reference in new issue