@plone/volto
Version:
Volto
84 lines (73 loc) • 2.47 kB
JSX
import PropTypes from 'prop-types';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import useDeepCompareEffect from 'use-deep-compare-effect';
import { getBaseUrl } from '@plone/volto/helpers/Url/Url';
import { getContextNavigation } from '@plone/volto/actions/contextNavigation/contextNavigation';
export function withContentNavigation(WrappedComponent) {
/**
* Options passed in params can be:
*
* - name - The title of the navigation tree.
* - root_path - Root node path, can be "frontend path", derived from router
* - includeTop - Bool, Include top nodeschema
* - currentFolderOnly - Bool, Only show the contents of the current folder.
* - topLevel - Int, Start level
* - bottomLevel - Int, Navigation tree depth
* - no_icons - Bool, Suppress Icons
* - thumb_scale - String, Override thumb scale
* - no_thumbs = Bool, Suppress thumbs
*
*/
function Wrapped(props) {
const {
location,
pathname = getBaseUrl(location.pathname),
params = {},
} = props;
let qs = Object.keys(params)
.sort()
.map((key) => `expand.contextnavigation.${key}=${params[key]}`)
.join('&');
const path = `${pathname}${
pathname.endsWith('/') ? '' : '/'
}@contextnavigation${qs ? `?${qs}` : ''}`;
const dispatch = useDispatch();
const nav = useSelector((state) => {
return state.contextNavigation?.[path]?.data;
});
useDeepCompareEffect(() => {
dispatch(getContextNavigation(pathname, params));
}, [pathname, dispatch, params]);
return <WrappedComponent {...props} navigation={nav} />;
}
Wrapped.propTypes = {
/**
* Location, from router
*/
location: PropTypes.shape({
pathname: PropTypes.string,
}),
/**
* Parameters passed to the @contextnavigation endpoint
*/
params: PropTypes.shape({
name: PropTypes.string,
root_path: PropTypes.string,
includeTop: PropTypes.bool,
currentFolderOnly: PropTypes.bool,
topLevel: PropTypes.number,
bottomLevel: PropTypes.number,
no_icons: PropTypes.bool,
thumb_scale: PropTypes.string,
no_thumbs: PropTypes.bool,
}),
};
Wrapped.displayName = `WithContextNavigation(${getDisplayName(
WrappedComponent,
)})`;
return Wrapped;
}
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}