From 8f829546c5cc37246a33a8421ad2fcb1ab5d0e68 Mon Sep 17 00:00:00 2001 From: chenos Date: Sat, 20 Apr 2024 19:18:44 +0800 Subject: [PATCH] fix: improve sort field migration (#4112) --- .../20240420105949-add-sort-field.test.ts | 84 +++++++++++++++++ .../20240410214249-migrate-sort-field.ts | 90 ------------------- .../20240420105949-add-sort-field.ts | 52 +++++++++++ 3 files changed, 136 insertions(+), 90 deletions(-) create mode 100644 packages/plugins/@nocobase/plugin-collection-manager/src/server/__tests__/migrations/20240420105949-add-sort-field.test.ts delete mode 100644 packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240410214249-migrate-sort-field.ts create mode 100644 packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240420105949-add-sort-field.ts diff --git a/packages/plugins/@nocobase/plugin-collection-manager/src/server/__tests__/migrations/20240420105949-add-sort-field.test.ts b/packages/plugins/@nocobase/plugin-collection-manager/src/server/__tests__/migrations/20240420105949-add-sort-field.test.ts new file mode 100644 index 0000000000..a6d4f952b1 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-collection-manager/src/server/__tests__/migrations/20240420105949-add-sort-field.test.ts @@ -0,0 +1,84 @@ +import { MockServer, createMockServer } from '@nocobase/test'; +import Migration from '../../migrations/20240420105949-add-sort-field'; +import PluginCollectionManagerServer from '../../server'; + +describe('nocobase-admin-menu', () => { + let app: MockServer; + + beforeEach(async () => { + app = await createMockServer({ + plugins: ['nocobase'], + }); + await app.version.update('0.21.0-alpha.12'); + }); + + afterEach(async () => { + await app.destroy(); + }); + + test('migration', async () => { + await app.db.getRepository('collections').create({ + values: { + autoGenId: true, + sortable: true, + name: 'foo', + template: 'general', + view: false, + fields: [ + { + type: 'string', + name: 'status', + }, + { + type: 'sort', + name: 'sort1', + scopeKey: 'status', + }, + { + type: 'sort', + name: 'sort3', + interface: 'sort3', + uiSchema: { + type: 'number', + title: 'Sort 3', + 'x-component': 'InputNumber', + 'x-component-props': { stringMode: true, step: '1' }, + 'x-validator': 'integer', + }, + }, + ], + }, + context: {}, + }); + const migration = new Migration({ + db: app.db, + // @ts-ignore + app: app, + plugin: app.pm.get(PluginCollectionManagerServer), + }); + await migration.up(); + const sort1 = await app.db.getRepository('fields').findOne({ + filter: { + collectionName: 'foo', + name: 'sort', + }, + }); + expect(sort1.interface).toBe('sort'); + expect(sort1.hidden).toBeFalsy(); + const sort2 = await app.db.getRepository('fields').findOne({ + filter: { + collectionName: 'foo', + name: 'sort1', + }, + }); + expect(sort2.interface).toBe('sort'); + expect(sort2.hidden).toBeFalsy(); + const sort3 = await app.db.getRepository('fields').findOne({ + filter: { + collectionName: 'foo', + name: 'sort3', + }, + }); + expect(sort3.get('uiSchema.title')).toBe('Sort 3'); + }); +}); diff --git a/packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240410214249-migrate-sort-field.ts b/packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240410214249-migrate-sort-field.ts deleted file mode 100644 index 7b9c70676d..0000000000 --- a/packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240410214249-migrate-sort-field.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Migration } from '@nocobase/server'; - -export default class extends Migration { - on = 'afterLoad'; // 'beforeLoad' or 'afterLoad' - appVersion = '<0.21.0-alpha.7'; - - private async syncCollectionsSortField() { - const collections = await this.db.getRepository('collections').find(); - - for (const collection of collections) { - const sortable = collection.get('sortable'); - if (!sortable) { - continue; - } - - const sortFieldName = sortable === true ? 'sort' : sortable; - - const fields = await collection.getFields(); - const sortField = fields.find((item) => item.get('type') === 'sort' && item.get('name') === sortFieldName); - - if (!sortField) { - await this.db.getRepository('fields').create({ - values: { - name: sortFieldName, - type: 'sort', - interface: 'sort', - uiSchema: { - title: sortFieldName, - type: 'number', - 'x-component': 'InputNumber', - 'x-component-props': { stringMode: true, step: '1' }, - 'x-validator': 'integer', - }, - collectionName: collection.get('name'), - }, - }); - } - } - } - - private async syncAssociationSortField() { - const sortableAssociations = await this.db.getRepository('fields').find({ - filter: { - 'options.sortable': true, - }, - }); - - for (const field of sortableAssociations) { - const collectionName = field.get('target'); - - const collection = await this.db.getRepository('collections').findOne({ - filter: { - name: collectionName, - }, - }); - - if (!collection) { - continue; - } - - const sortFieldName = field.get('sortBy') ? field.get('sortBy') : field.get('name') + '_sort'; - - const fields = await collection.getFields(); - const sortField = fields.find((item) => item.get('type') === 'sort' && item.get('name') === sortFieldName); - - if (!sortField) { - await this.db.getRepository('fields').create({ - values: { - name: sortFieldName, - type: 'sort', - interface: 'sort', - uiSchema: { - title: sortFieldName, - type: 'number', - 'x-component': 'InputNumber', - 'x-component-props': { stringMode: true, step: '1' }, - 'x-validator': 'integer', - }, - collectionName: collection.get('name'), - }, - }); - } - } - } - - async up() { - await this.syncCollectionsSortField(); - await this.syncAssociationSortField(); - } -} diff --git a/packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240420105949-add-sort-field.ts b/packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240420105949-add-sort-field.ts new file mode 100644 index 0000000000..5670912e57 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-collection-manager/src/server/migrations/20240420105949-add-sort-field.ts @@ -0,0 +1,52 @@ +import { Migration } from '@nocobase/server'; +import { CollectionRepository } from '../repositories'; + +export default class extends Migration { + on = 'afterLoad'; // 'beforeLoad' or 'afterLoad' + appVersion = '<0.21.0-alpha.13'; + + async up() { + const repository = this.db.getRepository('collections'); + await repository.load(); + const collections = await this.db.getRepository('collections').find(); + const fields = []; + for (const item of collections) { + const collection = this.db.getCollection(item.name); + collection.forEachField((field) => { + if (field.type === 'sort') { + fields.push({ + collectionName: item.name, + name: field.name, + }); + } + }); + } + const fieldRepository = this.db.getRepository('fields'); + for (const field of fields) { + this.app.log.info(`field path: ${field.collectionName}.${field.name}`); + const instance = await fieldRepository.findOne({ + filter: field, + }); + if (instance?.interface) { + continue; + } + await fieldRepository.updateOrCreate({ + values: { + ...field, + interface: 'sort', + type: 'sort', + hidden: false, + uiSchema: { + type: 'number', + title: field.name, + 'x-component': 'InputNumber', + 'x-component-props': { stringMode: true, step: '1' }, + 'x-validator': 'integer', + }, + scopeKey: instance?.scopeKey, + }, + filterKeys: ['collectionName', 'name'], + }); + } + } +}