diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditView/Header.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditView/Header.js index 9f975eed44..a5148d76a7 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditView/Header.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditView/Header.js @@ -2,12 +2,7 @@ import React, { useState } from 'react'; import { useParams, useRouteMatch } from 'react-router-dom'; import { Header as PluginHeader } from '@buffetjs/custom'; -import { - PopUpWarning, - request, - templateObject, - useGlobalContext, -} from 'strapi-helper-plugin'; +import { PopUpWarning, request, templateObject, useGlobalContext } from 'strapi-helper-plugin'; import { get } from 'lodash'; import pluginId from '../../pluginId'; import useDataManager from '../../hooks/useDataManager'; @@ -30,15 +25,13 @@ const Header = () => { slug, clearData, } = useDataManager(); - const isSingleType = useRouteMatch('/plugins/content-manager/singleType'); + const { + params: { contentType }, + } = useRouteMatch('/plugins/content-manager/:contentType'); + const isSingleType = contentType === 'singleType'; - const currentContentTypeMainField = get( - layout, - ['settings', 'mainField'], - 'id' - ); + const currentContentTypeMainField = get(layout, ['settings', 'mainField'], 'id'); const currentContentTypeName = get(layout, ['schema', 'info', 'name']); - const apiId = layout.uid.split('.')[1]; const isCreatingEntry = id === 'create'; /* eslint-disable indent */ @@ -46,8 +39,7 @@ const Header = () => { ? formatMessage({ id: `${pluginId}.containers.Edit.pluginHeader.title.new`, }) - : templateObject({ mainField: currentContentTypeMainField }, initialData) - .mainField; + : templateObject({ mainField: currentContentTypeMainField }, initialData).mainField; /* eslint-enable indent */ const headerTitle = isSingleType ? currentContentTypeName : entryHeaderTitle; @@ -106,9 +98,7 @@ const Header = () => { title: { label: headerTitle && headerTitle.toString(), }, - content: isSingleType - ? `${formatMessage({ id: `${pluginId}.api.id` })} : ${apiId}` - : '', + content: isSingleType ? `${formatMessage({ id: `${pluginId}.api.id` })} : ${layout.apiID}` : '', actions: getHeaderActions(), }; 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 79ceb8eaea..565de2bcb5 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 @@ -1,11 +1,4 @@ -import React, { - memo, - useCallback, - useMemo, - useEffect, - useReducer, - useRef, -} from 'react'; +import React, { memo, useCallback, useMemo, useEffect, useReducer, useRef } from 'react'; import PropTypes from 'prop-types'; import { get } from 'lodash'; import { useHistory, useLocation, useRouteMatch } from 'react-router-dom'; @@ -28,31 +21,22 @@ import reducer, { initialState } from './reducer'; /* eslint-disable react/no-array-index-key */ -const EditView = ({ - components, - currentEnvironment, - layouts, - plugins, - slug, -}) => { +const EditView = ({ components, currentEnvironment, layouts, plugins, slug }) => { const formatLayoutRef = useRef(); formatLayoutRef.current = createAttributesLayout; // Retrieve push to programmatically navigate between views const { push } = useHistory(); // Retrieve the search and the pathname const { search, pathname } = useLocation(); - const isSingleType = useRouteMatch('/plugins/content-manager/singleType'); - const [reducerState, dispatch] = useReducer(reducer, initialState, () => - init(initialState) - ); - const allLayoutData = useMemo(() => get(layouts, [slug], {}), [ - layouts, - slug, + const { + params: { contentType }, + } = useRouteMatch('/plugins/content-manager/:contentType'); + const isSingleType = contentType === 'singleType'; + const [reducerState, dispatch] = useReducer(reducer, initialState, () => init(initialState)); + const allLayoutData = useMemo(() => get(layouts, [slug], {}), [layouts, slug]); + const currentContentTypeLayoutData = useMemo(() => get(allLayoutData, ['contentType'], {}), [ + allLayoutData, ]); - const currentContentTypeLayoutData = useMemo( - () => get(allLayoutData, ['contentType'], {}), - [allLayoutData] - ); const currentContentTypeLayout = useMemo( () => get(currentContentTypeLayoutData, ['layouts', 'edit'], []), [currentContentTypeLayoutData] @@ -68,11 +52,7 @@ const EditView = ({ const getFieldMetas = useCallback( fieldName => { - return get( - currentContentTypeLayoutData, - ['metadatas', fieldName, 'edit'], - {} - ); + return get(currentContentTypeLayoutData, ['metadatas', fieldName, 'edit'], {}); }, [currentContentTypeLayoutData] ); @@ -117,10 +97,7 @@ const EditView = ({ }); }, [currentContentTypeLayout, currentContentTypeSchema.attributes]); - const { - formattedContentTypeLayout, - isDraggingComponent, - } = reducerState.toJS(); + const { formattedContentTypeLayout, isDraggingComponent } = reducerState.toJS(); // We can't use the getQueryParameters helper here because the search // can contain 'redirectUrl' several times since we can navigate between documents @@ -166,14 +143,7 @@ const EditView = ({ } = block; const { max, min } = getField(name); - return ( - - ); + return ; } return ( @@ -182,23 +152,14 @@ const EditView = ({ return (
{fieldsBlock.map(({ name, size }, fieldIndex) => { - const isComponent = - getFieldType(name) === 'component'; + const isComponent = getFieldType(name) === 'component'; if (isComponent) { const componentUid = getFieldComponentUid(name); - const isRepeatable = get( - getField(name), - 'repeatable', - false - ); + const isRepeatable = get(getField(name), 'repeatable', false); const { max, min } = getField(name); - const label = get( - getFieldMetas(name), - 'label', - componentUid - ); + const label = get(getFieldMetas(name), 'label', componentUid); return ( {currentContentTypeLayoutRelations.length > 0 && ( - +
{currentContentTypeLayoutRelations.map(relationName => { const relation = get( diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditViewDataManagerProvider/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditViewDataManagerProvider/index.js index 8472f11e3c..3624f9b19e 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditViewDataManagerProvider/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditViewDataManagerProvider/index.js @@ -2,11 +2,7 @@ import { cloneDeep, get, isEmpty, isEqual, set } from 'lodash'; import PropTypes from 'prop-types'; import React, { useEffect, useReducer, useState } from 'react'; import { Prompt, useParams, useRouteMatch } from 'react-router-dom'; -import { - LoadingIndicatorPage, - request, - useGlobalContext, -} from 'strapi-helper-plugin'; +import { LoadingIndicatorPage, request, useGlobalContext } from 'strapi-helper-plugin'; import EditViewDataManagerContext from '../../contexts/EditViewDataManager'; import pluginId from '../../pluginId'; import init from './init'; @@ -21,12 +17,7 @@ import { const getRequestUrl = path => `/${pluginId}/explorer/${path}`; -const EditViewDataManagerProvider = ({ - allLayoutData, - children, - redirectToPreviousPage, - slug, -}) => { +const EditViewDataManagerProvider = ({ allLayoutData, children, redirectToPreviousPage, slug }) => { const { id } = useParams(); // Retrieve the search const [reducerState, dispatch] = useReducer(reducer, initialState, init); @@ -44,7 +35,10 @@ const EditViewDataManagerProvider = ({ const abortController = new AbortController(); const { signal } = abortController; const { emitEvent, formatMessage } = useGlobalContext(); - const isSingleType = useRouteMatch('/plugins/content-manager/singleType'); + const { + params: { contentType }, + } = useRouteMatch('/plugins/content-manager/:contentType'); + const isSingleType = contentType === 'singleType'; useEffect(() => { if (!isLoading) { @@ -75,9 +69,7 @@ const EditViewDataManagerProvider = ({ } }; - const componentsDataStructure = Object.keys( - allLayoutData.components - ).reduce((acc, current) => { + const componentsDataStructure = Object.keys(allLayoutData.components).reduce((acc, current) => { acc[current] = createDefaultForm( get(allLayoutData, ['components', current, 'schema', 'attributes'], {}), allLayoutData.components @@ -114,11 +106,7 @@ const EditViewDataManagerProvider = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [id, slug, isCreatingEntry]); - const addComponentToDynamicZone = ( - keys, - componentUid, - shouldCheckErrors = false - ) => { + const addComponentToDynamicZone = (keys, componentUid, shouldCheckErrors = false) => { emitEvent('addComponentToDynamicZone'); dispatch({ type: 'ADD_COMPONENT_TO_DYNAMIC_ZONE', @@ -144,11 +132,7 @@ const EditViewDataManagerProvider = ({ }); }; - const addRepeatableComponentToField = ( - keys, - componentUid, - shouldCheckErrors = false - ) => { + const addRepeatableComponentToField = (keys, componentUid, shouldCheckErrors = false) => { dispatch({ type: 'ADD_REPEATABLE_COMPONENT_TO_FIELD', keys: keys.split('.'), @@ -358,9 +342,7 @@ const EditViewDataManagerProvider = ({ }; const shouldCheckDZErrors = dzName => { - const doesDZHaveError = Object.keys(formErrors).some( - key => key.split('.')[0] === dzName - ); + const doesDZHaveError = Object.keys(formErrors).some(key => key.split('.')[0] === dzName); const shouldCheckErrors = !isEmpty(formErrors) && doesDZHaveError; return shouldCheckErrors; 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 4811249c61..e533315f49 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 @@ -2,12 +2,8 @@ import React, { Suspense, lazy, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators, compose } from 'redux'; -import { Switch, Route } from 'react-router-dom'; -import { - LoadingIndicatorPage, - useGlobalContext, - request, -} from 'strapi-helper-plugin'; +import { Switch, Route, useRouteMatch } from 'react-router-dom'; +import { LoadingIndicatorPage, useGlobalContext, request } from 'strapi-helper-plugin'; import { DndProvider } from 'react-dnd'; import HTML5Backend from 'react-dnd-html5-backend'; import pluginId from '../../pluginId'; @@ -25,12 +21,8 @@ import reducer from './reducer'; import makeSelectMain from './selectors'; const EditSettingsView = lazy(() => import('../EditSettingsView')); -const CollectionTypeRecursivePath = lazy(() => - import('../CollectionTypeRecursivePath') -); -const SingleTypeRecursivePath = lazy(() => - import('../SingleTypeRecursivePath') -); +const CollectionTypeRecursivePath = lazy(() => import('../CollectionTypeRecursivePath')); +const SingleTypeRecursivePath = lazy(() => import('../SingleTypeRecursivePath')); function Main({ deleteLayout, @@ -50,7 +42,9 @@ function Main({ strapi.useInjectReducer({ key: 'main', reducer, pluginId }); const { emitEvent } = useGlobalContext(); - const slug = pathname.split('/')[4]; + const { + params: { slug }, + } = useRouteMatch('/plugins/content-manager/:contentType/:slug'); const getDataRef = useRef(); const getLayoutRef = useRef(); const resetPropsRef = useRef(); @@ -74,10 +68,9 @@ function Main({ getLayoutRef.current = async uid => { try { - const { data: layout } = await request( - getRequestUrl(`content-types/${uid}`), - { method: 'GET' } - ); + const { data: layout } = await request(getRequestUrl(`content-types/${uid}`), { + method: 'GET', + }); getLayoutSucceeded(layout, uid); } catch (err) { @@ -86,8 +79,7 @@ function Main({ }; resetPropsRef.current = resetProps; - const shouldShowLoader = - !pathname.includes('ctm-configurations/') && layouts[slug] === undefined; + const shouldShowLoader = !pathname.includes('ctm-configurations/') && layouts[slug] === undefined; useEffect(() => { getDataRef.current(); @@ -114,9 +106,7 @@ function Main({ deleteLayouts={deleteLayouts} emitEvent={emitEvent} components={components} - componentsAndModelsMainPossibleMainFields={ - componentsAndModelsMainPossibleMainFields - } + componentsAndModelsMainPossibleMainFields={componentsAndModelsMainPossibleMainFields} layouts={layouts} models={models} plugins={plugins} diff --git a/packages/strapi-plugin-content-manager/controllers/ContentTypes.js b/packages/strapi-plugin-content-manager/controllers/ContentTypes.js index b376f8313a..7a70faff81 100644 --- a/packages/strapi-plugin-content-manager/controllers/ContentTypes.js +++ b/packages/strapi-plugin-content-manager/controllers/ContentTypes.js @@ -2,10 +2,7 @@ const _ = require('lodash'); -const { - createModelConfigurationSchema, - validateKind, -} = require('./validation'); +const { createModelConfigurationSchema, validateKind } = require('./validation'); module.exports = { /** @@ -27,10 +24,7 @@ module.exports = { if (uid.startsWith('strapi::')) return false; if (uid === 'plugins::upload.file') return false; - if ( - kind && - _.get(strapi.contentTypes[uid], 'kind', 'collectionType') !== kind - ) { + if (kind && _.get(strapi.contentTypes[uid], 'kind', 'collectionType') !== kind) { return false; } @@ -63,14 +57,14 @@ module.exports = { } const service = strapi.plugins['content-manager'].services.contenttypes; - const componentService = - strapi.plugins['content-manager'].services.components; + const componentService = strapi.plugins['content-manager'].services.components; const contentTypeConfigurations = await service.getConfiguration(uid); const data = { contentType: { uid, + apiID: contentType.modelName, schema: service.formatContentTypeSchema(contentType), ...contentTypeConfigurations, }, @@ -104,10 +98,7 @@ module.exports = { let input; try { - input = await createModelConfigurationSchema( - contentType, - schema - ).validate(body, { + input = await createModelConfigurationSchema(contentType, schema).validate(body, { abortEarly: false, stripUnknown: true, strict: true,