Commit 8bb0b260 authored by Matija Obreza's avatar Matija Obreza
Browse files

Accession display page

- No map
- No My List
parent 452e941c
......@@ -130,5 +130,48 @@
"subsets": {
"title": "Title"
}
},
"accession": {
"pdciScore": "PDCI score of this accession is {{score, number}} of 10.0.",
"pdciInstitute": "Average PDCI score for this institute is {{score, number}}.",
"alias": {
"OTHERNUMB": "Other identifier",
"ACCENAME": "Accession name",
"DONORNUMB": "Donor accession number",
"COLLNUMB": "Collecting number"
},
"available": {
"true": "Available for distribution",
"false": "Not available for distribution",
"null": "Availability not known"
},
"coll": {
"collCode": "Collecting institute code",
"collNumb": "Collecting number",
"collDate": "Collecting date of sample",
"collMissId": "Collecting mission identifier",
"collName": "Collecting institute name",
"collSite": "Location of collecting site",
"collSrc": "Collecting source"
},
"geo": {
"latitude": "Latitude of collecting site",
"longitude": "Longitude of collecting site",
"uncertainty": "Coordinate uncertainty",
"datum": "Geodetic datum",
"method": "Georeferencing method",
"elevation": "Elevation of collecting site"
},
"storage": {
"10": "Seed collection",
"11": "Short term seed collection",
"12": "Medium term seed collection",
"13": "Long term seed collection",
"20": "Field collection",
"30": "In vitro collection",
"40": "Cryopreserved collection",
"50": "DNA collection",
"99": "Other"
}
}
}
......@@ -33,7 +33,6 @@ class Accession {
public donorName: string;
public donorNumb: string;
public duplSite: string[];
public duplSiteStr: string;
public geo: AccessionGeo;
public id: number;
public inSvalbard: boolean;
......@@ -50,10 +49,11 @@ class Accession {
public sampStat: number;
public seqNo: number;
public storage: number[];
public storageStr: string;
public taxonomy: Taxonomy2;
public uuid: string;
public version: number;
public historic: boolean;
public available: boolean;
public static DEFAULT_SORT = {
property: 'seqNo',
......
......@@ -11,7 +11,6 @@ class AccessionCollect {
public collNumb: string;
public collSite: string;
public collSrc: number;
public empty: boolean;
public id: number;
public version: number;
......
......@@ -5,7 +5,6 @@
class AccessionGeo {
public datum: string;
public elevation: number;
public empty: boolean;
public id: number;
public latitude: number;
public longitude: number;
......
......@@ -11,7 +11,7 @@ const header = {
};
const content = {
padding: ' 1.429rem',
padding: '1.429rem',
};
const action = {
......
import * as React from 'react';
import { ExternalLink } from 'ui/catalog/Links';
import { ExternalLink } from 'ui/common/Links';
interface IMyProps extends React.Props<any> {
value: string;
......
import * as React from 'react';
const ExternalLink = ({link, children}) =>
<a href={ link } target="_blank" rel="nofollow">{ children ? children : link }</a>;
const FaoWiewsLink = ({wiewsCode, children}) =>
<ExternalLink link={ `http://www.fao.org/wiews/data/organizations/en/?instcode=${wiewsCode}` }>{ children ? children : wiewsCode }</ExternalLink>;
const ExternalLink = ({ link, children }: { link: string, children?: any }) => (
<a href={ link } target="_blank" rel="nofollow">{ children ? children : link }</a>
);
const FaoWiewsLink = ({ wiewsCode, children }: { wiewsCode: string, children?: any }) => (
<ExternalLink link={ `http://www.fao.org/wiews/data/organizations/en/?instcode=${wiewsCode}` }>{ children ? children : wiewsCode }</ExternalLink>
);
export { FaoWiewsLink, ExternalLink };
......@@ -8,14 +8,16 @@ const styles = (theme) => ({
// marginTop: '1rem',
// marginBottom: '0',
color: '#4d4c46',
display: 'flex' as 'flex',
flexWrap: 'wrap' as 'wrap',
},
propertiesRow: {
/* tslint:disable */
'marginTop': '2px',
'marginBottom': '2px',
'& > *:first-child': {
borderRight: 'solid 2px white',
},
// '& > *:first-child': {
// borderRight: 'solid 2px white',
// },
'&:nth-child(even)': {
backgroundColor: '#f8f7f5',
},
......@@ -32,18 +34,25 @@ const styles = (theme) => ({
interface IItemProps extends React.ClassAttributes<any> {
// classes: any;
title: any;
small?: boolean;
keepEmpty?: boolean;
// children: any;
}
class PropertiesItem1 extends React.Component<IItemProps & WithStyles<'propertiesContainer' | 'propertiesRow' | 'propertiesValue'>, any> {
public render() {
const { title, classes, children } = this.props;
const { keepEmpty, small, title, classes, children } = this.props;
if (!keepEmpty && ! children) {
return null;
}
return (
<Grid container spacing={ 0 } className={ classes.propertiesRow }>
<Grid item xs={ 4 } md={ 3 } className="font-bold p-halfrem" style={ { fontSize: '1rem', fontFamily: 'Roboto, sans-serif' } }>{ title }</Grid>
<Grid item xs={ 8 } md={ 9 } className={ `${classes.propertiesValue} p-halfrem` } style={ { fontSize: '1rem' } }>{ children }</Grid>
<Grid item xs={ 12 } md={ small ? 3 : 12 } className={ classes.propertiesRow }>
<Grid container spacing={ 24 }>
<Grid item xs={ small ? 8 : 12 } md={ small ? 10 : 3 } className="font-bold p-halfrem" style={ { fontSize: '1rem', fontFamily: 'Roboto, sans-serif' } }>{ title }</Grid>
<Grid item xs={ small ? 4 : 12 } md={ small ? 2 : 9 } className={ `${classes.propertiesValue} p-halfrem` } style={ { fontSize: '1rem' } }>{ children }</Grid>
</Grid>
</Grid>
);
}
}
......@@ -57,11 +66,9 @@ class Properties1 extends React.Component<IProps & WithStyles<'propertiesContain
public render() {
const { children, classes} = this.props;
return (
<Grid container spacing={ 0 }>
<Grid item xs={ 12 } className={ classes.propertiesContainer }>
{ children }
</Grid>
</Grid>
<Grid container spacing={ 24 } className={ classes.propertiesContainer }>
{ children }
</Grid>
);
}
}
......
import * as React from 'react';
const htmlTaxa = (taxonomyHtml: string) => {
return { __html: taxonomyHtml };
};
const SciName = ({taxa}: {taxa: string}) =>
<span dangerouslySetInnerHTML={ htmlTaxa(taxa) } />;
export default SciName;
......@@ -4,6 +4,8 @@ import { withStyles } from '@material-ui/core/styles';
import Accession from 'model/Accession';
import { AccessionLink } from 'ui/genesys/Links';
import Card, {CardContent, CardActions} from 'ui/common/Card';
import DOI from 'ui/common/DOI';
import SciName from 'ui/genesys/SciName';
const styles = (theme) => ({
firstRow: {
......@@ -13,10 +15,6 @@ const styles = (theme) => ({
const AccessionCard = ({ accession, classes, index, ...other }: { accession: Accession, classes: any, index?: number } & React.ClassAttributes<any>) => {
const htmlTaxa = (taxonomyHtml: string) => {
return { __html: taxonomyHtml };
};
return (
<Card>
<CardContent>
......@@ -26,7 +24,7 @@ const AccessionCard = ({ accession, classes, index, ...other }: { accession: Acc
<AccessionLink to={ accession }>
{ accession.accessionNumber }
{ ` • ` }
<span dangerouslySetInnerHTML={ htmlTaxa(accession.taxonomy.taxonNameHtml) } />
<SciName taxa={ accession.taxonomy.taxonNameHtml } />
</AccessionLink>
</b>
{ accession.countryOfOrigin && ` • ${accession.countryOfOrigin.name}` }
......@@ -38,6 +36,8 @@ const AccessionCard = ({ accession, classes, index, ...other }: { accession: Acc
{ accession.institute.fullName }
{ accession.institute.country && `, ${accession.institute.country.name}` }
</em>
{ ` • DOI: ` }
{ accession.doi && <DOI noPrefix value={ accession.doi } /> || 'N/A' }
</div>
</CardContent>
{ false &&
......
import * as React from 'react';
import { ExternalLink } from 'ui/catalog/Links';
import { ExternalLink } from 'ui/common/Links';
import { translate } from 'react-i18next';
const THIS_YEAR = new Date().getFullYear();
......
import * as React from 'react';
import { withStyles } from '@material-ui/core/styles';
import Card, {CardHeader, CardContent} from 'ui/common/Card';
// import * as classnames from 'classnames';
import Header from './Header';
import Footer from './Footer';
import SidebarWrapper from './sidebar/SidebarWrapper';
......@@ -15,7 +17,6 @@ const styles = (theme) => ({
width: '100%',
overflow: 'visible' as 'visible',
position: 'absolute' as 'absolute',
},
content: {
flexGrow: 1,
......@@ -37,6 +38,19 @@ const styles = (theme) => ({
margin: '1em',
},
},
mainSection: {
},
mainSectionTitle: {
// color: 'Blue',
},
section: {
},
sectionTitle: {
fontSize: '1.3rem',
// color: 'Red',
},
});
interface ILayoutProps extends React.Props<any> {
......@@ -65,7 +79,22 @@ const Layout = ({classes, children = null, sidebar = null}: ILayoutProps) => (
);
const Contents = ({classes, children = null}) => children && <div className={ classes.pageContents }>{ children }</div>;
const Section1 = ({classes, title, children = null}) => children && (
<Card className={ classes.mainSection }>
<CardHeader classes={ { title: classes.mainSectionTitle } } title={ title } />
<CardContent>{ children }</CardContent>
</Card>
);
const Section2 = ({classes, title, children = null}) => children && (
<Card className={ classes.section }>
<CardHeader classes={ { title: classes.sectionTitle } } title={ title } />
<CardContent>{ children }</CardContent>
</Card>
);
export const PageContents = withStyles(styles)(Contents);
export const MainSection = withStyles(styles)(Section1);
export const PageSection = withStyles(styles)(Section2);
export default withStyles(styles)(Layout);
import * as React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import { translate } from 'react-i18next';
// Actions
import { loadAccession } from 'actions/accessions';
......@@ -9,12 +10,19 @@ import { loadAccession } from 'actions/accessions';
import Accession from 'model/Accession';
// UI
import PageLayout, { PageContents } from 'ui/layout/PageLayout';
import { Link } from 'react-router-dom';
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 AccessionCard from 'ui/genesys/accession/AccessionCard';
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';
interface IBrowsePageProps extends React.ClassAttributes<any> {
t: any;
uuid: string;
accession: Accession;
error: any;
......@@ -41,19 +49,133 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
}
public render() {
const { error, accession, uuid } = this.props;
const { t, error, accession, uuid } = this.props;
const stillLoading: boolean = ! error && (! accession || (uuid && accession && accession.uuid !== uuid));
return (
<PageLayout>
<ContentHeader title="Accession" />
<PageContents>
{ stillLoading && <Loading /> }
{ error && <div>{ JSON.stringify(error) }</div> }
{ accession && <AccessionCard accession={ accession } /> }
</PageContents>
<ScrollToTopOnMount />
<ContentHeader title="Accession details" subtitle="Passport data and everything else" />
{ stillLoading && <Loading /> }
{ error && <div>{ JSON.stringify(error) }</div> }
{ accession &&
<PageContents>
<MainSection title={ `Accession: ${accession.accessionNumber}` }>
<Properties>
{ accession.doi && <PropertiesItem title="DOI"><DOI noPrefix value={ accession.doi } /></PropertiesItem> }
<PropertiesItem title="Accession number">{ accession.accessionNumber }</PropertiesItem>
<PropertiesItem title="Holding institute">{ accession.institute.fullName }</PropertiesItem>
<PropertiesItem title="Country of holding institute">{ accession.institute.country.name }</PropertiesItem>
<PropertiesItem title="Acquisition date">{ accession.acquisitionDate }</PropertiesItem>
<PropertiesItem title="Biological status of accession">{ accession.sampStat }</PropertiesItem>
<PropertiesItem title="Availability for distribution">{ t(`accession.available.${accession.available}`) }</PropertiesItem>
{ accession.storage && accession.storage.length > 0 && <PropertiesItem title="Type of Germplasm storage">
{ accession.storage.map((storage, i) => (
<div key={ storage }>{ t(`accession.storage.${storage}`) }</div>
)) }
</PropertiesItem> }
<PropertiesItem title="Donor institute">{ accession.donorCode }</PropertiesItem>
<PropertiesItem title="Donor accession number">{ accession.donorNumb }</PropertiesItem>
{ accession.duplSite && accession.duplSite.length > 0 && <PropertiesItem title="Safety duplication institute">
{ accession.duplSite.map((duplSite, i) => (
<div key={ duplSite }>{ duplSite }</div>
)) }
</PropertiesItem> }
{ accession.acceUrl && <PropertiesItem title="Accession URL"><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
</Properties>
</MainSection>
<PageSection title="Taxonomy">
<Properties>
<PropertiesItem title="Genus">{ accession.taxonomy.genus }</PropertiesItem>
<PropertiesItem title="Species">
{ accession.taxonomy.species }
{ '' }
<Link to={ '/a' }>View <i>{ `${accession.taxonomy.genus} ${accession.taxonomy.species}` }</i> at { accession.institute.code }</Link>
</PropertiesItem>
<PropertiesItem title="Scientific name"><SciName taxa={ accession.taxonomy.taxonNameHtml } /></PropertiesItem>
{ accession.crop && <PropertiesItem title="Crop name">{ accession.crop.name }</PropertiesItem> }
<PropertiesItem title="Provided crop name">{ accession.cropName }</PropertiesItem>
</Properties>
</PageSection>
<PageSection title="Accession names">
<Properties>
{ accession.coll && accession.coll.collNumb && <PropertiesItem title={ t('accession.alias.COLLNUMB') }>{ accession.coll.collNumb } { accession.coll.collCode }</PropertiesItem> }
{ accession.donorCode && <PropertiesItem title={ t('accession.alias.DONORNUMB') }>{ accession.donorNumb } { accession.donorCode }</PropertiesItem> }
{ accession.aliases && accession.aliases.map((alias) => (
<PropertiesItem key={ alias.id } title={ t(`accession.alias.${alias.aliasType}`) }>{ alias.name } { alias.usedBy }</PropertiesItem>
)) }
</Properties>
</PageSection>
<PageSection title="Collecting information">
<Properties>
{ accession.countryOfOrigin && <PropertiesItem title="Country of origin">{ accession.countryOfOrigin.name }</PropertiesItem> }
{ accession.coll &&
[ 'collDate', 'collMissId', 'collNumb', 'collSite', 'collSrc' ]
.filter((prop) => accession.coll[prop] !== null).map((prop) => (
<PropertiesItem key={ prop } title={ t(`accession.coll.${prop}`) }>{ accession.coll[prop] }</PropertiesItem>
))
}
{ accession.coll &&
[ 'collCode', 'collName' ]
.filter((prop) => accession.coll[prop].length).map((prop) => (
<PropertiesItem key={ prop } title={ t(`accession.coll.${prop}`) }>{ accession.coll[prop] }</PropertiesItem>
))
}
{ accession.geo &&
[ 'latitude', 'longitude', 'datum', 'method', 'uncertainty', 'elevation' ]
.filter((prop) => accession.geo[prop] !== null).map((prop) => (
<PropertiesItem key={ prop } title={ t(`accession.geo.${prop}`) }>{ accession.geo[prop] }</PropertiesItem>
))
}
</Properties>
</PageSection>
{ accession.remarks && accession.remarks.length > 0 && <PageSection title="Remarks">
<Properties>
{ accession.remarks && accession.remarks.map((remark) => (
<PropertiesItem key={ remark.id } title={ remark.fieldName }>{ remark.remark }</PropertiesItem>
)) }
</Properties>
</PageSection> }
{ accession.pdci && <PageSection title="Passport Data Completeness Index">
<div style={ { marginBottom: '2em', padding: '2em', backgroundColor: '#b6c1b4', borderRadius: '6px' } }>
<span style={ { fontSize: '1.5em' } }>
{ t('accession.pdciScore', { score: accession.pdci.score }) }
{ /*<p>{ t(`accession.pdciInstitute`, { score: accession.pdci.score }) }</p>*/ }
</span>
{ ' ' }
<a href="#">Read about Passport Data Completeness Index</a>
</div>
<Properties>
{ accession.pdci.independentItems.map((item) => (
<PropertiesItem keepEmpty small key={ item } title={ item.toUpperCase() }>{ accession.pdci[item] }</PropertiesItem>
)) }
{ accession.pdci.dependentItems.map((item) => (
<PropertiesItem keepEmpty small key={ item } title={ item.toUpperCase() }>{ accession.pdci[item] }</PropertiesItem>
)) }
</Properties>
</PageSection> }
<PageSection title="Metadata">
<Properties>
<PropertiesItem title="UUID">{ `urn:uuid:${accession.uuid}` }</PropertiesItem>
<PropertiesItem title="Permanent URL"><ExternalLink link={ `https://purl.org/germplasm/id/${accession.uuid}` } /></PropertiesItem>
<PropertiesItem title="Last updated"><PrettyDate value={ accession.lastModifiedDate } /></PropertiesItem>
<PropertiesItem title="Created"><PrettyDate value={ accession.createdDate } /></PropertiesItem>
</Properties>
</PageSection>
</PageContents>
}
</PageLayout>
);
}
......@@ -70,4 +192,4 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(BrowsePage);
export default connect(mapStateToProps, mapDispatchToProps)(translate()(BrowsePage));
Markdown is supported
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