feat: improve the toolbar of the plugin manager
This commit is contained in:
parent
b49440da00
commit
a1ccc82fa1
@ -1,8 +1,8 @@
|
||||
import { Menu } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { LockOutlined } from '@ant-design/icons';
|
||||
import { SchemaComponent, useActionVisible, VisibleContext } from '../schema-component';
|
||||
import { ISchema, useForm } from '@formily/react';
|
||||
import { PluginManager } from '../plugin-manager';
|
||||
|
||||
const useCloseAction = () => {
|
||||
const { setVisible } = useActionVisible();
|
||||
@ -47,18 +47,17 @@ const schema: ISchema = {
|
||||
},
|
||||
};
|
||||
|
||||
export const ACLAction = () => {
|
||||
export const ACLShortcut = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||
<Menu.Item
|
||||
eventKey={'ACLAction'}
|
||||
<PluginManager.Toolbar.Item
|
||||
icon={<LockOutlined />}
|
||||
title={'角色和权限'}
|
||||
onClick={() => {
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
<LockOutlined />
|
||||
</Menu.Item>
|
||||
/>
|
||||
<SchemaComponent scope={{ useCloseAction }} schema={schema} />
|
||||
</VisibleContext.Provider>
|
||||
);
|
@ -1,3 +1,3 @@
|
||||
export * from './ACLProvider';
|
||||
export * from './RolePermissionManager';
|
||||
export * from './ACLAction';
|
||||
export * from './ACLShortcut';
|
||||
|
@ -13,6 +13,11 @@ import {
|
||||
SchemaComponentProvider,
|
||||
Menu,
|
||||
Action,
|
||||
PluginManagerProvider,
|
||||
DesignableSwitch,
|
||||
CollectionManagerShortcut,
|
||||
ACLShortcut,
|
||||
SystemSettingsShortcut,
|
||||
} from '@nocobase/client';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { Spin } from 'antd';
|
||||
@ -24,6 +29,10 @@ const providers = [
|
||||
[APIClientProvider, { apiClient }],
|
||||
[I18nextProvider, { i18n }],
|
||||
[AntdConfigProvider, { remoteLocale: true }],
|
||||
[
|
||||
PluginManagerProvider,
|
||||
{ components: { ACLShortcut, DesignableSwitch, CollectionManagerShortcut, SystemSettingsShortcut } },
|
||||
],
|
||||
[SchemaComponentProvider, { components: { Menu, Action } }],
|
||||
[RouteSwitchProvider, { components: { AuthLayout, AdminLayout } }],
|
||||
];
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Menu } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { DatabaseOutlined } from '@ant-design/icons';
|
||||
import { SchemaComponent, useActionVisible, VisibleContext } from '../schema-component';
|
||||
import { ISchema, useForm } from '@formily/react';
|
||||
import { PluginManager } from '../plugin-manager';
|
||||
|
||||
const useCloseAction = () => {
|
||||
const { setVisible } = useActionVisible();
|
||||
@ -47,18 +47,17 @@ const schema: ISchema = {
|
||||
},
|
||||
};
|
||||
|
||||
export const CollectionManagerAction = () => {
|
||||
export const CollectionManagerShortcut = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||
<Menu.Item
|
||||
eventKey={'CollectionManagerAction'}
|
||||
<PluginManager.Toolbar.Item
|
||||
icon={<DatabaseOutlined />}
|
||||
title={'数据表配置'}
|
||||
onClick={() => {
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
<DatabaseOutlined />
|
||||
</Menu.Item>
|
||||
/>
|
||||
<SchemaComponent scope={{ useCloseAction }} schema={schema} />
|
||||
</VisibleContext.Provider>
|
||||
);
|
@ -5,4 +5,4 @@ export * from './context';
|
||||
export * from './hooks';
|
||||
export * from './types';
|
||||
export * from './CollectionField';
|
||||
export * from './CollectionManagerAction';
|
||||
export * from './CollectionManagerShortcut';
|
||||
|
@ -7,13 +7,16 @@ export const CurrentUser = () => null;
|
||||
|
||||
CurrentUser.Dropdown = () => {
|
||||
return (
|
||||
// @ts-ignore
|
||||
<Menu.SubMenu eventKey={'CurrentUser.Dropdown'} title={'超级管理员'}>
|
||||
<ProfileAction />
|
||||
<Menu.Item>切换角色</Menu.Item>
|
||||
<Menu.Item>语言设置</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item>注销</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
<div style={{ display: 'inline-block' }}>
|
||||
<Menu selectable={false} mode={'horizontal'} theme={'dark'}>
|
||||
<Menu.SubMenu key={'current-user'} title={'超级管理员'}>
|
||||
<ProfileAction />
|
||||
<Menu.Item>切换角色</Menu.Item>
|
||||
<Menu.Item>语言设置</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item>注销</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,18 +1,41 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { Menu, Space, Tooltip } from 'antd';
|
||||
import { Menu, Space, Tooltip, MenuItemProps } from 'antd';
|
||||
import { SettingOutlined, MoreOutlined, DesktopOutlined } from '@ant-design/icons';
|
||||
import { CurrentUser, DesignableSwitch, CollectionManagerAction, ACLAction, SystemSettings } from '../';
|
||||
import { get } from 'lodash';
|
||||
import { PluginManagerContext, PluginManagerProvider } from '.';
|
||||
import { PluginManagerContext } from './context';
|
||||
import cls from 'classnames';
|
||||
import { ConfigProvider } from 'antd';
|
||||
|
||||
// TODO
|
||||
export const PluginManager: any = () => null;
|
||||
export const usePrefixCls = (
|
||||
tag?: string,
|
||||
props?: {
|
||||
prefixCls?: string;
|
||||
},
|
||||
) => {
|
||||
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
|
||||
return getPrefixCls(tag, props?.prefixCls);
|
||||
};
|
||||
|
||||
PluginManager.Provider = PluginManagerProvider;
|
||||
type PluginManagerType = {
|
||||
Toolbar?: React.FC<ToolbarProps> & {
|
||||
Item?: React.FC<MenuItemProps & { selected?: boolean }>;
|
||||
};
|
||||
};
|
||||
|
||||
const ToolbarItemContext = createContext(null);
|
||||
export const PluginManager: PluginManagerType = () => null;
|
||||
|
||||
PluginManager.Toolbar = (props: any) => {
|
||||
const ToolbarItemContext = createContext<ToolbarItemProps>(null);
|
||||
|
||||
interface ToolbarProps {
|
||||
items?: ToolbarItemProps[];
|
||||
}
|
||||
|
||||
interface ToolbarItemProps {
|
||||
component: string;
|
||||
pin?: boolean;
|
||||
}
|
||||
|
||||
PluginManager.Toolbar = (props: ToolbarProps) => {
|
||||
const { components } = useContext(PluginManagerContext);
|
||||
const { items = [] } = props;
|
||||
return (
|
||||
@ -44,7 +67,9 @@ PluginManager.Toolbar = (props: any) => {
|
||||
);
|
||||
})}
|
||||
<Menu.Divider></Menu.Divider>
|
||||
<Menu.Item icon={<SettingOutlined />}>管理插件</Menu.Item>
|
||||
<Menu.Item disabled icon={<SettingOutlined />}>
|
||||
管理插件
|
||||
</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</div>
|
||||
@ -53,18 +78,20 @@ PluginManager.Toolbar = (props: any) => {
|
||||
|
||||
PluginManager.Toolbar.Item = (props) => {
|
||||
const item = useContext(ToolbarItemContext);
|
||||
const { icon, title, ...others } = props;
|
||||
const { selected, icon, title, ...others } = props;
|
||||
const prefix = usePrefixCls();
|
||||
const className = cls({ [`${prefix}-menu-item-selected`]: selected });
|
||||
if (item.pin) {
|
||||
return (
|
||||
<Tooltip title={title}>
|
||||
<Menu.Item {...others} eventKey={item.component}>
|
||||
<Menu.Item {...others} className={className} eventKey={item.component}>
|
||||
{icon}
|
||||
</Menu.Item>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu.Item {...others} eventKey={item.component} icon={icon}>
|
||||
<Menu.Item {...others} className={className} eventKey={item.component} icon={icon}>
|
||||
{title}
|
||||
</Menu.Item>
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Menu } from 'antd';
|
||||
import React from 'react';
|
||||
import { SaveOutlined, KeyOutlined, DatabaseOutlined, VerifiedOutlined, NotificationOutlined } from '@ant-design/icons';
|
||||
import { DatabaseOutlined } from '@ant-design/icons';
|
||||
import { PluginManager } from '@nocobase/client';
|
||||
|
||||
export const Plugin1 = () => null;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { Layout } from 'antd';
|
||||
import { Button, Layout } from 'antd';
|
||||
import { useRoute } from '../../hooks';
|
||||
import { useHistory, useRouteMatch } from 'react-router-dom';
|
||||
import { findMenuItem, RemoteSchemaComponent, PluginManager } from '../../../';
|
||||
import { findMenuItem, RemoteSchemaComponent, PluginManager, CurrentUser } from '../../../';
|
||||
|
||||
export function AdminLayout(props: any) {
|
||||
const route = useRoute();
|
||||
@ -44,7 +44,15 @@ export function AdminLayout(props: any) {
|
||||
/>
|
||||
</div>
|
||||
<div style={{ position: 'absolute', top: 0, right: 0 }}>
|
||||
<PluginManager.Toolbar />
|
||||
<PluginManager.Toolbar
|
||||
items={[
|
||||
{ component: 'DesignableSwitch', pin: true },
|
||||
{ component: 'CollectionManagerShortcut', pin: true },
|
||||
{ component: 'ACLShortcut', pin: true },
|
||||
{ component: 'SystemSettingsShortcut' },
|
||||
]}
|
||||
/>
|
||||
<CurrentUser.Dropdown/>
|
||||
</div>
|
||||
</Layout.Header>
|
||||
<Layout>
|
||||
|
@ -3,12 +3,18 @@ import { Button, Menu } from 'antd';
|
||||
import { HighlightOutlined } from '@ant-design/icons';
|
||||
import cls from 'classnames';
|
||||
import { useDesignable } from '..';
|
||||
import { PluginManager } from '../../plugin-manager';
|
||||
|
||||
export const DesignableSwitch = () => {
|
||||
const { designable, setDesignable } = useDesignable();
|
||||
return (
|
||||
<Menu.Item key={'DesignableSwitch'} eventKey={'DesignableSwitch'}>
|
||||
<HighlightOutlined />
|
||||
</Menu.Item>
|
||||
<PluginManager.Toolbar.Item
|
||||
selected={designable}
|
||||
icon={<HighlightOutlined />}
|
||||
title={'界面配置'}
|
||||
onClick={() => {
|
||||
setDesignable(!designable);
|
||||
}}
|
||||
></PluginManager.Toolbar.Item>
|
||||
);
|
||||
};
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Menu } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { LockOutlined } from '@ant-design/icons';
|
||||
import { SettingOutlined } from '@ant-design/icons';
|
||||
import { SchemaComponent, useActionVisible, VisibleContext } from '../schema-component';
|
||||
import { ISchema, useForm } from '@formily/react';
|
||||
import { PluginManager } from '..';
|
||||
|
||||
const useCloseAction = () => {
|
||||
const { setVisible } = useActionVisible();
|
||||
@ -47,18 +48,18 @@ const schema: ISchema = {
|
||||
},
|
||||
};
|
||||
|
||||
export const SystemSettingsAction = () => {
|
||||
export const SystemSettingsShortcut = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||
<Menu.Item
|
||||
<PluginManager.Toolbar.Item
|
||||
eventKey={'ACLAction'}
|
||||
onClick={() => {
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
<LockOutlined /> 系统设置
|
||||
</Menu.Item>
|
||||
icon={<SettingOutlined />}
|
||||
title={'系统设置'}
|
||||
/>
|
||||
<SchemaComponent scope={{ useCloseAction }} schema={schema} />
|
||||
</VisibleContext.Provider>
|
||||
);
|
@ -1,5 +1 @@
|
||||
import { SystemSettingsAction } from './SystemSettingsAction';
|
||||
|
||||
export const SystemSettings = () => null;
|
||||
|
||||
SystemSettings.Action = SystemSettingsAction;
|
||||
export * from './SystemSettingsShortcut';
|
||||
|
Loading…
Reference in New Issue
Block a user