ryan 6 лет назад
Родитель
Сommit
40d7ba1e6a

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

@@ -1,12 +1,9 @@
 import { storiesOf } from '@storybook/react';
-import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
-import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
 import TableInputCSV from './TableInputCSV';
+import { withFullSizeStory } from '../../utils/storybook/withFullSizeStory';
 
 const TableInputStories = storiesOf('UI/Table/Input', module);
 
-TableInputStories.addDecorator(withCenteredStory);
-
 TableInputStories.add('default', () => {
-  return renderComponentWithTheme(TableInputCSV, {});
+  return withFullSizeStory(TableInputCSV, {});
 });

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

@@ -5,7 +5,7 @@ import TableInputCSV from './TableInputCSV';
 
 describe('TableInputCSV', () => {
   it('renders correctly', () => {
-    const tree = renderer.create(<TableInputCSV />).toJSON();
+    const tree = renderer.create(<TableInputCSV width={100} height={100} />).toJSON();
     //expect(tree).toMatchSnapshot();
     expect(tree).toBeDefined();
   });

+ 60 - 37
packages/grafana-ui/src/components/Table/TableInputCSV.tsx

@@ -18,6 +18,35 @@ interface ParseResults {
   errors: ParseError[];
 }
 
+// This mutates the table structure!
+export function checkAndFix(table: TableData): number {
+  let cols = table.columns.length;
+  let different = 0;
+  table.rows.forEach(row => {
+    if (cols !== row.length) {
+      different++;
+      cols = Math.max(cols, row.length);
+    }
+  });
+  if (different > 0) {
+    if (cols !== table.columns.length) {
+      const diff = cols - table.columns.length;
+      for (let i = 0; i < diff; i++) {
+        table.columns.push({
+          text: 'Column ' + table.columns.length,
+        });
+      }
+    }
+    table.rows.forEach(row => {
+      const diff = cols - row.length;
+      for (let i = 0; i < diff; i++) {
+        row.push(null);
+      }
+    });
+  }
+  return different;
+}
+
 export function parseCSV(text: string, config?: ParseConfig): ParseResults {
   const results = Papa.parse(text, { ...config, dynamicTyping: true, skipEmptyLines: true });
 
@@ -44,47 +73,32 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
     };
   }
 
-  let same = true;
-  let cols = data[0].length;
-  data.forEach(row => {
-    if (cols !== row.length) {
-      same = false;
-      cols = Math.max(cols, row.length);
-    }
-  });
-
-  // Use a second pass to update the sizes
-  if (!same) {
+  const first = results.data.shift();
+  const table = {
+    columns: first.map((v: any, index: number) => {
+      if (!v) {
+        v = 'Column ' + (index + 1);
+      }
+      return {
+        text: v.toString().trim(),
+      } as Column;
+    }),
+    rows: results.data,
+    type: 'table',
+    columnMap: {},
+  } as TableData;
+
+  const changed = checkAndFix(table);
+  if (changed > 0) {
     errors.push({
       type: 'warning', // A generalization of the error
-      message: 'not all rows have the same width',
+      message: 'not all rows have the same width. Changed:' + changed,
       code: 'width',
       row: 0,
     });
-    // Add null values to the end of all short arrays
-    data.forEach(row => {
-      const diff = cols - row.length;
-      for (let i = 0; i < diff; i++) {
-        row.push(null);
-      }
-    });
   }
-
-  const first = results.data.shift();
   return {
-    table: {
-      columns: first.map((v: any, index: number) => {
-        if (!v) {
-          v = 'Column ' + (index + 1);
-        }
-        return {
-          text: v.toString().trim(),
-        } as Column;
-      }),
-      rows: results.data,
-      type: 'table',
-      columnMap: {},
-    } as TableData,
+    table,
     meta,
     errors,
   };
@@ -92,6 +106,8 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
 
 interface Props {
   config?: ParseConfig;
+  width: number;
+  height: number;
 }
 
 interface State {
@@ -128,14 +144,21 @@ class TableInputCSV extends React.PureComponent<Props, State> {
   };
 
   render() {
+    const { width, height } = this.props;
     const { table, errors } = this.state.results;
 
     return (
-      <div>
+      <div
+        className={'gf-table-input-wrap'}
+        style={{
+          width: `${width}px`,
+          height: `${height}px`,
+        }}
+      >
         <textarea value={this.state.text} onChange={this.handleChange} onBlur={this.handleBlur} />
-        <div>
+        <footer>
           BAR: / ROWS:{table.rows.length} / COLS:{table.columns.length} / {JSON.stringify(errors)}
-        </div>
+        </footer>
       </div>
     );
   }

+ 17 - 0
packages/grafana-ui/src/components/Table/_TableInputCSV.scss

@@ -0,0 +1,17 @@
+.gf-table-input-wrap {
+  width: 100%;
+}
+
+.gf-table-input-wrap textarea {
+  height: 100%;
+  width: 100%;
+  resize: none;
+}
+
+.gf-table-input-wrap footer {
+  position: absolute;
+  bottom: 20px;
+  right: 20px;
+  border: 2px solid #222;
+  background: #ccc;
+}

+ 0 - 11
packages/grafana-ui/src/components/Table/__snapshots__/TableInputCSV.test.tsx.snap

@@ -1,11 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`TableInputCSV renders correctly 1`] = `
-<div>
-  <textarea
-    onBlur={[Function]}
-    onChange={[Function]}
-    value=""
-  />
-</div>
-`;

+ 1 - 0
packages/grafana-ui/src/components/index.scss

@@ -1,6 +1,7 @@
 @import 'CustomScrollbar/CustomScrollbar';
 @import 'DeleteButton/DeleteButton';
 @import 'ThresholdsEditor/ThresholdsEditor';
+@import 'Table/TableInputCSV';
 @import 'Tooltip/Tooltip';
 @import 'Select/Select';
 @import 'PanelOptionsGroup/PanelOptionsGroup';

+ 23 - 0
packages/grafana-ui/src/utils/storybook/withFullSizeStory.tsx

@@ -0,0 +1,23 @@
+import React from 'react';
+import { AutoSizer } from 'react-virtualized';
+
+export const withFullSizeStory = (component: React.ComponentType<any>, props: any) => (
+  <div
+    style={{
+      height: '100vh',
+      width: '100%',
+    }}
+  >
+    <AutoSizer>
+      {({ width, height }) => (
+        <>
+          {React.createElement(component, {
+            ...props,
+            width,
+            height,
+          })}
+        </>
+      )}
+    </AutoSizer>
+  </div>
+);