diff --git a/CHANGELOG.md b/CHANGELOG.md index d24053197..13fa77b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable, unreleased changes to this project will be documented in this file. - Added links instead of imperative navigation with onClick - #1969 by @taniotanio7 - Fixed clearing attribute values - #2047 by @witoszekdev - Fixed EditorJS integration in RichTextEditor input - #2052 by @witoszekdev +- Added links to table pagination buttons - #2063 by @witoszekdev +- Using push instead of replace to history stack for pagination navigation - #2063 by @witoszekdev ## 3.1 ### PREVIEW FEATURES diff --git a/package-lock.json b/package-lock.json index a86c2e29a..af3d22db8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2263,6 +2263,38 @@ } } }, + "@floating-ui/core": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.2.tgz", + "integrity": "sha512-FRVAkSNU/vGXLIsgbggcs70GkXKEOXgBBbNpYPNHSaKsCAMMd00NrjbtKTesxkdv9xm9N3+XiDlcFGY6WnatBg==" + }, + "@floating-ui/dom": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.2.tgz", + "integrity": "sha512-z1DnEa7F3d8Fm/eXSbii8UEGpcjZGkQaYYUI0WpEVgD3vBfebDW8j/3ysusxonuMexoigA+A3b/fYH7sEqiwyg==", + "requires": { + "@floating-ui/core": "^0.7.2" + } + }, + "@floating-ui/react-dom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.1.tgz", + "integrity": "sha512-Dd7e8AupUjzcjeGf1g3EItf/QRtEWKF5GGyEs5WA5n3zlHvEgZ4XrZM6ANhUnzgE3pUQAaXkcXLnibgFp1YBRw==", + "requires": { + "@floating-ui/dom": "^0.5.1", + "use-isomorphic-layout-effect": "^1.1.1" + } + }, + "@floating-ui/react-dom-interactions": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom-interactions/-/react-dom-interactions-0.5.0.tgz", + "integrity": "sha512-rfON7mkHjCeogd0BSXPa8GBp1TMxEytJQqGVlCouSUonJ4POqdHsqcxRnCh0yAaGVaL/nB/J1vq28V4RdoLszg==", + "requires": { + "@floating-ui/react-dom": "^0.7.0", + "aria-hidden": "^1.1.3", + "use-isomorphic-layout-effect": "^1.1.1" + } + }, "@formatjs/cli": { "version": "4.8.3", "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-4.8.3.tgz", @@ -5277,10 +5309,11 @@ } }, "@saleor/macaw-ui": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.5.2.tgz", - "integrity": "sha512-fAbIGLnMo9BiVuR6W6MMZUprIutS+f4i1oEG8PX7+WM4rMZbvD204wxvHyx5dXSrU1DhLzDR4MK7dEGK/jykHA==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.6.1.tgz", + "integrity": "sha512-C7WPbuQQTtDH3MVKg//74rSxUheav7TKubw8VytZsUEBWFSVpuzV8Hw+T6riKYJWOtTfYPNUkJlGi1B257hoQQ==", "requires": { + "@floating-ui/react-dom-interactions": "^0.5.0", "clsx": "^1.1.1", "downshift": "^6.1.7", "lodash": "^4.17.21", @@ -8194,6 +8227,14 @@ "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", "dev": true }, + "aria-hidden": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.1.3.tgz", + "integrity": "sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==", + "requires": { + "tslib": "^1.0.0" + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -30914,6 +30955,11 @@ "resolved": "https://registry.npmjs.org/use-force-update/-/use-force-update-1.0.7.tgz", "integrity": "sha512-k5dppYhO+I5X/cd7ildbrzeMZJkWwdAh5adaIk0qKN2euh7J0h2GBGBcB4QZ385eyHHnp7LIygvebdRx3XKdwA==" }, + "use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" + }, "use-react-router": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/use-react-router/-/use-react-router-1.0.7.tgz", diff --git a/package.json b/package.json index 7b6c3a663..1caeb6500 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@material-ui/lab": "^4.0.0-alpha.58", "@material-ui/styles": "^4.11.4", "@reach/auto-id": "^0.16.0", - "@saleor/macaw-ui": "^0.5.2", + "@saleor/macaw-ui": "^0.6.1", "@saleor/sdk": "^0.4.4", "@sentry/react": "^6.0.0", "@types/faker": "^5.1.6", diff --git a/src/apps/components/AppsListPage/AppListPage.stories.tsx b/src/apps/components/AppsListPage/AppListPage.stories.tsx index 25dbda797..37362e985 100644 --- a/src/apps/components/AppsListPage/AppListPage.stories.tsx +++ b/src/apps/components/AppsListPage/AppListPage.stories.tsx @@ -6,6 +6,7 @@ import { tabPageProps } from "@saleor/fixtures"; import Decorator from "@saleor/storybook/Decorator"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -30,13 +31,12 @@ const props: AppsListPageProps = { onAppInProgressRemove: () => undefined, onAppInstallRetry: () => undefined, onCustomAppRemove: () => undefined, - onInstalledAppRemove: () => undefined, - onNextPage: () => undefined, - onPreviousPage: () => undefined + onInstalledAppRemove: () => undefined }; storiesOf("Views / Apps / Apps list", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("default", () => ) .add("loading", () => ( = ({ onRemove, settings, disabled, - onNextPage, - onPreviousPage, onUpdateListSettings, - pageInfo, ...props }) => { const intl = useIntl(); @@ -57,16 +54,10 @@ const InstalledApps: React.FC = ({ - diff --git a/src/apps/views/AppsList/AppsList.tsx b/src/apps/views/AppsList/AppsList.tsx index f1640aa44..59ad5d052 100644 --- a/src/apps/views/AppsList/AppsList.tsx +++ b/src/apps/views/AppsList/AppsList.tsx @@ -19,7 +19,8 @@ import useLocalStorage from "@saleor/hooks/useLocalStorage"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { ListViews } from "@saleor/types"; import getAppErrorMessage from "@saleor/utils/errors/app"; @@ -62,7 +63,6 @@ export const AppsList: React.FC = ({ params }) => { const intl = useIntl(); const navigate = useNavigator(); const { updateListSettings, settings } = useListSettings(ListViews.APPS_LIST); - const paginate = usePaginator(); const paginationState = createPaginationState(settings?.rowNumber, params); const queryVariables = { sort: { @@ -95,11 +95,11 @@ export const AppsList: React.FC = ({ params }) => { } }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - data?.apps?.pageInfo, + const paginationValues = usePaginator({ + pageInfo: data?.apps?.pageInfo, paginationState, - params - ); + queryString: params + }); const { data: customAppsData, @@ -278,7 +278,7 @@ export const AppsList: React.FC = ({ params }) => { const customApps = customAppsData?.apps?.edges; return ( - <> + = ({ params }) => { loadingAppsInProgress={loadingAppsInProgress} disabled={loading || customAppsLoading} settings={settings} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} onAppInstallRetry={onAppInstallRetry} getCustomAppHref={id => customAppUrl(id)} @@ -329,7 +326,7 @@ export const AppsList: React.FC = ({ params }) => { }) } /> - + ); }; diff --git a/src/attributes/components/AttributeList/AttributeList.tsx b/src/attributes/components/AttributeList/AttributeList.tsx index 4c2273060..0a1d15621 100644 --- a/src/attributes/components/AttributeList/AttributeList.tsx +++ b/src/attributes/components/AttributeList/AttributeList.tsx @@ -8,7 +8,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { AttributeFragment } from "@saleor/graphql"; import { translateBoolean } from "@saleor/intl"; @@ -71,9 +71,6 @@ const AttributeList: React.FC = ({ attributes, disabled, isChecked, - onNextPage, - onPreviousPage, - pageInfo, selected, sort, toggle, @@ -172,15 +169,7 @@ const AttributeList: React.FC = ({ - + diff --git a/src/attributes/components/AttributeValues/AttributeValues.tsx b/src/attributes/components/AttributeValues/AttributeValues.tsx index 1e85aa40f..a05de6a72 100644 --- a/src/attributes/components/AttributeValues/AttributeValues.tsx +++ b/src/attributes/components/AttributeValues/AttributeValues.tsx @@ -20,12 +20,18 @@ import { } from "@saleor/graphql"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; import { renderCollection, stopPropagation } from "@saleor/misc"; -import { ListProps, RelayToFlat, ReorderAction } from "@saleor/types"; +import { + ListProps, + PaginateListProps, + RelayToFlat, + ReorderAction +} from "@saleor/types"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; export interface AttributeValuesProps - extends Pick> { + extends Pick>, + PaginateListProps { disabled: boolean; values: RelayToFlat; onValueAdd: () => void; diff --git a/src/attributes/views/AttributeList/AttributeList.tsx b/src/attributes/views/AttributeList/AttributeList.tsx index 301985677..b5cce7923 100644 --- a/src/attributes/views/AttributeList/AttributeList.tsx +++ b/src/attributes/views/AttributeList/AttributeList.tsx @@ -18,7 +18,8 @@ import { import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; @@ -48,7 +49,6 @@ interface AttributeListProps { const AttributeList: React.FC = ({ params }) => { const navigate = useNavigator(); - const paginate = usePaginator(); const notify = useNotifier(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids @@ -131,16 +131,16 @@ const AttributeList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.attributes.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.attributes.pageInfo), paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, attributeListUrl, params); return ( - <> + = ({ params }) => { isChecked={isSelected} onAll={resetFilters} onFilterChange={changeFilters} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSearchChange={handleSearchChange} onSort={handleSort} onTabChange={handleTabChange} onTabDelete={() => openModal("delete-search")} onTabSave={() => openModal("save-search")} - pageInfo={pageInfo} selected={listElements.length} sort={getSortParams(params)} tabs={tabs.map(tab => tab.name)} @@ -199,7 +196,7 @@ const AttributeList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; AttributeList.displayName = "AttributeList"; diff --git a/src/categories/components/CategoryList/CategoryList.tsx b/src/categories/components/CategoryList/CategoryList.tsx index 4de8fe039..328d97524 100644 --- a/src/categories/components/CategoryList/CategoryList.tsx +++ b/src/categories/components/CategoryList/CategoryList.tsx @@ -5,7 +5,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { CategoryFragment } from "@saleor/graphql"; import { makeStyles } from "@saleor/macaw-ui"; @@ -58,15 +58,12 @@ const CategoryList: React.FC = props => { disabled, settings, sort, - pageInfo, isChecked, isRoot, selected, toggle, toggleAll, toolbar, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort } = props; @@ -136,16 +133,10 @@ const CategoryList: React.FC = props => { - diff --git a/src/categories/components/CategoryListPage/CategoryListPage.tsx b/src/categories/components/CategoryListPage/CategoryListPage.tsx index 3db73cb59..75b052c7b 100644 --- a/src/categories/components/CategoryListPage/CategoryListPage.tsx +++ b/src/categories/components/CategoryListPage/CategoryListPage.tsx @@ -36,7 +36,6 @@ export const CategoryListPage: React.FC = ({ disabled, initialSearch, isChecked, - pageInfo, selected, settings, tabs, @@ -44,8 +43,6 @@ export const CategoryListPage: React.FC = ({ toggleAll, toolbar, onAll, - onNextPage, - onPreviousPage, onSearchChange, onTabChange, onTabDelete, @@ -95,14 +92,11 @@ export const CategoryListPage: React.FC = ({ disabled={disabled} isChecked={isChecked} isRoot={true} - pageInfo={pageInfo} selected={selected} settings={settings} toggle={toggle} toggleAll={toggleAll} toolbar={toolbar} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} onUpdateListSettings={onUpdateListSettings} {...listProps} /> diff --git a/src/categories/components/CategoryProductList/CategoryProductList.tsx b/src/categories/components/CategoryProductList/CategoryProductList.tsx index a557b2eb4..9f446c0bb 100644 --- a/src/categories/components/CategoryProductList/CategoryProductList.tsx +++ b/src/categories/components/CategoryProductList/CategoryProductList.tsx @@ -5,7 +5,7 @@ import Skeleton from "@saleor/components/Skeleton"; import TableCellAvatar from "@saleor/components/TableCellAvatar"; import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { CategoryDetailsQuery } from "@saleor/graphql"; import { makeStyles } from "@saleor/macaw-ui"; @@ -59,14 +59,11 @@ export const CategoryProductList: React.FC = props => const { disabled, isChecked, - pageInfo, products, selected, toggle, toggleAll, - toolbar, - onNextPage, - onPreviousPage + toolbar } = props; const classes = useStyles(props); @@ -100,15 +97,7 @@ export const CategoryProductList: React.FC = props => - + diff --git a/src/categories/components/CategoryProducts/CategoryProducts.tsx b/src/categories/components/CategoryProducts/CategoryProducts.tsx index 98c7a3fde..ab0708217 100644 --- a/src/categories/components/CategoryProducts/CategoryProducts.tsx +++ b/src/categories/components/CategoryProducts/CategoryProducts.tsx @@ -21,9 +21,6 @@ interface CategoryProductsProps extends PageListProps, ListActions { export const CategoryProducts: React.FC = ({ products, disabled, - pageInfo, - onNextPage, - onPreviousPage, categoryId, categoryName, isChecked, @@ -79,9 +76,6 @@ export const CategoryProducts: React.FC = ({ ; subcategories: RelayToFlat; - pageInfo: { - hasNextPage: boolean; - hasPreviousPage: boolean; - }; saveButtonBarState: ConfirmButtonTransitionState; addProductHref: string; onImageDelete: () => void; onSubmit: (data: CategoryUpdateData) => SubmitPromise; onImageUpload(file: File); - onNextPage(); - onPreviousPage(); onDelete(); } @@ -69,13 +63,10 @@ export const CategoryUpdatePage: React.FC = ({ category, disabled, errors, - pageInfo, products, saveButtonBarState, subcategories, onDelete, - onNextPage, - onPreviousPage, onSubmit, onImageDelete, onImageUpload, @@ -191,14 +182,11 @@ export const CategoryUpdatePage: React.FC = ({ disabled={disabled} isChecked={isChecked} isRoot={false} - pageInfo={pageInfo} selected={selected} sort={undefined} toggle={toggle} toggleAll={toggleAll} toolbar={subcategoryListToolbar} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} onSort={() => undefined} /> @@ -209,9 +197,6 @@ export const CategoryUpdatePage: React.FC = ({ categoryName={category?.name} products={products} disabled={disabled} - pageInfo={pageInfo} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} toggle={toggle} toggleAll={toggleAll} selected={selected} diff --git a/src/categories/views/CategoryDetails.tsx b/src/categories/views/CategoryDetails.tsx index 1bab1128e..4d13f49f4 100644 --- a/src/categories/views/CategoryDetails.tsx +++ b/src/categories/views/CategoryDetails.tsx @@ -21,6 +21,7 @@ import useLocalPaginator, { } from "@saleor/hooks/useLocalPaginator"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; +import { PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, errorMessages } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; @@ -174,7 +175,7 @@ export const CategoryDetails: React.FC = ({ CategoryUrlQueryParams >(navigate, params => categoryUrl(id, params), params); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( + const { pageInfo, ...paginationFunctions } = paginate( activeTab === CategoryPageTab.categories ? maybe(() => data.category.children.pageInfo) : maybe(() => data.category.products.pageInfo), @@ -208,7 +209,7 @@ export const CategoryDetails: React.FC = ({ ); return ( - <> + data.category.name)} /> = ({ } }) } - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} - pageInfo={pageInfo} onSubmit={handleSubmit} products={mapEdgesToItems(data?.category?.products)} saveButtonBarState={updateResult.status} @@ -371,7 +369,7 @@ export const CategoryDetails: React.FC = ({ /> - + ); }; export default CategoryDetails; diff --git a/src/categories/views/CategoryList/CategoryList.tsx b/src/categories/views/CategoryList/CategoryList.tsx index f90de37db..982a41b48 100644 --- a/src/categories/views/CategoryList/CategoryList.tsx +++ b/src/categories/views/CategoryList/CategoryList.tsx @@ -14,7 +14,8 @@ import useListSettings from "@saleor/hooks/useListSettings"; import useNavigator from "@saleor/hooks/useNavigator"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; import { maybe } from "@saleor/misc"; @@ -49,7 +50,6 @@ interface CategoryListProps { export const CategoryList: React.FC = ({ params }) => { const navigate = useNavigator(); - const paginate = usePaginator(); const { isSelected, listElements, toggle, toggleAll, reset } = useBulkActions( params.ids @@ -117,11 +117,11 @@ export const CategoryList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.categories.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.categories.pageInfo), paginationState, - params - ); + queryString: params + }); const handleCategoryBulkDelete = (data: CategoryBulkDeleteMutation) => { if (data.categoryBulkDelete.errors.length === 0) { @@ -141,7 +141,7 @@ export const CategoryList: React.FC = ({ params }) => { const handleSort = createSortHandler(navigate, categoryListUrl, params); return ( - <> + = ({ params }) => { sort={getSortParams(params)} onSort={handleSort} disabled={loading} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} - pageInfo={pageInfo} isChecked={isSelected} selected={listElements.length} toggle={toggle} @@ -235,7 +232,7 @@ export const CategoryList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; export default CategoryList; diff --git a/src/collections/components/CollectionList/CollectionList.tsx b/src/collections/components/CollectionList/CollectionList.tsx index 755864f04..fcf877bad 100644 --- a/src/collections/components/CollectionList/CollectionList.tsx +++ b/src/collections/components/CollectionList/CollectionList.tsx @@ -14,7 +14,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader"; import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages"; @@ -73,11 +73,8 @@ const CollectionList: React.FC = props => { disabled, settings, sort, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort, - pageInfo, isChecked, selected, selectedChannelId, @@ -150,16 +147,10 @@ const CollectionList: React.FC = props => { - diff --git a/src/collections/components/CollectionProducts/CollectionProducts.tsx b/src/collections/components/CollectionProducts/CollectionProducts.tsx index b7ae5aaba..e15350807 100644 --- a/src/collections/components/CollectionProducts/CollectionProducts.tsx +++ b/src/collections/components/CollectionProducts/CollectionProducts.tsx @@ -15,7 +15,7 @@ import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableB import TableCellAvatar from "@saleor/components/TableCellAvatar"; import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { CollectionDetailsQuery } from "@saleor/graphql"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; @@ -67,10 +67,7 @@ const CollectionProducts: React.FC = props => { collection, disabled, onAdd, - onNextPage, - onPreviousPage, onProductUnassign, - pageInfo, isChecked, selected, toggle, @@ -154,13 +151,7 @@ const CollectionProducts: React.FC = props => { - + diff --git a/src/collections/views/CollectionDetails.tsx b/src/collections/views/CollectionDetails.tsx index 23e9e17d8..324e78719 100644 --- a/src/collections/views/CollectionDetails.tsx +++ b/src/collections/views/CollectionDetails.tsx @@ -31,6 +31,7 @@ import useLocalPaginator, { import useLocalStorage from "@saleor/hooks/useLocalStorage"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; +import { PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, errorMessages } from "@saleor/intl"; import useProductSearch from "@saleor/searches/useProductSearch"; import { arrayDiff } from "@saleor/utils/arrays"; @@ -255,13 +256,13 @@ export const CollectionDetails: React.FC = ({ updateCollectionOpts.data?.collectionUpdate.errors ); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( + const { pageInfo, ...paginationValues } = paginate( data?.collection?.products?.pageInfo, paginationState ); return ( - <> + {!!allChannels?.length && ( = ({ }) } onSubmit={handleSubmit} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} - pageInfo={pageInfo} onProductUnassign={(productId, event) => { event.stopPropagation(); unassignProduct({ @@ -448,7 +446,7 @@ export const CollectionDetails: React.FC = ({ /> - + ); }; export default CollectionDetails; diff --git a/src/collections/views/CollectionList/CollectionList.tsx b/src/collections/views/CollectionList/CollectionList.tsx index df1c75794..122b8f0b9 100644 --- a/src/collections/views/CollectionList/CollectionList.tsx +++ b/src/collections/views/CollectionList/CollectionList.tsx @@ -15,7 +15,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -55,7 +56,6 @@ export const CollectionList: React.FC = ({ params }) => { const navigate = useNavigator(); const intl = useIntl(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -159,16 +159,16 @@ export const CollectionList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.collections.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.collections.pageInfo), paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, collectionListUrl, params); return ( - <> + = ({ params }) => { disabled={loading} collections={mapEdgesToItems(data?.collections)} settings={settings} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSort={handleSort} onUpdateListSettings={updateListSettings} - pageInfo={pageInfo} sort={getSortParams(params)} toolbar={ = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; export default CollectionList; diff --git a/src/components/Attributes/Attributes.stories.tsx b/src/components/Attributes/Attributes.stories.tsx index 223d75c2a..07eda4509 100644 --- a/src/components/Attributes/Attributes.stories.tsx +++ b/src/components/Attributes/Attributes.stories.tsx @@ -1,5 +1,6 @@ import Attributes, { AttributesProps } from "@saleor/components/Attributes"; import { fetchMoreProps } from "@saleor/fixtures"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -31,6 +32,7 @@ const props: AttributesProps = { storiesOf("Attributes / Attributes", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("default", () => ) .add("selected", () => ( diff --git a/src/components/TablePagination/TablePagination.tsx b/src/components/TablePagination/TablePagination.tsx index 97359d931..615440ce7 100644 --- a/src/components/TablePagination/TablePagination.tsx +++ b/src/components/TablePagination/TablePagination.tsx @@ -5,6 +5,7 @@ import { } from "@saleor/macaw-ui"; import React from "react"; import { defineMessages, useIntl } from "react-intl"; +import { Link, LinkProps } from "react-router-dom"; import { ListSettings } from "../../types"; @@ -22,17 +23,28 @@ const messages = defineMessages({ }); export interface PaginationProps - extends Omit { + extends Omit< + MacawPaginationProps, + "labels" | "rowNumber" | "nextIconButtonProps" | "prevIconButtonProps" + > { component?: React.ElementType; colSpan?: number; settings?: ListSettings; onUpdateListSettings?: ListSettingsUpdate; + prevHref?: string; + nextHref?: string; + disabled?: boolean; } export const TablePagination: React.FC = ({ component, colSpan, settings, onUpdateListSettings, + nextHref, + prevHref, + hasNextPage, + hasPreviousPage, + disabled, ...rest }) => { const intl = useIntl(); @@ -40,8 +52,10 @@ export const TablePagination: React.FC = ({ return ( - {...rest} + hasNextPage={hasNextPage && !disabled} + hasPreviousPage={hasPreviousPage && !disabled} labels={{ noOfRows: intl.formatMessage(messages.noOfRows) }} @@ -51,6 +65,12 @@ export const TablePagination: React.FC = ({ ? value => onUpdateListSettings("rowNumber", value) : undefined } + nextIconButtonProps={ + nextHref ? { component: Link, to: nextHref } : undefined + } + prevIconButtonProps={ + prevHref ? { component: Link, to: prevHref } : undefined + } /> ); diff --git a/src/components/TablePagination/TablePaginationWithContext.tsx b/src/components/TablePagination/TablePaginationWithContext.tsx new file mode 100644 index 000000000..1909babb3 --- /dev/null +++ b/src/components/TablePagination/TablePaginationWithContext.tsx @@ -0,0 +1,50 @@ +import { usePaginatorContext } from "@saleor/hooks/usePaginator"; +import React from "react"; + +import TablePagination, { PaginationProps } from "./TablePagination"; + +export type TablePaginationWithContextProps = Omit< + PaginationProps, + | "nextHref" + | "prevHref" + | "hasNextPage" + | "hasPreviousPage" + | "onNextPage" + | "onPreviousPage" +>; +export const TablePaginationWithContext = ( + props: TablePaginationWithContextProps +) => { + const { + hasNextPage, + hasPreviousPage, + paginatorType, + ...paginationProps + } = usePaginatorContext(); + + if (paginatorType === "click") { + const { loadNextPage, loadPreviousPage } = paginationProps; + + return ( + + ); + } + + const { prevPageHref, nextPageHref } = paginationProps; + + return ( + + ); +}; diff --git a/src/components/TablePagination/index.ts b/src/components/TablePagination/index.ts index 0d128c72d..262cf844b 100644 --- a/src/components/TablePagination/index.ts +++ b/src/components/TablePagination/index.ts @@ -1,3 +1,4 @@ export { default } from "./TablePagination"; export * from "./TablePagination"; export * from "./TablePaginationActions"; +export * from "./TablePaginationWithContext"; diff --git a/src/customers/components/CustomerList/CustomerList.tsx b/src/customers/components/CustomerList/CustomerList.tsx index 187d96d19..1620d33a6 100644 --- a/src/customers/components/CustomerList/CustomerList.tsx +++ b/src/customers/components/CustomerList/CustomerList.tsx @@ -8,7 +8,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { CustomerListUrlSortField, customerUrl } from "@saleor/customers/urls"; import { ListCustomersQuery, PermissionEnum } from "@saleor/graphql"; @@ -54,9 +54,6 @@ const CustomerList: React.FC = props => { settings, disabled, customers, - pageInfo, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort, toolbar, @@ -129,16 +126,10 @@ const CustomerList: React.FC = props => { - diff --git a/src/customers/views/CustomerList/CustomerList.tsx b/src/customers/views/CustomerList/CustomerList.tsx index 19e60ae2f..9b387e868 100644 --- a/src/customers/views/CustomerList/CustomerList.tsx +++ b/src/customers/views/CustomerList/CustomerList.tsx @@ -15,7 +15,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, sectionNames } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -54,7 +55,6 @@ interface CustomerListProps { export const CustomerList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -122,11 +122,11 @@ export const CustomerList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.customers.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.customers.pageInfo), paginationState, - params - ); + queryString: params + }); const [ bulkRemoveCustomers, @@ -148,7 +148,7 @@ export const CustomerList: React.FC = ({ params }) => { const handleSort = createSortHandler(navigate, customerListUrl, params); return ( - <> + = ({ params }) => { customers={mapEdgesToItems(data?.customers)} settings={settings} disabled={loading} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} onSort={handleSort} toolbar={ @@ -230,7 +227,7 @@ export const CustomerList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; export default CustomerList; diff --git a/src/discounts/components/DiscountCategories/DiscountCategories.tsx b/src/discounts/components/DiscountCategories/DiscountCategories.tsx index 5ff390a45..4fcb895b1 100644 --- a/src/discounts/components/DiscountCategories/DiscountCategories.tsx +++ b/src/discounts/components/DiscountCategories/DiscountCategories.tsx @@ -13,7 +13,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { SaleDetailsFragment, VoucherDetailsFragment } from "@saleor/graphql"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -38,11 +38,8 @@ const DiscountCategories: React.FC = props => { const { discount, disabled, - pageInfo, onCategoryAssign, onCategoryUnassign, - onPreviousPage, - onNextPage, toolbar, toggle, toggleAll, @@ -94,15 +91,7 @@ const DiscountCategories: React.FC = props => { - + diff --git a/src/discounts/components/DiscountCollections/DiscountCollections.tsx b/src/discounts/components/DiscountCollections/DiscountCollections.tsx index 58ce29cf9..5b0dd3303 100644 --- a/src/discounts/components/DiscountCollections/DiscountCollections.tsx +++ b/src/discounts/components/DiscountCollections/DiscountCollections.tsx @@ -13,7 +13,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { SaleDetailsFragment, VoucherDetailsFragment } from "@saleor/graphql"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -38,11 +38,8 @@ const DiscountCollections: React.FC = props => { const { discount: sale, disabled, - pageInfo, onCollectionAssign, onCollectionUnassign, - onPreviousPage, - onNextPage, isChecked, selected, toggle, @@ -92,15 +89,7 @@ const DiscountCollections: React.FC = props => { - + diff --git a/src/discounts/components/DiscountProducts/DiscountProducts.tsx b/src/discounts/components/DiscountProducts/DiscountProducts.tsx index 2cfa21eba..125d08fdd 100644 --- a/src/discounts/components/DiscountProducts/DiscountProducts.tsx +++ b/src/discounts/components/DiscountProducts/DiscountProducts.tsx @@ -14,7 +14,7 @@ import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableCellAvatar from "@saleor/components/TableCellAvatar"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { SaleDetailsFragment, VoucherDetailsFragment } from "@saleor/graphql"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -41,11 +41,8 @@ const DiscountProducts: React.FC = props => { const { products, disabled, - pageInfo, - onPreviousPage, onProductAssign, onProductUnassign, - onNextPage, isChecked, selected, toggle, @@ -101,15 +98,7 @@ const DiscountProducts: React.FC = props => { - + diff --git a/src/discounts/components/DiscountVariants/DiscountVariants.tsx b/src/discounts/components/DiscountVariants/DiscountVariants.tsx index 44a906a6e..54605d2f3 100644 --- a/src/discounts/components/DiscountVariants/DiscountVariants.tsx +++ b/src/discounts/components/DiscountVariants/DiscountVariants.tsx @@ -13,7 +13,7 @@ import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableCellAvatar from "@saleor/components/TableCellAvatar"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { SaleDetailsFragment } from "@saleor/graphql"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -38,11 +38,8 @@ const DiscountVariants: React.FC = props => { const { variants, disabled, - pageInfo, - onPreviousPage, onVariantAssign, onVariantUnassign, - onNextPage, isChecked, selected, toggle, @@ -100,15 +97,7 @@ const DiscountVariants: React.FC = props => { - + diff --git a/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx b/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx index 52cd76cdb..18d6d3916 100644 --- a/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx +++ b/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx @@ -106,7 +106,6 @@ const SaleDetailsPage: React.FC = ({ onSubmit, onTabClick, openChannelsModal, - pageInfo, sale, saveButtonBarState, onCategoryAssign, @@ -114,8 +113,6 @@ const SaleDetailsPage: React.FC = ({ onChannelsChange, onCollectionAssign, onCollectionUnassign, - onNextPage, - onPreviousPage, onProductAssign, onProductUnassign, onVariantAssign, @@ -277,9 +274,6 @@ const SaleDetailsPage: React.FC = ({ disabled={disabled} onCategoryAssign={onCategoryAssign} onCategoryUnassign={onCategoryUnassign} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} - pageInfo={pageInfo} discount={sale} isChecked={isChecked} selected={selected} @@ -292,9 +286,6 @@ const SaleDetailsPage: React.FC = ({ disabled={disabled} onCollectionAssign={onCollectionAssign} onCollectionUnassign={onCollectionUnassign} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} - pageInfo={pageInfo} discount={sale} isChecked={isChecked} selected={selected} @@ -305,11 +296,8 @@ const SaleDetailsPage: React.FC = ({ ) : activeTab === SaleDetailsPageTab.products ? ( = ({ ) : ( = props => { const { settings, disabled, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort, - pageInfo, sales, selectedChannelId, isChecked, @@ -174,16 +171,10 @@ const SaleList: React.FC = props => { - diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx index e206377f8..10e7cb81d 100644 --- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx +++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx @@ -109,7 +109,6 @@ const VoucherDetailsPage: React.FC = ({ channelListings = [], disabled, errors, - pageInfo, saveButtonBarState, voucher, onCategoryAssign, @@ -119,8 +118,6 @@ const VoucherDetailsPage: React.FC = ({ onCountryUnassign, onCollectionAssign, onCollectionUnassign, - onNextPage, - onPreviousPage, onProductAssign, onProductUnassign, onTabClick, @@ -309,9 +306,6 @@ const VoucherDetailsPage: React.FC = ({ disabled={disabled} onCategoryAssign={onCategoryAssign} onCategoryUnassign={onCategoryUnassign} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} - pageInfo={pageInfo} discount={voucher} isChecked={isChecked} selected={selected} @@ -324,9 +318,6 @@ const VoucherDetailsPage: React.FC = ({ disabled={disabled} onCollectionAssign={onCollectionAssign} onCollectionUnassign={onCollectionUnassign} - onNextPage={onNextPage} - onPreviousPage={onPreviousPage} - pageInfo={pageInfo} discount={voucher} isChecked={isChecked} selected={selected} @@ -337,11 +328,8 @@ const VoucherDetailsPage: React.FC = ({ ) : ( = props => { const { settings, disabled, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort, - pageInfo, vouchers, isChecked, selected, @@ -228,16 +225,10 @@ const VoucherList: React.FC = props => { - diff --git a/src/discounts/views/SaleDetails/SaleDetails.tsx b/src/discounts/views/SaleDetails/SaleDetails.tsx index dc29fc6d0..b0e91aadf 100644 --- a/src/discounts/views/SaleDetails/SaleDetails.tsx +++ b/src/discounts/views/SaleDetails/SaleDetails.tsx @@ -40,6 +40,7 @@ import useLocalPaginator, { import useLocalStorage from "@saleor/hooks/useLocalStorage"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; +import { PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, sectionNames } from "@saleor/intl"; import { maybe } from "@saleor/misc"; import useCategorySearch from "@saleor/searches/useCategorySearch"; @@ -251,7 +252,7 @@ export const SaleDetails: React.FC = ({ id, params }) => { } }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( + const { pageInfo, ...paginationValues } = paginate( tabPageInfo, paginationState ); @@ -269,7 +270,7 @@ export const SaleDetails: React.FC = ({ id, params }) => { ); return ( - <> + {!!allChannels?.length && ( = ({ id, params }) => { disabled={loading || saleCataloguesRemoveOpts.loading} errors={saleUpdateOpts.data?.saleUpdate.errors || []} selectedChannelId={selectedChannel} - pageInfo={pageInfo} openChannelsModal={handleChannelsModalOpen} onChannelsChange={setCurrentChannels} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onCategoryAssign={() => openModal("assign-category")} onCollectionAssign={() => openModal("assign-collection")} onCollectionUnassign={collectionId => @@ -589,7 +587,7 @@ export const SaleDetails: React.FC = ({ id, params }) => { /> - + ); }; export default SaleDetails; diff --git a/src/discounts/views/SaleList/SaleList.tsx b/src/discounts/views/SaleList/SaleList.tsx index aa2be2aaa..985f43f12 100644 --- a/src/discounts/views/SaleList/SaleList.tsx +++ b/src/discounts/views/SaleList/SaleList.tsx @@ -13,7 +13,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, sectionNames } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -52,7 +53,6 @@ interface SaleListProps { export const SaleList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -141,11 +141,11 @@ export const SaleList: React.FC = ({ params }) => { const canOpenBulkActionDialog = maybe(() => params.ids.length > 0); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.sales.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.sales.pageInfo), paginationState, - params - ); + queryString: params + }); const [saleBulkDelete, saleBulkDeleteOpts] = useSaleBulkDeleteMutation({ onCompleted: data => { @@ -171,7 +171,7 @@ export const SaleList: React.FC = ({ params }) => { }); return ( - <> + = ({ params }) => { sales={mapEdgesToItems(data?.sales)} settings={settings} disabled={loading} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSort={handleSort} onUpdateListSettings={updateListSettings} isChecked={isSelected} @@ -251,7 +248,7 @@ export const SaleList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; export default SaleList; diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 9a1d7a4f2..b79878cfc 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -40,6 +40,7 @@ import useLocalPaginator, { } from "@saleor/hooks/useLocalPaginator"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; +import { PaginatorContext } from "@saleor/hooks/usePaginator"; import useShop from "@saleor/hooks/useShop"; import { commonMessages, sectionNames } from "@saleor/intl"; import useCategorySearch from "@saleor/searches/useCategorySearch"; @@ -263,13 +264,13 @@ export const VoucherDetails: React.FC = ({ } }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( + const { pageInfo, ...paginationValues } = paginate( tabPageInfo, paginationState ); return ( - <> + {!!allChannels?.length && ( = ({ ...(updateChannelsOpts.data?.voucherChannelListingUpdate.errors || []) ]} selectedChannelId={channel?.id} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onCategoryAssign={() => openModal("assign-category")} onCollectionAssign={() => openModal("assign-collection")} onCollectionUnassign={collectionId => @@ -605,7 +603,7 @@ export const VoucherDetails: React.FC = ({ /> - + ); }; export default VoucherDetails; diff --git a/src/discounts/views/VoucherList/VoucherList.tsx b/src/discounts/views/VoucherList/VoucherList.tsx index 09f538332..fa886cc62 100644 --- a/src/discounts/views/VoucherList/VoucherList.tsx +++ b/src/discounts/views/VoucherList/VoucherList.tsx @@ -16,7 +16,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, sectionNames } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -55,7 +56,6 @@ interface VoucherListProps { export const VoucherList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -145,11 +145,11 @@ export const VoucherList: React.FC = ({ params }) => { const canOpenBulkActionDialog = maybe(() => params.ids.length > 0); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - data?.vouchers?.pageInfo, + const paginationValues = usePaginator({ + pageInfo: data?.vouchers?.pageInfo, paginationState, - params - ); + queryString: params + }); const [ voucherBulkDelete, @@ -178,7 +178,7 @@ export const VoucherList: React.FC = ({ params }) => { const handleSort = createSortHandler(navigate, voucherListUrl, params); return ( - <> + = ({ params }) => { settings={settings} vouchers={mapEdgesToItems(data?.vouchers)} disabled={loading} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} onSort={handleSort} isChecked={isSelected} @@ -258,7 +255,7 @@ export const VoucherList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; export default VoucherList; diff --git a/src/fixtures.ts b/src/fixtures.ts index 31cb54793..8915fa313 100644 --- a/src/fixtures.ts +++ b/src/fixtures.ts @@ -5,6 +5,7 @@ import { UserDetailsQuery } from "@saleor/graphql"; +import { PaginatorContextValues } from "./hooks/usePaginator"; import { FetchMoreProps, FilterPageProps, @@ -303,6 +304,16 @@ export const tabPageProps: TabPageProps = { tabs: ["Tab X"] }; +export const paginatorContextValues: PaginatorContextValues = { + endCursor: "", + startCursor: "", + hasNextPage: false, + hasPreviousPage: false, + nextPageHref: "", + prevPageHref: "", + paginatorType: "link" +}; + export const searchPageProps: SearchPageProps = { initialSearch: "", onSearchChange: () => undefined diff --git a/src/giftCards/GiftCardsList/GiftCardsListTable/GiftCardsListTableFooter.tsx b/src/giftCards/GiftCardsList/GiftCardsListTable/GiftCardsListTableFooter.tsx index 4bdee470e..549d28b06 100644 --- a/src/giftCards/GiftCardsList/GiftCardsListTable/GiftCardsListTableFooter.tsx +++ b/src/giftCards/GiftCardsList/GiftCardsListTable/GiftCardsListTableFooter.tsx @@ -6,8 +6,6 @@ import React from "react"; import { useGiftCardList } from "../providers/GiftCardListProvider"; const GiftCardsListTableFooter: React.FC = () => { - const paginate = usePaginator(); - const { settings, updateListSettings, @@ -17,23 +15,20 @@ const GiftCardsListTableFooter: React.FC = () => { numberOfColumns } = useGiftCardList(); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - apiPageInfo, + const paginationValues = usePaginator({ + pageInfo: apiPageInfo, paginationState, - params - ); + queryString: params + }); return ( diff --git a/src/hooks/useLocalPaginator.ts b/src/hooks/useLocalPaginator.ts index f96fd2996..041f2a060 100644 --- a/src/hooks/useLocalPaginator.ts +++ b/src/hooks/useLocalPaginator.ts @@ -117,6 +117,7 @@ function useLocalPaginator( return { loadNextPage, loadPreviousPage, + paginatorType: "click" as const, pageInfo: newPageInfo }; } diff --git a/src/hooks/usePaginator.ts b/src/hooks/usePaginator.ts index 4c44dfe3d..e0dbce707 100644 --- a/src/hooks/usePaginator.ts +++ b/src/hooks/usePaginator.ts @@ -1,7 +1,7 @@ import { stringifyQs } from "@saleor/utils/urls"; +import { createContext, useContext, useMemo } from "react"; import { Pagination } from "../types"; -import useNavigator from "./useNavigator"; export interface PageInfo { endCursor: string; @@ -36,50 +36,105 @@ export function createPaginationState( }; } -function usePaginator() { - const navigate = useNavigator(); - - function paginate( - pageInfo: PageInfo, - paginationState: PaginationState, - queryString: Pagination - ) { - const loadNextPage = () => - navigate( - "?" + - stringifyQs({ - ...queryString, - after: pageInfo.endCursor, - before: undefined - }), - { replace: true, resetScroll: true } - ); - - const loadPreviousPage = () => - navigate( - "?" + - stringifyQs({ - ...queryString, - after: undefined, - before: pageInfo.startCursor - }), - { replace: true, resetScroll: true } - ); - - const newPageInfo = pageInfo - ? { - ...pageInfo, - hasNextPage: !!paginationState.before || pageInfo.hasNextPage, - hasPreviousPage: !!paginationState.after || pageInfo.hasPreviousPage - } - : undefined; - - return { - loadNextPage, - loadPreviousPage, - pageInfo: newPageInfo - }; - } - return paginate; +interface UsePaginatorArgs { + pageInfo: PageInfo; + paginationState: PaginationState; + queryString: Pagination; } + +function usePaginator({ + queryString, + paginationState, + pageInfo +}: UsePaginatorArgs) { + const newPageInfo = useMemo( + () => + pageInfo + ? { + ...pageInfo, + hasNextPage: !!paginationState.before || pageInfo.hasNextPage, + hasPreviousPage: !!paginationState.after || pageInfo.hasPreviousPage + } + : undefined, + [paginationState, pageInfo] + ); + + const nextPageHref = useMemo(() => { + if (!newPageInfo?.hasNextPage || !pageInfo?.endCursor) { + return undefined; + } + + return ( + "?" + + stringifyQs({ + ...queryString, + after: pageInfo.endCursor, + before: undefined + }) + ); + }, [pageInfo?.endCursor, newPageInfo?.hasNextPage, queryString]); + + const prevPageHref = useMemo(() => { + if (!newPageInfo?.hasPreviousPage || !pageInfo?.startCursor) { + return undefined; + } + return ( + "?" + + stringifyQs({ + ...queryString, + after: undefined, + before: pageInfo.startCursor + }) + ); + }, [pageInfo?.startCursor, newPageInfo?.hasPreviousPage, queryString]); + + return { + nextPageHref, + prevPageHref, + paginatorType: "link" as const, + ...newPageInfo + }; +} + export default usePaginator; + +export interface PaginatorContextValuesCommon { + hasNextPage?: boolean; + hasPreviousPage?: boolean; + endCursor?: string; + startCursor?: string; +} + +export type PaginatorContextValues = PaginatorContextValuesCommon & + ( + | { + paginatorType: "link"; + nextPageHref?: string; + prevPageHref?: string; + loadNextPage?: never; + loadPreviousPage?: never; + } + | { + paginatorType: "click"; + nextPageHref?: never; + prevPageHref?: never; + loadNextPage: () => void; + loadPreviousPage: () => void; + } + ); + +export const PaginatorContext = createContext( + null +); + +export const usePaginatorContext = () => { + const context = useContext(PaginatorContext); + + if (context === null) { + throw new Error( + "usePaginatorContext must be used within a PaginatorContext.Provider" + ); + } + + return context; +}; diff --git a/src/navigation/components/MenuList/MenuList.tsx b/src/navigation/components/MenuList/MenuList.tsx index 93d47d979..48efdedd6 100644 --- a/src/navigation/components/MenuList/MenuList.tsx +++ b/src/navigation/components/MenuList/MenuList.tsx @@ -12,7 +12,7 @@ import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { MenuFragment } from "@saleor/graphql"; import { DeleteIcon, makeStyles } from "@saleor/macaw-ui"; @@ -64,11 +64,8 @@ const MenuList: React.FC = props => { isChecked, menus, onDelete, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort, - pageInfo, selected, sort, toggle, @@ -121,16 +118,10 @@ const MenuList: React.FC = props => { - diff --git a/src/navigation/views/MenuList/MenuList.tsx b/src/navigation/views/MenuList/MenuList.tsx index 6a100775e..c7192b342 100644 --- a/src/navigation/views/MenuList/MenuList.tsx +++ b/src/navigation/views/MenuList/MenuList.tsx @@ -13,7 +13,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { buttonMessages, commonMessages } from "@saleor/intl"; import { getStringOrPlaceholder, maybe } from "@saleor/misc"; @@ -36,7 +37,6 @@ interface MenuListProps { const MenuList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -72,11 +72,11 @@ const MenuList: React.FC = ({ params }) => { variables: queryVariables }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.menus.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.menus.pageInfo), paginationState, - params - ); + queryString: params + }); const [menuCreate, menuCreateOpts] = useMenuCreateMutation({ onCompleted: data => { @@ -126,7 +126,7 @@ const MenuList: React.FC = ({ params }) => { const handleSort = createSortHandler(navigate, menuListUrl, params); return ( - <> + = ({ params }) => { }) ) } - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} onSort={handleSort} - pageInfo={pageInfo} isChecked={isSelected} selected={listElements.length} sort={getSortParams(params)} @@ -242,7 +239,7 @@ const MenuList: React.FC = ({ params }) => { /> - + ); }; export default MenuList; diff --git a/src/orders/components/OrderDraftList/OrderDraftList.tsx b/src/orders/components/OrderDraftList/OrderDraftList.tsx index 19143ed68..01987c368 100644 --- a/src/orders/components/OrderDraftList/OrderDraftList.tsx +++ b/src/orders/components/OrderDraftList/OrderDraftList.tsx @@ -6,7 +6,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { OrderDraftListQuery } from "@saleor/graphql"; import { makeStyles } from "@saleor/macaw-ui"; @@ -63,9 +63,6 @@ export const OrderDraftList: React.FC = props => { disabled, settings, orders, - pageInfo, - onPreviousPage, - onNextPage, onUpdateListSettings, onSort, isChecked, @@ -148,16 +145,10 @@ export const OrderDraftList: React.FC = props => { - diff --git a/src/orders/components/OrderList/OrderList.tsx b/src/orders/components/OrderList/OrderList.tsx index 6e1a08360..ee0cced25 100644 --- a/src/orders/components/OrderList/OrderList.tsx +++ b/src/orders/components/OrderList/OrderList.tsx @@ -11,7 +11,7 @@ import Money from "@saleor/components/Money"; import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { OrderListQuery } from "@saleor/graphql"; import { makeStyles, Pill } from "@saleor/macaw-ui"; @@ -82,9 +82,6 @@ export const OrderList: React.FC = props => { disabled, settings, orders, - pageInfo, - onPreviousPage, - onNextPage, onUpdateListSettings, onSort, sort @@ -183,16 +180,11 @@ export const OrderList: React.FC = props => { - diff --git a/src/orders/views/OrderDraftList/OrderDraftList.tsx b/src/orders/views/OrderDraftList/OrderDraftList.tsx index e4a9b9e0e..eefb70d62 100644 --- a/src/orders/views/OrderDraftList/OrderDraftList.tsx +++ b/src/orders/views/OrderDraftList/OrderDraftList.tsx @@ -18,7 +18,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; import { maybe } from "@saleor/misc"; @@ -57,7 +58,6 @@ interface OrderDraftListProps { export const OrderDraftList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -165,11 +165,11 @@ export const OrderDraftList: React.FC = ({ params }) => { variables: queryVariables }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.draftOrders.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.draftOrders.pageInfo), paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, orderDraftListUrl, params); @@ -181,7 +181,7 @@ export const OrderDraftList: React.FC = ({ params }) => { }); return ( - <> + = ({ params }) => { disabled={loading} settings={settings} orders={mapEdgesToItems(data?.draftOrders)} - pageInfo={pageInfo} onAdd={() => openModal("create-order")} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSort={handleSort} onUpdateListSettings={updateListSettings} isChecked={isSelected} @@ -273,7 +270,7 @@ export const OrderDraftList: React.FC = ({ params }) => { }) } /> - + ); }; diff --git a/src/orders/views/OrderList/OrderList.tsx b/src/orders/views/OrderList/OrderList.tsx index 9d27ee41d..d7ddce914 100644 --- a/src/orders/views/OrderList/OrderList.tsx +++ b/src/orders/views/OrderList/OrderList.tsx @@ -14,7 +14,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { getStringOrPlaceholder } from "@saleor/misc"; import { ListViews } from "@saleor/types"; @@ -53,7 +54,6 @@ interface OrderListProps { export const OrderList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { updateListSettings, settings } = useListSettings( ListViews.ORDER_LIST ); @@ -140,16 +140,16 @@ export const OrderList: React.FC = ({ params }) => { variables: queryVariables }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - data?.orders?.pageInfo, + const paginationValues = usePaginator({ + pageInfo: data?.orders?.pageInfo, paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, orderListUrl, params); return ( - <> + = ({ params }) => { filterOpts={getFilterOpts(params, channelOpts)} limits={limitOpts.data?.shop.limits} orders={mapEdgesToItems(data?.orders)} - pageInfo={pageInfo} sort={getSortParams(params)} onAdd={() => openModal("create-order")} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} onSort={handleSort} onSearchChange={handleSearchChange} @@ -203,7 +200,7 @@ export const OrderList: React.FC = ({ params }) => { } /> )} - + ); }; diff --git a/src/pageTypes/components/PageTypeList/PageTypeList.tsx b/src/pageTypes/components/PageTypeList/PageTypeList.tsx index 533f58e57..087629311 100644 --- a/src/pageTypes/components/PageTypeList/PageTypeList.tsx +++ b/src/pageTypes/components/PageTypeList/PageTypeList.tsx @@ -4,7 +4,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { PageTypeFragment } from "@saleor/graphql"; import { makeStyles } from "@saleor/macaw-ui"; @@ -39,9 +39,6 @@ const PageTypeList: React.FC = props => { const { disabled, pageTypes, - pageInfo, - onNextPage, - onPreviousPage, onSort, isChecked, selected, @@ -82,14 +79,9 @@ const PageTypeList: React.FC = props => { - diff --git a/src/pageTypes/components/PageTypeListPage/PageTypeListPage.stories.tsx b/src/pageTypes/components/PageTypeListPage/PageTypeListPage.stories.tsx index 9900b7aa5..f18a46d25 100644 --- a/src/pageTypes/components/PageTypeListPage/PageTypeListPage.stories.tsx +++ b/src/pageTypes/components/PageTypeListPage/PageTypeListPage.stories.tsx @@ -1,4 +1,5 @@ import { PageTypeListUrlSortField } from "@saleor/pageTypes/urls"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -28,6 +29,7 @@ const props: PageTypeListPageProps = { storiesOf("Views / Page types / Page types list", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("default", () => ) .add("loading", () => ( diff --git a/src/pageTypes/views/PageTypeList/PageTypeList.tsx b/src/pageTypes/views/PageTypeList/PageTypeList.tsx index cbd25b3d4..05b4fbed5 100644 --- a/src/pageTypes/views/PageTypeList/PageTypeList.tsx +++ b/src/pageTypes/views/PageTypeList/PageTypeList.tsx @@ -13,7 +13,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -50,7 +51,6 @@ interface PageTypeListProps { export const PageTypeList: React.FC = ({ params }) => { const navigate = useNavigator(); - const paginate = usePaginator(); const notify = useNotifier(); const { isSelected, @@ -119,11 +119,11 @@ export const PageTypeList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - data?.pageTypes?.pageInfo, + const paginationValues = usePaginator({ + pageInfo: data?.pageTypes?.pageInfo, paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, pageTypeListUrl, params); @@ -165,7 +165,7 @@ export const PageTypeList: React.FC = ({ params }) => { const pageTypesData = mapEdgesToItems(data?.pageTypes); return ( - <> + = ({ params }) => { tabs={tabs.map(tab => tab.name)} disabled={loading} pageTypes={pageTypesData} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSort={handleSort} isChecked={isSelected} selected={selectedPageTypes.length} @@ -224,7 +221,7 @@ export const PageTypeList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={getStringOrPlaceholder(tabs[currentTab - 1]?.name)} /> - + ); }; PageTypeList.displayName = "PageTypeList"; diff --git a/src/pages/components/PageList/PageList.tsx b/src/pages/components/PageList/PageList.tsx index a8c85b87c..9900f8ab9 100644 --- a/src/pages/components/PageList/PageList.tsx +++ b/src/pages/components/PageList/PageList.tsx @@ -10,7 +10,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { PageFragment } from "@saleor/graphql"; import { makeStyles, Pill } from "@saleor/macaw-ui"; @@ -58,11 +58,8 @@ const PageList: React.FC = props => { settings, pages, disabled, - onNextPage, - pageInfo, onSort, onUpdateListSettings, - onPreviousPage, isChecked, selected, sort, @@ -136,16 +133,11 @@ const PageList: React.FC = props => { - diff --git a/src/pages/views/PageList/PageList.tsx b/src/pages/views/PageList/PageList.tsx index 22e530af2..7cd0ac807 100644 --- a/src/pages/views/PageList/PageList.tsx +++ b/src/pages/views/PageList/PageList.tsx @@ -12,7 +12,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; import { maybe } from "@saleor/misc"; @@ -39,7 +40,6 @@ interface PageListProps { export const PageList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); @@ -65,11 +65,11 @@ export const PageList: React.FC = ({ params }) => { variables: queryVariables }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.pages.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.pages.pageInfo), paginationState, - params - ); + queryString: params + }); const [openModal, closeModal] = createDialogActionHandlers< PageListUrlDialog, @@ -115,14 +115,11 @@ export const PageList: React.FC = ({ params }) => { const handleSort = createSortHandler(navigate, pageListUrl, params); return ( - <> + = ({ params }) => { }} /> - + ); }; diff --git a/src/permissionGroups/components/PermissionGroupList/PermissionGroupList.tsx b/src/permissionGroups/components/PermissionGroupList/PermissionGroupList.tsx index 140586965..7fddba57b 100644 --- a/src/permissionGroups/components/PermissionGroupList/PermissionGroupList.tsx +++ b/src/permissionGroups/components/PermissionGroupList/PermissionGroupList.tsx @@ -9,7 +9,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableCellHeader from "@saleor/components/TableCellHeader"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { PermissionGroupFragment } from "@saleor/graphql"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; @@ -65,16 +65,7 @@ interface PermissionGroupListProps } const PermissionGroupList: React.FC = props => { - const { - disabled, - permissionGroups, - pageInfo, - onDelete, - onNextPage, - onPreviousPage, - onSort, - sort - } = props; + const { disabled, permissionGroups, onDelete, onSort, sort } = props; const classes = useStyles(props); return ( @@ -107,14 +98,9 @@ const PermissionGroupList: React.FC = props => { - diff --git a/src/permissionGroups/components/PermissionGroupListPage/PermissionGroupListPage.stories.tsx b/src/permissionGroups/components/PermissionGroupListPage/PermissionGroupListPage.stories.tsx index d2f096f16..37a773007 100644 --- a/src/permissionGroups/components/PermissionGroupListPage/PermissionGroupListPage.stories.tsx +++ b/src/permissionGroups/components/PermissionGroupListPage/PermissionGroupListPage.stories.tsx @@ -9,6 +9,7 @@ import PermissionGroupListPage, { import { permissionGroups } from "@saleor/permissionGroups/fixtures"; import { PermissionGroupListUrlSortField } from "@saleor/permissionGroups/urls"; import Decorator from "@saleor/storybook/Decorator"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -27,6 +28,7 @@ const props: PermissionGroupListPageProps = { storiesOf("Views / Permission Groups / Permission Group List", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("default", () => ) .add("loading", () => ( = ({ params }) => { const navigate = useNavigator(); - const paginate = usePaginator(); const notify = useNotifier(); const intl = useIntl(); const { updateListSettings, settings } = useListSettings( @@ -58,11 +58,11 @@ export const PermissionGroupList: React.FC = ({ variables: queryVariables }); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - data?.permissionGroups.pageInfo, + const paginationValues = usePaginator({ + pageInfo: data?.permissionGroups.pageInfo, paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler( navigate, @@ -100,16 +100,13 @@ export const PermissionGroupList: React.FC = ({ }); return ( - <> + openModal("remove", { id })} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} onSort={handleSort} /> @@ -129,7 +126,7 @@ export const PermissionGroupList: React.FC = ({ open={params.action === "remove"} onClose={closeModal} /> - + ); }; diff --git a/src/plugins/components/PluginsList/PluginsList.tsx b/src/plugins/components/PluginsList/PluginsList.tsx index 2130fc0a9..aa7c26359 100644 --- a/src/plugins/components/PluginsList/PluginsList.tsx +++ b/src/plugins/components/PluginsList/PluginsList.tsx @@ -1,7 +1,7 @@ import { TableBody, TableCell, TableFooter, TableRow } from "@material-ui/core"; import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import { PluginBaseFragment } from "@saleor/graphql"; import useNavigator from "@saleor/hooks/useNavigator"; import { EditIcon, makeStyles } from "@saleor/macaw-ui"; @@ -37,12 +37,9 @@ const PluginList: React.FC = props => { settings, plugins, disabled, - onNextPage, - pageInfo, sort, onSort, - onUpdateListSettings, - onPreviousPage + onUpdateListSettings } = props; const classes = useStyles(props); const navigate = useNavigator(); @@ -53,16 +50,11 @@ const PluginList: React.FC = props => { - diff --git a/src/plugins/views/PluginList/PluginList.tsx b/src/plugins/views/PluginList/PluginList.tsx index 650851844..eab05d0f7 100644 --- a/src/plugins/views/PluginList/PluginList.tsx +++ b/src/plugins/views/PluginList/PluginList.tsx @@ -8,7 +8,8 @@ import useListSettings from "@saleor/hooks/useListSettings"; import useNavigator from "@saleor/hooks/useNavigator"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { maybe } from "@saleor/misc"; import { ListViews } from "@saleor/types"; @@ -43,7 +44,6 @@ interface PluginsListProps { export const PluginsList: React.FC = ({ params }) => { const navigate = useNavigator(); - const paginate = usePaginator(); const { updateListSettings, settings } = useListSettings( ListViews.PLUGINS_LIST ); @@ -103,11 +103,11 @@ export const PluginsList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.plugins.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.plugins.pageInfo), paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, pluginListUrl, params); const channelsSearchWithLoadMoreProps = useChannelsSearchWithLoadMore(); @@ -115,7 +115,7 @@ export const PluginsList: React.FC = ({ params }) => { const filterOpts = getFilterOpts(params, channelsSearchWithLoadMoreProps); return ( - <> + = ({ params }) => { initialSearch={params.query || ""} settings={settings} plugins={mapEdgesToItems(data?.plugins)} - pageInfo={pageInfo} sort={getSortParams(params)} tabs={getFilterTabs().map(tab => tab.name)} onAll={resetFilters} onFilterChange={changeFilters} onSearchChange={handleSearchChange} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSort={handleSort} onTabSave={() => openModal("save-search")} onTabDelete={() => openModal("delete-search")} @@ -150,7 +147,7 @@ export const PluginsList: React.FC = ({ params }) => { onSubmit={handleFilterTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; diff --git a/src/productTypes/components/ProductTypeList/ProductTypeList.tsx b/src/productTypes/components/ProductTypeList/ProductTypeList.tsx index bf48d49d8..dde9addb9 100644 --- a/src/productTypes/components/ProductTypeList/ProductTypeList.tsx +++ b/src/productTypes/components/ProductTypeList/ProductTypeList.tsx @@ -10,7 +10,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { ProductTypeFragment } from "@saleor/graphql"; import { makeStyles } from "@saleor/macaw-ui"; @@ -61,9 +61,6 @@ const ProductTypeList: React.FC = props => { const { disabled, productTypes, - pageInfo, - onNextPage, - onPreviousPage, onSort, isChecked, selected, @@ -127,15 +124,7 @@ const ProductTypeList: React.FC = props => { - + diff --git a/src/productTypes/views/ProductTypeList/ProductTypeList.tsx b/src/productTypes/views/ProductTypeList/ProductTypeList.tsx index 5bb8ab090..3bc6bf060 100644 --- a/src/productTypes/views/ProductTypeList/ProductTypeList.tsx +++ b/src/productTypes/views/ProductTypeList/ProductTypeList.tsx @@ -12,7 +12,8 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { usePaginationReset } from "@saleor/hooks/usePaginationReset"; import usePaginator, { - createPaginationState + createPaginationState, + PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; @@ -53,7 +54,6 @@ interface ProductTypeListProps { export const ProductTypeList: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { isSelected, listElements: selectedProductTypes, @@ -123,11 +123,11 @@ export const ProductTypeList: React.FC = ({ params }) => { handleTabChange(tabs.length + 1); }; - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - maybe(() => data.productTypes.pageInfo), + const paginationValues = usePaginator({ + pageInfo: maybe(() => data.productTypes.pageInfo), paginationState, - params - ); + queryString: params + }); const handleSort = createSortHandler(navigate, productTypeListUrl, params); @@ -169,7 +169,7 @@ export const ProductTypeList: React.FC = ({ params }) => { }); return ( - <> + = ({ params }) => { tabs={tabs.map(tab => tab.name)} disabled={loading} productTypes={productTypesData} - pageInfo={pageInfo} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onSort={handleSort} isChecked={isSelected} selected={selectedProductTypes.length} @@ -229,7 +226,7 @@ export const ProductTypeList: React.FC = ({ params }) => { onSubmit={handleTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; ProductTypeList.displayName = "ProductTypeList"; diff --git a/src/products/components/ProductList/ProductList.tsx b/src/products/components/ProductList/ProductList.tsx index 6e1949ec2..eb1f48685 100644 --- a/src/products/components/ProductList/ProductList.tsx +++ b/src/products/components/ProductList/ProductList.tsx @@ -19,7 +19,7 @@ import TableCellAvatar from "@saleor/components/TableCellAvatar"; import { AVATAR_MARGIN } from "@saleor/components/TableCellAvatar/Avatar"; import TableCellHeader from "@saleor/components/TableCellHeader"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import TooltipTableCellHeader from "@saleor/components/TooltipTableCellHeader"; import { commonTooltipMessages } from "@saleor/components/TooltipTableCellHeader/messages"; @@ -137,15 +137,12 @@ export const ProductList: React.FC = props => { disabled, isChecked, gridAttributes, - pageInfo, products, selected, sort, toggle, toggleAll, toolbar, - onNextPage, - onPreviousPage, onUpdateListSettings, onSort, selectedChannelId, @@ -323,16 +320,10 @@ export const ProductList: React.FC = props => { - diff --git a/src/products/components/ProductList/ProductListAttribute.stories.tsx b/src/products/components/ProductList/ProductListAttribute.stories.tsx index 8b0cd0db0..1432726cc 100644 --- a/src/products/components/ProductList/ProductListAttribute.stories.tsx +++ b/src/products/components/ProductList/ProductListAttribute.stories.tsx @@ -1,5 +1,6 @@ import { ProductListAttributeFragment } from "@saleor/graphql"; import Decorator from "@saleor/storybook/Decorator"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -85,6 +86,7 @@ const attributes: ProductListAttributeFragment[] = [ storiesOf("Views / Products / Product list / Attribute display", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("default", () => ( = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); - const paginate = usePaginator(); const { queue } = useBackgroundTask(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids @@ -341,14 +341,14 @@ export const ProductList: React.FC = ({ params }) => { channelOpts ); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( - data?.products?.pageInfo, + const paginationValues = usePaginator({ + pageInfo: data?.products?.pageInfo, paginationState, - params - ); + queryString: params + }); return ( - <> + = ({ params }) => { products={mapEdgesToItems(data?.products)} onColumnQueryChange={availableInGridAttributesOpts.search} onFetchMore={availableInGridAttributesOpts.loadMore} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} onUpdateListSettings={updateListSettings} - pageInfo={pageInfo} onAll={resetFilters} toolbar={ = ({ params }) => { onSubmit={handleFilterTabDelete} tabName={maybe(() => tabs[currentTab - 1].name, "...")} /> - + ); }; export default ProductList; diff --git a/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.stories.tsx b/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.stories.tsx index d37445ea0..5f2f5a8f0 100644 --- a/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.stories.tsx +++ b/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.stories.tsx @@ -1,5 +1,6 @@ import { shippingZone } from "@saleor/shipping/fixtures"; import Decorator from "@saleor/storybook//Decorator"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { mapEdgesToItems } from "@saleor/utils/maps"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -15,14 +16,8 @@ const products = mapEdgesToItems( const props: ShippingMethodProductsProps = { disabled: false, isChecked: () => undefined, - onNextPage: () => undefined, - onPreviousPage: () => undefined, onProductAssign: () => undefined, onProductUnassign: () => undefined, - pageInfo: { - hasNextPage: false, - hasPreviousPage: false - }, products, selected: products.length, toggle: () => undefined, @@ -32,4 +27,5 @@ const props: ShippingMethodProductsProps = { storiesOf("Shipping / ShippingMethodProducts", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("default", () => ); diff --git a/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.tsx b/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.tsx index e6d469082..2d320630e 100644 --- a/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.tsx +++ b/src/shipping/components/ShippingMethodProducts/ShippingMethodProducts.tsx @@ -13,7 +13,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import TableCellAvatar from "@saleor/components/TableCellAvatar"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import { ShippingZoneQuery } from "@saleor/graphql"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; import { renderCollection } from "@saleor/misc"; @@ -58,10 +58,7 @@ const numberOfColumns = 3; const ShippingMethodProducts: React.FC = props => { const { disabled, - pageInfo, products, - onNextPage, - onPreviousPage, onProductAssign, onProductUnassign, isChecked, @@ -112,16 +109,9 @@ const ShippingMethodProducts: React.FC = props => { - diff --git a/src/shipping/components/ShippingZoneRatesPage/ShippingZoneRatesPage.stories.tsx b/src/shipping/components/ShippingZoneRatesPage/ShippingZoneRatesPage.stories.tsx index bd9d81e79..c07d696f4 100644 --- a/src/shipping/components/ShippingZoneRatesPage/ShippingZoneRatesPage.stories.tsx +++ b/src/shipping/components/ShippingZoneRatesPage/ShippingZoneRatesPage.stories.tsx @@ -1,6 +1,7 @@ import { ShippingMethodTypeEnum } from "@saleor/graphql"; import { shippingZone } from "@saleor/shipping/fixtures"; import Decorator from "@saleor/storybook//Decorator"; +import { PaginatorContextDecorator } from "@saleor/storybook/PaginatorContextDecorator"; import { storiesOf } from "@storybook/react"; import React from "react"; @@ -47,11 +48,9 @@ const props: ShippingZoneRatesPageProps = { isChecked: () => undefined, onChannelsChange: () => undefined, onDelete: () => undefined, - onNextPage: () => undefined, onPostalCodeAssign: () => undefined, onPostalCodeInclusionChange: () => undefined, onPostalCodeUnassign: () => undefined, - onPreviousPage: () => undefined, onProductAssign: () => undefined, onProductUnassign: () => undefined, onSubmit: () => undefined, @@ -70,6 +69,7 @@ const props: ShippingZoneRatesPageProps = { storiesOf("Views / Shipping / Shipping rate", module) .addDecorator(Decorator) + .addDecorator(PaginatorContextDecorator) .add("create price rate", () => ) .add("create weight rate", () => ( diff --git a/src/shipping/components/ShippingZonesList/ShippingZonesList.tsx b/src/shipping/components/ShippingZonesList/ShippingZonesList.tsx index 7faa58788..6b3f4c594 100644 --- a/src/shipping/components/ShippingZonesList/ShippingZonesList.tsx +++ b/src/shipping/components/ShippingZonesList/ShippingZonesList.tsx @@ -12,7 +12,7 @@ import ResponsiveTable from "@saleor/components/ResponsiveTable"; import Skeleton from "@saleor/components/Skeleton"; import { TableButtonWrapper } from "@saleor/components/TableButtonWrapper/TableButtonWrapper"; import TableHead from "@saleor/components/TableHead"; -import TablePagination from "@saleor/components/TablePagination"; +import { TablePaginationWithContext } from "@saleor/components/TablePagination"; import TableRowLink from "@saleor/components/TableRowLink"; import { ShippingZoneFragment } from "@saleor/graphql"; import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; @@ -54,11 +54,8 @@ const ShippingZonesList: React.FC = props => { const { disabled, settings, - onNextPage, - onPreviousPage, onRemove, onUpdateListSettings, - pageInfo, shippingZones, isChecked, selected, @@ -118,16 +115,11 @@ const ShippingZonesList: React.FC = props => { - diff --git a/src/shipping/views/RateUpdate.tsx b/src/shipping/views/RateUpdate.tsx index f89153eeb..b9a043554 100644 --- a/src/shipping/views/RateUpdate.tsx +++ b/src/shipping/views/RateUpdate.tsx @@ -25,6 +25,7 @@ import useLocalPaginator, { } from "@saleor/hooks/useLocalPaginator"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; +import { PaginatorContext } from "@saleor/hooks/usePaginator"; import { commonMessages, sectionNames } from "@saleor/intl"; import { getById, @@ -107,7 +108,7 @@ export const RateUpdate: React.FC = ({ [] ); - const { loadNextPage, loadPreviousPage, pageInfo } = paginate( + const { pageInfo, ...paginationValues } = paginate( rate?.excludedProducts.pageInfo, paginationState ); @@ -314,7 +315,7 @@ export const RateUpdate: React.FC = ({ }; return ( - <> + {!!allChannels?.length && ( = ({ selected={listElements.length} toggle={toggle} toggleAll={toggleAll} - onNextPage={loadNextPage} - onPreviousPage={loadPreviousPage} - pageInfo={pageInfo} toolbar={ @@ -1889,14 +1918,18 @@ exports[`Storyshots Attributes / Attributes selected 1`] = ` >