mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
adding toolbar
This commit is contained in:
parent
9df47391ea
commit
40d7ba1e6a
@ -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, {});
|
||||||
});
|
});
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
|
@ -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,47 +73,32 @@ export function parseCSV(text: string, config?: ParseConfig): ParseResults {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let same = true;
|
const first = results.data.shift();
|
||||||
let cols = data[0].length;
|
const table = {
|
||||||
data.forEach(row => {
|
columns: first.map((v: any, index: number) => {
|
||||||
if (cols !== row.length) {
|
if (!v) {
|
||||||
same = false;
|
v = 'Column ' + (index + 1);
|
||||||
cols = Math.max(cols, row.length);
|
}
|
||||||
}
|
return {
|
||||||
});
|
text: v.toString().trim(),
|
||||||
|
} as Column;
|
||||||
|
}),
|
||||||
|
rows: results.data,
|
||||||
|
type: 'table',
|
||||||
|
columnMap: {},
|
||||||
|
} as TableData;
|
||||||
|
|
||||||
// Use a second pass to update the sizes
|
const changed = checkAndFix(table);
|
||||||
if (!same) {
|
if (changed > 0) {
|
||||||
errors.push({
|
errors.push({
|
||||||
type: 'warning', // A generalization of the error
|
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',
|
code: 'width',
|
||||||
row: 0,
|
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 {
|
return {
|
||||||
table: {
|
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,
|
|
||||||
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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
17
packages/grafana-ui/src/components/Table/_TableInputCSV.scss
Normal file
17
packages/grafana-ui/src/components/Table/_TableInputCSV.scss
Normal 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;
|
||||||
|
}
|
@ -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,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';
|
||||||
|
@ -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>
|
||||||
|
);
|
Loading…
Reference in New Issue
Block a user