language_provider.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { Value } from 'slate';
  2. import { HistoryItem, LanguageProvider, SelectableValue } from '@grafana/data';
  3. import { CompletionItemGroup, TypeaheadInput, TypeaheadOutput } from '@grafana/ui';
  4. import { TempoDatasource } from './datasource';
  5. export default class TempoLanguageProvider extends LanguageProvider {
  6. datasource: TempoDatasource;
  7. tags?: string[];
  8. constructor(datasource: TempoDatasource, initialValues?: any) {
  9. super();
  10. this.datasource = datasource;
  11. Object.assign(this, initialValues);
  12. }
  13. request = async (url: string, params = {}) => {
  14. const res = await this.datasource.metadataRequest(url, params);
  15. return res?.data;
  16. };
  17. start = async () => {
  18. await this.fetchTags();
  19. return [];
  20. };
  21. async fetchTags() {
  22. const response = await this.request('/api/search/tags', []);
  23. this.tags = response.tagNames;
  24. }
  25. provideCompletionItems = async (
  26. { prefix, text, value, labelKey, wrapperClasses }: TypeaheadInput,
  27. context: { history: Array<HistoryItem<any>> } = { history: [] }
  28. ): Promise<TypeaheadOutput> => {
  29. const emptyResult: TypeaheadOutput = { suggestions: [] };
  30. if (!value) {
  31. return emptyResult;
  32. }
  33. const query = value.endText.getText();
  34. const isValue = query[query.indexOf(text) - 1] === '=';
  35. if (isValue || text === '=') {
  36. return this.getTagValueCompletionItems(value);
  37. }
  38. return this.getTagsCompletionItems();
  39. };
  40. getTagsCompletionItems = (): TypeaheadOutput => {
  41. const { tags } = this;
  42. const suggestions: CompletionItemGroup[] = [];
  43. if (tags?.length) {
  44. suggestions.push({
  45. label: `Tag`,
  46. items: tags.map((tag) => ({ label: tag })),
  47. });
  48. }
  49. return { suggestions };
  50. };
  51. async getTagValueCompletionItems(value: Value) {
  52. const tags = value.endText.getText().split(' ');
  53. let tagName = tags[tags.length - 1] ?? '';
  54. tagName = tagName.split('=')[0];
  55. const response = await this.request(`/api/search/tag/${tagName}/values`, []);
  56. const suggestions: CompletionItemGroup[] = [];
  57. if (response && response.tagValues) {
  58. suggestions.push({
  59. label: `Tag Values`,
  60. items: response.tagValues.map((tagValue: string) => ({ label: tagValue })),
  61. });
  62. }
  63. return { suggestions };
  64. }
  65. async getOptions(tag: string): Promise<Array<SelectableValue<string>>> {
  66. const response = await this.request(`/api/search/tag/${tag}/values`);
  67. let options: Array<SelectableValue<string>> = [];
  68. if (response && response.tagValues) {
  69. options = response.tagValues.map((v: string) => ({
  70. value: v,
  71. label: v,
  72. }));
  73. }
  74. return options;
  75. }
  76. }