From f1d0dc74cf89207af76b7659095c4ae2fe6121e9 Mon Sep 17 00:00:00 2001 From: soupette Date: Wed, 4 Nov 2020 10:44:10 +0100 Subject: [PATCH] Merge schema in layout and improve useFetchContentType hook Signed-off-by: soupette --- packages/strapi-admin/admin/src/plugins.js | 16 +++--- .../CollectionTypeRecursivePath/index.js | 56 ++++++++++--------- .../admin/src/containers/EditView/index.js | 1 + .../admin/src/containers/Main/index.js | 1 - .../admin/src/containers/Main/selectors.js | 9 ++- .../hooks/useFetchContentTypeLayout/index.js | 27 ++++++--- .../useFetchContentTypeLayout/reducer.js | 10 ++++ .../utils/formatLayouts.js | 45 +++++++++++++-- 8 files changed, 116 insertions(+), 49 deletions(-) diff --git a/packages/strapi-admin/admin/src/plugins.js b/packages/strapi-admin/admin/src/plugins.js index 0c96a9d0cf..d9585deb3c 100644 --- a/packages/strapi-admin/admin/src/plugins.js +++ b/packages/strapi-admin/admin/src/plugins.js @@ -23,15 +23,15 @@ window.strapi = Object.assign(window.strapi || {}, { }); module.exports = { - 'strapi-plugin-documentation': require('../../../strapi-plugin-documentation/admin/src').default, - 'strapi-plugin-users-permissions': require('../../../strapi-plugin-users-permissions/admin/src') - .default, + // 'strapi-plugin-documentation': require('../../../strapi-plugin-documentation/admin/src').default, + // 'strapi-plugin-users-permissions': require('../../../strapi-plugin-users-permissions/admin/src') + // .default, 'strapi-plugin-content-manager': require('../../../strapi-plugin-content-manager/admin/src') .default, - 'strapi-plugin-content-type-builder': require('../../../strapi-plugin-content-type-builder/admin/src') - .default, + // 'strapi-plugin-content-type-builder': require('../../../strapi-plugin-content-type-builder/admin/src') + // .default, - 'strapi-plugin-email': require('../../../strapi-plugin-email/admin/src').default, - 'strapi-plugin-upload': require('../../../strapi-plugin-upload/admin/src').default, - 'strapi-plugin-graphql': require('../../../strapi-plugin-graphql/admin/src').default, + // 'strapi-plugin-email': require('../../../strapi-plugin-email/admin/src').default, + // 'strapi-plugin-upload': require('../../../strapi-plugin-upload/admin/src').default, + // 'strapi-plugin-graphql': require('../../../strapi-plugin-graphql/admin/src').default, }; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js index 3cc3716885..6848a70af6 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js @@ -1,19 +1,23 @@ -import React, { Suspense, lazy } from 'react'; +import React, { memo, Suspense, lazy } from 'react'; import { Switch, Route, useRouteMatch, useParams } from 'react-router-dom'; import { LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin'; import pluginPermissions from '../../permissions'; +import { useFetchContentTypeLayout } from '../../hooks'; +import EditView from '../EditView'; +import ListView from '../ListView'; -const EditView = lazy(() => import('../EditView')); -const EditSettingsView = lazy(() => import('../EditSettingsView')); -const ListView = lazy(() => import('../ListView')); -const ListSettingsView = lazy(() => import('../ListSettingsView')); +// const EditView = lazy(() => import('../EditView')); +// const EditSettingsView = lazy(() => import('../EditSettingsView')); +// const ListView = lazy(() => import('../ListView')); +// const ListSettingsView = lazy(() => import('../ListSettingsView')); const CollectionTypeRecursivePath = () => { const { url } = useRouteMatch(); const { slug } = useParams(); + const { isLoading, layout } = useFetchContentTypeLayout(slug); const renderRoute = (routeProps, Component) => { - return ; + return ; }; const renderPermissionsRoute = (routeProps, Component) => { return ( @@ -24,14 +28,14 @@ const CollectionTypeRecursivePath = () => { }; const settingsRoutes = [ - { - path: 'ctm-configurations/list-settings', - comp: ListSettingsView, - }, - { - path: 'ctm-configurations/edit-settings/:type', - comp: EditSettingsView, - }, + // { + // path: 'ctm-configurations/list-settings', + // comp: ListSettingsView, + // }, + // { + // path: 'ctm-configurations/edit-settings/:type', + // comp: EditSettingsView, + // }, ].map(({ path, comp }) => ( { )); const routes = [ - { path: ':id', comp: EditView }, - { path: '', comp: ListView }, - ].map(({ path, comp }) => ( - renderRoute(props, comp)} /> + { path: ':id', Comp: EditView }, + { path: '', Comp: ListView }, + ].map(({ path, Comp }) => ( + renderRoute(props, Comp)} /> )); + if (isLoading) { + return ; + } + return ( - }> - - {settingsRoutes} - {routes} - - + + {settingsRoutes} + {routes} + ); }; -export default CollectionTypeRecursivePath; +export default memo(CollectionTypeRecursivePath); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js index 2d9a67fbd2..cf2b745f58 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditView/index.js @@ -32,6 +32,7 @@ import InformationCard from './InformationCard'; /* eslint-disable react/no-array-index-key */ const EditView = ({ currentEnvironment, isSingleType, plugins, slug }) => { + // TODO const { isLoading, layout } = useFetchContentTypeLayout(slug); const { goBack } = useHistory(); const { pathname, state } = useLocation(); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js index 551c2cf135..c4f84ca919 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js @@ -28,7 +28,6 @@ function Main({ getData, getDataSucceeded, isLoading, resetProps }) { const fetchData = async signal => { getData(); - console.log('up'); try { const [{ data: components }, { data: models }] = await Promise.all( diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js index 0594f1b5b6..9458898c82 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js @@ -15,8 +15,13 @@ const makeSelectModels = () => createSelector(selectMainDomain(), substate => { const { models } = substate; - return models.filter(model => model.isDisplayed === true).map(({ uid }) => uid); + return { models: models.filter(model => model.isDisplayed === true).map(({ uid }) => uid) }; }); +const makeSelectModelAndComponentSchemas = () => + createSelector(selectMainDomain(), ({ components, models }) => ({ + schemas: [...components, ...models], + })); + export default makeSelectMain; -export { makeSelectModels, selectMainDomain }; +export { makeSelectModels, makeSelectModelAndComponentSchemas, selectMainDomain }; diff --git a/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/index.js b/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/index.js index def9583259..b3725cd7ec 100644 --- a/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/index.js @@ -3,35 +3,48 @@ import { useSelector } from 'react-redux'; import { request } from 'strapi-helper-plugin'; import formatLayouts from './utils/formatLayouts'; import reducer, { initialState } from './reducer'; -import { makeSelectModels } from '../../containers/Main/selectors'; +import { + makeSelectModels, + makeSelectModelAndComponentSchemas, +} from '../../containers/Main/selectors'; const useFetchContentTypeLayout = contentTypeUID => { - const [{ error, isLoading, layout }, dispatch] = useReducer(reducer, initialState); - const modelsSelector = useMemo(makeSelectModels, []); - const models = useSelector(state => modelsSelector(state), []); + const [{ error, isLoading, layout, layouts }, dispatch] = useReducer(reducer, initialState); + // const modelsSelector = useMemo(makeSelectModels, []); + // const models = useSelector(state => modelsSelector(state), []); + const schemasSelector = useMemo(makeSelectModelAndComponentSchemas, []); + const { schemas } = useSelector(state => schemasSelector(state), []); + console.log({ layouts, layout }); const getData = useCallback( async (uid, abortSignal = false) => { let signal = abortSignal || new AbortController().signal; + console.log('infi lopp'); + + if (layouts[uid]) { + dispatch({ type: 'SET_LAYOUT_FROM_STATE', uid }); + + return; + } dispatch({ type: 'GET_DATA' }); try { - const { data } = await request(`/content-manager/content-types/${uid}`, { + const { data } = await request(`/content-manager/content-types/${uid}/configuration`, { method: 'GET', signal, }); dispatch({ type: 'GET_DATA_SUCCEEDED', - data: formatLayouts(data, models), + data: formatLayouts(data, schemas), }); } catch (error) { console.error(error); dispatch({ type: 'GET_DATA_ERROR', error }); } }, - [models] + [schemas, layouts] ); useEffect(() => { diff --git a/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/reducer.js b/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/reducer.js index 7984c7a017..6d0e6c48c6 100644 --- a/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/reducer.js +++ b/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/reducer.js @@ -5,6 +5,7 @@ export const initialState = { error: null, isLoading: true, layout: {}, + layouts: {}, }; const reducer = (state, action) => @@ -13,11 +14,15 @@ const reducer = (state, action) => case 'GET_DATA': { draftState.isLoading = true; draftState.error = null; + draftState.layout = {}; break; } case 'GET_DATA_SUCCEEDED': { + const contentTypeUid = action.data.contentType.uid; + draftState.isLoading = false; draftState.layout = action.data; + draftState.layouts[contentTypeUid] = action.data; break; } case 'GET_DATA_ERROR': { @@ -25,6 +30,11 @@ const reducer = (state, action) => draftState.error = action.error; break; } + case 'SET_LAYOUT_FROM_STATE': { + draftState.error = null; + draftState.layout = state.layouts[action.uid]; + break; + } default: return draftState; } diff --git a/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/utils/formatLayouts.js b/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/utils/formatLayouts.js index aba7e5a91e..bd288559f9 100644 --- a/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/utils/formatLayouts.js +++ b/packages/strapi-plugin-content-manager/admin/src/hooks/useFetchContentTypeLayout/utils/formatLayouts.js @@ -4,7 +4,7 @@ import pluginId from '../../../pluginId'; const formatLayoutWithMetas = (obj, ctUid, models) => { const formatted = obj.layouts.edit.reduce((acc, current) => { const row = current.map(attribute => { - const fieldSchema = get(obj, ['schema', 'attributes', attribute.name], {}); + const fieldSchema = get(obj, ['attributes', attribute.name], {}); const data = { ...attribute, @@ -35,7 +35,7 @@ const generateRelationQueryInfos = (obj, fieldName, models) => { const uid = obj.uid; const endPoint = `/${pluginId}/explorer/${uid}/relation-list/${fieldName}`; const mainField = get(obj, ['metadatas', fieldName, 'edit', 'mainField'], ''); - const targetModel = get(obj, ['schema', 'attributes', fieldName, 'targetModel'], ''); + const targetModel = get(obj, ['attributes', fieldName, 'targetModel'], ''); const shouldDisplayRelationLink = models.indexOf(targetModel) !== -1; const queryInfos = { @@ -51,7 +51,7 @@ const generateRelationQueryInfos = (obj, fieldName, models) => { const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models) => { const endPoint = `/${pluginId}/explorer/${ctUid}/relation-list/${fieldName}`; const mainField = get(obj, ['metadatas', fieldName, 'edit', 'mainField'], ''); - const targetModel = get(obj, ['schema', 'attributes', fieldName, 'targetModel'], ''); + const targetModel = get(obj, ['attributes', fieldName, 'targetModel'], ''); const shouldDisplayRelationLink = models.indexOf(targetModel) !== -1; const queryInfos = { @@ -69,7 +69,7 @@ const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models) // editRelations is an array of strings... const formatEditRelationsLayoutWithMetas = (obj, models) => { const formatted = obj.layouts.editRelations.reduce((acc, current) => { - const fieldSchema = get(obj, ['schema', 'attributes', current], {}); + const fieldSchema = get(obj, ['attributes', current], {}); const metadatas = get(obj, ['metadatas', current, 'edit'], {}); const size = 6; @@ -89,13 +89,46 @@ const formatEditRelationsLayoutWithMetas = (obj, models) => { return formatted; }; -const formatLayouts = (data, models) => { +const formatListLayoutWithMetas = obj => { + const formatted = obj.layouts.list.reduce((acc, current) => { + const fieldSchema = get(obj, ['attributes', current], {}); + const metadatas = get(obj, ['metadatas', current, 'list'], {}); + + acc.push({ name: current, fieldSchema, metadatas }); + + return acc; + }, []); + + return formatted; +}; + +const mergeMetasWithSchema = (data, schemas) => { + const findSchema = refUid => schemas.find(obj => obj.uid === refUid); + const merged = Object.assign(data, {}); + const contentTypeUid = data.contentType.uid; + const contentTypeSchema = findSchema(contentTypeUid); + + set(merged, ['contentType'], { ...data.contentType, ...contentTypeSchema }); + + Object.keys(data.components).forEach(compoUID => { + const compoSchema = findSchema(compoUID); + + set(merged, ['components', compoUID], { ...data.components[compoUID], ...compoSchema }); + }); + + return merged; +}; + +const formatLayouts = (initialData, models) => { + const data = mergeMetasWithSchema(initialData, models); const formattedCTEditLayout = formatLayoutWithMetas(data.contentType, models); const ctUid = data.contentType.uid; const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType, models); + const formattedListLayout = formatListLayoutWithMetas(data.contentType); set(data, ['contentType', 'layouts', 'edit'], formattedCTEditLayout); set(data, ['contentType', 'layouts', 'editRelations'], formattedEditRelationsLayout); + set(data, ['contentType', 'layouts', 'list'], formattedListLayout); Object.keys(data.components).forEach(compoUID => { const formattedCompoEditLayout = formatLayoutWithMetas( @@ -111,4 +144,4 @@ const formatLayouts = (data, models) => { }; export default formatLayouts; -export { formatEditRelationsLayoutWithMetas, formatLayoutWithMetas }; +export { formatEditRelationsLayoutWithMetas, formatLayoutWithMetas, mergeMetasWithSchema };