mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Templating: Makes so __searchFilter can be used as part of regular expression (#20103)
* Fix: Fixes searchfilter wildcard char in regular expressions Fixes: #20006 * Refactor: Uses TemplateSrv and ScopedVars instead * Docs: Updates docs with new format * Tests: Corrects test description
This commit is contained in:
parent
fc5cc4cbf9
commit
7aeed4d987
@ -114,19 +114,25 @@ variable with all possible values that exist in the wildcard position.
|
||||
You can also create nested variables that use other variables in their definition. For example
|
||||
`apps.$app.servers.*` uses the variable `$app` in its query definition.
|
||||
|
||||
#### Using `$__searchFilter` to filter results in Query Variable
|
||||
#### Using `__searchFilter` to filter results in Query Variable
|
||||
> Available from Grafana 6.5 and above
|
||||
|
||||
Using `$__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box.
|
||||
When nothing has been entered by the user the default value for `$__searchFilter` is `*`.
|
||||
Using `__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box.
|
||||
When nothing has been entered by the user the default value for `__searchFilter` is `*` and `` when used as part of a regular expression.
|
||||
|
||||
The example below shows how to use `$__searchFilter` as part of the query field to enable searching for `server` while the user types in the dropdown select box.
|
||||
The example below shows how to use `__searchFilter` as part of the query field to enable searching for `server` while the user types in the dropdown select box.
|
||||
|
||||
Query
|
||||
```bash
|
||||
apps.$app.servers.$__searchFilter
|
||||
```
|
||||
|
||||
TagValues
|
||||
```bash
|
||||
tag_values(server, server=~${__searchFilter:regex})
|
||||
```
|
||||
|
||||
|
||||
### Variable Usage
|
||||
|
||||
You can use a variable in a metric node path or as a parameter to a function.
|
||||
|
@ -276,17 +276,19 @@ the hosts variable only show hosts from the current selected region with a query
|
||||
SELECT hostname FROM my_host WHERE region IN($region)
|
||||
```
|
||||
|
||||
#### Using `$__searchFilter` to filter results in Query Variable
|
||||
#### Using `__searchFilter` to filter results in Query Variable
|
||||
> Available from Grafana 6.5 and above
|
||||
|
||||
Using `$__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box.
|
||||
When nothing has been entered by the user the default value for `$__searchFilter` is `%`.
|
||||
Using `__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box.
|
||||
When nothing has been entered by the user the default value for `__searchFilter` is `%`.
|
||||
|
||||
The example below shows how to use `$__searchFilter` as part of the query field to enable searching for `hostname` while the user types in the dropdown select box.
|
||||
> Important that you surround the `__searchFilter` expression with quotes as Grafana does not do this for you.
|
||||
|
||||
The example below shows how to use `__searchFilter` as part of the query field to enable searching for `hostname` while the user types in the dropdown select box.
|
||||
|
||||
Query
|
||||
```sql
|
||||
SELECT hostname FROM my_host WHERE hostname LIKE $__searchFilter
|
||||
SELECT hostname FROM my_host WHERE hostname LIKE '$__searchFilter'
|
||||
```
|
||||
|
||||
### Using Variables in Queries
|
||||
|
@ -282,17 +282,19 @@ the hosts variable only show hosts from the current selected region with a query
|
||||
SELECT hostname FROM host WHERE region IN($region)
|
||||
```
|
||||
|
||||
#### Using `$__searchFilter` to filter results in Query Variable
|
||||
#### Using `__searchFilter` to filter results in Query Variable
|
||||
> Available from Grafana 6.5 and above
|
||||
|
||||
Using `$__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box.
|
||||
When nothing has been entered by the user the default value for `$__searchFilter` is `%`.
|
||||
Using `__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box.
|
||||
When nothing has been entered by the user the default value for `__searchFilter` is `%`.
|
||||
|
||||
The example below shows how to use `$__searchFilter` as part of the query field to enable searching for `hostname` while the user types in the dropdown select box.
|
||||
> Important that you surround the `__searchFilter` expression with quotes as Grafana does not do this for you.
|
||||
|
||||
The example below shows how to use `__searchFilter` as part of the query field to enable searching for `hostname` while the user types in the dropdown select box.
|
||||
|
||||
Query
|
||||
```sql
|
||||
SELECT hostname FROM my_host WHERE hostname LIKE $__searchFilter
|
||||
SELECT hostname FROM my_host WHERE hostname LIKE '$__searchFilter'
|
||||
```
|
||||
|
||||
### Using Variables in Queries
|
||||
|
@ -2,9 +2,10 @@ import {
|
||||
assignModelProperties,
|
||||
containsSearchFilter,
|
||||
containsVariable,
|
||||
interpolateSearchFilter,
|
||||
getSearchFilterScopedVar,
|
||||
SEARCH_FILTER_VARIABLE,
|
||||
} from '../variable';
|
||||
import { ScopedVars } from '@grafana/data';
|
||||
|
||||
describe('containsVariable', () => {
|
||||
describe('when checking if a string contains a variable', () => {
|
||||
@ -92,84 +93,164 @@ describe('containsSearchFilter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe(`when called with a query with ${SEARCH_FILTER_VARIABLE}`, () => {
|
||||
it('then it should return false', () => {
|
||||
const result = containsSearchFilter(`$app.${SEARCH_FILTER_VARIABLE}`);
|
||||
describe(`when called with a query with $${SEARCH_FILTER_VARIABLE}`, () => {
|
||||
it('then it should return true', () => {
|
||||
const result = containsSearchFilter(`$app.$${SEARCH_FILTER_VARIABLE}`);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`when called with a query with [[${SEARCH_FILTER_VARIABLE}]]`, () => {
|
||||
it('then it should return true', () => {
|
||||
const result = containsSearchFilter(`$app.[[${SEARCH_FILTER_VARIABLE}]]`);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`when called with a query with \$\{${SEARCH_FILTER_VARIABLE}:regex\}`, () => {
|
||||
it('then it should return true', () => {
|
||||
const result = containsSearchFilter(`$app.\$\{${SEARCH_FILTER_VARIABLE}:regex\}`);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('interpolateSearchFilter', () => {
|
||||
describe('when called with a query without ${SEARCH_FILTER_VARIABLE}', () => {
|
||||
it('then it should return query', () => {
|
||||
const query = '$app.*';
|
||||
const options = { searchFilter: 'filter' };
|
||||
const wildcardChar = '*';
|
||||
const quoteLiteral = false;
|
||||
interface GetSearchFilterScopedVarScenario {
|
||||
query: string;
|
||||
wildcardChar: string;
|
||||
options: { searchFilter?: string };
|
||||
expected: ScopedVars;
|
||||
}
|
||||
|
||||
const result = interpolateSearchFilter({
|
||||
query,
|
||||
options,
|
||||
wildcardChar,
|
||||
quoteLiteral,
|
||||
});
|
||||
const scenarios: GetSearchFilterScopedVarScenario[] = [
|
||||
// testing the $__searchFilter notation
|
||||
{
|
||||
query: 'abc.$__searchFilter',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: '' },
|
||||
expected: { __searchFilter: { value: '', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.$__searchFilter',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: '' },
|
||||
expected: { __searchFilter: { value: '*', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.$__searchFilter',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: { __searchFilter: { value: 'a', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.$__searchFilter',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: { __searchFilter: { value: 'a*', text: '' } },
|
||||
},
|
||||
// testing the [[__searchFilter]] notation
|
||||
{
|
||||
query: 'abc.[[__searchFilter]]',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: '' },
|
||||
expected: { __searchFilter: { value: '', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.[[__searchFilter]]',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: '' },
|
||||
expected: { __searchFilter: { value: '*', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.[[__searchFilter]]',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: { __searchFilter: { value: 'a', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.[[__searchFilter]]',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: { __searchFilter: { value: 'a*', text: '' } },
|
||||
},
|
||||
// testing the ${__searchFilter:fmt} notation
|
||||
{
|
||||
query: 'abc.${__searchFilter:regex}',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: '' },
|
||||
expected: { __searchFilter: { value: '', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.${__searchFilter:regex}',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: '' },
|
||||
expected: { __searchFilter: { value: '*', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.${__searchFilter:regex}',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: { __searchFilter: { value: 'a', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.${__searchFilter:regex}',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: { __searchFilter: { value: 'a*', text: '' } },
|
||||
},
|
||||
// testing the no options
|
||||
{
|
||||
query: 'abc.$__searchFilter',
|
||||
wildcardChar: '',
|
||||
options: null,
|
||||
expected: { __searchFilter: { value: '', text: '' } },
|
||||
},
|
||||
{
|
||||
query: 'abc.$__searchFilter',
|
||||
wildcardChar: '*',
|
||||
options: null,
|
||||
expected: { __searchFilter: { value: '*', text: '' } },
|
||||
},
|
||||
// testing the no search filter at all
|
||||
{
|
||||
query: 'abc.$def',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: '' },
|
||||
expected: {},
|
||||
},
|
||||
{
|
||||
query: 'abc.$def',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: '' },
|
||||
expected: {},
|
||||
},
|
||||
{
|
||||
query: 'abc.$def',
|
||||
wildcardChar: '',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: {},
|
||||
},
|
||||
{
|
||||
query: 'abc.$def',
|
||||
wildcardChar: '*',
|
||||
options: { searchFilter: 'a' },
|
||||
expected: {},
|
||||
},
|
||||
];
|
||||
|
||||
expect(result).toEqual(query);
|
||||
});
|
||||
});
|
||||
scenarios.map(scenario => {
|
||||
describe('getSearchFilterScopedVar', () => {
|
||||
describe(`when called with query:'${scenario.query}'`, () => {
|
||||
describe(`and wildcardChar:'${scenario.wildcardChar}'`, () => {
|
||||
describe(`and options:'${JSON.stringify(scenario.options, null, 0)}'`, () => {
|
||||
it(`then the result should be ${JSON.stringify(scenario.expected, null, 0)}`, () => {
|
||||
const { expected, ...args } = scenario;
|
||||
|
||||
describe(`when called with a query with ${SEARCH_FILTER_VARIABLE}`, () => {
|
||||
const query = `$app.${SEARCH_FILTER_VARIABLE}`;
|
||||
|
||||
describe('and no searchFilter is given', () => {
|
||||
it(`then ${SEARCH_FILTER_VARIABLE} should be replaced by wildchar character`, () => {
|
||||
const options = {};
|
||||
const wildcardChar = '*';
|
||||
const quoteLiteral = false;
|
||||
|
||||
const result = interpolateSearchFilter({
|
||||
query,
|
||||
options,
|
||||
wildcardChar,
|
||||
quoteLiteral,
|
||||
});
|
||||
|
||||
expect(result).toEqual(`$app.*`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and searchFilter is given', () => {
|
||||
const options = { searchFilter: 'filter' };
|
||||
|
||||
it(`then ${SEARCH_FILTER_VARIABLE} should be replaced with searchfilter and wildchar character`, () => {
|
||||
const wildcardChar = '*';
|
||||
const quoteLiteral = false;
|
||||
|
||||
const result = interpolateSearchFilter({
|
||||
query,
|
||||
options,
|
||||
wildcardChar,
|
||||
quoteLiteral,
|
||||
});
|
||||
|
||||
expect(result).toEqual(`$app.filter*`);
|
||||
});
|
||||
|
||||
describe(`and quoteLiteral is used`, () => {
|
||||
it(`then the literal should be quoted`, () => {
|
||||
const wildcardChar = '*';
|
||||
const quoteLiteral = true;
|
||||
|
||||
const result = interpolateSearchFilter({
|
||||
query,
|
||||
options,
|
||||
wildcardChar,
|
||||
quoteLiteral,
|
||||
expect(getSearchFilterScopedVar(args)).toEqual(expected);
|
||||
});
|
||||
|
||||
expect(result).toEqual(`$app.'filter*'`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import _ from 'lodash';
|
||||
import { variableRegex } from 'app/features/templating/variable';
|
||||
import { TimeRange, ScopedVars } from '@grafana/data';
|
||||
import { ScopedVars, TimeRange } from '@grafana/data';
|
||||
|
||||
function luceneEscape(value: string) {
|
||||
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, '\\$1');
|
||||
|
@ -1,5 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { assignModelProperties } from 'app/core/utils/model_utils';
|
||||
import { ScopedVars } from '@grafana/data';
|
||||
|
||||
/*
|
||||
* This regex matches 3 types of variable reference with an optional format specifier
|
||||
@ -15,31 +16,32 @@ export const variableRegexExec = (variableString: string) => {
|
||||
return variableRegex.exec(variableString);
|
||||
};
|
||||
|
||||
export const SEARCH_FILTER_VARIABLE = '$__searchFilter';
|
||||
export const SEARCH_FILTER_VARIABLE = '__searchFilter';
|
||||
|
||||
export const containsSearchFilter = (query: string): boolean =>
|
||||
query ? query.indexOf(SEARCH_FILTER_VARIABLE) !== -1 : false;
|
||||
|
||||
export interface InterpolateSearchFilterOptions {
|
||||
export const getSearchFilterScopedVar = (args: {
|
||||
query: string;
|
||||
options: any;
|
||||
wildcardChar: string;
|
||||
quoteLiteral: boolean;
|
||||
}
|
||||
|
||||
export const interpolateSearchFilter = (args: InterpolateSearchFilterOptions): string => {
|
||||
const { query, wildcardChar, quoteLiteral } = args;
|
||||
let { options } = args;
|
||||
|
||||
options: { searchFilter?: string };
|
||||
}): ScopedVars => {
|
||||
const { query, wildcardChar } = args;
|
||||
if (!containsSearchFilter(query)) {
|
||||
return query;
|
||||
return {};
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
let { options } = args;
|
||||
|
||||
const filter = options.searchFilter ? `${options.searchFilter}${wildcardChar}` : `${wildcardChar}`;
|
||||
const replaceValue = quoteLiteral ? `'${filter}'` : filter;
|
||||
options = options || { searchFilter: '' };
|
||||
const value = options.searchFilter ? `${options.searchFilter}${wildcardChar}` : `${wildcardChar}`;
|
||||
|
||||
return query.replace(SEARCH_FILTER_VARIABLE, replaceValue);
|
||||
return {
|
||||
__searchFilter: {
|
||||
value,
|
||||
text: '',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export enum VariableRefresh {
|
||||
|
@ -7,7 +7,7 @@ import { BackendSrv } from 'app/core/services/backend_srv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
//Types
|
||||
import { GraphiteQuery } from './types';
|
||||
import { interpolateSearchFilter } from '../../../features/templating/variable';
|
||||
import { getSearchFilterScopedVar } from '../../../features/templating/variable';
|
||||
|
||||
export class GraphiteDatasource {
|
||||
basicAuth: string;
|
||||
@ -251,12 +251,10 @@ export class GraphiteDatasource {
|
||||
|
||||
metricFindQuery(query: string, optionalOptions: any) {
|
||||
const options: any = optionalOptions || {};
|
||||
const interpolatedQuery = interpolateSearchFilter({
|
||||
query: this.templateSrv.replace(query),
|
||||
options: optionalOptions,
|
||||
wildcardChar: '*',
|
||||
quoteLiteral: false,
|
||||
});
|
||||
let interpolatedQuery = this.templateSrv.replace(
|
||||
query,
|
||||
getSearchFilterScopedVar({ query, wildcardChar: '', options: optionalOptions })
|
||||
);
|
||||
|
||||
// special handling for tag_values(<tag>[,<expression>]*), this is used for template variables
|
||||
let matches = interpolatedQuery.match(/^tag_values\(([^,]+)((, *[^,]+)*)\)$/);
|
||||
@ -289,6 +287,11 @@ export class GraphiteDatasource {
|
||||
return this.getTagsAutoComplete(expressions, undefined, options);
|
||||
}
|
||||
|
||||
interpolatedQuery = this.templateSrv.replace(
|
||||
query,
|
||||
getSearchFilterScopedVar({ query, wildcardChar: '*', options: optionalOptions })
|
||||
);
|
||||
|
||||
const httpOptions: any = {
|
||||
method: 'POST',
|
||||
url: '/metrics/find',
|
||||
|
@ -7,7 +7,7 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
//Types
|
||||
import { MysqlQueryForInterpolation } from './types';
|
||||
import { interpolateSearchFilter } from '../../../features/templating/variable';
|
||||
import { getSearchFilterScopedVar } from '../../../features/templating/variable';
|
||||
|
||||
export class MysqlDatasource {
|
||||
id: any;
|
||||
@ -131,12 +131,11 @@ export class MysqlDatasource {
|
||||
refId = optionalOptions.variable.name;
|
||||
}
|
||||
|
||||
const rawSql = interpolateSearchFilter({
|
||||
query: this.templateSrv.replace(query, {}, this.interpolateVariable),
|
||||
options: optionalOptions,
|
||||
wildcardChar: '%',
|
||||
quoteLiteral: true,
|
||||
});
|
||||
const rawSql = this.templateSrv.replace(
|
||||
query,
|
||||
getSearchFilterScopedVar({ query, wildcardChar: '%', options: optionalOptions }),
|
||||
this.interpolateVariable
|
||||
);
|
||||
|
||||
const interpolatedQuery = {
|
||||
refId: refId,
|
||||
|
@ -124,7 +124,7 @@ describe('MySQLDatasource', () => {
|
||||
describe('When performing metricFindQuery with $__searchFilter and a searchFilter is given', () => {
|
||||
let results: any;
|
||||
let calledWith: any = {};
|
||||
const query = 'select title from atable where title LIKE $__searchFilter';
|
||||
const query = "select title from atable where title LIKE '$__searchFilter'";
|
||||
const response = {
|
||||
results: {
|
||||
tempvar: {
|
||||
@ -162,7 +162,7 @@ describe('MySQLDatasource', () => {
|
||||
describe('When performing metricFindQuery with $__searchFilter but no searchFilter is given', () => {
|
||||
let results: any;
|
||||
let calledWith: any = {};
|
||||
const query = 'select title from atable where title LIKE $__searchFilter';
|
||||
const query = "select title from atable where title LIKE '$__searchFilter'";
|
||||
const response = {
|
||||
results: {
|
||||
tempvar: {
|
||||
|
@ -7,7 +7,7 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
//Types
|
||||
import { PostgresQueryForInterpolation } from './types';
|
||||
import { interpolateSearchFilter } from '../../../features/templating/variable';
|
||||
import { getSearchFilterScopedVar } from '../../../features/templating/variable';
|
||||
|
||||
export class PostgresDatasource {
|
||||
id: any;
|
||||
@ -127,18 +127,17 @@ export class PostgresDatasource {
|
||||
.then((data: any) => this.responseParser.transformAnnotationResponse(options, data));
|
||||
}
|
||||
|
||||
metricFindQuery(query: string, optionalOptions: { variable?: any }) {
|
||||
metricFindQuery(query: string, optionalOptions: { variable?: any; searchFilter?: string }) {
|
||||
let refId = 'tempvar';
|
||||
if (optionalOptions && optionalOptions.variable && optionalOptions.variable.name) {
|
||||
refId = optionalOptions.variable.name;
|
||||
}
|
||||
|
||||
const rawSql = interpolateSearchFilter({
|
||||
query: this.templateSrv.replace(query, {}, this.interpolateVariable),
|
||||
options: optionalOptions,
|
||||
wildcardChar: '%',
|
||||
quoteLiteral: true,
|
||||
});
|
||||
const rawSql = this.templateSrv.replace(
|
||||
query,
|
||||
getSearchFilterScopedVar({ query, wildcardChar: '%', options: optionalOptions }),
|
||||
this.interpolateVariable
|
||||
);
|
||||
|
||||
const interpolatedQuery = {
|
||||
refId: refId,
|
||||
|
@ -131,7 +131,7 @@ describe('PostgreSQLDatasource', () => {
|
||||
describe('When performing metricFindQuery with $__searchFilter and a searchFilter is given', () => {
|
||||
let results: any;
|
||||
let calledWith: any = {};
|
||||
const query = 'select title from atable where title LIKE $__searchFilter';
|
||||
const query = "select title from atable where title LIKE '$__searchFilter'";
|
||||
const response = {
|
||||
results: {
|
||||
tempvar: {
|
||||
@ -169,7 +169,7 @@ describe('PostgreSQLDatasource', () => {
|
||||
describe('When performing metricFindQuery with $__searchFilter but no searchFilter is given', () => {
|
||||
let results: any;
|
||||
let calledWith: any = {};
|
||||
const query = 'select title from atable where title LIKE $__searchFilter';
|
||||
const query = "select title from atable where title LIKE '$__searchFilter'";
|
||||
const response = {
|
||||
results: {
|
||||
tempvar: {
|
||||
|
@ -13,7 +13,7 @@ import { queryMetricTree } from './metricTree';
|
||||
import { from, merge, Observable } from 'rxjs';
|
||||
import { runStream } from './runStreams';
|
||||
import templateSrv from 'app/features/templating/template_srv';
|
||||
import { interpolateSearchFilter } from '../../../features/templating/variable';
|
||||
import { getSearchFilterScopedVar } from '../../../features/templating/variable';
|
||||
|
||||
type TestData = TimeSeries | TableData;
|
||||
|
||||
@ -126,12 +126,10 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> {
|
||||
metricFindQuery(query: string, options: any) {
|
||||
return new Promise<MetricFindValue[]>((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
const interpolatedQuery = interpolateSearchFilter({
|
||||
query: templateSrv.replace(query),
|
||||
options,
|
||||
wildcardChar: '*',
|
||||
quoteLiteral: false,
|
||||
});
|
||||
const interpolatedQuery = templateSrv.replace(
|
||||
query,
|
||||
getSearchFilterScopedVar({ query, wildcardChar: '*', options })
|
||||
);
|
||||
const children = queryMetricTree(interpolatedQuery);
|
||||
const items = children.map(item => ({ value: item.name, text: item.name }));
|
||||
resolve(items);
|
||||
|
Loading…
Reference in New Issue
Block a user