diff --git a/packages/core/admin/admin/src/StrapiApp.js b/packages/core/admin/admin/src/StrapiApp.js index 85d0535b5f..45be44beed 100644 --- a/packages/core/admin/admin/src/StrapiApp.js +++ b/packages/core/admin/admin/src/StrapiApp.js @@ -5,7 +5,7 @@ import { QueryClientProvider, QueryClient } from 'react-query'; import { ThemeProvider } from 'styled-components'; import { StrapiProvider } from '@strapi/helper-plugin'; import configureStore from './core/store/configureStore'; -import { Plugin } from './core/apis'; +import { Components, Fields, Plugin } from './core/apis'; import basename from './utils/basename'; import App from './pages/App'; import LanguageProvider from './components/LanguageProvider'; @@ -38,11 +38,13 @@ const appLocales = Object.keys(translations); class StrapiApp { constructor({ appPlugins }) { - this.translationMessages = translations; this.appPlugins = appPlugins || {}; + this.componentApi = Components(); + this.fieldApi = Fields(); this.middlewares = []; this.plugins = {}; this.reducers = { ...reducers }; + this.translationMessages = translations; } addMiddleware(middleware) { diff --git a/packages/core/admin/admin/src/core/apis/Components.js b/packages/core/admin/admin/src/core/apis/Components.js new file mode 100644 index 0000000000..5b2aeb5e6b --- /dev/null +++ b/packages/core/admin/admin/src/core/apis/Components.js @@ -0,0 +1,43 @@ +import { cloneDeep } from 'lodash'; +import invariant from 'invariant'; + +// TODO this API should be merged with the components one +class Components { + components = {}; + + getComponent = name => { + invariant(name, 'A name must be provided'); + + return cloneDeep(this.components[name]) || null; + }; + + getComponents = () => { + const components = cloneDeep(this.components); + + return Object.keys(components).reduce((acc, current) => { + acc[current] = components[current].Component; + + return acc; + }, {}); + }; + + registerComponent = component => { + const { name, Component } = component; + + invariant(Component, 'A Component must be provided'); + invariant(name, 'A name must be provided'); + invariant(this.components[name] === undefined, 'A similar field already exists'); + + this.components[name] = { Component }; + }; + + removeComponent = name => { + invariant(name, 'A name must be provided in order to remove a field'); + + delete this.components[name]; + }; +} + +export default () => { + return new Components(); +}; diff --git a/packages/core/admin/admin/src/core/apis/Fields.js b/packages/core/admin/admin/src/core/apis/Fields.js new file mode 100644 index 0000000000..2db0b16e67 --- /dev/null +++ b/packages/core/admin/admin/src/core/apis/Fields.js @@ -0,0 +1,43 @@ +import { cloneDeep } from 'lodash'; +import invariant from 'invariant'; + +// TODO this API should be merged with the components one +class Fields { + fields = {}; + + getField = type => { + invariant(type, 'A type must be provided'); + + return cloneDeep(this.fields[type]) || null; + }; + + getFields = () => { + const fields = cloneDeep(this.fields); + + return Object.keys(fields).reduce((acc, current) => { + acc[current] = fields[current].Component; + + return acc; + }, {}); + }; + + registerField = field => { + const { type, Component } = field; + + invariant(Component, 'A Component must be provided'); + invariant(type, 'A type must be provided'); + invariant(this.fields[type] === undefined, 'A similar field already exists'); + + this.fields[type] = { Component }; + }; + + removeField = type => { + invariant(type, 'A type must be provided in order to remove a field'); + + delete this.fields[type]; + }; +} + +export default () => { + return new Fields(); +}; diff --git a/packages/core/admin/admin/src/core/apis/index.js b/packages/core/admin/admin/src/core/apis/index.js index 77c8702e6d..1837f9a21b 100644 --- a/packages/core/admin/admin/src/core/apis/index.js +++ b/packages/core/admin/admin/src/core/apis/index.js @@ -1,2 +1,3 @@ -// eslint-disable-next-line import/prefer-default-export +export { default as Components } from './Components'; +export { default as Fields } from './Fields'; export { default as Plugin } from './Plugin'; diff --git a/packages/core/content-manager/admin/src/components/Inputs/index.js b/packages/core/content-manager/admin/src/components/Inputs/index.js index d870ca8d2c..39630fa06b 100644 --- a/packages/core/content-manager/admin/src/components/Inputs/index.js +++ b/packages/core/content-manager/admin/src/components/Inputs/index.js @@ -36,6 +36,7 @@ function Inputs({ queryInfos, value, }) { + // TODO change to app const { strapi: { fieldApi }, } = useStrapi(); @@ -174,8 +175,7 @@ function Inputs({ ]); const otherFields = useMemo(() => { - // return fieldApi.getFields(); - return {}; + return fieldApi.getFields(); }, [fieldApi]); const { description, visible } = metadatas; diff --git a/packages/core/content-manager/admin/src/components/Wysiwyg/MediaLib.js b/packages/core/content-manager/admin/src/components/Wysiwyg/MediaLib.js index a2bf70ddec..a14aa1b312 100644 --- a/packages/core/content-manager/admin/src/components/Wysiwyg/MediaLib.js +++ b/packages/core/content-manager/admin/src/components/Wysiwyg/MediaLib.js @@ -17,7 +17,7 @@ const MediaLib = ({ isOpen, onChange, onToggle }) => { } }, [isOpen]); - const Component = getComponent('media-library').Component; + const Component = getComponent('media-library')?.Component; const handleInputChange = data => { if (data) { diff --git a/packages/core/content-manager/admin/src/index.js b/packages/core/content-manager/admin/src/index.js index 31c12446ba..4f25f982a2 100644 --- a/packages/core/content-manager/admin/src/index.js +++ b/packages/core/content-manager/admin/src/index.js @@ -44,45 +44,8 @@ export default { name, pluginLogo, preventComponentRendering: false, - // reducers, trads, }); }, boot() {}, }; - -// export default strapi => { -// const pluginDescription = pluginPkg.strapi.description || pluginPkg.description; -// const plugin = { -// blockerComponent: null, -// blockerComponentProps: {}, -// description: pluginDescription, -// icon: pluginPkg.strapi.icon, -// id: pluginId, -// initializer: null, -// injectedComponents: [ -// { -// plugin: 'content-type-builder.listView', -// area: 'list.link', -// component: ConfigureViewButton, -// key: 'content-manager.link', -// }, -// ], -// injectionZones: { -// editView: { informations: [] }, -// listView: { actions: [], deleteModalAdditionalInfos: [] }, -// }, -// isReady: true, -// isRequired: pluginPkg.strapi.required || false, -// layout: null, - -// mainComponent: App, -// name: pluginPkg.strapi.name, -// pluginLogo, -// preventComponentRendering: false, -// reducers, -// trads, -// }; - -// return strapi.registerPlugin(plugin); -// }; diff --git a/packages/core/content-manager/admin/src/lifecycles.js b/packages/core/content-manager/admin/src/lifecycles.js deleted file mode 100644 index 4e2850191c..0000000000 --- a/packages/core/content-manager/admin/src/lifecycles.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * - * SET THE HOOKS TO ENABLE THE MAGIC OF STRAPI. - * ------------------------------------------- - * - * Secure, customise and enhance your project by setting - * the hooks via this file. - * - */ - -function lifecycles() { - // Set hooks for the AdminPage container. - // Note: we don't need to specify the first argument because we already know what "willSecure" refers to. - // this.setHooks({ - // didGetSecuredData, - // }); -} - -export default lifecycles; diff --git a/packages/core/content-manager/admin/src/tests/selectors.test.js b/packages/core/content-manager/admin/src/tests/selectors.test.js index e26e982b17..622aad3304 100644 --- a/packages/core/content-manager/admin/src/tests/selectors.test.js +++ b/packages/core/content-manager/admin/src/tests/selectors.test.js @@ -4,16 +4,16 @@ describe('selectors', () => { let store; beforeEach(() => { - store = new Map(); + store = {}; }); describe('selectPermissions', () => { it('resolves the permissions key of the "content-manager_rbacManager" store key', () => { - store.set('content-manager_rbacManager', { + store['content-manager_rbacManager'] = { permissions: { some: 'permission', }, - }); + }; const actual = selectPermissions(store); const expected = { @@ -26,11 +26,11 @@ describe('selectors', () => { describe('selectCollectionTypePermissions', () => { it('resolves the permissions key of the "permissionsManager" store key', () => { - store.set('permissionsManager', { + store.permissionsManager = { collectionTypesRelatedPermissions: { some: 'permission again', }, - }); + }; const actual = selectCollectionTypePermissions(store); const expected = {