mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PanelInspect: Interpolates variables in CSV file name (#31936)
* PanelInspect: Variables in CSV file name are interpolated * Chore: fixes failing test
This commit is contained in:
parent
3e66328deb
commit
66177e9463
@ -3,6 +3,7 @@ import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import {
|
||||
applyFieldOverrides,
|
||||
applyRawFieldOverrides,
|
||||
CSVConfig,
|
||||
DataFrame,
|
||||
DataTransformerID,
|
||||
dateTimeFormat,
|
||||
@ -10,9 +11,8 @@ import {
|
||||
SelectableValue,
|
||||
toCSV,
|
||||
transformDataFrame,
|
||||
CSVConfig,
|
||||
} from '@grafana/data';
|
||||
import { Button, Container, Field, HorizontalGroup, Spinner, Select, Switch, Table, VerticalGroup } from '@grafana/ui';
|
||||
import { Button, Container, Field, HorizontalGroup, Select, Spinner, Switch, Table, VerticalGroup } from '@grafana/ui';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { getPanelInspectorStyles } from './styles';
|
||||
@ -94,7 +94,7 @@ export class InspectDataTab extends PureComponent<Props, State> {
|
||||
type: 'text/csv;charset=utf-8',
|
||||
});
|
||||
const transformation = transformId !== DataTransformerID.noop ? '-as-' + transformId.toLocaleLowerCase() : '';
|
||||
const fileName = `${panel.title}-data${transformation}-${dateTimeFormat(new Date())}.csv`;
|
||||
const fileName = `${panel.getDisplayTitle()}-data${transformation}-${dateTimeFormat(new Date())}.csv`;
|
||||
saveAs(blob, fileName);
|
||||
};
|
||||
|
||||
|
@ -37,6 +37,7 @@ function setupTestContext(options: Partial<Props>) {
|
||||
events: { subscribe: jest.fn() },
|
||||
getQueryRunner: () => panelQueryRunner,
|
||||
getOptions: jest.fn(),
|
||||
getDisplayTitle: jest.fn(),
|
||||
} as unknown) as PanelModel,
|
||||
dashboard: ({
|
||||
panelInitialized: jest.fn(),
|
||||
|
@ -28,7 +28,7 @@ export interface Props {
|
||||
|
||||
export const PanelHeader: FC<Props> = ({ panel, error, isViewing, isEditing, data, alertState, dashboard }) => {
|
||||
const onCancelQuery = () => panel.getQueryRunner().cancelQuery();
|
||||
const title = panel.replaceVariables(panel.title, {}, 'text');
|
||||
const title = panel.getDisplayTitle();
|
||||
const className = cx('panel-header', !(isViewing || isEditing) ? 'grid-drag-handle' : '');
|
||||
|
||||
return (
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { PanelModel } from './PanelModel';
|
||||
import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks';
|
||||
import {
|
||||
DataLinkBuiltInVars,
|
||||
FieldConfigProperty,
|
||||
PanelData,
|
||||
PanelProps,
|
||||
standardEditorsRegistry,
|
||||
standardFieldConfigEditorRegistry,
|
||||
PanelData,
|
||||
DataLinkBuiltInVars,
|
||||
VariableModel,
|
||||
} from '@grafana/data';
|
||||
import { ComponentClass } from 'react';
|
||||
import { PanelQueryRunner } from '../../query/state/PanelQueryRunner';
|
||||
@ -17,6 +16,7 @@ import { setTemplateSrv } from '@grafana/runtime';
|
||||
import { variableAdapters } from '../../variables/adapters';
|
||||
import { createQueryVariableAdapter } from '../../variables/query/adapter';
|
||||
import { mockStandardFieldConfigOptions } from '../../../../test/helpers/fieldConfig';
|
||||
import { queryBuilder } from 'app/features/variables/shared/testing/builders';
|
||||
|
||||
standardFieldConfigEditorRegistry.setInit(() => mockStandardFieldConfigOptions());
|
||||
standardEditorsRegistry.setInit(() => mockStandardFieldConfigOptions());
|
||||
@ -28,16 +28,15 @@ setTimeSrv({
|
||||
}),
|
||||
} as any);
|
||||
|
||||
const getVariables = () => variablesMock;
|
||||
const getVariableWithName = (name: string) => variablesMock.filter((v) => v.name === name)[0];
|
||||
const getFilteredVariables = jest.fn();
|
||||
|
||||
setTemplateSrv(
|
||||
new TemplateSrv({
|
||||
// @ts-ignore
|
||||
getVariables: () => {
|
||||
return variablesMock;
|
||||
},
|
||||
// @ts-ignore
|
||||
getVariableWithName: (name: string) => {
|
||||
return variablesMock.filter((v) => v.name === name)[0];
|
||||
},
|
||||
getVariables,
|
||||
getVariableWithName,
|
||||
getFilteredVariables,
|
||||
})
|
||||
);
|
||||
|
||||
@ -223,7 +222,7 @@ describe('PanelModel', () => {
|
||||
|
||||
it('should interpolate $__all_variables variable', () => {
|
||||
const out = model.replaceVariables(`/d/1?$${DataLinkBuiltInVars.includeVars}`);
|
||||
expect(out).toBe('/d/1?var-test1=val1&var-test2=val2');
|
||||
expect(out).toBe('/d/1?var-test1=val1&var-test2=val2&var-test3=Value%203&var-test4=A&var-test4=B');
|
||||
});
|
||||
|
||||
it('should prefer the local variable value', () => {
|
||||
@ -328,7 +327,7 @@ describe('PanelModel', () => {
|
||||
expect(model.showColumns).toBe(true);
|
||||
});
|
||||
|
||||
it('should restore custom field config to what it was and preseve standard options', () => {
|
||||
it('should restore custom field config to what it was and preserve standard options', () => {
|
||||
model.changePlugin(tablePlugin);
|
||||
expect(model.fieldConfig.defaults.custom.customProp).toBe(true);
|
||||
});
|
||||
@ -438,30 +437,32 @@ describe('PanelModel', () => {
|
||||
expect(model.getQueryRunner().getLastResult()).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDisplayTitle', () => {
|
||||
it('when called then it should interpolate singe value variables in title', () => {
|
||||
const model = new PanelModel({
|
||||
title: 'Single value variable [[test3]] ${test3} ${test3:percentencode}',
|
||||
});
|
||||
const title = model.getDisplayTitle();
|
||||
|
||||
expect(title).toEqual('Single value variable Value 3 Value 3 Value%203');
|
||||
});
|
||||
|
||||
it('when called then it should interpolate multi value variables in title', () => {
|
||||
const model = new PanelModel({
|
||||
title: 'Multi value variable [[test4]] ${test4} ${test4:percentencode}',
|
||||
});
|
||||
const title = model.getDisplayTitle();
|
||||
|
||||
expect(title).toEqual('Multi value variable A + B A + B %7BA%2CB%7D');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const variablesMock = [
|
||||
{
|
||||
type: 'query',
|
||||
name: 'test1',
|
||||
label: 'Test1',
|
||||
hide: false,
|
||||
current: { value: 'val1' },
|
||||
skipUrlSync: false,
|
||||
getValueForUrl: function () {
|
||||
return 'val1';
|
||||
},
|
||||
} as VariableModel,
|
||||
{
|
||||
type: 'query',
|
||||
name: 'test2',
|
||||
label: 'Test2',
|
||||
hide: false,
|
||||
current: { value: 'val2' },
|
||||
skipUrlSync: false,
|
||||
getValueForUrl: function () {
|
||||
return 'val2';
|
||||
},
|
||||
} as VariableModel,
|
||||
queryBuilder().withId('test1').withName('test1').withCurrent('val1').build(),
|
||||
queryBuilder().withId('test2').withName('test2').withCurrent('val2').build(),
|
||||
queryBuilder().withId('test3').withName('test3').withCurrent('Value 3').build(),
|
||||
queryBuilder().withId('test4').withName('test4').withCurrent(['A', 'B']).build(),
|
||||
];
|
||||
|
@ -59,6 +59,7 @@ const notPersistedProperties: { [str: string]: boolean } = {
|
||||
replaceVariables: true,
|
||||
editSourceId: true,
|
||||
hasChanged: true,
|
||||
getDisplayTitle: true,
|
||||
};
|
||||
|
||||
// For angular panels we need to clean up properties when changing type
|
||||
@ -102,6 +103,7 @@ const mustKeepProps: { [str: string]: boolean } = {
|
||||
interval: true,
|
||||
replaceVariables: true,
|
||||
libraryPanel: true,
|
||||
getDisplayTitle: true,
|
||||
};
|
||||
|
||||
const defaults: any = {
|
||||
@ -551,6 +553,14 @@ export class PanelModel implements DataConfigSource {
|
||||
getSavedId(): number {
|
||||
return this.editSourceId ?? this.id;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the title used when displaying the title in the UI so it will include any interpolated variables.
|
||||
* If you need the raw title without interpolation use title property instead.
|
||||
* */
|
||||
getDisplayTitle(): string {
|
||||
return this.replaceVariables(this.title, {}, 'text');
|
||||
}
|
||||
}
|
||||
|
||||
function getPluginVersion(plugin: PanelPlugin): string {
|
||||
|
Loading…
Reference in New Issue
Block a user