mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #13953 from miqh/fix/suppress-aggregation-suggestions
Handle suggestions for alternate syntax aggregation contexts
This commit is contained in:
commit
24e5922d68
@ -156,7 +156,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAggregationCompletionItems({ value }: TypeaheadInput): TypeaheadOutput {
|
getAggregationCompletionItems({ value }: TypeaheadInput): TypeaheadOutput {
|
||||||
let refresher: Promise<any> = null;
|
const refresher: Promise<any> = null;
|
||||||
const suggestions: CompletionItemGroup[] = [];
|
const suggestions: CompletionItemGroup[] = [];
|
||||||
|
|
||||||
// Stitch all query lines together to support multi-line queries
|
// Stitch all query lines together to support multi-line queries
|
||||||
@ -172,12 +172,30 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
|||||||
return text;
|
return text;
|
||||||
}, '');
|
}, '');
|
||||||
|
|
||||||
const leftSide = queryText.slice(0, queryOffset);
|
// Try search for selector part on the left-hand side, such as `sum (m) by (l)`
|
||||||
const openParensAggregationIndex = leftSide.lastIndexOf('(');
|
const openParensAggregationIndex = queryText.lastIndexOf('(', queryOffset);
|
||||||
const openParensSelectorIndex = leftSide.slice(0, openParensAggregationIndex).lastIndexOf('(');
|
let openParensSelectorIndex = queryText.lastIndexOf('(', openParensAggregationIndex - 1);
|
||||||
const closeParensSelectorIndex = leftSide.slice(openParensSelectorIndex).indexOf(')') + openParensSelectorIndex;
|
let closeParensSelectorIndex = queryText.indexOf(')', openParensSelectorIndex);
|
||||||
|
|
||||||
let selectorString = leftSide.slice(openParensSelectorIndex + 1, closeParensSelectorIndex);
|
// Try search for selector part of an alternate aggregation clause, such as `sum by (l) (m)`
|
||||||
|
if (openParensSelectorIndex === -1) {
|
||||||
|
const closeParensAggregationIndex = queryText.indexOf(')', queryOffset);
|
||||||
|
closeParensSelectorIndex = queryText.indexOf(')', closeParensAggregationIndex + 1);
|
||||||
|
openParensSelectorIndex = queryText.lastIndexOf('(', closeParensSelectorIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
refresher,
|
||||||
|
suggestions,
|
||||||
|
context: 'context-aggregation',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Suggestions are useless for alternative aggregation clauses without a selector in context
|
||||||
|
if (openParensSelectorIndex === -1) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
let selectorString = queryText.slice(openParensSelectorIndex + 1, closeParensSelectorIndex);
|
||||||
|
|
||||||
// Range vector syntax not accounted for by subsequent parse so discard it if present
|
// Range vector syntax not accounted for by subsequent parse so discard it if present
|
||||||
selectorString = selectorString.replace(/\[[^\]]+\]$/, '');
|
selectorString = selectorString.replace(/\[[^\]]+\]$/, '');
|
||||||
@ -188,14 +206,10 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
|||||||
if (labelKeys) {
|
if (labelKeys) {
|
||||||
suggestions.push({ label: 'Labels', items: labelKeys.map(wrapLabel) });
|
suggestions.push({ label: 'Labels', items: labelKeys.map(wrapLabel) });
|
||||||
} else {
|
} else {
|
||||||
refresher = this.fetchSeriesLabels(selector);
|
result.refresher = this.fetchSeriesLabels(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return result;
|
||||||
refresher,
|
|
||||||
suggestions,
|
|
||||||
context: 'context-aggregation',
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getLabelCompletionItems({ text, wrapperClasses, labelKey, value }: TypeaheadInput): TypeaheadOutput {
|
getLabelCompletionItems({ text, wrapperClasses, labelKey, value }: TypeaheadInput): TypeaheadOutput {
|
||||||
|
@ -269,5 +269,48 @@ describe('Language completion provider', () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns no suggestions inside an unclear aggregation context using alternate syntax', () => {
|
||||||
|
const instance = new LanguageProvider(datasource, {
|
||||||
|
labelKeys: { '{__name__="metric"}': ['label1', 'label2', 'label3'] },
|
||||||
|
});
|
||||||
|
const value = Plain.deserialize('sum by ()');
|
||||||
|
const range = value.selection.merge({
|
||||||
|
anchorOffset: 8,
|
||||||
|
});
|
||||||
|
const valueWithSelection = value.change().select(range).value;
|
||||||
|
const result = instance.provideCompletionItems({
|
||||||
|
text: '',
|
||||||
|
prefix: '',
|
||||||
|
wrapperClasses: ['context-aggregation'],
|
||||||
|
value: valueWithSelection,
|
||||||
|
});
|
||||||
|
expect(result.context).toBe('context-aggregation');
|
||||||
|
expect(result.suggestions).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns label suggestions inside an aggregation context using alternate syntax', () => {
|
||||||
|
const instance = new LanguageProvider(datasource, {
|
||||||
|
labelKeys: { '{__name__="metric"}': ['label1', 'label2', 'label3'] },
|
||||||
|
});
|
||||||
|
const value = Plain.deserialize('sum by () (metric)');
|
||||||
|
const range = value.selection.merge({
|
||||||
|
anchorOffset: 8,
|
||||||
|
});
|
||||||
|
const valueWithSelection = value.change().select(range).value;
|
||||||
|
const result = instance.provideCompletionItems({
|
||||||
|
text: '',
|
||||||
|
prefix: '',
|
||||||
|
wrapperClasses: ['context-aggregation'],
|
||||||
|
value: valueWithSelection,
|
||||||
|
});
|
||||||
|
expect(result.context).toBe('context-aggregation');
|
||||||
|
expect(result.suggestions).toEqual([
|
||||||
|
{
|
||||||
|
items: [{ label: 'label1' }, { label: 'label2' }, { label: 'label3' }],
|
||||||
|
label: 'Labels',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user