Allow the commit message to be edited in the change view
Bug: Issue 4135 Change-Id: I8ccb2f8d9875a277aa8500be183defa0eee37982
This commit is contained in:
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-change-star/gr-change-star.html">
|
||||
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
|
||||
<link rel="import" href="../../shared/gr-editable-content/gr-editable-content.html">
|
||||
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
|
||||
<link rel="import" href="../../shared/gr-linked-text/gr-linked-text.html">
|
||||
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
|
||||
@@ -260,10 +261,19 @@ limitations under the License.
|
||||
</div>
|
||||
<div class="changeInfo-column commitAndRelated">
|
||||
<div class="commitMessage">
|
||||
<h4>Commit message</h4>
|
||||
<gr-linked-text pre
|
||||
content="[[_commitInfo.message]]"
|
||||
config="[[_projectConfig.commentlinks]]"></gr-linked-text>
|
||||
<h4>
|
||||
Commit message
|
||||
<gr-button link
|
||||
on-tap="_handleEditCommitMessage"
|
||||
hidden$="[[_hideEditCommitMessage]]">Edit</gr-button>
|
||||
</h4>
|
||||
<gr-editable-content id="commitMessageEditor"
|
||||
editing="[[_editingCommitMessage]]"
|
||||
content="{{_commitInfo.message}}">
|
||||
<gr-linked-text pre
|
||||
content="[[_commitInfo.message]]"
|
||||
config="[[_projectConfig.commentlinks]]"></gr-linked-text>
|
||||
</gr-editable-content>
|
||||
</div>
|
||||
<div class="relatedChanges">
|
||||
<gr-related-changes-list id="relatedChanges"
|
||||
|
@@ -59,6 +59,15 @@
|
||||
type: Object,
|
||||
value: function() { return {}; },
|
||||
},
|
||||
_editingCommitMessage: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
_hideEditCommitMessage: {
|
||||
type: Boolean,
|
||||
computed: '_computeHideEditCommitMessage(_loggedIn, ' +
|
||||
'_editingCommitMessage, _change.*, _patchRange.patchNum)',
|
||||
},
|
||||
_patchRange: Object,
|
||||
_allPatchSets: {
|
||||
type: Array,
|
||||
@@ -96,6 +105,10 @@
|
||||
this.addEventListener('comment-save', this._handleCommentSave.bind(this));
|
||||
this.addEventListener('comment-discard',
|
||||
this._handleCommentDiscard.bind(this));
|
||||
this.addEventListener('editable-content-save',
|
||||
this._handleCommitMessageSave.bind(this));
|
||||
this.addEventListener('editable-content-cancel',
|
||||
this._handleCommitMessageCancel.bind(this));
|
||||
this.listen(window, 'scroll', '_handleBodyScroll');
|
||||
},
|
||||
|
||||
@@ -126,6 +139,59 @@
|
||||
el.classList.remove('pinned');
|
||||
},
|
||||
|
||||
_handleEditCommitMessage: function(e) {
|
||||
this._editingCommitMessage = true;
|
||||
this.$.commitMessageEditor.focusTextarea();
|
||||
},
|
||||
|
||||
_handleCommitMessageSave: function(e) {
|
||||
var message = e.detail.content;
|
||||
|
||||
this.$.commitMessageEditor.disabled = true;
|
||||
this._saveCommitMessage(message).then(function(resp) {
|
||||
this.$.commitMessageEditor.disabled = false;
|
||||
if (!resp.ok) { return; }
|
||||
|
||||
this.set('_commitInfo.message', message);
|
||||
this._editingCommitMessage = false;
|
||||
this._reloadWindow();
|
||||
}.bind(this)).catch(function(err) {
|
||||
this.$.commitMessageEditor.disabled = false;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_reloadWindow: function() {
|
||||
window.location.reload();
|
||||
},
|
||||
|
||||
_handleCommitMessageCancel: function(e) {
|
||||
this._editingCommitMessage = false;
|
||||
},
|
||||
|
||||
_saveCommitMessage: function(message) {
|
||||
return this.$.restAPI.saveChangeCommitMessageEdit(
|
||||
this._changeNum, message).then(function(resp) {
|
||||
if (!resp.ok) { return resp; }
|
||||
|
||||
return this.$.restAPI.publishChangeEdit(this._changeNum);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_computeHideEditCommitMessage: function(loggedIn, editing, changeRecord,
|
||||
patchNum) {
|
||||
if (!changeRecord || !loggedIn || editing) { return true; }
|
||||
|
||||
patchNum = parseInt(patchNum, 10);
|
||||
if (isNaN(patchNum)) { return true; }
|
||||
|
||||
var change = changeRecord.base;
|
||||
if (change.revisions[change.current_revision]._number !== patchNum) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_handleCommentSave: function(e) {
|
||||
if (!e.target.comment.__draft) { return; }
|
||||
|
||||
|
@@ -230,5 +230,25 @@ limitations under the License.
|
||||
var status = element._computeChangeStatus(element._change, '2');
|
||||
assert.equal(status, '(draft)');
|
||||
});
|
||||
|
||||
test('show commit message edit button', function() {
|
||||
var changeRecord = {
|
||||
base: {
|
||||
revisions: {
|
||||
rev1: {_number: 1},
|
||||
rev2: {_number: 2},
|
||||
},
|
||||
current_revision: 'rev2',
|
||||
},
|
||||
};
|
||||
assert.isTrue(element._computeHideEditCommitMessage(
|
||||
false, false, changeRecord, '2'));
|
||||
assert.isTrue(element._computeHideEditCommitMessage(
|
||||
true, true, changeRecord, '2'));
|
||||
assert.isTrue(element._computeHideEditCommitMessage(
|
||||
true, false, changeRecord, '1'));
|
||||
assert.isFalse(element._computeHideEditCommitMessage(
|
||||
true, false, changeRecord, '2'));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@@ -0,0 +1,59 @@
|
||||
<!--
|
||||
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/polymer/polymer.html">
|
||||
<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
|
||||
<dom-module id="gr-editable-content">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
:host([disabled]) iron-autogrow-textarea {
|
||||
opacity: .5;
|
||||
}
|
||||
iron-autogrow-textarea {
|
||||
width: 100%;
|
||||
|
||||
--iron-autogrow-textarea: {
|
||||
white-space: pre;
|
||||
};
|
||||
}
|
||||
.editButtons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
<div hidden$="[[editing]]">
|
||||
<content></content>
|
||||
</div>
|
||||
<div class="editor" hidden$="[[!editing]]">
|
||||
<iron-autogrow-textarea
|
||||
bind-value="{{_newContent}}"
|
||||
disabled="[[disabled]]"></iron-autogrow-textarea>
|
||||
<div class="editButtons">
|
||||
<gr-button primary
|
||||
on-tap="_handleSave"
|
||||
disabled="[[disabled]]">Save</gr-button>
|
||||
<gr-button
|
||||
on-tap="_handleCancel"
|
||||
disabled="[[disabled]]">Cancel</gr-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script src="gr-editable-content.js"></script>
|
||||
</dom-module>
|
@@ -0,0 +1,70 @@
|
||||
// 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-editable-content',
|
||||
|
||||
/**
|
||||
* Fired when the save button is pressed.
|
||||
*
|
||||
* @event editable-content-save
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the cancel button is pressed.
|
||||
*
|
||||
* @event editable-content-cancel
|
||||
*/
|
||||
|
||||
properties: {
|
||||
content: {
|
||||
type: String,
|
||||
notify: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
reflectToAttribute: true,
|
||||
},
|
||||
editing: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer: '_editingChanged',
|
||||
},
|
||||
|
||||
_newContent: String,
|
||||
},
|
||||
|
||||
focusTextarea: function() {
|
||||
this.$$('iron-autogrow-textarea').textarea.focus();
|
||||
},
|
||||
|
||||
_editingChanged: function(editing) {
|
||||
if (!editing) { return; }
|
||||
this._newContent = this.content;
|
||||
},
|
||||
|
||||
_handleSave: function(e) {
|
||||
e.preventDefault();
|
||||
this.fire('editable-content-save', {content: this._newContent});
|
||||
},
|
||||
|
||||
_handleCancel: function(e) {
|
||||
e.preventDefault();
|
||||
this.editing = false;
|
||||
this.fire('editable-content-cancel');
|
||||
},
|
||||
});
|
||||
})();
|
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
||||
<title>gr-editable-content</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<script src="../../../bower_components/iron-test-helpers/mock-interactions.js"></script>
|
||||
|
||||
<link rel="import" href="gr-editable-content.html">
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-editable-content></gr-editable-content>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-editable-content tests', function() {
|
||||
var element;
|
||||
|
||||
setup(function() {
|
||||
element = fixture('basic');
|
||||
});
|
||||
|
||||
test('save event', function(done) {
|
||||
element._newContent = 'foo';
|
||||
element.addEventListener('editable-content-save', function(e) {
|
||||
assert.equal(e.detail.content, 'foo');
|
||||
done();
|
||||
});
|
||||
MockInteractions.tap(element.$$('gr-button[primary]'));
|
||||
});
|
||||
|
||||
test('cancel event', function(done) {
|
||||
element.addEventListener('editable-content-cancel', function() {
|
||||
done();
|
||||
});
|
||||
MockInteractions.tap(element.$$('gr-button:not([primary])'));
|
||||
});
|
||||
|
||||
test('editing content updates', function() {
|
||||
element.content = 'current content';
|
||||
element._newContent = 'stale content';
|
||||
element.editing = true;
|
||||
assert.equal(element._newContent, 'current content');
|
||||
});
|
||||
});
|
||||
</script>
|
@@ -506,6 +506,16 @@
|
||||
return this.send('POST', url, review, opt_errFn, opt_ctx);
|
||||
},
|
||||
|
||||
saveChangeCommitMessageEdit: function(changeNum, message) {
|
||||
var url = this.getChangeActionURL(changeNum, null, '/edit:message');
|
||||
return this.send('PUT', url, {message: message});
|
||||
},
|
||||
|
||||
publishChangeEdit: function(changeNum) {
|
||||
return this.send('POST',
|
||||
this.getChangeActionURL(changeNum, null, '/edit:publish'));
|
||||
},
|
||||
|
||||
saveChangeStarred: function(changeNum, starred) {
|
||||
var url = '/accounts/self/starred.changes/' + changeNum;
|
||||
var method = starred ? 'PUT' : 'DELETE';
|
||||
|
@@ -60,6 +60,7 @@ limitations under the License.
|
||||
'shared/gr-confirm-dialog/gr-confirm-dialog_test.html',
|
||||
'shared/gr-cursor-manager/gr-cursor-manager_test.html',
|
||||
'shared/gr-date-formatter/gr-date-formatter_test.html',
|
||||
'shared/gr-editable-content/gr-editable-content_test.html',
|
||||
'shared/gr-js-api-interface/gr-js-api-interface_test.html',
|
||||
'shared/gr-editable-label/gr-editable-label_test.html',
|
||||
'shared/gr-linked-text/gr-linked-text_test.html',
|
||||
|
Reference in New Issue
Block a user