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