diff --git a/package.json b/package.json index 1cb729f6..5b02dee0 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,9 @@ "webpack-dev-server": "^2.4.5" }, "dependencies": { + "comma-separated-values": "^3.6.4", "react": "^15.5.4", + "react-data-grid": "^2.0.42", "react-dom": "^15.5.4" } } diff --git a/scripts/start.js b/scripts/start.js index 519158a4..dfc362e4 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -3,7 +3,7 @@ process.on("unhandledRejection", err => { throw err; }); -const PORT = 8080; +const PORT = 8081; const webpack = require("webpack"); const WebpackDevServer = require("webpack-dev-server"); diff --git a/src/app.js b/src/app.js index 7c41ff1c..f7e228ef 100644 --- a/src/app.js +++ b/src/app.js @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom'; import FileViewer from './components/file-viewer.jsx'; ReactDOM.render( - , + , document.getElementById('app') ); \ No newline at end of file diff --git a/src/components/drivers/csv-viewer.jsx b/src/components/drivers/csv-viewer.jsx new file mode 100644 index 00000000..68044e8f --- /dev/null +++ b/src/components/drivers/csv-viewer.jsx @@ -0,0 +1,49 @@ +import React, { Component } from 'react'; + +import ReactDataGrid from "react-data-grid"; +import CSV from "comma-separated-values"; + +const rowGetter = data => i => data.rows[i]; + +const parse = data => { + const rows = []; + const columns = []; + + new CSV(data).forEach(array => { + if (columns.length < 1) { + array.forEach((cell, idx) => { + columns.push({ + key: `key-${idx}`, + name: cell, + resizable: true, + sortable: true, + filterable: true, + }); + }); + } else { + const row = {}; + array.forEach((cell, idx) => { + row[`key-${idx}`] = cell; + }); + rows.push(row); + } + }); + + return { rows, columns }; +}; + + +const CsvViewer = props => { + const data = parse(props.data) + + return ( + + ); +}; + +export default CsvViewer; \ No newline at end of file diff --git a/src/components/drivers/index.js b/src/components/drivers/index.js new file mode 100644 index 00000000..d12d32ba --- /dev/null +++ b/src/components/drivers/index.js @@ -0,0 +1 @@ +export { default as CsvViewer } from "./csv-viewer.jsx"; \ No newline at end of file diff --git a/src/components/fetch-wrapper.jsx b/src/components/fetch-wrapper.jsx new file mode 100644 index 00000000..235f3368 --- /dev/null +++ b/src/components/fetch-wrapper.jsx @@ -0,0 +1,50 @@ +import React, { Component } from 'react'; + +function withFetching(WrappedComponent, props) { + return class extends Component { + constructor(props) { + super(props); + this.state = { data: {} }; + this.xhr = this.createRequest() + } + + componentDidMount() { + this.fetch(this.props.filePath); + } + + componentWillUnmount() { + this.abort() + } + + render() { + if (this.state.data.length > 0 || Object.keys(this.state.data).length > 0) { + return ; + } else { + return

Loading..

+ } + } + + createRequest() { + const xhr = new XMLHttpRequest(); + + xhr.onreadystatechange = () => { + if (this.xhr.readyState == 4 && this.xhr.status == 200) { + this.setState({ data: xhr.responseText }) + } + } + + return xhr; + } + + fetch(path) { + this.xhr.open("GET", path, true); + this.xhr.send(); + } + + abort() { + this.xhr && this.xhr.abort(); + } + } +}; + +export default withFetching; \ No newline at end of file diff --git a/src/components/file-viewer.jsx b/src/components/file-viewer.jsx index 2a2466a7..7e228ddc 100644 --- a/src/components/file-viewer.jsx +++ b/src/components/file-viewer.jsx @@ -1,11 +1,34 @@ import React, { Component } from 'react'; -export default class FileViewer extends Component { +import { default as withFetching } from "./fetch-wrapper.jsx"; +import { CsvViewer } from "./drivers"; + +class FileViewer extends Component { render() { + let Driver = this.getDriver(this.props.fileType); + return (
- Hello, file viewer! +
); } + + getDriver(fileTYpe) { + switch (fileTYpe) { + case "csv": { + return withFetching(CsvViewer) + } + default: { + return

File type is not supported

+ } + } + } +}; + +FileViewer.propTypes = { + fileType: React.PropTypes.string.isRequired, + filePath: React.PropTypes.string.isRequired, } + +export default FileViewer;