mirror of
https://github.com/grafana/grafana.git
synced 2025-01-08 15:13:30 -06:00
DataLinks: Fix bug where links which use built in variables could be hidden (#71372)
This commit is contained in:
parent
ceb702b96a
commit
7ccd73c9ef
@ -644,86 +644,47 @@ describe('explore links utils', () => {
|
||||
});
|
||||
|
||||
describe('getVariableUsageInfo', () => {
|
||||
it('returns true when query contains variables and all variables are used', () => {
|
||||
const dataLink = {
|
||||
function makeDataLinkWithQuery(query: string): DataLink {
|
||||
return {
|
||||
url: '',
|
||||
title: '',
|
||||
internal: {
|
||||
datasourceUid: 'uid',
|
||||
datasourceName: 'dsName',
|
||||
query: { query: 'test ${testVal}' },
|
||||
query: { query },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function allVariablesDefinedInQuery(query: string) {
|
||||
const scopedVars = {
|
||||
testVal: { text: '', value: 'val1' },
|
||||
};
|
||||
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars).allVariablesDefined;
|
||||
return getVariableUsageInfo(makeDataLinkWithQuery(query), scopedVars).allVariablesDefined;
|
||||
}
|
||||
|
||||
expect(dataLinkRtnVal).toBe(true);
|
||||
it('returns true when query contains variables and all variables are used', () => {
|
||||
expect(allVariablesDefinedInQuery('test ${testVal}')).toBe(true);
|
||||
});
|
||||
|
||||
it('ignores global variables', () => {
|
||||
expect(allVariablesDefinedInQuery('test ${__rate_interval} $__from $__to')).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when query contains variables and no variables are used', () => {
|
||||
const dataLink = {
|
||||
url: '',
|
||||
title: '',
|
||||
internal: {
|
||||
datasourceUid: 'uid',
|
||||
datasourceName: 'dsName',
|
||||
query: { query: 'test ${diffVar}' },
|
||||
},
|
||||
};
|
||||
const scopedVars = {
|
||||
testVal: { text: '', value: 'val1' },
|
||||
};
|
||||
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars).allVariablesDefined;
|
||||
|
||||
expect(dataLinkRtnVal).toBe(false);
|
||||
expect(allVariablesDefinedInQuery('test ${diffVar}')).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false when query contains variables and some variables are used', () => {
|
||||
const dataLink = {
|
||||
url: '',
|
||||
title: '',
|
||||
internal: {
|
||||
datasourceUid: 'uid',
|
||||
datasourceName: 'dsName',
|
||||
query: { query: 'test ${testVal} ${diffVar}' },
|
||||
},
|
||||
};
|
||||
const scopedVars = {
|
||||
testVal: { text: '', value: 'val1' },
|
||||
};
|
||||
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars).allVariablesDefined;
|
||||
expect(dataLinkRtnVal).toBe(false);
|
||||
expect(allVariablesDefinedInQuery('test ${testVal} ${diffVar}')).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true when query contains no variables', () => {
|
||||
const dataLink = {
|
||||
url: '',
|
||||
title: '',
|
||||
internal: {
|
||||
datasourceUid: 'uid',
|
||||
datasourceName: 'dsName',
|
||||
query: { query: 'test' },
|
||||
},
|
||||
};
|
||||
const scopedVars = {
|
||||
testVal: { text: '', value: 'val1' },
|
||||
};
|
||||
const dataLinkRtnVal = getVariableUsageInfo(dataLink, scopedVars).allVariablesDefined;
|
||||
expect(dataLinkRtnVal).toBe(true);
|
||||
expect(allVariablesDefinedInQuery('test')).toBe(true);
|
||||
});
|
||||
|
||||
it('returns deduplicated list of variables', () => {
|
||||
const dataLink = {
|
||||
url: '',
|
||||
title: '',
|
||||
internal: {
|
||||
datasourceUid: 'uid',
|
||||
datasourceName: 'dsName',
|
||||
query: { query: 'test ${test} ${foo} ${test:raw} $test' },
|
||||
},
|
||||
};
|
||||
const dataLink = makeDataLinkWithQuery('test ${test} ${foo} ${test:raw} $test');
|
||||
const scopedVars = {
|
||||
testVal: { text: '', value: 'val1' },
|
||||
};
|
||||
|
@ -233,6 +233,23 @@ export function useLinks(range: TimeRange, splitOpenFn?: SplitOpen) {
|
||||
);
|
||||
}
|
||||
|
||||
// See https://grafana.com/docs/grafana/latest/dashboards/variables/add-template-variables/#global-variables
|
||||
const builtInVariables = [
|
||||
'__from',
|
||||
'__to',
|
||||
'__interval',
|
||||
'__interval_ms',
|
||||
'__org',
|
||||
'__user',
|
||||
'__range',
|
||||
'__rate_interval',
|
||||
'__timeFilter',
|
||||
'timeFilter',
|
||||
// These are only applicable in dashboards so should not affect this for Explore
|
||||
// '__dashboard',
|
||||
//'__name',
|
||||
];
|
||||
|
||||
/**
|
||||
* Use variable map from templateSrv to determine if all variables have values
|
||||
* @param query
|
||||
@ -244,14 +261,20 @@ export function getVariableUsageInfo<T extends DataLink>(
|
||||
): { variables: VariableInterpolation[]; allVariablesDefined: boolean } {
|
||||
let variables: VariableInterpolation[] = [];
|
||||
const replaceFn = getTemplateSrv().replace.bind(getTemplateSrv());
|
||||
// This adds info to the variables array while interpolating
|
||||
replaceFn(getStringsFromObject(query), scopedVars, undefined, variables);
|
||||
variables = uniqBy(variables, 'variableName');
|
||||
return {
|
||||
variables: variables,
|
||||
allVariablesDefined: variables.every((variable) => variable.found),
|
||||
allVariablesDefined: variables
|
||||
// We filter out builtin variables as they should be always defined but sometimes only later, like
|
||||
// __range_interval which is defined in prometheus at query time.
|
||||
.filter((v) => !builtInVariables.includes(v.variableName))
|
||||
.every((variable) => variable.found),
|
||||
};
|
||||
}
|
||||
|
||||
// Recursively get all strings from an object into a simple list with space as separator.
|
||||
function getStringsFromObject(obj: Object): string {
|
||||
let acc = '';
|
||||
let k: keyof typeof obj;
|
||||
|
Loading…
Reference in New Issue
Block a user