Commit 78e55bb6 authored by Oleksii Savran's avatar Oleksii Savran Committed by Matija Obreza

Diversity tree: updates

-Updated diversity tree stepper
-Returned loading crop diversity tree functionality
-Added contributor role
-Fixes
parent 2c435975
......@@ -20,6 +20,7 @@ enum CreatorRole {
COLLECTOR = 'COLLECTOR',
DIGITIZER = 'DIGITIZER',
CURATOR = 'CURATOR',
CONTRIBUTOR = 'CONTRIBUTOR',
}
export { DiversityTreeCreator as default, CreatorRole };
......@@ -1120,7 +1120,8 @@
"holdingInstitutes": "Holding institutes",
"countryOfInstitutes": "Country of holding institute",
"representedGenera": "Most represented Genera",
"representedSpecies": "Most represented Species"
"representedSpecies": "Most represented Species",
"diversityTrees": "Diversity trees"
},
"browse": {
"title": "Crop list",
......@@ -1775,7 +1776,7 @@
"currentVersion": "Current version"
},
"diversityTreeDisplay": {
"divTreeCreators": "Diversity tree creators",
"divTreeContributors": "Diversity tree contributors",
"rematch": "Rematch accessions",
"diversityTreeMetadata": "Diversity tree metadata",
"dataAndResources": "Data and resources",
......@@ -1860,7 +1861,6 @@
},
"creators": {
"stepName": "Diversity tree creators",
"Role": "Role: ",
"fullName": "Full name",
"fullNamePlaceholder": "Jane A. Doe",
"institutionalAffiliation": "Institutional affiliation",
......@@ -1895,10 +1895,7 @@
"stats_plural": "Diversity trees",
"creators": {
"role": {
"MANAGER": "Data manager",
"DIGITIZER": "Data digitizer",
"COLLECTOR": "Data collector",
"CURATOR": "Data curator",
"CONTRIBUTOR": "Contributor",
"null": "Not specified"
},
"roledesc": {
......
......@@ -24,7 +24,8 @@
"holdingInstitutes": "Holding institutes",
"countryOfInstitutes": "Country of holding institute",
"representedGenera": "Most represented Genera",
"representedSpecies": "Most represented Species"
"representedSpecies": "Most represented Species",
"diversityTrees": "Diversity trees"
},
"browse": {
"title": "Crop list",
......
......@@ -4,9 +4,11 @@ import { bindActionCreators } from 'redux';
import { WithTranslation, withTranslation } from 'react-i18next';
import withStyles from '@material-ui/core/styles/withStyles';
import * as _ from 'lodash';
import axios from 'axios';
// Actions
import { loadCropDetails } from 'crop/actions/public';
import { repositoryDownloadUrl } from 'repository/actions/public';
import { relinkAccessions } from 'crop/actions/admin';
import { applyFiltersAsync as applyFilters, applyOverviewFiltersAsync as applyOverviewFilters } from 'accessions/actions/public';
import { showSnackbar } from 'actions/snackbar';
......@@ -36,7 +38,7 @@ import { IPageRequest } from '@genesys/client/model/Page';
import ErrorMessage from 'ui/common/error/ErrorMessage';
import ImageGalleryView from 'repository/ui/c/ImageGalleryView';
import TreePreviewer from 'crop/ui/c/TreePreviewer';
// import RepositoryFile from 'model/repository/RepositoryFile';
import RepositoryFile from 'model/repository/RepositoryFile';
import { ScrollToTopOnMount } from 'ui/common/page/scrollers';
import { DatasetLink, DiversityTreeLink, SubsetLink } from 'ui/genesys/Links';
import { DescriptorListLink } from 'ui/catalog/Links';
......@@ -65,6 +67,7 @@ interface IDisplayPageProps extends React.ClassAttributes<any>, WithTranslation
relinkAccessions: (shortName: string) => void;
applyOverviewFilters: (filters: string | AccessionFilter, page?: IPageRequest) => void;
showSnackbar: (snack: string) => void;
repositoryDownloadUrl: (file: RepositoryFile) => string;
}
class DisplayPage extends React.Component<IDisplayPageProps, any> {
......@@ -75,12 +78,56 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
},
];
public state: {
treesData: {treeData: any, treeFile: any}[],
} = {
treesData: null,
};
public componentDidMount() {
const { loadCropDetails, shortName, cropDetails } = this.props;
const { loadCropDetails, shortName, cropDetails, repositoryDownloadUrl } = this.props;
if (shortName && (! cropDetails || shortName !== cropDetails.shortName)) {
loadCropDetails(shortName);
this.setState({ treesData: null });
}
// todo: remove when migration to cropDetails.diversityTrees will be finished
if (typeof window !== 'undefined') {
if (cropDetails && cropDetails.files && cropDetails.shortName === shortName && (!cropDetails.diversityTrees || !cropDetails.diversityTrees.length)) {
console.log(`Crop files`, cropDetails.files);
const treeFiles = cropDetails.files && cropDetails.files.filter((file) => {
return file.contentType === 'application/json' && file.originalFilename.match(/tree\.json$/);
});
if (treeFiles && treeFiles.length > 0) {
const treeFilePromises = treeFiles.map((treeFile) => axios.get(repositoryDownloadUrl(treeFile))
.then((response) => ({ treeData: response.data, treeFile }))
.catch((err) => { console.log(`Err`, err)}));
Promise.all(treeFilePromises)
.then((treesData) => this.setState({treesData: treesData.filter((treeData) => !!treeData)}))
.catch((err) => { console.log(`Error getting tree data`, err)});
}
}
}
}
public componentDidUpdate(prevProps: IDisplayPageProps) {
const { cropDetails: currentCrop } = prevProps;
const { cropDetails, repositoryDownloadUrl } = this.props;
const { treesData } = this.state;
if (cropDetails && (! currentCrop || (currentCrop.shortName !== cropDetails.shortName)) && (!cropDetails.diversityTrees || !cropDetails.diversityTrees.length)) {
console.log(`Crop files`, cropDetails.files);
const treeFiles = cropDetails.files && cropDetails.files.filter((file) => {
return file.contentType === 'application/json' && file.originalFilename.match(/tree\.json$/);
});
if (treeFiles && treeFiles.length > 0 && ! treesData) {
const treeFilePromises = treeFiles.map((treeFile) => axios.get(repositoryDownloadUrl(treeFile))
.then((response) => ({ treeData: response.data, treeFile }))
.catch((err) => { console.log(`Err`, err)}));
Promise.all(treeFilePromises)
.then((treesData) => this.setState({treesData: treesData.filter((treeData) => !!treeData)}))
.catch((err) => { console.log(`Error getting tree data`, err)});
}
}
}
private applyCropFilter = () => {
......@@ -124,6 +171,8 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
public render() {
const { cropDetails, error, shortName, classes, t } = this.props;
const { treesData } = this.state;
const crop = cropDetails;
return (
......@@ -207,6 +256,14 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
propertyItemProps={ {classes: {propertiesRowLabel: classes.italicProperties} } }
/>
}
{ treesData && treesData.map((tree) => (tree && tree.treeData.children && tree.treeData.children.length > 0 &&
<TreePreviewer
key={ tree.treeFile.uuid }
source={ tree.treeFile }
treeData={ tree.treeData }
name={ tree.treeFile.subject || tree.treeFile.title || crop.name }
/>
))}
</GridContainer >
}
<PropertiesCard title={ t(`crop.public.p.display.otherNames`) }
......@@ -266,7 +323,7 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
<Grid item lg={ 4 } xs={ 12 } style={ { minHeight: '100%' } }>
<PropertiesCard
style={ {height: '100%'} }
title={ t('DiversityTrees') } // todo: fix translations
title={ t('crop.public.p.display.diversityTrees') }
propertyItemProps={ { keepEmpty: true } }
propertiesList={
cropDetails.diversityTrees
......@@ -298,6 +355,7 @@ const mapDispatchToProps = (dispatch) => bindActionCreators({
relinkAccessions,
applyOverviewFilters,
showSnackbar,
repositoryDownloadUrl,
}, dispatch);
......
......@@ -18,7 +18,7 @@ import {
// Model
import DiversityTree from '@genesys/client/model/DiversityTree';
import DiversityTreeAccessionRef from '@genesys/client/model/DiversityTreeAccessionRef';
import DiversityTreeCreator from '@genesys/client/model/DiversityTreeCreator';
import DiversityTreeCreator, { CreatorRole } from '@genesys/client/model/DiversityTreeCreator';
// Service
import AccessionService from '@genesys/client/service/genesys/AccessionService';
......@@ -26,6 +26,7 @@ import DiversityTreeService from '@genesys/client/service/genesys/DiversityTreeS
// UI
import steps from 'divtree/ui/dashboard/diversity-tree-stepper/steps';
import { clearDiversityTree } from 'divtree/actions/public';
// Wrapped API Calls
const apiAddAccessions = createApiCaller(DiversityTreeService.addAccessions, DASHBOARD_RECEIVE_DIVERSITY_TREE);
......@@ -105,6 +106,7 @@ export const unpublishDiversityTree = (divtree: DiversityTree) => (dispatch) =>
};
export const approveDiversityTree = (divtree: DiversityTree) => (dispatch) => {
dispatch(clearDiversityTree());
return dispatch(apiApproveDiversityTrees([divtree]));
};
......@@ -117,6 +119,7 @@ export const createDiversityTreeCreator = () => (dispatch, getState) => {
const currentDiversityTree = getState().divtree.dashboard.divtree && getState().divtree.dashboard.divtree.data;
const creator = new DiversityTreeCreator();
creator.fullName = '';
creator.role = CreatorRole.CONTRIBUTOR;
return dispatch(apiCreateDiversityTreeCreator(currentDiversityTree.uuid, creator));
};
......
......@@ -11,7 +11,7 @@
"currentVersion": "Current version"
},
"diversityTreeDisplay": {
"divTreeCreators": "Diversity tree creators",
"divTreeContributors": "Diversity tree contributors",
"rematch": "Rematch accessions",
"diversityTreeMetadata": "Diversity tree metadata",
"dataAndResources": "Data and resources",
......@@ -96,7 +96,6 @@
},
"creators": {
"stepName": "Diversity tree creators",
"Role": "Role: ",
"fullName": "Full name",
"fullNamePlaceholder": "Jane A. Doe",
"institutionalAffiliation": "Institutional affiliation",
......@@ -131,10 +130,7 @@
"stats_plural": "Diversity trees",
"creators": {
"role": {
"MANAGER": "Data manager",
"DIGITIZER": "Data digitizer",
"COLLECTOR": "Data collector",
"CURATOR": "Data curator",
"CONTRIBUTOR": "Contributor",
"null": "Not specified"
},
"roledesc": {
......
......@@ -177,8 +177,8 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
public render() {
const {
error, divtree, loading, userRole, t, accessionRefs, rematchDiversityTreeAccessions, publishDiversityTree,
rejectDiversityTree, approveDiversityTree, deleteDiversityTree, editDiversityTree, uuid, classes, currentTab,
error, divtree, loading, userRole, t, accessionRefs, rematchDiversityTreeAccessions, approveDiversityTree,
deleteDiversityTree, editDiversityTree, uuid, classes, currentTab,
} = this.props;
const { treeData, treeDataLoading, accessions, treeError } = this.state;
const isActionsActive: boolean = userRole.findIndex((role) => role === 'ROLE_ADMINISTRATOR') !== -1 || (divtree && divtree.state === PublishState.REVIEWING);
......@@ -191,10 +191,9 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
title={ !loading ? t('divtree.public.p.display.title') : t('common:label.loading', { what: t('divtree.public.p.display.title') }) }
buttons={
<BackButton
defaultTarget="dashboard/divtree" // fixme
defaultTarget="/dashboard/divtree"
defaultBackText={ t('common:action.back') }
preferDefaultTarget
itemState={ divtree && divtree.state }
/>
}
/>
......@@ -223,8 +222,7 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
accessions={ accessionRefs }
loadAccessions={ this.loadMoreAccessions }
rematchDiversityTreeAccessions={ rematchDiversityTreeAccessions }
publishDiversityTree={ publishDiversityTree }
unpublishDiversityTree={ rejectDiversityTree }
unpublishDiversityTree={ editDiversityTree }
editDiversityTree={ editDiversityTree }
approveDiversityTree={ approveDiversityTree }
deleteDiversityTree={ deleteDiversityTree }
......
......@@ -228,14 +228,14 @@ class DetailInfo extends React.Component<IDetailInfoProps, any> {
{ divtree.creators && divtree.creators.length > 0 &&
<div>
<div className="pt-15 pb-15 pl-20 pr-20">
<h4 className="font-bold m-0">{ t('divtree.public.c.diversityTreeDisplay.divTreeCreators') }</h4>
<h4 className="font-bold m-0">{ t('divtree.public.c.diversityTreeDisplay.divTreeContributors') }</h4>
</div>
<Divider/>
<Grid container spacing={ 0 } className="p-20">
<Grid item xs={ 12 }>
<Properties>
{ divtree.creators && divtree.creators.map((creator) => creator && (
<PropertiesItem title={ t(`divtree.common.creators.role.${creator.role}`) } key={ creator.id }>
<PropertiesItem key={ creator.id }>
<span>
<b>{ creator.fullName }</b>
{ creator.institutionalAffiliation && <span> { creator.institutionalAffiliation }</span> }
......
......@@ -23,7 +23,6 @@ import DeleteIcon from '@material-ui/icons/Delete';
import { TextField } from 'ui/common/text-field';
import confirm from '@genesys/client/utilities/confirmAlert';
import DiversityTreeCreatorAutocompleteField from './DiversityTreeCreatorAutocompleteField';
import RadioSelection from 'ui/common/forms/RadioSelection';
interface IDiversityTreeCreatorFormProps extends React.ClassAttributes<any>, WithTranslation, WithStyles {
......@@ -79,19 +78,6 @@ class DiversityTreeCreatorForm extends React.Component<IDiversityTreeCreatorForm
});
};
private renderRoleLabel = (role) => (
<div style={ {paddingTop: '6px', marginBottom: '-6px'} }>
<b style={ {fontSize: '14px'} }>
{ this.props.t(`divtree.common.creators.role.${role}`) }
</b>
<div>
<p style={ {whiteSpace: 'pre-line'} }>
{ this.props.t(`divtree.common.creators.roledesc.${role}`) }
</p>
</div>
</div>
);
private onMouseLeave = (fields, index) => () => {
const { divtree, isInvalidForm } = this.props;
const oldCreator = divtree.creators[index];
......@@ -124,16 +110,6 @@ class DiversityTreeCreatorForm extends React.Component<IDiversityTreeCreatorForm
updateCreator={ this.updateCreatorData(fields, index) }
autocompleteCreators={ autocompleteCreators }
/>
<Field
required
name={ `${creator}.role` }
classes={ classes }
component={ RadioSelection }
options={ Object.keys(CreatorRole) }
formLabel={ t(`divtree.dashboard.p.stepper.creators.Role`) }
renderOptionLabel={ this.renderRoleLabel }
singleColumn
/>
<Field
name={ `${creator}.institutionalAffiliation` }
component={ TextField }
......
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