diff --git a/packages/strapi-admin/admin/src/containers/PluginDispatcher/index.js b/packages/strapi-admin/admin/src/containers/PluginDispatcher/index.js
new file mode 100644
index 0000000000..1d3adfdb10
--- /dev/null
+++ b/packages/strapi-admin/admin/src/containers/PluginDispatcher/index.js
@@ -0,0 +1,55 @@
+/**
+ *
+ * PluginDispatcher
+ *
+ */
+
+import React, { memo } from 'react';
+import PropTypes from 'prop-types';
+import { get } from 'lodash';
+
+import Helmet from 'react-helmet';
+import BlockerComponent from 'components/BlockerComponent';
+import ErrorBoundary from 'components/ErrorBoundary';
+
+export function PluginDispatcher(props) {
+ const {
+ global: { plugins },
+ match: {
+ params: { pluginId },
+ },
+ } = props;
+
+ const pluginToRender = get(plugins, pluginId, null);
+
+ if (!pluginToRender) {
+ return null;
+ }
+
+ const { mainComponent, name, preventComponentRendering } = pluginToRender;
+ const blockerComponentProps = pluginToRender.blockerComponentProps;
+ let PluginEntryComponent = preventComponentRendering
+ ? BlockerComponent
+ : mainComponent;
+
+ if (preventComponentRendering && pluginToRender.blockerComponent) {
+ PluginEntryComponent = pluginToRender.blockerComponent;
+ }
+
+ return (
+
+ );
+}
+
+PluginDispatcher.defaultProps = {};
+PluginDispatcher.propTypes = {
+ global: PropTypes.object.isRequired,
+ match: PropTypes.object.isRequired,
+};
+
+export default memo(PluginDispatcher);
diff --git a/packages/strapi-admin/admin/src/containers/PluginDispatcher/tests/index.test.js b/packages/strapi-admin/admin/src/containers/PluginDispatcher/tests/index.test.js
new file mode 100644
index 0000000000..ff357d368f
--- /dev/null
+++ b/packages/strapi-admin/admin/src/containers/PluginDispatcher/tests/index.test.js
@@ -0,0 +1,75 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import BlockerComponent from 'components/BlockerComponent';
+import { PluginDispatcher } from '../index';
+
+const BlockerComponent2 = () => BlockerComponent
;
+const Email = () => Email Plugin
;
+
+describe('', () => {
+ it('Should return null if the params does not match the pluginId', () => {
+ const props = {
+ global: { plugins: {} },
+ match: { params: { pluginId: 'email' } },
+ };
+
+ const rendered = shallow();
+
+ expect(rendered.children()).toHaveLength(0);
+ });
+
+ it('Should return the BlockerComponent if the plugin preventRendering prop is true', () => {
+ const props = {
+ global: {
+ plugins: {
+ email: {
+ mainComponent: Email,
+ preventComponentRendering: true,
+ blockerComponent: null,
+ },
+ },
+ },
+ match: { params: { pluginId: 'email' } },
+ };
+
+ const renderedComponent = shallow();
+
+ expect(renderedComponent.find(BlockerComponent)).toHaveLength(1);
+ });
+
+ it('Should return a custom BlockerComponent if the plugin preventRendering prop is true and a custom blocker is given', () => {
+ const props = {
+ global: {
+ plugins: {
+ email: {
+ mainComponent: Email,
+ preventComponentRendering: true,
+ blockerComponent: BlockerComponent2,
+ },
+ },
+ },
+ match: { params: { pluginId: 'email' } },
+ };
+
+ const renderedComponent = shallow();
+
+ expect(renderedComponent.find(BlockerComponent2)).toHaveLength(1);
+ });
+
+ it("Should return the plugin's mainComponent if all conditions are met", () => {
+ const props = {
+ global: {
+ plugins: {
+ email: {
+ mainComponent: Email,
+ },
+ },
+ },
+ match: { params: { pluginId: 'email' } },
+ };
+
+ const renderedComponent = shallow();
+
+ expect(renderedComponent.find(Email)).toHaveLength(1);
+ });
+});
diff --git a/packages/strapi-helper-plugin/lib/src/app.js b/packages/strapi-helper-plugin/lib/src/app.js
index c666f72f38..032059f13c 100644
--- a/packages/strapi-helper-plugin/lib/src/app.js
+++ b/packages/strapi-helper-plugin/lib/src/app.js
@@ -60,9 +60,7 @@ const store = strapi.store;
// Define the plugin root component
function Comp(props) {
- return (
-
- );
+ return ;
}
// Hot reloadable translation json files
@@ -73,14 +71,30 @@ if (module.hot) {
if (strapi) {
System.import('./i18n').then(result => {
const translationMessagesUpdated = result.translationMessages;
- strapi
- .refresh(pluginId)
- .translationMessages(translationMessagesUpdated);
+ strapi.refresh(pluginId).translationMessages(translationMessagesUpdated);
});
}
});
}
+// Require the Initializer component
+const initializer = (() => {
+ try {
+ return require('../../../../admin/src/initializer.js'); // eslint-disable-line import/no-unresolved
+ } catch (err) {
+ return null;
+ }
+})();
+
+// Require the plugin's lifecycle
+const lifecycles = (() => {
+ try {
+ return require('../../../../admin/src/lifecycles.js'); // eslint-disable-line import/no-unresolved
+ } catch (err) {
+ return null;
+ }
+})();
+
// Register the plugin.
strapi.registerPlugin({
blockerComponent: null,
@@ -89,8 +103,10 @@ strapi.registerPlugin({
description: pluginDescription,
icon: pluginPkg.strapi.icon,
id: pluginId,
+ initializer,
injectedComponents,
layout,
+ lifecycles,
leftMenuLinks: [],
mainComponent: Comp,
name: pluginPkg.strapi.name,