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,