UNPKG

@plone/volto

Version:
157 lines (139 loc) 5.11 kB
import React, { useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import hoistNonReactStatics from 'hoist-non-react-statics'; import useDeepCompareEffect from 'use-deep-compare-effect'; import { getContent } from '@plone/volto/actions/content/content'; import { getQueryStringResults } from '@plone/volto/actions/querystringsearch/querystringsearch'; import { usePagination } from '@plone/volto/helpers/Utils/usePagination'; import { getBaseUrl } from '@plone/volto/helpers/Url/Url'; import config from '@plone/volto/registry'; function getDisplayName(WrappedComponent) { return WrappedComponent.displayName || WrappedComponent.name || 'Component'; } export default function withQuerystringResults(WrappedComponent) { function WithQuerystringResults(props) { const { data = {}, id = data.block, properties: content, path, variation, } = props; const { settings } = config; const querystring = data.querystring || data; // For backwards compat with data saved before Blocks schema. Note, this is also how the Search block passes data to ListingBody const subrequestID = content?.UID ? `${content?.UID}-${id}` : id; const { b_size = settings.defaultPageSize } = querystring; // batchsize // save the path so it won't trigger dispatch on eager router location change const [initialPath] = React.useState(getBaseUrl(path)); const copyFields = ['limit', 'query', 'sort_on', 'sort_order', 'depth']; const { currentPage, setCurrentPage } = usePagination(id, 1); const adaptedQuery = Object.assign( variation?.fullobjects ? { fullobjects: 1 } : { metadata_fields: '_all' }, { b_size: b_size, }, ...copyFields.map((name) => Object.keys(querystring).includes(name) ? { [name]: querystring[name] } : {}, ), ); const adaptedQueryRef = useRef(adaptedQuery); const currentPageRef = useRef(currentPage); const querystringResults = useSelector( (state) => state.querystringsearch.subrequests, ); const dispatch = useDispatch(); const folderItems = content?.is_folderish ? content.items : []; const hasQuery = querystring?.query?.length > 0; const hasLoaded = hasQuery ? querystringResults?.[subrequestID]?.loaded : true; const listingItems = hasQuery ? querystringResults?.[subrequestID]?.items || [] : folderItems; const showAsFolderListing = !hasQuery && content?.items_total > b_size; const showAsQueryListing = hasQuery && querystringResults?.[subrequestID]?.total > b_size; const totalPages = showAsFolderListing ? Math.ceil(content.items_total / b_size) : showAsQueryListing ? Math.ceil(querystringResults[subrequestID].total / b_size) : 0; const prevBatch = showAsFolderListing ? content.batching?.prev : showAsQueryListing ? querystringResults[subrequestID].batching?.prev : null; const nextBatch = showAsFolderListing ? content.batching?.next : showAsQueryListing ? querystringResults[subrequestID].batching?.next : null; const isImageGallery = (!data.variation && data.template === 'imageGallery') || data.variation === 'imageGallery'; useDeepCompareEffect(() => { if (hasQuery) { dispatch( getQueryStringResults( initialPath, adaptedQuery, subrequestID, currentPage, ), ); } else if (isImageGallery && !hasQuery) { // when used as image gallery, it doesn't need a query to list children dispatch( getQueryStringResults( initialPath, { ...adaptedQuery, b_size: 10000000000, query: [ { i: 'path', o: 'plone.app.querystring.operation.string.relativePath', v: '', }, ], }, subrequestID, ), ); } else { dispatch(getContent(initialPath, null, null, currentPage)); } adaptedQueryRef.current = adaptedQuery; currentPageRef.current = currentPage; }, [ subrequestID, isImageGallery, adaptedQuery, hasQuery, initialPath, dispatch, currentPage, ]); return ( <WrappedComponent {...props} onPaginationChange={(e, { activePage }) => setCurrentPage(activePage)} total={querystringResults?.[subrequestID]?.total} batch_size={b_size} currentPage={currentPage} totalPages={totalPages} prevBatch={prevBatch} nextBatch={nextBatch} listingItems={listingItems} hasLoaded={hasLoaded} isFolderContentsListing={showAsFolderListing} /> ); } WithQuerystringResults.displayName = `WithQuerystringResults(${getDisplayName( WrappedComponent, )})`; return hoistNonReactStatics(WithQuerystringResults, WrappedComponent); }