strapi-plugin-content-manager
Version:
A powerful UI to easily manage your data.
126 lines (112 loc) • 4.19 kB
JavaScript
import React, { memo, useMemo } from 'react';
import { Switch, Route } from 'react-router-dom';
import { ErrorBoundary } from 'react-error-boundary';
import { get } from 'lodash';
import PropTypes from 'prop-types';
import { ErrorFallback, LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin';
import pluginPermissions from '../../permissions';
import { ContentTypeLayoutContext } from '../../contexts';
import { useFetchContentTypeLayout } from '../../hooks';
import { formatLayoutToApi } from '../../utils';
import EditViewLayoutManager from '../EditViewLayoutManager';
import EditSettingsView from '../EditSettingsView';
import ListViewLayout from '../ListViewLayoutManager';
import ListSettingsView from '../ListSettingsView';
const CollectionTypeRecursivePath = ({
match: {
params: { slug },
url,
},
}) => {
const { isLoading, layout, updateLayout } = useFetchContentTypeLayout(slug);
const { rawContentTypeLayout, rawComponentsLayouts } = useMemo(() => {
let rawContentTypeLayout = {};
let rawComponentsLayouts = {};
if (layout.contentType) {
rawContentTypeLayout = formatLayoutToApi(layout.contentType);
}
if (layout.components) {
rawComponentsLayouts = Object.keys(layout.components).reduce((acc, current) => {
acc[current] = formatLayoutToApi(layout.components[current]);
return acc;
}, {});
}
return { rawContentTypeLayout, rawComponentsLayouts };
}, [layout]);
const uid = get(layout, ['contentType', 'uid'], null);
// This statement is needed in order to prevent the CollectionTypeFormWrapper effects clean up phase to be run twice.
// What can happen is that when navigating from one entry to another the cleanup phase of the fetch data effect is run twice : once when
// unmounting, once when the url changes.
// Since it can happen that the layout there's a delay when the layout is being fetched and the url changes adding the uid ! == slug
// statement prevent the component from being mounted and unmounted twice.
if (uid !== slug || isLoading) {
return <LoadingIndicatorPage />;
}
const renderRoute = (
{
location: { state },
history: { goBack },
match: {
params: { id, origin },
},
},
Component
) => {
return (
<Component
slug={slug}
layout={layout}
state={state}
goBack={goBack}
id={id}
origin={origin}
/>
);
};
const routes = [
{ path: 'create/clone/:origin', comp: EditViewLayoutManager },
{ path: 'create', comp: EditViewLayoutManager },
{ path: ':id', comp: EditViewLayoutManager },
{ path: '', comp: ListViewLayout },
].map(({ path, comp }) => (
<Route key={path} path={`${url}/${path}`} render={props => renderRoute(props, comp)} />
));
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ContentTypeLayoutContext.Provider value={layout}>
<Switch>
<Route path={`${url}/configurations/list`}>
<CheckPagePermissions permissions={pluginPermissions.collectionTypesConfigurations}>
<ListSettingsView
layout={rawContentTypeLayout}
slug={slug}
updateLayout={updateLayout}
/>
</CheckPagePermissions>
</Route>
<Route path={`${url}/configurations/edit`}>
<CheckPagePermissions permissions={pluginPermissions.collectionTypesConfigurations}>
<EditSettingsView
components={rawComponentsLayouts}
isContentTypeView
mainLayout={rawContentTypeLayout}
slug={slug}
updateLayout={updateLayout}
/>
</CheckPagePermissions>
</Route>
{routes}
</Switch>
</ContentTypeLayoutContext.Provider>
</ErrorBoundary>
);
};
CollectionTypeRecursivePath.propTypes = {
match: PropTypes.shape({
url: PropTypes.string.isRequired,
params: PropTypes.shape({
slug: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
};
export default memo(CollectionTypeRecursivePath);