UNPKG

@kitconcept/volto-light-theme

Version:
217 lines (207 loc) 6.86 kB
import React, { createRef, useRef, useMemo } from 'react'; import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import cx from 'classnames'; import { Pagination, Dimmer, Loader } from 'semantic-ui-react'; import Slugger from 'github-slugger'; import { renderLinkElement } from '@plone/volto-slate/editor/render'; import config from '@plone/volto/registry'; import withQuerystringResults from '@plone/volto/components/manage/Blocks/Listing/withQuerystringResults'; const messages = defineMessages({ PaginationNavigationFor: { id: 'Pagination Navigation for {headline}', defaultMessage: 'Pagination Navigation for {headline}', }, PaginationNavigation: { id: 'Pagination Navigation', defaultMessage: 'Pagination Navigation', }, }); const Headline = ({ headlineTag, id, data = {}, listingItems, isEditMode, style, }) => { let attr = { id }; const slug = Slugger.slug(data.headline); attr.id = slug || id; const LinkedHeadline = useMemo( () => renderLinkElement(headlineTag), [headlineTag], ); return ( <LinkedHeadline mode={!isEditMode && 'view'} children={data.headline} attributes={attr} className={cx('headline', { emptyListing: !listingItems?.length > 0, })} style={style} /> ); }; export const ListingBody = (props) => { const { data = {}, isEditMode, listingItems, totalPages, onPaginationChange, variation, currentPage, batch_size, prevBatch, nextBatch, isFolderContentsListing, hasLoaded, id, total, properties, } = props; let ListingBodyTemplate; // Legacy support if template is present const variations = config.blocks?.blocksConfig['listing']?.variations || []; const defaultVariation = variations.filter((item) => item.isDefault)?.[0]; if (data.template && !data.variation) { const legacyTemplateConfig = variations.find( (item) => item.id === data.template, ); ListingBodyTemplate = legacyTemplateConfig.template; } else { ListingBodyTemplate = variation?.template ?? defaultVariation?.template ?? null; } const galleryRef = useRef(); const listingRef = createRef(); const NoResults = variation?.noResultsComponent ? variation.noResultsComponent : config.blocks?.blocksConfig['listing'].noResultsComponent; const HeadlineTag = data.headlineTag || 'h2'; return ( <> {data.headline && ( <Headline headlineTag={HeadlineTag} id={id} listingItems={listingItems} data={data} isEditMode={isEditMode} /> )} {listingItems?.length > 0 ? ( <div ref={listingRef}> <ListingBodyTemplate items={listingItems} isEditMode={isEditMode} ref={data.variation === 'imageGallery' ? galleryRef : undefined} {...data} {...variation} /> {totalPages > 1 && ( <div className="pagination-wrapper"> <Pagination aria-label={ data.headline ? props.intl.formatMessage( messages.PaginationNavigationFor, { headline: data.headline, }, ) : props.intl.formatMessage(messages.PaginationNavigation) } className="desktop-pagination" activePage={currentPage} totalPages={totalPages} onPageChange={(e, { activePage }) => { !isEditMode && listingRef.current.scrollIntoView({ behavior: 'smooth' }); onPaginationChange(e, { activePage }); }} firstItem={null} lastItem={null} prevItem={{ content: ( <FormattedMessage id="Previous Page" defaultMessage="Previous Page" /> ), icon: false, 'aria-disabled': !prevBatch, className: !prevBatch ? 'disabled' : null, }} nextItem={{ content: ( <FormattedMessage id="Next Page" defaultMessage="Next Page" /> ), icon: false, 'aria-disabled': !nextBatch, className: !nextBatch ? 'disabled' : null, }} /> <Pagination className="mobile-pagination" activePage={currentPage} totalPages={totalPages} boundaryRange={1} siblingRange={0} onPageChange={(e, { activePage }) => { !isEditMode && listingRef.current.scrollIntoView({ behavior: 'smooth' }); onPaginationChange(e, { activePage }); }} firstItem={null} lastItem={null} prevItem={undefined} nextItem={undefined} /> <div className="total"> <FormattedMessage id="Result" defaultMessage="Result" />{' '} {(currentPage - 1) * batch_size + 1}- {(currentPage - 1) * batch_size + listingItems.length}{' '} <FormattedMessage id="of" defaultMessage="of" />{' '} {total || properties.items_total} </div> </div> )} </div> ) : isEditMode ? ( <div className="listing message" ref={listingRef}> {isFolderContentsListing && ( <FormattedMessage id="No items found in this container." defaultMessage="No items found in this container." /> )} {hasLoaded && NoResults && ( <NoResults isEditMode={isEditMode} {...data} /> )} <Dimmer active={!hasLoaded} inverted> <Loader indeterminate size="small"> <FormattedMessage id="loading" defaultMessage="Loading" /> </Loader> </Dimmer> </div> ) : ( <div className="emptyListing"> {hasLoaded && NoResults && ( <NoResults isEditMode={isEditMode} {...data} /> )} <Dimmer active={!hasLoaded} inverted> <Loader indeterminate size="small"> <FormattedMessage id="loading" defaultMessage="Loading" /> </Loader> </Dimmer> </div> )} </> ); }; export default injectIntl(withQuerystringResults(ListingBody));