Merge "Ignore Trigger votes section in reply dialog when no permission"
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
index 8711f14..db0d236 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.ts
@@ -547,9 +547,25 @@
this.cancel();
break;
case 'Tab':
- if (this.suggestions.length > 0 && this.tabComplete) {
+ if (
+ this.queryStatus?.type === AutocompleteQueryStatusType.LOADING &&
+ this.tabComplete
+ ) {
e.preventDefault();
- this.handleInputCommit(true);
+ // Queue tab on load.
+ this.queryStatus = {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading... (Handle Tab on load)',
+ };
+ const queryId = this.activeQueryId;
+ this.latestSuggestionUpdateComplete?.then(() => {
+ if (queryId === this.activeQueryId) {
+ this.handleInputCommit(/* _tabComplete=*/ true);
+ }
+ });
+ } else if (this.suggestions.length > 0 && this.tabComplete) {
+ e.preventDefault();
+ this.handleInputCommit(/* _tabComplete=*/ true);
this.focus();
} else {
this.setFocus(false);
@@ -559,12 +575,24 @@
if (modifierPressed(e)) {
break;
}
- if (this.suggestions.length > 0) {
+ e.preventDefault();
+ if (this.queryStatus?.type === AutocompleteQueryStatusType.LOADING) {
+ // Queue enter on load.
+ this.queryStatus = {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading... (Handle Enter on load)',
+ };
+ const queryId = this.activeQueryId;
+ this.latestSuggestionUpdateComplete?.then(() => {
+ if (queryId === this.activeQueryId) {
+ this.handleItemSelectEnter(e);
+ }
+ });
+ } else if (this.suggestions.length > 0) {
// If suggestions are shown, act as if the keypress is in dropdown.
// suggestions length is 0 if error is shown.
this.handleItemSelectEnter(e);
} else {
- e.preventDefault();
this.handleInputCommit();
}
break;
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts
index a3da953..c59b8e8 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.ts
@@ -775,6 +775,142 @@
assert.isTrue(cancelHandler.called);
});
+ test('while loading queue enter commits', async () => {
+ const commitHandler = sinon.stub();
+ element.addEventListener('commit', commitHandler);
+ let resolvePromise: (value: AutocompleteSuggestion[]) => void;
+ const blockingPromise = new Promise<AutocompleteSuggestion[]>(resolve => {
+ resolvePromise = resolve;
+ });
+ element.query = (_: string) => blockingPromise;
+
+ element.setFocus(true);
+ element.text = 'blah';
+ await element.updateComplete;
+ await waitUntil(() => !suggestionsEl().isHidden);
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading...',
+ });
+
+ pressKey(inputEl(), Key.ENTER);
+ await element.updateComplete;
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading... (Handle Enter on load)',
+ });
+
+ resolvePromise!([{name: 'suggestion 1'}] as AutocompleteSuggestion[]);
+ await element.latestSuggestionUpdateComplete;
+ await element.updateComplete;
+
+ assert.equal(element.suggestions.length, 0);
+ assert.isUndefined(element.queryStatus);
+ assert.isTrue(commitHandler.called);
+ });
+
+ test('while loading queue tab completes', async () => {
+ element.tabComplete = true;
+ const commitHandler = sinon.stub();
+ element.addEventListener('commit', commitHandler);
+ const queryPromise = mockPromise<AutocompleteSuggestion[]>();
+ element.query = (_: string) => queryPromise;
+
+ element.setFocus(true);
+ element.text = 'blah';
+ await element.updateComplete;
+ await waitUntil(() => !suggestionsEl().isHidden);
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading...',
+ });
+
+ pressKey(inputEl(), Key.TAB);
+ await element.updateComplete;
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading... (Handle Tab on load)',
+ });
+
+ queryPromise.resolve([{name: 'suggestion 1'}] as AutocompleteSuggestion[]);
+ await element.latestSuggestionUpdateComplete;
+ await element.updateComplete;
+
+ assert.equal(element.suggestions.length, 0);
+ assert.isUndefined(element.queryStatus);
+ assert.isFalse(commitHandler.called);
+ assert.equal(element.text, 'suggestion 1');
+ });
+
+ test('while loading and queued update text cancels', async () => {
+ const commitHandler = sinon.stub();
+ element.addEventListener('commit', commitHandler);
+ const queryPromise = mockPromise<AutocompleteSuggestion[]>();
+ element.query = (_: string) => queryPromise;
+
+ element.setFocus(true);
+ element.text = 'blah';
+ await element.updateComplete;
+ await waitUntil(() => !suggestionsEl().isHidden);
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading...',
+ });
+
+ pressKey(inputEl(), Key.ENTER);
+ await element.updateComplete;
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading... (Handle Enter on load)',
+ });
+
+ element.text = 'more blah';
+ await element.updateComplete;
+
+ queryPromise.resolve([{name: 'suggestion 1'}] as AutocompleteSuggestion[]);
+ await element.latestSuggestionUpdateComplete;
+ await element.updateComplete;
+
+ // Commit for stale request is not called.
+ assert.isFalse(commitHandler.called);
+ });
+
+ test('while loading and queued esc cancels', async () => {
+ const commitHandler = sinon.stub();
+ element.addEventListener('commit', commitHandler);
+ const queryPromise = mockPromise<AutocompleteSuggestion[]>();
+ element.query = (_: string) => queryPromise;
+
+ element.setFocus(true);
+ element.text = 'blah';
+ await element.updateComplete;
+ await waitUntil(() => !suggestionsEl().isHidden);
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading...',
+ });
+
+ pressKey(inputEl(), Key.ENTER);
+ await element.updateComplete;
+ assert.deepEqual(element.queryStatus, {
+ type: AutocompleteQueryStatusType.LOADING,
+ message: 'Loading... (Handle Enter on load)',
+ });
+
+ pressKey(inputEl(), Key.ESC);
+ await element.updateComplete;
+
+ queryPromise.resolve([{name: 'suggestion 1'}] as AutocompleteSuggestion[]);
+ await element.latestSuggestionUpdateComplete;
+ await element.updateComplete;
+
+ // Commit for stale request is not called.
+ assert.isFalse(commitHandler.called);
+ // Query results and status are cleared
+ assert.equal(element.suggestions.length, 0);
+ assert.isUndefined(element.queryStatus);
+ });
+
suite('focus', () => {
let commitSpy: sinon.SinonSpy;
let focusSpy: sinon.SinonSpy;