summaryrefslogtreecommitdiffstats
path: root/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
diff options
context:
space:
mode:
Diffstat (limited to 'polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js')
-rw-r--r--polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js121
1 files changed, 87 insertions, 34 deletions
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index a1719da840..9f9f026e46 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -1,16 +1,19 @@
-// 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.
+/**
+ * @license
+ * 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';
@@ -40,7 +43,7 @@
};
const ButtonTooltips = {
- SAVE: 'Save reply but do not send',
+ SAVE: 'Save reply but do not send notification',
START_REVIEW: 'Mark as ready for review and send reply',
SEND: 'Send reply',
};
@@ -49,6 +52,10 @@
// googlesource.com.
const START_REVIEW_MESSAGE = 'This change is ready for review.';
+ const EMPTY_REPLY_MESSAGE = 'Cannot send an empty reply.';
+
+ const SEND_REPLY_TIMING_LABEL = 'SendReply';
+
Polymer({
is: 'gr-reply-dialog',
@@ -84,6 +91,12 @@
* @event comment-refresh
*/
+ /**
+ * Fires when the state of the send button (enabled/disabled) changes.
+ *
+ * @event send-disabled-changed
+ */
+
properties: {
/**
* @type {{ _number: number, removable_reviewers: Array }}
@@ -199,6 +212,17 @@
value: ButtonTooltips.SAVE,
readOnly: true,
},
+ _pluginMessage: {
+ type: String,
+ value: '',
+ },
+ _sendDisabled: {
+ type: Boolean,
+ computed: '_computeSendButtonDisabled(_sendButtonLabel, diffDrafts, ' +
+ 'draft, _reviewersMutated, _labelsChanged, _includeComments, ' +
+ 'disabled)',
+ observer: '_sendDisabledChanged',
+ },
},
FocusTarget,
@@ -237,14 +261,19 @@
open(opt_focusTarget) {
this.knownLatestState = LatestPatchState.CHECKING;
- this.fetchIsLatestKnown(this.change, this.$.restAPI)
- .then(isUpToDate => {
- this.knownLatestState = isUpToDate ?
+ this.fetchChangeUpdates(this.change, this.$.restAPI)
+ .then(result => {
+ this.knownLatestState = result.isLatest ?
LatestPatchState.LATEST : LatestPatchState.NOT_LATEST;
});
this._focusOn(opt_focusTarget);
- if (!this.draft || !this.draft.length) {
+ if (this.quote && this.quote.length) {
+ // If a reply quote has been provided, use it and clear the property.
+ this.draft = this.quote;
+ this.quote = '';
+ } else {
+ // Otherwise, check for an unsaved draft in localstorage.
this.draft = this._loadStoredDraft();
}
if (this.$.restAPI.hasPendingDiffDrafts()) {
@@ -261,9 +290,10 @@
},
getFocusStops() {
+ const end = this._sendDisabled ? this.$.cancelButton : this.$.sendButton;
return {
start: this.$.reviewers.focusStart,
- end: this.$.cancelButton,
+ end,
};
},
@@ -401,12 +431,7 @@
},
send(includeComments, startReview) {
- if (this.knownLatestState === 'not-latest') {
- this.fire('show-alert',
- {message: 'Cannot reply to non-latest patch.'});
- return Promise.resolve({});
- }
-
+ this.$.reporting.time(SEND_REPLY_TIMING_LABEL);
const labels = this.$.labelScores.getLabelValues();
const obj = {
@@ -510,7 +535,8 @@
},
_focusOn(section) {
- if (section === FocusTarget.ANY) {
+ // Safeguard- always want to focus on something.
+ if (!section || section === FocusTarget.ANY) {
section = this._chooseFocusTarget();
}
if (section === FocusTarget.BODY) {
@@ -719,6 +745,13 @@
// the text field of the CC entry.
return;
}
+ if (this._sendDisabled) {
+ this.dispatchEvent(new CustomEvent('show-alert', {
+ bubbles: true,
+ detail: {message: EMPTY_REPLY_MESSAGE},
+ }));
+ return;
+ }
return this.send(this._includeComments, this.canBeStarted)
.then(keepReviewers => {
this._purgeReviewersPendingRemove(false, keepReviewers);
@@ -774,6 +807,14 @@
return draft ? draft.message : '';
},
+ _handleAccountTextEntry() {
+ // When either of the account entries has input added to the autocomplete,
+ // it should trigger the save button to enable/
+ //
+ // Note: if the text is removed, the save button will not get disabled.
+ this._reviewersMutated = true;
+ },
+
_draftChanged(newDraft, oldDraft) {
this.debounce('store', () => {
if (!newDraft.length && oldDraft) {
@@ -821,16 +862,28 @@
return savingComments ? 'saving' : '';
},
- _computeSendButtonDisabled(knownLatestState, buttonLabel, drafts, text,
- reviewersMutated, labelsChanged, includeComments) {
- if (this._isState(knownLatestState, LatestPatchState.NOT_LATEST)) {
- return true;
- }
- if (buttonLabel === ButtonLabels.START_REVIEW) {
- return false;
- }
+ _computeSendButtonDisabled(buttonLabel, drafts, text, reviewersMutated,
+ labelsChanged, includeComments, disabled) {
+ if (disabled) { return true; }
+ if (buttonLabel === ButtonLabels.START_REVIEW) { return false; }
const hasDrafts = includeComments && Object.keys(drafts).length;
return !hasDrafts && !text.length && !reviewersMutated && !labelsChanged;
},
+
+ _computePatchSetWarning(patchNum, labelsChanged) {
+ let str = `Patch ${patchNum} is not latest.`;
+ if (labelsChanged) {
+ str += ' Voting on a non-latest patch will have no effect.';
+ }
+ return str;
+ },
+
+ setPluginMessage(message) {
+ this._pluginMessage = message;
+ },
+
+ _sendDisabledChanged(sendDisabled) {
+ this.dispatchEvent(new CustomEvent('send-disabled-changed'));
+ },
});
})();