Skip to content

Commit

Permalink
added Table atom type
Browse files Browse the repository at this point in the history
  • Loading branch information
joeltg committed Jul 21, 2016
1 parent 01581c2 commit 193b5bf
Show file tree
Hide file tree
Showing 8 changed files with 562 additions and 0 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"firebase": "^2.3.2",
"firebase-token-generator": "^2.0.0",
"firepad": "^1.3.0",
"fixed-data-table-2": "^0.7.1",
"fuzzy": "^0.1.1",
"googleapis": "^8.2.0",
"happypack": "^2.1.1",
Expand Down Expand Up @@ -148,6 +149,7 @@
"mongoose": "^4.1.12",
"murmurhash": "^0.0.2",
"newrelic": "^1.24.0",
"papaparse": "^4.1.2",
"passport": "^0.3.0",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^4.0.0",
Expand All @@ -163,6 +165,7 @@
"react-addons-css-transition-group": "^15.0.2",
"react-addons-pure-render-mixin": "^15.0.2",
"react-addons-shallow-compare": "^15.0.2",
"react-addons-update": "^15.2.1",
"react-anything-sortable": "^1.5.0",
"react-color": "^2.2.0",
"react-dom": "^15.0.2",
Expand Down
144 changes: 144 additions & 0 deletions src/components/AtomTypes/Table/TableEditor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import React, {PropTypes} from 'react';
import Radium, {Style} from 'radium';
import {safeGetInToJS} from 'utils/safeParse';
import update from 'react-addons-update';

import {Table, Cell, Column} from 'fixed-data-table-2';
import tableStyles from './fixed-data-table.css';

import Papa from 'papaparse';

let styles = {};

export const TableEditor = React.createClass({
propTypes: {
atomEditData: PropTypes.object,
},

getInitialState() {
return {
url: '',
width: 600,
height: 400,
isUploading: false,
rows: [],
header: false
};
},

componentWillMount() {
const url = safeGetInToJS(this.props.atomEditData, ['currentVersionData', 'content', 'url']) || '';
const header = safeGetInToJS(this.props.atomEditData, ['currentVersionData', 'content', 'header']) || false;
const height = safeGetInToJS(this.props.atomEditData, ['currentVersionData', 'content', 'header']) || 400;
this.setState({url, header, height});
},

loadCSV() {
const url = this.state.url;
Papa.parse(url, {
download: true,
header: false,
step: row => this.setState(update(this.state, {rows: {$push: row.data}}))
});
},

componentDidMount() {
this.loadCSV();
},

getSaveVersionContent() {
const {url, header} = this.state;
return {url, header};
},

handleFileSelect(evt) {
if (evt.target.files.length) {
this.setState({isUploading: true});
s3Upload(evt.target.files[0], ()=>{}, this.onFileFinish, 0);
}
},

onFileFinish(evt, index, type, filename) {
const url = 'https://assets.pubpub.org/' + filename;
this.setState({url, isUploading: false, rows: []}, this.loadCSV);
},

handleHeaderChange(evt) {
const header = evt.target.checked;
this.setState({header});
},

handleHeightChange(evt) {
const height = +evt.target.value;
this.setState({height});
},

setWidth(container) {
if (container && container.offsetWidth) {
this.setState({width: container.offsetWidth});
}
},

render() {
const {height, width, header, rows} = this.state;
const offset = header ? 1 : 0;
const columns = rows[0] || [];
const rowsCount = Math.max(0, rows.length - offset - 1);
const dimensions = {
width, height,
rowHeight: 50,
headerHeight: offset * 50
};
return <div style={styles.container} ref={this.setWidth}>
<label htmlFor="header" style={styles.label}>
Header Row:
<input id='header' name='header' type='checkbox' value={header} style={styles.header}
onChange={this.handleHeaderChange}/>
</label>
<label htmlFor="height" style={styles.label}>
Height:
<input id='height' name='height' type="number"
min={100} step={100} max={1000} value={height} style={styles.height}
onChange={this.handleHeightChange}/>
</label>
<label htmlFor="csvFile" style={styles.label}>
Upload a new file
<input id='csvFile' name='csv file' type="file" accept="text/csv" style={styles.file}
onChange={this.handleFileSelect} />
</label>
<h3>Preview</h3>

<Style rules={tableStyles} />

<Table rowsCount={rowsCount} {...dimensions}>
{columns.map((column, key) => {
const props = {key, width: 200};
props.cell = props => <Cell width={props.width} height={props.height}>{rows[props.rowIndex + offset][key]}</Cell>;
if (header) props.header = <Cell>{column}</Cell>;
return <Column {...props} />;
})}
</Table>

</div>;
}
});

export default Radium(TableEditor);

styles = {
container: {
width: '100%'
},
header: {
marginLeft: '12px',
marginBottom: '12px'
},
height: {
marginLeft: '12px',
marginBottom: '6px',
fontSize: '1em'
},
label: {
fontSize: '1.1em'
}
};
18 changes: 18 additions & 0 deletions src/components/AtomTypes/Table/TableEditor.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {expect} from 'chai';
import {shallowRender} from 'tests/helpersClient';
import {TableEditor} from './TableEditor.jsx'

describe('Components', () => {
describe('TableEditor.jsx', () => {

it('should render with empty props', () => {
const props = {};
const {renderOutput, error} = shallowRender(TableEditor, props) ;

expect(error).to.not.exist; // Did not render an error
expect(renderOutput).to.exist; // Successfully rendered

});

});
});
93 changes: 93 additions & 0 deletions src/components/AtomTypes/Table/TableViewer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, {PropTypes} from 'react';
import Radium, {Style} from 'radium';
import {safeGetInToJS} from 'utils/safeParse';
import update from 'react-addons-update';

import {Table, Cell, Column} from 'fixed-data-table-2';
import tableStyles from './fixed-data-table.css';

import Papa from 'papaparse';

let styles = {};

export const TableViewer = React.createClass({
propTypes: {
atomData: PropTypes.object,
renderType: PropTypes.string, // full, embed, static-full, static-embed
},

getInitialState() {
return {
url: '',
width: 600,
height: 400,
rows: [],
header: false
};
},

componentWillMount() {
const url = safeGetInToJS(this.props.atomEditData, ['currentVersionData', 'content', 'url']) || '';
const header = safeGetInToJS(this.props.atomEditData, ['currentVersionData', 'content', 'header']) || false;
const height = safeGetInToJS(this.props.atomEditData, ['currentVersionData', 'content', 'height']) || 400;
this.setState({url, header, height});
},

loadCSV() {
const url = this.state.url;
Papa.parse(url, {
download: true,
header: false,
step: row => this.setState(update(this.state, {rows: {$push: row.data}}))
});
},

componentDidMount() {
this.loadCSV();
},

setWidth(container) {
if (container && container.offsetWidth) {
this.setState({width: container.offsetWidth});
}
},

render() {
const {height, width, header, rows} = this.state;
const offset = header ? 1 : 0;
const columns = rows[0] || [];
const rowsCount = Math.max(0, rows.length - offset - 1);
const dimensions = {
width, height,
rowHeight: 50,
headerHeight: offset * 50
};

switch (this.props.renderType) {
case 'embed':
case 'static-embed':
case 'full':
case 'static-full':
default:
return <div ref={this.setWidth} style={styles.container}>
<Style rules={tableStyles} />
<Table rowsCount={rowsCount} {...dimensions}>
{columns.map((column, key) => {
const props = {key, width: 200};
props.cell = props => <Cell width={props.width} height={props.height}>{rows[props.rowIndex + offset][key]}</Cell>;
if (header) props.header = <Cell>{column}</Cell>;
return <Column {...props} />;
})}
</Table>
</div>;
}
}
});

export default Radium(TableViewer);

styles = {
container: {
width: '100%'
}
};
18 changes: 18 additions & 0 deletions src/components/AtomTypes/Table/TableViewer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {expect} from 'chai';
import {shallowRender} from 'tests/helpersClient';
import {TableViewer} from './TableViewer.jsx'

describe('Components', () => {
describe('TableViewer.jsx', () => {

it('should render with empty props', () => {
const props = {};
const {renderOutput, error} = shallowRender(TableViewer, props) ;

expect(error).to.not.exist; // Did not render an error
expect(renderOutput).to.exist; // Successfully rendered

});

});
});

0 comments on commit 193b5bf

Please sign in to comment.