import * as React from 'react'; import {connect} from 'react-redux'; import {bindActionCreators} from 'redux'; import { translate } from 'react-i18next'; import { withStyles } from '@material-ui/core/styles'; // Actions import { loadAccession, applyFilters, loadAccessionAuditLog } from 'accessions/actions/public'; import {addAccessionToMyList, removeAccessionFromMyList} from 'list/actions/public'; import navigateTo from 'actions/navigation'; // Constants import { ROLE_USER } from 'constants/userRoles'; // Models import AccessionDetails from 'model/accession/AccessionDetails'; import RepositoryFile from 'model/repository/RepositoryFile'; import AccessionAuditLog from 'model/accession/AccessionAuditLog'; // UI import PrettyDate from 'ui/common/time/PrettyDate'; import PageLayout, { PageContents, MainSection, PageSection } from 'ui/layout/PageLayout'; import ContentHeader from 'ui/common/heading/ContentHeader'; import Loading from 'ui/common/Loading'; import { Properties, PropertiesItem } from 'ui/common/Properties'; import DOI from 'ui/common/DOI'; import { ExternalLink } from 'ui/common/Links'; import SciName from 'ui/genesys/SciName'; import { ScrollToTopOnMount } from 'ui/common/page/scrollers'; import ReduxCheckbox from 'ui/common/checkbox'; import CropChips from 'crop/ui/c/CropChips'; import LocationMap from 'ui/common/LocationMap'; import {CountryLink, DatasetLink, InstituteLink, SubsetLink} from 'ui/genesys/Links'; import PropertiesCard from 'ui/common/PropertiesCard'; import GridContainer from 'ui/layout/GridContainer'; import McpdDate from 'ui/common/time/McpdDate'; import PdciTable from './c/PdciTable'; import ImageGalleryView from 'repository/ui/c/ImageGalleryView'; import Button from '@material-ui/core/Button/Button'; import AuditedInfo from 'ui/common/AuditedInfo'; import Authorize from 'ui/common/authorized/Authorize'; import TemperatureChart from './c/TemperatureChart'; import PrecipitationChart from './c/PrecipitationChart'; import ClimateTable from './c/ClimateTable'; import PageTitle from 'ui/common/PageTitle'; import ActionButton from 'ui/common/buttons/ActionButton'; const styles = (theme) => ({ pageSection: { marginBottom: '1em', }, selected: { background: '#c9e2cb', }, historic: { background: '#ffe2e2 !important', }, }); interface IBrowsePageProps { t?: any; classes?: any; uuid: string; doi: string; // DOI comes from the route without the '10.' accession: AccessionDetails; auditLog: AccessionAuditLog; error: any; loadAccession: any; loadAccessionAuditLog: any; accessions: any; addAccessionToMyList: any; removeAccessionFromMyList: any; applyFilters: any; navigateTo: (location: string) => void; } class BrowsePage extends React.Component { protected static needs = [ ({ params: { uuid, doi } }) => { return doi ? loadAccession({ doi: `10.${doi}` }) : loadAccession({ uuid }); }, ]; constructor(props: IBrowsePageProps, context: any) { super(props, context); } public componentWillMount() { const { doi, uuid, loadAccession } = this.props; const accession = this.props.accession ? this.props.accession.details : null; const theDoi = `10.${doi}`; if (doi && (! accession || theDoi !== accession.doi)) { loadAccession({ doi: theDoi }); } if (uuid && (! accession || uuid !== accession.uuid)) { loadAccession({ uuid }); } } public componentWillReceiveProps(nextProps): void { const {uuid, doi, navigateTo} = this.props; const accession = this.props.accession ? this.props.accession.details : null; if (accession && accession.doi && !doi && accession.uuid === uuid) { navigateTo(`/${accession.doi}`); } } private loadAuditLog = () => { const { doi, uuid, loadAccessionAuditLog } = this.props; const theDoi = `10.${doi}`; if (doi) { loadAccessionAuditLog({ doi: theDoi }); } else { loadAccessionAuditLog({uuid}); } } private onCheckboxChange = (event, checked) => { const {accession: {details: accession}, addAccessionToMyList, removeAccessionFromMyList} = this.props; if (checked) { addAccessionToMyList(accession.uuid); } else { removeAccessionFromMyList(accession.uuid); } } private applyFilterForInstituteSpecies = () => { const { accession: {details: accession}, applyFilters } = this.props; const filter = {holder: {code: [ accession.institute.code ]}, taxa: { genus: [ accession.taxonomy.genus ], species: [ accession.taxonomy.species ] }}; applyFilters(filter); } private makeRange = (variable: number, diff: number) => { return { ge: Math.round(variable - diff), le: Math.round(variable + diff), }; } private applyClimateFilters = () => { const { accession: {details: accession}, applyFilters } = this.props; // BIO1 = Annual Mean Temperature !! // BIO2 = Mean Diurnal Range (Mean of monthly (max temp - min temp)) // BIO3 = Isothermality (BIO2/BIO7) (* 100) // BIO4 = Temperature Seasonality (standard deviation *100) // BIO5 = Max Temperature of Warmest Month // BIO6 = Min Temperature of Coldest Month // BIO7 = Temperature Annual Range (BIO5-BIO6) // BIO8 = Mean Temperature of Wettest Quarter // BIO9 = Mean Temperature of Driest Quarter // BIO10 = Mean Temperature of Warmest Quarter // BIO11 = Mean Temperature of Coldest Quarter // BIO12 = Annual Precipitation // BIO13 = Precipitation of Wettest Month // BIO14 = Precipitation of Driest Month // BIO15 = Precipitation Seasonality (Coefficient of Variation) // BIO16 = Precipitation of Wettest Quarter // BIO17 = Precipitation of Driest Quarter // BIO18 = Precipitation of Warmest Quarter !! // BIO19 = Precipitation of Coldest Quarter !! const tempDiff = 2; const filter = { taxa: { genus: [ accession.taxonomy.genus ], // species: [ accession.taxonomy.species ], }, geo: { climate: { // temperature bio1: this.makeRange(accession.geo.climate.bio1, tempDiff), // bio2: this.makeRange(accession.geo.climate.bio2, tempDiff), bio4: this.makeRange(accession.geo.climate.bio4, accession.geo.climate.bio4 * .50), // bio7: this.makeRange(accession.geo.climate.bio7, tempDiff), // bio8: this.makeRange(accession.geo.climate.bio8, tempDiff), // bio9: this.makeRange(accession.geo.climate.bio9, tempDiff), // bio10: this.makeRange(accession.geo.climate.bio10, tempDiff), // bio11: this.makeRange(accession.geo.climate.bio11, tempDiff), // precipitation bio12: this.makeRange(accession.geo.climate.bio12, accession.geo.climate.bio12 * .25), // bio13: this.makeRange(accession.geo.climate.bio13, precDif), // bio14: this.makeRange(accession.geo.climate.bio14, precDif), // bio15: this.makeRange(accession.geo.climate.bio15, accession.geo.climate.bio15 * .25), bio18: this.makeRange(accession.geo.climate.bio18, accession.geo.climate.bio18 * .25), bio19: this.makeRange(accession.geo.climate.bio19, accession.geo.climate.bio19 * .25), }, }, }; applyFilters(filter); } public render() { const { t, error, uuid, doi, accessions, auditLog, classes } = this.props; const { auditAccession, auditAccessionId, auditAccessionCollect, auditAccessionGeo } = auditLog || { auditAccession: {}, auditAccessionId: {}, auditAccessionCollect: {}, auditAccessionGeo: {} }; const { details: accession, pdci, datasets, subsets, files, imageGallery } = this.props.accession ? this.props.accession : {details: null, pdci: null, datasets: null, subsets: null, files: null, imageGallery: null}; const isChecked = accession && accessions && accessions.includes(accession.uuid); const theDoi = `10.${doi}`; const stillLoading: boolean = ! error && (! accession || (doi && accession && accession.doi !== theDoi) || (uuid && accession && accession.uuid !== uuid)); const hasLatLon = accession && accession.geo && accession.geo.latitude !== null && accession.geo.longitude !== null; return ( { stillLoading ? :
{ error &&
{ JSON.stringify(error) }
} { accession && { t('accessions.public.p.display.title') }
{ isChecked ? t('accessions.public.p.display.removeFromMyList', {accessionNumber: accession.accessionNumber}) : t('accessions.public.p.display.addToMyList', {accessionNumber: accession.accessionNumber}) } } input={ { value: isChecked, onChange: this.onCheckboxChange, } } />
} > { accession.doi && } { accession.accessionNumber } { accession.institute.fullName } { accession.historic && { t('accessions.public.p.display.isHistoric') } } { accession.institute.code } { accession.countryOfOrigin && { } } { accession.sampStat && { t(`accessions.common.sampleStatus.${accession.sampStat}`) } } { accession.storage && accession.storage.length > 0 && { accession.storage.map((storage, i) => (
{ t(`accessions.common.storage.${storage}`) }
)) }
} { t(`accessions.common.available.${accession.available}`) } { t(`accessions.common.mlsStatus.${accession.mlsStatus}`) } { accession.donorCode && { accession.donorCode } } { accession.donorNumb && { accession.donorNumb } } { accession.duplSite && accession.duplSite.length > 0 && { accession.duplSite.map((duplSite, i) => (
{ duplSite }
)) }
} { accession.acceUrl && }
{ imageGallery && } { accession.taxonomy.genus } { accession.taxonomy.species } { ' — ' } View { `${accession.taxonomy.genus} ${accession.taxonomy.species}` } at { accession.institute.code } { accession.crop && } { accession.cropName } { (accession.donorCode || (accession.aliases && accession.aliases.length > 0)) && { accession.donorCode && { accession.donorNumb } { accession.donorCode } } { accession.aliases && accession.aliases.map((alias) => ( { alias.name } { alias.usedBy } )) } } { accession.coll && { accession.countryOfOrigin && } { accession.coll.collDate && } { accession.coll.collSrc && { t(`accessions.common.collectingSource.${accession.coll.collSrc}`) } } { accession.coll && [ 'collMissId', 'collNumb', 'collSite' ] .filter((prop) => accession.coll[prop] !== null).map((prop) => ( { accession.coll[prop] } )) } { accession.coll && [ 'collCode', 'collName' ] .filter((prop) => accession.coll[prop].length).map((prop) => ( { accession.coll[prop] } )) } { accession.geo && [ 'latitude', 'longitude', 'datum', 'method', 'uncertainty', 'elevation' ] .filter((prop) => accession.geo[prop] !== null).map((prop) => ( { accession.geo[prop] } )) } { hasLatLon && } } { accession.geo && accession.geo.climate &&
} { accession.geo && accession.geo.climate && { [...Array(19).keys()].map((i) => ( { accession.geo.climate[`bio${i + 1}`] && Number(accession.geo.climate[`bio${i + 1}`]).toFixed(1) } )) }
} { accession.remarks && accession.remarks.length > 0 && { accession.remarks && accession.remarks.map((remark) => ( { remark.remark } )) } } { files && { files.map((e: RepositoryFile) => ( }> { e.originalFilename } )) } } { pdci && } { `urn:uuid:${accession.uuid}` } { datasets && datasets.length > 0 && ({ value: })) } /> } { subsets && subsets.length > 0 && ({ value: })) } /> } } }
); } } const mapStateToProps = (state, ownProps) => ({ accession: state.accessions.public.accession, auditLog: state.accessions.public.auditLog, error: state.accessions.public.accessionError, uuid: ownProps.match.params.uuid, doi: ownProps.match.params.doi, accessions: state.list.public.myList.accessions, }); const mapDispatchToProps = (dispatch) => bindActionCreators({ addAccessionToMyList, removeAccessionFromMyList, loadAccession, loadAccessionAuditLog, applyFilters, navigateTo, }, dispatch); export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(translate()(BrowsePage)));