Show toast messages for storing diff comment drafts
With this change, toast messages show when diff comments are being saved and notify when saving is complete, even when the diff view is no-longer loaded. This signal is intended to encourage users to write diff comments and feel free to navigate away to view other parts of a change. With this change, new toast messages are able to replace existing toast messages. Feature: Issue 6970 Change-Id: I5973673d85c73b14794cb5e5b21327dd0c27ec1d
This commit is contained in:
@@ -126,7 +126,9 @@
|
||||
*/
|
||||
_showAlert(text, opt_actionText, opt_actionCallback,
|
||||
opt_dismissOnNavigation) {
|
||||
if (this._alertElement) { return; }
|
||||
if (this._alertElement) {
|
||||
this._hideAlert();
|
||||
}
|
||||
|
||||
this._clearHideAlertHandle();
|
||||
if (opt_dismissOnNavigation) {
|
||||
|
||||
@@ -272,20 +272,11 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
|
||||
test('dismissOnNavigation respected', () => {
|
||||
const asyncStub = sandbox.stub(element, 'async');
|
||||
const hideSpy = sandbox.spy(element, '_hideAlert');
|
||||
// No async call when dismissOnNavigation supplied.
|
||||
element._showAlert('test', null, null, true);
|
||||
assert.isFalse(asyncStub.called);
|
||||
|
||||
// When page nav happens, clear alert.
|
||||
document.dispatchEvent(new CustomEvent('location-change'));
|
||||
assert.isTrue(hideSpy.called);
|
||||
|
||||
// When timeout is not supplied, use HIDE_ALERT_TIMEOUT_MS.
|
||||
element._showAlert('test');
|
||||
assert.isTrue(asyncStub.called);
|
||||
test('_showAlert hides existing alerts', () => {
|
||||
element._alertElement = element._createToastAlert();
|
||||
const hideStub = sandbox.stub(element, '_hideAlert');
|
||||
element._showAlert();
|
||||
assert.isTrue(hideStub.calledOnce);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
'use strict';
|
||||
|
||||
const STORAGE_DEBOUNCE_INTERVAL = 400;
|
||||
const TOAST_DEBOUNCE_INTERVAL = 200;
|
||||
|
||||
const SAVING_MESSAGE = 'Saving';
|
||||
const DRAFT_SINGULAR = 'draft...';
|
||||
const DRAFT_PLURAL = 'drafts...';
|
||||
const SAVED_MESSAGE = 'All changes saved';
|
||||
|
||||
Polymer({
|
||||
is: 'gr-diff-comment',
|
||||
@@ -109,6 +115,11 @@
|
||||
type: Boolean,
|
||||
observer: '_toggleResolved',
|
||||
},
|
||||
|
||||
_numPendingDiffRequests: {
|
||||
type: Object,
|
||||
value: {number: 0}, // Intentional to share the object across instances.
|
||||
},
|
||||
},
|
||||
|
||||
observers: [
|
||||
@@ -424,13 +435,52 @@
|
||||
});
|
||||
},
|
||||
|
||||
_getSavingMessage(numPending) {
|
||||
if (numPending === 0) { return SAVED_MESSAGE; }
|
||||
return [
|
||||
SAVING_MESSAGE,
|
||||
numPending,
|
||||
numPending === 1 ? DRAFT_SINGULAR : DRAFT_PLURAL,
|
||||
].join(' ');
|
||||
},
|
||||
|
||||
_showStartRequest() {
|
||||
const numPending = ++this._numPendingDiffRequests.number;
|
||||
this._updateRequestToast(numPending);
|
||||
},
|
||||
|
||||
_showEndRequest() {
|
||||
const numPending = --this._numPendingDiffRequests.number;
|
||||
this._updateRequestToast(numPending);
|
||||
},
|
||||
|
||||
_updateRequestToast(numPending) {
|
||||
const message = this._getSavingMessage(numPending);
|
||||
this.debounce('draft-toast', () => {
|
||||
// Note: the event is fired on the body rather than this element because
|
||||
// this element may not be attached by the time this executes, in which
|
||||
// case the event would not bubble.
|
||||
document.body.dispatchEvent(new CustomEvent('show-alert',
|
||||
{detail: {message}, bubbles: true}));
|
||||
}, TOAST_DEBOUNCE_INTERVAL);
|
||||
},
|
||||
|
||||
_saveDraft(draft) {
|
||||
return this.$.restAPI.saveDiffDraft(this.changeNum, this.patchNum, draft);
|
||||
this._showStartRequest();
|
||||
return this.$.restAPI.saveDiffDraft(this.changeNum, this.patchNum, draft)
|
||||
.then(result => {
|
||||
this._showEndRequest();
|
||||
return result;
|
||||
});
|
||||
},
|
||||
|
||||
_deleteDraft(draft) {
|
||||
this._showStartRequest();
|
||||
return this.$.restAPI.deleteDiffDraft(this.changeNum, this.patchNum,
|
||||
draft);
|
||||
draft).then(result => {
|
||||
this._showEndRequest();
|
||||
return result;
|
||||
});
|
||||
},
|
||||
|
||||
_getPatchNum() {
|
||||
|
||||
@@ -602,5 +602,34 @@ limitations under the License.
|
||||
element.comment = {unresolved: true};
|
||||
assert.isFalse(element.$$('.resolve input').checked);
|
||||
});
|
||||
|
||||
suite('draft saving messages', () => {
|
||||
test('_getSavingMessage', () => {
|
||||
assert.equal(element._getSavingMessage(0), 'All changes saved');
|
||||
assert.equal(element._getSavingMessage(1), 'Saving 1 draft...');
|
||||
assert.equal(element._getSavingMessage(2), 'Saving 2 drafts...');
|
||||
assert.equal(element._getSavingMessage(3), 'Saving 3 drafts...');
|
||||
});
|
||||
|
||||
test('_show{Start,End}Request', () => {
|
||||
const updateStub = sandbox.stub(element, '_updateRequestToast');
|
||||
element._numPendingDiffRequests.number = 1;
|
||||
|
||||
element._showStartRequest();
|
||||
assert.isTrue(updateStub.calledOnce);
|
||||
assert.equal(updateStub.lastCall.args[0], 2);
|
||||
assert.equal(element._numPendingDiffRequests.number, 2);
|
||||
|
||||
element._showEndRequest();
|
||||
assert.isTrue(updateStub.calledTwice);
|
||||
assert.equal(updateStub.lastCall.args[0], 1);
|
||||
assert.equal(element._numPendingDiffRequests.number, 1);
|
||||
|
||||
element._showEndRequest();
|
||||
assert.isTrue(updateStub.calledThrice);
|
||||
assert.equal(updateStub.lastCall.args[0], 0);
|
||||
assert.equal(element._numPendingDiffRequests.number, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user