Merge "Add revert button to PolyGerrit."

This commit is contained in:
Andrew Bonventre
2016-04-26 21:45:53 +00:00
committed by Gerrit Code Review
7 changed files with 263 additions and 26 deletions

View File

@@ -25,6 +25,7 @@ limitations under the License.
<link rel="import" href="../gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html">
<link rel="import" href="../gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.html">
<link rel="import" href="../gr-confirm-revert-dialog/gr-confirm-revert-dialog.html">
<dom-module id="gr-change-actions">
<template>
@@ -92,10 +93,16 @@ limitations under the License.
hidden></gr-confirm-rebase-dialog>
<gr-confirm-cherrypick-dialog id="confirmCherrypick"
class="confirmDialog"
message="[[commitMessage]]"
commit-info="[[commitInfo]]"
on-confirm="_handleCherrypickConfirm"
on-cancel="_handleConfirmDialogCancel"
hidden></gr-confirm-cherrypick-dialog>
<gr-confirm-revert-dialog id="confirmRevertDialog"
class="confirmDialog"
commit-info="[[commitInfo]]"
on-confirm="_handleRevertDialogConfirm"
on-cancel="_handleConfirmDialogCancel"
hidden></gr-confirm-revert-dialog>
</gr-overlay>
<gr-js-api-interface id="jsAPI"></gr-js-api-interface>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>

View File

@@ -19,6 +19,7 @@
ABANDON: 'abandon',
DELETE: '/',
RESTORE: 'restore',
REVERT: 'revert',
};
// TODO(andybons): Add the rest of the revision actions.
@@ -37,6 +38,7 @@
'publish': 'Publishing...',
'rebase': 'Rebasing...',
'restore': 'Restoring...',
'revert': 'Reverting...',
'submit': 'Submitting...',
};
@@ -60,7 +62,10 @@
},
changeNum: String,
patchNum: String,
commitMessage: String,
commitInfo: {
type: Object,
readOnly: true,
},
_loading: {
type: Boolean,
value: true,
@@ -145,26 +150,35 @@
e.preventDefault();
var el = Polymer.dom(e).rootTarget;
var key = el.getAttribute('data-action-key');
if (key === RevisionActions.SUBMIT &&
this._canSubmitChange() === false) {
return;
}
var type = el.getAttribute('data-action-type');
if (type === ActionType.REVISION) {
if (key === RevisionActions.REBASE) {
this._showActionDialog(this.$.confirmRebase);
return;
} else if (key === RevisionActions.CHERRYPICK) {
this._showActionDialog(this.$.confirmCherrypick);
return;
}
this._fireAction(this._prependSlash(key),
this._revisionActions[key], true);
this._handleRevisionAction(key);
} else if (key === ChangeActions.REVERT) {
this._showActionDialog(this.$.confirmRevertDialog);
} else {
this._fireAction(this._prependSlash(key), this.actions[key], false);
}
},
_handleRevisionAction: function(key) {
switch (key) {
case RevisionActions.REBASE:
this._showActionDialog(this.$.confirmRebase);
break;
case RevisionActions.CHERRYPICK:
this._showActionDialog(this.$.confirmCherrypick);
break;
case RevisionActions.SUBMIT:
if (!this._canSubmitChange()) {
return;
}
// no break here, fallthrough.
default:
this._fireAction(this._prependSlash(key),
this._revisionActions[key], true);
}
},
_prependSlash: function(key) {
return key === '/' ? key : '/' + key;
},
@@ -221,6 +235,25 @@
);
},
_handleRevertDialogConfirm: function() {
var el = this.$.confirmRevertDialog;
if (!el.message) {
// TODO(viktard): Fix validation.
alert('The revert commit message cant be empty.');
return;
}
this.$.overlay.close();
el.hidden = false;
this._fireAction(
'/revert',
this.actions.revert,
false,
{
message: el.message,
}
);
},
_setLoadingOnButtonWithKey: function(key) {
var buttonEl = this.$$('[data-action-key="' + key + '"]');
buttonEl.setAttribute('loading', true);
@@ -246,6 +279,7 @@
_handleResponse: function(action, response) {
return this.$.restAPI.getResponseObject(response).then(function(obj) {
switch (action.__key) {
case ChangeActions.REVERT:
case RevisionActions.CHERRYPICK:
page.show(this.changePath(obj._number));
break;

View File

@@ -37,7 +37,7 @@ limitations under the License.
var response = {
ok: true,
};
setup(function(done) {
setup(function() {
stub('gr-rest-api-interface', {
getChangeRevisionActions: function() {
return Promise.resolve({
@@ -82,7 +82,7 @@ limitations under the License.
element = fixture('basic');
element.changeNum = '42';
element.patchNum = '2';
element.reload().then(function() { done(); });
return element.reload();
});
test('submit, rebase, and cherry-pick buttons show', function(done) {
@@ -156,11 +156,21 @@ limitations under the License.
});
});
test('cherry-pick change', function(done) {
var fireActionStub = sinon.stub(element, '_fireAction');
var alertStub = sinon.stub(window, 'alert');
suite('cherry-pick', function() {
var fireActionStub;
var alertStub;
flush(function() {
setup(function() {
fireActionStub = sinon.stub(element, '_fireAction');
alertStub = sinon.stub(window, 'alert');
});
teardown(function() {
alertStub.restore();
fireActionStub.restore();
});
test('works', function() {
var rebaseButton = element.$$('gr-button[data-action-key="rebase"]');
MockInteractions.tap(rebaseButton);
var action = {
@@ -188,13 +198,58 @@ limitations under the License.
message: 'foo message',
}
]);
});
});
fireActionStub.restore();
suite('revert change', function() {
var alertStub, fireActionStub;
setup(function() {
fireActionStub = sinon.stub(element, '_fireAction');
alertStub = sinon.stub(window, 'alert');
element.actions = {
revert: {
method: 'POST',
label: 'Revert',
title: 'Revert the change',
enabled: true
}
};
return element.reload();
});
teardown(function() {
alertStub.restore();
done();
});
fireActionStub.restore();
});
test('validation', function() {
element._handleRevertDialogConfirm();
assert.notOk(fireActionStub.called);
assert.ok(alertStub.called);
});
test('works', function() {
var revertButton = element.$$('gr-button[data-action-key="revert"]');
MockInteractions.tap(revertButton);
element.$.confirmRevertDialog.message = 'foo message';
element._handleRevertDialogConfirm();
assert.notOk(alertStub.called);
var action = {
__key: 'revert',
__type: 'change',
enabled: true,
label: 'Revert',
method: 'POST',
title: 'Revert the change',
};
assert.deepEqual(fireActionStub.lastCall.args, [
'/revert', action, false, {
message: 'foo message',
}]);
});
});
});
</script>

View File

@@ -254,7 +254,7 @@ limitations under the License.
actions="[[_change.actions]]"
change-num="[[_changeNum]]"
patch-num="[[_patchNum]]"
commit-message="[[_commitInfo.message]]"
commit-info="[[_commitInfo]]"
on-reload-change="_handleReloadChange"></gr-change-actions>
</div>
<div class="changeInfo-column commitAndRelated">

View File

@@ -32,6 +32,16 @@
properties: {
branch: String,
message: String,
commitInfo: {
type: Object,
readOnly: true,
observer: '_commitInfoChanged',
},
},
_commitInfoChanged: function(commitInfo) {
// Pre-populate cherry-pick message for editing from commit info.
this.message = commitInfo.message;
},
_handleConfirmTap: function(e) {

View File

@@ -0,0 +1,66 @@
<!--
Copyright (C) 2016 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-revert-dialog">
<template>
<style>
:host {
display: block;
width: 30em;
}
:host([disabled]) {
opacity: .5;
pointer-events: none;
}
label {
cursor: pointer;
}
iron-autogrow-textarea {
padding: 0;
}
.main label,
.main input[type="text"] {
display: block;
font: inherit;
width: 100%;
}
.main .message {
border: groove;
width: 100%;
}
</style>
<gr-confirm-dialog
confirm-label="Revert"
on-confirm="_handleConfirmTap"
on-cancel="_handleCancelTap">
<div class="header">Revert Merged Change</div>
<div class="main">
<label for="messageInput">
Revert Commit Message
</label>
<iron-autogrow-textarea
id="messageInput"
class="message"
bind-value="{{message}}"></iron-autogrow-textarea>
</div>
</gr-confirm-dialog>
</template>
<script src="gr-confirm-revert-dialog.js"></script>
</dom-module>

View File

@@ -0,0 +1,65 @@
// Copyright (C) 2016 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-revert-dialog',
/**
* Fired when the confirm button is pressed.
*
* @event confirm
*/
/**
* Fired when the cancel button is pressed.
*
* @event cancel
*/
properties: {
branch: String,
message: String,
commitInfo: {
type: Object,
readOnly: true,
observer: '_commitInfoChanged',
},
},
_commitInfoChanged: function(commitInfo) {
// Strip 'Change-Id: xxx'
var commitMessage = commitInfo.message.replace(
/\n{1,2}\nChange-Id: \w+\n/gm, '');
var revertCommitText = 'This reverts commit ';
// Selector for previous revert text and commit.
var previousRevertText =
new RegExp('\n{1,2}' + revertCommitText + '\\w+.\n*', 'gm')
commitMessage = commitMessage.replace(previousRevertText, '');
this.message = 'Revert "' + commitMessage + '"\n\n' +
revertCommitText + commitInfo.commit + '.';
},
_handleConfirmTap: function(e) {
e.preventDefault();
this.fire('confirm', null, {bubbles: false});
},
_handleCancelTap: function(e) {
e.preventDefault();
this.fire('cancel', null, {bubbles: false});
},
});
})();