UI for comments deletion by admins
This change depends on API implemented in Change 105052. Feature: Issue 4644 Change-Id: I91137aaa69eef419e08c8a568cef9350d8a1448b
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<!--
|
||||
Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../shared/gr-confirm-dialog/gr-confirm-dialog.html">
|
||||
|
||||
<dom-module id="gr-confirm-delete-comment-dialog">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
:host([disabled]) {
|
||||
opacity: .5;
|
||||
pointer-events: none;
|
||||
}
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
label {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
iron-autogrow-textarea {
|
||||
font-family: var(--monospace-font-family);
|
||||
padding: 0;
|
||||
width: 73ch; /* Add a char to account for the border. */
|
||||
|
||||
--iron-autogrow-textarea {
|
||||
border: 1px solid #ddd;
|
||||
font-family: var(--monospace-font-family);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<gr-confirm-dialog
|
||||
confirm-label="Delete"
|
||||
on-confirm="_handleConfirmTap"
|
||||
on-cancel="_handleCancelTap">
|
||||
<div class="header">Delete Comment</div>
|
||||
<div class="main">
|
||||
<label for="messageInput">Enter comment delete reason</label>
|
||||
<iron-autogrow-textarea
|
||||
id="messageInput"
|
||||
class="message"
|
||||
autocomplete="on"
|
||||
placeholder="<Insert reasoning here>"
|
||||
bind-value="{{message}}"></iron-autogrow-textarea>
|
||||
</div>
|
||||
</gr-confirm-dialog>
|
||||
</template>
|
||||
<script src="gr-confirm-delete-comment-dialog.js"></script>
|
||||
</dom-module>
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
Polymer({
|
||||
is: 'gr-confirm-delete-comment-dialog',
|
||||
|
||||
/**
|
||||
* Fired when the confirm button is pressed.
|
||||
*
|
||||
* @event confirm
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the cancel button is pressed.
|
||||
*
|
||||
* @event cancel
|
||||
*/
|
||||
|
||||
properties: {
|
||||
message: String,
|
||||
},
|
||||
|
||||
resetFocus: function() {
|
||||
this.$.messageInput.textarea.focus();
|
||||
},
|
||||
|
||||
_handleConfirmTap: function(e) {
|
||||
e.preventDefault();
|
||||
this.fire('confirm', {reason: this.message}, {bubbles: false});
|
||||
},
|
||||
|
||||
_handleCancelTap: function(e) {
|
||||
e.preventDefault();
|
||||
this.fire('cancel', null, {bubbles: false});
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -19,10 +19,13 @@ limitations under the License.
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
|
||||
<link rel="import" href="../../shared/gr-formatted-text/gr-formatted-text.html">
|
||||
<link rel="import" href="../../shared/gr-storage/gr-storage.html">
|
||||
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../../shared/gr-storage/gr-storage.html">
|
||||
<link rel="import" href="../../shared/gr-tooltip-content/gr-tooltip-content.html">
|
||||
<link rel="import" href="../gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.html">
|
||||
|
||||
<script src="../../../scripts/rootElement.js"></script>
|
||||
|
||||
<dom-module id="gr-diff-comment">
|
||||
<template>
|
||||
@@ -72,6 +75,8 @@ limitations under the License.
|
||||
.date {
|
||||
justify-content: flex-end;
|
||||
margin-left: 5px;
|
||||
min-width: 4.5em;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
a.date:link,
|
||||
@@ -177,6 +182,15 @@ limitations under the License.
|
||||
color: #333;
|
||||
font-size: 12px;
|
||||
}
|
||||
gr-confirm-dialog .main {
|
||||
background-color: #fef;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
#deleteBtn {
|
||||
margin-top: .5em;
|
||||
}
|
||||
</style>
|
||||
<div id="container"
|
||||
class="container"
|
||||
@@ -256,6 +270,13 @@ limitations under the License.
|
||||
<div class="action unresolved hideOnPublished" hidden$="[[resolved]]">
|
||||
Unresolved
|
||||
</div>
|
||||
<gr-button
|
||||
id="deleteBtn"
|
||||
class="action delete"
|
||||
on-tap="_handleCommentDelete"
|
||||
hidden$="[[!_isAdmin]]">
|
||||
Delete
|
||||
</gr-button>
|
||||
</div>
|
||||
<div class="actions robotActions" hidden$="[[!_showRobotActions]]">
|
||||
<gr-button class="action fix"
|
||||
@@ -265,6 +286,12 @@ limitations under the License.
|
||||
</gr-button>
|
||||
</div>
|
||||
</div>
|
||||
<gr-overlay id="overlay" with-backdrop>
|
||||
<gr-confirm-delete-comment-dialog id="confirmDeleteComment"
|
||||
on-confirm="_handleConfirmDeleteComment"
|
||||
on-cancel="_handleCancelDeleteComment">
|
||||
</gr-confirm-delete-comment-dialog>
|
||||
</gr-overlay>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
<gr-storage id="storage"></gr-storage>
|
||||
</template>
|
||||
|
||||
@@ -90,6 +90,10 @@
|
||||
},
|
||||
projectConfig: Object,
|
||||
robotButtonDisabled: Boolean,
|
||||
_isAdmin: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
_xhrPromise: Object, // Used for testing.
|
||||
_messageText: {
|
||||
@@ -118,6 +122,9 @@
|
||||
} else if (this.comment) {
|
||||
this.collapsed = this.comment.collapsed;
|
||||
}
|
||||
this._getIsAdmin().then(function(isAdmin) {
|
||||
this._isAdmin = isAdmin;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
detached: function() {
|
||||
@@ -141,6 +148,10 @@
|
||||
return this.side === 'PARENT';
|
||||
},
|
||||
|
||||
_getIsAdmin: function() {
|
||||
return this.$.restAPI.getIsAdmin();
|
||||
},
|
||||
|
||||
save: function() {
|
||||
this.comment.message = this._messageText;
|
||||
|
||||
@@ -462,5 +473,24 @@
|
||||
this.comment.unresolved = !resolved;
|
||||
this.fire('comment-update', this._getEventPayload());
|
||||
},
|
||||
|
||||
_handleCommentDelete: function() {
|
||||
Polymer.dom(Gerrit.getRootElement()).appendChild(this.$.overlay);
|
||||
this.$.overlay.open();
|
||||
},
|
||||
|
||||
_handleCancelDeleteComment: function() {
|
||||
Polymer.dom(Gerrit.getRootElement()).removeChild(this.$.overlay);
|
||||
this.$.overlay.close();
|
||||
},
|
||||
|
||||
_handleConfirmDeleteComment: function() {
|
||||
this.$.restAPI.deleteComment(
|
||||
this.changeNum, this.patchNum, this.comment.id,
|
||||
this.$.confirmDeleteComment.message).then(function(newComment) {
|
||||
this._handleCancelDeleteComment();
|
||||
this.comment = newComment;
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -248,6 +248,27 @@ limitations under the License.
|
||||
assert.isTrue(element._handleSave.called);
|
||||
});
|
||||
});
|
||||
test('delete comment button for non-admins is hidden', function() {
|
||||
element._isAdmin = false;
|
||||
assert.isTrue(element.$$('.action.delete').hidden);
|
||||
});
|
||||
|
||||
test('delete comment', function(done) {
|
||||
sandbox.stub(
|
||||
element.$.restAPI, 'deleteComment').returns(Promise.resolve());
|
||||
sandbox.spy(element.$.overlay, 'open');
|
||||
element.changeNum = 42;
|
||||
element.patchNum = 0xDEADBEEF;
|
||||
element._isAdmin = true;
|
||||
MockInteractions.tap(element.$$('.action.delete'));
|
||||
element.$.overlay.open.lastCall.returnValue.then(function() {
|
||||
element.$.confirmDeleteComment.message = 'removal reason';
|
||||
element._handleConfirmDeleteComment();
|
||||
assert.isTrue(element.$.restAPI.deleteComment.calledWith(
|
||||
42, 0xDEADBEEF, 'baf0414d_60047215', 'removal reason'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('gr-diff-comment draft tests', function() {
|
||||
|
||||
@@ -339,6 +339,18 @@
|
||||
});
|
||||
},
|
||||
|
||||
getIsAdmin() {
|
||||
return this.getLoggedIn().then(isLoggedIn => {
|
||||
if (isLoggedIn) {
|
||||
return this.getAccountCapabilities();
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}).then(capabilities => {
|
||||
return capabilities && capabilities.administrateServer;
|
||||
});
|
||||
},
|
||||
|
||||
checkCredentials() {
|
||||
// Skip the REST response cache.
|
||||
return this.fetchJSON('/accounts/self/detail');
|
||||
@@ -1113,5 +1125,14 @@
|
||||
return this.send(
|
||||
'POST', this.getChangeActionURL(changeNum, null, '/ready'), review);
|
||||
},
|
||||
|
||||
deleteComment: function(changeNum, patchNum, commentID, reason) {
|
||||
var url = this._changeBaseURL(changeNum, patchNum) +
|
||||
'/comments/' + commentID + '/delete';
|
||||
return this.send('POST', url, {reason: reason}).then(
|
||||
function(response) {
|
||||
return this.getResponseObject(response);
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -630,5 +630,18 @@ limitations under the License.
|
||||
assert.isTrue(element.send.calledWith(
|
||||
'POST', '/changes/42/ready', {message: 'Please review.'}));
|
||||
});
|
||||
|
||||
test('deleteComment', done => {
|
||||
sandbox.stub(element, 'send').returns(Promise.resolve());
|
||||
sandbox.stub(element, 'getResponseObject').returns('some response');
|
||||
element.deleteComment('foo', 'bar', '01234', 'removal reason')
|
||||
.then(response => {
|
||||
assert.equal(response, 'some response');
|
||||
done();
|
||||
});
|
||||
assert.isTrue(element.send.calledWith(
|
||||
'POST', '/changes/foo/revisions/bar/comments/01234/delete',
|
||||
{reason:'removal reason'}));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user