Commit 6e1a1487 authored by Viacheslav Pavlov's avatar Viacheslav Pavlov Committed by Matija Obreza

i18n

- src/translations.json for application strings
- translations for common components
- translations split into modules, a script compiles one translation file
- i18n for user module
- i18n for requests module
- i18n for list module
- i18n for accessions module
- i18n for repository module
- i18n for subsets
- i18n for institutes module
- i18n for crop module
parent 59af41c0
const fg = require('fast-glob');
const _ = require('lodash');
const fs = require('fs');
fg([`./src/**/translations.json`, `./src/translations.json`])
.then((entries) => entries.map((path) => getTranslations(path)))
.then((content) => fs.writeFileSync(`locales/en/translations.json`, `{\n${content}}`));
const getTranslations = (path) => {
const prefix = path.substring(path.indexOf('./src/') + './src/'.length, path.indexOf('/translations.json'));
console.log('Loading translations of module', prefix);
const fileContent = fs.readFileSync(path, 'utf8');
return prefix !== '/' ? _(`"${prefix}": ${fileContent}\n`).value() : fileContent.substr(1, fileContent.length - 2);
};
{
"action": {
"add": "Add {{what, lowercase}}",
"applyFilters": "Apply filters",
"approve": "Approve and publish",
"back": "Back",
"backTo": "Back to {{where, lowercase}}",
"cancel": "Cancel",
"delete": "Delete",
"deleteData": "Delete data",
"edit": "Edit",
"login": "Login",
"logout": "Logout",
"nextStep": "Next step",
"reject": "Reject",
"remove": "Remove",
"reset": "Reset",
"return": "Return",
"save": "Save",
"saveChanges": "Save changes",
"search": "Search",
"viewDetails": "View details"
"sendToReview": "Send to review",
"unpublish": "Unpublish"
},
"label": {
"item": "Item",
"item_plural": "Items",
"list": "List",
"list_plural": "Lists",
"prettyNumber": "{{value, number}}"
"csv": {
"autoDetect": "Auto-detect ",
"autoDetectLabel": "Auto-detect CSV settings",
"comma": "Comma",
"configuration": "CSV configuration",
"escapeCharacter": "Escape character",
"other": "Other",
"quoteCharacter": "Quote character",
"semicolon": "Semicolon",
"separator": "Separator character",
"space": "Space",
"tab": "Tab",
"typeYourEscapeCharacter": "Type your escape character",
"typeYourQuoteCharacter": "Type your quote character",
"typeYourSeparator": "Type your separator"
},
"f": {
"dateSearch": "Date search",
"fromIncluding": "From including",
"lastModifiedDate": "Last modified date",
"textSearch": "Text search"
},
"message": {
"confirmDelete": "Deleting the {{what, lowercase}} record is only possible when there is no associated data."
"fileUploader": {
"chooseFiles": "Choose files to upload",
"dragFiles": "Drag files here \n or",
"release": "Release to upload"
},
"label": {
"dateNotProvided": "Date not provided",
"description": "Description",
"either": "Either",
"itemEditorWarn": "Don't use the ItemsEditor for more than 100 items!",
"lastUpdated": "Last updated",
"no": "No",
"prettyNumber": "{{value, number}}",
"sortBy": "Sort By",
"stepsForDataPublication": "Steps for data publication completion",
"title": "Title",
"yes": "Yes"
},
"paginate": {
"numberOfItems": "{{count, number}} {{what, lowercase}}",
......
This diff is collapsed.
This diff is collapsed.
......@@ -19,16 +19,17 @@
"main": "index.js",
"scripts": {
"clean": "rimraf target",
"build": "webpack --config config/webpack-development.config.js",
"build": "npm run generateI18n && webpack --config config/webpack-development.config.js",
"build:production": "cross-env NODE_ENV=production SSR=true webpack --config config/webpack-production.config.js",
"build:server": "cross-env NODE_ENV=production SSR=true webpack --config config/server.config.js",
"serve": "webpack-dev-server --config config/webpack-development.config.js",
"serve": "npm run generateI18n && webpack-dev-server --config config/webpack-development.config.js",
"serve:production": "cross-env NODE_ENV=production webpack-dev-server --config config/webpack-production.config.js",
"build:ssr": "rimraf target && npm run build:production && npm run build:server",
"build:ssr": "npm run generateI18n && rimraf target && npm run build:production && npm run build:server",
"serve:ssr": "npm run build:ssr && cd target/app/server && cross-env SSR=true node server.js",
"debug:ssr": "rimraf target && npm run build && cross-env SSR=true webpack --config config/server.config.js && cd target/app/server && cross-env SSR=true node server.js",
"debug:ssr2": "cross-env SSR=true webpack --config config/server.config.js && cd target/app/server && cross-env SSR=true node server.js",
"run:ssr": "cd target/app/server && cross-env SSR=true node server.js",
"generateI18n": "node i18n/generateI18n.ts",
"i18nscan": "i18next-scanner --config i18next-scanner.config.js 'src/**/*.tsx'"
},
"dependencies": {
......@@ -45,6 +46,7 @@
"es-cookie": "^1.2.0",
"express": "^4.16.3",
"express-http-proxy": "^1.2.0",
"fast-glob": "^2.2.3",
"flattenjs": "^1.0.4",
"form-data": "^2.3.2",
"history": "^4.7.2",
......
{
"public": {
"c": {
"accessionCard": {
"addToMyList": "Add to my list"
},
"pdciTable": {
"pdciScore": "PDCI score of this accession is {{score, number}} of 10.0.",
"readPDCI": "Read about Passport Data Completeness Index",
"pdciInstitute": "Average PDCI score for this institute is {{score, number}}."
}
},
"f": {
"filtersTitle": "Filter accessions",
"seqNumber": "Sequential number",
"subtaxon": "Subtaxon",
"originOfMaterial": "Origin of material",
"elevation": "Elevation",
"status": "Status",
"historic": "Historic records",
"available": "Available for distribution",
"mlsStatus": "Included in MLS",
"sgsv": "Backed up in SGSV"
},
"p": {
"display": {
"title": "Accession details",
"subTitle": "Passport data and everything else",
"removeFromMyList": "Remove {{accessionNumber}} from my list",
"addToMyList": "Add {{accessionNumber}} to my list",
"holdingInstitute": "Holding institute",
"DOI": "DOI",
"acquisitionDate": "Acquisition Date",
"availability": "Availability for distribution",
"ITPGRFAMLS": "ITPGRFA MLS",
"donorInstitute": "Donor institute",
"donorAccessionNumber": "Donor accession number",
"safetyDuplicationInstitute": "Safety duplication institute",
"accessionURL": "Accession URL",
"scientificName": "Scientific name",
"cropName": "Crop name",
"providedCropName": "Provided crop name",
"accessionNames": "Accession names",
"collectingInformation": "Collecting information",
"remarks": "Remarks",
"pdci": "Passport Data Completeness Index",
"metadata": "Metadata",
"permanentURL": "Permanent URL",
"associatedDatasets": "Associated Datasets",
"associatedSubsets": "Associated Subsets"
},
"browse": {
"title": "Accession browser",
"subTitle": "Explore curated sets of accessions"
}
}
},
"tab": {
"data": "Accessions",
"overview": "Overview",
"map": "Map"
},
"common": {
"modelName": "Accession",
"modelName_plural": "Accessions",
"menu": "Accessions",
"stats": "Accession record",
"stats_plural": "Accession records",
"acceNumb": "Accession number",
"countryOfOrigin": "Country of origin",
"instituteCode": "Institute code",
"taxonomy": "Taxonomy",
"genus": "Genus",
"species": "Species",
"doi": "DOI",
"sampStat": "Biological status of accession",
"storageType": "Type of germplasm storage",
"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 provided"
},
"mlsStatus": {
"true": "Accession is part of the Multi-lateral system of ITPGRFA",
"false": "Not declared in the Multi-lateral system of ITPGRFA ",
"null": "Status not provided"
},
"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"
},
"sampleStatus": {
"100": "Wild",
"110": "Natural",
"120": "Semi-natural/wild",
"130": "Semi-natural/sown",
"200": "Weedy",
"300": "Traditional cultivar/Landrace",
"400": "Breeding/Research Material",
"410": "Breeders Line",
"411": "Synthetic population",
"412": "Hybrid",
"413": "Founder stock/base population",
"414": "Inbred line",
"415": "Segregating population",
"416": "Clonal selection",
"420": "Genetic stock",
"421": "Mutant",
"422": "Cytogenetic stocks",
"423": "Other genetic stocks",
"500": "Advanced/improved cultivar",
"600": "GMO",
"999": "Other"
},
"overview": {
"institute code": "Holding Institute",
"institute country code3": "Country of holding institute",
"crop shortName": "Crop name",
"cropName": "Crop",
"sampStat": "Biological status of accession",
"taxonomy genus": "Genus",
"taxonomy genusSpecies": "Species",
"countryOfOrigin code3": "Country of Origin",
"donorCode": "FAO WIEWS code of donor institute",
"mlsStatus": "ITGPRFA Multi-lateral system",
"available": "Available for distribution",
"duplSite": "Site of safety duplication",
"breederCode": "Breeder code",
"sgsv": "Safety duplicated in Svalbard",
"storage": "Type of Germplasm storage"
}
}
}
\ No newline at end of file
import * as React from 'react';
import {translate} from 'react-i18next';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import { parse } from 'query-string';
......@@ -40,7 +41,7 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
}
public render() {
const { paged, filterCode, currentTab } = this.props;
const { paged, filterCode, currentTab, t} = this.props;
const renderAccession = (s: Accession, index: number) => {
return <AccessionCard key={ s.uuid } index={ index } accession={ s } />;
......@@ -50,11 +51,11 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
<PageLayout sidebar={
<AccessionFilters initialValues={ paged && paged.filter || {} } onSubmit={ this.myApplyFilters } />
}>
<ContentHeader title="Accession browser" subTitle="Explore curated sets of accessions" />
<ContentHeader title="accessions.public.p.browse.title" subTitle="accessions.public.p.browse.subTitle" />
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="label.accession"
displayName="accessions.common.modelName"
sortOptions={ Accession.SORT_OPTIONS }
infinite
/>
......@@ -62,15 +63,15 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
tab={ currentTab }
actions={
<span>
<Button variant="raised"> Select all </Button>
<Button variant="raised"> Delete </Button>
<Button variant="raised"> Share </Button>
<Button variant="raised">{ t('TODO-Demo Select all') }</Button>
<Button variant="raised">{ t('TODO-Demo Delete') }</Button>
<Button variant="raised">{ t('TODO-Demo Share') }</Button>
</span>
}
>
<Tab name="data" to={ `/a/${filterCode || ''}` }>Accessions</Tab>
<Tab name="overview" to={ `/a/overview/${filterCode || ''}` }>Overview</Tab>
<Tab name="map" to={ `/a/map/${filterCode || '' }` }>Map</Tab>
<Tab name="data" to={ `/a/${filterCode || ''}` }>{ t('accessions.tab.data') }</Tab>
<Tab name="overview" to={ `/a/overview/${filterCode || ''}` }>{ t('accessions.tab.overview') }</Tab>
<Tab name="map" to={ `/a/map/${filterCode || '' }` }>{ t('accessions.tab.map') }</Tab>
</Tabs>
......@@ -107,4 +108,4 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(BrowsePage);
export default translate()(connect(mapStateToProps, mapDispatchToProps)(BrowsePage));
......@@ -95,7 +95,7 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
return (
<PageLayout withFooter>
<ScrollToTopOnMount />
<ContentHeader title="Accession details" subtitle="Passport data and everything else" />
<ContentHeader title="accessions.public.p.display.title" subtitle="accessions.public.p.display.subTitle" />
{ stillLoading ? <Loading /> :
<div>
......@@ -105,12 +105,12 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
<PageContents>
<MainSection title={
<div>
Accession: { accession.accessionNumber }
{ t('accessions.common.modelName') }: { accession.accessionNumber }
<div className="float-right">
<ReduxCheckbox
label={
<b>
{ isChecked ? `Remove ${accession.accessionNumber} from my list` : `Add ${accession.accessionNumber} to my list` }
{ isChecked ? t('accessions.public.p.display.removeFromMyList', {accessionNumber: accession.accessionNumber}) : t('accessions.public.p.display.addToMyList', {accessionNumber: accession.accessionNumber}) }
</b>
}
input={ {
......@@ -123,85 +123,85 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
}
>
<Properties>
{ accession.doi && <PropertiesItem title="DOI"><DOI noPrefix value={ accession.doi } /></PropertiesItem> }
<PropertiesItem title="Accession number">{ accession.accessionNumber }</PropertiesItem>
<PropertiesItem title="Holding institute">
{ accession.doi && <PropertiesItem title="accessions.public.p.display.DOI"><DOI noPrefix value={ accession.doi } /></PropertiesItem> }
<PropertiesItem title="accessions.common.acceNumb" >{ accession.accessionNumber }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.holdingInstitute">
<InstituteLink to={ accession.institute }>
{ accession.institute.fullName }
</InstituteLink>
<span> &mdash; </span>
<CountryLink noflag country={ accession.institute.country }/>
</PropertiesItem>
<PropertiesItem title="Institute code">{ accession.institute.code }</PropertiesItem>
<PropertiesItem title="Acquisition date"><McpdDate value={ accession.acquisitionDate } /></PropertiesItem>
{ accession.countryOfOrigin && <PropertiesItem title="Country of origin">{ <CountryLink country={ accession.countryOfOrigin }/> }</PropertiesItem> }
{ accession.sampStat && <PropertiesItem title="Biological status of accession">{ t(`accession.sampleStatus.${accession.sampStat}`) }</PropertiesItem> }
{ accession.storage && accession.storage.length > 0 && <PropertiesItem title="Type of Germplasm storage">
<PropertiesItem title="accessions.common.instituteCode">{ accession.institute.code }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.acquisitionDate"><McpdDate value={ accession.acquisitionDate } /></PropertiesItem>
{ accession.countryOfOrigin && <PropertiesItem title="accessions.common.countryOfOrigin">{ <CountryLink country={ accession.countryOfOrigin }/> }</PropertiesItem> }
{ accession.sampStat && <PropertiesItem title="accessions.common.sampStat">{ t(`accessions.common.sampleStatus.${accession.sampStat}`) }</PropertiesItem> }
{ accession.storage && accession.storage.length > 0 && <PropertiesItem title="accessions.common.storageType">
{ accession.storage.map((storage, i) => (
<div key={ storage } style={ {width: '100%', paddingTop: '.25rem'} }>{ t(`accession.storage.${storage}`) }</div>
<div key={ storage } style={ {width: '100%', paddingTop: '.25rem'} }>{ t(`accessions.common.storage.${storage}`) }</div>
)) }
</PropertiesItem> }
<PropertiesItem title="Availability for distribution" keepEmpty>{ t(`accession.available.${accession.available}`) }</PropertiesItem>
<PropertiesItem title="ITPGRFA MLS" keepEmpty>{ t(`accession.mlsStatus.${accession.mlsStatus}`) }</PropertiesItem>
<PropertiesItem title="Donor institute">{ accession.donorCode }</PropertiesItem>
<PropertiesItem title="Donor accession number">{ accession.donorNumb }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.availability" keepEmpty>{ t(`accessions.common.available.${accession.available}`) }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.ITPGRFAMLS" keepEmpty>{ t(`accessions.common.mlsStatus.${accession.mlsStatus}`) }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.donorInstitute">{ accession.donorCode }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.donorAccessionNumber">{ accession.donorNumb }</PropertiesItem>
{ accession.duplSite && accession.duplSite.length > 0 && <PropertiesItem title="Safety duplication institute">
{ accession.duplSite && accession.duplSite.length > 0 && <PropertiesItem title="accessions.public.p.display.safetyDuplicationInstitute">
{ accession.duplSite.map((duplSite, i) => (
<div key={ duplSite } style={ {width: '100%', paddingTop: '.25rem'} }>{ duplSite }</div>
)) }
</PropertiesItem> }
{ accession.acceUrl && <PropertiesItem title="Accession URL"><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
{ accession.acceUrl && <PropertiesItem title="accessions.public.p.display.accessionURL"><ExternalLink link={ accession.acceUrl } /></PropertiesItem> }
</Properties>
</MainSection>
<PageSection title="Taxonomy">
<PageSection title="accessions.common.taxonomy">
<Properties>
<PropertiesItem title="Genus">{ accession.taxonomy.genus }</PropertiesItem>
<PropertiesItem title="Species">
<PropertiesItem title="accessions.common.genus">{ accession.taxonomy.genus }</PropertiesItem>
<PropertiesItem title="accessions.common.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"><CropChips crops={ accession.crop.shortName } /></PropertiesItem> }
<PropertiesItem title="Provided crop name">{ accession.cropName }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.scientificName"><SciName taxa={ accession.taxonomy.taxonNameHtml } /></PropertiesItem>
{ accession.crop && <PropertiesItem title="accessions.public.p.display.cropName"><CropChips crops={ accession.crop.shortName } /></PropertiesItem> }
<PropertiesItem title="accessions.public.p.display.providedCropName">{ accession.cropName }</PropertiesItem>
</Properties>
</PageSection>
{ (accession.donorCode || (accession.aliases && accession.aliases.length > 0)) &&
<PageSection title="Accession names">
<PageSection title="accessions.public.p.display.accessionNames">
<Properties>
{ accession.donorCode && <PropertiesItem title={ t('accession.alias.DONORNUMB') }>{ accession.donorNumb } <em>{ accession.donorCode }</em></PropertiesItem> }
{ accession.donorCode && <PropertiesItem title={ t('accessions.common.alias.DONORNUMB') }>{ accession.donorNumb } <em>{ accession.donorCode }</em></PropertiesItem> }
{ accession.aliases && accession.aliases.map((alias) => (
<PropertiesItem key={ alias.id } title={ t(`accession.alias.${alias.aliasType}`) }>{ alias.name } <em>{ alias.usedBy }</em></PropertiesItem>
<PropertiesItem key={ alias.id } title={ t(`accessions.common.alias.${alias.aliasType}`) }>{ alias.name } <em>{ alias.usedBy }</em></PropertiesItem>
)) }
</Properties>
</PageSection>
}
{ accession.coll &&
<PageSection title="Collecting information">
<PageSection title="accessions.public.p.display.collectingInformation">
<Properties>
{ accession.countryOfOrigin && <PropertiesItem title="Country of origin">{ <CountryLink country={ accession.countryOfOrigin }/> }</PropertiesItem> }
{ accession.coll.collDate && <PropertiesItem key="collDate" title={ t(`accession.coll.collDate`) }><McpdDate value={ accession.coll.collDate } /></PropertiesItem> }
{ accession.countryOfOrigin && <PropertiesItem title="accessions.common.countryOfOrigin">{ <CountryLink country={ accession.countryOfOrigin }/> }</PropertiesItem> }
{ accession.coll.collDate && <PropertiesItem key="collDate" title={ t(`accessions.common.coll.collDate`) }><McpdDate value={ accession.coll.collDate } /></PropertiesItem> }
{ accession.coll &&
[ 'collMissId', 'collNumb', 'collSite', 'collSrc' ]
.filter((prop) => accession.coll[prop] !== null).map((prop) => (
<PropertiesItem key={ prop } title={ t(`accession.coll.${prop}`) }>{ accession.coll[prop] }</PropertiesItem>
<PropertiesItem key={ prop } title={ t(`accessions.common.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>
<PropertiesItem key={ prop } title={ t(`accessions.common.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>
<PropertiesItem key={ prop } title={ t(`accessions.common.geo.${prop}`) }>{ accession.geo[prop] }</PropertiesItem>
))
}
</Properties>
......@@ -220,7 +220,7 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
</PageSection>
}
{ accession.remarks && accession.remarks.length > 0 && <PageSection title="Remarks">
{ accession.remarks && accession.remarks.length > 0 && <PageSection title="accessions.public.p.display.remarks">
<Properties>
{ accession.remarks && accession.remarks.map((remark) => (
<PropertiesItem key={ remark.id } title={ remark.fieldName }>{ remark.remark }</PropertiesItem>
......@@ -228,14 +228,14 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
</Properties>
</PageSection> }
{ pdci && <PdciTable pdci={ pdci } title="Passport Data Completeness Index"/> }
{ pdci && <PdciTable pdci={ pdci } title="accessions.public.p.display.pdci"/> }
<PageSection title="Metadata">
<PageSection title="accessions.public.p.display.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>
<PropertiesItem title="common:label.UUID">{ `urn:uuid:${accession.uuid}` }</PropertiesItem>
<PropertiesItem title="accessions.public.p.display.permanentURL"><ExternalLink link={ `https://purl.org/germplasm/id/${accession.uuid}` } /></PropertiesItem>
<PropertiesItem title="common:label.lastUpdated"><PrettyDate value={ accession.lastModifiedDate } /></PropertiesItem>
<PropertiesItem title="common:label.created"><PrettyDate value={ accession.createdDate } /></PropertiesItem>
</Properties>
</PageSection>
......@@ -243,17 +243,17 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
{ datasets && datasets.length > 0 &&
<PropertiesCard
small
title="Associated datasets"
title="accessions.public.p.display.associatedDatasets"
propertyItemProps={ {