import { DeleteOutlined, SettingOutlined } from '@ant-design/icons'; import { css } from '@emotion/css'; import { Avatar, Card, Layout, Menu, message, PageHeader, Popconfirm, Spin, Switch, Tabs } from 'antd'; import React, { createContext, useContext, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Redirect, useHistory, useRouteMatch } from 'react-router-dom'; import { ACLPane } from '../acl'; import { useAPIClient, useRequest } from '../api-client'; import { CollectionManagerPane } from '../collection-manager'; import { useDocumentTitle } from '../document-title'; import { Icon } from '../icon'; import { RouteSwitchContext } from '../route-switch'; import { useCompile } from '../schema-component'; import { BlockTemplatesPane } from '../schema-templates'; import { SystemSettingsPane } from '../system-settings'; export const SettingsCenterContext = createContext({}); const PluginCard = (props) => { const history = useHistory(); const { data = {} } = props; const api = useAPIClient(); const { t } = useTranslation(); return ( { history.push(`/admin/settings/${data.name}`); }} /> ) : null, { await api.request({ url: `pm:remove/${data.name}`, }); message.success(t('插件删除成功')); window.location.reload(); }} onCancel={() => {}} okText={t('Yes')} cancelText={t('No')} > , { await api.request({ url: `pm:${checked ? 'enable' : 'disable'}/${data.name}`, }); message.success(checked ? t('插件激活成功') : t('插件禁用成功')); window.location.reload(); }} defaultChecked={data.enabled} >, ].filter(Boolean)} > } description={data.description} title={ {data.name} {data.version} } /> ); }; const BuiltInPluginCard = (props) => { const { data } = props; return ( Settings, Remove, ]} > } description={data.description} title={ {data.name} {data.version} } /> ); }; const LocalPlugins = () => { const { data, loading } = useRequest({ url: 'applicationPlugins:list', params: { filter: { 'builtIn.$isFalsy': true, }, sort: 'name', }, }); if (loading) { return ; } return ( <> {data?.data?.map((item) => { return ; })} ); }; const BuiltinPlugins = () => { const { data, loading } = useRequest({ url: 'applicationPlugins:list', params: { filter: { 'builtIn.$isTruly': true, }, sort: 'name', }, }); if (loading) { return ; } return ( <> {data?.data?.map((item) => { return ; })} ); }; const MarketplacePlugins = () => { const { t } = useTranslation(); return
{t('Coming soon...')}
; }; const PluginList = (props) => { const match = useRouteMatch(); const history = useHistory(); const { tabName = 'local' } = match.params || {}; const { setTitle } = useDocumentTitle(); const { t } = useTranslation(); return (
{ history.push(`/admin/pm/list/${activeKey}`); }} > } />
{React.createElement( { local: LocalPlugins, 'built-in': BuiltinPlugins, marketplace: MarketplacePlugins, }[tabName], )}
); }; const settings = { acl: { title: '{{t("ACL")}}', icon: 'LockOutlined', tabs: { roles: { title: '{{t("Roles & Permissions")}}', component: ACLPane, }, }, }, 'block-templates': { title: '{{t("Block templates")}}', icon: 'LayoutOutlined', tabs: { list: { title: '{{t("Block templates")}}', component: BlockTemplatesPane, }, }, }, 'collection-manager': { icon: 'DatabaseOutlined', title: '{{t("Collection manager")}}', tabs: { collections: { title: '{{t("Collections & Fields")}}', component: CollectionManagerPane, }, }, }, 'system-settings': { icon: 'SettingOutlined', title: '{{t("System settings")}}', tabs: { 'system-settings': { title: '{{t("System settings")}}', component: SystemSettingsPane, }, }, }, }; const SettingsCenter = (props) => { const match = useRouteMatch(); const history = useHistory(); const items = useContext(SettingsCenterContext); const compile = useCompile(); const firstUri = useMemo(() => { const keys = Object.keys(items).sort(); const pluginName = keys.shift(); const tabName = Object.keys(items?.[pluginName]?.tabs || {}).shift(); return `/admin/settings/${pluginName}/${tabName}`; }, [items]); const { pluginName, tabName } = match.params || {}; if (!pluginName) { return ; } if (!items[pluginName]) { return ; } if (!tabName) { const firstTabName = Object.keys(items[pluginName]?.tabs).shift(); return ; } const component = items[pluginName]?.tabs?.[tabName]?.component; const menuItems: any = Object.keys(items) .sort() .map((key) => { const item = items[key]; const tabKey = Object.keys(item.tabs).shift(); return { label: compile(item.title), key: key, icon: item.icon ? : null, }; }); return (
} className={css` width: var(--side-menu-width); overflow: hidden; flex: 0 0 var(--side-menu-width); max-width: var(--side-menu-width); min-width: var(--side-menu-width); pointer-events: none; `} >
{ const item = items[e.key]; const tabKey = Object.keys(item.tabs).shift(); history.push(`/admin/settings/${e.key}/${tabKey}`); }} items={menuItems as any} /> { history.push(`/admin/settings/${pluginName}/${activeKey}`); }} > {Object.keys(items[pluginName]?.tabs).map((tabKey) => { const tab = items[pluginName].tabs?.[tabKey]; return ; })} } />
{component && React.createElement(component)}
); }; export const SettingsCenterProvider = (props) => { const { settings = {} } = props; const items = useContext(SettingsCenterContext); return ( {props.children} ); }; export const PMProvider = (props) => { const { routes, ...others } = useContext(RouteSwitchContext); routes[1].routes.unshift( { type: 'route', path: '/admin/pm/list/:tabName?', component: PluginList, }, { type: 'route', path: '/admin/settings/:pluginName?/:tabName?', component: SettingsCenter, uiSchemaUid: routes[1].uiSchemaUid, }, ); return ( {props.children} ); }; export default PMProvider; export * from './PluginManagerLink';