Commit b99ccd13 authored by Matija Obreza's avatar Matija Obreza
Browse files

Displaying accession data in tabular form

parent 75c4ef17
......@@ -17,6 +17,8 @@ require('roboto-fontface/css/roboto/roboto-fontface.css');
// leaflet map
require('leaflet/dist/leaflet.css');
// react virtualized
require('react-virtualized/styles.css');
require('../styles/font-awesome/css/font-awesome.css');
require('../styles/bootstrap/css/bootstrap.min.css');
......
......@@ -11721,6 +11721,18 @@
"warning": "3.0.0"
}
},
"react-virtualized": {
"version": "9.18.5",
"resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.18.5.tgz",
"integrity": "sha512-eC9ortLeHkQs+WvpxVYJfiQqv7h+QoFmRGvYLi5UN0oKjcni/km9skrBKKw6xsYJRMMy7wnkEMOsBD28f41ovQ==",
"requires": {
"babel-runtime": "6.26.0",
"classnames": "2.2.5",
"dom-helpers": "3.3.1",
"loose-envify": "1.3.1",
"prop-types": "15.6.0"
}
},
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
......
......@@ -18,10 +18,48 @@ import GenesysBrowseFilters from './c/Filters';
import PrettyFilters from 'ui/common/filter/PrettyFilters';
import DOI from 'ui/common/DOI';
import { MultiGrid as VMultiGrid, AutoSizer } from 'react-virtualized';
import Grid from 'material-ui/Grid';
const styles = (theme) => ({
filterSection: theme.leftPanel.root,
BodyGrid: {
width: '100%',
border: '1px solid #e0e0e0',
},
tableCell: {
padding: '.5rem 1rem',
borderRight: 'dotted 1px White',
borderBottom: 'solid 1px White',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
display: 'inline-block',
overflow: 'hidden' as 'hidden',
},
tableHeaderCell: {
fontWeight: 'bold' as 'bold',
color: 'White',
borderRight: 'dotted 1px #a0d457',
},
evenRow: {
backgroundColor: '#f3f2ee',
},
oddRow: {
backgroundColor: '#f8f7f5',
},
noCells: {
position: 'absolute' as 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
display: 'flex',
alignItems: 'center' as 'center',
justifyContent: 'center' as 'center',
fontSize: '1em',
color: '#bdbdbd',
},
});
interface IBrowsePageProps extends React.ClassAttributes<any> {
......@@ -48,7 +86,33 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
public constructor(props: any) {
super(props);
this.state = { paged: null, filter: {} };
this.state = {
paged: null,
filter: {},
displayedColumns: [
{ path: 'acceNumb', width: 200, title: 'Accession number' },
{ path: 'seqNo', width: 100, className: 'text-right', title: 'Seq' },
{ path: 'taxonomy', width: 400, title: 'Scientific name', renderer: (data) => {
// console.log('Rendering taxonomy', data.taxonomy.sciNameHtml);
return <span dangerouslySetInnerHTML={ this.htmlTaxa(data.taxonomy.sciNameHtml) } />;
} },
{ path: 'acceName', width: 400, title: 'Accession name' },
{ path: 'doi', width: 200, title: 'DOI', renderer: (data) => {
// console.log('Rendering DOI', data.doi);
return data.doi ? <DOI noPrefix value={ data.doi } /> : null;
} },
{ path: 'institute.code', width: 100, title: 'Institute code', renderer: (data) => data.institute.code },
{ path: 'institute.name', width: 400, title: 'Institute name', renderer: (data) => data.institute.fullName },
{ path: 'cropName', width: 200, title: 'Crop' },
{ path: 'sampStat', width: 300, title: 'Biological status of sample', renderer: (data) => data.sampStat && this.decode(data.sampStat, 'sampStat') },
],
};
this._cellRenderer = this._cellRenderer.bind(this);
this._getColumnWidth = this._getColumnWidth.bind(this);
this._getRowClassName = this._getRowClassName.bind(this);
// this._getRowHeight = this._getRowHeight.bind(this);
this._noContentRenderer = this._noContentRenderer.bind(this);
}
......@@ -129,13 +193,10 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
return { __html: taxonomyHtml };
}
private decode(obj, path): string {
if (! obj) {
private decode(val, path): string {
if (! val) {
return null;
}
const val = obj[path]; // FIXME use proper JSONpath
// console.log(obj, path, obj[path]);
const { decoder } = this.state;
if (! decoder) {
return val;
......@@ -153,7 +214,7 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
public render() {
const { classes } = this.props;
const { paged, filter } = this.state;
const { paged, filter, displayedColumns } = this.state;
const stillLoading: boolean = (! paged || ! paged.content);
......@@ -177,21 +238,26 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
</Grid>
</Grid>
{ stillLoading ? <Loading /> :
<Grid container spacing={ 0 }>
{ paged.content.map((acce, index) => (
<Grid item xs={ 12 } key={ `${index}` } className="stripy-item" style={ { margin: '.3rem 0', padding: '.3rem 1rem' } }>
<Grid container spacing={ 0 }>
<Grid item xs={ 4 } md={ 2 } >{ acce.acceNumb } <b>{ acce.acceName }</b></Grid>
<Grid item xs={ 4 } md={ 2 } ><DOI value={ acce.doi } noPrefix /></Grid>
<Grid item xs={ 4 } md={ 2 }>{ acce.institute.code }</Grid>
<Grid item xs={ 12 } md={ 6 } >{ acce.orgCty ? acce.orgCty.name : '' }</Grid>
<Grid item xs={ 12 } md={ 6 } dangerouslySetInnerHTML={ this.htmlTaxa(acce.taxonomy.sciNameHtml) } />
<Grid item xs={ 12 } md={ 6 } >{ this.decode(acce, 'sampStat') }</Grid>
</Grid>
</Grid>
)) }
</Grid>
<AutoSizer disableHeight>
{ ({ width }) => (
<VMultiGrid
{ ...paged.content }
fixedRowCount={ 1 }
fixedColumnCount={ 1 }
cellRenderer={ this._cellRenderer }
className={ classes.BodyGrid }
columnWidth={ this._getColumnWidth }
columnCount={ displayedColumns.length }
height={ 800 }
noContentRenderer={ this._noContentRenderer }
overscanColumnCount={ 1 }
overscanRowCount={ 3 }
rowHeight={ 36 }
rowCount={ paged.content.length }
width={ width }
/>
) }
</AutoSizer>
}
</Grid>
<Grid container spacing={ 0 }>
......@@ -204,6 +270,55 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
</Grid>
);
}
private _cellRenderer({columnIndex, key, rowIndex, style}) {
if (rowIndex === 0) {
return this._headerRenderer({columnIndex, key, style});
}
const { classes } = this.props;
const { paged, displayedColumns } = this.state;
const rowClass = this._getRowClassName(rowIndex);
const cellClass = displayedColumns[columnIndex].className || '';
// console.log(`c ${rowIndex},${columnIndex}`, paged.content[rowIndex]);
return (
<div key={ key } style={ style } className={ `${classes.tableCell} ${rowClass} ${cellClass}` }>
{ displayedColumns[columnIndex].renderer ?
displayedColumns[columnIndex].renderer(paged.content[rowIndex - 1])
:
paged.content[rowIndex - 1][displayedColumns[columnIndex].path]
}
</div>
);
}
private _headerRenderer({columnIndex, key, style}) {
const { classes } = this.props;
const { displayedColumns } = this.state;
const cellClass = displayedColumns[columnIndex].className || '';
// console.log(`c ${rowIndex},${columnIndex}`, paged.content[rowIndex]);
return (
<div key={ key } style={ style } className={ `${classes.tableCell} ${classes.tableHeaderCell} ${cellClass} back-green` }>
{ displayedColumns[columnIndex].title }
</div>
);
}
private _noContentRenderer() {
const { classes } = this.props;
return <div className={ classes.noCells }>No cells</div>;
}
private _getColumnWidth({index}) {
const { displayedColumns } = this.state;
return displayedColumns[index].width;
}
private _getRowClassName(row) {
const { classes } = this.props;
return row % 2 === 0 ? classes.evenRow : classes.oddRow;
}
}
const mapStateToProps = (state, ownProps) => ({
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment