diff --git a/packages/plugin-ui-schema-storage/src/__tests__/ui-schema-repository.test.ts b/packages/plugin-ui-schema-storage/src/__tests__/ui-schema-repository.test.ts index 1e9cc0a22..9479d61ec 100644 --- a/packages/plugin-ui-schema-storage/src/__tests__/ui-schema-repository.test.ts +++ b/packages/plugin-ui-schema-storage/src/__tests__/ui-schema-repository.test.ts @@ -478,9 +478,9 @@ describe('ui_schema repository', () => { await repository.insertAfterBegin(rootUid, newNode); const schema = await repository.getJsonSchema(rootUid); - expect(schema.properties['newNode']['x-index']).toEqual(1); - expect(schema.properties.a1['x-index']).toEqual(2); - expect(schema.properties.b1['x-index']).toEqual(3); + expect(schema['properties']['newNode']['x-index']).toEqual(1); + expect(schema['properties'].a1['x-index']).toEqual(2); + expect(schema['properties'].b1['x-index']).toEqual(3); }); it('should insertBeforeEnd', async () => { @@ -490,9 +490,9 @@ describe('ui_schema repository', () => { await repository.insertBeforeEnd(rootUid, newNode); const schema = await repository.getJsonSchema(rootUid); - expect(schema.properties['newNode']['x-index']).toEqual(3); - expect(schema.properties.a1['x-index']).toEqual(1); - expect(schema.properties.b1['x-index']).toEqual(2); + expect(schema['properties']['newNode']['x-index']).toEqual(3); + expect(schema['properties'].a1['x-index']).toEqual(1); + expect(schema['properties'].b1['x-index']).toEqual(2); }); it('should insertBeforeBegin', async () => { @@ -509,9 +509,9 @@ describe('ui_schema repository', () => { await repository.insertBeforeBegin(b1Node.get('x-uid') as string, newNode); const schema = await repository.getJsonSchema(rootUid); - expect(schema.properties['newNode']['x-index']).toEqual(2); - expect(schema.properties.a1['x-index']).toEqual(1); - expect(schema.properties.b1['x-index']).toEqual(3); + expect(schema['properties']['newNode']['x-index']).toEqual(2); + expect(schema['properties'].a1['x-index']).toEqual(1); + expect(schema['properties'].b1['x-index']).toEqual(3); }); it('should insertAfterEnd a1', async () => { @@ -528,9 +528,9 @@ describe('ui_schema repository', () => { await repository.insertAfterEnd(a1Node.get('x-uid') as string, newNode); const schema = await repository.getJsonSchema(rootUid); - expect(schema.properties['newNode']['x-index']).toEqual(2); - expect(schema.properties.a1['x-index']).toEqual(1); - expect(schema.properties.b1['x-index']).toEqual(3); + expect(schema['properties']['newNode']['x-index']).toEqual(2); + expect(schema['properties'].a1['x-index']).toEqual(1); + expect(schema['properties'].b1['x-index']).toEqual(3); }); it('should insertAfterEnd b1', async () => { @@ -547,9 +547,9 @@ describe('ui_schema repository', () => { await repository.insertAfterEnd(b1Node.get('x-uid') as string, newNode); const schema = await repository.getJsonSchema(rootUid); - expect(schema.properties['newNode']['x-index']).toEqual(3); - expect(schema.properties.a1['x-index']).toEqual(1); - expect(schema.properties.b1['x-index']).toEqual(2); + expect(schema['properties']['newNode']['x-index']).toEqual(3); + expect(schema['properties'].a1['x-index']).toEqual(1); + expect(schema['properties'].b1['x-index']).toEqual(2); }); }); @@ -614,11 +614,136 @@ describe('ui_schema repository', () => { await repository.insertAfterBegin('n2', 'n4'); const schema = await repository.getJsonSchema('n1'); - expect(schema.properties.b.properties.d['x-uid']).toEqual('n4'); + expect(schema['properties'].b.properties.d['x-uid']).toEqual('n4'); }); }); describe('remove', () => { + it('should remove node in schema table', async () => { + const schema = { + type: 'void', + 'x-uid': 'root', + 'x-component': 'Menu', + 'x-designer': 'Menu.Designer', + 'x-initializer': 'MenuItemInitializer', + 'x-component-props': { + mode: 'mix', + theme: 'dark', + // defaultSelectedUid: 'u8', + onSelect: '{{ onSelect }}', + sideMenuRefScopeKey: 'sideMenuRef', + }, + properties: { + item3: { + 'x-uid': 'item3', + type: 'void', + title: 'SubMenu u3', + 'x-component': 'Menu.SubMenu', + 'x-component-props': {}, + properties: { + item6: { + type: 'void', + title: 'SubMenu u6', + 'x-component': 'Menu.SubMenu', + 'x-component-props': {}, + properties: { + item7: { + type: 'void', + title: 'Menu Item u7', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + properties: { + page1: { + type: 'void', + 'x-component': 'Page', + 'x-async': true, + properties: { + grid1: { + type: 'void', + 'x-component': 'Grid', + 'x-item-initializer': 'BlockInitializer', + properties: {}, + }, + }, + }, + }, + }, + item8: { + type: 'void', + title: 'Menu Item u8', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + }, + }, + item4: { + type: 'void', + title: 'Menu Item u4', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item5: { + type: 'void', + title: 'Menu Item u5', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + }, + }, + item1: { + 'x-uid': 'item1', + type: 'void', + title: 'Menu Item u1', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item2: { + 'x-uid': 'item2', + type: 'void', + title: 'Menu Item u2', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + item9: { + 'x-uid': 'item9', + type: 'void', + title: 'SubMenu u9', + 'x-component': 'Menu.SubMenu', + 'x-component-props': {}, + properties: { + item10: { + type: 'void', + title: 'Menu Item u10', + 'x-component': 'Menu.Item', + 'x-component-props': {}, + }, + }, + }, + }, + }; + + await repository.insert(schema); + await repository.remove('item1'); + + const item1Node = await repository.findOne({ + filter: { + 'x-uid': 'item1', + }, + }); + + expect(item1Node).toBeNull(); + + let tree = await repository.getProperties('root'); + expect(tree['properties']['item1']).toBeUndefined(); + await repository.remove('item2'); + await repository.remove('item3'); + await repository.remove('item9'); + + tree = await repository.getJsonSchema('root'); + console.log(JSON.stringify(tree, null, 2)); + expect(tree['properties']).toBeUndefined(); + }); + it('should remove node', async () => { await repository.insert({ 'x-uid': 'n1', diff --git a/packages/plugin-ui-schema-storage/src/repository.ts b/packages/plugin-ui-schema-storage/src/repository.ts index 77e7aade4..0865fd754 100644 --- a/packages/plugin-ui-schema-storage/src/repository.ts +++ b/packages/plugin-ui-schema-storage/src/repository.ts @@ -23,19 +23,20 @@ interface InsertAdjacentOptions extends removeParentOptions {} const nodeKeys = ['properties', 'definitions', 'patternProperties', 'additionalProperties', 'items']; export class UiSchemaRepository extends Repository { - get uiSchemasTableName() { + tableNameAdapter(tableName) { if (this.database.sequelize.getDialect() === 'postgres') { - return `"${this.model.tableName}"`; + return `"${tableName}"`; } - return this.model.tableName; + return tableName; + } + + get uiSchemasTableName() { + return this.tableNameAdapter(this.model.tableName); } get uiSchemaTreePathTableName() { const model = this.database.getCollection('uiSchemaTreePath').model; - if (this.database.sequelize.getDialect() === 'postgres') { - return `"${model.tableName}"`; - } - return model.tableName; + return this.tableNameAdapter(model.tableName); } sqlAdapter(sql: string) { @@ -130,7 +131,7 @@ export class UiSchemaRepository extends Repository { return lodash.pick(schema, ['type', 'properties']); } - async getJsonSchema(uid: string, options?: GetJsonSchemaOptions) { + async getJsonSchema(uid: string, options?: GetJsonSchemaOptions): Promise { const db = this.database; const treeTable = this.uiSchemaTreePathTableName; @@ -161,10 +162,14 @@ export class UiSchemaRepository extends Repository { return schema; } + private ignoreSchemaProperties(schemaProperties) { + return lodash.omit(schemaProperties, nodeKeys); + } + nodesToSchema(nodes, rootUid) { const nodeAttributeSanitize = (node) => { const schema = { - ...(lodash.isPlainObject(node.schema) ? node.schema : JSON.parse(node.schema)), + ...this.ignoreSchemaProperties(lodash.isPlainObject(node.schema) ? node.schema : JSON.parse(node.schema)), ...lodash.pick(node, [...nodeKeys, 'name']), ['x-uid']: node['x-uid'], ['x-async']: !!node.async, @@ -412,8 +417,6 @@ export class UiSchemaRepository extends Repository { transaction = await this.database.sequelize.transaction(); } - const treePathTable = this.uiSchemaTreePathTableName; - try { if (options?.removeParentsIfNoChildren) { await this.removeEmptyParents({ transaction, uid, breakRemoveOn: options.breakRemoveOn }); @@ -424,10 +427,9 @@ export class UiSchemaRepository extends Repository { } await this.database.sequelize.query( - `DELETE FROM ${this.uiSchemasTableName} WHERE 'x-uid' IN ( - SELECT descendant FROM ${treePathTable} WHERE ancestor = :uid - ) - `, + this.sqlAdapter(`DELETE FROM ${this.uiSchemasTableName} WHERE "x-uid" IN ( + SELECT descendant FROM ${this.uiSchemaTreePathTableName} WHERE ancestor = :uid + )`), { replacements: { uid, @@ -435,13 +437,14 @@ export class UiSchemaRepository extends Repository { transaction, }, ); + await this.database.sequelize.query( ` - DELETE FROM ${treePathTable} + DELETE FROM ${this.uiSchemaTreePathTableName} WHERE descendant IN ( select descendant FROM (SELECT descendant - FROM ${treePathTable} + FROM ${this.uiSchemaTreePathTableName} WHERE ancestor = :uid)as descendantTable) `, { replacements: {