2016-08-19 13:57:50 +02:00
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* LeftMenu
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2020-06-09 16:37:51 +02:00
|
|
|
import React, {
|
|
|
|
|
forwardRef,
|
2020-06-09 17:11:28 +02:00
|
|
|
memo,
|
2020-06-09 16:37:51 +02:00
|
|
|
useContext,
|
|
|
|
|
useEffect,
|
|
|
|
|
useImperativeHandle,
|
|
|
|
|
useMemo,
|
|
|
|
|
useReducer,
|
|
|
|
|
} from 'react';
|
2020-02-07 14:46:12 +01:00
|
|
|
import PropTypes from 'prop-types';
|
2020-06-08 11:25:05 +02:00
|
|
|
import { useLocation } from 'react-router-dom';
|
2020-06-09 16:37:51 +02:00
|
|
|
|
|
|
|
|
import { UserContext, hasPermissions, request } from 'strapi-helper-plugin';
|
2020-06-08 11:25:05 +02:00
|
|
|
import {
|
|
|
|
|
LeftMenuLinksSection,
|
|
|
|
|
LeftMenuFooter,
|
|
|
|
|
LeftMenuHeader,
|
|
|
|
|
LinksContainer,
|
|
|
|
|
} from '../../components/LeftMenu';
|
2020-06-10 11:45:58 +02:00
|
|
|
import { useSettingsMenu } from '../../hooks';
|
2020-06-09 16:37:51 +02:00
|
|
|
import { generateModelsLinks } from './utils';
|
2020-06-09 12:05:59 +02:00
|
|
|
import init from './init';
|
2020-06-08 13:15:01 +02:00
|
|
|
import reducer, { initialState } from './reducer';
|
2020-06-08 16:51:42 +02:00
|
|
|
import Loader from './Loader';
|
2019-09-17 17:19:10 +02:00
|
|
|
import Wrapper from './Wrapper';
|
2016-08-19 13:57:50 +02:00
|
|
|
|
2020-06-09 16:37:51 +02:00
|
|
|
const LeftMenu = forwardRef(({ version, plugins }, ref) => {
|
2020-06-08 11:25:05 +02:00
|
|
|
const location = useLocation();
|
2020-06-08 13:15:01 +02:00
|
|
|
const permissions = useContext(UserContext);
|
2020-06-10 11:45:58 +02:00
|
|
|
const { menu: settingsMenu } = useSettingsMenu();
|
2020-06-09 16:37:51 +02:00
|
|
|
const [
|
|
|
|
|
{
|
|
|
|
|
collectionTypesSectionLinks,
|
|
|
|
|
generalSectionLinks,
|
|
|
|
|
isLoading,
|
|
|
|
|
pluginsSectionLinks,
|
|
|
|
|
singleTypesSectionLinks,
|
|
|
|
|
},
|
|
|
|
|
dispatch,
|
2020-06-10 11:45:58 +02:00
|
|
|
] = useReducer(reducer, initialState, () => init(initialState, plugins, settingsMenu));
|
2020-06-09 12:05:59 +02:00
|
|
|
const generalSectionLinksFiltered = useMemo(
|
|
|
|
|
() => generalSectionLinks.filter(link => link.isDisplayed),
|
|
|
|
|
[generalSectionLinks]
|
|
|
|
|
);
|
|
|
|
|
const pluginsSectionLinksFiltered = useMemo(
|
|
|
|
|
() => pluginsSectionLinks.filter(link => link.isDisplayed),
|
|
|
|
|
[pluginsSectionLinks]
|
|
|
|
|
);
|
|
|
|
|
|
2020-06-09 16:37:51 +02:00
|
|
|
const singleTypesSectionLinksFiltered = useMemo(
|
|
|
|
|
() => singleTypesSectionLinks.filter(link => link.isDisplayed),
|
|
|
|
|
[singleTypesSectionLinks]
|
|
|
|
|
);
|
|
|
|
|
const collectTypesSectionLinksFiltered = useMemo(
|
|
|
|
|
() => collectionTypesSectionLinks.filter(link => link.isDisplayed),
|
|
|
|
|
[collectionTypesSectionLinks]
|
|
|
|
|
);
|
|
|
|
|
|
2020-06-09 17:11:28 +02:00
|
|
|
const checkPermissions = async (index, permissionsToCheck) => {
|
|
|
|
|
const hasPermission = await hasPermissions(permissions, permissionsToCheck);
|
|
|
|
|
|
|
|
|
|
return { index, hasPermission };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const generateArrayOfPromises = array =>
|
|
|
|
|
array.map((_, index) => checkPermissions(index, array[index].permissions));
|
|
|
|
|
|
2020-06-09 16:37:51 +02:00
|
|
|
const getModels = async () => {
|
|
|
|
|
const requestURL = '/content-manager/content-types';
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const { data } = await request(requestURL, { method: 'GET' });
|
2020-06-09 17:11:28 +02:00
|
|
|
|
2020-06-09 16:37:51 +02:00
|
|
|
const formattedData = generateModelsLinks(data);
|
2020-06-09 17:11:28 +02:00
|
|
|
const collectionTypesSectionLinksArrayOfPromises = generateArrayOfPromises(
|
|
|
|
|
formattedData.collectionTypesSectionLinks
|
|
|
|
|
);
|
|
|
|
|
const collectionTypesSectionResults = await Promise.all(
|
|
|
|
|
collectionTypesSectionLinksArrayOfPromises
|
|
|
|
|
);
|
|
|
|
|
const singleTypesSectionLinksArrayOfPromises = generateArrayOfPromises(
|
|
|
|
|
formattedData.singleTypesSectionLinks
|
|
|
|
|
);
|
|
|
|
|
const singleTypesSectionResults = await Promise.all(singleTypesSectionLinksArrayOfPromises);
|
2020-06-09 16:37:51 +02:00
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'GET_MODELS_SUCCEEDED',
|
|
|
|
|
data: formattedData,
|
|
|
|
|
});
|
2020-06-09 17:11:28 +02:00
|
|
|
|
|
|
|
|
// TODO maybe we should display a loader while permissions are being checked
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'SET_LINK_PERMISSIONS',
|
|
|
|
|
data: {
|
|
|
|
|
collectionTypesSectionLinks: collectionTypesSectionResults,
|
|
|
|
|
singleTypesSectionLinks: singleTypesSectionResults,
|
|
|
|
|
// pluginsSectionLinks: pluginsSectionResults,
|
|
|
|
|
},
|
|
|
|
|
});
|
2020-06-09 16:37:51 +02:00
|
|
|
} catch (err) {
|
|
|
|
|
console.log(err);
|
|
|
|
|
strapi.notification.error('notification.error');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Make the getModels method available for all the other plugins
|
|
|
|
|
// So they can regenerate the menu when they need
|
|
|
|
|
// It's specially used in the content type builder
|
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
|
|
|
getModels,
|
|
|
|
|
}));
|
|
|
|
|
|
2020-06-08 13:15:01 +02:00
|
|
|
useEffect(() => {
|
|
|
|
|
const getLinksPermissions = async () => {
|
2020-06-09 12:05:59 +02:00
|
|
|
const generalSectionLinksArrayOfPromises = generateArrayOfPromises(generalSectionLinks);
|
|
|
|
|
const pluginsSectionLinksArrayOfPromises = generateArrayOfPromises(pluginsSectionLinks);
|
2020-06-08 13:15:01 +02:00
|
|
|
|
2020-06-09 16:37:51 +02:00
|
|
|
await getModels();
|
|
|
|
|
// TODO check permissions form models
|
|
|
|
|
|
2020-06-09 12:05:59 +02:00
|
|
|
const generalSectionResults = await Promise.all(generalSectionLinksArrayOfPromises);
|
|
|
|
|
const pluginsSectionResults = await Promise.all(pluginsSectionLinksArrayOfPromises);
|
2020-06-08 16:51:42 +02:00
|
|
|
|
2020-06-09 08:37:41 +02:00
|
|
|
dispatch({
|
|
|
|
|
type: 'SET_LINK_PERMISSIONS',
|
2020-06-09 12:05:59 +02:00
|
|
|
data: {
|
|
|
|
|
generalSectionLinks: generalSectionResults,
|
|
|
|
|
pluginsSectionLinks: pluginsSectionResults,
|
|
|
|
|
},
|
2020-06-08 13:15:01 +02:00
|
|
|
});
|
2020-06-08 16:51:42 +02:00
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'TOGGLE_IS_LOADING',
|
|
|
|
|
});
|
2020-06-08 13:15:01 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
getLinksPermissions();
|
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
|
}, []);
|
2020-06-08 11:25:05 +02:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Wrapper>
|
2020-06-08 16:51:42 +02:00
|
|
|
<Loader show={isLoading} />
|
2020-06-08 11:25:05 +02:00
|
|
|
<LeftMenuHeader />
|
|
|
|
|
<LinksContainer>
|
2020-06-09 16:37:51 +02:00
|
|
|
{collectTypesSectionLinksFiltered.length && (
|
|
|
|
|
<LeftMenuLinksSection
|
|
|
|
|
section="collectionType"
|
|
|
|
|
name="collectionType"
|
|
|
|
|
links={collectTypesSectionLinksFiltered}
|
|
|
|
|
location={location}
|
|
|
|
|
searchable
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{singleTypesSectionLinksFiltered.length && (
|
|
|
|
|
<LeftMenuLinksSection
|
|
|
|
|
section="singleType"
|
|
|
|
|
name="singleType"
|
|
|
|
|
links={singleTypesSectionLinksFiltered}
|
|
|
|
|
location={location}
|
|
|
|
|
searchable
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2020-06-09 12:05:59 +02:00
|
|
|
<LeftMenuLinksSection
|
|
|
|
|
section="plugins"
|
|
|
|
|
name="plugins"
|
|
|
|
|
links={pluginsSectionLinksFiltered}
|
|
|
|
|
location={location}
|
|
|
|
|
searchable={false}
|
|
|
|
|
emptyLinksListMessage="app.components.LeftMenuLinkContainer.noPluginsInstalled"
|
|
|
|
|
/>
|
|
|
|
|
{generalSectionLinksFiltered.length && (
|
2020-06-08 13:15:01 +02:00
|
|
|
<LeftMenuLinksSection
|
|
|
|
|
section="general"
|
|
|
|
|
name="general"
|
2020-06-09 12:05:59 +02:00
|
|
|
links={generalSectionLinksFiltered}
|
2020-06-08 13:15:01 +02:00
|
|
|
location={location}
|
|
|
|
|
searchable={false}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2020-06-08 11:25:05 +02:00
|
|
|
</LinksContainer>
|
|
|
|
|
<LeftMenuFooter key="footer" version={version} />
|
|
|
|
|
</Wrapper>
|
|
|
|
|
);
|
2020-06-09 16:37:51 +02:00
|
|
|
});
|
2016-08-19 13:57:50 +02:00
|
|
|
|
2020-02-07 14:46:12 +01:00
|
|
|
LeftMenu.propTypes = {
|
|
|
|
|
version: PropTypes.string.isRequired,
|
|
|
|
|
plugins: PropTypes.object.isRequired,
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-09 17:11:28 +02:00
|
|
|
export default memo(LeftMenu);
|