mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-03 20:58:01 +08:00
feat: add sortable parameter to collection options
This commit is contained in:
parent
e12b8f44d1
commit
16d07e9b4a
60
packages/database/src/__tests__/collection.sortable.test.ts
Normal file
60
packages/database/src/__tests__/collection.sortable.test.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { mockDatabase } from './index';
|
||||||
|
|
||||||
|
describe('collection sortable options', () => {
|
||||||
|
test('sortable=true', async () => {
|
||||||
|
const db = mockDatabase();
|
||||||
|
|
||||||
|
const Test = db.collection({
|
||||||
|
name: 'test',
|
||||||
|
sortable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const model = Test.model;
|
||||||
|
|
||||||
|
await db.sync();
|
||||||
|
const instance = await model.create();
|
||||||
|
expect(model.rawAttributes['sort']).toBeDefined();
|
||||||
|
expect(instance.get('sort')).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sortable=string', async () => {
|
||||||
|
const db = mockDatabase();
|
||||||
|
|
||||||
|
const Test = db.collection({
|
||||||
|
name: 'test',
|
||||||
|
sortable: 'order',
|
||||||
|
});
|
||||||
|
|
||||||
|
const model = Test.model;
|
||||||
|
|
||||||
|
await db.sync();
|
||||||
|
const instance = await model.create();
|
||||||
|
expect(model.rawAttributes['order']).toBeDefined();
|
||||||
|
expect(instance.get('order')).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sortable=object', async () => {
|
||||||
|
const db = mockDatabase();
|
||||||
|
|
||||||
|
const Test = db.collection({
|
||||||
|
name: 'test',
|
||||||
|
sortable: {
|
||||||
|
name: 'sort',
|
||||||
|
scopeKey: 'status',
|
||||||
|
},
|
||||||
|
fields: [{ type: 'string', name: 'status' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.sync();
|
||||||
|
|
||||||
|
const t1 = await Test.model.create({ status: 'publish' });
|
||||||
|
const t2 = await Test.model.create({ status: 'publish' });
|
||||||
|
const t3 = await Test.model.create({ status: 'draft' });
|
||||||
|
const t4 = await Test.model.create({ status: 'draft' });
|
||||||
|
|
||||||
|
expect(t1.get('sort')).toBe(1);
|
||||||
|
expect(t2.get('sort')).toBe(2);
|
||||||
|
expect(t3.get('sort')).toBe(1);
|
||||||
|
expect(t4.get('sort')).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
@ -1,17 +1,18 @@
|
|||||||
import { Sequelize, ModelCtor, Model, ModelOptions } from 'sequelize';
|
import merge from 'deepmerge';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
import { default as lodash, default as _ } from 'lodash';
|
||||||
|
import { Model, ModelCtor, ModelOptions } from 'sequelize';
|
||||||
|
import { SyncOptions } from 'sequelize/types/lib/sequelize';
|
||||||
import { Database } from './database';
|
import { Database } from './database';
|
||||||
import { Field, FieldOptions } from './fields';
|
import { Field, FieldOptions } from './fields';
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { Repository } from './repository';
|
import { Repository } from './repository';
|
||||||
import { SyncOptions } from 'sequelize/types/lib/sequelize';
|
|
||||||
import lodash from 'lodash';
|
|
||||||
import merge from 'deepmerge';
|
|
||||||
const { hooks } = require('sequelize/lib/hooks');
|
const { hooks } = require('sequelize/lib/hooks');
|
||||||
|
|
||||||
export type RepositoryType = typeof Repository;
|
export type RepositoryType = typeof Repository;
|
||||||
|
|
||||||
|
export type CollectionSortable = string | boolean | { name?: string; scopeKey?: string };
|
||||||
|
|
||||||
export interface CollectionOptions extends Omit<ModelOptions, 'name'> {
|
export interface CollectionOptions extends Omit<ModelOptions, 'name'> {
|
||||||
name: string;
|
name: string;
|
||||||
tableName?: string;
|
tableName?: string;
|
||||||
@ -19,6 +20,7 @@ export interface CollectionOptions extends Omit<ModelOptions, 'name'> {
|
|||||||
fields?: FieldOptions[];
|
fields?: FieldOptions[];
|
||||||
model?: string | ModelCtor<Model>;
|
model?: string | ModelCtor<Model>;
|
||||||
repository?: string | RepositoryType;
|
repository?: string | RepositoryType;
|
||||||
|
sortable?: CollectionSortable;
|
||||||
/**
|
/**
|
||||||
* @default true
|
* @default true
|
||||||
*/
|
*/
|
||||||
@ -61,6 +63,7 @@ export class Collection<
|
|||||||
this.modelInit();
|
this.modelInit();
|
||||||
this.setFields(options.fields);
|
this.setFields(options.fields);
|
||||||
this.setRepository(options.repository);
|
this.setRepository(options.repository);
|
||||||
|
this.setSortable(options.sortable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private sequelizeModelOptions() {
|
private sequelizeModelOptions() {
|
||||||
@ -211,6 +214,27 @@ export class Collection<
|
|||||||
(<any>this.model)._setupHooks(bindHooks);
|
(<any>this.model)._setupHooks(bindHooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSortable(sortable) {
|
||||||
|
if (!sortable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sortable === true) {
|
||||||
|
this.setField('sort', {
|
||||||
|
type: 'sort',
|
||||||
|
hidden: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (typeof sortable === 'string') {
|
||||||
|
this.setField(sortable, {
|
||||||
|
type: 'sort',
|
||||||
|
hidden: true,
|
||||||
|
});
|
||||||
|
} else if (typeof sortable === 'object') {
|
||||||
|
const { name, ...opts } = sortable;
|
||||||
|
this.setField(name || 'sort', { type: 'sort', hidden: true, ...opts });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import { applyMixins, AsyncEmitter } from '@nocobase/utils';
|
import { applyMixins, AsyncEmitter } from '@nocobase/utils';
|
||||||
import merge from 'deepmerge';
|
import merge from 'deepmerge';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { Model, ModelCtor, Op, Options, QueryInterfaceDropAllTablesOptions, Sequelize, SyncOptions, Utils } from 'sequelize';
|
import {
|
||||||
|
Model,
|
||||||
|
ModelCtor,
|
||||||
|
Op,
|
||||||
|
Options,
|
||||||
|
QueryInterfaceDropAllTablesOptions,
|
||||||
|
Sequelize,
|
||||||
|
SyncOptions,
|
||||||
|
Utils
|
||||||
|
} from 'sequelize';
|
||||||
import { Collection, CollectionOptions, RepositoryType } from './collection';
|
import { Collection, CollectionOptions, RepositoryType } from './collection';
|
||||||
import { ImporterReader, ImportFileExtension } from './collection-importer';
|
import { ImporterReader, ImportFileExtension } from './collection-importer';
|
||||||
import * as FieldTypes from './fields';
|
import * as FieldTypes from './fields';
|
||||||
@ -295,6 +304,18 @@ export function extend(collectionOptions: CollectionOptions, mergeOptions?: Merg
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const defineCollection = (collectionOptions: CollectionOptions) => {
|
||||||
|
return collectionOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const extendCollection = (collectionOptions: CollectionOptions, mergeOptions?: MergeOptions) => {
|
||||||
|
return {
|
||||||
|
collectionOptions,
|
||||||
|
mergeOptions,
|
||||||
|
extend: true,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
applyMixins(Database, [AsyncEmitter]);
|
applyMixins(Database, [AsyncEmitter]);
|
||||||
|
|
||||||
export default Database;
|
export default Database;
|
||||||
|
@ -1,31 +1,30 @@
|
|||||||
|
import lodash, { omit } from 'lodash';
|
||||||
import {
|
import {
|
||||||
Association,
|
Association,
|
||||||
BulkCreateOptions,
|
BulkCreateOptions,
|
||||||
CreateOptions as SequelizeCreateOptions,
|
CreateOptions as SequelizeCreateOptions,
|
||||||
UpdateOptions as SequelizeUpdateOptions,
|
|
||||||
FindAndCountOptions as SequelizeAndCountOptions,
|
|
||||||
DestroyOptions as SequelizeDestroyOptions,
|
DestroyOptions as SequelizeDestroyOptions,
|
||||||
|
FindAndCountOptions as SequelizeAndCountOptions,
|
||||||
FindOptions as SequelizeFindOptions,
|
FindOptions as SequelizeFindOptions,
|
||||||
Model,
|
Model,
|
||||||
ModelCtor,
|
ModelCtor,
|
||||||
Op,
|
Op,
|
||||||
Transaction,
|
Transaction,
|
||||||
|
UpdateOptions as SequelizeUpdateOptions
|
||||||
} from 'sequelize';
|
} from 'sequelize';
|
||||||
|
|
||||||
import { Collection } from './collection';
|
import { Collection } from './collection';
|
||||||
import lodash, { omit } from 'lodash';
|
|
||||||
import { Database } from './database';
|
import { Database } from './database';
|
||||||
import { updateAssociations, updateModelByValues } from './update-associations';
|
|
||||||
import { RelationField } from './fields';
|
import { RelationField } from './fields';
|
||||||
import FilterParser from './filter-parser';
|
import FilterParser from './filter-parser';
|
||||||
import { OptionsParser } from './options-parser';
|
import { OptionsParser } from './options-parser';
|
||||||
import { RelationRepository } from './relation-repository/relation-repository';
|
|
||||||
import { HasOneRepository } from './relation-repository/hasone-repository';
|
|
||||||
import { BelongsToRepository } from './relation-repository/belongs-to-repository';
|
|
||||||
import { BelongsToManyRepository } from './relation-repository/belongs-to-many-repository';
|
import { BelongsToManyRepository } from './relation-repository/belongs-to-many-repository';
|
||||||
|
import { BelongsToRepository } from './relation-repository/belongs-to-repository';
|
||||||
import { HasManyRepository } from './relation-repository/hasmany-repository';
|
import { HasManyRepository } from './relation-repository/hasmany-repository';
|
||||||
import { UpdateGuard } from './update-guard';
|
import { HasOneRepository } from './relation-repository/hasone-repository';
|
||||||
|
import { RelationRepository } from './relation-repository/relation-repository';
|
||||||
import { transactionWrapperBuilder } from './transaction-decorator';
|
import { transactionWrapperBuilder } from './transaction-decorator';
|
||||||
|
import { updateAssociations, updateModelByValues } from './update-associations';
|
||||||
|
import { UpdateGuard } from './update-guard';
|
||||||
|
|
||||||
const debug = require('debug')('noco-database');
|
const debug = require('debug')('noco-database');
|
||||||
|
|
||||||
@ -324,15 +323,11 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|||||||
async createMany(options: CreateManyOptions) {
|
async createMany(options: CreateManyOptions) {
|
||||||
const transaction = await this.getTransaction(options);
|
const transaction = await this.getTransaction(options);
|
||||||
const { records } = options;
|
const { records } = options;
|
||||||
const instances = await this.collection.model.bulkCreate(records, {
|
const instances = [];
|
||||||
...options,
|
for (const values of records) {
|
||||||
transaction,
|
const instance = await this.create({ values, transaction });
|
||||||
});
|
instances.push(instance);
|
||||||
|
|
||||||
for (let i = 0; i < instances.length; i++) {
|
|
||||||
await updateAssociations(instances[i], records[i], { ...options, transaction });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user