From 0832a568682c70d2758f3b8b2399ac0e8402df81 Mon Sep 17 00:00:00 2001 From: ChengLei Shao Date: Fri, 10 Mar 2023 19:16:00 +0800 Subject: [PATCH] feat: multiple apps (#1540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: skip yarn install in pm command * feat: dump sub app by sub app name * feat: dump & restore by sub app * chore: enable application name to edit * chore: field belongsTo uiSchema * test: drop schema * feat: uiSchema migrator * fix: test * fix: remove uiSchema * fix: rerun migration * chore: migrate fieldsHistory uiSchema * fix: set uiSchema options * chore: transaction params * fix: sql error in mysql * fix: sql compatibility * feat: collection group api * chore: restore & dump action template * chore: tmp commit * chore: collectionGroupAction * feat: dumpableCollection api * refactor: dump command * fix: remove uiSchemaUid * chore: get uiSchemaUid from tmp field * feat: return dumped file url in dumper.dump * feat: dump api * refactor: collection groyoup * chore: comment * feat: restore command force option * feat: dump with collection groups * refactor: restore command * feat: restore http api * fix: test * fix: test * fix: restore test * chore: volta pin * fix: sub app load collection options * fix: stop sub app * feat: add stopped status to application to prevent duplicate application stop * chore: tmp commit * test: upgrade * feat: pass upgrade event to sub app * fix: app manager client * fix: remove stopped status * fix: emit beforeStop event * feat: support dump & restore subApp through api * chore: dumpable collections api * refactor: getTableNameWithSchema * fix: schema name * feat: cname * refactor: collection 同步实现方式 * refactor: move collection group manager to database * fix: test * fix: remove uiSchema * fix: uiSchema * fix: remove settings * chore: plugin enable & disable event * feat: modal warning * fix: users_jobs namespace * fix: rolesUischemas namespace * fix: am snippet * feat: beforeSubAppInstall event * fix: improve NOCOBASE_LOCALE_KEY & NOCOBASE_ROLE_KEY --------- Co-authored-by: chenos --- .gitignore | 1 + .../client/src/plugins/multi-app-manager.ts | 1 + .../client/src/application/Application.tsx | 31 +- .../CollectionHistoryProvider.tsx | 2 +- .../CollectionManagerProvider.tsx | 2 +- .../Configuration/EditFieldAction.tsx | 4 +- .../OverridingCollectionField.tsx | 2 +- .../Configuration/ViewInheritedField.tsx | 4 +- .../Configuration/schemas/collectionFields.ts | 2 +- .../src/collection-manager/action-hooks.ts | 10 +- .../src/collection-manager/sub-table.tsx | 4 +- .../PinnedPluginListProvider.tsx | 51 +++ .../core/client/src/plugin-manager/context.ts | 1 + .../core/client/src/plugin-manager/index.ts | 2 + .../core/client/src/pm/PluginManagerLink.tsx | 52 ++- packages/core/client/src/pm/index.tsx | 13 +- .../route-switch/antd/admin-layout/index.tsx | 6 +- .../core/DesignableSwitch.tsx | 14 +- packages/core/client/src/user/CurrentUser.tsx | 27 +- packages/core/client/src/user/SwitchRole.tsx | 5 +- .../database/src/collection-group-manager.ts | 94 +++++ packages/core/database/src/collection.ts | 18 +- packages/core/database/src/database.ts | 7 +- packages/core/database/src/fields/field.ts | 18 +- packages/core/database/src/index.ts | 2 +- packages/core/database/src/sync-runner.ts | 14 +- packages/core/sdk/src/APIClient.ts | 26 +- .../server/src/__tests__/application.test.ts | 1 + .../__tests__/multiple-application.test.ts | 23 +- .../core/server/src/__tests__/upgrade.test.ts | 33 ++ packages/core/server/src/app-manager.ts | 37 +- packages/core/server/src/application.ts | 25 +- packages/core/server/src/commands/pm.ts | 4 +- .../core/server/src/plugin-manager/index.ts | 3 +- .../src/plugin-manager/options/collection.ts | 8 +- ...sitory.ts => plugin-manager-repository.ts} | 2 +- .../{PluginManager.ts => plugin-manager.ts} | 35 +- packages/core/test/src/mockServer.ts | 7 + .../acl/src/collections/roles-users.ts | 2 +- packages/plugins/acl/src/collections/roles.ts | 7 +- .../acl/src/collections/rolesResources.ts | 2 +- .../src/collections/rolesResourcesActions.ts | 2 +- .../src/collections/rolesResourcesScopes.ts | 2 +- packages/plugins/acl/src/server.ts | 2 +- .../src/server/collections/auditChanges.ts | 2 +- .../src/server/collections/auditLogs.ts | 2 +- .../src/server/collections/chartsQueries.ts | 2 + .../src/server/collections/chinaRegions.ts | 2 +- .../src/__tests__/action.test.ts | 9 +- .../__tests__/collections.repository.test.ts | 6 +- .../field-options/default-value.test.ts | 2 +- .../src/__tests__/fields/reverseField.test.ts | 23 +- .../__tests__/http-api/collections.test.ts | 8 +- .../collection-manager/src/__tests__/index.ts | 14 +- .../drop-ui-schema-relation.test.ts | 162 ++++++++ .../migrations/update-id-to-bigint.test.ts | 9 +- .../src/collections/collectionCategories.ts | 12 +- .../src/collections/collections.ts | 2 +- .../src/collections/fields.ts | 8 +- .../20230225111111-drop-ui-schema-relation.ts | 82 ++++ .../src/models/collection.ts | 5 + .../collection-manager/src/models/field.ts | 26 +- .../plugins/collection-manager/src/server.ts | 8 +- packages/plugins/duplicator/package.json | 2 + .../src/server/__tests__/api.test.ts | 73 ++++ .../collection-group-manager.test.ts | 37 ++ .../{dump.test.ts => dump-action.test.ts} | 0 .../src/server/__tests__/dumper.test.ts | 35 ++ .../__tests__/fixtures/dump.nbdump.fixture | Bin 0 -> 21317 bytes .../duplicator/src/server/__tests__/index.ts | 11 + .../src/server/actions/dump-action.ts | 25 ++ .../actions/dumpable-collections-action.ts | 13 + .../duplicator/src/server/actions/get-app.ts | 14 + .../src/server/actions/get-dict-action.ts | 34 ++ .../src/server/actions/restore-action.ts | 43 +++ .../duplicator/src/server/app-migrator.ts | 79 +--- .../src/server/collection-group-manager.ts | 241 +----------- .../src/server/commands/dump-command.ts | 49 +++ .../duplicator/src/server/commands/dump.ts | 15 - .../commands/inquire-question-builder.ts | 72 ++++ .../src/server/commands/restore-command.ts | 94 +++++ .../duplicator/src/server/commands/restore.ts | 22 -- .../plugins/duplicator/src/server/dumper.ts | 171 +++++---- .../plugins/duplicator/src/server/restorer.ts | 158 ++++---- .../plugins/duplicator/src/server/server.ts | 64 ++-- .../src/server/collections/attachments.ts | 2 +- .../src/server/collections/storages.ts | 2 +- .../plugins/file-manager/src/server/server.ts | 10 + .../src/server/collections/graphPositions.ts | 2 +- .../src/server/collections/iframe-html.ts | 2 +- .../server/collections/mapConfiguration.ts | 16 +- .../plugins/multi-app-manager/client.d.ts | 4 + packages/plugins/multi-app-manager/client.js | 30 ++ .../plugins/multi-app-manager/server.d.ts | 4 + packages/plugins/multi-app-manager/server.js | 30 ++ .../src/client/AppManager.tsx | 21 ++ .../src/client/AppNameInput.tsx | 22 ++ .../multi-app-manager/src/client/Settings.tsx | 15 + .../multi-app-manager/src/client/index.tsx | 92 +++++ .../client/settings/schemas/applications.ts | 351 ++++++++++++++++++ .../src/collections/applications.ts | 46 --- .../plugins/multi-app-manager/src/index.ts | 5 +- .../__tests__/mock-get-schema.test.ts | 0 .../__tests__/multiple-apps.test.ts | 0 .../src/server/collections/applications.ts | 45 +++ .../multi-app-manager/src/server/index.ts | 4 + .../src/{ => server}/models/application.ts | 6 + .../src/{ => server}/server.ts | 52 ++- .../src/server/collections/oidcProviders.ts | 2 +- .../src/server/collections/samlProviders.ts | 2 +- .../src/server/collections/sequences.ts | 68 +++- .../server/collections/collectionsHistory.ts | 2 +- .../src/server/collections/fieldsHistory.ts | 14 +- .../src/collections/systemSettings.ts | 2 +- .../src/collections/uiRoutes.ts | 2 +- .../src/collections/uiSchemaServerHooks.ts | 2 +- .../src/collections/uiSchemaTemplates.ts | 2 +- .../src/collections/uiSchemaTreePath.ts | 2 +- .../src/collections/uiSchemas.ts | 2 +- .../plugins/users/src/collections/users.ts | 7 +- .../src/server/collections/verifications.ts | 18 +- .../collections/verifications_providers.ts | 14 +- .../src/server/collections/executions.ts | 12 +- .../src/server/collections/flow_nodes.ts | 12 +- .../workflow/src/server/collections/jobs.ts | 16 +- .../src/server/collections/workflows.ts | 36 +- .../manual/collecions/users_jobs.ts | 2 +- packages/presets/nocobase/src/index.ts | 13 +- yarn.lock | 310 ++++++++++++++-- 129 files changed, 2618 insertions(+), 927 deletions(-) create mode 100644 packages/app/client/src/plugins/multi-app-manager.ts create mode 100644 packages/core/client/src/plugin-manager/PinnedPluginListProvider.tsx create mode 100644 packages/core/database/src/collection-group-manager.ts create mode 100644 packages/core/server/src/__tests__/upgrade.test.ts rename packages/core/server/src/plugin-manager/{PluginManagerRepository.ts => plugin-manager-repository.ts} (96%) rename packages/core/server/src/plugin-manager/{PluginManager.ts => plugin-manager.ts} (98%) create mode 100644 packages/plugins/collection-manager/src/__tests__/migrations/drop-ui-schema-relation.test.ts create mode 100644 packages/plugins/collection-manager/src/migrations/20230225111111-drop-ui-schema-relation.ts create mode 100644 packages/plugins/duplicator/src/server/__tests__/api.test.ts create mode 100644 packages/plugins/duplicator/src/server/__tests__/collection-group-manager.test.ts rename packages/plugins/duplicator/src/server/__tests__/{dump.test.ts => dump-action.test.ts} (100%) create mode 100644 packages/plugins/duplicator/src/server/__tests__/dumper.test.ts create mode 100644 packages/plugins/duplicator/src/server/__tests__/fixtures/dump.nbdump.fixture create mode 100644 packages/plugins/duplicator/src/server/__tests__/index.ts create mode 100644 packages/plugins/duplicator/src/server/actions/dump-action.ts create mode 100644 packages/plugins/duplicator/src/server/actions/dumpable-collections-action.ts create mode 100644 packages/plugins/duplicator/src/server/actions/get-app.ts create mode 100644 packages/plugins/duplicator/src/server/actions/get-dict-action.ts create mode 100644 packages/plugins/duplicator/src/server/actions/restore-action.ts create mode 100644 packages/plugins/duplicator/src/server/commands/dump-command.ts delete mode 100644 packages/plugins/duplicator/src/server/commands/dump.ts create mode 100644 packages/plugins/duplicator/src/server/commands/inquire-question-builder.ts create mode 100644 packages/plugins/duplicator/src/server/commands/restore-command.ts delete mode 100644 packages/plugins/duplicator/src/server/commands/restore.ts create mode 100755 packages/plugins/multi-app-manager/client.d.ts create mode 100755 packages/plugins/multi-app-manager/client.js create mode 100755 packages/plugins/multi-app-manager/server.d.ts create mode 100755 packages/plugins/multi-app-manager/server.js create mode 100644 packages/plugins/multi-app-manager/src/client/AppManager.tsx create mode 100644 packages/plugins/multi-app-manager/src/client/AppNameInput.tsx create mode 100644 packages/plugins/multi-app-manager/src/client/Settings.tsx create mode 100644 packages/plugins/multi-app-manager/src/client/index.tsx create mode 100644 packages/plugins/multi-app-manager/src/client/settings/schemas/applications.ts delete mode 100644 packages/plugins/multi-app-manager/src/collections/applications.ts rename packages/plugins/multi-app-manager/src/{ => server}/__tests__/mock-get-schema.test.ts (100%) rename packages/plugins/multi-app-manager/src/{ => server}/__tests__/multiple-apps.test.ts (100%) create mode 100644 packages/plugins/multi-app-manager/src/server/collections/applications.ts create mode 100644 packages/plugins/multi-app-manager/src/server/index.ts rename packages/plugins/multi-app-manager/src/{ => server}/models/application.ts (95%) rename packages/plugins/multi-app-manager/src/{ => server}/server.ts (79%) diff --git a/.gitignore b/.gitignore index b0b615528..28be725f0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ dist/ docker/**/storage cache/diskstore-* *.nbdump +storage/duplicator/* \ No newline at end of file diff --git a/packages/app/client/src/plugins/multi-app-manager.ts b/packages/app/client/src/plugins/multi-app-manager.ts new file mode 100644 index 000000000..2faddb857 --- /dev/null +++ b/packages/app/client/src/plugins/multi-app-manager.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-multi-app-manager/client'; \ No newline at end of file diff --git a/packages/core/client/src/application/Application.tsx b/packages/core/client/src/application/Application.tsx index b0b8e0720..2b7112abd 100644 --- a/packages/core/client/src/application/Application.tsx +++ b/packages/core/client/src/application/Application.tsx @@ -3,14 +3,13 @@ import { i18n as i18next } from 'i18next'; import React, { useEffect, useState } from 'react'; import { I18nextProvider } from 'react-i18next'; import { Link, NavLink } from 'react-router-dom'; -import { ACLProvider, ACLShortcut } from '../acl'; +import { ACLProvider } from '../acl'; import { AntdConfigProvider } from '../antd-config-provider'; import { APIClient, APIClientProvider } from '../api-client'; import { BlockSchemaComponentProvider } from '../block-provider'; -import { CollectionManagerShortcut } from '../collection-manager'; import { RemoteDocumentTitleProvider } from '../document-title'; import { i18n } from '../i18n'; -import { PluginManagerProvider } from '../plugin-manager'; +import { PinnedPluginListProvider } from '../plugin-manager'; import PMProvider, { PluginManagerLink, SettingsCenterDropdown } from '../pm'; import { AdminLayout, @@ -18,17 +17,17 @@ import { RemoteRouteSwitchProvider, RouteSchemaComponent, RouteSwitch, - useRoutes, + useRoutes } from '../route-switch'; import { AntdSchemaComponentProvider, DesignableSwitch, MenuItemInitializers, - SchemaComponentProvider, + SchemaComponentProvider } from '../schema-component'; import { SchemaInitializerProvider } from '../schema-initializer'; -import { BlockTemplateDetails, BlockTemplatePage, SchemaTemplateShortcut } from '../schema-templates'; -import { SystemSettingsProvider, SystemSettingsShortcut } from '../system-settings'; +import { BlockTemplateDetails, BlockTemplatePage } from '../schema-templates'; +import { SystemSettingsProvider } from '../system-settings'; import { SigninPage, SignupPage } from '../user'; import { SigninPageExtensionProvider } from '../user/SigninPageExtension'; import { compose } from './compose'; @@ -94,18 +93,16 @@ export class Application { }, }); this.use(SystemSettingsProvider); - this.use(PluginManagerProvider, { - components: { - ACLShortcut, - DesignableSwitch, - CollectionManagerShortcut, - SystemSettingsShortcut, - SchemaTemplateShortcut, - PluginManagerLink, - SettingsCenterDropdown, + this.use(PinnedPluginListProvider, { + items: { + ui: { order: 100, component: 'DesignableSwitch', pin: true, snippet: 'ui.*' }, + pm: { order: 200, component: 'PluginManagerLink', pin: true, snippet: 'pm' }, + sc: { order: 300, component: 'SettingsCenterDropdown', pin: true, snippet: 'pm.*' }, }, }); - this.use(SchemaComponentProvider, { components: { Link, NavLink } }); + this.use(SchemaComponentProvider, { + components: { Link, NavLink, DesignableSwitch, PluginManagerLink, SettingsCenterDropdown }, + }); this.use(SchemaInitializerProvider, { initializers: { MenuItemInitializers, diff --git a/packages/core/client/src/collection-manager/CollectionHistoryProvider.tsx b/packages/core/client/src/collection-manager/CollectionHistoryProvider.tsx index c0bb92f43..956ab63be 100644 --- a/packages/core/client/src/collection-manager/CollectionHistoryProvider.tsx +++ b/packages/core/client/src/collection-manager/CollectionHistoryProvider.tsx @@ -21,7 +21,7 @@ export const CollectionHistoryProvider: React.FC = (props) => { action: 'list', params: { paginate: false, - appends: ['fields', 'fields.uiSchema'], + appends: ['fields'], filter: { // inherit: false, }, diff --git a/packages/core/client/src/collection-manager/CollectionManagerProvider.tsx b/packages/core/client/src/collection-manager/CollectionManagerProvider.tsx index 0d93e6635..46ac952c7 100644 --- a/packages/core/client/src/collection-manager/CollectionManagerProvider.tsx +++ b/packages/core/client/src/collection-manager/CollectionManagerProvider.tsx @@ -38,7 +38,7 @@ export const RemoteCollectionManagerProvider = (props: any) => { action: 'list', params: { paginate: false, - appends: ['fields', 'fields.uiSchema', 'category'], + appends: ['fields', 'category'], filter: { // inherit: false, }, diff --git a/packages/core/client/src/collection-manager/Configuration/EditFieldAction.tsx b/packages/core/client/src/collection-manager/Configuration/EditFieldAction.tsx index 656288ff7..401a09e79 100644 --- a/packages/core/client/src/collection-manager/Configuration/EditFieldAction.tsx +++ b/packages/core/client/src/collection-manager/Configuration/EditFieldAction.tsx @@ -6,7 +6,7 @@ import set from 'lodash/set'; import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useAPIClient, useRequest } from '../../api-client'; -import { useRecord, RecordProvider } from '../../record-provider'; +import { RecordProvider, useRecord } from '../../record-provider'; import { ActionContext, SchemaComponent, useActionContext, useCompile } from '../../schema-component'; import { useCancelAction, useUpdateAction } from '../action-hooks'; import { useCollectionManager } from '../hooks'; @@ -131,7 +131,7 @@ export const EditFieldAction = (props) => { onClick={async () => { const { data } = await api.resource('collections.fields', record.collectionName).get({ filterByTk: record.name, - appends: ['uiSchema', 'reverseField'], + appends: ['reverseField'], }); setData(data?.data); const interfaceConf = getInterface(record.interface); diff --git a/packages/core/client/src/collection-manager/Configuration/OverridingCollectionField.tsx b/packages/core/client/src/collection-manager/Configuration/OverridingCollectionField.tsx index 7016a56b6..a7245cd33 100644 --- a/packages/core/client/src/collection-manager/Configuration/OverridingCollectionField.tsx +++ b/packages/core/client/src/collection-manager/Configuration/OverridingCollectionField.tsx @@ -156,7 +156,7 @@ export const OverridingFieldAction = (props) => { if (!disabled) { const { data } = await api.resource('collections.fields', record.collectionName).get({ filterByTk: record.name, - appends: ['uiSchema', 'reverseField'], + appends: ['reverseField'], }); setData(data?.data); const interfaceConf = getInterface(record.interface); diff --git a/packages/core/client/src/collection-manager/Configuration/ViewInheritedField.tsx b/packages/core/client/src/collection-manager/Configuration/ViewInheritedField.tsx index 5a8c0492a..1921c69a5 100644 --- a/packages/core/client/src/collection-manager/Configuration/ViewInheritedField.tsx +++ b/packages/core/client/src/collection-manager/Configuration/ViewInheritedField.tsx @@ -6,7 +6,7 @@ import set from 'lodash/set'; import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useAPIClient, useRequest } from '../../api-client'; -import { useRecord, RecordProvider } from '../../record-provider'; +import { RecordProvider, useRecord } from '../../record-provider'; import { ActionContext, SchemaComponent, useCompile } from '../../schema-component'; import { useCollectionManager } from '../hooks'; import { IField } from '../interfaces/types'; @@ -82,7 +82,7 @@ export const ViewFieldAction = (props) => { onClick={async () => { const { data } = await api.resource('collections.fields', record.collectionName).get({ filterByTk: record.name, - appends: ['uiSchema', 'reverseField'], + appends: ['reverseField'], }); setData(data?.data); const interfaceConf = getInterface(record.interface); diff --git a/packages/core/client/src/collection-manager/Configuration/schemas/collectionFields.ts b/packages/core/client/src/collection-manager/Configuration/schemas/collectionFields.ts index 4ab4bef1f..fdfbdef60 100644 --- a/packages/core/client/src/collection-manager/Configuration/schemas/collectionFields.ts +++ b/packages/core/client/src/collection-manager/Configuration/schemas/collectionFields.ts @@ -76,7 +76,7 @@ export const collectionFieldSchema: ISchema = { 'interface.$not': null, }, sort: ['sort'], - appends: ['uiSchema'], + // appends: ['uiSchema'], }, }, }, diff --git a/packages/core/client/src/collection-manager/action-hooks.ts b/packages/core/client/src/collection-manager/action-hooks.ts index 3fe8d3036..b50556804 100644 --- a/packages/core/client/src/collection-manager/action-hooks.ts +++ b/packages/core/client/src/collection-manager/action-hooks.ts @@ -1,4 +1,4 @@ -import { useForm } from '@formily/react'; +import { useField, useForm } from '@formily/react'; import { message } from 'antd'; import { useEffect } from 'react'; import { useCollection, useCollectionManager } from '.'; @@ -185,15 +185,19 @@ export const useFilterAction = () => { export const useCreateAction = () => { const form = useForm(); + const field = useField(); const ctx = useActionContext(); const { refresh } = useResourceActionContext(); const { resource } = useResourceContext(); return { async run() { await form.submit(); + field.data = field.data || {}; + field.data.loading = true; await resource.create({ values: form.values }); ctx.setVisible(false); await form.reset(); + field.data.loading = false; refresh(); }, }; @@ -242,6 +246,7 @@ export const useMoveAction = () => { }; export const useUpdateAction = () => { + const field = useField(); const form = useForm(); const ctx = useActionContext(); const { refresh } = useResourceActionContext(); @@ -250,9 +255,12 @@ export const useUpdateAction = () => { return { async run() { await form.submit(); + field.data = field.data || {}; + field.data.loading = true; await resource.update({ filterByTk, values: form.values }); ctx.setVisible(false); await form.reset(); + field.data.loading = false; refresh(); }, }; diff --git a/packages/core/client/src/collection-manager/sub-table.tsx b/packages/core/client/src/collection-manager/sub-table.tsx index e78fc8329..32394c7be 100644 --- a/packages/core/client/src/collection-manager/sub-table.tsx +++ b/packages/core/client/src/collection-manager/sub-table.tsx @@ -8,7 +8,7 @@ import { useCollectionManager, useRecord, useRecordIndex, - useRequest, + useRequest } from '../'; import { useAPIClient } from '../api-client'; @@ -183,7 +183,7 @@ export const SubFieldDataSourceProvider = observer((props) => { .resource('fields') .list({ paginate: false, - appends: ['uiSchema'], + // appends: ['uiSchema'], sort: 'sort', filter: { parentKey: record.key, diff --git a/packages/core/client/src/plugin-manager/PinnedPluginListProvider.tsx b/packages/core/client/src/plugin-manager/PinnedPluginListProvider.tsx new file mode 100644 index 000000000..a4a2c9fc2 --- /dev/null +++ b/packages/core/client/src/plugin-manager/PinnedPluginListProvider.tsx @@ -0,0 +1,51 @@ +import { css } from '@emotion/css'; +import { SchemaOptionsContext } from '@formily/react'; +import { get } from 'lodash'; +import React, { useContext } from 'react'; +import { useACLRoleContext } from '../acl/ACLProvider'; +import { PinnedPluginListContext } from './context'; + +export const PinnedPluginListProvider: React.FC<{ items: any }> = (props) => { + const { children, items } = props; + const ctx = useContext(PinnedPluginListContext); + return ( + + {children} + + ); +}; + +export const PinnedPluginList = () => { + const { allowAll, snippets } = useACLRoleContext(); + const getSnippetsAllow = (aclKey) => { + return allowAll || snippets?.includes(aclKey); + }; + const ctx = useContext(PinnedPluginListContext); + const { components } = useContext(SchemaOptionsContext); + return ( +
+ {Object.values(ctx.items) + .sort((a, b) => a.order - b.order) + .filter((v) => getSnippetsAllow(v.snippet)) + .map((item) => { + const Action = get(components, item.component); + return Action ? : null; + })} +
+ ); +}; diff --git a/packages/core/client/src/plugin-manager/context.ts b/packages/core/client/src/plugin-manager/context.ts index 3220782c6..11d864925 100644 --- a/packages/core/client/src/plugin-manager/context.ts +++ b/packages/core/client/src/plugin-manager/context.ts @@ -1,3 +1,4 @@ import { createContext } from 'react'; export const PluginManagerContext = createContext({}); +export const PinnedPluginListContext = createContext({ items: {} }); diff --git a/packages/core/client/src/plugin-manager/index.ts b/packages/core/client/src/plugin-manager/index.ts index dfbf7596f..74f96aa39 100644 --- a/packages/core/client/src/plugin-manager/index.ts +++ b/packages/core/client/src/plugin-manager/index.ts @@ -1,3 +1,5 @@ export * from './context'; +export * from './PinnedPluginListProvider'; export * from './PluginManager'; export * from './PluginManagerProvider'; + diff --git a/packages/core/client/src/pm/PluginManagerLink.tsx b/packages/core/client/src/pm/PluginManagerLink.tsx index bf06c0332..4192d3250 100644 --- a/packages/core/client/src/pm/PluginManagerLink.tsx +++ b/packages/core/client/src/pm/PluginManagerLink.tsx @@ -1,27 +1,23 @@ -import { AppstoreAddOutlined, SettingOutlined } from '@ant-design/icons'; -import { Dropdown, Menu } from 'antd'; +import { ApiOutlined, SettingOutlined } from '@ant-design/icons'; +import { Button, Dropdown, Menu } from 'antd'; import React, { useContext, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; import { useACLRoleContext } from '../acl/ACLProvider'; -import { PluginManager } from '../plugin-manager'; import { ActionContext, useCompile } from '../schema-component'; import { getPluginsTabs, SettingsCenterContext } from './index'; export const PluginManagerLink = () => { - const [visible, setVisible] = useState(false); const { t } = useTranslation(); const history = useHistory(); return ( - - } - title={t('Plugin manager')} - onClick={() => { - history.push('/admin/pm/list'); - }} - /> - +