Merge ~pappacena/launchpad:delete-message-revision-ui into launchpad:master

Proposed by Thiago F. Pappacena
Status: Needs review
Proposed branch: ~pappacena/launchpad:delete-message-revision-ui
Merge into: launchpad:master
Diff against target: 161 lines (+79/-5)
3 files modified
lib/canonical/launchpad/icing/css/base.scss (+7/-0)
lib/lp/answers/templates/questionmessage-display.pt (+5/-1)
lib/lp/services/messages/javascript/messages.edit.js (+67/-4)
Reviewer Review Type Date Requested Status
Launchpad code reviewers Pending
Review via email: mp+403471@code.launchpad.net

Commit message

Allowing users to delete message revision history

To post a comment you must log in.
Revision history for this message
Thiago F. Pappacena (pappacena) wrote (last edit ):

We are missing some tests (and applying the <a> tag to bug comments and code review), but this works fine the way it is on question messages.

Unmerged commits

6546c93... by Thiago F. Pappacena

Allowing users to delete message revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lib/canonical/launchpad/icing/css/base.scss b/lib/canonical/launchpad/icing/css/base.scss
index 1e33ca7..cff195c 100644
--- a/lib/canonical/launchpad/icing/css/base.scss
+++ b/lib/canonical/launchpad/icing/css/base.scss
@@ -624,6 +624,13 @@ body {
624 display: none;624 display: none;
625 padding-left: 20px;625 padding-left: 20px;
626 padding-bottom: 10px;626 padding-bottom: 10px;
627
628 // If the content was deleted, we show a default message with
629 // this CSS class.
630 .deleted-content {
631 padding: 5px;
632 opacity: 50%;
633 }
627 }634 }
628 }635 }
629636
diff --git a/lib/lp/answers/templates/questionmessage-display.pt b/lib/lp/answers/templates/questionmessage-display.pt
index c1ed29a..346f11b 100644
--- a/lib/lp/answers/templates/questionmessage-display.pt
+++ b/lib/lp/answers/templates/questionmessage-display.pt
@@ -8,7 +8,8 @@
8 tal:define="css_classes view/getBoardCommentCSSClass"8 tal:define="css_classes view/getBoardCommentCSSClass"
9 tal:attributes="class string:${css_classes};9 tal:attributes="class string:${css_classes};
10 id string:comment-${context/index};10 id string:comment-${context/index};
11 data-baseurl context/fmt:url">11 data-baseurl context/fmt:url;
12 data-i-can-edit view/can_edit">
12 <div class="boardCommentDetails">13 <div class="boardCommentDetails">
13 <table>14 <table>
14 <tbody>15 <tbody>
@@ -23,6 +24,9 @@
23 <script type="text/template">24 <script type="text/template">
24 <div class='message-revision-item'>25 <div class='message-revision-item'>
25 <div class='message-revision-title'>26 <div class='message-revision-title'>
27 <a class="sprite remove action-icon message-revision-del-btn">
28 Remove
29 </a>
26 <a class="js-action">30 <a class="js-action">
27 Revision #{revision}, created at {date_created}31 Revision #{revision}, created at {date_created}
28 </a>32 </a>
diff --git a/lib/lp/services/messages/javascript/messages.edit.js b/lib/lp/services/messages/javascript/messages.edit.js
index c6e79b6..5c565bd 100644
--- a/lib/lp/services/messages/javascript/messages.edit.js
+++ b/lib/lp/services/messages/javascript/messages.edit.js
@@ -7,6 +7,7 @@
7 * - A div container with the class .editable-message containing everything7 * - A div container with the class .editable-message containing everything
8 * else related to the message8 * else related to the message
9 * - A data-baseurl="/path/to/msg" on the .editable-message container9 * - A data-baseurl="/path/to/msg" on the .editable-message container
10 * - A data-i-can-edit="True|False" on the .editable-message container
10 * - A .editable-message-body container with the original msg content11 * - A .editable-message-body container with the original msg content
11 * - A .editable-message-edit-btn element inside the main container, that will12 * - A .editable-message-edit-btn element inside the main container, that will
12 * switch the view to edit form when clicked.13 * switch the view to edit form when clicked.
@@ -39,6 +40,20 @@ YUI.add('lp.services.messages.edit', function(Y) {
39 "Please try again in a few minutes."40 "Please try again in a few minutes."
40 );41 );
4142
43 module.confirm_delete_revision_msg = (
44 "Are you sure you want to delete this revision content?");
45
46 module.deleted_content_msg = (
47 "<span class='deleted-content'>" +
48 " Content deleted by the user." +
49 "</span>"
50 );
51
52 // Making it easier to mock on tests.
53 module.confirm = function(msg) {
54 return confirm(msg)
55 };
56
42 module.htmlify_msg = function(text) {57 module.htmlify_msg = function(text) {
43 text = text.replace(/&/g, "&amp;");58 text = text.replace(/&/g, "&amp;");
44 text = text.replace(/</g, "&lt;");59 text = text.replace(/</g, "&lt;");
@@ -182,6 +197,7 @@ YUI.add('lp.services.messages.edit', function(Y) {
182 module.fillMessageRevisions = function(elements, revisions) {197 module.fillMessageRevisions = function(elements, revisions) {
183 // Position the message revision list element.198 // Position the message revision list element.
184 revisions = revisions.reverse();199 revisions = revisions.reverse();
200 var i_can_edit = elements.container.getData('i-can-edit') === "True";
185 var revisions_container = elements.container.one(201 var revisions_container = elements.container.one(
186 ".message-revision-container");202 ".message-revision-container");
187 var last_edit_el = elements.last_edit.getDOMNode();203 var last_edit_el = elements.last_edit.getDOMNode();
@@ -198,16 +214,28 @@ YUI.add('lp.services.messages.edit', function(Y) {
198 revisions_container.setStyle('display', 'none');214 revisions_container.setStyle('display', 'none');
199 });215 });
200216
201 var content = "";217 nodes_holder.getDOMNode().innerHTML = "";
202 revisions.forEach(function(rev) {218 revisions.forEach(function(rev) {
203 var attrs = rev.getAttrs();219 var attrs = rev.getAttrs();
204 var date_created = new Date(attrs.date_created);220 var date_created = new Date(attrs.date_created);
205 attrs.date_created = date_created.toLocaleString();221 attrs.date_created = date_created.toLocaleString();
206 attrs.content = module.htmlify_msg(attrs.content);222 if (!attrs.date_deleted) {
207 content += Y.Lang.sub(template, attrs);223 attrs.content = module.htmlify_msg(attrs.content);
224 }
225 else {
226 attrs.content = module.deleted_content_msg;
227 }
228 var node = Y.DOM.create(Y.Lang.sub(template, attrs));
229 node.dataset['revision_url'] = attrs.self_link;
230 nodes_holder.appendChild(node);
231
232 if(attrs.date_deleted || !i_can_edit) {
233 // If it was already deleted or I don't have permission to
234 // delete it, remove the "delete button".
235 module.removeDeleteRevisionButton(Y.Node(node));
236 }
208 });237 });
209238
210 nodes_holder.getDOMNode().innerHTML = content;
211 nodes_holder.all(".message-revision-item").each(function(rev_item) {239 nodes_holder.all(".message-revision-item").each(function(rev_item) {
212 rev_item.one(".message-revision-title").on('click', function() {240 rev_item.one(".message-revision-title").on('click', function() {
213 nodes_holder.all('.message-revision-body').setStyle(241 nodes_holder.all('.message-revision-body').setStyle(
@@ -220,9 +248,44 @@ YUI.add('lp.services.messages.edit', function(Y) {
220 'active');248 'active');
221 rev_item.addClass('active');249 rev_item.addClass('active');
222 });250 });
251
252 var delete_btn = rev_item.one(".message-revision-del-btn");
253 if (delete_btn) {
254 delete_btn.on('click', function() {
255 module.deleteMessageRevisionContent(rev_item);
256 });
257 }
223 });258 });
224 };259 };
225260
261 module.removeDeleteRevisionButton = function(rev_item_node) {
262 var delete_btn = rev_item_node.one('.message-revision-del-btn');
263 if (delete_btn) {
264 var node_to_remove = delete_btn.getDOMNode();
265 node_to_remove.parentNode.removeChild(node_to_remove);
266 }
267 };
268
269 module.deleteMessageRevisionContent = function(rev_item) {
270 var revision_url = rev_item.getData('revision_url');
271 if (module.confirm(module.confirm_delete_revision_msg)) {
272 var config = {
273 on: {
274 success: function() {
275 var body_dom = rev_item.one(
276 '.message-revision-body').getDOMNode();
277 body_dom.innerHTML = module.deleted_content_msg;
278 module.removeDeleteRevisionButton(rev_item);
279 },
280 failure: function(err) {
281 alert("There was an error. Please try again.");
282 }
283 }
284 };
285 this.lp_client.named_post(revision_url, 'deleteContent', config);
286 }
287 };
288
226 module.onLastEditClick = function(elements, baseurl) {289 module.onLastEditClick = function(elements, baseurl) {
227 // Hide all open revision containers.290 // Hide all open revision containers.
228 Y.all('.message-revision-container').each(function(container) {291 Y.all('.message-revision-container').each(function(container) {