mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 19:04:38 +00:00
Improve settings menu and left menu
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
6889940033
commit
3f3f36a576
@ -23,6 +23,7 @@ import {
|
||||
LeftMenuHeader,
|
||||
LinksContainer,
|
||||
} from '../../components/LeftMenu';
|
||||
import { useSettingsMenu } from '../../hooks';
|
||||
import { generateModelsLinks } from './utils';
|
||||
import init from './init';
|
||||
import reducer, { initialState } from './reducer';
|
||||
@ -32,6 +33,7 @@ import Wrapper from './Wrapper';
|
||||
const LeftMenu = forwardRef(({ version, plugins }, ref) => {
|
||||
const location = useLocation();
|
||||
const permissions = useContext(UserContext);
|
||||
const { menu: settingsMenu } = useSettingsMenu();
|
||||
const [
|
||||
{
|
||||
collectionTypesSectionLinks,
|
||||
@ -41,7 +43,7 @@ const LeftMenu = forwardRef(({ version, plugins }, ref) => {
|
||||
singleTypesSectionLinks,
|
||||
},
|
||||
dispatch,
|
||||
] = useReducer(reducer, initialState, () => init(initialState, plugins));
|
||||
] = useReducer(reducer, initialState, () => init(initialState, plugins, settingsMenu));
|
||||
const generalSectionLinksFiltered = useMemo(
|
||||
() => generalSectionLinks.filter(link => link.isDisplayed),
|
||||
[generalSectionLinks]
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { get, omit, set } from 'lodash';
|
||||
import { SETTINGS_BASE_URL } from '../../config';
|
||||
import { getPluginsSettingsPermissions, sortLinks } from './utils';
|
||||
import { getSettingsMenuLinksPermissions, sortLinks } from './utils';
|
||||
|
||||
const init = (initialState, plugins = {}) => {
|
||||
// For each plugin retrieve the permissions associated to each injected link
|
||||
const settingsPermissions = getPluginsSettingsPermissions(plugins);
|
||||
const init = (initialState, plugins = {}, settingsMenu = []) => {
|
||||
const settingsLinkPermissions = getSettingsMenuLinksPermissions(settingsMenu);
|
||||
|
||||
const pluginsLinks = Object.values(plugins).reduce((acc, current) => {
|
||||
const pluginsSectionLinks = get(current, 'menu.pluginsSectionLinks', []);
|
||||
@ -19,11 +18,10 @@ const init = (initialState, plugins = {}) => {
|
||||
obj => obj.destination === SETTINGS_BASE_URL
|
||||
);
|
||||
|
||||
if (settingsPermissions.length && settingsLinkIndex !== -1) {
|
||||
if (!settingsLinkPermissions.filter(perm => perm === null).length && settingsLinkIndex !== -1) {
|
||||
const permissionsPath = ['generalSectionLinks', settingsLinkIndex, 'permissions'];
|
||||
const alreadyCreatedPermissions = get(initialState, permissionsPath, []);
|
||||
|
||||
set(initialState, permissionsPath, [...alreadyCreatedPermissions, ...settingsPermissions]);
|
||||
set(initialState, permissionsPath, settingsLinkPermissions);
|
||||
}
|
||||
|
||||
if (sortedLinks.length) {
|
||||
|
||||
@ -33,20 +33,20 @@ const initialState = {
|
||||
destination: SETTINGS_BASE_URL,
|
||||
permissions: [
|
||||
// webhooks
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
// users
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
// roles
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
// { action: 'admin::webhook.create', subject: null },
|
||||
// { action: 'admin::webhook.read', subject: null },
|
||||
// { action: 'admin::webhook.update', subject: null },
|
||||
// { action: 'admin::webhook.delete', subject: null },
|
||||
// // users
|
||||
// { action: 'admin::users.create', subject: null },
|
||||
// { action: 'admin::users.read', subject: null },
|
||||
// { action: 'admin::users.update', subject: null },
|
||||
// { action: 'admin::users.delete', subject: null },
|
||||
// // roles
|
||||
// { action: 'admin::roles.create', subject: null },
|
||||
// { action: 'admin::roles.update', subject: null },
|
||||
// { action: 'admin::roles.read', subject: null },
|
||||
// { action: 'admin::roles.delete', subject: null },
|
||||
// Here are added the plugins settings permissions during the init phase
|
||||
],
|
||||
},
|
||||
|
||||
@ -103,6 +103,65 @@ describe('ADMIN | LeftMenu | init', () => {
|
||||
});
|
||||
|
||||
it('should set the permissions in the settings link correctly for the plugins', () => {
|
||||
const menu = [
|
||||
{
|
||||
id: 'global',
|
||||
title: { id: 'Settings.global' },
|
||||
links: [
|
||||
{
|
||||
title: 'Settings.webhooks.title',
|
||||
to: '/settings/webhooks',
|
||||
name: 'webhooks',
|
||||
permissions: [
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'media-library',
|
||||
permissions: [
|
||||
{
|
||||
action: 'plugins::upload.settings.read',
|
||||
subject: null,
|
||||
},
|
||||
],
|
||||
title: { id: 'upload.plugin.name', defaultMessage: 'Media Library' },
|
||||
to: '/settings/media-library',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'permissions',
|
||||
title: 'Settings.permissions',
|
||||
links: [
|
||||
{
|
||||
title: 'roles',
|
||||
to: '/settings/roles',
|
||||
name: 'roles',
|
||||
permissions: [
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'users',
|
||||
|
||||
to: '/settings/users?pageSize=10&page=1&_sort=firstname%3AASC',
|
||||
name: 'users',
|
||||
permissions: [
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const initialState = {
|
||||
generalSectionLinks: [
|
||||
{
|
||||
@ -130,81 +189,13 @@ describe('ADMIN | LeftMenu | init', () => {
|
||||
label: 'app.components.LeftMenuLinkContainer.settings',
|
||||
isDisplayed: false,
|
||||
destination: SETTINGS_BASE_URL,
|
||||
permissions: [
|
||||
// webhooks
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
// users
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
// roles
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
// Here are added the plugins settings permissions during the init phase
|
||||
],
|
||||
permissions: [],
|
||||
},
|
||||
],
|
||||
pluginsSectionLinks: [],
|
||||
isLoading: true,
|
||||
};
|
||||
const plugins = {
|
||||
test: {
|
||||
settings: {
|
||||
global: {
|
||||
links: [
|
||||
{
|
||||
title: {
|
||||
id: 'test.plugin.name',
|
||||
defaultMessage: 'Test',
|
||||
},
|
||||
name: 'test',
|
||||
to: '/settings/test',
|
||||
Component: () => null,
|
||||
permissions: [{ action: 'plugins::test.settings.read', subject: null }],
|
||||
},
|
||||
{
|
||||
title: {
|
||||
id: 'test.plugin.name1',
|
||||
defaultMessage: 'Test1',
|
||||
},
|
||||
name: 'test1',
|
||||
to: '/settings/test1',
|
||||
Component: () => null,
|
||||
permissions: [{ action: 'plugins::test1.settings.read', subject: null }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
other: {},
|
||||
upload: {
|
||||
settings: {
|
||||
global: {
|
||||
links: [
|
||||
{
|
||||
title: {
|
||||
id: 'upload.plugin.name',
|
||||
defaultMessage: 'Media Library',
|
||||
},
|
||||
name: 'media-library',
|
||||
to: 'settings/media-library',
|
||||
Component: () => null,
|
||||
permissions: [
|
||||
{ action: 'plugins::upload.settings.read', subject: null },
|
||||
{ action: 'plugins::upload.settings.read.test', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const plugins = {};
|
||||
const expected = {
|
||||
generalSectionLinks: [
|
||||
{
|
||||
@ -238,20 +229,20 @@ describe('ADMIN | LeftMenu | init', () => {
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
{
|
||||
action: 'plugins::upload.settings.read',
|
||||
subject: null,
|
||||
},
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
// users
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
// roles
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
{ action: 'plugins::test.settings.read', subject: null },
|
||||
{ action: 'plugins::test1.settings.read', subject: null },
|
||||
{ action: 'plugins::upload.settings.read', subject: null },
|
||||
{ action: 'plugins::upload.settings.read.test', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -259,6 +250,132 @@ describe('ADMIN | LeftMenu | init', () => {
|
||||
isLoading: true,
|
||||
};
|
||||
|
||||
expect(init(initialState, plugins)).toEqual(expected);
|
||||
expect(init(initialState, plugins, menu)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should set the permissions in the settings link to an empty array if at least one link of the settings menu has no permissions', () => {
|
||||
const menu = [
|
||||
{
|
||||
id: 'global',
|
||||
title: { id: 'Settings.global' },
|
||||
links: [
|
||||
{
|
||||
title: 'Settings.webhooks.title',
|
||||
to: '/settings/webhooks',
|
||||
name: 'webhooks',
|
||||
permissions: [
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'media-library',
|
||||
permissions: [],
|
||||
title: { id: 'upload.plugin.name', defaultMessage: 'Media Library' },
|
||||
to: '/settings/media-library',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'permissions',
|
||||
title: 'Settings.permissions',
|
||||
links: [
|
||||
{
|
||||
title: 'roles',
|
||||
to: '/settings/roles',
|
||||
name: 'roles',
|
||||
permissions: [
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'users',
|
||||
|
||||
to: '/settings/users?pageSize=10&page=1&_sort=firstname%3AASC',
|
||||
name: 'users',
|
||||
permissions: [
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const initialState = {
|
||||
generalSectionLinks: [
|
||||
{
|
||||
icon: 'list',
|
||||
label: 'app.components.LeftMenuLinkContainer.listPlugins',
|
||||
destination: '/list-plugins',
|
||||
isDisplayed: false,
|
||||
permissions: [
|
||||
{ action: 'admin::marketplace.read', subject: null },
|
||||
{ action: 'admin::marketplace.plugins.uninstall', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'shopping-basket',
|
||||
label: 'app.components.LeftMenuLinkContainer.installNewPlugin',
|
||||
destination: '/marketplace',
|
||||
isDisplayed: false,
|
||||
permissions: [
|
||||
{ action: 'admin::marketplace.read', subject: null },
|
||||
{ action: 'admin::marketplace.plugins.install', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'cog',
|
||||
label: 'app.components.LeftMenuLinkContainer.settings',
|
||||
isDisplayed: false,
|
||||
destination: SETTINGS_BASE_URL,
|
||||
permissions: [],
|
||||
},
|
||||
],
|
||||
pluginsSectionLinks: [],
|
||||
isLoading: true,
|
||||
};
|
||||
const plugins = {};
|
||||
const expected = {
|
||||
generalSectionLinks: [
|
||||
{
|
||||
icon: 'list',
|
||||
label: 'app.components.LeftMenuLinkContainer.listPlugins',
|
||||
destination: '/list-plugins',
|
||||
isDisplayed: false,
|
||||
permissions: [
|
||||
{ action: 'admin::marketplace.read', subject: null },
|
||||
{ action: 'admin::marketplace.plugins.uninstall', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'shopping-basket',
|
||||
label: 'app.components.LeftMenuLinkContainer.installNewPlugin',
|
||||
destination: '/marketplace',
|
||||
isDisplayed: false,
|
||||
permissions: [
|
||||
{ action: 'admin::marketplace.read', subject: null },
|
||||
{ action: 'admin::marketplace.plugins.install', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: 'cog',
|
||||
label: 'app.components.LeftMenuLinkContainer.settings',
|
||||
isDisplayed: false,
|
||||
destination: SETTINGS_BASE_URL,
|
||||
permissions: [],
|
||||
},
|
||||
],
|
||||
pluginsSectionLinks: [],
|
||||
isLoading: true,
|
||||
};
|
||||
|
||||
expect(init(initialState, plugins, menu)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
// Retrieve the plugin settings object
|
||||
// The settings API works as follows for a plugin
|
||||
// Declare the links that will be injected into the settings menu
|
||||
//
|
||||
// Path: my-plugin/admin/src/index.js
|
||||
/*
|
||||
************************************************************
|
||||
* 1. Declare a section that will be added to the setting menu
|
||||
* const menuSection = {
|
||||
* // Unique id of the section
|
||||
* id: pluginId,
|
||||
* // Title of Menu section using i18n
|
||||
* title: {
|
||||
* id: `${pluginId}.foo`,
|
||||
* defaultMessage: 'Super cool setting',
|
||||
* },
|
||||
* // Array of links to be displayed
|
||||
* links: [
|
||||
* {
|
||||
* // Using string
|
||||
* title: 'Setting page 1',
|
||||
* to: `${strapi.settingsBaseURL}/${pluginId}/setting1`,
|
||||
* name: 'setting1',
|
||||
* permissions: [{ action: 'plugins::my-plugin.action-name', subject: null }],
|
||||
* },
|
||||
* {
|
||||
* // Using i18n with a corresponding translation key
|
||||
* title: {
|
||||
* id: `${pluginId}.bar`,
|
||||
* defaultMessage: 'Setting page 2',
|
||||
* },
|
||||
* to: `${strapi.settingsBaseURL}/${pluginId}/setting2`,
|
||||
* name: 'setting2',
|
||||
* permissions: [{ action: 'plugins::my-plugin.action-name2', subject: null }],
|
||||
* },
|
||||
* ],
|
||||
* };
|
||||
* ************************************************************
|
||||
* 2. Add a setting to the global section of the menu
|
||||
* const global = {
|
||||
* links: [
|
||||
* {
|
||||
* title: {
|
||||
* id: getTrad('plugin.name'),
|
||||
* defaultMessage: 'Media Library',
|
||||
* },
|
||||
* name: 'media-library',
|
||||
* to: `${strapi.settingsBaseURL}/media-library`,
|
||||
* Component: SettingsPage,
|
||||
* // TODO write documentation
|
||||
* permissions: [{ action: 'plugins::my-plugin.action-name', subject: null }],
|
||||
* },
|
||||
* ],
|
||||
* };
|
||||
***********************************************************
|
||||
* 3. Define the settings in the plugin object
|
||||
* const settings = { global, menuSection };
|
||||
*/
|
||||
|
||||
import { get } from 'lodash';
|
||||
|
||||
const getPluginsSettingsPermissions = plugins => {
|
||||
const globalSettingsLinksPermissions = Object.values(plugins).reduce((acc, current) => {
|
||||
const pluginSettings = get(current, 'settings', {});
|
||||
const getSettingsLinkPermissions = settings => {
|
||||
return Object.values(settings).reduce((acc, current) => {
|
||||
const links = get(current, 'links', []);
|
||||
|
||||
links.forEach(link => {
|
||||
const permissions = get(link, 'permissions', []);
|
||||
|
||||
permissions.forEach(permission => {
|
||||
acc.push(permission);
|
||||
});
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
};
|
||||
|
||||
const pluginPermissions = getSettingsLinkPermissions(pluginSettings);
|
||||
|
||||
return [...acc, ...pluginPermissions];
|
||||
}, []);
|
||||
|
||||
return [...globalSettingsLinksPermissions];
|
||||
};
|
||||
|
||||
export default getPluginsSettingsPermissions;
|
||||
@ -0,0 +1,21 @@
|
||||
import { get, isEmpty } from 'lodash';
|
||||
|
||||
const getSettingsMenuLinksPermissions = menu =>
|
||||
menu.reduce((acc, current) => {
|
||||
const links = get(current, 'links', []);
|
||||
|
||||
const permissions = links.reduce((acc, current) => {
|
||||
// console.log({ c: current });
|
||||
let currentPermissions = get(current, 'permissions', null);
|
||||
|
||||
if (isEmpty(currentPermissions)) {
|
||||
return [...acc, null];
|
||||
}
|
||||
|
||||
return [...acc, ...currentPermissions];
|
||||
}, []);
|
||||
|
||||
return [...acc, ...permissions];
|
||||
}, []);
|
||||
|
||||
export default getSettingsMenuLinksPermissions;
|
||||
@ -1,3 +1,3 @@
|
||||
export { default as generateModelsLinks } from './generateModelsLinks';
|
||||
export { default as getPluginsSettingsPermissions } from './getPluginsSettingsPermissions';
|
||||
export { default as getSettingsMenuLinksPermissions } from './getSettingsMenuLinksPermissions';
|
||||
export { default as sortLinks } from './sortLinks';
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
import getPluginsSettingsPermissions from '../getPluginsSettingsPermissions';
|
||||
|
||||
describe('ADMIN | LeftMenu | utils | getPluginsSettingsPermissions', () => {
|
||||
it('should return an empty array', () => {
|
||||
expect(getPluginsSettingsPermissions({})).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return an array containing all the permissions of the plugins settings links', () => {
|
||||
const menuSection = {
|
||||
// Unique id of the section
|
||||
id: 'test',
|
||||
// Title of Menu section using i18n
|
||||
title: {
|
||||
id: 'test.foo',
|
||||
defaultMessage: 'Super cool setting',
|
||||
},
|
||||
// Array of links to be displayed
|
||||
links: [
|
||||
{
|
||||
// Using string
|
||||
title: 'Setting page 1',
|
||||
to: 'settings/test/setting1',
|
||||
name: 'setting1',
|
||||
permissions: [{ action: 'plugins::test.action-name', subject: null }],
|
||||
},
|
||||
{
|
||||
// Using i18n with a corresponding translation key
|
||||
title: {
|
||||
id: 'test.bar',
|
||||
defaultMessage: 'Setting page 2',
|
||||
},
|
||||
to: 'settings/test/setting2',
|
||||
name: 'setting2',
|
||||
permissions: [{ action: 'plugins::my-plugin.action-name2', subject: null }],
|
||||
},
|
||||
],
|
||||
};
|
||||
const plugins = {
|
||||
test: {
|
||||
settings: {
|
||||
global: {
|
||||
links: [
|
||||
{
|
||||
title: {
|
||||
id: 'test.plugin.name',
|
||||
defaultMessage: 'Test',
|
||||
},
|
||||
name: 'test',
|
||||
to: '/settings/test',
|
||||
Component: () => null,
|
||||
permissions: [{ action: 'plugins::test.settings.read', subject: null }],
|
||||
},
|
||||
{
|
||||
title: {
|
||||
id: 'test.plugin.name1',
|
||||
defaultMessage: 'Test1',
|
||||
},
|
||||
name: 'test1',
|
||||
to: '/settings/test1',
|
||||
Component: () => null,
|
||||
permissions: [{ action: 'plugins::test1.settings.read', subject: null }],
|
||||
},
|
||||
],
|
||||
},
|
||||
menuSection,
|
||||
},
|
||||
},
|
||||
other: {},
|
||||
upload: {
|
||||
settings: {
|
||||
global: {
|
||||
links: [
|
||||
{
|
||||
title: {
|
||||
id: 'upload.plugin.name',
|
||||
defaultMessage: 'Media Library',
|
||||
},
|
||||
name: 'media-library',
|
||||
to: 'settings/media-library',
|
||||
Component: () => null,
|
||||
permissions: [
|
||||
{ action: 'plugins::upload.settings.read', subject: null },
|
||||
{ action: 'plugins::upload.settings.read.test', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const expected = [
|
||||
{ action: 'plugins::test.action-name', subject: null },
|
||||
{ action: 'plugins::my-plugin.action-name2', subject: null },
|
||||
{ action: 'plugins::upload.settings.read', subject: null },
|
||||
{ action: 'plugins::upload.settings.read.test', subject: null },
|
||||
];
|
||||
|
||||
expect(getPluginsSettingsPermissions(plugins)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,86 @@
|
||||
import getSettingsMenuLinksPermissions from '../getSettingsMenuLinksPermissions';
|
||||
|
||||
describe('ADMIN | LeftMenu | utils | getSettingsMenuLinksPermissions', () => {
|
||||
it('should return an array containing all the permissions of each link', () => {
|
||||
const data = [
|
||||
{
|
||||
id: 'global',
|
||||
title: { id: 'Settings.global' },
|
||||
links: [
|
||||
{
|
||||
title: 'Settings.webhooks.title',
|
||||
to: '/settings/webhooks',
|
||||
name: 'webhooks',
|
||||
permissions: [
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'media-library',
|
||||
permissions: [
|
||||
{
|
||||
action: 'plugins::upload.settings.read',
|
||||
subject: null,
|
||||
},
|
||||
],
|
||||
title: { id: 'upload.plugin.name', defaultMessage: 'Media Library' },
|
||||
to: '/settings/media-library',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'permissions',
|
||||
title: 'Settings.permissions',
|
||||
links: [
|
||||
{
|
||||
title: 'roles',
|
||||
to: '/settings/roles',
|
||||
name: 'roles',
|
||||
permissions: [
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'users',
|
||||
|
||||
to: '/settings/users?pageSize=10&page=1&_sort=firstname%3AASC',
|
||||
name: 'users',
|
||||
permissions: [
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const expected = [
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
{
|
||||
action: 'plugins::upload.settings.read',
|
||||
subject: null,
|
||||
},
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
];
|
||||
|
||||
expect(getSettingsMenuLinksPermissions(data)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@ -14,8 +14,9 @@ import { BackHeader, useGlobalContext, LeftMenuList } from 'strapi-helper-plugin
|
||||
import { Switch, Redirect, Route, useParams, useHistory } from 'react-router-dom';
|
||||
import RolesListPage from 'ee_else_ce/containers/Roles/ListPage';
|
||||
import RolesCreatePage from 'ee_else_ce/containers/Roles/CreatePage';
|
||||
import SettingsSearchHeaderProvider from '../SettingsHeaderSearchContextProvider';
|
||||
import HeaderSearch from '../../components/HeaderSearch';
|
||||
import { useSettingsMenu } from '../../hooks';
|
||||
import SettingsSearchHeaderProvider from '../SettingsHeaderSearchContextProvider';
|
||||
import UsersEditPage from '../Users/EditPage';
|
||||
import UsersListPage from '../Users/ListPage';
|
||||
import RolesEditPage from '../Roles/EditPage';
|
||||
@ -26,20 +27,13 @@ import ListView from '../Webhooks/ListView';
|
||||
import SettingDispatcher from './SettingDispatcher';
|
||||
import LeftMenu from './StyledLeftMenu';
|
||||
import Wrapper from './Wrapper';
|
||||
import retrieveGlobalLinks from './utils/retrieveGlobalLinks';
|
||||
import retrievePluginsMenu from './utils/retrievePluginsMenu';
|
||||
|
||||
function SettingsPage() {
|
||||
const { settingId } = useParams();
|
||||
const { goBack } = useHistory();
|
||||
const { formatMessage, plugins, settingsBaseURL } = useGlobalContext();
|
||||
const { settingsBaseURL } = useGlobalContext();
|
||||
const [headerSearchState, setShowHeaderSearchState] = useState({ show: false, label: '' });
|
||||
|
||||
// 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 { menu, globalLinks } = useSettingsMenu();
|
||||
|
||||
const createdRoutes = globalLinks
|
||||
.map(({ to, Component, exact }) => (
|
||||
@ -49,39 +43,6 @@ function SettingsPage() {
|
||||
return refArray.findIndex(obj => obj.key === route.key) === index;
|
||||
});
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
id: 'global',
|
||||
title: { id: 'Settings.global' },
|
||||
links: [
|
||||
{
|
||||
title: formatMessage({ id: 'Settings.webhooks.title' }),
|
||||
to: `${settingsBaseURL}/webhooks`,
|
||||
name: 'webhooks',
|
||||
},
|
||||
...globalLinks,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'permissions',
|
||||
title: 'Settings.permissions',
|
||||
links: [
|
||||
{
|
||||
title: formatMessage({ id: 'Settings.permissions.menu.link.roles.label' }),
|
||||
to: `${settingsBaseURL}/roles`,
|
||||
name: 'roles',
|
||||
},
|
||||
{
|
||||
title: formatMessage({ id: 'Settings.permissions.menu.link.users.label' }),
|
||||
// Init the search params directly
|
||||
to: `${settingsBaseURL}/users?pageSize=10&page=1&_sort=firstname%3AASC`,
|
||||
name: 'users',
|
||||
},
|
||||
],
|
||||
},
|
||||
...pluginsMenu,
|
||||
];
|
||||
|
||||
const toggleHeaderSearch = label =>
|
||||
setShowHeaderSearchState(prev => {
|
||||
if (prev.show) {
|
||||
@ -109,7 +70,7 @@ function SettingsPage() {
|
||||
<div className="row">
|
||||
<div className="col-md-3">
|
||||
<LeftMenu>
|
||||
{menuItems.map(item => {
|
||||
{menu.map(item => {
|
||||
return <LeftMenuList {...item} key={item.id} />;
|
||||
})}
|
||||
</LeftMenu>
|
||||
|
||||
@ -4,4 +4,5 @@ export { default as useFetchPluginsFromMarketPlace } from './useFetchPluginsFrom
|
||||
export { default as useFetchRole } from './useFetchRole';
|
||||
export { default as useRolesList } from './useRolesList';
|
||||
export { default as useSettingsHeaderSearchContext } from './useSettingsHeaderSearchContext';
|
||||
export { default as useSettingsMenu } from './useSettingsMenu';
|
||||
export { default as useUsersForm } from './useUsersForm';
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useGlobalContext } from 'strapi-helper-plugin';
|
||||
import { retrieveGlobalLinks, retrievePluginsMenu } from '../../utils';
|
||||
|
||||
const useSettingsMenu = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { plugins, settingsBaseURL } = useGlobalContext();
|
||||
// Retrieve the links that will be injected into the global section
|
||||
const globalLinks = useMemo(() => retrieveGlobalLinks(plugins), [plugins]);
|
||||
// Create the plugins settings section
|
||||
// Note it is currently not possible to add a link into a plugin section
|
||||
const pluginsMenu = useMemo(() => retrievePluginsMenu(plugins), [plugins]);
|
||||
|
||||
const menu = [
|
||||
{
|
||||
id: 'global',
|
||||
title: { id: 'Settings.global' },
|
||||
links: [
|
||||
{
|
||||
title: formatMessage({ id: 'Settings.webhooks.title' }),
|
||||
to: `${settingsBaseURL}/webhooks`,
|
||||
name: 'webhooks',
|
||||
permissions: [
|
||||
{ action: 'admin::webhook.create', subject: null },
|
||||
{ action: 'admin::webhook.read', subject: null },
|
||||
{ action: 'admin::webhook.update', subject: null },
|
||||
{ action: 'admin::webhook.delete', subject: null },
|
||||
],
|
||||
},
|
||||
...globalLinks,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'permissions',
|
||||
title: 'Settings.permissions',
|
||||
links: [
|
||||
{
|
||||
title: formatMessage({ id: 'Settings.permissions.menu.link.roles.label' }),
|
||||
to: `${settingsBaseURL}/roles`,
|
||||
name: 'roles',
|
||||
permissions: [
|
||||
{ action: 'admin::roles.create', subject: null },
|
||||
{ action: 'admin::roles.update', subject: null },
|
||||
{ action: 'admin::roles.read', subject: null },
|
||||
{ action: 'admin::roles.delete', subject: null },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: formatMessage({ id: 'Settings.permissions.menu.link.users.label' }),
|
||||
// Init the search params directly
|
||||
to: `${settingsBaseURL}/users?pageSize=10&page=1&_sort=firstname%3AASC`,
|
||||
name: 'users',
|
||||
permissions: [
|
||||
{ action: 'admin::users.create', subject: null },
|
||||
{ action: 'admin::users.read', subject: null },
|
||||
{ action: 'admin::users.update', subject: null },
|
||||
{ action: 'admin::users.delete', subject: null },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
...pluginsMenu,
|
||||
];
|
||||
|
||||
return { menu, globalLinks, pluginsMenu };
|
||||
};
|
||||
|
||||
export default useSettingsMenu;
|
||||
@ -1,4 +1,6 @@
|
||||
export { default as checkFormValidity } from './checkFormValidity';
|
||||
export { default as formatAPIErrors } from './formatAPIErrors';
|
||||
export { default as retrieveGlobalLinks } from './retrieveGlobalLinks';
|
||||
export { default as retrievePluginsMenu } from './retrievePluginsMenu';
|
||||
export { default as roleTabsLabel } from './roleTabsLabel';
|
||||
export { default as fakePermissionsData } from './fakePermissionsData';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user