From c9643ac2b7fb535203e09bbc592d48900b5e4d30 Mon Sep 17 00:00:00 2001 From: Chareice Date: Thu, 10 Feb 2022 22:53:26 +0800 Subject: [PATCH] feat: bind new menu to role --- .../src/__tests__/server-hook-impl.test.ts | 46 ++++++++++++++++++- .../src/__tests__/server-hook.test.ts | 6 +-- .../src/repository.ts | 6 ++- .../server-hooks/hooks/bind-menu-to-row.ts | 17 +++++++ .../src/server-hooks/hooks/index.ts | 4 +- .../{removeSchema.ts => remove-schema.ts} | 1 - .../src/server-hooks/index.ts | 20 ++++---- .../plugin-ui-schema-storage/src/server.ts | 6 +++ 8 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 packages/plugin-ui-schema-storage/src/server-hooks/hooks/bind-menu-to-row.ts rename packages/plugin-ui-schema-storage/src/server-hooks/hooks/{removeSchema.ts => remove-schema.ts} (93%) diff --git a/packages/plugin-ui-schema-storage/src/__tests__/server-hook-impl.test.ts b/packages/plugin-ui-schema-storage/src/__tests__/server-hook-impl.test.ts index d29208bcb..f11ef14e0 100644 --- a/packages/plugin-ui-schema-storage/src/__tests__/server-hook-impl.test.ts +++ b/packages/plugin-ui-schema-storage/src/__tests__/server-hook-impl.test.ts @@ -1,7 +1,8 @@ import { mockServer, MockServer } from '@nocobase/test'; -import { Database } from '@nocobase/database'; +import { BelongsToManyRepository, Database, HasManyRepository } from '@nocobase/database'; import PluginUiSchema, { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage'; import PluginCollectionManager from '@nocobase/plugin-collection-manager'; +import PluginACL from '@nocobase/plugin-acl'; describe('server hooks', () => { let app: MockServer; @@ -23,6 +24,7 @@ describe('server hooks', () => { await app.cleanDb(); app.plugin(PluginUiSchema); app.plugin(PluginCollectionManager); + app.plugin(PluginACL); await app.loadAndInstall(); @@ -261,4 +263,46 @@ describe('server hooks', () => { expect(jsonTree['properties']['child1']).toBeDefined(); expect(jsonTree['properties']['child2']).not.toBeDefined(); }); + + it('should bind menu to role when create new menu', async () => { + await db.getRepository('roles').create({ + values: { + name: 'role1', + allowConfigure: true, + allowNewMenu: true, + }, + }); + + await db.getRepository('roles').create({ + values: { + name: 'role2', + allowConfigure: true, + allowNewMenu: false, + }, + }); + + const schema = { + 'x-uid': 'root', + name: 'root', + properties: { + child2: { + 'x-uid': 'child2', + 'x-server-hooks': [ + { + type: 'onSelfCreate', + method: 'bindMenuToRow', + }, + ], + }, + }, + }; + + await uiSchemaRepository.insert(schema); + + const role1Menus = await db.getRepository('roles.menuUiSchemas', 'role1').find(); + expect(role1Menus.length).toEqual(1); + + const role2Menus = await db.getRepository('roles.menuUiSchemas', 'role2').find(); + expect(role2Menus.length).toEqual(0); + }); }); diff --git a/packages/plugin-ui-schema-storage/src/__tests__/server-hook.test.ts b/packages/plugin-ui-schema-storage/src/__tests__/server-hook.test.ts index 814dcbf06..5e3d06077 100644 --- a/packages/plugin-ui-schema-storage/src/__tests__/server-hook.test.ts +++ b/packages/plugin-ui-schema-storage/src/__tests__/server-hook.test.ts @@ -157,11 +157,7 @@ describe('server hooks', () => { serverHooks.register('onSelfCreate', 'afterCreateMenu', hookFn); - await uiSchemaRepository.create({ - values: { - schema: menuSchema, - }, - }); + await uiSchemaRepository.insert(menuSchema); expect(hookFn).toHaveBeenCalled(); }); diff --git a/packages/plugin-ui-schema-storage/src/repository.ts b/packages/plugin-ui-schema-storage/src/repository.ts index b365f8b0c..f38634b89 100644 --- a/packages/plugin-ui-schema-storage/src/repository.ts +++ b/packages/plugin-ui-schema-storage/src/repository.ts @@ -438,7 +438,7 @@ export default class UiSchemaRepository extends Repository { } } - async insert(schema: any, options?) { + async insert(schema: any, options?: TransactionAble) { const nodes = UiSchemaRepository.schemaToSingleNodes(schema); const insertedNodes = await this.insertNodes(nodes, options); return this.getJsonSchema(insertedNodes[0].get('uid'), { @@ -457,7 +457,9 @@ export default class UiSchemaRepository extends Repository { serverHooks, }, transaction, - hooks: false, + context: { + disableInsertHook: true, + }, }); return node; diff --git a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/bind-menu-to-row.ts b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/bind-menu-to-row.ts new file mode 100644 index 000000000..6e184992f --- /dev/null +++ b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/bind-menu-to-row.ts @@ -0,0 +1,17 @@ +import { BelongsToManyRepository } from '@nocobase/database'; + +export async function bindMenuToRow({ schemaInstance, db, options }) { + const { transaction } = options; + const addNewMenuRoles = await db.getRepository('roles').find({ + filter: { + allowNewMenu: true, + }, + }); + + for (const role of addNewMenuRoles) { + await db.getRepository('roles.menuUiSchemas', role.get('name')).set({ + tk: schemaInstance.get('uid'), + transaction, + }); + } +} diff --git a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/index.ts b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/index.ts index 3d3e02b1d..8ffe5d94b 100644 --- a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/index.ts +++ b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/index.ts @@ -1,9 +1,11 @@ import { hookFactory } from './factory'; -import { removeSchema } from './removeSchema'; +import { removeSchema } from './remove-schema'; +import { bindMenuToRow } from './bind-menu-to-row'; const hooks = [ hookFactory('onCollectionDestroy', 'removeSchema', removeSchema), hookFactory('onCollectionFieldDestroy', 'removeSchema', removeSchema), + hookFactory('onSelfCreate', 'bindMenuToRow', bindMenuToRow), ]; export { hooks }; diff --git a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/removeSchema.ts b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts similarity index 93% rename from packages/plugin-ui-schema-storage/src/server-hooks/hooks/removeSchema.ts rename to packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts index 4a4321984..5fab3af3f 100644 --- a/packages/plugin-ui-schema-storage/src/server-hooks/hooks/removeSchema.ts +++ b/packages/plugin-ui-schema-storage/src/server-hooks/hooks/remove-schema.ts @@ -1,4 +1,3 @@ -import { hookFactory } from './factory'; import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage'; export async function removeSchema({ schemaInstance, options, db, params }) { diff --git a/packages/plugin-ui-schema-storage/src/server-hooks/index.ts b/packages/plugin-ui-schema-storage/src/server-hooks/index.ts index 00056954b..a474c74c3 100644 --- a/packages/plugin-ui-schema-storage/src/server-hooks/index.ts +++ b/packages/plugin-ui-schema-storage/src/server-hooks/index.ts @@ -91,17 +91,19 @@ export class ServerHooks { protected async onUiSchemaCreate(schemaInstance, options) { const { transaction } = options; - await this.findHooksAndCall( - { - type: 'onSelfCreate', - uid: schemaInstance.schema['x-uid'], - }, - { + const serverHooks = schemaInstance.get('serverHooks') || []; + + const onSelfCreateHooks = serverHooks.filter((serverHook) => serverHook.get('type') === 'onSelfCreate'); + + for (const serverHook of onSelfCreateHooks) { + const hookFunc = this.hooks.get('onSelfCreate')?.get(serverHook.get('method')); + await hookFunc({ schemaInstance, options, - }, - transaction, - ); + db: this.db, + params: serverHook.get('params'), + }); + } } protected async findHooksAndCall(hooksFilter, hooksArgs, transaction) { diff --git a/packages/plugin-ui-schema-storage/src/server.ts b/packages/plugin-ui-schema-storage/src/server.ts index 8b17d6e98..9b4d6bcd6 100644 --- a/packages/plugin-ui-schema-storage/src/server.ts +++ b/packages/plugin-ui-schema-storage/src/server.ts @@ -33,6 +33,12 @@ export default class PluginUiSchema extends Plugin { const { transaction } = options; const uiSchemaRepository = db.getCollection('ui_schemas').repository as UiSchemaRepository; + const context = options.context; + + if (context?.disableInsertHook) { + return; + } + await uiSchemaRepository.insert(model.toJSON(), { transaction, });