Add cherry-pick action When cherry pick was successful, open new created change. To implement the URL computation, existing method _computeChangePath() was moved from change view to REST client behaviour to reuse from change action element. TODOs: - implement branch name suggestion oracle - improve error handling when branch or message is missing (alert) - improve error handling when conflict occurs (409) - improve error handling when branch doesn't exist (400) Test Plan: 1. Open a change 2. Click Cherry Pick button 3. Type destination branch and click confirm button 4. Confirm, that the change cherry-picked and new change is opened Bug: Issue 3906 Change-Id: I587f541dbc3338dc138f306c400f5f8857fd16a3
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html index 1593fab..582a28a 100644 --- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html +++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
@@ -23,6 +23,7 @@ <link rel="import" href="../../shared/gr-overlay/gr-overlay.html"> <link rel="import" href="../../shared/gr-request/gr-request.html"> +<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"> <dom-module id="gr-change-actions"> @@ -78,6 +79,12 @@ on-confirm="_handleRebaseConfirm" on-cancel="_handleConfirmDialogCancel" hidden></gr-confirm-rebase-dialog> + <gr-confirm-cherrypick-dialog id="confirmCherrypick" + class="confirmDialog" + message="[[commitMessage]]" + on-confirm="_handleCherrypickConfirm" + on-cancel="_handleConfirmDialogCancel" + hidden></gr-confirm-cherrypick-dialog> </gr-overlay> </template> <script src="gr-change-actions.js"></script>
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js index a89c0aa..04b9bb5 100644 --- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js +++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -23,6 +23,7 @@ // TODO(andybons): Add the rest of the revision actions. var RevisionActions = { + CHERRYPICK: 'cherrypick', DELETE: '/', PUBLISH: 'publish', REBASE: 'rebase', @@ -44,6 +45,7 @@ }, changeNum: String, patchNum: String, + commitMessage: String, _loading: { type: Boolean, value: true, @@ -67,12 +69,7 @@ }, _actionsChanged: function(actions, revisionActions) { - this.hidden = - revisionActions.rebase == null && - revisionActions.submit == null && - revisionActions.publish == null && - actions.abandon == null && - actions.restore == null; + this.hidden = actions.length == 0 && revisionActions.length == 0; }, _computeRevisionActionsPath: function(changeNum, patchNum) { @@ -100,6 +97,7 @@ _computeLoadingLabel: function(action) { return { + 'cherrypick': 'Cherry-Picking...', 'rebase': 'Rebasing...', 'submit': 'Submitting...', }[action]; @@ -124,7 +122,10 @@ var type = el.getAttribute('data-action-type'); if (type == 'revision') { if (key == RevisionActions.REBASE) { - this._showRebaseDialog(); + this._showActionDialog(this.$.confirmRebase); + return; + } else if (key == RevisionActions.CHERRYPICK) { + this._showActionDialog(this.$.confirmCherrypick); return; } this._fireRevisionAction(this._prependSlash(key), @@ -167,6 +168,28 @@ payload); }, + _handleCherrypickConfirm: function() { + var el = this.$.confirmCherrypick; + if (!el.branch) { + // TODO(davido): Fix error handling + alert('The destination branch can’t be empty.'); + return; + } + if (!el.message) { + alert('The commit message can’t be empty.'); + return; + } + this.$.overlay.close(); + el.hidden = false; + this._fireRevisionAction('/cherrypick', + this._revisionActions.cherrypick, + { + destination: el.branch, + message: el.message, + } + ); + }, + _fireChangeAction: function(endpoint, action) { this._send(action.method, {}, endpoint).then( function() { @@ -193,8 +216,12 @@ } this._send(action.method, opt_payload, endpoint, true).then( - function() { - this.fire('reload-change', null, {bubbles: false}); + function(req) { + if (action.__key == RevisionActions.CHERRYPICK) { + page.show(this.changePath(req.response._number)); + } else { + this.fire('reload-change', null, {bubbles: false}); + } enableButton(); }.bind(this)).catch(function(err) { // TODO(andybons): Handle merge conflict (409 status); @@ -205,8 +232,8 @@ }); }, - _showRebaseDialog: function() { - this.$.confirmRebase.hidden = false; + _showActionDialog: function(dialog) { + dialog.hidden = false; this.$.overlay.open(); },
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html index 1c5eb9c..ca2df18 100644 --- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html +++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
@@ -96,10 +96,10 @@ server.respond(); }); - test('submit and rebase buttons show', function(done) { + test('submit, rebase, and cherry-pick buttons show', function(done) { flush(function() { var buttonEls = Polymer.dom(element.root).querySelectorAll('gr-button'); - assert.equal(buttonEls.length, 2); + assert.equal(buttonEls.length, 3); assert.isFalse(element.hidden); done(); });
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html index 1dbdbfb..ff47383 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -269,6 +269,7 @@ actions="[[_change.actions]]" change-num="[[_changeNum]]" patch-num="[[_patchNum]]" + commit-message="[[_commitInfo.message]]" on-reload-change="_handleReloadChange"></gr-change-actions> </div> <div class="changeInfo-column commitAndRelated">
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js index a42a379..b76b3c4 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -116,10 +116,10 @@ var currentPatchNum = this._change.revisions[this._change.current_revision]._number; if (patchNum == currentPatchNum) { - page.show(this._computeChangePath(this._changeNum)); + page.show(this.changePath(this._changeNum)); return; } - page.show(this._computeChangePath(this._changeNum) + '/' + patchNum); + page.show(this.changePath(this._changeNum) + '/' + patchNum); }, _handleReplyTap: function(e) { @@ -206,10 +206,6 @@ this.fire('title-change', {title: title}); }, - _computeChangePath: function(changeNum) { - return '/c/' + changeNum; - }, - _computeChangePermalink: function(changeNum) { return '/' + changeNum; }, @@ -321,7 +317,7 @@ }, _handleReloadChange: function() { - page.show(this._computeChangePath(this._changeNum)); + page.show(this.changePath(this._changeNum)); }, _reload: function() {
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html new file mode 100644 index 0000000..b21575b --- /dev/null +++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html
@@ -0,0 +1,74 @@ +<!-- +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-cherrypick-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="Cherry Pick" + on-confirm="_handleConfirmTap" + on-cancel="_handleCancelTap"> + <div class="header">Cherry Pick Change to Another Branch</div> + <div class="main"> + <label for="branchInput"> + Cherry Pick to branch + </label> + <input is="iron-input" + type="text" + id="branchInput" + bind-value="{{branch}}" + placeholder="Destination branch"> + <label for="messageInput"> + Cherry Pick 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-cherrypick-dialog.js"></script> +</dom-module>
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js new file mode 100644 index 0000000..f27e4e2 --- /dev/null +++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
@@ -0,0 +1,47 @@ +// 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-cherrypick-dialog', + + /** + * Fired when the confirm button is pressed. + * + * @event confirm + */ + + /** + * Fired when the cancel button is pressed. + * + * @event cancel + */ + + properties: { + branch: String, + message: String, + }, + + _handleConfirmTap: function(e) { + e.preventDefault(); + this.fire('confirm', null, {bubbles: false}); + }, + + _handleCancelTap: function(e) { + e.preventDefault(); + this.fire('cancel', null, {bubbles: false}); + }, + }); +})();