From 055080a25b7b9ea5ee16b1d186a0d5c5b0897ead Mon Sep 17 00:00:00 2001 From: Damien de Lemeny Date: Wed, 21 Feb 2024 10:50:11 -0500 Subject: [PATCH 1/2] Use a lenient regexp to match fields in autocomplete --- src/datasource/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datasource/utils.ts b/src/datasource/utils.ts index 40d8b0e..bc2fb7b 100644 --- a/src/datasource/utils.ts +++ b/src/datasource/utils.ts @@ -27,7 +27,7 @@ export function useDatasourceFields(datasource: QuickwitDataSource) { const getSuggestions = useCallback(async (word: string): Promise => { let suggestions: Suggestion = { from: 0, options: [] }; - const wordIsField = word.match(/([\w\.]+):"?(\S*)/); + const wordIsField = word.match(/([^:\s]+):"?([^"\s]*)"?/); if (wordIsField?.length) { const [_match, fieldName, _fieldValue] = wordIsField; const candidateValues = await datasource.getTagValues({ key: fieldName }); From 7775bbdda3742eb8a891d34c884e7ef062c8a56b Mon Sep 17 00:00:00 2001 From: Damien de Lemeny Date: Wed, 21 Feb 2024 10:50:58 -0500 Subject: [PATCH 2/2] Safeguard against empty observables --- src/components/LuceneQueryEditor.tsx | 16 +++++++++++----- src/datasource/index.ts | 25 ++++++++++++++----------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/components/LuceneQueryEditor.tsx b/src/components/LuceneQueryEditor.tsx index b100180..44f9da1 100644 --- a/src/components/LuceneQueryEditor.tsx +++ b/src/components/LuceneQueryEditor.tsx @@ -36,17 +36,23 @@ export function LuceneQueryEditor(props: LuceneQueryEditorProps){ const {autocompleter} = props; const datasourceCompletions = useCallback(async (context: CompletionContext)=>{ + let suggestions; let word = context.matchBefore(/\S*/); if (!word){ return null } - const suggestions = await autocompleter(word?.text); - return { - from: word.from + suggestions.from, - options: suggestions.options + suggestions = await autocompleter(word?.text); + if (suggestions && suggestions.options.length > 0 ) { + return { + from: word.from + suggestions.from, + options: suggestions.options + } } + return null }, [autocompleter]) - const autocomplete = autocompletion({ override: [datasourceCompletions] }) + const autocomplete = autocompletion({ + override: [datasourceCompletions] + }) return ( { const dataquery = this.getDataQueryRequest(queryDef, range) return super.query(dataquery).pipe( - mergeMap(res=> res.data.map((df: DataFrame)=>{ - - return df.fields[0]!.values.map((bucket)=>({ - text: bucket, - value: bucket, - })) + mergeMap(res=> { + return res.data.map((df: DataFrame)=>{ + if (df.fields.length === 0) { return [] } + return df.fields[0].values.map((bucket)=>({ + text: bucket, + value: bucket, + })) + }) }) - ) ) } @@ -335,7 +336,8 @@ export class QuickwitDataSource * Get tag keys for adhoc filters */ getTagKeys(spec?: FieldCapsSpec) { - return lastValueFrom(this.getFields(spec)); + const fields = this.getFields(spec) + return lastValueFrom(fields, {defaultValue:[]}); } /** @@ -343,7 +345,8 @@ export class QuickwitDataSource */ getTagValues(options: any) { const range = getDefaultTimeRange(); - return lastValueFrom(this.getTerms({ field: options.key }, range)); + const terms = this.getTerms({ field: options.key }, range) + return lastValueFrom(terms, {defaultValue:[]}); } /** @@ -436,12 +439,12 @@ export class QuickwitDataSource if (query) { if (parsedQuery.find === 'fields') { parsedQuery.type = this.interpolateLuceneQuery(parsedQuery.type); - return lastValueFrom(this.getFields({aggregatable:true, type:parsedQuery.type, _range:range})); + return lastValueFrom(this.getFields({aggregatable:true, type:parsedQuery.type, _range:range}), {defaultValue:[]}); } if (parsedQuery.find === 'terms') { parsedQuery.field = this.interpolateLuceneQuery(parsedQuery.field); parsedQuery.query = this.interpolateLuceneQuery(parsedQuery.query); - return lastValueFrom(this.getTerms(parsedQuery, range)); + return lastValueFrom(this.getTerms(parsedQuery, range), {defaultValue:[]}); } } return Promise.resolve([]);