Merge "Consolidate button styles and update disabled"
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
index 79f06fe..aa40a6e 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -104,7 +104,7 @@
},
_computeProjectURL(project) {
- return Gerrit.Nav.getUrlForProject(project, true);
+ return Gerrit.Nav.getUrlForProjectChanges(project, true);
},
_computeProjectBranchURL(change) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index e95c494..32fa7a6 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -314,7 +314,7 @@
},
_computeProjectURL(project) {
- return Gerrit.Nav.getUrlForProject(project);
+ return Gerrit.Nav.getUrlForProjectChanges(project);
},
_computeBranchURL(project, branch) {
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 21cd100..02a0514 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
@@ -39,6 +39,8 @@
const REPLY_REFIT_DEBOUNCE_INTERVAL_MS = 500;
+ const TRAILING_WHITESPACE_REGEX = /[ \t]+$/gm;
+
Polymer({
is: 'gr-change-view',
@@ -298,7 +300,8 @@
},
_handleCommitMessageSave(e) {
- const message = e.detail.content;
+ // Trim trailing whitespace from each line.
+ const message = e.detail.content.replace(TRAILING_WHITESPACE_REGEX, '');
this.$.jsAPI.handleCommitMessage(this._change, message);
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index 6c95046..d0f3d90 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -638,6 +638,22 @@
_change));
});
+ test('_handleCommitMessageSave trims trailing whitespace', () => {
+ const putStub = sandbox.stub(element.$.restAPI, 'putChangeCommitMessage')
+ .returns(Promise.resolve({}));
+
+ const mockEvent = content => { return {detail: {content}}; };
+
+ element._handleCommitMessageSave(mockEvent('test \n test '));
+ assert.equal(putStub.lastCall.args[1], 'test\n test');
+
+ element._handleCommitMessageSave(mockEvent(' test\ntest'));
+ assert.equal(putStub.lastCall.args[1], ' test\ntest');
+
+ element._handleCommitMessageSave(mockEvent('\n\n\n\n\n\n\n\n'));
+ assert.equal(putStub.lastCall.args[1], '\n\n\n\n\n\n\n\n');
+ });
+
test('_computeChangeIdCommitMessageError', () => {
let commitMessage =
'Change-Id: I4ce18b2395bca69d7a9aa48bf4554faa56282483';
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 054f0f1..ac15882 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -430,6 +430,10 @@
},
_getFiles() {
+ if (this.editLoaded) {
+ return this.$.restAPI.getChangeEditFilesAsSpeciallySortedArray(
+ this.changeNum, this.patchRange);
+ }
return this.$.restAPI.getChangeFilesAsSpeciallySortedArray(
this.changeNum, this.patchRange);
},
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index be03e38..7e9f843 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -116,6 +116,48 @@
});
});
+ test('get file list with change edit', done => {
+ element.editLoaded = true;
+
+ sandbox.stub(element.$.restAPI,
+ 'getChangeEditFiles', () => {
+ return Promise.resolve({
+ commit: {},
+ files: {
+ '/COMMIT_MSG': {
+ lines_inserted: 9,
+ },
+ 'tags.html': {
+ lines_deleted: 123,
+ },
+ 'about.txt': {},
+ },
+ });
+ });
+
+ element._getFiles().then(files => {
+ const filenames = files.map(f => { return f.__path; });
+ assert.deepEqual(filenames, ['/COMMIT_MSG', 'about.txt', 'tags.html']);
+ assert.deepEqual(files[0], {
+ lines_inserted: 9,
+ lines_deleted: 0,
+ __path: '/COMMIT_MSG',
+ });
+ assert.deepEqual(files[1], {
+ lines_inserted: 0,
+ lines_deleted: 0,
+ __path: 'about.txt',
+ });
+ assert.deepEqual(files[2], {
+ lines_inserted: 0,
+ lines_deleted: 123,
+ __path: 'tags.html',
+ });
+
+ done();
+ });
+ });
+
test('calculate totals for patch number', () => {
element._files = [
{__path: '/COMMIT_MSG', lines_inserted: 9},
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index 6ff78d8..afb3585 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -130,7 +130,7 @@
* the project.
* @return {string}
*/
- getUrlForProject(project, opt_openOnly) {
+ getUrlForProjectChanges(project, opt_openOnly) {
return this._getUrlFor({
view: Gerrit.Nav.View.SEARCH,
project,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
index 335ed36..dc75073 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
@@ -46,7 +46,8 @@
:host([disabled]) {
pointer-events: none;
}
- :host([disabled]) .container {
+ :host([disabled]) .body,
+ :host([disabled]) .date {
opacity: .5;
}
:host([is-robot-comment]) {
@@ -210,6 +211,12 @@
#deleteBtn.showDeleteButtons {
display: block;
}
+ #savingMessage {
+ display: none;
+ }
+ :host([disabled]) #savingMessage {
+ display: inline;
+ }
</style>
<div id="container"
class="container"
@@ -224,6 +231,7 @@
title="This draft is only visible to you. To publish drafts, click the red 'Reply' button at the top of the change or press the 'A' key."
max-width="20em"
show-icon></gr-tooltip-content>
+ <span id="savingMessage">[[_savingMessage]]</span>
</div>
<div class="headerMiddle">
<span class="collapsedContent">[[comment.message]]</span>
@@ -249,64 +257,66 @@
</label>
</div>
</div>
- <template is="dom-if" if="[[comment.robot_id]]">
- <div class="robotId" hidden$="[[collapsed]]">
- [[comment.robot_id]]
+ <div class="body">
+ <template is="dom-if" if="[[comment.robot_id]]">
+ <div class="robotId" hidden$="[[collapsed]]">
+ [[comment.robot_id]]
+ </div>
+ </template>
+ <gr-textarea
+ id="editTextarea"
+ class="editMessage"
+ autocomplete="on"
+ monospace
+ disabled="{{disabled}}"
+ rows="4"
+ text="{{_messageText}}"></gr-textarea>
+ <gr-formatted-text class="message"
+ content="[[comment.message]]"
+ no-trailing-margin="[[!comment.__draft]]"
+ collapsed="[[collapsed]]"
+ config="[[projectConfig.commentlinks]]"></gr-formatted-text>
+ <div hidden$="[[!comment.robot_run_id]]">
+ <div class="runIdInformation" hidden$="[[collapsed]]">
+ Run ID:
+ <a class="robotRunLink" href$="[[comment.url]]">
+ <span class="robotRun">[[comment.robot_run_id]]</span>
+ </a>
+ </div>
</div>
- </template>
- <gr-textarea
- id="editTextarea"
- class="editMessage"
- autocomplete="on"
- monospace
- disabled="{{disabled}}"
- rows="4"
- text="{{_messageText}}"></gr-textarea>
- <gr-formatted-text class="message"
- content="[[comment.message]]"
- no-trailing-margin="[[!comment.__draft]]"
- collapsed="[[collapsed]]"
- config="[[projectConfig.commentlinks]]"></gr-formatted-text>
- <div hidden$="[[!comment.robot_run_id]]">
- <div class="runIdInformation" hidden$="[[collapsed]]">
- Run ID:
- <a class="robotRunLink" href$="[[comment.url]]">
- <span class="robotRun">[[comment.robot_run_id]]</span>
- </a>
+ <div class="actions humanActions" hidden$="[[!_showHumanActions]]">
+ <div class="action resolve hideOnPublished">
+ <label>
+ <input type="checkbox"
+ checked$="[[resolved]]"
+ on-change="_handleToggleResolved">
+ Resolved
+ </label>
+ </div>
+ <div class="action unresolved hideOnPublished" hidden$="[[resolved]]">
+ Unresolved
+ </div>
+ <div class="rightActions">
+ <gr-button link class="action cancel hideOnPublished"
+ on-tap="_handleCancel" hidden>Cancel</gr-button>
+ <gr-button link class="action discard hideOnPublished"
+ on-tap="_handleDiscard">Discard</gr-button>
+ <gr-button link class="action edit hideOnPublished"
+ on-tap="_handleEdit">Edit</gr-button>
+ <gr-button link class="action save hideOnPublished"
+ on-tap="_handleSave"
+ disabled$="[[_computeSaveDisabled(_messageText)]]">Save
+ </gr-button>
+ </div>
</div>
- </div>
- <div class="actions humanActions" hidden$="[[!_showHumanActions]]">
- <div class="action resolve hideOnPublished">
- <label>
- <input type="checkbox"
- checked$="[[resolved]]"
- on-change="_handleToggleResolved">
- Resolved
- </label>
- </div>
- <div class="action unresolved hideOnPublished" hidden$="[[resolved]]">
- Unresolved
- </div>
- <div class="rightActions">
- <gr-button link class="action cancel hideOnPublished"
- on-tap="_handleCancel" hidden>Cancel</gr-button>
- <gr-button link class="action discard hideOnPublished"
- on-tap="_handleDiscard">Discard</gr-button>
- <gr-button link class="action edit hideOnPublished"
- on-tap="_handleEdit">Edit</gr-button>
- <gr-button link class="action save hideOnPublished"
- on-tap="_handleSave"
- disabled$="[[_computeSaveDisabled(_messageText)]]">Save
+ <div class="actions robotActions" hidden$="[[!_showRobotActions]]">
+ <gr-button link class="action fix"
+ on-tap="_handleFix"
+ disabled="[[robotButtonDisabled]]">
+ Please Fix
</gr-button>
</div>
</div>
- <div class="actions robotActions" hidden$="[[!_showRobotActions]]">
- <gr-button link class="action fix"
- on-tap="_handleFix"
- disabled="[[robotButtonDisabled]]">
- Please Fix
- </gr-button>
- </div>
</div>
<gr-overlay id="confirmDeleteOverlay" with-backdrop>
<gr-confirm-delete-comment-dialog id="confirmDeleteComment"
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
index e8717b5..c5dd524 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
@@ -21,6 +21,8 @@
const DRAFT_SINGULAR = 'draft...';
const DRAFT_PLURAL = 'drafts...';
const SAVED_MESSAGE = 'All changes saved';
+ const SAVING_PROGRESS_MESSAGE = 'Saving draft...';
+ const DiSCARDING_PROGRESS_MESSAGE = 'Discarding draft...';
Polymer({
is: 'gr-diff-comment',
@@ -120,6 +122,8 @@
type: Object,
value: {number: 0}, // Intentional to share the object across instances.
},
+
+ _savingMessage: String,
},
observers: [
@@ -433,6 +437,7 @@
if (!this.comment.__draft) {
throw Error('Cannot discard a non-draft comment.');
}
+ this._savingMessage = DiSCARDING_PROGRESS_MESSAGE;
this.editing = false;
this.disabled = true;
this._eraseDraftComment();
@@ -497,6 +502,7 @@
},
_saveDraft(draft) {
+ this._savingMessage = SAVING_PROGRESS_MESSAGE;
this._showStartRequest();
return this.$.restAPI.saveDiffDraft(this.changeNum, this.patchNum, draft)
.then(result => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
index 1dc6c45..0d0b90e 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
@@ -698,5 +698,22 @@
assert.equal(element._numPendingDraftRequests.number, 0);
});
});
+
+ suite('saving progress indicators', () => {
+ setup(() => {
+ sandbox.stub(element, '_deleteDraft').returns(Promise.resolve());
+ element._savingMessage = '';
+ });
+
+ test('saving', () => {
+ element._saveDraft();
+ assert.equal(element._savingMessage, 'Saving draft...');
+ });
+
+ test('discarding', () => {
+ element._discardDraft();
+ assert.equal(element._savingMessage, 'Discarding draft...');
+ });
+ });
});
</script>
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
index b6a2ad2..c6cf7ce 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
@@ -99,6 +99,8 @@
<gr-endpoint-decorator name="editor">
<gr-endpoint-param name="fileContent" value="[[_newContent]]">
</gr-endpoint-param>
+ <gr-endpoint-param name="prefs" value="[[_prefs]]">
+ </gr-endpoint-param>
<textarea value="{{_newContent::input}}" id="file"></textarea>
</gr-endpoint-decorator>
</div>
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
index 5652793..52ce943 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
@@ -35,7 +35,6 @@
_change: Object,
_changeEditDetail: Object,
_changeNum: String,
- _loggedIn: Boolean,
_path: String,
_content: String,
_newContent: String,
@@ -44,6 +43,7 @@
value: true,
computed: '_computeSaveDisabled(_content, _newContent)',
},
+ _prefs: Object,
},
behaviors: [
@@ -53,13 +53,17 @@
],
attached() {
- this._getLoggedIn().then(loggedIn => { this._loggedIn = loggedIn; });
+ this._getEditPrefs().then(prefs => { this._prefs = prefs; });
},
_getLoggedIn() {
return this.$.restAPI.getLoggedIn();
},
+ _getEditPrefs() {
+ return this.$.restAPI.getEditPrefs();
+ },
+
_paramsChanged(value) {
if (value.view !== Gerrit.Nav.View.EDIT) { return; }
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
index e3e6474..b3bcb22 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
@@ -46,7 +46,7 @@
setup(() => {
stub('gr-rest-api-interface', {
- getLoggedIn() { return Promise.resolve(true); },
+ getEditPrefs() { return Promise.resolve({}); },
});
sandbox = sinon.sandbox.create();
element = fixture('basic');
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 9a7a59e..3bb0178 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -915,6 +915,18 @@
/**
* @param {number|string} changeNum
+ * @param {!Promise<?Object>} patchRange
+ */
+ getChangeEditFiles(changeNum, patchRange) {
+ let endpoint = '/edit?list';
+ if (patchRange.basePatchNum !== 'PARENT') {
+ endpoint += '&base=' + encodeURIComponent(patchRange.basePatchNum);
+ }
+ return this._getChangeURLAndFetch(changeNum, endpoint);
+ },
+
+ /**
+ * @param {number|string} changeNum
* @param {number|string} patchNum
* @param {string} query
* @return {!Promise<!Object>}
@@ -929,6 +941,11 @@
this._normalizeChangeFilesResponse.bind(this));
},
+ getChangeEditFilesAsSpeciallySortedArray(changeNum, patchRange) {
+ return this.getChangeEditFiles(changeNum, patchRange).then(files =>
+ this._normalizeChangeFilesResponse(files.files));
+ },
+
/**
* The closure compiler doesn't realize this.specialFilePathCompare is
* valid.
@@ -1330,6 +1347,10 @@
'/edit:publish');
},
+ getEditPrefs() {
+ return this._fetchSharedCacheURL('/accounts/self/preferences.edit');
+ },
+
putChangeCommitMessage(changeNum, message) {
const p = {message};
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/message', p);