Merge schema in layout and improve useFetchContentType hook

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-11-04 10:44:10 +01:00
parent b834aea0c9
commit f1d0dc74cf
8 changed files with 116 additions and 49 deletions

View File

@ -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,
};

View File

@ -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);

View File

@ -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();

View File

@ -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(

View File

@ -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 };

View File

@ -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(() => {

View File

@ -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;
}

View File

@ -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 };