From 78dbc0a684272be66e72cbd70fdcbd48b20d1c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Fern=C3=A1ndez=20de=20Alba?= Date: Thu, 13 Apr 2023 17:10:32 +0200 Subject: [PATCH] Revert "Add current page parameter to the route in the listing and search block pagination (#4159)" This reverts commit c40e772701e4f6771a541898621457ec45500859. --- .../Blocks/Listing/ListingBody.test.jsx | 20 --- .../Blocks/Listing/withQuerystringResults.jsx | 3 +- .../manage/Blocks/Search/hocs/withSearch.jsx | 12 +- src/helpers/Utils/usePagination.js | 62 +++------- src/helpers/Utils/usePagination.test.js | 115 ------------------ 5 files changed, 20 insertions(+), 192 deletions(-) delete mode 100644 src/helpers/Utils/usePagination.test.js diff --git a/src/components/manage/Blocks/Listing/ListingBody.test.jsx b/src/components/manage/Blocks/Listing/ListingBody.test.jsx index 8a5c359972..d52c7df814 100644 --- a/src/components/manage/Blocks/Listing/ListingBody.test.jsx +++ b/src/components/manage/Blocks/Listing/ListingBody.test.jsx @@ -36,26 +36,6 @@ test('renders a ListingBody component', () => { content: { data: { is_folderish: true, - blocks: { - '839ee00b-013b-4f4a-9b10-8867938fdac3': { - '@type': 'listing', - block: '839ee00b-013b-4f4a-9b10-8867938fdac3', - headlineTag: 'h2', - query: [], - querystring: { - b_size: '2', - query: [ - { - i: 'path', - o: 'plone.app.querystring.operation.string.absolutePath', - v: '/', - }, - ], - sort_order: 'ascending', - }, - variation: 'default', - }, - }, }, }, intl: { diff --git a/src/components/manage/Blocks/Listing/withQuerystringResults.jsx b/src/components/manage/Blocks/Listing/withQuerystringResults.jsx index c550cf93cb..d675fc050a 100644 --- a/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +++ b/src/components/manage/Blocks/Listing/withQuerystringResults.jsx @@ -25,7 +25,7 @@ export default function withQuerystringResults(WrappedComponent) { const [initialPath] = React.useState(getBaseUrl(path)); const copyFields = ['limit', 'query', 'sort_on', 'sort_order', 'depth']; - const { currentPage, setCurrentPage } = usePagination(data.block, 1); + const adaptedQuery = Object.assign( variation?.fullobjects ? { fullobjects: 1 } : { metadata_fields: '_all' }, { @@ -37,6 +37,7 @@ export default function withQuerystringResults(WrappedComponent) { : {}, ), ); + const { currentPage, setCurrentPage } = usePagination(querystring, 1); const querystringResults = useSelector( (state) => state.querystringsearch.subrequests, ); diff --git a/src/components/manage/Blocks/Search/hocs/withSearch.jsx b/src/components/manage/Blocks/Search/hocs/withSearch.jsx index fd1842fbc1..5177dd6304 100644 --- a/src/components/manage/Blocks/Search/hocs/withSearch.jsx +++ b/src/components/manage/Blocks/Search/hocs/withSearch.jsx @@ -144,16 +144,12 @@ const getSearchFields = (searchData) => { }; /** - * A hook that will mirror the search block state to a hash location + * A HOC that will mirror the search block state to a hash location */ const useHashState = () => { const location = useLocation(); const history = useHistory(); - /** - * Required to maintain parameter compatibility. - With this we will maintain support for receiving hash (#) and search (?) type parameters. - */ const oldState = React.useMemo(() => { return { ...qs.parse(location.search), @@ -169,7 +165,7 @@ const useHashState = () => { const setSearchData = React.useCallback( (searchData) => { - const newParams = qs.parse(location.search); + const newParams = qs.parse(location.hash); let changed = false; @@ -186,11 +182,11 @@ const useHashState = () => { if (changed) { history.push({ - search: qs.stringify(newParams), + hash: qs.stringify(newParams), }); } }, - [history, oldState, location.search], + [history, oldState, location.hash], ); return [current, setSearchData]; diff --git a/src/helpers/Utils/usePagination.js b/src/helpers/Utils/usePagination.js index dc984e9932..acb12d2ac5 100644 --- a/src/helpers/Utils/usePagination.js +++ b/src/helpers/Utils/usePagination.js @@ -1,59 +1,25 @@ -import React, { useRef, useEffect } from 'react'; -import { useHistory, useLocation } from 'react-router-dom'; -import qs from 'query-string'; -import { useSelector } from 'react-redux'; -import { slugify } from '@plone/volto/helpers/Utils/Utils'; - -/** - * @function useCreatePageQueryStringKey - * @description A hook that creates a key with an id if there are multiple blocks with pagination. - * @returns {string} Example: page || page_012345678 - */ -const useCreatePageQueryStringKey = (id) => { - const blockTypesWithPagination = ['search', 'listing']; - const blocks = useSelector((state) => state?.content?.data?.blocks) || []; - const blocksLayout = - useSelector((state) => state?.content?.data?.blocks_layout?.items) || []; - const displayedBlocks = blocksLayout?.map((item) => blocks[item]); - const hasMultiplePaginations = - displayedBlocks.filter((item) => - blockTypesWithPagination.includes(item['@type']), - ).length > 1 || false; - - return hasMultiplePaginations ? slugify(`page-${id}`) : 'page'; -}; +import React from 'react'; +import { isEqual } from 'lodash'; +import { usePrevious } from './usePrevious'; +import useDeepCompareEffect from 'use-deep-compare-effect'; /** * A pagination helper that tracks the query and resets pagination in case the * query changes. */ -export const usePagination = (id = null, defaultPage = 1) => { - const location = useLocation(); - const history = useHistory(); - const pageQueryStringKey = useCreatePageQueryStringKey(id); - const pageQueryParam = - qs.parse(location.search)[pageQueryStringKey] || defaultPage; - const [currentPage, setCurrentPage] = React.useState( - parseInt(pageQueryParam), - ); - const queryRef = useRef(qs.parse(location.search)?.query); +export const usePagination = (query, defaultPage = 1) => { + const previousQuery = usePrevious(query); + const [currentPage, setCurrentPage] = React.useState(defaultPage); - useEffect(() => { - if (queryRef.current !== qs.parse(location.search)?.query) { - setCurrentPage(defaultPage); - queryRef.current = qs.parse(location.search)?.query; - } - const newParams = { - ...qs.parse(location.search), - [pageQueryStringKey]: currentPage, - }; - history.replace({ - search: qs.stringify(newParams), - }); - }, [currentPage, defaultPage, location.search, history, pageQueryStringKey]); + useDeepCompareEffect(() => { + setCurrentPage(defaultPage); + }, [query, previousQuery, defaultPage]); return { - currentPage, + currentPage: + previousQuery && !isEqual(previousQuery, query) + ? defaultPage + : currentPage, setCurrentPage, }; }; diff --git a/src/helpers/Utils/usePagination.test.js b/src/helpers/Utils/usePagination.test.js deleted file mode 100644 index 26924d78a0..0000000000 --- a/src/helpers/Utils/usePagination.test.js +++ /dev/null @@ -1,115 +0,0 @@ -import { renderHook } from '@testing-library/react-hooks'; -import { usePagination } from './usePagination'; -import * as redux from 'react-redux'; -import routeData from 'react-router'; -import { slugify } from '@plone/volto/helpers/Utils/Utils'; - -const searchBlockId = '545b33de-92cf-4747-969d-68851837b317'; -const searchBlockId2 = '454b33de-92cf-4747-969d-68851837b713'; -const searchBlock = { - '@type': 'search', - query: { - b_size: '4', - query: [ - { - i: 'path', - o: 'plone.app.querystring.operation.string.relativePath', - v: '', - }, - ], - sort_order: 'ascending', - }, - showSearchInput: true, - showTotalResults: true, -}; -let state = { - content: { - data: { - blocks: { - [searchBlockId]: searchBlock, - }, - blocks_layout: { - items: [searchBlockId], - }, - }, - }, -}; - -let mockUseLocationValue = { - pathname: '/testroute', - search: '', -}; - -const setUp = (searchParam, numberOfSearches) => { - mockUseLocationValue.search = searchParam; - if (numberOfSearches > 1) { - state.content.data.blocks[searchBlockId2] = searchBlock; - state.content.data.blocks_layout.items.push(searchBlockId2); - } - return renderHook(({ id, defaultPage }) => usePagination(id, defaultPage), { - initialProps: { - id: searchBlockId, - defaultPage: 1, - }, - }); -}; - -describe(`Tests for usePagination, for the block ${searchBlockId}`, () => { - const useLocation = jest.spyOn(routeData, 'useLocation'); - const useHistory = jest.spyOn(routeData, 'useHistory'); - const useSelector = jest.spyOn(redux, 'useSelector'); - beforeEach(() => { - useLocation.mockReturnValue(mockUseLocationValue); - useHistory.mockReturnValue({ replace: jest.fn() }); - useSelector.mockImplementation((cb) => cb(state)); - }); - - it('1 paginated block with id and defaultPage 1 - shoud be 1', () => { - const { result } = setUp(); - expect(result.current.currentPage).toBe(1); - }); - - it('1 paginated block without params - shoud be 1', () => { - const { result } = setUp(); - expect(result.current.currentPage).toBe(1); - }); - - const param1 = '?page=2'; - it(`1 paginated block with params: ${param1} - shoud be 2`, () => { - const { result } = setUp(param1); - expect(result.current.currentPage).toBe(2); - }); - - const param2 = `?${slugify(`page-${searchBlockId}`)}=2`; - it(`2 paginated blocks with current block in the params: ${param2} - shoud be 2`, () => { - const { result } = setUp(param2, 2); - expect(result.current.currentPage).toBe(2); - }); - - const param3 = `?${slugify(`page-${searchBlockId2}`)}=2`; - it(`2 paginated blocks with the other block in the params: ${param3} - shoud be 1`, () => { - const { result } = setUp(param3, 2); - expect(result.current.currentPage).toBe(1); - }); - - const param4 = `?${slugify(`page-${searchBlockId}`)}=2&${slugify( - `page-${searchBlockId2}`, - )}=1`; - it(`2 paginated blocks with both blocks in the params, current 2: ${param4} - shoud be 2`, () => { - const { result } = setUp(param4, 2); - expect(result.current.currentPage).toBe(2); - }); - - const param5 = `?${slugify(`page-${searchBlockId}`)}=1&${slugify( - `page-${searchBlockId2}`, - )}=2`; - it(`2 paginated blocks with both blocks in the params, current 1: ${param5} - shoud be 1`, () => { - const { result } = setUp(param5, 2); - expect(result.current.currentPage).toBe(1); - }); - - it(`2 paginated blocks with wrong page param: ${param1} - shoud be 1`, () => { - const { result } = setUp(param1, 2); - expect(result.current.currentPage).toBe(1); - }); -});