diff --git a/packages/core/admin/admin/src/StrapiApp.js b/packages/core/admin/admin/src/StrapiApp.js
index 85d0535b5f..f36c126a28 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.translations = translations;
}
addMiddleware(middleware) {
@@ -93,9 +95,9 @@ class StrapiApp {
return acc;
}, {});
- this.translationMessages = Object.keys(this.translationMessages).reduce((acc, current) => {
+ this.translations = Object.keys(this.translations).reduce((acc, current) => {
acc[current] = {
- ...this.translationMessages[current],
+ ...this.translations[current],
...(pluginTranslations[current] || {}),
};
@@ -125,7 +127,7 @@ class StrapiApp {
-
+
<>
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/admin/admin/src/plugins.js b/packages/core/admin/admin/src/plugins.js
index 0b3059d2cc..f595fe116a 100644
--- a/packages/core/admin/admin/src/plugins.js
+++ b/packages/core/admin/admin/src/plugins.js
@@ -3,9 +3,11 @@ import documentationPlugin from '../../../../plugins/documentation/admin/src';
import graphqlPlugin from '../../../../plugins/graphql/admin/src';
import sentryPlugin from '../../../../plugins/sentry/admin/src';
import usersPermissionsPlugin from '../../../../plugins/users-permissions/admin/src';
+import cmPlugin from '../../../content-manager/admin/src';
import emailPlugin from '../../../email/admin/src';
const plugins = {
+ '@strapi/plugin-content-manager': cmPlugin,
'@strapi/plugin-documentation': documentationPlugin,
'@strapi/plugin-email': emailPlugin,
'@strapi/plugin-graphql': graphqlPlugin,
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 c10d170bc1..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();
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/containers/EditViewLayoutManager/selectors.js b/packages/core/content-manager/admin/src/containers/EditViewLayoutManager/selectors.js
index 6d44325b79..e8a8011197 100644
--- a/packages/core/content-manager/admin/src/containers/EditViewLayoutManager/selectors.js
+++ b/packages/core/content-manager/admin/src/containers/EditViewLayoutManager/selectors.js
@@ -1,5 +1,5 @@
import pluginId from '../../pluginId';
-const selectLayout = state => state.get(`${pluginId}_editViewLayoutManager`).currentLayout;
+const selectLayout = state => state.[`${pluginId}_editViewLayoutManager`].currentLayout;
export default selectLayout;
diff --git a/packages/core/content-manager/admin/src/containers/ListView/selectors.js b/packages/core/content-manager/admin/src/containers/ListView/selectors.js
index eaedece71a..da6b6143a1 100644
--- a/packages/core/content-manager/admin/src/containers/ListView/selectors.js
+++ b/packages/core/content-manager/admin/src/containers/ListView/selectors.js
@@ -5,7 +5,7 @@ import { initialState } from './reducer';
/**
* Direct selector to the listView state domain
*/
-const listViewDomain = () => state => state.get(`${pluginId}_listView`) || initialState;
+const listViewDomain = () => state => state[`${pluginId}_listView`] || initialState;
/**
* Other specific selectors
diff --git a/packages/core/content-manager/admin/src/containers/Main/selectors.js b/packages/core/content-manager/admin/src/containers/Main/selectors.js
index b0a3fa9022..8d6e83473d 100644
--- a/packages/core/content-manager/admin/src/containers/Main/selectors.js
+++ b/packages/core/content-manager/admin/src/containers/Main/selectors.js
@@ -3,7 +3,7 @@ import pluginId from '../../pluginId';
import { initialState } from './reducer';
const selectMainDomain = () => state => {
- return state.get(`${pluginId}_main`) || initialState;
+ return state[`${pluginId}_main`] || initialState;
};
const makeSelectMain = () =>
diff --git a/packages/core/content-manager/admin/src/hooks/useFindRedirectionLink/selectors.js b/packages/core/content-manager/admin/src/hooks/useFindRedirectionLink/selectors.js
index 857c325c94..762110e486 100644
--- a/packages/core/content-manager/admin/src/hooks/useFindRedirectionLink/selectors.js
+++ b/packages/core/content-manager/admin/src/hooks/useFindRedirectionLink/selectors.js
@@ -1,5 +1,5 @@
const selectMenuLinks = state => {
- const menuState = state.get('menu');
+ const menuState = state.menu;
return menuState.collectionTypesSectionLinks;
};
diff --git a/packages/core/content-manager/admin/src/index.js b/packages/core/content-manager/admin/src/index.js
index cc0fc01123..4f25f982a2 100644
--- a/packages/core/content-manager/admin/src/index.js
+++ b/packages/core/content-manager/admin/src/index.js
@@ -9,44 +9,43 @@ import pluginPkg from '../../package.json';
import pluginId from './pluginId';
import pluginLogo from './assets/images/logo.svg';
import App from './containers/Main';
-
import ConfigureViewButton from './InjectedComponents/ContentTypeBuilder/ConfigureViewButton';
-import lifecycles from './lifecycles';
import reducers from './reducers';
import trads from './translations';
-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,
- lifecycles,
- mainComponent: App,
- name: pluginPkg.strapi.name,
- pluginLogo,
- preventComponentRendering: false,
- reducers,
- trads,
- };
+const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
+const icon = pluginPkg.strapi.icon;
+const name = pluginPkg.strapi.name;
- return strapi.registerPlugin(plugin);
+export default {
+ register(app) {
+ app.addReducers(reducers);
+
+ app.registerPlugin({
+ description: pluginDescription,
+ icon,
+ id: pluginId,
+ // TODO
+ 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,
+ mainComponent: App,
+ name,
+ pluginLogo,
+ preventComponentRendering: false,
+ trads,
+ });
+ },
+ boot() {},
};
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/selectors.js b/packages/core/content-manager/admin/src/selectors.js
index c9c1d3ca77..4f0296c725 100644
--- a/packages/core/content-manager/admin/src/selectors.js
+++ b/packages/core/content-manager/admin/src/selectors.js
@@ -1,6 +1,6 @@
import pluginId from './pluginId';
-export const selectPermissions = state => state.get(`${pluginId}_rbacManager`).permissions;
+export const selectPermissions = state => state[`${pluginId}_rbacManager`].permissions;
export const selectCollectionTypePermissions = state =>
- state.get('permissionsManager').collectionTypesRelatedPermissions;
+ state.permissionsManager.collectionTypesRelatedPermissions;
diff --git a/packages/core/content-manager/admin/src/sharedReducers/crudReducer/selectors.js b/packages/core/content-manager/admin/src/sharedReducers/crudReducer/selectors.js
index 0669de9051..31a3823f07 100644
--- a/packages/core/content-manager/admin/src/sharedReducers/crudReducer/selectors.js
+++ b/packages/core/content-manager/admin/src/sharedReducers/crudReducer/selectors.js
@@ -1,5 +1,5 @@
import pluginId from '../../pluginId';
-const selectCrudReducer = state => state.get(`${pluginId}_editViewCrudReducer`);
+const selectCrudReducer = state => state[`${pluginId}_editViewCrudReducer`];
export default selectCrudReducer;
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 = {
diff --git a/packages/core/helper-plugin/lib/src/components/InputSelect/Select.js b/packages/core/helper-plugin/lib/src/components/InputSelect/Select.js
index 8ca10cc1eb..10f0d05d7a 100644
--- a/packages/core/helper-plugin/lib/src/components/InputSelect/Select.js
+++ b/packages/core/helper-plugin/lib/src/components/InputSelect/Select.js
@@ -8,7 +8,7 @@ const Select = styled.select`
padding-left: 1rem;
background-position: right -1px center;
background-repeat: no-repeat;
- background-image: url(${Bkg});
+ background-image: url("${Bkg}");
border: 1px solid #e3e9f3;
border-radius: 0.25rem;
line-height: 3.2rem;
diff --git a/packages/core/helper-plugin/lib/src/components/LiLink/StyledLink.js b/packages/core/helper-plugin/lib/src/components/LiLink/StyledLink.js
index 6d0bb1b479..a0934c6c9c 100644
--- a/packages/core/helper-plugin/lib/src/components/LiLink/StyledLink.js
+++ b/packages/core/helper-plugin/lib/src/components/LiLink/StyledLink.js
@@ -21,7 +21,7 @@ const StyledLink = styled(Link)`
}
.layout {
display: inline-block;
- background-image: url(${Layout});
+ background-image: url("${Layout}");
}
&:hover {
text-decoration: none;
@@ -31,7 +31,7 @@ const StyledLink = styled(Link)`
color: #007eff;
}
.layout {
- background-image: url(${LayoutHover});
+ background-image: url("${LayoutHover}");
}
}
`;
diff --git a/packages/core/helper-plugin/lib/src/components/PageFooter/Wrapper.js b/packages/core/helper-plugin/lib/src/components/PageFooter/Wrapper.js
index e15fe2a40b..19ba881721 100644
--- a/packages/core/helper-plugin/lib/src/components/PageFooter/Wrapper.js
+++ b/packages/core/helper-plugin/lib/src/components/PageFooter/Wrapper.js
@@ -18,6 +18,7 @@ const Wrapper = styled.div`
display: flex;
> select {
+ background-image: url("${Bkg}");
width: 75px !important;
height: 3.2rem !important;
padding-top: 0rem;
@@ -25,7 +26,6 @@ const Wrapper = styled.div`
padding-right: 3rem;
background-position: right -1px center;
background-repeat: no-repeat;
- background-image: url(${Bkg});
border: 1px solid #e3e9f3;
border-radius: 0.25rem;
line-height: 29px;