feat: removeEmptyParents server hook
This commit is contained in:
parent
85ab936c4c
commit
4607e0da49
@ -0,0 +1,160 @@
|
||||
import { mockServer, MockServer } from '@nocobase/test';
|
||||
import { Database } from '@nocobase/database';
|
||||
import PluginUiSchema, { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
|
||||
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
||||
import { removeEmptyParents } from '../server-hooks/removeEmptyParents';
|
||||
|
||||
describe('server hooks', () => {
|
||||
let app: MockServer;
|
||||
let db: Database;
|
||||
let uiSchemaRepository: UiSchemaRepository;
|
||||
let uiSchemaPlugin: PluginUiSchema;
|
||||
|
||||
afterEach(async () => {
|
||||
await app.destroy();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
app = mockServer({
|
||||
registerActions: true,
|
||||
});
|
||||
|
||||
db = app.db;
|
||||
|
||||
await app.cleanDb();
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginCollectionManager);
|
||||
|
||||
await app.loadAndInstall();
|
||||
|
||||
uiSchemaRepository = db.getRepository('ui_schemas');
|
||||
|
||||
uiSchemaPlugin = app.getPlugin<PluginUiSchema>('PluginUiSchema');
|
||||
});
|
||||
|
||||
it('should clean row struct', async () => {
|
||||
const PostModel = await db.getRepository('collections').create({
|
||||
values: {
|
||||
name: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
await db.getRepository('fields').create({
|
||||
values: {
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
collectionName: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
await db.getRepository('fields').create({
|
||||
values: {
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
collectionName: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
await db.getRepository('fields').create({
|
||||
values: {
|
||||
name: 'intro',
|
||||
type: 'string',
|
||||
collectionName: 'posts',
|
||||
},
|
||||
});
|
||||
|
||||
const schema = {
|
||||
type: 'void',
|
||||
name: 'grid1',
|
||||
'x-decorator': 'Form',
|
||||
'x-component': 'Grid',
|
||||
'x-item-initializer': 'AddGridFormItem',
|
||||
'x-uid': 'grid1',
|
||||
properties: {
|
||||
row1: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-uid': 'row1',
|
||||
properties: {
|
||||
col11: {
|
||||
type: 'void',
|
||||
'x-uid': 'col11',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
title: 'Name',
|
||||
'x-uid': 'posts-name',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'posts.name',
|
||||
'x-server-hooks': [
|
||||
{
|
||||
type: 'onCollectionFieldDestroy',
|
||||
collection: 'posts',
|
||||
fields: ['name'],
|
||||
method: 'removeEmptyParents',
|
||||
},
|
||||
],
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
title: 'Title',
|
||||
'x-uid': 'posts-title',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-collection-field': 'posts.title',
|
||||
'x-server-hooks': [
|
||||
{
|
||||
type: 'onCollectionFieldDestroy',
|
||||
collection: 'posts',
|
||||
fields: ['title'],
|
||||
method: 'removeEmptyParents',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
col12: {
|
||||
type: 'void',
|
||||
'x-uid': 'col12',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
intro: {
|
||||
'x-uid': 'posts-intro',
|
||||
type: 'string',
|
||||
title: 'Intro',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-server-hooks': [
|
||||
{
|
||||
type: 'onCollectionFieldDestroy',
|
||||
collection: 'posts',
|
||||
fields: ['intro'],
|
||||
method: 'removeEmptyParents',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await uiSchemaRepository.insert(schema);
|
||||
|
||||
uiSchemaPlugin.serverHooks.register('onCollectionFieldDestroy', 'removeEmptyParents', removeEmptyParents);
|
||||
|
||||
await db.getRepository('fields').destroy({
|
||||
filter: {
|
||||
name: 'intro',
|
||||
},
|
||||
individualHooks: true,
|
||||
});
|
||||
|
||||
const jsonTree = await uiSchemaRepository.getJsonSchema('grid1');
|
||||
expect(jsonTree['properties']['row1']['properties']['col11']).toBeDefined();
|
||||
expect(jsonTree['properties']['row1']['properties']['col12']).not.toBeDefined();
|
||||
});
|
||||
});
|
@ -178,11 +178,7 @@ describe('server hooks', () => {
|
||||
],
|
||||
};
|
||||
|
||||
await uiSchemaRepository.create({
|
||||
values: {
|
||||
schema: menuSchema,
|
||||
},
|
||||
});
|
||||
await uiSchemaRepository.insert(menuSchema);
|
||||
|
||||
const PostModel = await db.getRepository('collections').create({
|
||||
values: {
|
||||
|
@ -110,7 +110,7 @@ export class ServerHooks {
|
||||
const hookFunc = this.hooks.get(hookRecord.get('type') as HookType)?.get(hoodMethodName);
|
||||
|
||||
if (hookFunc) {
|
||||
await hookFunc({ ...hooksArgs, schemaInstance: (<any>hookRecord).uiSchema });
|
||||
await hookFunc({ ...hooksArgs, schemaInstance: (<any>hookRecord).uiSchema, db: this.db });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
|
||||
|
||||
// given a child uid, if it is a single child ,return its parent
|
||||
async function isSingleChild(uid, db, transaction) {
|
||||
const parent = await db.getRepository('ui_schema_tree_path').findOne({
|
||||
filter: {
|
||||
descendant: uid,
|
||||
depth: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const countResult = await db.sequelize.query(
|
||||
`SELECT COUNT(*) FROM ${
|
||||
db.getCollection('ui_schema_tree_path').model.tableName
|
||||
} where ancestor = :ancestor and depth = 1`,
|
||||
{
|
||||
replacements: {
|
||||
ancestor: parent.get('ancestor'),
|
||||
},
|
||||
type: 'SELECT',
|
||||
transaction,
|
||||
},
|
||||
);
|
||||
|
||||
const parentChildrenCount = countResult[0]['count'];
|
||||
|
||||
if (parentChildrenCount == 1) {
|
||||
return parent.get('ancestor');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function removeEmptyParents({ schemaInstance, options, db }) {
|
||||
const { transaction } = options;
|
||||
const uiSchemaRepository: UiSchemaRepository = db.getRepository('ui_schemas');
|
||||
const uid = schemaInstance.get('uid');
|
||||
|
||||
// find parent uid
|
||||
const parentUid = await isSingleChild(uid, db, transaction);
|
||||
|
||||
if (parentUid) {
|
||||
const rowUid = await isSingleChild(parentUid, db, transaction);
|
||||
if (rowUid) {
|
||||
await uiSchemaRepository.remove(rowUid, { transaction });
|
||||
} else {
|
||||
await uiSchemaRepository.remove(parentUid, { transaction });
|
||||
}
|
||||
} else {
|
||||
await uiSchemaRepository.remove(uid, { transaction });
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user