diff --git a/public/app/plugins/datasource/tempo/traceql/autocomplete.ts b/public/app/plugins/datasource/tempo/traceql/autocomplete.ts index a409d381884..20caeaf1343 100644 --- a/public/app/plugins/datasource/tempo/traceql/autocomplete.ts +++ b/public/app/plugins/datasource/tempo/traceql/autocomplete.ts @@ -1,3 +1,4 @@ +import { SelectableValue } from '@grafana/data'; import type { Monaco, monacoTypes } from '@grafana/ui'; import TempoLanguageProvider from '../language_provider'; @@ -29,6 +30,7 @@ export class CompletionProvider implements monacoTypes.languages.CompletionItemP editor: monacoTypes.editor.IStandaloneCodeEditor | undefined; private tags: { [tag: string]: Set } = {}; + private cachedValues: { [key: string]: Array> } = {}; provideCompletionItems( model: monacoTypes.editor.ITextModel, @@ -81,6 +83,18 @@ export class CompletionProvider implements monacoTypes.languages.CompletionItemP } } + private async getTagValues(tagName: string): Promise>> { + let tagValues: Array> = []; + + if (this.cachedValues.hasOwnProperty(tagName)) { + tagValues = this.cachedValues[tagName]; + } else { + tagValues = await this.languageProvider.getOptions(tagName); + this.cachedValues[tagName] = tagValues; + } + return tagValues; + } + /** * Get suggestion based on the situation we are in like whether we should suggest tag names or values. * @param situation @@ -114,19 +128,18 @@ export class CompletionProvider implements monacoTypes.languages.CompletionItemP })); case 'SPANSET_IN_VALUE': const tagName = this.overrideTagName(situation.tagName); - return await this.languageProvider.getOptions(tagName).then((res) => { - const items: Completion[] = []; - res.forEach((val) => { - if (val?.label) { - items.push({ - label: val.label, - insertText: situation.betweenQuotes ? val.label : `"${val.label}"`, - type: 'TAG_VALUE', - }); - } - }); - return items; + const tagValues = await this.getTagValues(tagName); + const items: Completion[] = []; + tagValues.forEach((val) => { + if (val?.label) { + items.push({ + label: val.label, + insertText: situation.betweenQuotes ? val.label : `"${val.label}"`, + type: 'TAG_VALUE', + }); + } }); + return items; case 'SPANSET_AFTER_VALUE': return CompletionProvider.logicalOps.concat('}').map((key) => ({ label: key,