Skip to content
Snippets Groups Projects
Commit 0558d0b9 authored by Esko Ikkala's avatar Esko Ikkala
Browse files

Render results with react-virtualized

parent 89ac84fd
No related branches found
No related tags found
No related merge requests found
import React from 'react';
import Immutable from 'immutable';
import PropTypes from 'prop-types';
import {
AutoSizer,
Column,
Table,
SortDirection,
SortIndicator
} from 'react-virtualized';
import { withStyles } from '@material-ui/core/styles';
const styles = theme => ({
root: {
width: '100%',
marginTop: theme.spacing.unit * 25,
},
headerRow: {
borderBottom: '1px solid #e0e0e0'
},
evenRow: {
borderBottom: '1px solid #e0e0e0'
},
oddRow: {
borderBottom: '1px solid #e0e0e0',
//backgroundColor: '#fafafa'
},
headerColumn: {
textTransform: 'none'
},
noRows: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '1em',
color: '#bdbdbd',
}
});
class VirtualizedTable extends React.PureComponent {
constructor(props) {
super(props);
const sortBy = 'source';
const sortDirection = SortDirection.ASC;
const sortedList = this._sortList({sortBy, sortDirection});
this.state = {
disableHeader: false,
headerHeight: 30,
height: 500,
overscanRowCount: 10,
rowHeight: 40,
rowCount: this.props.list.size,
scrollToIndex: undefined,
sortBy,
sortDirection,
sortedList,
useDynamicRowHeight: false,
};
this._getRowHeight = this._getRowHeight.bind(this);
this._headerRenderer = this._headerRenderer.bind(this);
this._noRowsRenderer = this._noRowsRenderer.bind(this);
this._onRowCountChange = this._onRowCountChange.bind(this);
this._onScrollToRowChange = this._onScrollToRowChange.bind(this);
this._rowClassName = this._rowClassName.bind(this);
this._sort = this._sort.bind(this);
}
render() {
const {
disableHeader,
headerHeight,
height,
overscanRowCount,
rowHeight,
rowCount,
scrollToIndex,
sortBy,
sortDirection,
sortedList,
useDynamicRowHeight,
} = this.state;
const { classes } = this.props;
const rowGetter = ({index}) => this._getDatum(sortedList, index);
return (
<div>
<AutoSizer>
{({width}) => (
<Table
disableHeader={disableHeader}
headerClassName={classes.headerColumn}
headerHeight={headerHeight}
height={height}
noRowsRenderer={this._noRowsRenderer}
overscanRowCount={overscanRowCount}
rowClassName={this._rowClassName}
rowHeight={useDynamicRowHeight ? this._getRowHeight : rowHeight}
rowGetter={rowGetter}
rowCount={rowCount}
scrollToIndex={scrollToIndex}
sort={this._sort}
sortBy={sortBy}
sortDirection={sortDirection}
width={width}
style={classes}
>
<Column
label="Label"
cellDataGetter={({rowData}) => rowData.label}
dataKey="label"
width={150}
/>
<Column
label="Type"
cellDataGetter={({rowData}) => rowData.typeLabel}
dataKey="typeLabel"
width={150}
/>
<Column
label="Area"
cellDataGetter={({rowData}) => rowData.broaderAreaLabel}
dataKey="broaderAreaLabel"
width={150}
/>
<Column
label="Source"
cellDataGetter={({rowData}) => rowData.source}
dataKey="source"
width={150}
/>
</Table>
)}
</AutoSizer>
</div>
);
}
_getDatum(list, index) {
return list.get(index % list.size);
}
_getRowHeight({index}) {
const list = this.props.list;
return this._getDatum(list, index).size;
}
_headerRenderer({dataKey, sortBy, sortDirection}) {
return (
<div>
Full Name
{sortBy === dataKey && <SortIndicator sortDirection={sortDirection} />}
</div>
);
}
_noRowsRenderer() {
const { classes } = this.props;
return <div className={classes.noRows}>No rows</div>;
}
_onRowCountChange(event) {
const rowCount = parseInt(event.target.value, 10) || 0;
this.setState({rowCount});
}
_onScrollToRowChange(event) {
const {rowCount} = this.state;
let scrollToIndex = Math.min(
rowCount - 1,
parseInt(event.target.value, 10),
);
if (isNaN(scrollToIndex)) {
scrollToIndex = undefined;
}
this.setState({scrollToIndex});
}
_rowClassName({index}) {
const { classes } = this.props;
if (index < 0) {
return classes.headerRow;
} else {
return index % 2 === 0 ? classes.evenRow : classes.oddRow;
}
}
_sort({sortBy, sortDirection}) {
const sortedList = this._sortList({sortBy, sortDirection});
this.setState({sortBy, sortDirection, sortedList});
}
_sortList({sortBy, sortDirection}) {
const list = this.props.list;
return list
.sortBy(item => item[sortBy])
.update(
list => (sortDirection === SortDirection.DESC ? list.reverse() : list),
);
}
_updateUseDynamicRowHeight(value) {
this.setState({
useDynamicRowHeight: value,
});
}
}
VirtualizedTable.propTypes = {
list: PropTypes.instanceOf(Immutable.List).isRequired,
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(VirtualizedTable);
...@@ -17,7 +17,9 @@ import Tab from '@material-ui/core/Tab'; ...@@ -17,7 +17,9 @@ import Tab from '@material-ui/core/Tab';
import IntegrationAutosuggest from '../components/IntegrationAutosuggest'; import IntegrationAutosuggest from '../components/IntegrationAutosuggest';
import LeafletMap from '../components/map/LeafletMap'; import LeafletMap from '../components/map/LeafletMap';
import Message from '../components/Message'; import Message from '../components/Message';
import ResultTable from '../components/result-table/ResultTable'; //import ResultTable from '../components/result-table/ResultTable';
import VirtualizedTable from '../components/VirtualizedTable';
import Immutable from 'immutable';
import { import {
...@@ -119,6 +121,11 @@ let MapApp = (props) => { ...@@ -119,6 +121,11 @@ let MapApp = (props) => {
const anchor = 'left'; const anchor = 'left';
//console.log(props.search.results) //console.log(props.search.results)
let resultList = [];
if (props.search.results.length > 0) {
resultList = Immutable.List(props.search.results);
}
const drawer = ( const drawer = (
<Drawer <Drawer
...@@ -156,7 +163,7 @@ let MapApp = (props) => { ...@@ -156,7 +163,7 @@ let MapApp = (props) => {
clearResults={props.clearResults} clearResults={props.clearResults}
/> />
{props.search.results.length > 0 && {props.search.results.length > 0 &&
<ResultTable data={props.search.results} /> <VirtualizedTable list={resultList} />
} }
</Drawer> </Drawer>
); );
......
...@@ -6,11 +6,13 @@ import { Provider } from 'react-redux'; ...@@ -6,11 +6,13 @@ import { Provider } from 'react-redux';
import reducer from './reducers'; import reducer from './reducers';
import rootEpic from './epics'; import rootEpic from './epics';
import ReduxToastr from 'react-redux-toastr'; import ReduxToastr from 'react-redux-toastr';
import 'react-redux-toastr/lib/css/react-redux-toastr.min.css';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { actions as toastrActions } from 'react-redux-toastr'; import { actions as toastrActions } from 'react-redux-toastr';
import App from './components/App'; import App from './components/App';
import 'react-redux-toastr/lib/css/react-redux-toastr.min.css';
import 'react-virtualized/styles.css';
const store = createStore( const store = createStore(
reducer, reducer,
// applyMiddleware() tells createStore() how to handle middleware // applyMiddleware() tells createStore() how to handle middleware
......
.Table {
width: 100%;
margin-top: 15px;
}
.headerRow,
.evenRow,
.oddRow {
border-bottom: 1px solid #e0e0e0;
}
.oddRow {
background-color: #fafafa;
}
.headerColumn {
text-transform: none;
}
.exampleColumn {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.noRows {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 1em;
color: #bdbdbd;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment