From d3bd0c71ddd39780be190f1b05d871a4a3960336 Mon Sep 17 00:00:00 2001 From: katherinehhh Date: Wed, 27 Mar 2024 12:03:24 +0800 Subject: [PATCH] chore: menu permissions & plugins setting permissions (#3822) * chore: menu permissions * chore: plugins setting permissions * chore: plugins setting permissions * chore: plugins setting permissions --- .../client/permissions/GeneralPermissions.tsx | 71 +++++---- .../client/permissions/MenuPermissions.tsx | 135 ++++++++++++------ .../src/client/permissions/Permissions.tsx | 45 +++--- .../client/permissions/PluginPermissions.tsx | 13 +- 4 files changed, 156 insertions(+), 108 deletions(-) diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/GeneralPermissions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/GeneralPermissions.tsx index 376262ab1..57ab7b288 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/GeneralPermissions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/GeneralPermissions.tsx @@ -5,11 +5,12 @@ import { Checkbox, message } from 'antd'; import uniq from 'lodash/uniq'; import React, { useContext, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { uid } from '@formily/shared'; +import { useMemoizedFn } from 'ahooks'; import { RolesManagerContext } from '../RolesManagerProvider'; import { StrategyActions } from './StrategyActions'; import { useACLTranslation } from '../locale'; -import { uid } from '@formily/shared'; -import { useMemoizedFn } from 'ahooks'; +import { PluginPermissions } from './PluginPermissions'; const SnippetCheckboxGroup = connect((props) => { const { t } = useTranslation(); @@ -61,25 +62,8 @@ export const GeneralPermissions: React.FC<{ const { role, setRole } = useContext(RolesManagerContext); const { t } = useACLTranslation(); const api = useAPIClient(); - const { data } = useRequest( - () => - api - .resource('roles') - .get({ - filterByTk: role?.name, - }) - .then((res) => { - const record = res?.data?.data; - record.snippets?.forEach((key: string) => { - record[key] = true; - }); - return record; - }), - { - ready: active, - refreshDeps: [role?.name], - }, - ); + const pm = role?.snippets?.includes('pm.*'); + const update = useMemoizedFn(async (form: Form) => { await api.resource('roles').update({ filterByTk: role.name, @@ -90,37 +74,48 @@ export const GeneralPermissions: React.FC<{ }); const form = useMemo(() => { return createForm({ - values: data, + values: role, effects() { onFormValuesChange(async (form) => { await update(form); }); }, }); - }, [data, update]); + }, [role, update]); return ( = ({ active }) => { const { styles } = useStyles(); - const { role } = useContext(RolesManagerContext); + const { role, setRole } = useContext(RolesManagerContext); const api = useAPIClient(); const { items } = useMenuItems(); const { t } = useTranslation(); @@ -107,51 +110,89 @@ export const MenuPermissions: React.FC<{ }; }); }; - + const update = useMemoizedFn(async (form: Form) => { + await api.resource('roles').update({ + filterByTk: role.name, + values: form.values, + }); + setRole({ ...role, ...form.values }); + message.success(t('Saved successfully')); + }); + const form = useMemo(() => { + return createForm({ + values: role, + effects() { + onFormValuesChange(async (form) => { + await update(form); + }); + }, + }); + }, [role, update]); return ( - - { - if (allChecked) { - await resource.set({ - values: [], - }); - } else { - await resource.set({ - values: allUids, - }); - } - refresh(); - message.success(t('Saved successfully')); - }} - />{' '} - {t('Accessible')} - - ), - render: (_, schema) => { - const checked = uids.includes(schema.uid); - return handleChange(checked, schema)} />; + <> + + properties: { + allowNewMenu: { + title: t('Menu permissions'), + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox', + 'x-content': t('New menu items are allowed to be accessed by default.'), + }, + }, + }} + /> + +
+ { + if (allChecked) { + await resource.set({ + values: [], + }); + } else { + await resource.set({ + values: allUids, + }); + } + refresh(); + message.success(t('Saved successfully')); + }} + />{' '} + {t('Accessible')} + + ), + render: (_, schema) => { + const checked = uids.includes(schema.uid); + return handleChange(checked, schema)} />; + }, + }, + ]} + dataSource={translateTitle(items)} + /> + ); }; diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/Permissions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/Permissions.tsx index 05ed5a0da..8b28cdbda 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/Permissions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/Permissions.tsx @@ -1,4 +1,4 @@ -import { useApp } from '@nocobase/client'; +import { useApp, useRequest, useAPIClient } from '@nocobase/client'; import { Tabs } from 'antd'; import React, { useContext, useEffect, useMemo } from 'react'; import { RolesManagerContext } from '../RolesManagerProvider'; @@ -7,7 +7,6 @@ import { AvailableActionsProvider } from './AvailableActions'; import { GeneralPermissions } from './GeneralPermissions'; import { MenuItemsProvider } from './MenuItemsProvider'; import { MenuPermissions } from './MenuPermissions'; -import { PluginPermissions } from './PluginPermissions'; const TabLayout: React.FC = (props) => { return
{props.children}
; @@ -16,7 +15,7 @@ const TabLayout: React.FC = (props) => { export const Permissions: React.FC<{ active: boolean }> = ({ active }) => { const { t } = useACLTranslation(); const [activeKey, setActiveKey] = React.useState('general'); - const { role } = useContext(RolesManagerContext); + const { role, setRole } = useContext(RolesManagerContext); const pm = role?.snippets?.includes('pm.*'); const app = useApp(); const DataSourcePermissionManager = app.getComponent('DataSourcePermissionManager'); @@ -25,7 +24,7 @@ export const Permissions: React.FC<{ active: boolean }> = ({ active }) => { () => [ { key: 'general', - label: t('General'), + label: t('System'), children: ( @@ -43,19 +42,6 @@ export const Permissions: React.FC<{ active: boolean }> = ({ active }) => { ), }, - ...(pm - ? [ - { - key: 'plugin', - label: t('Plugin settings'), - children: ( - - - - ), - }, - ] - : []), ...(DataSourcePermissionManager ? [ { @@ -74,10 +60,33 @@ export const Permissions: React.FC<{ active: boolean }> = ({ active }) => { ], [pm, activeKey, active, t], ); - + const api = useAPIClient(); + const { data } = useRequest( + () => + api + .resource('roles') + .get({ + filterByTk: role?.name, + }) + .then((res) => { + const record = res?.data?.data; + record.snippets?.forEach((key: string) => { + record[key] = true; + }); + return record; + }), + { + ready: active && !!role, + refreshDeps: [role?.name], + }, + ); useEffect(() => { setActiveKey('general'); }, [role?.name]); + + useEffect(() => { + setRole(data); + }, [data]); return ( setActiveKey(key)} items={items} /> diff --git a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx index 301d61bdb..f42090efb 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx +++ b/packages/plugins/@nocobase/plugin-acl/src/client/permissions/PluginPermissions.tsx @@ -38,7 +38,7 @@ export const PluginPermissions: React.FC<{ const compile = useCompile(); const settings = app.pluginSettingsManager.getList(false); const allAclSnippets = app.pluginSettingsManager.getAclSnippets(); - const [snippets, setSnippets] = useState([]); + const [snippets, setSnippets] = useState(role?.snippets || []); const flatPlugins = useMemo(() => { return flatMap(settings, (item) => { if (item.children) { @@ -52,12 +52,11 @@ export const PluginPermissions: React.FC<{ () => snippets.includes('pm.*') && snippets.every((item) => !item.startsWith('!pm.')), [snippets], ); - const { t } = useTranslation(); const { loading, refresh } = useRequest( { resource: 'roles.snippets', - resourceOf: role.name, + resourceOf: role?.name, action: 'list', params: { paginate: false, @@ -66,6 +65,7 @@ export const PluginPermissions: React.FC<{ { ready: !!role && active, refreshDeps: [role?.name], + manual: true, onSuccess(data) { setSnippets( data?.data.filter((v) => { @@ -75,7 +75,10 @@ export const PluginPermissions: React.FC<{ }, }, ); - const resource = api.resource('roles.snippets', role.name); + if (!role) { + return; + } + const resource = api.resource('roles.snippets', role?.name); const handleChange = async (checked, record) => { const childrenKeys = getChildrenKeys(record?.children, []); const totalKeys = childrenKeys.concat(record.aclSnippet); @@ -129,7 +132,7 @@ export const PluginPermissions: React.FC<{ refresh(); message.success(t('Saved successfully')); }} - />{' '} + /> {t('Accessible')} ),