diff --git a/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md b/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md index 66764c01e6..1927604dbf 100644 --- a/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md +++ b/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md @@ -191,3 +191,85 @@ export default strapi => { return strapi.registerPlugin(plugin); }; ``` + +## Adding a setting into the global section + +In order to add a link into the global section of the settings view you need to create a global array containing the links you want to add; + +**Path —** `plugins/my-plugin/admin/src/index.js`. + +import pluginPkg from '../../package.json'; +// Import the component +import Settings from './containers/Settings'; +import SettingLink from './components/SettingLink'; +import pluginId from './pluginId'; + +export default strapi => { +const pluginDescription = +pluginPkg.strapi.description || pluginPkg.description; + +// Declare the links that will be injected into the settings menu +const menuSection = { +id: pluginId, +title: { +id: `${pluginId}.foo`, +defaultMessage: 'Super cool setting', +}, +links: [ +{ +title: 'Setting page 1', +to: `${strapi.settingsBaseURL}/${pluginId}/setting1`, +name: 'setting1', +}, +{ +title: { +id: `${pluginId}.bar`, +defaultMessage: 'Setting page 2', +}, +to: `${strapi.settingsBaseURL}/${pluginId}/setting2`, +name: 'setting2', +}, +], +}; + +const plugin = { +blockerComponent: null, +blockerComponentProps: {}, +description: pluginDescription, +icon: pluginPkg.strapi.icon, +id: pluginId, +initializer: () => null, +injectedComponents: [], +isReady: true, +leftMenuLinks: [], +leftMenuSections: [], +mainComponent: null, +name: pluginPkg.strapi.name, +preventComponentRendering: false, +settings: { +// Add a link into the global section of the settings view +global: [ +{ +title: 'Setting link 1', +to: `${strapi.settingsBaseURL}/setting-link-1`, +name: 'settingLink1', +Component: SettingLink, +// True or false +exact: false, +}, +], +mainComponent: Settings, +menuSection, +}, +trads: {}, +}; + +return strapi.registerPlugin(plugin); +}; + +``` + +::: danger +It is currently not possible to add a link into another plugin's setting section +::: +``` diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/index.js b/packages/strapi-admin/admin/src/containers/SettingsPage/index.js index c69aa05b33..7721a34f3c 100644 --- a/packages/strapi-admin/admin/src/containers/SettingsPage/index.js +++ b/packages/strapi-admin/admin/src/containers/SettingsPage/index.js @@ -6,29 +6,30 @@ import React, { memo } from 'react'; import { useGlobalContext, LeftMenu, LeftMenuList } from 'strapi-helper-plugin'; -import { get } from 'lodash'; import { Switch, Redirect, Route, useParams } from 'react-router-dom'; - import EditView from '../Webhooks/EditView'; import ListView from '../Webhooks/ListView'; import SettingDispatcher from './SettingDispatcher'; import Wrapper from './Wrapper'; +import retrieveGlobalLinks from './utils/retrieveGlobalLinks'; +import retrievePluginsMenu from './utils/retrievePluginsMenu'; function SettingsPage() { const { settingId } = useParams(); const { formatMessage, plugins, settingsBaseURL } = useGlobalContext(); + // Retrieve the links that will be injected into the global section + const globalLinks = retrieveGlobalLinks(plugins); + // Create the plugins settings section + // Note it is currently not possible to add a link into a plugin section + const pluginsMenu = retrievePluginsMenu(plugins); - const pluginsMenu = Object.keys(plugins).reduce((acc, current) => { - const pluginMenu = get(plugins, [current, 'settings', 'menuSection'], null); - - if (!pluginMenu) { - return acc; - } - - acc.push(pluginMenu); - - return acc; - }, []); + const createdRoutes = globalLinks + .map(({ to, Component, exact }) => ( + + )) + .filter((route, index, refArray) => { + return refArray.findIndex(obj => obj.key === route.key) === index; + }); const menuItems = [ { @@ -40,6 +41,7 @@ function SettingsPage() { to: `${settingsBaseURL}/webhooks`, name: 'webhooks', }, + ...globalLinks, ], }, ...pluginsMenu, @@ -74,6 +76,7 @@ function SettingsPage() { path={`${settingsBaseURL}/webhooks/:id`} component={EditView} /> + {createdRoutes} { + return Object.values(pluginsObj).reduce((acc, current) => { + const links = get(current, ['settings', 'global'], null); + + if (links) { + for (let i = 0; i < links.length; i++) { + acc.push(links[i]); + } + } + + return acc; + }, []); +}; + +export default retrieveGlobalLinks; diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/utils/retrievePluginsMenu.js b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/retrievePluginsMenu.js new file mode 100644 index 0000000000..ca703113bc --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/retrievePluginsMenu.js @@ -0,0 +1,17 @@ +import { get } from 'lodash'; + +const retrievePluginsMenu = pluginsObj => { + return Object.values(pluginsObj).reduce((acc, current) => { + const pluginMenu = get(current, ['settings', 'menuSection'], null); + + if (!pluginMenu) { + return acc; + } + + acc.push(pluginMenu); + + return acc; + }, []); +}; + +export default retrievePluginsMenu; diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrieveGlobalLinks.test.js b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrieveGlobalLinks.test.js new file mode 100644 index 0000000000..85509eb280 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrieveGlobalLinks.test.js @@ -0,0 +1,33 @@ +import retrieveGlobalLinks from '../retrieveGlobalLinks'; + +describe('ADMIN | containers | SettingsPage | utils', () => { + describe('retrieveGlobalLinks', () => { + it('should return an empty array if there is no plugins', () => { + expect(retrieveGlobalLinks({})).toHaveLength(0); + }); + + it('should return an array of links', () => { + const plugins = { + test: { + settings: { + global: [], + }, + }, + noSettings: {}, + foo: { + settings: { + global: ['test'], + }, + }, + bar: { + settings: { + global: ['test2'], + }, + }, + }; + const expected = ['test', 'test2']; + + expect(retrieveGlobalLinks(plugins)).toEqual(expected); + }); + }); +}); diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrievePluginsMenu.test.js b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrievePluginsMenu.test.js new file mode 100644 index 0000000000..ca0c3d68e7 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrievePluginsMenu.test.js @@ -0,0 +1,33 @@ +import retrievePluginsMenu from '../retrievePluginsMenu'; + +describe('ADMIN | containers | SettingsPage | utils', () => { + describe('retrievePluginsMenu', () => { + it('should return an empty array if there is no plugins', () => { + expect(retrievePluginsMenu({})).toHaveLength(0); + }); + + it('should return an array of menu sections', () => { + const plugins = { + test: { + settings: { + menuSection: null, + }, + }, + noSettings: {}, + foo: { + settings: { + menuSection: { label: 'test' }, + }, + }, + bar: { + settings: { + menuSection: { label: 'test2' }, + }, + }, + }; + const expected = [{ label: 'test' }, { label: 'test2' }]; + + expect(retrievePluginsMenu(plugins)).toEqual(expected); + }); + }); +});