Commit cb145be4 authored by Maxym Borodenko's avatar Maxym Borodenko Committed by Viacheslav Pavlov
Browse files

Dashboard: Subsets

fixed subset editPage route
parent b46f58d2
......@@ -1559,6 +1559,20 @@
"status": "Status"
}
},
"f": {
"filterTitle": "Filter subsets",
"textSearch": "Text search",
"title": "Title",
"titlePlaceholder": "International",
"description": "Description",
"descriptionPlaceholder": "Subset description",
"institute": "Institute",
"institutePlaceholder": "MEX002",
"crop": "Crop",
"dateCreated": "Date created",
"publisher": "Publisher",
"publisherPlaceholder": "Publisher"
},
"menu": {
"subsets": "Subsets",
"listSubsets": "List subsets",
......
......@@ -9,7 +9,10 @@ import Subset from 'model/subset/Subset';
import SubsetService from 'service/genesys/SubsetService';
import Page from 'model/Page';
import {AccessionRef} from 'model/accession/AccessionRef';
import SubsetFilter from 'model/subset/SubsetFilter';
// actions
import navigateTo from 'actions/navigation';
const receiveSubsets = (paged: FilteredPage<Subset>, error = null) => ({
type: DASHBOARD_RECEIVE_SUBSETS,
......@@ -82,3 +85,23 @@ export const loadMoreAccessions = (uuid: string, paged?: Page<AccessionRef>) =>
dispatch(receiveAccessions(null, error));
});
};
export const applyFilters = (filters: string | SubsetFilter, page?: Page<Subset>) => (dispatch) => {
console.log('Applying new filter', filters, page);
return SubsetService.mySubsets(filters, Page.nextPage(page))
.then((paged) => {
if (paged.number === 0) {
dispatch(receiveSubsets(paged));
} else {
dispatch(appendSubsets(paged));
}
dispatch(updateRoute(paged));
}).catch((error) => {
console.log(`API error`, error);
dispatch(receiveSubsets(null, error));
});
};
const updateRoute = (paged: FilteredPage<Subset>) => (dispatch) => {
dispatch(navigateTo(paged.filterCode ? `/dashboard/subsets/${paged.filterCode}` : '/dashboard/subsets'));
};
......@@ -11,6 +11,7 @@ export const DASHBOARD_RECEIVE_SUBSET = 'subsets/dashboard/RECEIVE_SUBSET';
export const DASHBOARD_REMOVE_SUBSET = 'subsets/dashboard/REMOVE_SUBSET';
export const DASHBOARD_RECEIVE_ACCESSIONS = 'subsets/DASHBOARD_RECEIVE_ACCESSIONS';
export const DASHBOARD_APPEND_ACCESSIONS = 'subsets/DASHBOARD_APPEND_ACCESSIONS';
export const DASHBOARD_FILTER_FORM = 'Form/Subset/DASHBOARD_FILTER_FORM';
export const SUBSET_FILTERFORM = 'Form/Subset/SUBSET_FILTERFORM';
export const SUBSET_FORM = 'Form/Subset/SUBSET_FORM';
......
......@@ -47,7 +47,16 @@ const dashboardRoutes = [
],
},
{
path: '/subsets/:uuid/',
path: '/subsets/:filterCode(v.+)?',
component: SubsetDashboardPage,
auth: [ROLE_USER, ROLE_ADMINISTRATOR],
exact: true,
extraProps: {
title: 'Subsets',
},
},
{
path: '/subsets/:uuid([a-z\\-0-9]+)/',
component: SubsetStepper,
auth: [ROLE_USER, ROLE_ADMINISTRATOR],
extraProps: {
......@@ -57,14 +66,7 @@ const dashboardRoutes = [
...steps,
],
},
{
path: '/subsets',
component: SubsetDashboardPage,
exact: true,
extraProps: {
title: 'My Dashboard',
},
},
];
export {publicRoutes as subsetPublicRoutes, dashboardRoutes as subsetDashboardRoutes};
......@@ -42,6 +42,20 @@
"status": "Status"
}
},
"f": {
"filterTitle": "Filter subsets",
"textSearch": "Text search",
"title": "Title",
"titlePlaceholder": "International",
"description": "Description",
"descriptionPlaceholder": "Subset description",
"institute": "Institute",
"institutePlaceholder": "MEX002",
"crop": "Crop",
"dateCreated": "Date created",
"publisher": "Publisher",
"publisherPlaceholder": "Publisher"
},
"menu": {
"subsets": "Subsets",
"listSubsets": "List subsets",
......
import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { translate } from 'react-i18next';
import { parse } from 'query-string';
// Actions
import { loadMoreSubsets } from 'subsets/actions/dashboard';
import { loadMoreSubsets, applyFilters} from 'subsets/actions/dashboard';
// Models
import FilteredPage from 'model/FilteredPage';
import Subset from 'model/subset/Subset';
import SubsetFilter from 'model/subset/SubsetFilter';
import {SortDirection} from 'model/Page';
// UI
import SubsetFilters from './c/SubsetFilters';
import CreateSubsetButton from './c/CreateSubsetButton';
import SubsetDashboardCard from './c/SubsetDashboardRow';
import MyDataTable from 'ui/common/tables/MyDataTable';
import ContentLayout from 'ui/layout/ContentLayout';
interface IDashboardPageProps extends React.ClassAttributes<any> {
paged: FilteredPage<Subset>;
loadMoreSubsets: (page?: FilteredPage<Subset>) => void;
history: any;
location: any;
login: any;
t: any;
filterCode: string;
applyFilters: any;
}
const sortOptions = {
......@@ -40,7 +47,10 @@ const tableHeaderProps = [
class DashboardPage extends React.Component<IDashboardPageProps> {
protected static needs = [
() => loadMoreSubsets(),
({ search, params: { filterCode } }) => {
const qs = parse(search || '');
return applyFilters(filterCode || '', FilteredPage.fromQueryString(qs));
},
];
constructor(props: IDashboardPageProps, context: any) {
......@@ -48,28 +58,58 @@ class DashboardPage extends React.Component<IDashboardPageProps> {
}
public componentWillMount() {
const {paged, loadMoreSubsets} = this.props;
const {paged, applyFilters, filterCode} = this.props;
if (filterCode) {
if (!paged || paged.filterCode !== filterCode) {
applyFilters(filterCode);
}
} else {
applyFilters('');
}
}
if (!paged) {
loadMoreSubsets();
public componentWillReceiveProps(nextProps) {
const {applyFilters, filterCode} = this.props;
if (filterCode && (!nextProps.filterCode)) {
applyFilters('');
}
}
protected myApplyFilters = (filters: SubsetFilter) => {
const { paged, applyFilters } = this.props;
if (paged) {
applyFilters(filters, { page: 0, direction: paged.sort[0].direction, properties: [ paged.sort[0].property ] });
} else {
applyFilters(filters);
}
}
protected onSortChange = (sortBy: string, dir: SortDirection) => {
const { paged, applyFilters, filterCode } = this.props;
applyFilters(filterCode || '', FilteredPage.reSort(paged, sortBy, dir));
}
public render() {
const {paged, login: { authorities: userRoles }, loadMoreSubsets} = this.props;
const {paged, login: { authorities: userRoles }, loadMoreSubsets, t} = this.props;
const renderSubset = (s: Subset, index: number) => {
return <SubsetDashboardCard key={ s.uuid } subset={ s } index={ index } isAdmin={ userRoles.findIndex((role) => role === 'ROLE_ADMINISTRATOR') !== -1 }/>;
};
return (
<MyDataTable
loadMoreData={ loadMoreSubsets }
paged={ paged }
renderTableRow={ renderSubset }
sortOptions={ sortOptions }
headerProps={ tableHeaderProps }
/>
<ContentLayout left={
<SubsetFilters initialValues={ paged && paged.filter || {} } onSubmit={ this.myApplyFilters } t={ t }/>
} customHeaderHeight>
<MyDataTable
loadMoreData={ loadMoreSubsets }
paged={ paged }
renderTableRow={ renderSubset }
sortOptions={ sortOptions }
headerProps={ tableHeaderProps }
onSortChange={ this.onSortChange }
/>
<CreateSubsetButton />
</ContentLayout>
);
}
}
......@@ -77,11 +117,12 @@ class DashboardPage extends React.Component<IDashboardPageProps> {
const mapStateToProps = (state, ownProps) => ({
paged: state.subsets.dashboard.paged || undefined,
login: state.login,
filterCode: ownProps.match.params.filterCode,
});
const mapDispatchToProps = (dispatch) => bindActionCreators({
loadMoreSubsets,
applyFilters,
}, dispatch);
export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage);
export default connect(mapStateToProps, mapDispatchToProps)((translate()(DashboardPage)));
import * as React from 'react';
import { translate } from 'react-i18next';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
// UI
import { withStyles } from '@material-ui/core/styles';
import SpeedDial from '@material-ui/lab/SpeedDial';
import SpeedDialIcon from '@material-ui/lab/SpeedDialIcon';
import AddIcon from '@material-ui/icons/Add';
// actions
import navigateTo from 'actions/navigation';
const styles = (theme) => ({
speedDial: {
position: 'fixed' as 'fixed',
bottom: theme.spacing.unit * 2,
right: theme.spacing.unit * 3,
},
tooltipText: {
fontSize: '18px',
},
});
interface ICreateSubsetButtonProps extends React.ClassAttributes<any> {
classes: any;
t: any;
navigateTo: any;
}
class CreateSubsetButton extends React.Component<ICreateSubsetButtonProps, any> {
public state = {
open: false,
};
private handleOpen = () => {
this.setState({open: true});
}
private handleClose = () => {
this.setState({open: false});
}
public render() {
const { classes, navigateTo, t } = this.props;
const { open } = this.state;
const createSubset = () => navigateTo(`/dashboard/subsets/edit`);
return (
<SpeedDial
ariaLabel={ `${ t('common:action.create') } ${ (t('subsets.common.modelName')).toLowerCase() }` }
className={ classes.speedDial }
icon={ <SpeedDialIcon openIcon={ <AddIcon/> }/> }
onBlur={ this.handleClose }
onClick={ createSubset }
onMouseEnter={ this.handleOpen }
onMouseLeave={ this.handleClose }
open={ open }
/>
);
}
}
const mapDispatchToProps = (dispatch) => bindActionCreators({
navigateTo,
}, dispatch);
export default translate()(connect(null, mapDispatchToProps)(withStyles(styles)(CreateSubsetButton)));
import * as React from 'react';
import { reduxForm } from 'redux-form';
import {DASHBOARD_FILTER_FORM} from 'subsets/constants';
import FiltersBlock from 'ui/common/filter/FiltersBlock';
import CollapsibleComponentSearch from 'ui/common/filter/CollapsibleComponentSearch';
import CropFilter from 'crop/ui/c/CropFilter';
import StringFilter from 'ui/common/filter/StringFilter';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import StatusFilter from 'ui/catalog/dashboard/c/StatusFilter';
const SubsetFilters = ({handleSubmit, initialValues, initialize, t, ...other}) => {
return (
<FiltersBlock title={ t('subsets.dashboard.f.filterTitle') } handleSubmit={ handleSubmit } initialize={ initialize } { ...other }>
<CollapsibleComponentSearch title={ t('common:label.status') }>
<StatusFilter/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('subsets.dashboard.f.textSearch') }>
<StringFilter name="title" searchType="contains" label={ t('subsets.dashboard.f.title') } placeholder={ t('subsets.dashboard.f.titlePlaceholder') }/>
<StringFilter name="description" searchType="contains" label={ t('subsets.dashboard.f.description') } placeholder={ t('subsets.dashboard.f.descriptionPlaceholder') }/>
<StringArrFilter name="institutes" label={ t('subsets.dashboard.f.institute') } placeholder={ t('subsets.dashboard.f.institutePlaceholder') }/>
<StringFilter name="dateCreated" searchType="contains" label={ t('subsets.dashboard.f.dateCreated') }/>
<StringArrFilter name="publisher" label={ t('subsets.dashboard.f.publisher') } placeholder={ t('subsets.dashboard.f.publisherPlaceholder') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('subsets.dashboard.f.crop') }>
<CropFilter />
</CollapsibleComponentSearch>
</FiltersBlock>
);
};
export default reduxForm({
enableReinitialize: true,
form: DASHBOARD_FILTER_FORM,
})(SubsetFilters);
......@@ -40,16 +40,6 @@ const DASHBOARD_MENUS = [
{
to: '/dashboard/subsets',
label: 'subsets.dashboard.menu.subsets',
subMenus: [
{
to: '/dashboard/subsets',
label: 'subsets.dashboard.menu.listSubsets',
},
{
to: '/dashboard/subsets/edit',
label: 'subsets.dashboard.menu.createSubsets',
},
],
},
];
......
......@@ -27,7 +27,6 @@ class BrowsePage<T> extends React.Component<IBrowsePageProps<T> & any, any> {
if (! paged) {
applyFilters(filterCode || '');
} else if (filterCode !== paged.filterCode) {
console.log(filterCode, `==============================!======================`, paged.filterCode);
updateRoute(paged);
}
}
......
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