Skip to content

Commit

Permalink
extract usePagination and useSort from useReferenceMany
Browse files Browse the repository at this point in the history
  • Loading branch information
ThieryMichel committed May 21, 2019
1 parent 0d1d66c commit 09a9a26
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { ReactElement, FunctionComponent } from 'react';

import {
SORT_ASC,
SORT_DESC,
} from '../../reducer/admin/resource/list/queryReducer';
import { Record, Sort, RecordMap, Identifier, Dispatch } from '../../types';
import { Record, Sort, RecordMap, Identifier } from '../../types';
import useReferenceMany from './useReferenceMany';
import useSort from '../useSort';
import usePagination from '../usePagination';

interface ChildrenFuncParams {
currentSort: Sort;
Expand Down Expand Up @@ -35,17 +33,6 @@ interface Props {
total?: number;
}

const sortReducer = (state: Sort, field: string | Sort): Sort => {
if (typeof field !== 'string') {
return field;
}
const order =
state.field === field && state.order === SORT_ASC
? SORT_DESC
: SORT_ASC;
return { field, order };
};

/**
* Render related records to the current one.
*
Expand Down Expand Up @@ -100,21 +87,19 @@ export const ReferenceManyFieldController: FunctionComponent<Props> = ({
filter,
source,
basePath,
perPage,
sort,
perPage: initialPerPage,
sort: initialSort,
children,
}) => {
const { sort, sortBy } = useSort(initialSort);
const { page, perPage, setPage, setPerPage } = usePagination(
initialPerPage
);
const {
currentSort,
data,
ids,
loadedOnce,
page,
currentPerPage,
referenceBasePath,
setPage,
setPerPage,
setSort,
total,
} = useReferenceMany({
resource,
Expand All @@ -125,20 +110,21 @@ export const ReferenceManyFieldController: FunctionComponent<Props> = ({
source,
basePath,
perPage,
page,
sort,
});

return children({
currentSort,
currentSort: sort,
data,
ids,
loadedOnce,
page,
perPage: currentPerPage,
perPage,
referenceBasePath,
setPage,
setPerPage,
setSort,
setSort: sortBy,
total,
});
};
Expand Down
50 changes: 10 additions & 40 deletions packages/ra-core/src/controller/field/useReferenceMany.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { ReactNode, useState, useReducer, useEffect, useMemo } from 'react';
import { useEffect, useMemo } from 'react';
// @ts-ignore
import { useSelector, useDispatch } from 'react-redux';
import get from 'lodash/get';

import { crudGetManyReference } from '../../actions';
import {
SORT_ASC,
SORT_DESC,
} from '../../reducer/admin/resource/list/queryReducer';
import {
getIds,
getReferences,
Expand All @@ -17,16 +13,10 @@ import {
import { Record, Sort, RecordMap, Identifier, Dispatch } from '../../types';

interface ChildrenFuncParams {
currentSort: Sort;
data: RecordMap;
ids: Identifier[];
loadedOnce: boolean;
page: number;
currentPerPage: number;
referenceBasePath: string;
setPage: (page: number) => void;
setPerPage: (perPage: number) => void;
setSort: (field: string) => void;
total: number;
}

Expand All @@ -36,7 +26,8 @@ interface Options {
filter?: any;
ids?: any[];
loadedOnce?: boolean;
perPage?: number;
page: number;
perPage: number;
record?: Record;
reference: string;
resource: string;
Expand All @@ -46,17 +37,6 @@ interface Options {
total?: number;
}

const sortReducer = (state: Sort, field: string | Sort): Sort => {
if (typeof field !== 'string') {
return field;
}
const order =
state.field === field && state.order === SORT_ASC
? SORT_DESC
: SORT_ASC;
return { field, order };
};

const defaultFilter = {};

const useReferenceMany = ({
Expand All @@ -67,7 +47,8 @@ const useReferenceMany = ({
filter = defaultFilter,
source,
basePath,
perPage = 25,
page,
perPage,
sort = { field: 'id', order: 'DESC' },
}: Options): ChildrenFuncParams => {
const referenceId = get(record, source);
Expand All @@ -81,11 +62,6 @@ const useReferenceMany = ({
relatedTo,
]);
const total = useSelector(selectTotal(relatedTo), [relatedTo]);
const [page, setPage] = useState(1);
const [currentPerPage, setPerPage] = useState(perPage);
useEffect(() => setPerPage(perPage), [perPage]);
const [currentSort, setSort] = useReducer(sortReducer, sort);
useEffect(() => setSort(sort), [sort.field, sort.order]);

const dispatch = useDispatch();

Expand All @@ -98,8 +74,8 @@ const useReferenceMany = ({
filter,
source,
page,
perPage: currentPerPage,
sort: currentSort,
perPage,
sort,
dispatch,
}),
[
Expand All @@ -111,25 +87,19 @@ const useReferenceMany = ({
source,
crudGetManyReference,
page,
currentPerPage,
currentSort.field,
currentSort.order,
perPage,
sort.field,
sort.order,
]
);

const referenceBasePath = basePath.replace(resource, reference);

return {
currentSort,
data,
ids,
loadedOnce: typeof ids !== 'undefined',
page,
currentPerPage,
referenceBasePath,
setPage,
setPerPage,
setSort,
total,
};
};
Expand Down
21 changes: 21 additions & 0 deletions packages/ra-core/src/controller/usePagination.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useState, useEffect } from 'react';

interface PaginationProps {
page: number;
perPage: number;
setPage: (page: number) => void;
setPerPage: (perPage: number) => void;
}

export default (initialPerPage: number = 25): PaginationProps => {
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(initialPerPage);
useEffect(() => setPerPage(initialPerPage), [initialPerPage]);

return {
page,
perPage,
setPage,
setPerPage,
};
};
31 changes: 31 additions & 0 deletions packages/ra-core/src/controller/useSort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useReducer, useEffect } from 'react';

import {
SORT_ASC,
SORT_DESC,
} from '../reducer/admin/resource/list/queryReducer';
import { Sort } from '../types';

const sortReducer = (state: Sort, field: string | Sort): Sort => {
if (typeof field !== 'string') {
return field;
}
const order =
state.field === field && state.order === SORT_ASC
? SORT_DESC
: SORT_ASC;
return { field, order };
};

export default (initialSort: Sort = { field: 'id', order: 'DESC' }) => {
const [sort, dispatch] = useReducer(sortReducer, initialSort);
useEffect(() => dispatch(initialSort), [
initialSort.field,
initialSort.order,
]);

return {
sortBy: (field: string) => dispatch(field),
sort,
};
};

0 comments on commit 09a9a26

Please sign in to comment.