mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
ce8b5030c1
commit
bf1e5aa16c
@ -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
|
||||
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>) => {
|
||||
|
Loading…
Reference in New Issue
Block a user