mirror of
https://github.com/strapi/strapi.git
synced 2025-11-09 22:59:14 +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 = {
|
module.exports = {
|
||||||
'strapi-plugin-documentation': require('../../../strapi-plugin-documentation/admin/src').default,
|
// 'strapi-plugin-documentation': require('../../../strapi-plugin-documentation/admin/src').default,
|
||||||
'strapi-plugin-users-permissions': require('../../../strapi-plugin-users-permissions/admin/src')
|
// 'strapi-plugin-users-permissions': require('../../../strapi-plugin-users-permissions/admin/src')
|
||||||
.default,
|
// .default,
|
||||||
'strapi-plugin-content-manager': require('../../../strapi-plugin-content-manager/admin/src')
|
'strapi-plugin-content-manager': require('../../../strapi-plugin-content-manager/admin/src')
|
||||||
.default,
|
.default,
|
||||||
'strapi-plugin-content-type-builder': require('../../../strapi-plugin-content-type-builder/admin/src')
|
// 'strapi-plugin-content-type-builder': require('../../../strapi-plugin-content-type-builder/admin/src')
|
||||||
.default,
|
// .default,
|
||||||
|
|
||||||
'strapi-plugin-email': require('../../../strapi-plugin-email/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-upload': require('../../../strapi-plugin-upload/admin/src').default,
|
||||||
'strapi-plugin-graphql': require('../../../strapi-plugin-graphql/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 { Switch, Route, useRouteMatch, useParams } from 'react-router-dom';
|
||||||
import { LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin';
|
import { LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin';
|
||||||
import pluginPermissions from '../../permissions';
|
import pluginPermissions from '../../permissions';
|
||||||
|
import { useFetchContentTypeLayout } from '../../hooks';
|
||||||
|
import EditView from '../EditView';
|
||||||
|
import ListView from '../ListView';
|
||||||
|
|
||||||
const EditView = lazy(() => import('../EditView'));
|
// const EditView = lazy(() => import('../EditView'));
|
||||||
const EditSettingsView = lazy(() => import('../EditSettingsView'));
|
// const EditSettingsView = lazy(() => import('../EditSettingsView'));
|
||||||
const ListView = lazy(() => import('../ListView'));
|
// const ListView = lazy(() => import('../ListView'));
|
||||||
const ListSettingsView = lazy(() => import('../ListSettingsView'));
|
// const ListSettingsView = lazy(() => import('../ListSettingsView'));
|
||||||
|
|
||||||
const CollectionTypeRecursivePath = () => {
|
const CollectionTypeRecursivePath = () => {
|
||||||
const { url } = useRouteMatch();
|
const { url } = useRouteMatch();
|
||||||
const { slug } = useParams();
|
const { slug } = useParams();
|
||||||
|
const { isLoading, layout } = useFetchContentTypeLayout(slug);
|
||||||
|
|
||||||
const renderRoute = (routeProps, Component) => {
|
const renderRoute = (routeProps, Component) => {
|
||||||
return <Component {...routeProps} slug={slug} />;
|
return <Component {...routeProps} slug={slug} layout={layout} />;
|
||||||
};
|
};
|
||||||
const renderPermissionsRoute = (routeProps, Component) => {
|
const renderPermissionsRoute = (routeProps, Component) => {
|
||||||
return (
|
return (
|
||||||
@ -24,14 +28,14 @@ const CollectionTypeRecursivePath = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const settingsRoutes = [
|
const settingsRoutes = [
|
||||||
{
|
// {
|
||||||
path: 'ctm-configurations/list-settings',
|
// path: 'ctm-configurations/list-settings',
|
||||||
comp: ListSettingsView,
|
// comp: ListSettingsView,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'ctm-configurations/edit-settings/:type',
|
// path: 'ctm-configurations/edit-settings/:type',
|
||||||
comp: EditSettingsView,
|
// comp: EditSettingsView,
|
||||||
},
|
// },
|
||||||
].map(({ path, comp }) => (
|
].map(({ path, comp }) => (
|
||||||
<Route
|
<Route
|
||||||
key={path}
|
key={path}
|
||||||
@ -41,20 +45,22 @@ const CollectionTypeRecursivePath = () => {
|
|||||||
));
|
));
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{ path: ':id', comp: EditView },
|
{ path: ':id', Comp: EditView },
|
||||||
{ path: '', comp: ListView },
|
{ path: '', Comp: ListView },
|
||||||
].map(({ path, comp }) => (
|
].map(({ path, Comp }) => (
|
||||||
<Route key={path} path={`${url}/${path}`} render={props => renderRoute(props, comp)} />
|
<Route key={path} path={`${url}/${path}`} render={props => renderRoute(props, Comp)} />
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <LoadingIndicatorPage />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<LoadingIndicatorPage />}>
|
|
||||||
<Switch>
|
<Switch>
|
||||||
{settingsRoutes}
|
{settingsRoutes}
|
||||||
{routes}
|
{routes}
|
||||||
</Switch>
|
</Switch>
|
||||||
</Suspense>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CollectionTypeRecursivePath;
|
export default memo(CollectionTypeRecursivePath);
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import InformationCard from './InformationCard';
|
|||||||
|
|
||||||
/* eslint-disable react/no-array-index-key */
|
/* eslint-disable react/no-array-index-key */
|
||||||
const EditView = ({ currentEnvironment, isSingleType, plugins, slug }) => {
|
const EditView = ({ currentEnvironment, isSingleType, plugins, slug }) => {
|
||||||
|
// TODO
|
||||||
const { isLoading, layout } = useFetchContentTypeLayout(slug);
|
const { isLoading, layout } = useFetchContentTypeLayout(slug);
|
||||||
const { goBack } = useHistory();
|
const { goBack } = useHistory();
|
||||||
const { pathname, state } = useLocation();
|
const { pathname, state } = useLocation();
|
||||||
|
|||||||
@ -28,7 +28,6 @@ function Main({ getData, getDataSucceeded, isLoading, resetProps }) {
|
|||||||
|
|
||||||
const fetchData = async signal => {
|
const fetchData = async signal => {
|
||||||
getData();
|
getData();
|
||||||
console.log('up');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [{ data: components }, { data: models }] = await Promise.all(
|
const [{ data: components }, { data: models }] = await Promise.all(
|
||||||
|
|||||||
@ -15,8 +15,13 @@ const makeSelectModels = () =>
|
|||||||
createSelector(selectMainDomain(), substate => {
|
createSelector(selectMainDomain(), substate => {
|
||||||
const { models } = 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 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 { request } from 'strapi-helper-plugin';
|
||||||
import formatLayouts from './utils/formatLayouts';
|
import formatLayouts from './utils/formatLayouts';
|
||||||
import reducer, { initialState } from './reducer';
|
import reducer, { initialState } from './reducer';
|
||||||
import { makeSelectModels } from '../../containers/Main/selectors';
|
import {
|
||||||
|
makeSelectModels,
|
||||||
|
makeSelectModelAndComponentSchemas,
|
||||||
|
} from '../../containers/Main/selectors';
|
||||||
|
|
||||||
const useFetchContentTypeLayout = contentTypeUID => {
|
const useFetchContentTypeLayout = contentTypeUID => {
|
||||||
const [{ error, isLoading, layout }, dispatch] = useReducer(reducer, initialState);
|
const [{ error, isLoading, layout, layouts }, dispatch] = useReducer(reducer, initialState);
|
||||||
const modelsSelector = useMemo(makeSelectModels, []);
|
// const modelsSelector = useMemo(makeSelectModels, []);
|
||||||
const models = useSelector(state => modelsSelector(state), []);
|
// const models = useSelector(state => modelsSelector(state), []);
|
||||||
|
const schemasSelector = useMemo(makeSelectModelAndComponentSchemas, []);
|
||||||
|
const { schemas } = useSelector(state => schemasSelector(state), []);
|
||||||
|
console.log({ layouts, layout });
|
||||||
|
|
||||||
const getData = useCallback(
|
const getData = useCallback(
|
||||||
async (uid, abortSignal = false) => {
|
async (uid, abortSignal = false) => {
|
||||||
let signal = abortSignal || new AbortController().signal;
|
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' });
|
dispatch({ type: 'GET_DATA' });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data } = await request(`/content-manager/content-types/${uid}`, {
|
const { data } = await request(`/content-manager/content-types/${uid}/configuration`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
signal,
|
signal,
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'GET_DATA_SUCCEEDED',
|
type: 'GET_DATA_SUCCEEDED',
|
||||||
data: formatLayouts(data, models),
|
data: formatLayouts(data, schemas),
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
dispatch({ type: 'GET_DATA_ERROR', error });
|
dispatch({ type: 'GET_DATA_ERROR', error });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[models]
|
[schemas, layouts]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ export const initialState = {
|
|||||||
error: null,
|
error: null,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
layout: {},
|
layout: {},
|
||||||
|
layouts: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducer = (state, action) =>
|
const reducer = (state, action) =>
|
||||||
@ -13,11 +14,15 @@ const reducer = (state, action) =>
|
|||||||
case 'GET_DATA': {
|
case 'GET_DATA': {
|
||||||
draftState.isLoading = true;
|
draftState.isLoading = true;
|
||||||
draftState.error = null;
|
draftState.error = null;
|
||||||
|
draftState.layout = {};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'GET_DATA_SUCCEEDED': {
|
case 'GET_DATA_SUCCEEDED': {
|
||||||
|
const contentTypeUid = action.data.contentType.uid;
|
||||||
|
|
||||||
draftState.isLoading = false;
|
draftState.isLoading = false;
|
||||||
draftState.layout = action.data;
|
draftState.layout = action.data;
|
||||||
|
draftState.layouts[contentTypeUid] = action.data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'GET_DATA_ERROR': {
|
case 'GET_DATA_ERROR': {
|
||||||
@ -25,6 +30,11 @@ const reducer = (state, action) =>
|
|||||||
draftState.error = action.error;
|
draftState.error = action.error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'SET_LAYOUT_FROM_STATE': {
|
||||||
|
draftState.error = null;
|
||||||
|
draftState.layout = state.layouts[action.uid];
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return draftState;
|
return draftState;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import pluginId from '../../../pluginId';
|
|||||||
const formatLayoutWithMetas = (obj, ctUid, models) => {
|
const formatLayoutWithMetas = (obj, ctUid, models) => {
|
||||||
const formatted = obj.layouts.edit.reduce((acc, current) => {
|
const formatted = obj.layouts.edit.reduce((acc, current) => {
|
||||||
const row = current.map(attribute => {
|
const row = current.map(attribute => {
|
||||||
const fieldSchema = get(obj, ['schema', 'attributes', attribute.name], {});
|
const fieldSchema = get(obj, ['attributes', attribute.name], {});
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
...attribute,
|
...attribute,
|
||||||
@ -35,7 +35,7 @@ const generateRelationQueryInfos = (obj, fieldName, models) => {
|
|||||||
const uid = obj.uid;
|
const uid = obj.uid;
|
||||||
const endPoint = `/${pluginId}/explorer/${uid}/relation-list/${fieldName}`;
|
const endPoint = `/${pluginId}/explorer/${uid}/relation-list/${fieldName}`;
|
||||||
const mainField = get(obj, ['metadatas', fieldName, 'edit', 'mainField'], '');
|
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 shouldDisplayRelationLink = models.indexOf(targetModel) !== -1;
|
||||||
|
|
||||||
const queryInfos = {
|
const queryInfos = {
|
||||||
@ -51,7 +51,7 @@ const generateRelationQueryInfos = (obj, fieldName, models) => {
|
|||||||
const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models) => {
|
const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models) => {
|
||||||
const endPoint = `/${pluginId}/explorer/${ctUid}/relation-list/${fieldName}`;
|
const endPoint = `/${pluginId}/explorer/${ctUid}/relation-list/${fieldName}`;
|
||||||
const mainField = get(obj, ['metadatas', fieldName, 'edit', 'mainField'], '');
|
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 shouldDisplayRelationLink = models.indexOf(targetModel) !== -1;
|
||||||
|
|
||||||
const queryInfos = {
|
const queryInfos = {
|
||||||
@ -69,7 +69,7 @@ const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models)
|
|||||||
// editRelations is an array of strings...
|
// editRelations is an array of strings...
|
||||||
const formatEditRelationsLayoutWithMetas = (obj, models) => {
|
const formatEditRelationsLayoutWithMetas = (obj, models) => {
|
||||||
const formatted = obj.layouts.editRelations.reduce((acc, current) => {
|
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 metadatas = get(obj, ['metadatas', current, 'edit'], {});
|
||||||
const size = 6;
|
const size = 6;
|
||||||
|
|
||||||
@ -89,13 +89,46 @@ const formatEditRelationsLayoutWithMetas = (obj, models) => {
|
|||||||
return formatted;
|
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 formattedCTEditLayout = formatLayoutWithMetas(data.contentType, models);
|
||||||
const ctUid = data.contentType.uid;
|
const ctUid = data.contentType.uid;
|
||||||
const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType, models);
|
const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType, models);
|
||||||
|
const formattedListLayout = formatListLayoutWithMetas(data.contentType);
|
||||||
|
|
||||||
set(data, ['contentType', 'layouts', 'edit'], formattedCTEditLayout);
|
set(data, ['contentType', 'layouts', 'edit'], formattedCTEditLayout);
|
||||||
set(data, ['contentType', 'layouts', 'editRelations'], formattedEditRelationsLayout);
|
set(data, ['contentType', 'layouts', 'editRelations'], formattedEditRelationsLayout);
|
||||||
|
set(data, ['contentType', 'layouts', 'list'], formattedListLayout);
|
||||||
|
|
||||||
Object.keys(data.components).forEach(compoUID => {
|
Object.keys(data.components).forEach(compoUID => {
|
||||||
const formattedCompoEditLayout = formatLayoutWithMetas(
|
const formattedCompoEditLayout = formatLayoutWithMetas(
|
||||||
@ -111,4 +144,4 @@ const formatLayouts = (data, models) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default formatLayouts;
|
export default formatLayouts;
|
||||||
export { formatEditRelationsLayoutWithMetas, formatLayoutWithMetas };
|
export { formatEditRelationsLayoutWithMetas, formatLayoutWithMetas, mergeMetasWithSchema };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user