From 511a6677d2b8b163b8b97e85f97535ef3a763845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Fern=C3=A1ndez=20de=20Alba?= Date: Tue, 18 Jul 2023 15:37:52 +0200 Subject: [PATCH] Fix the condition deciding on listing pagination format so it takes into account container blocks as well (#4978) --- news/4978.bugfix | 1 + src/config/index.js | 1 + src/helpers/Blocks/Blocks.js | 22 +++++++++++++++++ src/helpers/Blocks/Blocks.test.js | 38 ++++++++++++++++++++++++++++++ src/helpers/Utils/usePagination.js | 9 ++----- src/helpers/index.js | 3 +++ test-setup-config.js | 1 + 7 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 news/4978.bugfix diff --git a/news/4978.bugfix b/news/4978.bugfix new file mode 100644 index 0000000000..5e4e82448f --- /dev/null +++ b/news/4978.bugfix @@ -0,0 +1 @@ +Fix the condition deciding on listing pagination format so it takes into account container blocks as well @sneridagh diff --git a/src/config/index.js b/src/config/index.js index b438841fee..99501a1ede 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -185,6 +185,7 @@ let config = { querystringSearchGet: false, blockSettingsTabFieldsetsInitialStateOpen: true, excludeLinksAndReferencesMenuItem: true, + containerBlockTypes: [], }, experimental: { addBlockButton: { diff --git a/src/helpers/Blocks/Blocks.js b/src/helpers/Blocks/Blocks.js index e87e6adc47..2fc4b439b6 100644 --- a/src/helpers/Blocks/Blocks.js +++ b/src/helpers/Blocks/Blocks.js @@ -533,3 +533,25 @@ export const getPreviousNextBlock = ({ content, block }) => { return [previousBlock, nextBlock]; }; + +/** + * Given a `block` object and a list of block types, return a list of block ids matching the types + * + * @function findBlocks + * @param {Object} types A list with the list of types to be matched + * @return {Array} An array of block ids + */ +export function findBlocks(blocks, types, result = []) { + const containerBlockTypes = config.settings.containerBlockTypes; + + Object.keys(blocks).forEach((blockId) => { + const block = blocks[blockId]; + if (types.includes(block['@type'])) { + result.push(blockId); + } else if (containerBlockTypes.includes(block['@type']) || block.blocks) { + findBlocks(block.blocks, types, result); + } + }); + + return result; +} diff --git a/src/helpers/Blocks/Blocks.test.js b/src/helpers/Blocks/Blocks.test.js index 68f866c14e..84abfb0b28 100644 --- a/src/helpers/Blocks/Blocks.test.js +++ b/src/helpers/Blocks/Blocks.test.js @@ -19,6 +19,8 @@ import { buildStyleClassNamesFromData, buildStyleClassNamesExtenders, getPreviousNextBlock, + blocksFormGenerator, + findBlocks, } from './Blocks'; import config from '@plone/volto/registry'; @@ -1226,3 +1228,39 @@ describe('Blocks', () => { }); }); }); + +describe('findBlocks', () => { + it('Get all blocks in the first level (main block container)', () => { + const blocks = { + '1': { title: 'title', '@type': 'title' }, + '2': { title: 'an image', '@type': 'image' }, + '3': { title: 'description', '@type': 'description' }, + '4': { title: 'a text', '@type': 'slate' }, + }; + const types = ['description']; + expect(findBlocks(blocks, types)).toStrictEqual(['3']); + }); + + it('Get all blocks in the first level (main block container) given a list', () => { + const blocks = { + '1': { title: 'title', '@type': 'title' }, + '2': { title: 'an image', '@type': 'image' }, + '3': { title: 'description', '@type': 'description' }, + '4': { title: 'a text', '@type': 'slate' }, + }; + const types = ['description', 'slate']; + expect(findBlocks(blocks, types)).toStrictEqual(['3', '4']); + }); + + it('Get all blocks in the first level (main block container) given a list', () => { + const blocks = { + '1': { title: 'title', '@type': 'title' }, + '2': { title: 'an image', '@type': 'image' }, + '3': { title: 'description', '@type': 'description' }, + '4': { title: 'a text', '@type': 'slate' }, + '5': { title: 'a text', '@type': 'slate' }, + }; + const types = ['description', 'slate']; + expect(findBlocks(blocks, types)).toStrictEqual(['3', '4', '5']); + }); +}); diff --git a/src/helpers/Utils/usePagination.js b/src/helpers/Utils/usePagination.js index 083ec48682..674b072bde 100644 --- a/src/helpers/Utils/usePagination.js +++ b/src/helpers/Utils/usePagination.js @@ -2,7 +2,7 @@ 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'; +import { findBlocks, slugify } from '@plone/volto/helpers'; /** * @function useCreatePageQueryStringKey @@ -12,13 +12,8 @@ import { slugify } from '@plone/volto/helpers/Utils/Utils'; 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; + findBlocks(blocks, blockTypesWithPagination).length > 1; return hasMultiplePaginations ? slugify(`page-${id}`) : 'page'; }; diff --git a/src/helpers/index.js b/src/helpers/index.js index ef59a10445..0ed17a312f 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -58,6 +58,7 @@ export { buildStyleClassNamesFromData, buildStyleClassNamesExtenders, getPreviousNextBlock, + findBlocks, } from '@plone/volto/helpers/Blocks/Blocks'; export { default as BodyClass } from '@plone/volto/helpers/BodyClass/BodyClass'; export { default as ScrollToTop } from '@plone/volto/helpers/ScrollToTop/ScrollToTop'; @@ -91,6 +92,8 @@ export { replaceItemOfArray, cloneDeepSchema, reorderArray, + isInteractiveElement, + slugify, } from '@plone/volto/helpers/Utils/Utils'; export { messages } from './MessageLabels/MessageLabels'; export { diff --git a/test-setup-config.js b/test-setup-config.js index b24c2961b4..c90ac63bbc 100644 --- a/test-setup-config.js +++ b/test-setup-config.js @@ -82,6 +82,7 @@ config.set('settings', { viewableInBrowserObjects: [], styleClassNameConverters, styleClassNameExtenders, + containerBlockTypes: [], }); config.set('blocks', { blocksConfig: {