Commit bf01348d authored by Matija Obreza's avatar Matija Obreza
Browse files

PagedLoader with `loadMore(paged)` method, not `loadXxxxPage`

- all modules require `loadMore(paged: FilteredPage<>)` action
- onPaginationChange obsolete, using `loadMoreData(FilteredPage.resort(...))` - loads 1st page
parent 5afc0c23
......@@ -8,10 +8,11 @@ import AccessionFilter from 'model/accession/AccessionFilter';
import AccessionDetails from 'model/accession/AccessionDetails';
import AccessionMapInfo from 'model/accession/AccessionMapInfo';
import {RECEIVE_ACCESSIONS, RECEIVE_ACCESSION, RECEIVE_ACCESSION_OVERVIEW, APPEND_ACCESSIONS, RECEIVE_ACCESSION_MAPINFO} from 'accessions/constants';
import { RECEIVE_ACCESSIONS, RECEIVE_ACCESSION, RECEIVE_ACCESSION_OVERVIEW, APPEND_ACCESSIONS, RECEIVE_ACCESSION_MAPINFO } from 'accessions/constants';
import AccessionService from 'service/genesys/AccessionService';
import { AccessionRef } from 'model/accession/AccessionRef';
import { showSnackbar } from 'actions/snackbar';
import Page from 'model/Page';
const receiveAccessions = (paged: FilteredPage<Accession>, error = null) => ({
type: RECEIVE_ACCESSIONS,
......@@ -42,11 +43,6 @@ export const toUUIDPromise = (identifiers: AccessionRef[]) => (dispatch, getStat
return AccessionService.toUUID(identifiers);
};
export const listAccessionsPromise = (filter: string | AccessionFilter, page: IPageRequest) => (dispatch, getState): Promise<FilteredPage<Accession>> => {
return AccessionService.list(filter, page);
};
export const updateRoute = (paged: FilteredPage<Accession>, path: string = '/a') => (dispatch) => {
const qs = {
s: paged.sort[0].property === Accession.DEFAULT_SORT.property ? undefined : paged.sort[0].property,
......@@ -76,6 +72,22 @@ export const applyFilters = (filters: string | AccessionFilter, page: IPageReque
});
};
export const loadMoreAccessions = (paged?: FilteredPage<Accession>) => (dispatch) => {
console.log('Load more accessions', paged);
return AccessionService.list(paged ? paged.filterCode : '', Page.nextPage(paged))
.then((paged) => {
if (paged.number === 0) {
dispatch(receiveAccessions(paged));
} else {
dispatch(appendAccessions(paged));
}
dispatch(updateRoute(paged));
}).catch((error) => {
console.log(`API error`, error);
dispatch(receiveAccessions(null, error));
});
};
export const applyOverviewFilters = (filters: string | AccessionFilter, page: IPageRequest = { page: 0 }) => (dispatch) => {
console.log('Applying new filter', filters);
return AccessionService.listOverview(filters)
......@@ -113,35 +125,36 @@ export const loadAccessionsMapInfo = (filters: string | AccessionFilter) => (dis
});
};
export const loadAccessionsPage = (page: IPageRequest) => (dispatch, getState) => {
const filterCode = getState().accessions.public.paged.filterCode;
return AccessionService.list(filterCode, page)
.then((paged) => {
if (paged.number === 0) {
dispatch(receiveAccessions(paged));
} else {
dispatch(appendAccessions(paged));
}
dispatch(updateRoute(paged));
}).catch((error) => {
console.log(`API error`, error);
dispatch(receiveAccessions(null, error));
});
};
// Load accession page without redirect
export const loadAccessionsPageAction = (page: IPageRequest, filterCode: string | AccessionFilter) => (dispatch, getState) => {
return AccessionService.list(filterCode, page)
.then((paged) => {
if (paged.number === 0) {
dispatch(receiveAccessions(paged));
} else {
dispatch(appendAccessions(paged));
}
}).catch((error) => {
console.log(`API error`, error);
dispatch(receiveAccessions(null, error.response));
});
};
// export const loadAccessionsPage = (page: IPageRequest) => (dispatch, getState) => {
// const filterCode = getState().accessions.public.paged.filterCode;
// return AccessionService.list(filterCode, page)
// .then((paged) => {
// if (paged.number === 0) {
// dispatch(receiveAccessions(paged));
// } else {
// dispatch(appendAccessions(paged));
// }
// dispatch(updateRoute(paged));
// }).catch((error) => {
// console.log(`API error`, error);
// dispatch(receiveAccessions(null, error));
// });
// };
// // Load accession page without redirect
// export const loadAccessionsPageAction = (page: IPageRequest, filterCode: string | AccessionFilter) => (dispatch, getState) => {
// return AccessionService.list(filterCode, page)
// .then((paged) => {
// if (paged.number === 0) {
// dispatch(receiveAccessions(paged));
// } else {
// dispatch(appendAccessions(paged));
// }
// }).catch((error) => {
// console.log(`API error`, error);
// dispatch(receiveAccessions(null, error.response));
// });
// };
export const loadAccession = ({ uuid, doi }: { uuid?: string, doi?: string }) => (dispatch) => {
const loader = doi ? AccessionService.getDetailsByDoi : AccessionService.getDetailsByUuid;
......
......@@ -5,7 +5,7 @@ import {bindActionCreators} from 'redux';
import { parse } from 'query-string';
// Actions
import { applyFilters, loadAccessionsPage, updateRoute } from 'accessions/actions/public';
import { applyFilters, loadMoreAccessions, updateRoute } from 'accessions/actions/public';
// Models
import Accession from 'model/accession/Accession';
......@@ -41,7 +41,7 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
}
public render() {
const { paged, filterCode, currentTab, t} = this.props;
const { paged, loadMoreData, filterCode, currentTab, t} = this.props;
const renderAccession = (s: Accession, index: number) => {
return <AccessionCard key={ s.uuid } index={ index } accession={ s } />;
......@@ -54,7 +54,7 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
<ContentHeader title={ t('accessions.public.p.browse.title') } subTitle={ t('accessions.public.p.browse.subTitle') } />
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
onSortChange={ this.onSortChange }
displayName="accessions.common.modelName"
sortOptions={ Accession.SORT_OPTIONS }
infinite
......@@ -84,7 +84,7 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
{ ! paged ? <Loading /> :
<PagedLoader
paged={ paged }
loadPage={ this.loadNextPage }
loadMore={ loadMoreData }
roughItemHeight={ 45 }
itemRenderer={ renderAccession }
/>
......@@ -103,7 +103,7 @@ const mapStateToProps = (state, ownProps) => ({
const mapDispatchToProps = (dispatch) => bindActionCreators({
applyFilters,
loadDataPage: loadAccessionsPage,
loadMoreData: loadMoreAccessions,
updateRoute,
}, dispatch);
......
import * as React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { parse } from 'query-string';
import { translate } from 'react-i18next';
import * as _ from 'lodash';
// Actions
import {applyFilters, loadAccessionsPage, listAccessionsPromise, updateRoute, applyOverviewFilters, loadAccessionsOverviewPage} from 'accessions/actions/public';
import { applyFilters, updateRoute, applyOverviewFilters, loadAccessionsOverviewPage } from 'accessions/actions/public';
import { showSnackbar } from 'actions/snackbar';
// Models
import Accession from 'model/accession/Accession';
import FilteredPage, {IPageRequest} from 'model/FilteredPage';
import FilteredPage, { IPageRequest } from 'model/FilteredPage';
import AccessionFilter from 'model/accession/AccessionFilter';
import AccessionOverview from 'model/accession/AccessionOverview';
......@@ -20,7 +20,7 @@ import PageLayout, { PageContents } from 'ui/layout/PageLayout';
import GridLayout from 'ui/layout/GridLayout';
import ContentHeader from 'ui/common/heading/ContentHeader';
import Loading from 'ui/common/Loading';
import Tabs, {Tab} from 'ui/common/Tabs';
import Tabs, { Tab } from 'ui/common/Tabs';
import PropertiesCard from 'ui/common/PropertiesCard';
import PrettyFilters from 'ui/common/filter/PrettyFilters';
import Number from 'ui/common/Number';
......@@ -216,8 +216,6 @@ const mapStateToProps = (state, ownProps) => ({
const mapDispatchToProps = (dispatch) => bindActionCreators({
showSnackbar,
applyFilters,
loadDataPage: loadAccessionsPage,
loadDataPromise: listAccessionsPromise,
applyOverviewFilters,
loadAccessionsOverviewPage,
updateRoute,
......
......@@ -7,6 +7,7 @@ import FaoInstituteFilter from 'model/genesys/FaoInstituteFilter';
import FilteredPage, {IPageRequest} from 'model/FilteredPage';
import InstituteService from 'service/genesys/InstituteService';
import { showSnackbar } from 'actions/snackbar';
import Page from 'model/Page';
const receiveInstitutes = (paged: FilteredPage<FaoInstitute>, error = null) => ({
type: RECEIVE_INSTITUTES,
......@@ -31,10 +32,6 @@ export const updateRoute = (paged: FilteredPage<FaoInstitute>) => (dispatch) =>
dispatch(navigateTo(paged.filterCode ? `/wiews/${paged.filterCode}` : '/wiews', qs));
};
export const listInstitutesPromise = (filter: string | FaoInstituteFilter, page: IPageRequest) => (dispatch, getState): Promise<FilteredPage<FaoInstitute>> => {
return InstituteService.list(filter, page);
};
export const applyFilters = (filters: string | FaoInstituteFilter, page: IPageRequest = { page: 0 }) => (dispatch) => {
console.log('Applying new filter', filters);
dispatch(showSnackbar('Applying filters...'));
......@@ -50,9 +47,8 @@ export const applyFilters = (filters: string | FaoInstituteFilter, page: IPageRe
});
};
export const loadInstitutesPage = (page: IPageRequest) => (dispatch, getState) => {
const filterCode = getState().institutes.public.paged.filterCode;
return InstituteService.list(filterCode, page)
export const loadMoreInstitutes = (paged?: FilteredPage<FaoInstitute>) => (dispatch) => {
return InstituteService.list(paged && paged.filterCode, Page.nextPage(paged))
.then((paged) => {
if (paged.number === 0) {
dispatch(receiveInstitutes(paged));
......
import * as React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { parse } from 'query-string';
import { translate } from 'react-i18next';
// Actions
import {applyFilters, loadInstitutesPage, updateRoute} from 'institutes/actions/public';
import { applyFilters, loadMoreInstitutes, updateRoute } from 'institutes/actions/public';
// Models
import FaoInstitute from 'model/genesys/FaoInstitute';
......@@ -39,7 +39,7 @@ class BrowsePage extends BrowsePageTemplate<FaoInstitute> {
}
public render() {
const { paged, t } = this.props;
const { paged, t, loadMoreData } = this.props;
const renderInstitute = (s: FaoInstitute, index: number) => {
return <InstituteCard key={ s.code } index={ index } institute={ s } />;
......@@ -54,7 +54,7 @@ class BrowsePage extends BrowsePageTemplate<FaoInstitute> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
onSortChange={ this.onSortChange }
displayName="institutes.common.modelName"
sortOptions={ FaoInstitute.SORT_OPTIONS }
infinite
......@@ -69,7 +69,7 @@ class BrowsePage extends BrowsePageTemplate<FaoInstitute> {
{ ! paged ? <Loading /> :
<PagedLoader
paged={ paged }
loadPage={ this.loadNextPage }
loadMore={ loadMoreData }
roughItemHeight={ 45 }
itemRenderer={ renderInstitute } />
}
......@@ -86,7 +86,7 @@ const mapStateToProps = (state, ownProps) => ({
const mapDispatchToProps = (dispatch) => bindActionCreators({
applyFilters,
loadDataPage: loadInstitutesPage,
loadMoreData: loadMoreInstitutes,
updateRoute,
}, dispatch);
......
......@@ -5,9 +5,9 @@ import {ADMIN_APPEND_MATERIAL_REQUESTS, ADMIN_RECEIVE_MATERIAL_REQUEST, ADMIN_RE
// models
import MaterialRequest from 'model/request/MaterialRequest';
import FilteredPage, {IPageRequest} from 'model/FilteredPage';
import FilteredPage from 'model/FilteredPage';
import RequestService from 'service/genesys/RequestService';
import MaterialRequestFilter from 'model/request/MaterialRequestFilter';
import Page from 'model/Page';
const receiveRequests = (paged: FilteredPage<MaterialRequest>, error = null) => ({
......@@ -39,12 +39,8 @@ const refreshRequestPID = (request: MaterialRequest) => (dispatch, getState) =>
}
};
export const listMaterialRequestsPromise = (filter: string | MaterialRequestFilter, page: IPageRequest) => (dispatch, getState): Promise<FilteredPage<MaterialRequest>> => {
return RequestService.list(filter, page);
};
export const listMaterialRequests = (page: IPageRequest) => (dispatch) => {
return RequestService.list(null, page)
export const loadMoreRequests = (paged?: FilteredPage<MaterialRequest>) => (dispatch) => {
return RequestService.list(paged && paged.filterCode, Page.nextPage(paged))
.then((page) => {
if (page.number === 0) {
dispatch(receiveRequests(page));
......
import * as React from 'react';
import {translate} from 'react-i18next';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import { translate } from 'react-i18next';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
// Actions
import {listMaterialRequests} from 'requests/actions/admin';
import { loadMoreRequests } from 'requests/actions/admin';
// Models
import MaterialRequest from 'model/request/MaterialRequest';
......@@ -21,14 +21,14 @@ import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
class BrowsePage extends BrowsePageTemplate<any> {
public componentWillMount() {
const {paged, loadDataPage} = this.props;
const { paged, loadMoreData } = this.props;
if (!paged) {
loadDataPage(0);
loadMoreData();
}
}
public render() {
const { paged, t } = this.props;
const { paged, t, loadMoreData } = this.props;
const renderRequest = (r: MaterialRequest, index: number) => {
return <RequestCard key={ r.uuid } index={ index } request={ r } />;
......@@ -41,7 +41,7 @@ class BrowsePage extends BrowsePageTemplate<any> {
{ ! paged ? <Loading /> :
<PagedLoader
paged={ paged }
loadPage={ this.loadNextPage }
loadMore={ loadMoreData }
roughItemHeight={ 80 }
itemRenderer={ renderRequest } />
}
......@@ -56,7 +56,7 @@ const mapStateToProps = (state) => ({
});
const mapDispatchToProps = (dispatch) => bindActionCreators({
loadDataPage: listMaterialRequests,
loadMoreData: loadMoreRequests,
}, dispatch);
......
......@@ -40,7 +40,7 @@ class BrowsePage extends BrowsePageTemplate<Subset> {
}
public render() {
const { paged, t } = this.props;
const { paged, t, loadMoreData } = this.props;
const renderSubset = (s: Subset) => {
return <SubsetCard key={ s.uuid } subset={ s } />;
......@@ -55,7 +55,7 @@ class BrowsePage extends BrowsePageTemplate<Subset> {
<PaginationComponent
pageObj={ paged }
onChange={ this.onPaginationChange }
onSortChange={ this.onSortChange }
displayName="subsets.common.modelName"
sortOptions={ Subset.SORT_OPTIONS }
infinite
......@@ -70,7 +70,7 @@ class BrowsePage extends BrowsePageTemplate<Subset> {
{ ! paged ? <Loading /> :
<PagedLoader
paged={ paged }
loadPage={ this.loadNextPage }
loadMore={ loadMoreData }
roughItemHeight={ 300 }
itemRenderer={ renderSubset } />
}
......
......@@ -16,7 +16,7 @@ import Page from 'model/Page';
interface IDashboardPageProps extends React.ClassAttributes<any> {
paged: FilteredPage<Subset>;
loadMySubsets: (page?: Page<Subset>) => void;
loadMoreSubsets: (page?: Page<Subset>) => void;
history: any;
location: any;
login: any;
......@@ -51,15 +51,15 @@ class DashboardPage extends React.Component<IDashboardPageProps> {
}
public componentWillMount() {
const {paged, loadMySubsets} = this.props;
const {paged, loadMoreSubsets} = this.props;
if (!paged) {
loadMySubsets();
loadMoreSubsets();
}
}
public render() {
const {paged, login: { authorities: userRoles }, loadMySubsets} = this.props;
const {paged, login: { authorities: userRoles }, loadMoreSubsets} = 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 }/>;
......@@ -67,7 +67,7 @@ class DashboardPage extends React.Component<IDashboardPageProps> {
return (
<MyDataTable
loadMoreData={ loadMySubsets }
loadMoreData={ loadMoreSubsets }
paged={ paged }
renderTableRow={ renderSubset }
sortOptions={ sortOptions }
......
import * as React from 'react';
import { translate } from 'react-i18next';
import {withStyles} from '@material-ui/core/styles';
import { withStyles } from '@material-ui/core/styles';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import FormControl from '@material-ui/core/FormControl';
// utility
import {log} from 'utilities/debug';
import {CSV, ICsvConfiguration} from 'utilities/CSV';
import { log } from 'utilities/debug';
import { CSV, ICsvConfiguration } from 'utilities/CSV';
// models
import {AccessionRef} from 'model/accession/AccessionRef';
import Accession from 'model/accession/Accession';
import AccessionFilter from 'model/accession/AccessionFilter';
import {IPageRequest} from 'model/FilteredPage';
import Page from 'model/Page';
import { AccessionRef } from 'model/accession/AccessionRef';
import Subset from 'model/subset/Subset';
// ui
import CSVConfiguration, {CSVConfig} from 'ui/common/csv-configuration/CSVConfiguration';
import CSVConfiguration, { CSVConfig } from 'ui/common/csv-configuration/CSVConfiguration';
import AccessionRefsTable from 'ui/catalog/accession/AccessionRefsTable';
interface IListOfAccession extends React.ClassAttributes<any> {
classes: any;
listAccessions: (filter: string | AccessionFilter, page: IPageRequest) => Promise<Page<Accession>>;
subset: Subset;
onAccessionsUpdated: (AccessionRefs: AccessionRef[]) => void;
t: any;
......
import * as React from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
// actions
import {updateSubsetAccessionRefs} from 'subsets/actions/editor';
import {listAccessionsPromise} from 'accessions/actions/public'; // TODO maybe move to dashboard or import from service
import { updateSubsetAccessionRefs } from 'subsets/actions/editor';
// models
import Subset from 'model/subset/Subset';
import Page from 'model/Page';
import Accession from 'model/accession/Accession';
import {AccessionRef} from 'model/accession/AccessionRef';
import AccessionFilter from 'model/accession/AccessionFilter';
import {IPageRequest} from 'model/FilteredPage';
import { AccessionRef } from 'model/accession/AccessionRef';
// ui
import ListOfAccessions from './ListOfAccessions';
import StepperTemplate from 'ui/common/stepper/StepperTemplate';
......@@ -20,17 +16,15 @@ import Loading from 'ui/common/Loading';
interface IAccessionsListStep extends React.ClassAttributes<any> {
item: Subset;
updateSubsetAccessionRefs: (subset: Subset, accessionRefs: AccessionRef[]) => Promise<Subset>;
listAccessions: (filter: string | AccessionFilter, page: IPageRequest) => Promise<Page<Accession>>;
}
class AccessionsListStep extends StepperTemplate<IAccessionsListStep> {
protected renderContent = () => {
const {item, listAccessions} = this.props;
const { item } = this.props;
return !item ? <Loading /> : (
<ListOfAccessions
listAccessions={ listAccessions }
onAccessionsUpdated={ this.updateaccessionRefs }
subset={ item }
/>
......@@ -49,7 +43,6 @@ const mapStateToProps = (state, ownProps) => ({
const mapDispatchToProps = (dispatch) => bindActionCreators({
updateSubsetAccessionRefs,
listAccessions: listAccessionsPromise,
}, dispatch);
export default connect(
......
......@@ -11,7 +11,7 @@ interface IProps<T> extends React.Props<any> {
roughItemHeight?: number; // px of height of element, defaults to 50px, determines when loadNextPage is called
itemRenderer: (item: T, index?: number) => any;
loadingIndicator?: any;
loadPage: (page: number, pageSize: number) => Promise<Page<T>>;
loadMore: (paged?: Page<T>) => void;
}
export default class PagedLoader<T> extends React.Component<IProps<T>, any> {
......@@ -21,15 +21,14 @@ export default class PagedLoader<T> extends React.Component<IProps<T>, any> {
}
private endOfListVisibilityChange = (isVisible: boolean): void => {
const { paged, loadPage } = this.props;
const { paged, loadMore } = this.props;
// log(`Visibility ${isVisible}`);
if (paged && isVisible) {
// we should load some stuff
if (paged && ! paged.last) {
log('Calling for next page', paged.number + 1);
loadPage(paged.number + 1, paged.size);
loadMore(paged);
}
}
}
......
......@@ -2,14 +2,14 @@ import * as React from 'react';
// Models
import FilteredPage from 'model/FilteredPage';
import Page from 'model/Page';
import { SortDirection } from 'model/Page';
interface IBrowsePageProps<T> extends React.ClassAttributes<any> {
paged: FilteredPage<T>;
renderItem: (s: T, index: number) => any;
filterCode: string;
applyFilters: any;
loadMoreData: (paged?: Page<any>) => void;
loadMoreData: (paged?: FilteredPage<any>) => void;
updateRoute: any;
currentTab: any;
t?: any;
......@@ -30,9 +30,9 @@ class BrowsePage<T> extends React.Component<IBrowsePageProps<T>, any> {
}
}
protected onPaginationChange = (page, results, sortBy, dir) => {
const { loadMoreData } = this.props;
loadMoreData();
protected onSortChange = (sortBy: string, dir: SortDirection) => {
const { paged, loadMoreData } = this.props;
loadMoreData(FilteredPage.reSort(paged, sortBy, dir));
}
/// Wrap applyFilters dispatch and fills the current sort selection
......
......@@ -7,6 +7,7 @@ import navigateTo from 'actions/navigation';
import {log} from 'utilities/debug';
import * as _ from 'lodash';
import UserFilter from 'model/UserFilter';
import Page from 'model/Page';
const receiveUsers = (paged: FilteredPage<User>, error = null) => ({
type: ADMIN_RECEIVE_USERS,
......@@ -115,6 +116,21 @@ export const applyFilters = (filters: string | UserFilter, page: IPageRequest =
});
};
export const loadMoreUsers = (paged?: FilteredPage<User>) => (dispatch) => {
return UserService.listUsers(paged ? paged.filterCode : '', Page.nextPage(paged))
.then((paged) => {
if (paged.number === 0) {
dispatch(receiveUsers(paged));
} else {
dispatch(appendUsers(paged));
}
dispatch(updateRoute(paged));
}).catch((error) => {
console.log(`API error`, error);
dispatch(receiveUsers(null, error));
});
};
export const updateRoute = (paged: FilteredPage<User>) => (dispatch) => {