launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #27304
[Merge] ~ilasc/launchpad:add-delete-comment-revision-ui into launchpad:master
Ioana Lasc has proposed merging ~ilasc/launchpad:add-delete-comment-revision-ui into launchpad:master.
Commit message:
Add delete comment revision capability
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~ilasc/launchpad/+git/launchpad/+merge/406151
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~ilasc/launchpad:add-delete-comment-revision-ui into launchpad:master.
diff --git a/lib/canonical/launchpad/icing/css/base.scss b/lib/canonical/launchpad/icing/css/base.scss
index 1e33ca7..086e64d 100644
--- a/lib/canonical/launchpad/icing/css/base.scss
+++ b/lib/canonical/launchpad/icing/css/base.scss
@@ -625,6 +625,13 @@ body {
padding-left: 20px;
padding-bottom: 10px;
}
+
+ // If the content was deleted, we show a default message with
+ // this CSS class.
+ .deleted-content {
+ padding: 5px;
+ opacity: 50%;
+ }
}
.active {
diff --git a/lib/lp/answers/templates/questionmessage-display.pt b/lib/lp/answers/templates/questionmessage-display.pt
index 49973ab..f9014a9 100644
--- a/lib/lp/answers/templates/questionmessage-display.pt
+++ b/lib/lp/answers/templates/questionmessage-display.pt
@@ -8,7 +8,8 @@
tal:define="css_classes view/getBoardCommentCSSClass"
tal:attributes="class string:${css_classes};
id string:comment-${context/index};
- data-baseurl context/fmt:url">
+ data-baseurl context/fmt:url;
+ data-i-can-edit view/can_edit">
<div class="boardCommentDetails">
<table>
<tbody>
@@ -23,6 +24,9 @@
<script type="text/template">
<div class='message-revision-item'>
<div class='message-revision-title'>
+ <a class="sprite remove action-icon message-revision-del-btn">
+ Remove
+ </a>
<a class="js-action">
Revision #{revision}, created at {date_created_display}
</a>
diff --git a/lib/lp/services/messages/javascript/messages.edit.js b/lib/lp/services/messages/javascript/messages.edit.js
index 56762e8..1da3dbd 100644
--- a/lib/lp/services/messages/javascript/messages.edit.js
+++ b/lib/lp/services/messages/javascript/messages.edit.js
@@ -7,6 +7,7 @@
* - A div container with the class .editable-message containing everything
* else related to the message
* - A data-baseurl="/path/to/msg" on the .editable-message container
+ * - A data-i-can-edit="True|False" on the .editable-message container
* - A .editable-message-body container with the original msg content
* - A .editable-message-edit-btn element inside the main container, that will
* switch the view to edit form when clicked.
@@ -39,6 +40,20 @@ YUI.add('lp.services.messages.edit', function(Y) {
"Please try again in a few minutes."
);
+ module.confirm_delete_revision_msg = (
+ "Are you sure you want to delete this revision content?");
+
+ module.deleted_content_msg = (
+ "<span class='deleted-content'>" +
+ " Content deleted by the user." +
+ "</span>"
+ );
+
+ // Making it easier to mock on tests.
+ module.confirm = function(msg) {
+ return confirm(msg);
+ };
+
module.htmlify_msg = function(text) {
text = text.replace(/&/g, "&");
text = text.replace(/</g, "<");
@@ -182,6 +197,7 @@ YUI.add('lp.services.messages.edit', function(Y) {
module.fillMessageRevisions = function(elements, revisions) {
// Position the message revision list element.
revisions = revisions.reverse();
+ var i_can_edit = elements.container.getData('i-can-edit') === "True";
var revisions_container = elements.container.one(
".message-revision-container");
var last_edit_el = elements.last_edit.getDOMNode();
@@ -198,14 +214,26 @@ YUI.add('lp.services.messages.edit', function(Y) {
revisions_container.setStyle('display', 'none');
});
- var content = "";
+ nodes_holder.getDOMNode().innerHTML = "";
revisions.forEach(function(rev) {
var attrs = rev.getAttrs();
- attrs.content = module.htmlify_msg(attrs.content);
- content += Y.Lang.sub(template, attrs);
+ if (!attrs.date_deleted) {
+ attrs.content = module.htmlify_msg(attrs.content);
+ }
+ else {
+ attrs.content = module.deleted_content_msg;
+ }
+ var node = Y.DOM.create(Y.Lang.sub(template, attrs));
+ node.dataset['revision_url'] = attrs.self_link;
+ nodes_holder.appendChild(node);
+
+ if(attrs.date_deleted || !i_can_edit) {
+ // If it was already deleted or I don't have permission to
+ // delete it, remove the "delete button".
+ module.removeDeleteRevisionButton(Y.Node(node));
+ }
});
- nodes_holder.getDOMNode().innerHTML = content;
nodes_holder.all(".message-revision-item").each(function(rev_item) {
rev_item.one(".message-revision-title").on('click', function() {
nodes_holder.all('.message-revision-body').setStyle(
@@ -218,9 +246,44 @@ YUI.add('lp.services.messages.edit', function(Y) {
'active');
rev_item.addClass('active');
});
+
+ var delete_btn = rev_item.one(".message-revision-del-btn");
+ if (delete_btn) {
+ delete_btn.on('click', function() {
+ module.deleteMessageRevisionContent(rev_item);
+ });
+ }
});
};
+ module.removeDeleteRevisionButton = function(rev_item_node) {
+ var delete_btn = rev_item_node.one('.message-revision-del-btn');
+ if (delete_btn) {
+ var node_to_remove = delete_btn.getDOMNode();
+ node_to_remove.parentNode.removeChild(node_to_remove);
+ }
+ };
+
+ module.deleteMessageRevisionContent = function(rev_item) {
+ var revision_url = rev_item.getData('revision_url');
+ if (module.confirm(module.confirm_delete_revision_msg)) {
+ var config = {
+ on: {
+ success: function() {
+ var body_dom = rev_item.one(
+ '.message-revision-body').getDOMNode();
+ body_dom.innerHTML = module.deleted_content_msg;
+ module.removeDeleteRevisionButton(rev_item);
+ },
+ failure: function(err) {
+ alert("There was an error. Please try again.");
+ }
+ }
+ };
+ this.lp_client.named_post(revision_url, 'deleteContent', config);
+ }
+ };
+
module.onLastEditClick = function(elements, baseurl) {
// Hide all open revision containers.
Y.all('.message-revision-container').each(function(container) {
diff --git a/lib/lp/services/messages/javascript/tests/test_messages.edit.html b/lib/lp/services/messages/javascript/tests/test_messages.edit.html
index 9d394c2..c2a38d1 100644
--- a/lib/lp/services/messages/javascript/tests/test_messages.edit.html
+++ b/lib/lp/services/messages/javascript/tests/test_messages.edit.html
@@ -54,7 +54,7 @@ GNU Affero General Public License version 3 (see the file LICENSE).
<!-- First editable message -->
<div class="editable-message" id="first-message"
- data-baseurl="/message/1">
+ data-baseurl="/message/1" data-i-can-edit="True">
<!-- Revision list container and its template -->
<div class="message-revision-container">
<!-- The revision list pop-up header, with the image that closes
@@ -74,6 +74,9 @@ GNU Affero General Public License version 3 (see the file LICENSE).
<!-- The description of the revision, that will expand the
revision content once clicked. -->
<div class='message-revision-title'>
+ <a class="sprite remove action-icon message-revision-del-btn">
+ Remove
+ </a>
<a class="js-action">Revision #{revision}, created at {date_created_display}</a>
</div>
<!-- The revision content itself -->
@@ -108,7 +111,7 @@ GNU Affero General Public License version 3 (see the file LICENSE).
<!-- Second editable message -->
<div class="editable-message" id="second-message"
- data-baseurl="/message/2">
+ data-baseurl="/message/2" data-i-can-edit="True">
<!-- Revision list container and its template -->
<div class="message-revision-container">
<div class="message-revision-container-header">
@@ -119,6 +122,9 @@ GNU Affero General Public License version 3 (see the file LICENSE).
<script type="text/template">
<div class='message-revision-item'>
<div class='message-revision-title'>
+ <a class="sprite remove action-icon message-revision-del-btn">
+ Remove
+ </a>
<a class="js-action">Revision #{revision}, created at {date_created_display}</a>
</div>
<div class='message-revision-body'>{content}</div>
diff --git a/lib/lp/services/messages/javascript/tests/test_messages.edit.js b/lib/lp/services/messages/javascript/tests/test_messages.edit.js
index d9644f0..e3b4d54 100644
--- a/lib/lp/services/messages/javascript/tests/test_messages.edit.js
+++ b/lib/lp/services/messages/javascript/tests/test_messages.edit.js
@@ -78,11 +78,11 @@ YUI.add('lp.services.messages.edit.test', function(Y) {
this.msg_bodies[i].setStyle('display', '');
this.msg_forms[i].setStyle('display', '');
this.textareas[i].getDOMNode().value = '';
- this.last_edit[0].getDOMNode().innerHTML = ':';
- this.last_edit[1].getDOMNode().innerHTML = (
- '(last edit 5 minutes ago):');
this.revision_history_lists[i].getDOMNode().innerHTML = '';
}
+ this.last_edit[0].getDOMNode().innerHTML = ':';
+ this.last_edit[1].getDOMNode().innerHTML = (
+ '(last edit 5 minutes ago):');
},
test_instantiation_hides_forms: function() {
@@ -219,24 +219,65 @@ YUI.add('lp.services.messages.edit.test', function(Y) {
var title = rev.one('.message-revision-title');
var body = rev.one('.message-revision-body');
var expected_title = Y.Lang.sub(
- '<a class="js-action">' +
- 'Revision #{revision}, created at {date_created_display}' +
- '</a>',
+ 'Remove Revision #{revision},'+
+ ' created at {date_created_display}',
entry);
- Y.Assert.areSame(
- expected_title, title.getDOMNode().innerHTML.trim());
+ Y.Assert.areEqual(
+ expected_title, title.getDOMNode().innerText);
+
Y.Assert.areSame(
module.htmlify_msg(entry.content),
body.getDOMNode().innerHTML);
});
- // Lets make sure that a click on the "close" button hides the
- // revisions list.
- revisions_container.one(
- '.message-revision-close').simulate('click');
- Y.Assert.areSame('none', revisions_container.getStyle('display'));
- }
+ revisions = this.revision_history_lists[1].all(
+ ".message-revision-item");
+ Y.Assert.areSame(2, revisions.size());
+ // Delete one revision from the revision list of
+ // the second message
+ revisions.each(function(rev, j) {
+ var entry = response.entries[response.entries.length - j -1];
+ var title = rev.one('.message-revision-title');
+ var body = rev.one('.message-revision-body');
+
+ if (j===0){
+ // mock user's response to modal widonw that is
+ // asking the confirmation to delete revision
+ module.confirm = function(){
+ return 'True';
+ };
+ // user clicks on the Remove icon for the revision
+ rev.one('.message-revision-del-btn').simulate('click');
+ module.lp_client.io_provider.success({
+ responseText: 'null',
+ responseHeaders: {'Content-Type': 'application/json'}
+ });
+
+ // the title displayed for the revision stays the same
+ var expected_title = Y.Lang.sub(
+ 'Revision #{revision},' +
+ ' created at {date_created_display}',
+ entry);
+ Y.Assert.areSame(
+ expected_title,
+ title.getDOMNode().innerText);
+
+ // the content has changed to reflect deletion
+ var expected_body = Y.Lang.sub(
+ 'Content deleted by the user.',
+ entry);
+ Y.Assert.areEqual(
+ expected_body, body.getDOMNode().innerText);
+ }
+ });
+ // The number of revisions in the list stays the same
+ // and we asserted above the content displayed has changed
+ // to reflect deletion for revision 2
+ var after_delete_revis = this.revision_history_lists[1].all(
+ ".message-revision-item");
+ Y.Assert.areSame(2, after_delete_revis.size());
+ }
};
suite.add(new Y.Test.Case(TestMessageEdit));
Follow ups