Commit 1521b8f6 authored by Matija Obreza's avatar Matija Obreza
Browse files

Added translations

parent 39324ca6
Pipeline #5274 passed with stages
in 3 minutes and 40 seconds
......@@ -28,6 +28,8 @@ const optionsBase = {
format: (value, format, lng) => {
if (format === 'uppercase') {
return value.toUpperCase();
} else if (format === 'lowercase') {
return value.toLowerCase();
}
return value;
},
......
{
"button": {
"label": {
"search": "Search"
}
"action": {
"add": "Add {{what, lowercase}}",
"backTo": "Back to {{where, lowercase}}",
"cancel": "Cancel",
"delete": "Delete",
"edit": "Edit",
"login": "Login",
"logout": "Logout",
"search": "Search",
"viewDetails": "View details"
},
"label": {
"item": "Item",
"item_plural": "Items",
"list": "List",
"list_plural": "Lists"
},
"message": {
"confirmDelete": "Deleting the {{what, lowercase}} record is only possible when there is no associated data."
},
"paginate": {
"numberOfItems": "{{count}} {{what, lowercase}}"
}
}
......@@ -14,11 +14,57 @@
"Translate Genesys": "Translate Genesys",
"copyright": "© {{from}} - {{to}} Data providers and the Crop Trust"
},
"label": {
"crop": "Crop",
"crop_plural": "Crops",
"dataset": "Dataset",
"dataset_plural": "Datasets",
"descriptor": "Descriptor",
"descriptor_plural": "Descriptors",
"descriptorlist": "Crop descriptor",
"descriptorlist_plural": "Crop descriptors",
"partner": "Partner",
"partner_plural": "Partners",
"vocabulary": "Controlled vocabulary",
"vocabulary_plural": "Controlled vocabularies",
"metadata": "Record metadata"
},
"menu": {
"datasets": "Datasets",
"descriptorlists": "Crop descriptors",
"descriptors": "Descriptors",
"partners": "Partners"
"Accessions": "Accessions",
"Controlled vocabularies": "Controlled vocabularies",
"Crops": "Crops",
"Datasets": "Datasets",
"Descriptor lists": "Crop descriptors",
"Descriptors": "Descriptors",
"Home": "Home",
"My Dashboard": "My dashboard",
"My profile": "My profile",
"Partners": "Partners"
},
"p": {
"crop": {
"subtitle": "List of crops registered with Genesys",
"title": "Crops"
},
"dataset": {
"title": "Dataset details"
},
"datasets": {
"title": "Datasets",
"subtitle": "Datasets published by Genesys partners"
},
"partner": {
"address": "Address",
"countries": "Countries",
"email": "Contact email",
"phone": "Phone number",
"urls": "Websites",
"wiewsCodes": "FAO WIEWS codes"
},
"vocab": {
"subtitle": "Commonly used controlled vocabularies",
"title": "Vocabularies"
}
},
"stats": {
"Accessions": "Accession records",
......
import * as React from 'react';
import { translate } from 'react-i18next';
import FastForward from 'material-ui-icons/FastForward';
import FastRewind from 'material-ui-icons/FastRewind';
import PlayArrow from 'material-ui-icons/PlayArrow';
......@@ -17,6 +19,8 @@ import {Page} from 'model/common.model';
interface IPaginationComponentProps extends React.ClassAttributes<any> {
classes: any;
t: any;
width: Breakpoint;
pageObj: Page<any>;
onChange: (page?: number, results?: number, sortBy?: string, dir?: string) => void;
......@@ -132,7 +136,7 @@ const mobile = ['sm', 'xs'] as Breakpoint[];
class PaginationComponent extends React.Component<IPaginationComponentProps, any> {
public render() {
const { classes, displayName, width, pageObj, onChange, sortOptions, infinite } = this.props;
const { t, classes, displayName, width, pageObj, onChange, sortOptions, infinite } = this.props;
let { sortBy } = this.props;
if (!sortBy) {
......@@ -158,7 +162,7 @@ class PaginationComponent extends React.Component<IPaginationComponentProps, any
<Grid container spacing={ 0 } className={ classes.root }>
<Grid item xs={ 12 }>
<div className={ `${classes.floatLeft} ${classes.bold} ${classes.textPagination}` }>
<Number value={ pageObj ? pageObj.totalElements : 0 } /> { displayName || 'items' }
{ t('common:paginate.numberOfItems', { count: pageObj ? pageObj.totalElements : 0, what: t(displayName || 'common:label.item', { count: pageObj ? pageObj.totalElements : 0 }) }) }
</div>
{ ! infinite &&
<Select
......@@ -291,4 +295,4 @@ class PaginationComponent extends React.Component<IPaginationComponentProps, any
}
}
export default compose(withStyles(styles), withWidth())(PaginationComponent);
export default translate()(compose(withStyles(styles), withWidth())(PaginationComponent));
import * as React from 'react';
import { withStyles} from 'material-ui/styles';
import { translate } from 'react-i18next';
import Drawer from 'material-ui/Drawer';
import { ListItem } from 'material-ui/List';
import { Link } from 'react-router-dom';
......@@ -61,11 +63,13 @@ interface ILeftMenuProps extends React.ClassAttributes<any> {
open: any;
closeMenu: (flag) => any;
classes: any;
t: any;
}
class LeftMenu extends React.Component<ILeftMenuProps, any> {
public render() {
const { t } = this.props;
const closeBtn = {
color: '#fff',
......@@ -86,28 +90,28 @@ class LeftMenu extends React.Component<ILeftMenuProps, any> {
<Close style={ closeBtn }/>
</div>
<ListItem button>
<Link to="/" >Home</Link>
<Link to="/">{ t('menu.Home') }</Link>
</ListItem>
<ListItem button>
<Link to="/datasets" >Datasets</Link>
<Link to="/datasets">{ t('menu.Datasets') }</Link>
</ListItem>
<ListItem button>
<Link to="/partners" >Partners</Link>
<Link to="/partners">{ t('menu.Partners') }</Link>
</ListItem>
<ListItem button>
<Link to="/descriptorlists">Crop descriptors</Link>
<Link to="/descriptorlists">{ t('menu.Descriptor lists') }</Link>
</ListItem>
<ListItem button>
<Link to="/descriptors" >Descriptors</Link>
<Link to="/descriptors">{ t('menu.Descriptors') }</Link>
</ListItem>
<ListItem button>
<Link to="/accessions" >Accessions</Link>
<Link to="/accessions">{ t('menu.Accessions') }</Link>
</ListItem>
<ListItem button>
<Link to="/crops" >Crops</Link>
<Link to="/crops">{ t('menu.Crops') }</Link>
</ListItem>
<ListItem button>
<Link to="/vocabulary" >Controlled vocabularies</Link>
<Link to="/vocabulary">{ t('menu.Controlled vocabularies') }</Link>
</ListItem>
</div>
</Drawer>
......@@ -116,4 +120,4 @@ class LeftMenu extends React.Component<ILeftMenuProps, any> {
}
}
export default (withStyles as any)(styleSheet)(LeftMenu);
export default translate()((withStyles as any)(styleSheet)(LeftMenu));
import * as React from 'react';
import {withStyles} from 'material-ui/styles';
import { withStyles } from 'material-ui/styles';
import { translate } from 'react-i18next';
import { Link } from 'react-router-dom';
import Button from 'material-ui/Button';
......@@ -10,6 +11,7 @@ interface IUserMenuComponentProps extends React.ClassAttributes<any> {
classes: any;
logoutRequest: () => Promise<any>;
userName: string;
t: any;
}
const styles = {
......@@ -80,7 +82,7 @@ class UserMenuComponent extends React.Component<IUserMenuComponentProps, any> {
public render() {
const { logoutRequest, classes } = this.props;
const { logoutRequest, classes, t } = this.props;
const arrow = {
verticalAlign: 'middle',
......@@ -105,17 +107,17 @@ class UserMenuComponent extends React.Component<IUserMenuComponentProps, any> {
open={ this.state.open }
onClose={ this.handleRequestClose }
>
<Link to="/dashboard"><MenuItem>My Dashboard</MenuItem></Link>
<Link to="/profile"><MenuItem>My profile</MenuItem></Link>
<Link to="/accessions"><MenuItem>Accessions</MenuItem></Link>
<Link to="/crops"><MenuItem>Crops</MenuItem></Link>
<Link to="/vocabulary"><MenuItem>Controlled vocabularies</MenuItem></Link>
<Link to="/dashboard"><MenuItem>{ t('menu.My Dashboard') }</MenuItem></Link>
<Link to="/profile"><MenuItem>{ t('menu.My profile') }</MenuItem></Link>
<Link to="/accessions"><MenuItem>{ t('menu.Accessions') }</MenuItem></Link>
<Link to="/crops"><MenuItem>{ t('menu.Crops') }</MenuItem></Link>
<Link to="/vocabulary"><MenuItem>{ t('menu.Controlled vocabularies') }</MenuItem></Link>
<Link to="/gui"><MenuItem>UI Tests</MenuItem></Link>
<MenuItem onClick={ logoutRequest } >Logout</MenuItem>
<MenuItem onClick={ logoutRequest } >{ t('common:action.logout') }</MenuItem>
</Menu>
</div>
);
}
}
export default withStyles(styles)(UserMenuComponent);
export default translate()(withStyles(styles)(UserMenuComponent));
......@@ -115,7 +115,8 @@ class Header extends React.Component<IHeaderProps | any, any> {
if (this.hasRole(roles)) {
return <UserMenuComponent userName={ this.props.login.user_name } logoutRequest={ this.logout }/>;
} else {
return <Link className={ this.props.classes.linkLogin } to="/login">Login</Link>;
const { t } = this.props;
return <Link className={ this.props.classes.linkLogin } to="/login">{ t('common:action.login') }</Link>;
}
}
......@@ -156,10 +157,10 @@ class Header extends React.Component<IHeaderProps | any, any> {
<img src="/images/GENESYS-LOGO.svg" className={ classes.logoIcon } />
</Link>
<div className="navigation-block">
<NavLink activeClassName="active" to="/datasets">{ t('menu.datasets') }</NavLink>
<NavLink activeClassName="active" to="/partners">{ t('menu.partners') }</NavLink>
<NavLink activeClassName="active" to="/descriptorlists">{ t('menu.descriptorlists') }</NavLink>
<NavLink activeClassName="active" to="/descriptors">{ t('menu.descriptors') }</NavLink>
<NavLink activeClassName="active" to="/datasets">{ t('menu.Datasets') }</NavLink>
<NavLink activeClassName="active" to="/partners">{ t('menu.Partners') }</NavLink>
<NavLink activeClassName="active" to="/descriptorlists">{ t('menu.Descriptor lists') }</NavLink>
<NavLink activeClassName="active" to="/descriptors">{ t('menu.Descriptors') }</NavLink>
</div>
</div>
<div>{ this.renderLogin([ROLE_USER, ROLE_ADMINISTRATOR]) }</div>
......
import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { translate } from 'react-i18next';
import Grid from 'material-ui/Grid';
import { listCrops, createCrop } from 'actions/crop';
......@@ -16,6 +18,7 @@ interface IBrowsePageProps extends React.ClassAttributes<any> {
crops?: Crop[];
listCrops: any;
createCrop: any;
t: any;
}
class BrowsePage extends React.Component<IBrowsePageProps & any, any> {
......@@ -29,12 +32,12 @@ class BrowsePage extends React.Component<IBrowsePageProps & any, any> {
}
public render() {
const { crops, createCrop} = this.props;
const { crops, createCrop, t } = this.props;
return (
<div>
<Authorize role="ROLE_ADMINISTRATOR">
<ContentHeaderWithButton title="What do you want to do?" buttons={ <Button raised onClick={ createCrop }>Add crop</Button> } />
<ContentHeaderWithButton title="What do you want to do?" buttons={ <Button raised onClick={ createCrop }>{ t('common:action.add', { what: t('label.crop') }) }</Button> } />
</Authorize>
<Grid container spacing={ 0 } className="back-gray">
{ crops && crops.sort((a, b) => a.title.localeCompare(b.title)).map((crop: Crop) => (
......@@ -57,4 +60,4 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
createCrop,
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(BrowsePage);
export default translate()(connect(mapStateToProps, mapDispatchToProps)(BrowsePage));
import * as React from 'react';
import { translate } from 'react-i18next';
import ContentHeader from 'ui/common/heading/ContentHeader';
import renderRoutes from 'ui/renderRoutes';
export default function Wrapper({route, match}) {
function Wrapper({route, match, t}) {
return (
<div>
<ContentHeader title="Crops" subTitle="We give priority to some and ignore others"/>
<ContentHeader title={ t('p.crop.title') } subTitle={ t('p.crop.subtitle') } />
{ renderRoutes(route.routes, match.path) }
</div>
);
}
export default translate()(Wrapper);
......@@ -109,7 +109,7 @@ class BrowsePage extends React.Component<IDatasetsProps, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="datasets"
displayName="label.dataset"
sortOptions={ Dataset.SORT_OPTIONS }
infinite
/>
......@@ -140,7 +140,7 @@ class BrowsePage extends React.Component<IDatasetsProps, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="datasets"
displayName="label.dataset"
sortOptions={ Dataset.SORT_OPTIONS }
infinite
/>
......
......@@ -2,6 +2,7 @@ import * as React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { withStyles } from 'material-ui/styles';
import { translate } from 'react-i18next';
import { loadDataset, deleteDataset, publishDataset } from 'actions/dataset';
import { Dataset } from 'model/dataset.model';
......@@ -15,6 +16,8 @@ import Grid from 'material-ui/Grid';
interface IDatasetDetailProps extends React.ClassAttributes<any> {
classes: any;
t: any;
uuid: string;
dataset: Dataset;
loadDataset: (uuid: string) => Promise<Dataset>;
......@@ -47,7 +50,7 @@ class DatasetDetail extends React.Component<IDatasetDetailProps, any> {
}
public render() {
const { classes, uuid, dataset, publishDataset, deleteDataset } = this.props;
const { t, classes, uuid, dataset, publishDataset, deleteDataset } = this.props;
const stillLoading: boolean = (! dataset || (uuid && dataset && dataset.uuid !== uuid));
......@@ -58,9 +61,9 @@ class DatasetDetail extends React.Component<IDatasetDetailProps, any> {
<Grid item xs={ 12 } md={ 10 }>
<Grid container spacing={ 0 }>
<Grid item xs={ 12 } className={ `back-gray-yellow pl-20 pr-20 pt-10 pb-10 ${classes.backSection}` }>
<h4 className="font-bold lh-35 m-0">Dataset Detail</h4>
<h4 className="font-bold lh-35 m-0">{ t('p.dataset.title') }</h4>
<div className={ classes.flexGrow }/>
<BackButton defaultTarget="/datasets" defaultBackText="BACK TO LIST"/>
<BackButton defaultTarget="/datasets" defaultBackText={ t('common:action.backTo', { where: t('common:label.list') }) }/>
</Grid>
{ stillLoading ? <Loading /> :
<Grid item xs={ 12 } className="p-10">
......@@ -73,7 +76,7 @@ class DatasetDetail extends React.Component<IDatasetDetailProps, any> {
<Grid container spacing={ 0 }>
<Grid item xs={ 12 } className={ `back-gray-yellow pt-10 pb-10 pr-20 ${classes.backSection}` }>
<div className={ classes.flexGrow }/>
<BackButton defaultTarget="/datasets" defaultBackText="BACK TO LIST"/>
<BackButton defaultTarget="/datasets" defaultBackText={ t('common:action.backTo', { where: t('common:label.list') }) }/>
</Grid>
</Grid>
</div>
......@@ -92,4 +95,4 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
deleteDataset,
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)((withStyles as any)(styles)(DatasetDetail));
export default translate()(connect(mapStateToProps, mapDispatchToProps)((withStyles as any)(styles)(DatasetDetail)));
import * as React from 'react';
import { translate } from 'react-i18next';
import ContentHeader from 'ui/common/heading/ContentHeader';
import renderRoutes from 'ui/renderRoutes';
export default function Wrapper({route, match}) {
function Wrapper({route, match, t}) {
return (
<div>
<ContentHeader title="Datasets" subTitle="Datasets published by Genesys partners"/>
<ContentHeader title={ t('p.datasets.title') } subTitle={ t('p.datasets.subtitle') }/>
{ renderRoutes(route.routes, match.path) }
</div>
);
}
export default translate()(Wrapper);
......@@ -111,7 +111,7 @@ class BrowsePage extends React.Component<IDescriptorListsPageProps & any, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="descriptors"
displayName="label.descriptor"
infinite
sortOptions={ Descriptor.SORT_OPTIONS }
/>
......@@ -139,7 +139,7 @@ class BrowsePage extends React.Component<IDescriptorListsPageProps & any, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="descriptors"
displayName="label.descriptor"
infinite
sortOptions={ Descriptor.SORT_OPTIONS }
/>
......
......@@ -118,7 +118,7 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="lists"
displayName="label.descriptorlist"
sortOptions={ DescriptorList.SORT_OPTIONS }
infinite
/>
......@@ -148,7 +148,7 @@ class BrowsePage extends React.Component<IBrowsePageProps, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="lists"
displayName="label.descriptorlist"
sortOptions={ DescriptorList.SORT_OPTIONS }
infinite
/>
......
......@@ -25,6 +25,7 @@ interface IBrowsePageProps extends React.ClassAttributes<any> {
login: any;
classes: any;
router: any;
t: any;
pagination?: Pagination<IPartnerFilter>;
paged?: Page<Partner>;
......@@ -99,7 +100,7 @@ class PartnerListPage extends React.Component<IBrowsePageProps, any> {
public render() {
const {classes, paged, pagination} = this.props;
const { classes, paged, pagination } = this.props;
const stillLoading: boolean = (! paged || ! paged.content);
......@@ -116,7 +117,7 @@ class PartnerListPage extends React.Component<IBrowsePageProps, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="partners"
displayName="label.partner"
sortOptions={ Partner.SORT_OPTIONS }
infinite
/>
......@@ -150,7 +151,7 @@ class PartnerListPage extends React.Component<IBrowsePageProps, any> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
displayName="partners"
displayName="label.partner"
sortOptions={ Partner.SORT_OPTIONS }
infinite
/>
......
......@@ -2,6 +2,7 @@
import * as React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import { translate } from 'react-i18next';
import {loadPartner, editPartner, deletePartner} from 'actions/partner';
import {Partner} from 'model/partner.model';
......@@ -19,6 +20,8 @@ import Permissions from 'ui/common/permission/Permissions';
interface IPartnerPageProps extends React.ClassAttributes<any> {
classes: any;
t: any;
uuid?: string;
partner?: Partner;
loading?: any;
......@@ -48,12 +51,12 @@ class PartnerPage extends React.Component<IPartnerPageProps, any> {
}
private onDelete = (e) => {
const {partner, deletePartner} = this.props;
const { t, partner, deletePartner } = this.props;
confirm(<span>Delete <b>{ partner.name }</b>?</span>, {
description: `Deleting the partner record is only possible when there is no associated data.`,
confirmLabel: 'Delete',
abortLabel: 'Cancel',
description: t('common:message.confirmDelete', { what: t('label.partner') }),
confirmLabel: t('common:action.delete'),
abortLabel: t('common:action.cancel'),
}).then(() => {
deletePartner(partner);
}).catch(() => {
......@@ -62,7 +65,7 @@ class PartnerPage extends React.Component<IPartnerPageProps, any> {
}
public render() {
const {uuid, partner} = this.props;
const { t, uuid, partner } = this.props;
const stillLoading: boolean = (! partner || (uuid && (partner.uuid !== uuid)));
......@@ -83,45 +86,45 @@ class PartnerPage extends React.Component<IPartnerPageProps, any> {
<Properties>
{ partner.urls.length > 0 && (
<PropertiesItem title="Websites:">
<PropertiesItem title={ t('p.partner.urls') }>
{ partner.urls.map((url) => (
<div key={ url }><ExternalLink link={ url }>{ url }</ExternalLink></div>
)) }
</PropertiesItem>
) }
{ partner.wiewsCodes.length > 0 && (
<PropertiesItem title="FAO WIEWS codes:">
<PropertiesItem title={ t('p.partner.wiewsCodes') }>
{ partner.wiewsCodes.map((wiewsCode) => (
<div key={ wiewsCode }><FaoWiewsLink wiewsCode={ wiewsCode }>{ wiewsCode }</FaoWiewsLink></div>
)) }
</PropertiesItem>
) }
{ partner.countryCodes.length > 0 && (
<PropertiesItem title="Countries:">
<PropertiesItem title={ t('p.partner.countries') }>
{ partner.countryCodes.map((countryCode) => (
<div key={ countryCode }>{ countryCode }</div>
)) }
</PropertiesItem>
) }
{ partner.email && (
<PropertiesItem title="Email:">
<PropertiesItem title={ t('p.partner.email') }>
<div><a href={ `mailto:${partner.email}` }>{ partner.email }</a></div>
</PropertiesItem>
) }
{ partner.phone && (
<PropertiesItem title="Phone number:">{ partner.phone }</PropertiesItem>
<PropertiesItem title={ t('p.partner.phone') }>{ partner.phone }</PropertiesItem>