saleor-dashboard/src/hooks/useLocalPaginator.ts

122 lines
2.9 KiB
TypeScript
Raw Normal View History

2021-06-08 08:54:13 +00:00
import { useEffect, useState } from "react";
export interface PageInfo {
endCursor: string;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string;
}
export interface PaginationState {
after?: string;
before?: string;
first?: number;
last?: number;
}
2021-12-06 14:41:18 +00:00
/**
* Local pagination state.
* @param paginateBy Number of items per page.
* @returns Pagination state and setter.
*/
export function useLocalPaginationState(
paginateBy: number
): [PaginationState, (paginationState: PaginationState) => void] {
const [state, setState] = useState<PaginationState>({
first: paginateBy
});
const setPaginationState = (paginationState: PaginationState) => {
if (paginationState.after) {
setState({
after: paginationState.after,
first: paginateBy
});
} else if (paginationState.before) {
setState({
before: paginationState.before,
last: paginateBy
});
} else {
setState({
first: paginateBy
});
}
};
2021-06-08 08:54:13 +00:00
useEffect(() => {
setPaginationState(state);
}, [paginateBy]);
return [state, setPaginationState];
}
2021-12-06 14:41:18 +00:00
/**
* Local pagination state persisted as long as section is not changed.
* @param paginateBy Number of items per page.
* @param section Section name. When changed, pagination state is reset.
* @returns Pagination state and setter.
*/
export function useSectionLocalPaginationState(
paginateBy: number,
section: string
): [PaginationState, (paginationState: PaginationState) => void] {
const [paginationSection, setPaginationSection] = useState(section);
const [paginationState, setPaginationState] = useLocalPaginationState(
paginateBy
);
useEffect(() => {
if (section !== paginationSection) {
setPaginationState({});
}
}, [section]);
useEffect(() => {
if (section !== paginationSection) {
setPaginationSection(section);
}
}, [paginationState]);
return [
section === paginationSection ? paginationState : {},
setPaginationState
];
}
function useLocalPaginator(
setPaginationState: (paginationState: PaginationState) => void
) {
function paginate(pageInfo: PageInfo, paginationState: PaginationState) {
const loadNextPage = () =>
setPaginationState({
...paginationState,
after: pageInfo.endCursor,
before: undefined
});
const loadPreviousPage = () =>
setPaginationState({
...paginationState,
after: undefined,
before: pageInfo.startCursor
});
const newPageInfo = pageInfo
? {
...pageInfo,
hasNextPage: !!paginationState.before || pageInfo.hasNextPage,
hasPreviousPage: !!paginationState.after || pageInfo.hasPreviousPage
}
: undefined;
return {
loadNextPage,
loadPreviousPage,
pageInfo: newPageInfo
};
}
return paginate;
}
export default useLocalPaginator;