feat: add sortable parameter to collection options

This commit is contained in:
chenos 2022-02-11 14:34:33 +08:00
parent e12b8f44d1
commit 16d07e9b4a
4 changed files with 124 additions and 24 deletions

View 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);
});
});

View File

@ -1,17 +1,18 @@
import { Sequelize, ModelCtor, Model, ModelOptions } from 'sequelize';
import merge from 'deepmerge';
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 { Field, FieldOptions } from './fields';
import _ from 'lodash';
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');
export type RepositoryType = typeof Repository;
export type CollectionSortable = string | boolean | { name?: string; scopeKey?: string };
export interface CollectionOptions extends Omit<ModelOptions, 'name'> {
name: string;
tableName?: string;
@ -19,6 +20,7 @@ export interface CollectionOptions extends Omit<ModelOptions, 'name'> {
fields?: FieldOptions[];
model?: string | ModelCtor<Model>;
repository?: string | RepositoryType;
sortable?: CollectionSortable;
/**
* @default true
*/
@ -61,6 +63,7 @@ export class Collection<
this.modelInit();
this.setFields(options.fields);
this.setRepository(options.repository);
this.setSortable(options.sortable);
}
private sequelizeModelOptions() {
@ -211,6 +214,27 @@ export class Collection<
(<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
*

View File

@ -1,7 +1,16 @@
import { applyMixins, AsyncEmitter } from '@nocobase/utils';
import merge from 'deepmerge';
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 { ImporterReader, ImportFileExtension } from './collection-importer';
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]);
export default Database;

View File

@ -1,31 +1,30 @@
import lodash, { omit } from 'lodash';
import {
Association,
BulkCreateOptions,
CreateOptions as SequelizeCreateOptions,
UpdateOptions as SequelizeUpdateOptions,
FindAndCountOptions as SequelizeAndCountOptions,
DestroyOptions as SequelizeDestroyOptions,
FindAndCountOptions as SequelizeAndCountOptions,
FindOptions as SequelizeFindOptions,
Model,
ModelCtor,
Op,
Transaction,
UpdateOptions as SequelizeUpdateOptions
} from 'sequelize';
import { Collection } from './collection';
import lodash, { omit } from 'lodash';
import { Database } from './database';
import { updateAssociations, updateModelByValues } from './update-associations';
import { RelationField } from './fields';
import FilterParser from './filter-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 { BelongsToRepository } from './relation-repository/belongs-to-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 { updateAssociations, updateModelByValues } from './update-associations';
import { UpdateGuard } from './update-guard';
const debug = require('debug')('noco-database');
@ -324,15 +323,11 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
async createMany(options: CreateManyOptions) {
const transaction = await this.getTransaction(options);
const { records } = options;
const instances = await this.collection.model.bulkCreate(records, {
...options,
transaction,
});
for (let i = 0; i < instances.length; i++) {
await updateAssociations(instances[i], records[i], { ...options, transaction });
const instances = [];
for (const values of records) {
const instance = await this.create({ values, transaction });
instances.push(instance);
}
return instances;
}