WIP quoting and editing of comments. not working!

pull/1619/head
Richard 10 years ago
parent b02d01550b
commit 5820a8e470
  1. 2
      app/assets/javascripts/angular/directives/components/authoring-directive.js
  2. 14
      app/assets/javascripts/angular/helpers/components/path-helper.js
  3. 19
      app/assets/javascripts/angular/services/activity-service.js
  4. 43
      app/assets/javascripts/angular/work_packages/tabs/editable-comment-directive.js
  5. 34
      app/assets/javascripts/angular/work_packages/tabs/user-activity-directive.js
  6. 5
      public/templates/work_packages/tabs/_editable_comment.html
  7. 10
      public/templates/work_packages/tabs/_user_activity.html
  8. 3
      public/templates/work_packages/tabs/activity.html

@ -46,7 +46,7 @@ angular.module('openproject.uiComponents')
scope.authorLink = '<a href="'+ PathHelper.userPath(scope.author.id) + '">' + scope.author.name + '</a>'; scope.authorLink = '<a href="'+ PathHelper.userPath(scope.author.id) + '">' + scope.author.name + '</a>';
if (scope.activity) { if (scope.activity) {
scope.timestamp = '<a title="' + time + '" href="' + PathHelper.activityPath(scope.project, createdOn.format('YYYY-MM-DD')) + '">' + timeago + '</a>'; scope.timestamp = '<a title="' + time + '" href="' + PathHelper.activityFromPath(scope.project, createdOn.format('YYYY-MM-DD')) + '">' + timeago + '</a>';
} else { } else {
scope.timestamp = '<span class="timestamp" title="' + time + '">' + timeago + '</span>'; scope.timestamp = '<span class="timestamp" title="' + time + '">' + timeago + '</span>';
} }

@ -36,7 +36,19 @@ angular.module('openproject.helpers')
apiV3: '/api/v3', apiV3: '/api/v3',
staticBase: window.appBasePath ? window.appBasePath : '', staticBase: window.appBasePath ? window.appBasePath : '',
activityPath: function(projectIdentifier, from) { activityPath: function(activityId) {
return 'activities/' + activityId;
},
activitiesPath: function(workPackageId) {
var path = '';
if(workPackageId) {
path = '/work_packages/' + workPackageId;
}
path = path + '/activities';
return path;
},
activityFromPath: function(projectIdentifier, from) {
var link = '/activity'; var link = '/activity';
if (projectIdentifier) { if (projectIdentifier) {

@ -34,7 +34,7 @@ angular.module('openproject.services')
var ActivityService = { var ActivityService = {
createComment: function(workPackageId, activities, descending, comment) { createComment: function(workPackageId, activities, descending, comment) {
var resource = HALAPIResource.setup("work_packages/" + workPackageId + "/activities"); var resource = HALAPIResource.setup(PathHelper.activitiesPath(workPackageId));
var options = { var options = {
ajax: { ajax: {
method: "POST", method: "POST",
@ -53,6 +53,23 @@ angular.module('openproject.services')
return activity; return activity;
} }
}); });
},
updateComment: function(activityId, comment) {
var resource = HALAPIResource.setup(PathHelper.activityPath(activityId));
var options = {
ajax: {
method: "PUT",
data: { comment: comment }
}
};
return resource.fetch(options).then(function(activity){
// We are unable to add to the work package's embedded activities directly
if(activity) {
// Might have to just reload the work package here ala Till
}
});
} }
} }

@ -0,0 +1,43 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.directives')
.directive('editableComment', [function(){
return {
restrict: 'A',
scope: {
activity: '=',
commentInEdit: '='
},
templateUrl: '/templates/work_packages/tabs/_editable_comment.html',
link: function(scope){
}
};
}]);

@ -28,7 +28,7 @@
angular.module('openproject.workPackages.tabs') angular.module('openproject.workPackages.tabs')
.directive('userActivity', ['I18n', 'PathHelper', function(I18n, PathHelper) { .directive('userActivity', ['I18n', 'PathHelper', 'ActivityService', function(I18n, PathHelper, ActivityService) {
return { return {
restrict: 'E', restrict: 'E',
replace: true, replace: true,
@ -36,17 +36,45 @@ angular.module('openproject.workPackages.tabs')
scope: { scope: {
activity: '=', activity: '=',
currentAnchor: '=', currentAnchor: '=',
activityNo: '=' activityNo: '=',
inputElementId: '='
}, },
link: function(scope) { link: function(scope, element) {
scope.I18n = I18n; scope.I18n = I18n;
scope.userPath = PathHelper.staticUserPath; scope.userPath = PathHelper.staticUserPath;
scope.inEdit = false;
scope.activity.links.user.fetch().then(function(user) { scope.activity.links.user.fetch().then(function(user) {
scope.userId = user.props.id; scope.userId = user.props.id;
scope.userName = user.props.name; scope.userName = user.props.name;
scope.userAvatar = user.props.avatar; scope.userAvatar = user.props.avatar;
}); });
scope.editComment = function() {
scope.inEdit = true;
};
scope.cancelEdit = function() {
scope.inEdit = false;
};
scope.quoteComment = function() {
angular.element('#' + scope.inputElementId).val(quotedText(scope.activity.props.rawComment));
};
scope.updateComment = function(comment) {
ActivityService.updateComment(scope.activity.props.id, comment).then(function(activity){
});
};
// TODO RS: Move this into WorkPackageDetailsHepler once it has been merge in from attachments branch
function quotedText(rawComment) {
quoted = rawComment.split("\n")
.map(function(line){ return "\n> " + line; })
.join('');
return scope.userName + " wrote:" + quoted;
}
} }
}; };
}]); }]);

@ -0,0 +1,5 @@
<span class="message"
ng-show="activity.props._type == 'Activity::Comment'"
ng-bind-html="activity.props.comment"/>
<textarea ng-if="commentInEdit = activity.props.id" id="edit-comment-text"></textarea>

@ -1,13 +1,21 @@
<div class="work-package-details-activities-activity-contents"> <div class="work-package-details-activities-activity-contents">
<div class="comments-number"><a ng-href="#{{ currentAnchor }}" ng-bind="'#' + activityNo"></a> <div class="comments-number"><a ng-href="#{{ currentAnchor }}" ng-bind="'#' + activityNo"></a>
<div class="comments-icons"><i class="icon-quote" ng-click="quoteComment()"></i><i class="icon-edit" ng-click="editComment()"></i></div>
</div> </div>
<img class="avatar" ng-src="{{ userAvatar }}" /> <img class="avatar" ng-src="{{ userAvatar }}" />
<span class="user"><a ng-href="{{ userPath(userId) }}" name="{{ currentAnchor }}" ng-bind="userName"></a></span> <span class="user"><a ng-href="{{ userPath(userId) }}" name="{{ currentAnchor }}" ng-bind="userName"></a></span>
<span class="date">{{ I18n.t('js.label_commented_on') }} <span ng-bind="activity.props.createdAt | date:'short'"/></span> <span class="date">{{ I18n.t('js.label_commented_on') }} <span ng-bind="activity.props.createdAt | date:'short'"/></span>
<span class="comment wiki"> <span class="comment wiki">
<span class="message" <span ng-if="!inEdit"
class="message"
ng-show="activity.props._type == 'Activity::Comment'" ng-show="activity.props._type == 'Activity::Comment'"
ng-bind-html="activity.props.comment"/> ng-bind-html="activity.props.comment"/>
<div ng-if="inEdit">
<textarea id="edit-comment-text"
ng-bind-html="activity.props.rawComment"></textarea>
<button class="button" ng-click="updateComment()">{{ I18n.t('js.button_update') }}</button>
<span><a href="" ng-click="cancelEdit()">cancel</span>
</div>
<ul class="work-package-details-activities-messages"> <ul class="work-package-details-activities-messages">
<li ng-repeat="detail in activity.props.htmlDetails track by $index"> <li ng-repeat="detail in activity.props.htmlDetails track by $index">
<span class="message" ng-bind-html="detail"/> <span class="message" ng-bind-html="detail"/>

@ -11,7 +11,8 @@
ng-bind="currentDate"/> ng-bind="currentDate"/>
<user-activity activity="activity" <user-activity activity="activity"
activity-no="activityNo" activity-no="activityNo"
current-anchor="currentAnchor"> current-anchor="currentAnchor"
input-element-id="'add-comment-text'">
</user-activity> </user-activity>
</li> </li>
</ul> </ul>

Loading…
Cancel
Save