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-button/gr-button.html">
|
||||||
<link rel="import" href="../../shared/gr-change-star/gr-change-star.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-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-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-linked-text/gr-linked-text.html">
|
||||||
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
|
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
|
||||||
@@ -260,10 +261,19 @@ limitations under the License.
|
|||||||
</div>
|
</div>
|
||||||
<div class="changeInfo-column commitAndRelated">
|
<div class="changeInfo-column commitAndRelated">
|
||||||
<div class="commitMessage">
|
<div class="commitMessage">
|
||||||
<h4>Commit message</h4>
|
<h4>
|
||||||
<gr-linked-text pre
|
Commit message
|
||||||
content="[[_commitInfo.message]]"
|
<gr-button link
|
||||||
config="[[_projectConfig.commentlinks]]"></gr-linked-text>
|
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>
|
||||||
<div class="relatedChanges">
|
<div class="relatedChanges">
|
||||||
<gr-related-changes-list id="relatedChanges"
|
<gr-related-changes-list id="relatedChanges"
|
||||||
|
@@ -59,6 +59,15 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
value: function() { return {}; },
|
value: function() { return {}; },
|
||||||
},
|
},
|
||||||
|
_editingCommitMessage: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
_hideEditCommitMessage: {
|
||||||
|
type: Boolean,
|
||||||
|
computed: '_computeHideEditCommitMessage(_loggedIn, ' +
|
||||||
|
'_editingCommitMessage, _change.*, _patchRange.patchNum)',
|
||||||
|
},
|
||||||
_patchRange: Object,
|
_patchRange: Object,
|
||||||
_allPatchSets: {
|
_allPatchSets: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -96,6 +105,10 @@
|
|||||||
this.addEventListener('comment-save', this._handleCommentSave.bind(this));
|
this.addEventListener('comment-save', this._handleCommentSave.bind(this));
|
||||||
this.addEventListener('comment-discard',
|
this.addEventListener('comment-discard',
|
||||||
this._handleCommentDiscard.bind(this));
|
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');
|
this.listen(window, 'scroll', '_handleBodyScroll');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -126,6 +139,59 @@
|
|||||||
el.classList.remove('pinned');
|
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) {
|
_handleCommentSave: function(e) {
|
||||||
if (!e.target.comment.__draft) { return; }
|
if (!e.target.comment.__draft) { return; }
|
||||||
|
|
||||||
|
@@ -230,5 +230,25 @@ limitations under the License.
|
|||||||
var status = element._computeChangeStatus(element._change, '2');
|
var status = element._computeChangeStatus(element._change, '2');
|
||||||
assert.equal(status, '(draft)');
|
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>
|
</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);
|
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) {
|
saveChangeStarred: function(changeNum, starred) {
|
||||||
var url = '/accounts/self/starred.changes/' + changeNum;
|
var url = '/accounts/self/starred.changes/' + changeNum;
|
||||||
var method = starred ? 'PUT' : 'DELETE';
|
var method = starred ? 'PUT' : 'DELETE';
|
||||||
|
@@ -60,6 +60,7 @@ limitations under the License.
|
|||||||
'shared/gr-confirm-dialog/gr-confirm-dialog_test.html',
|
'shared/gr-confirm-dialog/gr-confirm-dialog_test.html',
|
||||||
'shared/gr-cursor-manager/gr-cursor-manager_test.html',
|
'shared/gr-cursor-manager/gr-cursor-manager_test.html',
|
||||||
'shared/gr-date-formatter/gr-date-formatter_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-js-api-interface/gr-js-api-interface_test.html',
|
||||||
'shared/gr-editable-label/gr-editable-label_test.html',
|
'shared/gr-editable-label/gr-editable-label_test.html',
|
||||||
'shared/gr-linked-text/gr-linked-text_test.html',
|
'shared/gr-linked-text/gr-linked-text_test.html',
|
||||||
|
Reference in New Issue
Block a user