mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 11:54:10 +00:00 
			
		
		
		
	Merge schema in layout and improve useFetchContentType hook
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
		
							parent
							
								
									b834aea0c9
								
							
						
					
					
						commit
						f1d0dc74cf
					
				@ -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,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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 <Component {...routeProps} slug={slug} />;
 | 
			
		||||
    return <Component {...routeProps} slug={slug} layout={layout} />;
 | 
			
		||||
  };
 | 
			
		||||
  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 }) => (
 | 
			
		||||
    <Route
 | 
			
		||||
      key={path}
 | 
			
		||||
@ -41,20 +45,22 @@ const CollectionTypeRecursivePath = () => {
 | 
			
		||||
  ));
 | 
			
		||||
 | 
			
		||||
  const routes = [
 | 
			
		||||
    { path: ':id', comp: EditView },
 | 
			
		||||
    { path: '', comp: ListView },
 | 
			
		||||
  ].map(({ path, comp }) => (
 | 
			
		||||
    <Route key={path} path={`${url}/${path}`} render={props => renderRoute(props, comp)} />
 | 
			
		||||
    { path: ':id', Comp: EditView },
 | 
			
		||||
    { path: '', Comp: ListView },
 | 
			
		||||
  ].map(({ path, Comp }) => (
 | 
			
		||||
    <Route key={path} path={`${url}/${path}`} render={props => renderRoute(props, Comp)} />
 | 
			
		||||
  ));
 | 
			
		||||
 | 
			
		||||
  if (isLoading) {
 | 
			
		||||
    return <LoadingIndicatorPage />;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Suspense fallback={<LoadingIndicatorPage />}>
 | 
			
		||||
    <Switch>
 | 
			
		||||
      {settingsRoutes}
 | 
			
		||||
      {routes}
 | 
			
		||||
    </Switch>
 | 
			
		||||
    </Suspense>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default CollectionTypeRecursivePath;
 | 
			
		||||
export default memo(CollectionTypeRecursivePath);
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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(
 | 
			
		||||
 | 
			
		||||
@ -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 };
 | 
			
		||||
 | 
			
		||||
@ -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(() => {
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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 };
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user