diff --git a/packages/client/src/plugin-manager/PluginManager.tsx b/packages/client/src/plugin-manager/PluginManager.tsx index 56a119ee9..e2af0f622 100644 --- a/packages/client/src/plugin-manager/PluginManager.tsx +++ b/packages/client/src/plugin-manager/PluginManager.tsx @@ -1,53 +1,71 @@ -import React, { createContext } from 'react'; -import { Menu, Space } from 'antd'; +import React, { createContext, useContext } from 'react'; +import { Menu, Space, Tooltip } from 'antd'; import { SettingOutlined, MoreOutlined, DesktopOutlined } from '@ant-design/icons'; import { CurrentUser, DesignableSwitch, CollectionManagerAction, ACLAction, SystemSettings } from '../'; import { get } from 'lodash'; -import { PluginManagerProvider } from '.'; +import { PluginManagerContext, PluginManagerProvider } from '.'; -export const PluginManager = () => null; +// TODO +export const PluginManager: any = () => null; PluginManager.Provider = PluginManagerProvider; +const ToolbarItemContext = createContext(null); + PluginManager.Toolbar = (props: any) => { - const components = { CurrentUser, DesignableSwitch, CollectionManagerAction, ACLAction, SystemSettings }; - const items = [ - { - action: 'DesignableSwitch', - pin: true, - }, - { - action: 'CollectionManagerAction', - pin: true, - }, - { - action: 'ACLAction', - pin: true, - }, - { - action: 'SystemSettings.Action', - }, - ]; - const CurrentUserDropdown = get(components, 'CurrentUser.Dropdown'); + const { components } = useContext(PluginManagerContext); + const { items = [] } = props; return ( - - {items - .filter((item) => item.pin) - .map((item) => { - const Action = get(components, item.action); - return Action && ; - })} - }> +
+ {items - .filter((item) => !item.pin) + .filter((item) => item.pin) .map((item) => { - const Action = get(components, item.action); - return Action && ; + const Action = get(components, item.component); + return ( + Action && ( + + + + ) + ); })} - - }>管理插件 - - - + }> + {items + .filter((item) => !item.pin) + .map((item) => { + const Action = get(components, item.component); + return ( + Action && ( + + + + ) + ); + })} + + }>管理插件 + +
+ + ); +}; + +PluginManager.Toolbar.Item = (props) => { + const item = useContext(ToolbarItemContext); + const { icon, title, ...others } = props; + if (item.pin) { + return ( + + + {icon} + + + ); + } + return ( + + {title} + ); }; diff --git a/packages/client/src/plugin-manager/demos/demo1.tsx b/packages/client/src/plugin-manager/demos/demo1.tsx new file mode 100644 index 000000000..866c2f4a3 --- /dev/null +++ b/packages/client/src/plugin-manager/demos/demo1.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { Action, PluginManager, PluginManagerProvider, SchemaComponentProvider } from '@nocobase/client'; +import * as plugins from './plugins'; + +export default () => { + return ( + + + + + + ); +}; diff --git a/packages/client/src/plugin-manager/demos/plugins/index.tsx b/packages/client/src/plugin-manager/demos/plugins/index.tsx new file mode 100644 index 000000000..2a632ebf5 --- /dev/null +++ b/packages/client/src/plugin-manager/demos/plugins/index.tsx @@ -0,0 +1,5 @@ +export * from './plugin1'; +export * from './plugin2'; +export * from './plugin3'; +export * from './plugin4'; +export * from './plugin5'; diff --git a/packages/client/src/plugin-manager/demos/plugins/plugin1.tsx b/packages/client/src/plugin-manager/demos/plugins/plugin1.tsx new file mode 100644 index 000000000..9447a87f6 --- /dev/null +++ b/packages/client/src/plugin-manager/demos/plugins/plugin1.tsx @@ -0,0 +1,17 @@ +import { Menu } from 'antd'; +import React from 'react'; +import { SaveOutlined, KeyOutlined, DatabaseOutlined, VerifiedOutlined, NotificationOutlined } from '@ant-design/icons'; +import { PluginManager } from '@nocobase/client'; + +export const Plugin1 = () => null; +Plugin1.ToolbarItem = () => { + return ( + } + title={'Plugin1'} + onClick={() => { + alert('Plugin1'); + }} + /> + ); +}; diff --git a/packages/client/src/plugin-manager/demos/plugins/plugin2.tsx b/packages/client/src/plugin-manager/demos/plugins/plugin2.tsx new file mode 100644 index 000000000..eb809bc4a --- /dev/null +++ b/packages/client/src/plugin-manager/demos/plugins/plugin2.tsx @@ -0,0 +1,65 @@ +import React, { useState } from 'react'; +import { VerifiedOutlined } from '@ant-design/icons'; +import { ISchema, useForm } from '@formily/react'; +import { PluginManager, SchemaComponent, useActionVisible, VisibleContext } from '@nocobase/client'; + +const useCloseAction = () => { + const { setVisible } = useActionVisible(); + const form = useForm(); + return { + async run() { + setVisible(false); + form.submit((values) => { + console.log(values); + }); + }, + }; +}; + +const schema: ISchema = { + type: 'object', + properties: { + drawer1: { + 'x-component': 'Action.Drawer', + type: 'void', + title: 'Drawer Title', + properties: { + hello1: { + 'x-content': 'Hello', + title: 'T1', + }, + footer1: { + 'x-component': 'Action.Drawer.Footer', + type: 'void', + properties: { + close1: { + title: 'Close', + 'x-component': 'Action', + 'x-component-props': { + useAction: '{{ useCloseAction }}', + }, + }, + }, + }, + }, + }, + }, +}; + +export const Plugin2 = () => null; + +Plugin2.ToolbarItem = () => { + const [visible, setVisible] = useState(false); + return ( + + } + title={'Plugin2'} + onClick={() => { + setVisible(true); + }} + /> + + + ); +}; diff --git a/packages/client/src/plugin-manager/demos/plugins/plugin3.tsx b/packages/client/src/plugin-manager/demos/plugins/plugin3.tsx new file mode 100644 index 000000000..102d8aa5b --- /dev/null +++ b/packages/client/src/plugin-manager/demos/plugins/plugin3.tsx @@ -0,0 +1,17 @@ +import { Menu } from 'antd'; +import React from 'react'; +import { SaveOutlined, KeyOutlined, DatabaseOutlined, VerifiedOutlined, NotificationOutlined } from '@ant-design/icons'; +import { PluginManager } from '@nocobase/client'; + +export const Plugin3 = () => null; +Plugin3.ToolbarItem = () => { + return ( + } + title={'Plugin3'} + onClick={() => { + alert('Plugin3'); + }} + /> + ); +}; diff --git a/packages/client/src/plugin-manager/demos/plugins/plugin4.tsx b/packages/client/src/plugin-manager/demos/plugins/plugin4.tsx new file mode 100644 index 000000000..637317688 --- /dev/null +++ b/packages/client/src/plugin-manager/demos/plugins/plugin4.tsx @@ -0,0 +1,65 @@ +import React, { useState } from 'react'; +import { VerifiedOutlined } from '@ant-design/icons'; +import { ISchema, useForm } from '@formily/react'; +import { PluginManager, SchemaComponent, useActionVisible, VisibleContext } from '@nocobase/client'; + +const useCloseAction = () => { + const { setVisible } = useActionVisible(); + const form = useForm(); + return { + async run() { + setVisible(false); + form.submit((values) => { + console.log(values); + }); + }, + }; +}; + +const schema: ISchema = { + type: 'object', + properties: { + drawer1: { + 'x-component': 'Action.Drawer', + type: 'void', + title: 'Drawer Title', + properties: { + hello1: { + 'x-content': 'Hello', + title: 'T1', + }, + footer1: { + 'x-component': 'Action.Drawer.Footer', + type: 'void', + properties: { + close1: { + title: 'Close', + 'x-component': 'Action', + 'x-component-props': { + useAction: '{{ useCloseAction }}', + }, + }, + }, + }, + }, + }, + }, +}; + +export const Plugin4 = () => null; + +Plugin4.ToolbarItem = () => { + const [visible, setVisible] = useState(false); + return ( + + } + title={'Plugin4'} + onClick={() => { + setVisible(true); + }} + /> + + + ); +}; diff --git a/packages/client/src/plugin-manager/demos/plugins/plugin5.tsx b/packages/client/src/plugin-manager/demos/plugins/plugin5.tsx new file mode 100644 index 000000000..a9a671c94 --- /dev/null +++ b/packages/client/src/plugin-manager/demos/plugins/plugin5.tsx @@ -0,0 +1,17 @@ +import { Menu } from 'antd'; +import React from 'react'; +import { SaveOutlined, KeyOutlined, DatabaseOutlined, VerifiedOutlined, NotificationOutlined } from '@ant-design/icons'; +import { PluginManager } from '@nocobase/client'; + +export const Plugin5 = () => null; +Plugin5.ToolbarItem = () => { + return ( + } + title={'Plugin5'} + onClick={() => { + alert('Plugin5'); + }} + /> + ); +}; diff --git a/packages/client/src/plugin-manager/index.md b/packages/client/src/plugin-manager/index.md index fd2687e1b..2aada8867 100644 --- a/packages/client/src/plugin-manager/index.md +++ b/packages/client/src/plugin-manager/index.md @@ -7,49 +7,53 @@ group: # PluginManager -```tsx | pure - - - -``` +## PluginManagerProvider -## 扩展 +## PluginManager.Toolbar -如何扩展插件的 `PluginManager.Toolbar.Item` +插件管理器的工具栏,用于便捷的展示所有插件,不常用的可折叠显示。 + + + +## PluginManager.Toolbar.Item + +工具栏项,各个插件都可以配置自己的 `PluginManager.Toolbar.Item` + +- `icon` pin 时,只显示 icon +- `title` pin 时,title 以 tooltip 的方式显示 + +最简单的示例 ```tsx | pure -import React from 'react'; -import { Button, Menu } from 'antd'; -import { HighlightOutlined } from '@ant-design/icons'; - -export const DesignableSwitch = () => { - const { designable, setDesignable } = useDesignable(); +Plugin1.ToolbarItem = () => { return ( - - - + } + title={'Plugin1'} + onClick={() => { + alert('Plugin1'); + }} + /> ); }; -``` \ No newline at end of file +``` + +弹出抽屉 + +```tsx | pure +Plugin2.ToolbarItem = () => { + const [visible, setVisible] = useState(false); + return ( + + } + title={'Plugin2'} + onClick={() => { + setVisible(true); + }} + /> + + + ); +}; +```