feat: bind new menu to role

This commit is contained in:
Chareice 2022-02-10 22:53:26 +08:00 committed by chenos
parent f167bf90b4
commit c9643ac2b7
8 changed files with 87 additions and 19 deletions

View File

@ -1,7 +1,8 @@
import { mockServer, MockServer } from '@nocobase/test'; 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 PluginUiSchema, { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
import PluginCollectionManager from '@nocobase/plugin-collection-manager'; import PluginCollectionManager from '@nocobase/plugin-collection-manager';
import PluginACL from '@nocobase/plugin-acl';
describe('server hooks', () => { describe('server hooks', () => {
let app: MockServer; let app: MockServer;
@ -23,6 +24,7 @@ describe('server hooks', () => {
await app.cleanDb(); await app.cleanDb();
app.plugin(PluginUiSchema); app.plugin(PluginUiSchema);
app.plugin(PluginCollectionManager); app.plugin(PluginCollectionManager);
app.plugin(PluginACL);
await app.loadAndInstall(); await app.loadAndInstall();
@ -261,4 +263,46 @@ describe('server hooks', () => {
expect(jsonTree['properties']['child1']).toBeDefined(); expect(jsonTree['properties']['child1']).toBeDefined();
expect(jsonTree['properties']['child2']).not.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<BelongsToManyRepository>('roles.menuUiSchemas', 'role1').find();
expect(role1Menus.length).toEqual(1);
const role2Menus = await db.getRepository<BelongsToManyRepository>('roles.menuUiSchemas', 'role2').find();
expect(role2Menus.length).toEqual(0);
});
}); });

View File

@ -157,11 +157,7 @@ describe('server hooks', () => {
serverHooks.register('onSelfCreate', 'afterCreateMenu', hookFn); serverHooks.register('onSelfCreate', 'afterCreateMenu', hookFn);
await uiSchemaRepository.create({ await uiSchemaRepository.insert(menuSchema);
values: {
schema: menuSchema,
},
});
expect(hookFn).toHaveBeenCalled(); expect(hookFn).toHaveBeenCalled();
}); });

View File

@ -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 nodes = UiSchemaRepository.schemaToSingleNodes(schema);
const insertedNodes = await this.insertNodes(nodes, options); const insertedNodes = await this.insertNodes(nodes, options);
return this.getJsonSchema(insertedNodes[0].get('uid'), { return this.getJsonSchema(insertedNodes[0].get('uid'), {
@ -457,7 +457,9 @@ export default class UiSchemaRepository extends Repository {
serverHooks, serverHooks,
}, },
transaction, transaction,
hooks: false, context: {
disableInsertHook: true,
},
}); });
return node; return node;

View File

@ -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,
});
}
}

View File

@ -1,9 +1,11 @@
import { hookFactory } from './factory'; import { hookFactory } from './factory';
import { removeSchema } from './removeSchema'; import { removeSchema } from './remove-schema';
import { bindMenuToRow } from './bind-menu-to-row';
const hooks = [ const hooks = [
hookFactory('onCollectionDestroy', 'removeSchema', removeSchema), hookFactory('onCollectionDestroy', 'removeSchema', removeSchema),
hookFactory('onCollectionFieldDestroy', 'removeSchema', removeSchema), hookFactory('onCollectionFieldDestroy', 'removeSchema', removeSchema),
hookFactory('onSelfCreate', 'bindMenuToRow', bindMenuToRow),
]; ];
export { hooks }; export { hooks };

View File

@ -1,4 +1,3 @@
import { hookFactory } from './factory';
import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage'; import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
export async function removeSchema({ schemaInstance, options, db, params }) { export async function removeSchema({ schemaInstance, options, db, params }) {

View File

@ -91,17 +91,19 @@ export class ServerHooks {
protected async onUiSchemaCreate(schemaInstance, options) { protected async onUiSchemaCreate(schemaInstance, options) {
const { transaction } = options; const { transaction } = options;
await this.findHooksAndCall( const serverHooks = schemaInstance.get('serverHooks') || [];
{
type: 'onSelfCreate', const onSelfCreateHooks = serverHooks.filter((serverHook) => serverHook.get('type') === 'onSelfCreate');
uid: schemaInstance.schema['x-uid'],
}, for (const serverHook of onSelfCreateHooks) {
{ const hookFunc = this.hooks.get('onSelfCreate')?.get(serverHook.get('method'));
await hookFunc({
schemaInstance, schemaInstance,
options, options,
}, db: this.db,
transaction, params: serverHook.get('params'),
); });
}
} }
protected async findHooksAndCall(hooksFilter, hooksArgs, transaction) { protected async findHooksAndCall(hooksFilter, hooksArgs, transaction) {

View File

@ -33,6 +33,12 @@ export default class PluginUiSchema extends Plugin {
const { transaction } = options; const { transaction } = options;
const uiSchemaRepository = db.getCollection('ui_schemas').repository as UiSchemaRepository; const uiSchemaRepository = db.getCollection('ui_schemas').repository as UiSchemaRepository;
const context = options.context;
if (context?.disableInsertHook) {
return;
}
await uiSchemaRepository.insert(model.toJSON(), { await uiSchemaRepository.insert(model.toJSON(), {
transaction, transaction,
}); });