adding toolbar

This commit is contained in:
ryan 2019-03-08 18:02:52 -08:00
parent 9df47391ea
commit 40d7ba1e6a
7 changed files with 103 additions and 53 deletions

View File

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

View File

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

View File

@ -18,6 +18,35 @@ interface ParseResults {
errors: ParseError[]; 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 { export function parseCSV(text: string, config?: ParseConfig): ParseResults {
const results = Papa.parse(text, { ...config, dynamicTyping: true, skipEmptyLines: true }); const results = Papa.parse(text, { ...config, dynamicTyping: true, skipEmptyLines: true });
@ -44,35 +73,8 @@ 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) {
errors.push({
type: 'warning', // A generalization of the error
message: 'not all rows have the same width',
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(); const first = results.data.shift();
return { const table = {
table: {
columns: first.map((v: any, index: number) => { columns: first.map((v: any, index: number) => {
if (!v) { if (!v) {
v = 'Column ' + (index + 1); v = 'Column ' + (index + 1);
@ -84,7 +86,19 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
rows: results.data, rows: results.data,
type: 'table', type: 'table',
columnMap: {}, columnMap: {},
} as TableData, } 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. Changed:' + changed,
code: 'width',
row: 0,
});
}
return {
table,
meta, meta,
errors, errors,
}; };
@ -92,6 +106,8 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
interface Props { interface Props {
config?: ParseConfig; config?: ParseConfig;
width: number;
height: number;
} }
interface State { interface State {
@ -128,14 +144,21 @@ class TableInputCSV extends React.PureComponent<Props, State> {
}; };
render() { render() {
const { width, height } = this.props;
const { table, errors } = this.state.results; const { table, errors } = this.state.results;
return ( 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} /> <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)} BAR: / ROWS:{table.rows.length} / COLS:{table.columns.length} / {JSON.stringify(errors)}
</div> </footer>
</div> </div>
); );
} }

View File

@ -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;
}

View File

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

View File

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

View File

@ -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>
);