From 609bd3c24b321a6524cf8815f8856a238df655c6 Mon Sep 17 00:00:00 2001 From: Youhei Sakurai Date: Wed, 29 Nov 2023 23:22:40 +0900 Subject: [PATCH] [Console] Fix wrong autocomplete suggestions on typing in slash (#171948) Closes #171947 ## Summary This PR fixes wrong autocomplete suggestions on typing in slash in some specific cases. ![fix-suggestion-on-slash](https://github.com/elastic/kibana/assets/721858/f3cab482-63ca-4ee7-99b7-0e3fc37e8940) ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) ## Release note Fixes wrong autocomplete suggestions on typing in slash (cherry picked from commit 11136b688061fd3f4914915ea0da6e3917b5e66b) --- .../public/lib/autocomplete/autocomplete.ts | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/plugins/console/public/lib/autocomplete/autocomplete.ts b/src/plugins/console/public/lib/autocomplete/autocomplete.ts index ec543a1663d98..c6b425697abcf 100644 --- a/src/plugins/console/public/lib/autocomplete/autocomplete.ts +++ b/src/plugins/console/public/lib/autocomplete/autocomplete.ts @@ -983,32 +983,33 @@ export default function ({ context.urlTokenPath = ret.urlTokenPath; const components = getTopLevelUrlCompleteComponents(context.method); - const { tokenPath, predicate } = (() => { - const lastUrlTokenPath = - Array.isArray(context.urlTokenPath) && context.urlTokenPath.length !== 0 - ? context.urlTokenPath[context.urlTokenPath.length - 1] - : null; - // Checking the last chunk of path like 'c,d,' of 'GET /a/b/c,d,' - if ( - Array.isArray(lastUrlTokenPath) && - // true if neither c nor d equals to every ConstantComponent's name (such as _search) - !_.find( - components, - (c) => c instanceof ConstantComponent && _.find(lastUrlTokenPath, (p) => c.name === p) - ) - ) { - // will simulate autocomplete on 'GET /a/b/' with a filter by index - return { - tokenPath: context.urlTokenPath?.slice(0, -1), - predicate: (term: ReturnType[0]) => term.meta === 'index', - }; - } else { - // will do nothing special - return { tokenPath: context.urlTokenPath, predicate: () => true }; + let urlTokenPath = context.urlTokenPath; + let predicate: (term: ReturnType[0]) => boolean = () => true; + + const tokenIter = createTokenIterator({ editor, position: pos }); + const currentTokenType = tokenIter.getCurrentToken()?.type; + const previousTokenType = tokenIter.stepBackward()?.type; + if (!Array.isArray(urlTokenPath)) { + // skip checks for url.comma + } else if (previousTokenType === 'url.comma' && currentTokenType === 'url.comma') { + predicate = () => false; // two consecutive commas empty the autocomplete + } else if ( + (previousTokenType === 'url.part' && currentTokenType === 'url.comma') || + (previousTokenType === 'url.slash' && currentTokenType === 'url.comma') || + (previousTokenType === 'url.comma' && currentTokenType === 'url.part') + ) { + const lastUrlTokenPath = _.last(urlTokenPath) || []; // ['c', 'd'] from 'GET /a/b/c,d,' + const constantComponents = _.filter(components, (c) => c instanceof ConstantComponent); + const constantComponentNames = _.map(constantComponents, 'name'); + + // check if neither 'c' nor 'd' is a constant component name such as '_search' + if (_.every(lastUrlTokenPath, (token) => !_.includes(constantComponentNames, token))) { + urlTokenPath = urlTokenPath.slice(0, -1); // drop the last 'c,d,' part from the url path + predicate = (term) => term.meta === 'index'; // limit the autocomplete to indices only } - })(); + } - populateContext(tokenPath, context, editor, true, components); + populateContext(urlTokenPath, context, editor, true, components); context.autoCompleteSet = _.filter( addMetaToTermsList(context.autoCompleteSet!, 'endpoint'), predicate