165 lines
7.0 KiB
JavaScript
165 lines
7.0 KiB
JavaScript
import { useEffect } from 'react';
|
||
import { useNotification, useStrapiApp, useAPIErrorHandler, useAuth } from '@strapi/admin/strapi-admin';
|
||
import { useNotifyAT } from '@strapi/design-system';
|
||
import { stringify } from 'qs';
|
||
import { useIntl } from 'react-intl';
|
||
import { COLLECTION_TYPES, SINGLE_TYPES } from '../constants/collections.mjs';
|
||
import { HOOKS } from '../constants/hooks.mjs';
|
||
import { setInitialData } from '../modules/app.mjs';
|
||
import { useTypedDispatch, useTypedSelector } from '../modules/hooks.mjs';
|
||
import { useGetAllContentTypeSettingsQuery } from '../services/contentTypes.mjs';
|
||
import { useGetInitialDataQuery } from '../services/init.mjs';
|
||
import { getTranslation } from '../utils/translations.mjs';
|
||
|
||
const { MUTATE_COLLECTION_TYPES_LINKS, MUTATE_SINGLE_TYPES_LINKS } = HOOKS;
|
||
const useContentManagerInitData = ()=>{
|
||
const { toggleNotification } = useNotification();
|
||
const dispatch = useTypedDispatch();
|
||
const runHookWaterfall = useStrapiApp('useContentManagerInitData', (state)=>state.runHookWaterfall);
|
||
const { notifyStatus } = useNotifyAT();
|
||
const { formatMessage } = useIntl();
|
||
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
|
||
const checkUserHasPermissions = useAuth('useContentManagerInitData', (state)=>state.checkUserHasPermissions);
|
||
const state = useTypedSelector((state)=>state['content-manager'].app);
|
||
const initialDataQuery = useGetInitialDataQuery(undefined, {
|
||
/**
|
||
* TODO: remove this when the CTB has been refactored to use redux-toolkit-query
|
||
* and it can invalidate the cache on mutation
|
||
*/ refetchOnMountOrArgChange: true
|
||
});
|
||
useEffect(()=>{
|
||
if (initialDataQuery.data) {
|
||
notifyStatus(formatMessage({
|
||
id: getTranslation('App.schemas.data-loaded'),
|
||
defaultMessage: 'The schemas have been successfully loaded.'
|
||
}));
|
||
}
|
||
}, [
|
||
formatMessage,
|
||
initialDataQuery.data,
|
||
notifyStatus
|
||
]);
|
||
useEffect(()=>{
|
||
if (initialDataQuery.error) {
|
||
toggleNotification({
|
||
type: 'danger',
|
||
message: formatAPIError(initialDataQuery.error)
|
||
});
|
||
}
|
||
}, [
|
||
formatAPIError,
|
||
initialDataQuery.error,
|
||
toggleNotification
|
||
]);
|
||
const contentTypeSettingsQuery = useGetAllContentTypeSettingsQuery();
|
||
useEffect(()=>{
|
||
if (contentTypeSettingsQuery.error) {
|
||
toggleNotification({
|
||
type: 'danger',
|
||
message: formatAPIError(contentTypeSettingsQuery.error)
|
||
});
|
||
}
|
||
}, [
|
||
formatAPIError,
|
||
contentTypeSettingsQuery.error,
|
||
toggleNotification
|
||
]);
|
||
const formatData = async (components, contentTypes, fieldSizes, contentTypeConfigurations)=>{
|
||
/**
|
||
* We group these by the two types we support. We do with an object because we can use default
|
||
* values of arrays to make sure we always have an array to manipulate further on if, for example,
|
||
* a user has not made any single types.
|
||
*
|
||
* This means we have to manually add new content types to this hook if we add a new type – but
|
||
* the safety is worth it.
|
||
*/ const { collectionType: collectionTypeLinks, singleType: singleTypeLinks } = contentTypes.reduce((acc, model)=>{
|
||
acc[model.kind].push(model);
|
||
return acc;
|
||
}, {
|
||
collectionType: [],
|
||
singleType: []
|
||
});
|
||
const collectionTypeSectionLinks = generateLinks(collectionTypeLinks, 'collectionTypes', contentTypeConfigurations);
|
||
const singleTypeSectionLinks = generateLinks(singleTypeLinks, 'singleTypes');
|
||
// Collection Types verifications
|
||
const collectionTypeLinksPermissions = await Promise.all(collectionTypeSectionLinks.map(({ permissions })=>checkUserHasPermissions(permissions)));
|
||
const authorizedCollectionTypeLinks = collectionTypeSectionLinks.filter((_, index)=>collectionTypeLinksPermissions[index].length > 0);
|
||
// Single Types verifications
|
||
const singleTypeLinksPermissions = await Promise.all(singleTypeSectionLinks.map(({ permissions })=>checkUserHasPermissions(permissions)));
|
||
const authorizedSingleTypeLinks = singleTypeSectionLinks.filter((_, index)=>singleTypeLinksPermissions[index].length > 0);
|
||
const { ctLinks } = runHookWaterfall(MUTATE_COLLECTION_TYPES_LINKS, {
|
||
ctLinks: authorizedCollectionTypeLinks,
|
||
models: contentTypes
|
||
});
|
||
const { stLinks } = runHookWaterfall(MUTATE_SINGLE_TYPES_LINKS, {
|
||
stLinks: authorizedSingleTypeLinks,
|
||
models: contentTypes
|
||
});
|
||
dispatch(setInitialData({
|
||
authorizedCollectionTypeLinks: ctLinks,
|
||
authorizedSingleTypeLinks: stLinks,
|
||
components,
|
||
contentTypeSchemas: contentTypes,
|
||
fieldSizes
|
||
}));
|
||
};
|
||
useEffect(()=>{
|
||
if (initialDataQuery.data && contentTypeSettingsQuery.data) {
|
||
formatData(initialDataQuery.data.components, initialDataQuery.data.contentTypes, initialDataQuery.data.fieldSizes, contentTypeSettingsQuery.data);
|
||
}
|
||
}, [
|
||
initialDataQuery.data,
|
||
contentTypeSettingsQuery.data
|
||
]);
|
||
return {
|
||
...state
|
||
};
|
||
};
|
||
const generateLinks = (links, type, configurations = [])=>{
|
||
return links.filter((link)=>link.isDisplayed).map((link)=>{
|
||
const collectionTypesPermissions = [
|
||
{
|
||
action: 'plugin::content-manager.explorer.create',
|
||
subject: link.uid
|
||
},
|
||
{
|
||
action: 'plugin::content-manager.explorer.read',
|
||
subject: link.uid
|
||
}
|
||
];
|
||
const singleTypesPermissions = [
|
||
{
|
||
action: 'plugin::content-manager.explorer.read',
|
||
subject: link.uid
|
||
}
|
||
];
|
||
const permissions = type === 'collectionTypes' ? collectionTypesPermissions : singleTypesPermissions;
|
||
const currentContentTypeConfig = configurations.find(({ uid })=>uid === link.uid);
|
||
let search = null;
|
||
if (currentContentTypeConfig) {
|
||
const searchParams = {
|
||
page: 1,
|
||
pageSize: currentContentTypeConfig.settings.pageSize,
|
||
sort: `${currentContentTypeConfig.settings.defaultSortBy}:${currentContentTypeConfig.settings.defaultSortOrder}`
|
||
};
|
||
search = stringify(searchParams, {
|
||
encode: false
|
||
});
|
||
}
|
||
return {
|
||
permissions,
|
||
search,
|
||
kind: link.kind,
|
||
title: link.info.displayName,
|
||
to: `/content-manager/${link.kind === 'collectionType' ? COLLECTION_TYPES : SINGLE_TYPES}/${link.uid}`,
|
||
uid: link.uid,
|
||
// Used for the list item key in the helper plugin
|
||
name: link.uid,
|
||
isDisplayed: link.isDisplayed
|
||
};
|
||
});
|
||
};
|
||
|
||
export { useContentManagerInitData };
|
||
//# sourceMappingURL=useContentManagerInitData.mjs.map
|