fix: improve sort field migration (#4112)

This commit is contained in:
chenos 2024-04-20 19:18:44 +08:00 committed by GitHub
parent 52893e213e
commit 8f829546c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 136 additions and 90 deletions

View File

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

View File

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

View File

@ -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<CollectionRepository>('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'],
});
}
}
}