Merge pull request #10530 from strapi/core/remove-middleware-cm-edit-layout

Core/remove middleware cm edit layout
This commit is contained in:
cyril lopez 2021-06-23 10:07:52 +02:00 committed by GitHub
commit 63c7dff65a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 151 deletions

View File

@ -1,3 +1,27 @@
/**
* Hook that allows to mutate the displayed headers of the list view table
* @constant
* @type {string}
*/
export const INJECT_COLUMN_IN_TABLE = 'CM/pages/ListView/inject-column-in-table';
/**
* Hook that allows to mutate the CM's collection types links pre-set filters
* @constant
* @type {string}
*/
export const MUTATE_COLLECTION_TYPES_LINKS = 'CM/pages/App/mutate-collection-types-links';
/**
* Hook that allows to mutate the CM's edit view layout
* @constant
* @type {string}
*/
export const MUTATE_EDIT_VIEW_LAYOUT = 'CM/pages/EditView/mutate-edit-view-layout';
/**
* Hook that allows to mutate the CM's single types links pre-set filters
* @constant
* @type {string}
*/
export const MUTATE_SINGLE_TYPES_LINKS = 'CM/pages/App/mutate-single-types-links';

View File

@ -9,6 +9,7 @@ import pluginPkg from '../../package.json';
import {
INJECT_COLUMN_IN_TABLE,
MUTATE_COLLECTION_TYPES_LINKS,
MUTATE_EDIT_VIEW_LAYOUT,
MUTATE_SINGLE_TYPES_LINKS,
} from './exposedHooks';
import pluginId from './pluginId';
@ -33,12 +34,10 @@ export default {
});
app.addReducers(reducers);
// Hook that allows to mutate the displayed headers of the list view table
app.createHook(INJECT_COLUMN_IN_TABLE);
// Hook that allows to mutate the CM's link pre-set filters
app.createHook(MUTATE_COLLECTION_TYPES_LINKS);
app.createHook(MUTATE_SINGLE_TYPES_LINKS);
app.createHook(MUTATE_EDIT_VIEW_LAYOUT);
app.registerPlugin({
description: pluginDescription,

View File

@ -1,7 +1,8 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { LoadingIndicatorPage, useQueryParams } from '@strapi/helper-plugin';
import { LoadingIndicatorPage, useQueryParams, useStrapiApp } from '@strapi/helper-plugin';
import { MUTATE_EDIT_VIEW_LAYOUT } from '../../exposedHooks';
import { useSyncRbac } from '../../hooks';
import { resetProps, setLayout } from './actions';
import selectLayout from './selectors';
@ -11,15 +12,19 @@ const EditViewLayoutManager = ({ layout, ...rest }) => {
const currentLayout = useSelector(selectLayout);
const dispatch = useDispatch();
const [{ query }] = useQueryParams();
const { runHookWaterfall } = useStrapiApp();
const permissions = useSyncRbac(query, rest.slug, 'editView');
useEffect(() => {
dispatch(setLayout(layout, query));
// Allow the plugins to extend the edit view layout
const mutatedLayout = runHookWaterfall(MUTATE_EDIT_VIEW_LAYOUT, { layout, query });
dispatch(setLayout(mutatedLayout.layout, query));
return () => {
dispatch(resetProps());
};
}, [layout, dispatch, query]);
}, [layout, dispatch, query, runHookWaterfall]);
if (!currentLayout || !permissions) {
return <LoadingIndicatorPage />;

View File

@ -97,60 +97,57 @@ const enhanceComponentLayoutForRelations = (layout, locale) =>
return enhancedRow;
});
const extendCMEditViewLayoutMiddleware = () => () => next => action => {
if (action.type !== 'ContentManager/EditViewLayoutManager/SET_LAYOUT') {
return next(action);
}
const getPathToContentType = pathArray => ['contentType', ...pathArray];
const hasi18nEnabled = get(
action,
const mutateEditViewLayoutHook = ({ layout, query }) => {
const hasI18nEnabled = get(
layout,
getPathToContentType(['pluginOptions', 'i18n', 'localized']),
false
);
if (!hasi18nEnabled) {
return next(action);
if (!hasI18nEnabled) {
return { layout, query };
}
const currentLocale = get(action, ['query', 'plugins', 'i18n', 'locale'], null);
const currentLocale = get(query, ['plugins', 'i18n', 'locale'], null);
// This might break the cm, has the user might be redirected to the homepage
if (!currentLocale) {
return next(action);
return { layout, query };
}
const editLayoutPath = getPathToContentType(['layouts', 'edit']);
const editRelationsPath = getPathToContentType(['layouts', 'editRelations']);
const editLayout = get(action, editLayoutPath);
const editRelationsLayout = get(action, editRelationsPath);
const editLayout = get(layout, editLayoutPath);
const editRelationsLayout = get(layout, editRelationsPath);
const nextEditRelationLayout = enhanceRelationLayout(editRelationsLayout, currentLocale);
const nextEditLayout = enhanceEditLayout(editLayout);
const enhancedLayouts = {
...action.layout.contentType.layouts,
...layout.contentType.layouts,
editRelations: nextEditRelationLayout,
edit: nextEditLayout,
};
const components = enhanceComponentsLayout(action.layout.components, currentLocale);
const enhancedAction = {
...action,
const components = enhanceComponentsLayout(layout.components, currentLocale);
const enhancedData = {
query,
layout: {
...action.layout,
...layout,
contentType: {
...action.layout.contentType,
...layout.contentType,
layouts: enhancedLayouts,
},
components,
},
};
return next(enhancedAction);
return enhancedData;
};
const getPathToContentType = pathArray => ['layout', 'contentType', ...pathArray];
export default extendCMEditViewLayoutMiddleware;
export default mutateEditViewLayoutHook;
export {
enhanceComponentLayoutForRelations,
enhanceComponentsLayout,

View File

@ -1,102 +1,106 @@
import React from 'react';
import { Globe, GlobeCrossed } from '@buffetjs/icons';
import { getTrad } from '../../utils';
import extendCMEditViewLayoutMiddleware, {
import mutateEditViewLayout, {
enhanceComponentsLayout,
enhanceEditLayout,
enhanceRelationLayout,
} from '../extendCMEditViewLayoutMiddleware';
} from '../mutateEditViewLayout';
const localizedTrad = getTrad('Field.localized');
const localizedTradDefaultMessage = 'This value is unique for the selected locale';
const notLocalizedTrad = getTrad('Field.not-localized');
const notLocalizedTradDefaultMessage = 'This value is common to all locales';
describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
it('should forward the action if the type is undefined', () => {
const middleware = extendCMEditViewLayoutMiddleware();
const action = { test: true, type: undefined };
const next = jest.fn();
middleware()(next)(action);
expect(next).toBeCalledWith(action);
});
it('should forward if the type is not correct', () => {
const middleware = extendCMEditViewLayoutMiddleware();
const action = { test: true, type: 'TEST' };
const next = jest.fn();
middleware()(next)(action);
expect(next).toBeCalledWith(action);
});
describe('should forward when the type is ContentManager/EditViewLayoutManager/SET_LAYOUT', () => {
it('should forward when i18n is not enabled on the content type', () => {
const layout = {
components: {},
contentType: {
uid: 'test',
pluginOptions: { i18n: { localized: false } },
layouts: {
edit: ['test'],
},
describe('i18n | contentManagerHooks | mutateEditViewLayout', () => {
it('should forward when i18n is not enabled on the content type', () => {
const layout = {
components: {},
contentType: {
uid: 'test',
pluginOptions: { i18n: { localized: false } },
layouts: {
edit: ['test'],
},
};
const action = {
type: 'ContentManager/EditViewLayoutManager/SET_LAYOUT',
layout,
};
const middleware = extendCMEditViewLayoutMiddleware();
const next = jest.fn();
},
};
const data = {
layout,
query: null,
};
const results = mutateEditViewLayout(data);
middleware()(next)(action);
expect(results).toEqual(data);
});
expect(next).toBeCalledWith(action);
});
it('should forward the action when i18n is enabled and the query.locale is not defined', () => {
const layout = {
contentType: {
uid: 'test',
pluginOptions: { i18n: { localized: true } },
layouts: {
edit: [],
editRelations: [
{
fieldSchema: {},
metadatas: {},
name: 'addresses',
queryInfos: {},
size: 6,
targetModelPluginOptions: {},
},
],
},
},
};
it('should forward the action when i18n is enabled and the query.locale is not defined', () => {
const layout = {
contentType: {
uid: 'test',
pluginOptions: { i18n: { localized: true } },
layouts: {
edit: [],
editRelations: [
{
fieldSchema: {},
metadatas: {},
name: 'addresses',
queryInfos: {},
size: 6,
targetModelPluginOptions: {},
const data = {
query: null,
layout,
};
const results = mutateEditViewLayout(data);
expect(results).toEqual(data);
});
it('should modify the editRelations layout when i18n is enabled and the query.locale is defined', () => {
const layout = {
contentType: {
uid: 'test',
pluginOptions: { i18n: { localized: true } },
layouts: {
edit: [],
editRelations: [
{
fieldSchema: {},
metadatas: {},
name: 'addresses',
queryInfos: {
test: true,
defaultParams: {},
paramsToKeep: ['plugins.i18n.locale'],
},
],
},
size: 6,
targetModelPluginOptions: {},
},
],
},
};
},
components: {},
};
const action = {
type: 'ContentManager/EditViewLayoutManager/SET_LAYOUT',
layout,
};
const middleware = extendCMEditViewLayoutMiddleware();
const data = {
layout,
query: { plugins: { i18n: { locale: 'en' } } },
};
const results = mutateEditViewLayout(data);
const next = jest.fn();
middleware()(next)(action);
expect(next).toBeCalledWith(action);
});
it('should modify the editRelations layout when i18n is enabled and the query.locale is defined', () => {
const layout = {
expect(results).toEqual({
...data,
layout: {
...layout,
contentType: {
uid: 'test',
pluginOptions: { i18n: { localized: true } },
...layout.contentType,
layouts: {
edit: [],
editRelations: [
@ -111,53 +115,15 @@ describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
},
size: 6,
targetModelPluginOptions: {},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
},
],
},
},
components: {},
};
const action = {
type: 'ContentManager/EditViewLayoutManager/SET_LAYOUT',
layout,
query: { plugins: { i18n: { locale: 'en' } } },
};
const middleware = extendCMEditViewLayoutMiddleware();
const next = jest.fn();
middleware()(next)(action);
expect(next).toBeCalledWith({
...action,
layout: {
...layout,
contentType: {
...layout.contentType,
layouts: {
edit: [],
editRelations: [
{
fieldSchema: {},
metadatas: {},
name: 'addresses',
queryInfos: {
test: true,
defaultParams: {},
paramsToKeep: ['plugins.i18n.locale'],
},
size: 6,
targetModelPluginOptions: {},
labelIcon: {
title: { id: localizedTrad, defaultMessage: localizedTradDefaultMessage },
icon: <Globe />,
},
},
],
},
},
},
});
},
});
});

View File

@ -19,6 +19,7 @@ import DeleteModalAdditionalInfos from './components/DeleteModalAdditionalInfos'
import addLocaleToCollectionTypesLinksHook from './contentManagerHooks/addLocaleToCollectionTypesLinks';
import addLocaleToSingleTypesLinksHook from './contentManagerHooks/addLocaleToSingleTypesLinks';
import addColumnToTableHook from './contentManagerHooks/addColumnToTable';
import mutateEditViewLayoutHook from './contentManagerHooks/mutateEditViewLayout';
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
const icon = pluginPkg.strapi.icon;
@ -50,6 +51,8 @@ export default {
app.registerHook('CM/pages/App/mutate-single-types-links', addLocaleToSingleTypesLinksHook);
// Hook that adds a column into the CM's LV table
app.registerHook('CM/pages/ListView/inject-column-in-table', addColumnToTableHook);
// Hooks that mutates the edit view layout
app.registerHook('CM/pages/EditView/mutate-edit-view-layout', mutateEditViewLayoutHook);
// Add the settings link
app.addSettingsLink('global', {
intlLabel: {

View File

@ -1,12 +1,10 @@
import addCommonFieldsToInitialDataMiddleware from './addCommonFieldsToInitialDataMiddleware';
import extendCMEditViewLayoutMiddleware from './extendCMEditViewLayoutMiddleware';
import extendCTBInitialDataMiddleware from './extendCTBInitialDataMiddleware';
import extendCTBAttributeInitialDataMiddleware from './extendCTBAttributeInitialDataMiddleware';
import localePermissionMiddleware from './localePermissionMiddleware';
const middlewares = [
addCommonFieldsToInitialDataMiddleware,
extendCMEditViewLayoutMiddleware,
extendCTBInitialDataMiddleware,
extendCTBAttributeInitialDataMiddleware,
localePermissionMiddleware,