The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/plugins/datasource/tempo/language_provider.ts

114 lines
3.1 KiB

import { Value } from 'slate';
import { LanguageProvider, SelectableValue } from '@grafana/data';
import { CompletionItemGroup, TypeaheadInput, TypeaheadOutput } from '@grafana/ui';
import { TempoDatasource } from './datasource';
export default class TempoLanguageProvider extends LanguageProvider {
datasource: TempoDatasource;
tags?: string[];
constructor(datasource: TempoDatasource, initialValues?: any) {
super();
this.datasource = datasource;
Object.assign(this, initialValues);
}
request = async (url: string, params = {}) => {
const res = await this.datasource.metadataRequest(url, params);
return res?.data;
};
start = async () => {
if (!this.startTask) {
this.startTask = this.fetchTags().then(() => {
return [];
});
}
return this.startTask;
};
async fetchTags() {
const response = await this.request('/api/search/tags', []);
this.tags = response.tagNames;
}
getTags = () => {
return this.tags;
};
provideCompletionItems = async ({ text, value }: TypeaheadInput): Promise<TypeaheadOutput> => {
const emptyResult: TypeaheadOutput = { suggestions: [] };
if (!value) {
return emptyResult;
}
const query = value.endText.getText();
const isValue = query[query.indexOf(text) - 1] === '=';
if (isValue || text === '=') {
return this.getTagValueCompletionItems(value);
}
return this.getTagsCompletionItems();
};
getTagsCompletionItems = (): TypeaheadOutput => {
const { tags } = this;
const suggestions: CompletionItemGroup[] = [];
if (tags?.length) {
suggestions.push({
label: `Tag`,
items: tags.map((tag) => ({ label: tag })),
});
}
return { suggestions };
};
async getTagValueCompletionItems(value: Value) {
const tags = value.endText.getText().split(' ');
let tagName = tags[tags.length - 1] ?? '';
tagName = tagName.split('=')[0];
const response = await this.request(`/api/v2/search/tag/${tagName}/values`, []);
const suggestions: CompletionItemGroup[] = [];
if (response && response.tagValues) {
suggestions.push({
label: `Tag Values`,
items: response.tagValues.map((tagValue: string) => ({ label: tagValue, insertText: `"${tagValue}"` })),
});
}
return { suggestions };
}
async getOptionsV1(tag: string): Promise<Array<SelectableValue<string>>> {
const response = await this.request(`/api/search/tag/${tag}/values`);
let options: Array<SelectableValue<string>> = [];
if (response && response.tagValues) {
options = response.tagValues.map((v: string) => ({
value: v,
label: v,
}));
}
return options;
}
async getOptionsV2(tag: string): Promise<Array<SelectableValue<string>>> {
const response = await this.request(`/api/v2/search/tag/${tag}/values`);
let options: Array<SelectableValue<string>> = [];
if (response && response.tagValues) {
options = response.tagValues.map((v: { type: string; value: string }) => ({
type: v.type,
value: v.value,
label: v.value,
}));
}
return options;
}
}