Explorar o código

return table directly, not the debug info

ryan %!s(int64=6) %!d(string=hai) anos
pai
achega
9134620c1a

+ 5 - 4
packages/grafana-ui/src/components/Table/TableInputCSV.story.tsx

@@ -3,7 +3,7 @@ import React from 'react';
 import { storiesOf } from '@storybook/react';
 import { storiesOf } from '@storybook/react';
 import TableInputCSV from './TableInputCSV';
 import TableInputCSV from './TableInputCSV';
 import { action } from '@storybook/addon-actions';
 import { action } from '@storybook/addon-actions';
-import { ParseResults } from '../../utils/processTableData';
+import { TableData } from '../../types/data';
 
 
 const TableInputStories = storiesOf('UI/Table/Input', module);
 const TableInputStories = storiesOf('UI/Table/Input', module);
 
 
@@ -11,11 +11,12 @@ TableInputStories.add('default', () => {
   return (
   return (
     <div>
     <div>
       <TableInputCSV
       <TableInputCSV
+        text="a,b,c\n1,2,3"
         width={'90%'}
         width={'90%'}
         height={'90vh'}
         height={'90vh'}
-        onTableParsed={(results: ParseResults) => {
-          console.log('Table Results', results);
-          action('Parsed')(results);
+        onTableParsed={(table: TableData, text: string) => {
+          console.log('Table', table, text);
+          action('Table')(table, text);
         }}
         }}
       />
       />
     </div>
     </div>

+ 4 - 3
packages/grafana-ui/src/components/Table/TableInputCSV.test.tsx

@@ -2,17 +2,18 @@ import React from 'react';
 
 
 import renderer from 'react-test-renderer';
 import renderer from 'react-test-renderer';
 import TableInputCSV from './TableInputCSV';
 import TableInputCSV from './TableInputCSV';
-import { ParseResults } from '../../utils/processTableData';
+import { TableData } from '../../types/data';
 
 
 describe('TableInputCSV', () => {
 describe('TableInputCSV', () => {
   it('renders correctly', () => {
   it('renders correctly', () => {
     const tree = renderer
     const tree = renderer
       .create(
       .create(
         <TableInputCSV
         <TableInputCSV
+          text="a,b,c\n1,2,3"
           width={100}
           width={100}
           height={100}
           height={100}
-          onTableParsed={(results: ParseResults) => {
-            console.log('GOT', results);
+          onTableParsed={(table: TableData, text: string) => {
+            console.log('Table:', table, 'from:', text);
           }}
           }}
         />
         />
       )
       )

+ 29 - 12
packages/grafana-ui/src/components/Table/TableInputCSV.tsx

@@ -1,39 +1,56 @@
 import React from 'react';
 import React from 'react';
 import debounce from 'lodash/debounce';
 import debounce from 'lodash/debounce';
-import { ParseConfig, ParseResults, parseCSV } from '../../utils/processTableData';
+import { ParseConfig, parseCSV, ParseDetails } from '../../utils/processTableData';
+import { TableData } from '../../types/data';
 
 
 interface Props {
 interface Props {
   config?: ParseConfig;
   config?: ParseConfig;
   width: number | string;
   width: number | string;
   height: number | string;
   height: number | string;
-  onTableParsed: (results: ParseResults) => void;
+  text: string;
+  onTableParsed: (table: TableData, text: string) => void;
 }
 }
 
 
 interface State {
 interface State {
   text: string;
   text: string;
-  results: ParseResults;
+  table: TableData;
+  details: ParseDetails;
 }
 }
 
 
 class TableInputCSV extends React.PureComponent<Props, State> {
 class TableInputCSV extends React.PureComponent<Props, State> {
   constructor(props: Props) {
   constructor(props: Props) {
     super(props);
     super(props);
+
+    // Shoud this happen in onComponentMounted?
+    const { text, config, onTableParsed } = props;
+    const details = {};
+    const table = parseCSV(text, config, details);
     this.state = {
     this.state = {
-      text: '',
-      results: parseCSV('', this.props.config),
+      text,
+      table,
+      details,
     };
     };
+    onTableParsed(table, text);
   }
   }
 
 
   readCSV = debounce(() => {
   readCSV = debounce(() => {
-    const results = parseCSV(this.state.text, this.props.config);
-    this.setState({ results });
+    const details = {};
+    const table = parseCSV(this.state.text, this.props.config, details);
+    this.setState({ table, details });
   }, 150);
   }, 150);
 
 
   componentDidUpdate(prevProps: Props, prevState: State) {
   componentDidUpdate(prevProps: Props, prevState: State) {
-    if (this.state.text !== prevState.text || this.props.config !== prevProps.config) {
+    const { text } = this.state;
+    if (text !== prevState.text || this.props.config !== prevProps.config) {
       this.readCSV();
       this.readCSV();
     }
     }
-    if (this.state.results !== prevState.results) {
-      this.props.onTableParsed(this.state.results);
+    // If the props text has changed, replace our local version
+    if (this.props.text !== prevProps.text && this.props.text !== text) {
+      this.setState({ text: this.props.text });
+    }
+
+    if (this.state.table !== prevState.table) {
+      this.props.onTableParsed(this.state.table, this.state.text);
     }
     }
   }
   }
 
 
@@ -43,9 +60,9 @@ class TableInputCSV extends React.PureComponent<Props, State> {
 
 
   render() {
   render() {
     const { width, height } = this.props;
     const { width, height } = this.props;
-    const { table, errors } = this.state.results;
+    const { table, details } = this.state;
 
 
-    const hasErrors = errors.length > 0;
+    const hasErrors = details.errors && details.errors.length > 0;
 
 
     return (
     return (
       <div className="gf-table-input-csv" style={{ width, height }}>
       <div className="gf-table-input-csv" style={{ width, height }}>

+ 58 - 34
packages/grafana-ui/src/utils/__snapshots__/processTableData.test.ts.snap

@@ -1,42 +1,66 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 
+exports[`processTableData basic processing should generate a header and fix widths 1`] = `
+Object {
+  "columnMap": Object {},
+  "columns": Array [
+    Object {
+      "text": "Column 1",
+    },
+    Object {
+      "text": "Column 2",
+    },
+    Object {
+      "text": "Column 3",
+    },
+  ],
+  "rows": Array [
+    Array [
+      1,
+      null,
+      null,
+    ],
+    Array [
+      2,
+      3,
+      4,
+    ],
+    Array [
+      5,
+      6,
+      null,
+    ],
+  ],
+  "type": "table",
+}
+`;
+
 exports[`processTableData basic processing should read header and two rows 1`] = `
 exports[`processTableData basic processing should read header and two rows 1`] = `
 Object {
 Object {
-  "errors": Array [],
-  "meta": Object {
-    "aborted": false,
-    "cursor": 17,
-    "delimiter": ",",
-    "linebreak": "
-",
-    "truncated": false,
-  },
-  "table": Object {
-    "columnMap": Object {},
-    "columns": Array [
-      Object {
-        "text": "a",
-      },
-      Object {
-        "text": "b",
-      },
-      Object {
-        "text": "c",
-      },
+  "columnMap": Object {},
+  "columns": Array [
+    Object {
+      "text": "a",
+    },
+    Object {
+      "text": "b",
+    },
+    Object {
+      "text": "c",
+    },
+  ],
+  "rows": Array [
+    Array [
+      1,
+      2,
+      3,
     ],
     ],
-    "rows": Array [
-      Array [
-        1,
-        2,
-        3,
-      ],
-      Array [
-        4,
-        5,
-        6,
-      ],
+    Array [
+      4,
+      5,
+      6,
     ],
     ],
-    "type": "table",
-  },
+  ],
+  "type": "table",
 }
 }
 `;
 `;

+ 12 - 2
packages/grafana-ui/src/utils/processTableData.test.ts

@@ -3,8 +3,18 @@ import { parseCSV } from './processTableData';
 describe('processTableData', () => {
 describe('processTableData', () => {
   describe('basic processing', () => {
   describe('basic processing', () => {
     it('should read header and two rows', () => {
     it('should read header and two rows', () => {
-      const simpleCSV = 'a,b,c\n1,2,3\n4,5,6';
-      expect(parseCSV(simpleCSV)).toMatchSnapshot();
+      const text = 'a,b,c\n1,2,3\n4,5,6';
+      expect(parseCSV(text)).toMatchSnapshot();
+    });
+
+    it('should generate a header and fix widths', () => {
+      const text = '1\n2,3,4\n5,6';
+      const table = parseCSV(text, {
+        headerIsFirstLine: false,
+      });
+      expect(table.rows.length).toBe(3);
+
+      expect(table).toMatchSnapshot();
     });
     });
   });
   });
 });
 });

+ 31 - 25
packages/grafana-ui/src/utils/processTableData.ts

@@ -12,10 +12,9 @@ export interface ParseConfig {
   comments?: boolean | string; // default: false
   comments?: boolean | string; // default: false
 }
 }
 
 
-export interface ParseResults {
-  table: TableData;
-  meta: ParseMeta;
-  errors: ParseError[];
+export interface ParseDetails {
+  meta?: ParseMeta;
+  errors?: ParseError[];
 }
 }
 
 
 /**
 /**
@@ -84,12 +83,26 @@ function makeColumns(values: any[]): Column[] {
   });
   });
 }
 }
 
 
-export function parseCSV(text: string, config?: ParseConfig): ParseResults {
+/**
+ * Convert text into a valid TableData object
+ *
+ * @param text
+ * @param config
+ * @param details, if exists the result will be filled with parse details
+ */
+export function parseCSV(text: string, config?: ParseConfig, details?: ParseDetails): TableData {
   const results = Papa.parse(text, { ...config, dynamicTyping: true, skipEmptyLines: true });
   const results = Papa.parse(text, { ...config, dynamicTyping: true, skipEmptyLines: true });
   const { data, meta, errors } = results;
   const { data, meta, errors } = results;
+
+  // Fill the parse details fro debugging
+  if (details) {
+    details.errors = errors;
+    details.meta = meta;
+  }
+
   if (!data || data.length < 1) {
   if (!data || data.length < 1) {
-    if (!text) {
-      // Show a more reasonable warning on empty input text
+    // Show a more reasonable warning on empty input text
+    if (details && !text) {
       errors.length = 0;
       errors.length = 0;
       errors.push({
       errors.push({
         code: 'empty',
         code: 'empty',
@@ -97,16 +110,13 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
         type: 'warning',
         type: 'warning',
         row: 0,
         row: 0,
       });
       });
+      details.errors = errors;
     }
     }
     return {
     return {
-      table: {
-        columns: [],
-        rows: [],
-        type: 'table',
-        columnMap: {},
-      },
-      meta,
-      errors,
+      columns: [],
+      rows: [],
+      type: 'table',
+      columnMap: {},
     };
     };
   }
   }
 
 
@@ -114,14 +124,10 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
   const headerIsNotFirstLine = config && config.headerIsFirstLine === false;
   const headerIsNotFirstLine = config && config.headerIsFirstLine === false;
   const header = headerIsNotFirstLine ? [] : results.data.shift();
   const header = headerIsNotFirstLine ? [] : results.data.shift();
 
 
-  return {
-    table: matchRowSizes({
-      columns: makeColumns(header),
-      rows: results.data,
-      type: 'table',
-      columnMap: {},
-    }),
-    meta,
-    errors,
-  };
+  return matchRowSizes({
+    columns: makeColumns(header),
+    rows: results.data,
+    type: 'table',
+    columnMap: {},
+  });
 }
 }