Commit 0dd9797d authored by Loic Huder's avatar Loic Huder
Browse files

Merge branch 'investigation-date-filter' into 'master'

Adds a date filter to the InvestigationTable (single day pick)

See merge request !424
parents db08287a 4f94d870
Pipeline #32081 passed with stages
in 7 minutes and 32 seconds
import React from 'react';
import { Glyphicon, Button } from 'react-bootstrap';
import DayPickerInput from 'react-day-picker/DayPickerInput';
import { formatDate, parseDate } from 'react-day-picker/moment';
import { INVESTIGATION_DATE_FORMAT } from '../../constants';
import styles from './InvestigationDateFilter.module.css';
function InvestigationDateFilter(props) {
const { rootClassName, value, onDayChange, onClear } = props;
return (
<div className={rootClassName}>
<DayPickerInput
inputProps={{ className: styles.dateFilterInput }}
value={value}
placeholder="Filter by start date"
format={INVESTIGATION_DATE_FORMAT}
formatDate={formatDate}
parseDate={parseDate}
onDayChange={onDayChange}
/>
<Button
disabled={!value}
onClick={onClear}
bsStyle="link"
className={styles.clearButton}
>
<Glyphicon glyph="remove" />
</Button>
</div>
);
}
export default InvestigationDateFilter;
.clearButton {
color: inherit;
padding-left: 6px;
}
.clearButton:hover {
color: darkslategray;
}
.dateFilterInput {
padding: 7px 0;
}
import React from 'react'; import React, { useState } from 'react';
import { Col, Glyphicon, Grid, Row } from 'react-bootstrap'; import { Col, Glyphicon, Grid, Row } from 'react-bootstrap';
import { Link } from 'react-router-dom'; import moment from 'moment';
import { import {
DATASET_COUNT, DATASET_COUNT,
FILE_COUNT, FILE_COUNT,
SAMPLE_COUNT,
VOLUME, VOLUME,
} from '../../constants/parameterTypes'; } from '../../constants/parameterTypes';
import DOIBadge from '../doi/DOIBadge'; import DOIBadge from '../doi/DOIBadge';
...@@ -12,24 +11,17 @@ import ResponsiveTable from '../Table/ResponsiveTable'; ...@@ -12,24 +11,17 @@ import ResponsiveTable from '../Table/ResponsiveTable';
import InvestigationWidget from './InvestigationWidget'; import InvestigationWidget from './InvestigationWidget';
import { beamlineFormatter, dateFormatter, nameFormatter } from './utils'; import { beamlineFormatter, dateFormatter, nameFormatter } from './utils';
import { stringifyBytesSize } from '../../helpers'; import { stringifyBytesSize } from '../../helpers';
import InvestigationDateFilter from './InvestigationDateFilter';
import styles from './InvestigationTable.module.css';
class InvestigationTable extends React.Component { function volumeFormatter(cell, investigation) {
logbookFormatter(cell, investigation) {
return (
<Link to={`/investigation/${investigation.id}/events`}>
<Glyphicon glyph="list-alt" />
</Link>
);
}
volumeFormatter(cell, investigation) {
const volume = investigation.parameters.find((o) => o.name === VOLUME); const volume = investigation.parameters.find((o) => o.name === VOLUME);
if (volume && volume.value && volume.value !== 0) { if (volume && volume.value && volume.value !== 0) {
return stringifyBytesSize(volume.value); return stringifyBytesSize(volume.value);
} }
} }
experimentFormatter(cell, investigation, rowIndex, extraData) { function experimentFormatter(cell, investigation, rowIndex, extraData) {
return ( return (
<Grid style={{ textAlign: 'center' }}> <Grid style={{ textAlign: 'center' }}>
<Row className="show-grid"> <Row className="show-grid">
...@@ -62,47 +54,39 @@ class InvestigationTable extends React.Component { ...@@ -62,47 +54,39 @@ class InvestigationTable extends React.Component {
</Row> </Row>
</Grid> </Grid>
); );
} }
/** /**
* This looks into the parameters of the investigation * This looks into the parameters of the investigation
*/ */
getParameter(investigation, parameterName) { function getParameter(investigation, parameterName) {
const parameter = investigation.parameters.find( const parameter = investigation.parameters.find(
(o) => o.name === parameterName (o) => o.name === parameterName
); );
if (parameter && parameter.value) { if (parameter && parameter.value) {
return parameter.value; return parameter.value;
} }
} }
sampleCountFormatter(cell, investigation, extraData) { function fileCountFormatter(cell, investigation) {
const sampleCount = extraData.getParameter(investigation, SAMPLE_COUNT); const fileCount = getParameter(investigation, FILE_COUNT);
if (sampleCount) {
if (sampleCount !== 0) { if (!fileCount) {
return sampleCount; return undefined;
}
}
} }
fileCountFormatter(cell, investigation, rowIndex, extraData) {
const fileCount = extraData.getParameter(investigation, FILE_COUNT);
if (fileCount) {
if (fileCount !== 0) {
return ( return (
<span style={{ width: 50, textAlign: 'right', float: 'left' }}> <span style={{ width: 50, textAlign: 'right', float: 'left' }}>
{fileCount} {fileCount}
</span> </span>
); );
} }
}
}
datasetCountFormatter(cell, investigation, rowIndex, extraData) { function datasetCountFormatter(cell, investigation) {
const datasetCount = investigation.parameters.find( const datasetCount = investigation.parameters.find(
(o) => o.name === DATASET_COUNT (o) => o.name === DATASET_COUNT
); );
if (datasetCount && datasetCount.value && datasetCount.value !== 0) { if (datasetCount && datasetCount.value) {
return ( return (
<> <>
<span style={{ width: 40, textAlign: 'right', float: 'left' }}> <span style={{ width: 40, textAlign: 'right', float: 'left' }}>
...@@ -118,30 +102,23 @@ class InvestigationTable extends React.Component { ...@@ -118,30 +102,23 @@ class InvestigationTable extends React.Component {
fontSize: 12, fontSize: 12,
}} }}
> >
({extraData.volumeFormatter(cell, investigation, extraData)}) ({volumeFormatter(cell, investigation)})
</span> </span>
</> </>
); );
} }
} }
/**
* It return true if releaseDate < now
*/
isReleased(investigation) {
return !!investigation && !!investigation.releaseDate;
}
getColumns() { function getLgHeaderStyle(width, hidden) {
function getLgHeaderStyle(width, hidden) {
return { return {
xs: { hidden: true }, xs: { hidden: true },
sm: { hidden: true }, sm: { hidden: true },
md: { hidden: true }, md: { hidden: true },
lg: { hidden, width, textAlign: 'center' }, lg: { hidden, width, textAlign: 'center' },
}; };
} }
function getColumns(props) {
return [ return [
{ {
text: 'id', text: 'id',
...@@ -151,8 +128,8 @@ class InvestigationTable extends React.Component { ...@@ -151,8 +128,8 @@ class InvestigationTable extends React.Component {
{ {
text: 'Experiment', text: 'Experiment',
dataField: 'name', dataField: 'name',
formatter: this.experimentFormatter, formatter: experimentFormatter,
formatExtraData: this, formatExtraData: props,
sort: true, sort: true,
hidden: false, hidden: false,
headerStyle: () => ({ width: '50%', textAlign: 'center' }), headerStyle: () => ({ width: '50%', textAlign: 'center' }),
...@@ -172,7 +149,7 @@ class InvestigationTable extends React.Component { ...@@ -172,7 +149,7 @@ class InvestigationTable extends React.Component {
props.withProposalLinks, props.withProposalLinks,
props.user.isAdministrator props.user.isAdministrator
), ),
formatExtraData: this.props, formatExtraData: props,
sort: true, sort: true,
hidden: false, hidden: false,
headerStyle: () => ({ width: '50%', textAlign: 'center' }), headerStyle: () => ({ width: '50%', textAlign: 'center' }),
...@@ -218,23 +195,21 @@ class InvestigationTable extends React.Component { ...@@ -218,23 +195,21 @@ class InvestigationTable extends React.Component {
{ {
text: 'Datasets', text: 'Datasets',
dataField: 'datasets', dataField: 'datasets',
formatter: this.datasetCountFormatter, formatter: datasetCountFormatter,
formatExtraData: this,
responsiveHeaderStyle: getLgHeaderStyle( responsiveHeaderStyle: getLgHeaderStyle(
130, 130,
!this.props.showInvestigationStats !props.showInvestigationStats
), ),
}, },
{ {
text: 'Files', text: 'Files',
hidden: !this.props.user.isAdministrator, hidden: !props.user.isAdministrator,
dataField: 'dummy-1', dataField: 'dummy-1',
isDummyField: true, isDummyField: true,
formatter: this.fileCountFormatter, formatter: fileCountFormatter,
formatExtraData: this,
responsiveHeaderStyle: getLgHeaderStyle( responsiveHeaderStyle: getLgHeaderStyle(
80, 80,
!this.props.showInvestigationStats !props.showInvestigationStats
), ),
}, },
{ {
...@@ -252,13 +227,15 @@ class InvestigationTable extends React.Component { ...@@ -252,13 +227,15 @@ class InvestigationTable extends React.Component {
responsiveHeaderStyle: getLgHeaderStyle(260, false), responsiveHeaderStyle: getLgHeaderStyle(260, false),
}, },
]; ];
} }
function InvestigationTable(props) {
const { expanded, user, investigations } = props;
const [dateFilter, setDateFilter] = useState();
render() {
const expandRow = { const expandRow = {
showExpandColumn: true, showExpandColumn: true,
//expandByColumnOnly: true, expanded,
expanded: this.props.expanded,
expandColumnPosition: 'right', expandColumnPosition: 'right',
expandHeaderColumnRenderer: ({ isAnyExpands }) => { expandHeaderColumnRenderer: ({ isAnyExpands }) => {
if (isAnyExpands) { if (isAnyExpands) {
...@@ -283,19 +260,30 @@ class InvestigationTable extends React.Component { ...@@ -283,19 +260,30 @@ class InvestigationTable extends React.Component {
renderer: (investigation) => ( renderer: (investigation) => (
<InvestigationWidget <InvestigationWidget
investigation={investigation} investigation={investigation}
sessionId={this.props.user.sessionId} sessionId={user.sessionId}
/> />
), ),
}; };
return ( return (
<>
<div className={styles.wrapper}>
<InvestigationDateFilter
rootClassName={styles.filter}
value={dateFilter && dateFilter.toDate()}
onDayChange={(date) => setDateFilter(moment(date))}
onClear={() => setDateFilter(undefined)}
/>
</div>
<ResponsiveTable <ResponsiveTable
data={this.props.investigations} data={investigations.filter(
columns={this.getColumns()} (inv) => !dateFilter || dateFilter.isSame(inv.startDate, 'day')
)}
columns={getColumns(props)}
expandRow={expandRow} expandRow={expandRow}
/> />
</>
); );
}
} }
export default InvestigationTable; export default InvestigationTable;
.wrapper {
position: relative;
}
@media (min-width: 50em) {
.filter {
display: flex;
align-items: center;
position: absolute;
left: 0;
top: 0;
}
}
...@@ -7,9 +7,7 @@ import ResponsiveTable from '../Table/ResponsiveTable'; ...@@ -7,9 +7,7 @@ import ResponsiveTable from '../Table/ResponsiveTable';
import StatusFilterDropdown from './StatusFilterDropdown'; import StatusFilterDropdown from './StatusFilterDropdown';
import styles from './ParcelTable.module.css'; import styles from './ParcelTable.module.css';
import moment from 'moment'; import moment from 'moment';
import DayPickerInput from 'react-day-picker/DayPickerInput'; import InvestigationDateFilter from '../Investigation/InvestigationDateFilter';
import { formatDate, parseDate } from 'react-day-picker/moment';
import { INVESTIGATION_DATE_FORMAT } from '../../constants';
function getActionColumn(handleView) { function getActionColumn(handleView) {
return { return {
...@@ -170,25 +168,12 @@ function ParcelTable(props) { ...@@ -170,25 +168,12 @@ function ParcelTable(props) {
</Button> </Button>
</div> </div>
{investigations && ( {investigations && (
<div className={styles.filter}> <InvestigationDateFilter
<DayPickerInput rootClassName={styles.filter}
inputProps={{ className: styles.dateFilterInput }}
value={dateFilter && dateFilter.toDate()} value={dateFilter && dateFilter.toDate()}
placeholder="Filter by start date"
format={INVESTIGATION_DATE_FORMAT}
formatDate={formatDate}
parseDate={parseDate}
onDayChange={handleStartDateChange} onDayChange={handleStartDateChange}
onClear={handleDateFilterClear}
/> />
<Button
disabled={!dateFilter}
onClick={handleDateFilterClear}
bsStyle="link"
className={styles.clearButton}
>
<Glyphicon glyph="remove" />
</Button>
</div>
)} )}
</div> </div>
<ResponsiveTable <ResponsiveTable
......
...@@ -31,10 +31,6 @@ ...@@ -31,10 +31,6 @@
color: darkslategray; color: darkslategray;
} }
.dateFilterInput {
padding: 7px 0;
}
.clickable { .clickable {
cursor: pointer; cursor: pointer;
} }
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