prometheus: query-editor: refactor: rename intent to situation (#41079)
* prometheus: query-editor: refactor: rename intent to situation * fixed forgotten rename
This commit is contained in:
+19
-14
@@ -1,4 +1,4 @@
|
||||
import type { Intent, Label } from './intent';
|
||||
import type { Situation, Label } from './situation';
|
||||
import { NeverCaseError } from './util';
|
||||
// FIXME: we should not load this from the "outside", but we cannot do that while we have the "old" query-field too
|
||||
import { FUNCTIONS } from '../../../promql';
|
||||
@@ -139,28 +139,33 @@ async function getLabelValuesForMetricCompletions(
|
||||
}));
|
||||
}
|
||||
|
||||
export async function getCompletions(intent: Intent, dataProvider: DataProvider): Promise<Completion[]> {
|
||||
switch (intent.type) {
|
||||
case 'ALL_DURATIONS':
|
||||
export async function getCompletions(situation: Situation, dataProvider: DataProvider): Promise<Completion[]> {
|
||||
switch (situation.type) {
|
||||
case 'IN_DURATION':
|
||||
return DURATION_COMPLETIONS;
|
||||
case 'ALL_METRIC_NAMES':
|
||||
case 'IN_FUNCTION':
|
||||
return getAllMetricNamesCompletions(dataProvider);
|
||||
case 'FUNCTIONS_AND_ALL_METRIC_NAMES': {
|
||||
case 'AT_ROOT': {
|
||||
const metricNames = await getAllMetricNamesCompletions(dataProvider);
|
||||
return [...FUNCTION_COMPLETIONS, ...metricNames];
|
||||
}
|
||||
case 'HISTORY_AND_FUNCTIONS_AND_ALL_METRIC_NAMES': {
|
||||
case 'EMPTY': {
|
||||
const metricNames = await getAllMetricNamesCompletions(dataProvider);
|
||||
const historyCompletions = await getAllHistoryCompletions(dataProvider);
|
||||
return [...historyCompletions, ...FUNCTION_COMPLETIONS, ...metricNames];
|
||||
}
|
||||
case 'LABEL_NAMES_FOR_SELECTOR':
|
||||
return getLabelNamesForSelectorCompletions(intent.metricName, intent.otherLabels, dataProvider);
|
||||
case 'LABEL_NAMES_FOR_BY':
|
||||
return getLabelNamesForByCompletions(intent.metricName, intent.otherLabels, dataProvider);
|
||||
case 'LABEL_VALUES':
|
||||
return getLabelValuesForMetricCompletions(intent.metricName, intent.labelName, intent.otherLabels, dataProvider);
|
||||
case 'IN_LABEL_SELECTOR_NO_LABEL_NAME':
|
||||
return getLabelNamesForSelectorCompletions(situation.metricName, situation.otherLabels, dataProvider);
|
||||
case 'IN_GROUPING':
|
||||
return getLabelNamesForByCompletions(situation.metricName, situation.otherLabels, dataProvider);
|
||||
case 'IN_LABEL_SELECTOR_WITH_LABEL_NAME':
|
||||
return getLabelValuesForMetricCompletions(
|
||||
situation.metricName,
|
||||
situation.labelName,
|
||||
situation.otherLabels,
|
||||
dataProvider
|
||||
);
|
||||
default:
|
||||
throw new NeverCaseError(intent);
|
||||
throw new NeverCaseError(situation);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import type { Monaco, monacoTypes } from '@grafana/ui';
|
||||
|
||||
import { getIntent } from './intent';
|
||||
import { getSituation } from './situation';
|
||||
import { getCompletions, DataProvider, CompletionType } from './completions';
|
||||
import { NeverCaseError } from './util';
|
||||
|
||||
@@ -47,8 +47,8 @@ export function getCompletionProvider(
|
||||
lineNumber: position.lineNumber,
|
||||
};
|
||||
const offset = model.getOffsetAt(positionClone);
|
||||
const intent = getIntent(model.getValue(), offset);
|
||||
const completionsPromise = intent != null ? getCompletions(intent, dataProvider) : Promise.resolve([]);
|
||||
const situation = getSituation(model.getValue(), offset);
|
||||
const completionsPromise = situation != null ? getCompletions(situation, dataProvider) : Promise.resolve([]);
|
||||
return completionsPromise.then((items) => {
|
||||
// monaco by-default alphabetically orders the items.
|
||||
// to stop it, we use a number-as-string sortkey,
|
||||
|
||||
+43
-43
@@ -1,7 +1,7 @@
|
||||
import { getIntent, Intent } from './intent';
|
||||
import { getSituation, Situation } from './situation';
|
||||
|
||||
// we use the `^` character as the cursor-marker in the string.
|
||||
function assertIntent(situation: string, expectedIntent: Intent | null) {
|
||||
function assertSituation(situation: string, expectedSituation: Situation | null) {
|
||||
// first we find the cursor-position
|
||||
const pos = situation.indexOf('^');
|
||||
if (pos === -1) {
|
||||
@@ -16,61 +16,61 @@ function assertIntent(situation: string, expectedIntent: Intent | null) {
|
||||
throw new Error('multiple cursors');
|
||||
}
|
||||
|
||||
const result = getIntent(text, pos);
|
||||
const result = getSituation(text, pos);
|
||||
|
||||
if (expectedIntent === null) {
|
||||
if (expectedSituation === null) {
|
||||
expect(result).toStrictEqual(null);
|
||||
} else {
|
||||
expect(result).toMatchObject(expectedIntent);
|
||||
expect(result).toMatchObject(expectedSituation);
|
||||
}
|
||||
}
|
||||
|
||||
describe('intent', () => {
|
||||
describe('situation', () => {
|
||||
it('handles things', () => {
|
||||
assertIntent('^', {
|
||||
type: 'HISTORY_AND_FUNCTIONS_AND_ALL_METRIC_NAMES',
|
||||
assertSituation('^', {
|
||||
type: 'EMPTY',
|
||||
});
|
||||
|
||||
assertIntent('sum(one) / ^', {
|
||||
type: 'FUNCTIONS_AND_ALL_METRIC_NAMES',
|
||||
assertSituation('sum(one) / ^', {
|
||||
type: 'AT_ROOT',
|
||||
});
|
||||
|
||||
assertIntent('sum(^)', {
|
||||
type: 'ALL_METRIC_NAMES',
|
||||
assertSituation('sum(^)', {
|
||||
type: 'IN_FUNCTION',
|
||||
});
|
||||
|
||||
assertIntent('sum(one) / sum(^)', {
|
||||
type: 'ALL_METRIC_NAMES',
|
||||
assertSituation('sum(one) / sum(^)', {
|
||||
type: 'IN_FUNCTION',
|
||||
});
|
||||
|
||||
assertIntent('something{}[^]', {
|
||||
type: 'ALL_DURATIONS',
|
||||
assertSituation('something{}[^]', {
|
||||
type: 'IN_DURATION',
|
||||
});
|
||||
|
||||
assertIntent('something{label~^}', null);
|
||||
assertSituation('something{label~^}', null);
|
||||
});
|
||||
|
||||
it('handles label names', () => {
|
||||
assertIntent('something{^}', {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR',
|
||||
assertSituation('something{^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('sum(something) by (^)', {
|
||||
type: 'LABEL_NAMES_FOR_BY',
|
||||
assertSituation('sum(something) by (^)', {
|
||||
type: 'IN_GROUPING',
|
||||
metricName: 'something',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('sum by (^) (something)', {
|
||||
type: 'LABEL_NAMES_FOR_BY',
|
||||
assertSituation('sum by (^) (something)', {
|
||||
type: 'IN_GROUPING',
|
||||
metricName: 'something',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('something{one="val1",two!="val2",three=~"val3",four!~"val4",^}', {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR',
|
||||
assertSituation('something{one="val1",two!="val2",three=~"val3",four!~"val4",^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
otherLabels: [
|
||||
{ name: 'one', value: 'val1', op: '=' },
|
||||
@@ -80,61 +80,61 @@ describe('intent', () => {
|
||||
],
|
||||
});
|
||||
|
||||
assertIntent('{^}', {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR',
|
||||
assertSituation('{^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('{one="val1",^}', {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR',
|
||||
assertSituation('{one="val1",^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val1', op: '=' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('handles label values', () => {
|
||||
assertIntent('something{job=^}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('something{job=^}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: 'job',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('something{job!=^}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('something{job!=^}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: 'job',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('something{job=~^}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('something{job=~^}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: 'job',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('something{job!~^}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('something{job!~^}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: 'job',
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertIntent('something{job=^,host="h1"}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('something{job=^,host="h1"}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: 'job',
|
||||
otherLabels: [{ name: 'host', value: 'h1', op: '=' }],
|
||||
});
|
||||
|
||||
assertIntent('{job=^,host="h1"}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('{job=^,host="h1"}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
labelName: 'job',
|
||||
otherLabels: [{ name: 'host', value: 'h1', op: '=' }],
|
||||
});
|
||||
|
||||
assertIntent('something{one="val1",two!="val2",three=^,four=~"val4",five!~"val5"}', {
|
||||
type: 'LABEL_VALUES',
|
||||
assertSituation('something{one="val1",two!="val2",three=^,four=~"val4",five!~"val5"}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: 'three',
|
||||
otherLabels: [
|
||||
+25
-25
@@ -84,31 +84,31 @@ export type Label = {
|
||||
op: LabelOperator;
|
||||
};
|
||||
|
||||
export type Intent =
|
||||
export type Situation =
|
||||
| {
|
||||
type: 'ALL_METRIC_NAMES';
|
||||
type: 'IN_FUNCTION';
|
||||
}
|
||||
| {
|
||||
type: 'FUNCTIONS_AND_ALL_METRIC_NAMES';
|
||||
type: 'AT_ROOT';
|
||||
}
|
||||
| {
|
||||
type: 'HISTORY_AND_FUNCTIONS_AND_ALL_METRIC_NAMES';
|
||||
type: 'EMPTY';
|
||||
}
|
||||
| {
|
||||
type: 'ALL_DURATIONS';
|
||||
type: 'IN_DURATION';
|
||||
}
|
||||
| {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR';
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME';
|
||||
metricName?: string;
|
||||
otherLabels: Label[];
|
||||
}
|
||||
| {
|
||||
type: 'LABEL_NAMES_FOR_BY';
|
||||
type: 'IN_GROUPING';
|
||||
metricName: string;
|
||||
otherLabels: Label[];
|
||||
}
|
||||
| {
|
||||
type: 'LABEL_VALUES';
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME';
|
||||
metricName?: string;
|
||||
labelName: string;
|
||||
otherLabels: Label[];
|
||||
@@ -116,7 +116,7 @@ export type Intent =
|
||||
|
||||
type Resolver = {
|
||||
path: NodeTypeName[];
|
||||
fun: (node: SyntaxNode, text: string, pos: number) => Intent | null;
|
||||
fun: (node: SyntaxNode, text: string, pos: number) => Situation | null;
|
||||
};
|
||||
|
||||
function isPathMatch(resolverPath: string[], cursorPath: string[]): boolean {
|
||||
@@ -259,7 +259,7 @@ function getNodeInSubtree(node: SyntaxNode, typeName: NodeTypeName): SyntaxNode
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveLabelsForGrouping(node: SyntaxNode, text: string, pos: number): Intent | null {
|
||||
function resolveLabelsForGrouping(node: SyntaxNode, text: string, pos: number): Situation | null {
|
||||
const aggrExpNode = walk(node, [
|
||||
['parent', 'AggregateModifier'],
|
||||
['parent', 'AggregateExpr'],
|
||||
@@ -284,13 +284,13 @@ function resolveLabelsForGrouping(node: SyntaxNode, text: string, pos: number):
|
||||
|
||||
const metricName = getNodeText(idNode, text);
|
||||
return {
|
||||
type: 'LABEL_NAMES_FOR_BY',
|
||||
type: 'IN_GROUPING',
|
||||
metricName,
|
||||
otherLabels: [],
|
||||
};
|
||||
}
|
||||
|
||||
function resolveLabelMatcherError(node: SyntaxNode, text: string, pos: number): Intent | null {
|
||||
function resolveLabelMatcherError(node: SyntaxNode, text: string, pos: number): Situation | null {
|
||||
// we are probably in the scenario where the user is before entering the
|
||||
// label-value, like `{job=^}` (^ marks the cursor)
|
||||
const parent = walk(node, [['parent', 'LabelMatcher']]);
|
||||
@@ -355,7 +355,7 @@ function resolveLabelMatcherError(node: SyntaxNode, text: string, pos: number):
|
||||
if (metricNameNode === null) {
|
||||
// we are probably in a situation without a metric name
|
||||
return {
|
||||
type: 'LABEL_VALUES',
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
labelName,
|
||||
otherLabels,
|
||||
};
|
||||
@@ -364,28 +364,28 @@ function resolveLabelMatcherError(node: SyntaxNode, text: string, pos: number):
|
||||
const metricName = getNodeText(metricNameNode, text);
|
||||
|
||||
return {
|
||||
type: 'LABEL_VALUES',
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName,
|
||||
labelName,
|
||||
otherLabels,
|
||||
};
|
||||
}
|
||||
|
||||
function resolveTopLevel(node: SyntaxNode, text: string, pos: number): Intent {
|
||||
function resolveTopLevel(node: SyntaxNode, text: string, pos: number): Situation {
|
||||
return {
|
||||
type: 'FUNCTIONS_AND_ALL_METRIC_NAMES',
|
||||
type: 'AT_ROOT',
|
||||
};
|
||||
}
|
||||
|
||||
function resolveInFunction(node: SyntaxNode, text: string, pos: number): Intent {
|
||||
function resolveInFunction(node: SyntaxNode, text: string, pos: number): Situation {
|
||||
return {
|
||||
type: 'ALL_METRIC_NAMES',
|
||||
type: 'IN_FUNCTION',
|
||||
};
|
||||
}
|
||||
|
||||
function resolveDurations(node: SyntaxNode, text: string, pos: number): Intent {
|
||||
function resolveDurations(node: SyntaxNode, text: string, pos: number): Situation {
|
||||
return {
|
||||
type: 'ALL_DURATIONS',
|
||||
type: 'IN_DURATION',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ function subTreeHasError(node: SyntaxNode): boolean {
|
||||
return getNodeInSubtree(node, ERROR_NODE_NAME) !== null;
|
||||
}
|
||||
|
||||
function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Intent | null {
|
||||
function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Situation | null {
|
||||
// for example `something{^}`
|
||||
|
||||
// there are some false positives that can end up in this situation, that we want
|
||||
@@ -414,7 +414,7 @@ function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number)
|
||||
if (metricNameNode === null) {
|
||||
// we are probably in a situation without a metric name.
|
||||
return {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR',
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels,
|
||||
};
|
||||
}
|
||||
@@ -422,7 +422,7 @@ function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number)
|
||||
const metricName = getNodeText(metricNameNode, text);
|
||||
|
||||
return {
|
||||
type: 'LABEL_NAMES_FOR_SELECTOR',
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName,
|
||||
otherLabels,
|
||||
};
|
||||
@@ -451,13 +451,13 @@ function getErrorNode(tree: Tree, pos: number): SyntaxNode | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getIntent(text: string, pos: number): Intent | null {
|
||||
export function getSituation(text: string, pos: number): Situation | null {
|
||||
// there is a special-case when we are at the start of writing text,
|
||||
// so we handle that case first
|
||||
|
||||
if (text === '') {
|
||||
return {
|
||||
type: 'HISTORY_AND_FUNCTIONS_AND_ALL_METRIC_NAMES',
|
||||
type: 'EMPTY',
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user