diff --git a/public/app/features/templating/formatRegistry.ts b/public/app/features/templating/formatRegistry.ts index ce8dbafb2bc..c981c25df44 100644 --- a/public/app/features/templating/formatRegistry.ts +++ b/public/app/features/templating/formatRegistry.ts @@ -1,7 +1,8 @@ import kbn from 'app/core/utils/kbn'; -import { Registry, RegistryItem, VariableModel, textUtil, dateTime } from '@grafana/data'; -import { map, isArray, replace } from 'lodash'; +import { dateTime, Registry, RegistryItem, textUtil, VariableModel } from '@grafana/data'; +import { isArray, map, replace } from 'lodash'; import { formatVariableLabel } from '../variables/shared/formatVariable'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/state/types'; export interface FormatOptions { value: any; @@ -204,7 +205,7 @@ export const formatRegistry = new Registry(() => { description: 'Format variables in their text representation. Example in multi variable scenario A + B + C.', formatter: (options, variable) => { if (typeof options.text === 'string') { - return options.text; + return options.value === ALL_VARIABLE_VALUE ? ALL_VARIABLE_TEXT : options.text; } const current = (variable as any)?.current; diff --git a/public/app/features/templating/template_srv.test.ts b/public/app/features/templating/template_srv.test.ts index ab973a3301f..1c433f277cc 100644 --- a/public/app/features/templating/template_srv.test.ts +++ b/public/app/features/templating/template_srv.test.ts @@ -1,7 +1,9 @@ import { dateTime, TimeRange } from '@grafana/data'; import { initTemplateSrv } from '../../../test/helpers/initTemplateSrv'; +import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput'; describe('templateSrv', () => { + silenceConsoleOutput(); let _templateSrv: any; describe('init', () => { @@ -253,6 +255,11 @@ describe('templateSrv', () => { expect(target).toBe('this.*.filters'); }); + it('should replace ${test:text} with "all" value', () => { + const target = _templateSrv.replace('this.${test:text}.filters', {}); + expect(target).toBe('this.All.filters'); + }); + it('should not escape custom all value', () => { const target = _templateSrv.replace('this.$test', {}, 'regex'); expect(target).toBe('this.*'); @@ -524,6 +531,13 @@ describe('templateSrv', () => { current: { value: '$__all', text: '' }, options: [{ value: '$__all' }, { value: 'db1', text: 'Database 1' }, { value: 'db2', text: 'Database 2' }], }, + { + type: 'custom', + name: 'custom_all_value', + allValue: 'CUSTOM_ALL', + current: { value: '$__all', text: '' }, + options: [{ value: '$__all' }, { value: 'A-Value', text: 'This A' }, { value: 'B-Value', text: 'This B' }], + }, ]); _templateSrv.updateIndex(); }); @@ -542,6 +556,11 @@ describe('templateSrv', () => { const target = _templateSrv.replaceWithText('Db: $databases'); expect(target).toBe('Db: All'); }); + + it('should replace $__all with All for values with custom all', () => { + const target = _templateSrv.replaceWithText('Custom: $custom_all_value'); + expect(target).toBe('Custom: All'); + }); }); describe('built in interval variables', () => { diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index a0174f56d08..0a881f69174 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -5,8 +5,8 @@ import { variableRegex } from '../variables/utils'; import { isAdHoc } from '../variables/guard'; import { VariableModel } from '../variables/types'; import { setTemplateSrv, TemplateSrv as BaseTemplateSrv } from '@grafana/runtime'; -import { formatRegistry, FormatOptions } from './formatRegistry'; -import { ALL_VARIABLE_TEXT } from '../variables/state/types'; +import { FormatOptions, formatRegistry } from './formatRegistry'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../variables/state/types'; interface FieldAccessorCache { [key: string]: (obj: any) => any; @@ -282,7 +282,7 @@ export class TemplateSrv implements BaseTemplateSrv { value = this.getAllValue(variable); text = ALL_VARIABLE_TEXT; // skip formatting of custom all values - if (variable.allValue) { + if (variable.allValue && fmt !== 'text') { return this.replace(value); } } @@ -302,7 +302,7 @@ export class TemplateSrv implements BaseTemplateSrv { } isAllValue(value: any) { - return value === '$__all' || (Array.isArray(value) && value[0] === '$__all'); + return value === ALL_VARIABLE_VALUE || (Array.isArray(value) && value[0] === ALL_VARIABLE_VALUE); } replaceWithText(target: string, scopedVars?: ScopedVars) { diff --git a/public/test/core/utils/silenceConsoleOutput.ts b/public/test/core/utils/silenceConsoleOutput.ts index 3205c7db7aa..cd63508ccbf 100644 --- a/public/test/core/utils/silenceConsoleOutput.ts +++ b/public/test/core/utils/silenceConsoleOutput.ts @@ -4,6 +4,7 @@ export const silenceConsoleOutput = () => { jest.spyOn(console, 'error').mockImplementation(jest.fn()); jest.spyOn(console, 'debug').mockImplementation(jest.fn()); jest.spyOn(console, 'info').mockImplementation(jest.fn()); + jest.spyOn(console, 'warn').mockImplementation(jest.fn()); }); afterEach(() => { @@ -11,5 +12,6 @@ export const silenceConsoleOutput = () => { jest.spyOn(console, 'error').mockRestore(); jest.spyOn(console, 'debug').mockRestore(); jest.spyOn(console, 'info').mockRestore(); + jest.spyOn(console, 'warn').mockRestore(); }); };