PanelInspect: Make header names reflect the field name in the exported CSV file (#24624)

* fix header names and filename

* use panel title as filename

* add frame argument

* escaping double quotes

* wrapping header name in  quotes

* Fix replace

* Add test for csv double quotes escaping

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
Peter Holmberg 2020-05-14 20:14:23 +02:00 committed by GitHub
parent ce8b5030c1
commit bf1e5aa16c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 3 deletions

View File

@ -4,6 +4,7 @@ import { getDataFrameRow } from '../dataframe/processDataFrame';
// Test with local CSV files
import fs from 'fs';
import { toDataFrameDTO } from '../dataframe/processDataFrame';
import { MutableDataFrame } from '../dataframe';
describe('read csv', () => {
it('should get X and y', () => {
@ -88,3 +89,30 @@ describe('write csv', () => {
expect(fields.map(f => f.name).join(',')).toEqual('a,b,c'); // the names
});
});
describe('DataFrame to CSV', () => {
it('should escape double quotes in the field names', () => {
const dataFrame = new MutableDataFrame({
fields: [
{ name: 'Time', values: [1589455688623] },
// As we have traceId in message already this will shadow it.
{
name: 'Value',
values: ['1234'],
labels: {
label1: 'value1',
label2: 'value1',
},
},
],
});
const csv = toCSV([dataFrame]);
expect(csv).toMatchInlineSnapshot(`
"\\"Time\\",\\"{label1=\\"\\"value1\\"\\", label2=\\"\\"value1\\"\\"}\\"
1589455688623,1234
"
`);
});
});

View File

@ -7,6 +7,7 @@ import isNumber from 'lodash/isNumber';
import { DataFrame, Field, FieldType, FieldConfig } from '../types';
import { guessFieldTypeFromValue } from '../dataframe/processDataFrame';
import { MutableDataFrame } from '../dataframe/MutableDataFrame';
import { getFieldDisplayName } from '../field';
export enum CSVHeaderStyle {
full,
@ -289,7 +290,7 @@ export function toCSV(data: DataFrame[], config?: CSVConfig): string {
if (i > 0) {
csv += config.delimiter;
}
csv += fields[i].name;
csv += `"${getFieldDisplayName(fields[i], series).replace(/"/g, '""')}"`;
}
csv += config.newline;
}

View File

@ -7,6 +7,7 @@ import {
toCSV,
transformDataFrame,
getFrameDisplayName,
dateTimeFormat,
} from '@grafana/data';
import { Button, Field, Icon, LegacyForms, Select, Table } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors';
@ -49,13 +50,16 @@ export class InspectDataTab extends PureComponent<Props, State> {
}
exportCsv = (dataFrame: DataFrame) => {
const { panel } = this.props;
const { transformId } = this.state;
const dataFrameCsv = toCSV([dataFrame]);
const blob = new Blob([dataFrameCsv], {
type: 'application/csv;charset=utf-8',
});
saveAs(blob, dataFrame.name + '-' + new Date().getUTCDate() + '.csv');
const transformation = transformId !== DataTransformerID.noop ? '-as-' + transformId.toLocaleLowerCase() : '';
const fileName = `${panel.title}-data${transformation}-${dateTimeFormat(new Date())}.csv`;
saveAs(blob, fileName);
};
onSelectedFrameChanged = (item: SelectableValue<number>) => {