TemplateVariables: Introduces $__searchFilter to Query Variables (#19858)
* WIP: Initial hardcoded version * Feature: Introduces SearchFiltering to Graphite * Feature: Adds searchFiltering to MySql * Tests: Adds tests to Graphite and MySql * Feature: Adds $__searchFilter to TestData * Refactor: Adds searchFilter to Postgres and extracts function * Tests: Adds tests to variable * Refactor: Adds debounce and lodash import optimization * Docs: Adds documentation * Refactor: Removes unused function and fixes typo * Docs: Updates docs * Fixed issue with UI not updating when no was used due to async func and no .apply in the non lazy path
This commit is contained in:
committed by
Torkel Ödegaard
parent
c674fa1d79
commit
cb0e80e7b9
+13
-7
@@ -1,18 +1,18 @@
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
DataSourceApi,
|
||||
DataQueryRequest,
|
||||
DataSourceInstanceSettings,
|
||||
DataQueryResponse,
|
||||
DataSourceApi,
|
||||
DataSourceInstanceSettings,
|
||||
MetricFindValue,
|
||||
} from '@grafana/ui';
|
||||
import { TableData, TimeSeries } from '@grafana/data';
|
||||
import { TestDataQuery, Scenario } from './types';
|
||||
import { Scenario, TestDataQuery } from './types';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { queryMetricTree } from './metricTree';
|
||||
import { Observable, from, merge } from 'rxjs';
|
||||
import { from, merge, Observable } from 'rxjs';
|
||||
import { runStream } from './runStreams';
|
||||
import templateSrv from 'app/features/templating/template_srv';
|
||||
import { interpolateSearchFilter } from '../../../features/templating/variable';
|
||||
|
||||
type TestData = TimeSeries | TableData;
|
||||
|
||||
@@ -119,10 +119,16 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> {
|
||||
return getBackendSrv().get('/api/tsdb/testdata/scenarios');
|
||||
}
|
||||
|
||||
metricFindQuery(query: string) {
|
||||
metricFindQuery(query: string, options: any) {
|
||||
return new Promise<MetricFindValue[]>((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
const children = queryMetricTree(templateSrv.replace(query));
|
||||
const interpolatedQuery = interpolateSearchFilter({
|
||||
query: templateSrv.replace(query),
|
||||
options,
|
||||
wildcardChar: '*',
|
||||
quoteLiteral: false,
|
||||
});
|
||||
const children = queryMetricTree(interpolatedQuery);
|
||||
const items = children.map(item => ({ value: item.name, text: item.name }));
|
||||
resolve(items);
|
||||
}, 100);
|
||||
|
||||
@@ -16,4 +16,9 @@ describe('MetricTree', () => {
|
||||
const nodes = queryMetricTree('A.{AB,AC}.*').map(i => i.name);
|
||||
expect(nodes).toEqual(['ABA', 'ABB', 'ABC', 'ACA', 'ACB', 'ACC']);
|
||||
});
|
||||
|
||||
it('queryMetric tree supports wildcard matching', () => {
|
||||
const nodes = queryMetricTree('A.AB.AB*').map(i => i.name);
|
||||
expect(nodes).toEqual(['ABA', 'ABB', 'ABC']);
|
||||
});
|
||||
});
|
||||
|
||||
+11
-1
@@ -35,6 +35,10 @@ function buildMetricTree(parent: string, depth: number): TreeNode[] {
|
||||
}
|
||||
|
||||
function queryTree(children: TreeNode[], query: string[], queryIndex: number): TreeNode[] {
|
||||
if (queryIndex >= query.length) {
|
||||
return children;
|
||||
}
|
||||
|
||||
if (query[queryIndex] === '*') {
|
||||
return children;
|
||||
}
|
||||
@@ -50,7 +54,13 @@ function queryTree(children: TreeNode[], query: string[], queryIndex: number): T
|
||||
|
||||
for (const node of children) {
|
||||
for (const nameToMatch of namesToMatch) {
|
||||
if (node.name === nameToMatch) {
|
||||
if (nameToMatch.indexOf('*') !== -1) {
|
||||
const pattern = nameToMatch.replace('*', '');
|
||||
const regex = new RegExp(`^${pattern}.*`, 'gi');
|
||||
if (regex.test(node.name)) {
|
||||
result = result.concat(queryTree([node], query, queryIndex + 1));
|
||||
}
|
||||
} else if (node.name === nameToMatch) {
|
||||
result = result.concat(queryTree(node.children, query, queryIndex + 1));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user