Commit 88b79d8a authored by Oleksii Savran's avatar Oleksii Savran Committed by Matija Obreza

Added loading accessions functionality, fixes

parent 565e4340
...@@ -2,13 +2,21 @@ import * as React from 'react'; ...@@ -2,13 +2,21 @@ import * as React from 'react';
import { withStyles, WithStyles, createStyles } from '@material-ui/core/styles'; import { withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
import { WithTranslation, withTranslation } from 'react-i18next'; import { WithTranslation, withTranslation } from 'react-i18next';
// Model
import Accession from 'model/accession/Accession';
import FilteredPage from 'model/FilteredPage';
import Page from 'model/Page';
import ConfiguredTree from 'crop/ui/c/ConfiguredTree'; import ConfiguredTree from 'crop/ui/c/ConfiguredTree';
// import Button from '@material-ui/core/Button/Button'; import Button from '@material-ui/core/Button';
import * as classnames from 'classnames'; import * as classnames from 'classnames';
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import Card, { CardContent, CardHeader } from 'ui/common/Card'; import Card, { CardContent, CardHeader } from 'ui/common/Card';
import IconButton from '@material-ui/core/IconButton/IconButton'; import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close'; import CloseIcon from '@material-ui/icons/Close';
import PagedLoader from 'ui/common/PagedLoader';
import Loading from 'ui/common/Loading';
import AccessionCard from 'accessions/ui/c/AccessionCard';
const styles = (theme) => createStyles({ const styles = (theme) => createStyles({
...@@ -30,9 +38,11 @@ const styles = (theme) => createStyles({ ...@@ -30,9 +38,11 @@ const styles = (theme) => createStyles({
position: 'absolute', position: 'absolute',
backgroundColor: 'white', backgroundColor: 'white',
border: 'solid 2px grey', border: 'solid 2px grey',
visibility: 'hidden', // visibility: 'hidden',
display: 'flex', display: 'none',
// display: 'flex',
flexDirection: 'column', flexDirection: 'column',
padding: '5px',
}, },
popupData: { popupData: {
fontSize: '1rem', fontSize: '1rem',
...@@ -41,14 +51,13 @@ const styles = (theme) => createStyles({ ...@@ -41,14 +51,13 @@ const styles = (theme) => createStyles({
textAlign: 'center', textAlign: 'center',
}, },
visible: { visible: {
visibility: 'visible', display: 'flex',
// visibility: 'visible',
}, },
node: { node: {
position: 'absolute', position: 'absolute',
// width: 'calc(90% - 20px)',
width: 'max-content', width: 'max-content',
textAlign: 'right', textAlign: 'right',
// left: 'calc(-90% + 40px)',
right: '-10px', right: '-10px',
}, },
leafNode: { leafNode: {
...@@ -58,14 +67,14 @@ const styles = (theme) => createStyles({ ...@@ -58,14 +67,14 @@ const styles = (theme) => createStyles({
display: 'inline-block', display: 'inline-block',
verticalAlign: 'top', verticalAlign: 'top',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
lineHeight: '1.38',
}, },
accessionList: { accessionList: {
width: '400px', width: '400px',
position: 'absolute', position: 'absolute',
right: 0, right: 0,
[theme.breakpoints.down('md')]: { height: '100%',
width: '300px', overflow: 'scroll',
},
[theme.breakpoints.down('xs')]: { [theme.breakpoints.down('xs')]: {
width: '100vw', width: '100vw',
}, },
...@@ -75,6 +84,11 @@ const styles = (theme) => createStyles({ ...@@ -75,6 +84,11 @@ const styles = (theme) => createStyles({
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
}, },
stickyHeader: {
position: 'sticky',
top: 0,
backgroundColor: 'white',
},
}); });
class NodeLabel extends React.PureComponent<any, any> { class NodeLabel extends React.PureComponent<any, any> {
...@@ -84,17 +98,19 @@ class NodeLabel extends React.PureComponent<any, any> { ...@@ -84,17 +98,19 @@ class NodeLabel extends React.PureComponent<any, any> {
}; };
private onClick = (e) => { private onClick = (e) => {
const { nodeData, clickHandler } = this.props; const { nodeData, clickHandler /* , expandCallback */ } = this.props;
if (this.state.count === 1) { if (this.state.count === 1) {
console.log('expand!'); console.log('expand!');
// pass click event to the node for expanding
clearTimeout(this.timeout); clearTimeout(this.timeout);
// expandCallback();
this.setState({ count: 0 }); this.setState({ count: 0 });
return; return;
} }
const x = e.clientX; const x = e.clientX;
const y = e.clientY; const y = e.clientY;
e.stopPropagation(); e.stopPropagation(); // prevent expanding
this.setState({ count: 1 }); this.setState({ count: 1 });
this.timeout = setTimeout(() => { this.timeout = setTimeout(() => {
...@@ -117,12 +133,15 @@ class NodeLabel extends React.PureComponent<any, any> { ...@@ -117,12 +133,15 @@ class NodeLabel extends React.PureComponent<any, any> {
interface ITreeExplorerProps extends React.ClassAttributes<any>, WithTranslation, WithStyles { interface ITreeExplorerProps extends React.ClassAttributes<any>, WithTranslation, WithStyles {
treeData: any; treeData: any;
loadNodeAccessions: (nodeKey: string) => void;
loadMoreNodeAccessions: (paged: Page<Accession>) => void;
accessions: FilteredPage<Accession>;
} }
class TreeExplorer extends React.Component<ITreeExplorerProps, any> { class TreeExplorer extends React.Component<ITreeExplorerProps, any> {
private readonly treeWrapperRef: React.RefObject<HTMLDivElement>; private readonly treeWrapperRef: React.RefObject<HTMLDivElement>;
private readonly popupRef: React.RefObject<HTMLDivElement>; private readonly popupRef: React.RefObject<HTMLDivElement>;
private LABEL_HEIGHT = 16; private LABEL_HEIGHT = 20;
public constructor(props: ITreeExplorerProps, context: any) { public constructor(props: ITreeExplorerProps, context: any) {
super(props, context); super(props, context);
...@@ -141,12 +160,14 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> { ...@@ -141,12 +160,14 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> {
public componentDidMount(): void { public componentDidMount(): void {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
window.addEventListener('wheel', this.throttledHide); window.addEventListener('wheel', this.throttledHide);
document.documentElement.classList.add('modal-open');
} }
} }
public componentWillUnmount(): void { public componentWillUnmount(): void {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
window.removeEventListener('wheel', this.throttledHide); window.removeEventListener('wheel', this.throttledHide);
document.documentElement.classList.remove('modal-open');
} }
} }
...@@ -172,36 +193,54 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> { ...@@ -172,36 +193,54 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> {
private throttledHide = throttle(this.hidePopup, 1000); private throttledHide = throttle(this.hidePopup, 1000);
private showList = (e) => { private showList = (e) => {
const { loadNodeAccessions } = this.props;
console.log('show list click!'); console.log('show list click!');
// e.stopPropagation(); e.stopPropagation();
this.setState({ accessionListIsOpen: true }); this.setState({ accessionListIsOpen: true });
loadNodeAccessions(this.state.popupData.nodeKey);
}; };
private closeAccessionList = () => { private closeAccessionList = () => {
this.setState({ accessionListIsOpen: false }) this.setState({ accessionListIsOpen: false })
}; };
private renderAccession = (s: Accession, index: number) => {
return <div className="mt-5 mb-5"><AccessionCard key={ s.uuid } index={ index } accession={ s } editMode={ true }/></div>;
};
private handleWrapperClick = (e) => {
console.log('wrapper click!!', e.target);
if (e.target.tagName !== 'H6' && this.state.popupData) {
setTimeout(this.hidePopup, 1); // prevents rerender on tree's drag start}
}
};
// private onNodeExpand = () => {
// setTimeout(this.hidePopup, 1);
// // this.hidePopup();
// };
private onButtonMouseDown = (e) => e.stopPropagation();
public render() { public render() {
const { treeData, classes } = this.props; const { treeData, classes, accessions, loadMoreNodeAccessions, t } = this.props;
const { x, y, popupData, accessionListIsOpen } = this.state; const { x, y, popupData, accessionListIsOpen } = this.state;
// todo: translations
return ( return (
<div className={ classes.treeWrapper } ref={ this.treeWrapperRef }> <div className={ classes.treeWrapper } ref={ this.treeWrapperRef } onMouseDown={ this.handleWrapperClick }>
<ConfiguredTree <ConfiguredTree
treeData={ [treeData] } treeData={ [treeData] }
initialZoom={ 0.25 } initialZoom={ 0.25 }
zoomable zoomable
nodeLabelComponent={{ nodeLabelComponent={ {
render: <NodeLabel clickHandler={ this.handleClick } classes={ classes }/>, render: <NodeLabel clickHandler={ this.handleClick } classes={ classes } /* expandCallback={ this.onNodeExpand } */ />,
foreignObjectWrapper: { foreignObjectWrapper: {
y: -(this.LABEL_HEIGHT / 2), y: -this.LABEL_HEIGHT / 2,
x: -10, x: -10,
height: this.LABEL_HEIGHT, height: this.LABEL_HEIGHT,
width: 10, width: 10,
}, },
}} } }
// onClickHandler={ this.onNodeClick }
/> />
<div <div
className={ classnames({ [classes.visible]: !!popupData, [classes.popup]: true }) } className={ classnames({ [classes.visible]: !!popupData, [classes.popup]: true }) }
...@@ -212,16 +251,20 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> { ...@@ -212,16 +251,20 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> {
{ popupData && { popupData &&
<> <>
<div className={ classes.popupTitle }>{ popupData.name }</div> <div className={ classes.popupTitle }>{ popupData.name }</div>
<div className="mb-1rem">Node key: { popupData.nodeKey }</div> <div className="mb-1rem">
{ t('divtree.public.c.treeExplorer.nodeKey', { what: popupData.nodeKey }) }
</div>
</> </>
} }
</div> </div>
{ /* fixme: Button causes fontSize issues in header */ } <Button onClick={ this.showList } onMouseDown={ this.onButtonMouseDown }>
<div onClick={ this.showList }>Accessions List</div> { t('divtree.public.c.treeExplorer.accessionList') }
</Button>
</div> </div>
{ accessionListIsOpen && { accessionListIsOpen &&
<Card className={ classes.accessionList }> <Card className={ classes.accessionList }>
<CardHeader <CardHeader
className={ classes.stickyHeader }
title={ title={
<div className={ classes.cardTitle }> <div className={ classes.cardTitle }>
<div> <div>
...@@ -236,7 +279,17 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> { ...@@ -236,7 +279,17 @@ class TreeExplorer extends React.Component<ITreeExplorerProps, any> {
} }
/> />
<CardContent> <CardContent>
TEST { accessions && accessions.content && accessions.content.length > 0 &&
<PagedLoader
paged={ accessions }
itemRenderer={ this.renderAccession }
loadMore={ loadMoreNodeAccessions }
/>
}
{ accessions && accessions.content && accessions.content.length === 0 &&
<div>{ t('divtree.public.c.treeExplorer.noAccessions') }</div>
}
{ !accessions && <Loading/> }
</CardContent> </CardContent>
</Card> </Card>
} }
......
...@@ -46,6 +46,7 @@ class AccessionFilter { ...@@ -46,6 +46,7 @@ class AccessionFilter {
public subsets?: string[]; public subsets?: string[];
public datasets?: string[]; public datasets?: string[];
public networks?: string[]; public networks?: string[];
public nodeKey?: string;
public NOT?: AccessionFilter; public NOT?: AccessionFilter;
public NULL?: string[]; public NULL?: string[];
......
...@@ -1788,7 +1788,14 @@ ...@@ -1788,7 +1788,14 @@
"map": "Accession map", "map": "Accession map",
"mapDescription": "Explore diversity tree accessions on the map", "mapDescription": "Explore diversity tree accessions on the map",
"browse": "Filter accessions", "browse": "Filter accessions",
"browseDescription": "Apply custom filters to accessions in this diversity tree" "browseDescription": "Apply custom filters to accessions in this diversity tree",
"view": "View",
"info": "Info"
},
"treeExplorer": {
"nodeKey": "Node key: {{what}}",
"accessionList": "Accession list",
"noAccessions": "No accessions"
} }
}, },
"f": { "f": {
......
...@@ -6,7 +6,6 @@ interface IConfiguredTreeProps extends React.ClassAttributes<any> { ...@@ -6,7 +6,6 @@ interface IConfiguredTreeProps extends React.ClassAttributes<any> {
treeData: any[]; treeData: any[];
initialZoom: number; initialZoom: number;
zoomable?: boolean; zoomable?: boolean;
onClickHandler?: any;
nodeLabelComponent?: { render: React.ReactNode, foreignObjectWrapper: Record<string, number | string> }; nodeLabelComponent?: { render: React.ReactNode, foreignObjectWrapper: Record<string, number | string> };
} }
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
// Actions // Actions
import navigateTo from 'actions/navigation'; import navigateTo from 'actions/navigation';
import {filterCodeToUrl} from 'actions/filterCode'; import { filterCodeToUrl } from 'actions/filterCode';
// import { showSnackbar } from 'actions/snackbar'; // import { showSnackbar } from 'actions/snackbar';
import {createApiCaller} from 'actions/ApiCall'; import { createApiCaller , createPureApiCaller } from 'actions/ApiCall';
// Constants // Constants
import { import {
...@@ -24,6 +24,8 @@ import OpResponse from '@genesys/client/model/OpResponse'; ...@@ -24,6 +24,8 @@ import OpResponse from '@genesys/client/model/OpResponse';
import { apiDeleteDiversityTrees, apiRejectDiversityTrees } from 'divtree/actions/editor'; import { apiDeleteDiversityTrees, apiRejectDiversityTrees } from 'divtree/actions/editor';
import DiversityTree from '@genesys/client/model/DiversityTree'; import DiversityTree from '@genesys/client/model/DiversityTree';
import AccessionService from '../../service/genesys/AccessionService';
import Accession from '../../model/accession/Accession';
// Wrapped API Calls // Wrapped API Calls
const apiListDiversityTreeAccessions = createApiCaller(DiversityTreeService.listAccessions, APPEND_DIVERSITY_TREE_ACCESSIONS); const apiListDiversityTreeAccessions = createApiCaller(DiversityTreeService.listAccessions, APPEND_DIVERSITY_TREE_ACCESSIONS);
const apiLoadDiversityTree = createApiCaller(DiversityTreeService.get, RECEIVE_DIVERSITY_TREE); const apiLoadDiversityTree = createApiCaller(DiversityTreeService.get, RECEIVE_DIVERSITY_TREE);
...@@ -32,6 +34,8 @@ const apiRematchAccessions = createApiCaller(DiversityTreeService.rematchAccessi ...@@ -32,6 +34,8 @@ const apiRematchAccessions = createApiCaller(DiversityTreeService.rematchAccessi
const apiRejectDiversityTree = createApiCaller(DiversityTreeService.reject, RECEIVE_DIVERSITY_TREE); const apiRejectDiversityTree = createApiCaller(DiversityTreeService.reject, RECEIVE_DIVERSITY_TREE);
const apiApproveDiversityTree = createApiCaller(DiversityTreeService.approve, RECEIVE_DIVERSITY_TREE); const apiApproveDiversityTree = createApiCaller(DiversityTreeService.approve, RECEIVE_DIVERSITY_TREE);
const apiLoadNodeAccesisons = createPureApiCaller(AccessionService.list);
export const loadMoreAccessions = (uuid: string, paged?: Page<AccessionRef>) => (dispatch, getState) => { export const loadMoreAccessions = (uuid: string, paged?: Page<AccessionRef>) => (dispatch, getState) => {
return dispatch(apiListDiversityTreeAccessions(uuid, Page.nextPage(paged))); return dispatch(apiListDiversityTreeAccessions(uuid, Page.nextPage(paged)));
}; };
...@@ -90,4 +94,12 @@ export const deleteDiversityTree = (divtree: DiversityTree) => (dispatch) => { ...@@ -90,4 +94,12 @@ export const deleteDiversityTree = (divtree: DiversityTree) => (dispatch) => {
}); });
}; };
export const loadNodeAccessions = (uuid: string, nodeKey: string) => (dispatch) => {
const filter = { diversityTrees: [uuid], nodeKey };
return dispatch(apiLoadNodeAccesisons(filter, { page: 0 }));
};
export const loadMoreNodeAccessions = (paged: FilteredPage<Accession>) => (dispatch) => {
return dispatch(apiLoadNodeAccesisons(paged.filterCode, Page.nextPage(paged)));
};
...@@ -24,7 +24,14 @@ ...@@ -24,7 +24,14 @@
"map": "Accession map", "map": "Accession map",
"mapDescription": "Explore diversity tree accessions on the map", "mapDescription": "Explore diversity tree accessions on the map",
"browse": "Filter accessions", "browse": "Filter accessions",
"browseDescription": "Apply custom filters to accessions in this diversity tree" "browseDescription": "Apply custom filters to accessions in this diversity tree",
"view": "View",
"info": "Info"
},
"treeExplorer": {
"nodeKey": "Node key: {{what}}",
"accessionList": "Accession list",
"noAccessions": "No accessions"
} }
}, },
"f": { "f": {
......
...@@ -13,11 +13,17 @@ import { ...@@ -13,11 +13,17 @@ import {
approveDiversityTree, approveDiversityTree,
deleteDiversityTree, deleteDiversityTree,
editDiversityTree, editDiversityTree,
loadNodeAccessions,
loadMoreNodeAccessions,
} from 'divtree/actions/public'; } from 'divtree/actions/public';
import navigateTo from 'actions/navigation'; import navigateTo from 'actions/navigation';
import { repositoryDownloadUrl } from 'repository/actions/public'; import { repositoryDownloadUrl } from 'repository/actions/public';
// import { addSubsetAccessionsToMyList } from 'list/actions/public'; // import { addSubsetAccessionsToMyList } from 'list/actions/public';
// Models // Models
import FilteredPage from 'model/FilteredPage';
import Accession from 'model/accession/Accession';
import RepositoryFile from 'model/repository/RepositoryFile';
import Page from '@genesys/client/model/Page';
import DiversityTree from '@genesys/client/model/DiversityTree'; import DiversityTree from '@genesys/client/model/DiversityTree';
import { PublishState } from '@genesys/client/model/common.model'; import { PublishState } from '@genesys/client/model/common.model';
import DiversityTreeAccessionRef from '@genesys/client/model/DiversityTreeAccessionRef'; import DiversityTreeAccessionRef from '@genesys/client/model/DiversityTreeAccessionRef';
...@@ -26,13 +32,11 @@ import PageLayout, { PageContents } from 'ui/layout/PageLayout'; ...@@ -26,13 +32,11 @@ import PageLayout, { PageContents } from 'ui/layout/PageLayout';
import Loading from 'ui/common/Loading'; import Loading from 'ui/common/Loading';
import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton'; import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
import PageTitle from 'ui/common/PageTitle'; import PageTitle from 'ui/common/PageTitle';
import Page from '@genesys/client/model/Page';
import ErrorMessage from 'ui/common/error/ErrorMessage'; import ErrorMessage from 'ui/common/error/ErrorMessage';
import { ScrollToTopOnMount } from 'ui/common/page/scrollers'; import { ScrollToTopOnMount } from 'ui/common/page/scrollers';
import BackButton from 'ui/common/buttons/BackButton'; import BackButton from 'ui/common/buttons/BackButton';
import DiversityTreeDisplay from './c/DiversityTreeDisplay'; import DiversityTreeDisplay from './c/DiversityTreeDisplay';
import Tabs, { Tab } from 'ui/common/Tabs'; import Tabs, { Tab } from 'ui/common/Tabs';
import RepositoryFile from 'model/repository/RepositoryFile';
import TreeExplorer from 'divtree/ui/c/TreeExplorer'; import TreeExplorer from 'divtree/ui/c/TreeExplorer';
const styles = () => createStyles({ const styles = () => createStyles({
...@@ -71,6 +75,8 @@ interface IDisplayPageProps extends React.ClassAttributes<any>, WithTranslation, ...@@ -71,6 +75,8 @@ interface IDisplayPageProps extends React.ClassAttributes<any>, WithTranslation,
accessionRefs: Page<DiversityTreeAccessionRef>; accessionRefs: Page<DiversityTreeAccessionRef>;
currentTab?: string; currentTab?: string;
repositoryDownloadUrl: (file: RepositoryFile) => string; repositoryDownloadUrl: (file: RepositoryFile) => string;
loadNodeAccessions: (uuid: string, nodeKey: string) => Promise<FilteredPage<Accession>>;
loadMoreNodeAccessions: (paged: Page<Accession>) => Promise<FilteredPage<Accession>>;
} }
class DisplayPage extends React.Component<IDisplayPageProps, any> { class DisplayPage extends React.Component<IDisplayPageProps, any> {
...@@ -91,6 +97,8 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> { ...@@ -91,6 +97,8 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
public state = { public state = {
treeData: null, treeData: null,
treeDataLoading: false, treeDataLoading: false,
treeError: null,
accessions: null,
}; };
public componentDidMount() { public componentDidMount() {
...@@ -102,7 +110,6 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> { ...@@ -102,7 +110,6 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
if (divtree && divtree.treeFile && divtree.uuid === uuid) { if (divtree && divtree.treeFile && divtree.uuid === uuid) {
console.log('DivTree file', divtree.treeFile);
// const treeFiles = cropDetails.files && cropDetails.files.filter((file) => { // const treeFiles = cropDetails.files && cropDetails.files.filter((file) => {
// return file.contentType === 'application/json' && file.originalFilename.match(/tree\.json$/); // return file.contentType === 'application/json' && file.originalFilename.match(/tree\.json$/);
// }); // });
...@@ -126,34 +133,54 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> { ...@@ -126,34 +133,54 @@ class DisplayPage extends React.Component<IDisplayPageProps, any> {
private loadTreeFile = (treeFile: RepositoryFile) => { private loadTreeFile = (treeFile: RepositoryFile) => {
const { repositoryDownloadUrl } = this.props; const { repositoryDownloadUrl } = this.props;
console.log('load divtree', treeFile);
this.setState({ treeDataLoading: true }); this.setState({ treeDataLoading: true, treeError: null });
axios axios
.get(repositoryDownloadUrl(treeFile)) .get(repositoryDownloadUrl(treeFile))
.then((response) => { .then((response) => {
console.log(`Tree data`, treeFile, response.data);
if (typeof response.data === 'object') { if (typeof response.data === 'object') {
this.setState({ treeData: response.data, treeDataLoading: false }); this.setState({ treeData: response.data, treeDataLoading: false });
} }
}) })
.catch((err) => { .catch((e) => {
console.log(`Error getting tree data`, err); console.log(`Error getting tree data`, e);
this.setState({ treeDataLoading: false }); this.setState({ treeDataLoading: false, treeError: e });
}); });
}; };
private loadNodeAccessions = (nodeKey: string) => {
const { loadNodeAccessions, divtree } = this.props;
this.setState({ accessions: null });
loadNodeAccessions(divtree.uuid, nodeKey)
.then((data) => {
this.setState({ accessions: data });
})
.catch((e) => console.log('Loading accessions error: ', e));
};
private loadMoreNodeAccessions = (paged: Page<Accession>) => {
const { loadMoreNodeAccessions } = this.props;
loadMoreNodeAccessions(paged)
.then((data) => {
this.setState({ accessions: Page.merge(this.state.accessions, data) });
})
.catch((e) => console.log('Loading accessions error: ', e));