refactor(plugin-field-sort): move sort field to plugin

This commit is contained in:
mytharcher 2024-08-20 02:36:48 +00:00
parent ac0bae6be9
commit 9b9e03ea19
32 changed files with 438 additions and 29 deletions

View File

@ -20,7 +20,7 @@ describe('middleware', () => {
app = await createMockServer({ app = await createMockServer({
registerActions: true, registerActions: true,
acl: true, acl: true,
plugins: ['users', 'auth', 'acl', 'data-source-manager'], plugins: ['users', 'auth', 'acl', 'field-sort', 'data-source-manager'],
}); });
// app.plugin(ApiKeysPlugin); // app.plugin(ApiKeysPlugin);

View File

@ -48,7 +48,6 @@ import {
UpdatedAtFieldInterface, UpdatedAtFieldInterface,
UpdatedByFieldInterface, UpdatedByFieldInterface,
UrlFieldInterface, UrlFieldInterface,
SortFieldInterface,
UUIDFieldInterface, UUIDFieldInterface,
NanoidFieldInterface, NanoidFieldInterface,
UnixTimestampFieldInterface, UnixTimestampFieldInterface,
@ -169,7 +168,6 @@ export class CollectionPlugin extends Plugin {
UpdatedAtFieldInterface, UpdatedAtFieldInterface,
UpdatedByFieldInterface, UpdatedByFieldInterface,
UrlFieldInterface, UrlFieldInterface,
SortFieldInterface,
UUIDFieldInterface, UUIDFieldInterface,
NanoidFieldInterface, NanoidFieldInterface,
UnixTimestampFieldInterface, UnixTimestampFieldInterface,

View File

@ -8,7 +8,6 @@
*/ */
import { createConsoleLogger, createLogger, Logger, LoggerOptions } from '@nocobase/logger'; import { createConsoleLogger, createLogger, Logger, LoggerOptions } from '@nocobase/logger';
import { LockManager } from '@nocobase/lock-manager';
import { applyMixins, AsyncEmitter } from '@nocobase/utils'; import { applyMixins, AsyncEmitter } from '@nocobase/utils';
import chalk from 'chalk'; import chalk from 'chalk';
import merge from 'deepmerge'; import merge from 'deepmerge';
@ -107,7 +106,6 @@ export interface IDatabaseOptions extends Options {
logger?: LoggerOptions | Logger; logger?: LoggerOptions | Logger;
customHooks?: any; customHooks?: any;
instanceId?: string; instanceId?: string;
lockManager?: LockManager;
} }
export type DatabaseOptions = IDatabaseOptions; export type DatabaseOptions = IDatabaseOptions;
@ -183,7 +181,6 @@ export class Database extends EventEmitter implements AsyncEmitter {
modelHook: ModelHook; modelHook: ModelHook;
delayCollectionExtend = new Map<string, { collectionOptions: CollectionOptions; mergeOptions?: any }[]>(); delayCollectionExtend = new Map<string, { collectionOptions: CollectionOptions; mergeOptions?: any }[]>();
logger: Logger; logger: Logger;
lockManager: LockManager;
interfaceManager = new InterfaceManager(this); interfaceManager = new InterfaceManager(this);
collectionFactory: CollectionFactory = new CollectionFactory(this); collectionFactory: CollectionFactory = new CollectionFactory(this);
@ -202,10 +199,6 @@ export class Database extends EventEmitter implements AsyncEmitter {
...lodash.clone(options), ...lodash.clone(options),
}; };
if (opts.lockManager) {
this.lockManager = opts.lockManager;
}
if (options.logger) { if (options.logger) {
if (typeof options.logger['log'] === 'function') { if (typeof options.logger['log'] === 'function') {
this.logger = options.logger as Logger; this.logger = options.logger as Logger;

View File

@ -27,7 +27,6 @@ import {
import { PasswordFieldOptions } from './password-field'; import { PasswordFieldOptions } from './password-field';
import { RadioFieldOptions } from './radio-field'; import { RadioFieldOptions } from './radio-field';
import { SetFieldOptions } from './set-field'; import { SetFieldOptions } from './set-field';
import { SortFieldOptions } from './sort-field';
import { StringFieldOptions } from './string-field'; import { StringFieldOptions } from './string-field';
import { TextFieldOptions } from './text-field'; import { TextFieldOptions } from './text-field';
import { TimeFieldOptions } from './time-field'; import { TimeFieldOptions } from './time-field';
@ -52,7 +51,6 @@ export * from './password-field';
export * from './radio-field'; export * from './radio-field';
export * from './relation-field'; export * from './relation-field';
export * from './set-field'; export * from './set-field';
export * from './sort-field';
export * from './string-field'; export * from './string-field';
export * from './text-field'; export * from './text-field';
export * from './time-field'; export * from './time-field';
@ -74,7 +72,6 @@ export type FieldOptions =
| JsonbFieldOptions | JsonbFieldOptions
| BooleanFieldOptions | BooleanFieldOptions
| RadioFieldOptions | RadioFieldOptions
| SortFieldOptions
| TextFieldOptions | TextFieldOptions
| VirtualFieldOptions | VirtualFieldOptions
| ArrayFieldOptions | ArrayFieldOptions

View File

@ -101,10 +101,6 @@ export function mockDatabase(options: IDatabaseOptions = {}): MockDatabase {
} }
} }
if (!options.lockManager) {
dbOptions.lockManager = new LockManager();
}
const db = new MockDatabase(dbOptions); const db = new MockDatabase(dbOptions);
return db; return db;

View File

@ -1240,7 +1240,6 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
context: { app: this }, context: { app: this },
}, },
logger: this._logger.child({ module: 'database' }), logger: this._logger.child({ module: 'database' }),
lockManager: this.lockManager,
}); });
return db; return db;
} }

View File

@ -17,6 +17,7 @@
"@nocobase/client": "1.x", "@nocobase/client": "1.x",
"@nocobase/database": "1.x", "@nocobase/database": "1.x",
"@nocobase/plugin-error-handler": "1.x", "@nocobase/plugin-error-handler": "1.x",
"@nocobase/plugin-field-sort": "1.x",
"@nocobase/server": "1.x", "@nocobase/server": "1.x",
"@nocobase/test": "1.x", "@nocobase/test": "1.x",
"@nocobase/utils": "1.x" "@nocobase/utils": "1.x"

View File

@ -13,7 +13,7 @@ export async function createApp(options: any = {}) {
const app = await createMockServer({ const app = await createMockServer({
acl: false, acl: false,
...options, ...options,
plugins: ['error-handler', 'data-source-main', 'ui-schema-storage'], plugins: ['error-handler', 'field-sort', 'data-source-main', 'ui-schema-storage'],
}); });
return app; return app;
} }

View File

@ -0,0 +1,2 @@
/node_modules
/src

View File

@ -0,0 +1 @@
# @nocobase/plugin-field-sort

View File

@ -0,0 +1,2 @@
export * from './dist/client';
export { default } from './dist/client';

View File

@ -0,0 +1 @@
module.exports = require('./dist/client/index.js');

View File

@ -0,0 +1,11 @@
{
"name": "@nocobase/plugin-field-sort",
"version": "1.3.0-alpha",
"main": "dist/server/index.js",
"dependencies": {},
"peerDependencies": {
"@nocobase/client": "1.x",
"@nocobase/server": "1.x",
"@nocobase/test": "1.x"
}
}

View File

@ -0,0 +1,2 @@
export * from './dist/server';
export { default } from './dist/server';

View File

@ -0,0 +1 @@
module.exports = require('./dist/server/index.js');

View File

@ -0,0 +1,249 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
// CSS modules
type CSSModuleClasses = { readonly [key: string]: string };
declare module '*.module.css' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.scss' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.sass' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.less' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.styl' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.stylus' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.pcss' {
const classes: CSSModuleClasses;
export default classes;
}
declare module '*.module.sss' {
const classes: CSSModuleClasses;
export default classes;
}
// CSS
declare module '*.css' { }
declare module '*.scss' { }
declare module '*.sass' { }
declare module '*.less' { }
declare module '*.styl' { }
declare module '*.stylus' { }
declare module '*.pcss' { }
declare module '*.sss' { }
// Built-in asset types
// see `src/node/constants.ts`
// images
declare module '*.apng' {
const src: string;
export default src;
}
declare module '*.png' {
const src: string;
export default src;
}
declare module '*.jpg' {
const src: string;
export default src;
}
declare module '*.jpeg' {
const src: string;
export default src;
}
declare module '*.jfif' {
const src: string;
export default src;
}
declare module '*.pjpeg' {
const src: string;
export default src;
}
declare module '*.pjp' {
const src: string;
export default src;
}
declare module '*.gif' {
const src: string;
export default src;
}
declare module '*.svg' {
const src: string;
export default src;
}
declare module '*.ico' {
const src: string;
export default src;
}
declare module '*.webp' {
const src: string;
export default src;
}
declare module '*.avif' {
const src: string;
export default src;
}
// media
declare module '*.mp4' {
const src: string;
export default src;
}
declare module '*.webm' {
const src: string;
export default src;
}
declare module '*.ogg' {
const src: string;
export default src;
}
declare module '*.mp3' {
const src: string;
export default src;
}
declare module '*.wav' {
const src: string;
export default src;
}
declare module '*.flac' {
const src: string;
export default src;
}
declare module '*.aac' {
const src: string;
export default src;
}
declare module '*.opus' {
const src: string;
export default src;
}
declare module '*.mov' {
const src: string;
export default src;
}
declare module '*.m4a' {
const src: string;
export default src;
}
declare module '*.vtt' {
const src: string;
export default src;
}
// fonts
declare module '*.woff' {
const src: string;
export default src;
}
declare module '*.woff2' {
const src: string;
export default src;
}
declare module '*.eot' {
const src: string;
export default src;
}
declare module '*.ttf' {
const src: string;
export default src;
}
declare module '*.otf' {
const src: string;
export default src;
}
// other
declare module '*.webmanifest' {
const src: string;
export default src;
}
declare module '*.pdf' {
const src: string;
export default src;
}
declare module '*.txt' {
const src: string;
export default src;
}
// wasm?init
declare module '*.wasm?init' {
const initWasm: (options?: WebAssembly.Imports) => Promise<WebAssembly.Instance>;
export default initWasm;
}
// web worker
declare module '*?worker' {
const workerConstructor: {
new(options?: { name?: string }): Worker;
};
export default workerConstructor;
}
declare module '*?worker&inline' {
const workerConstructor: {
new(options?: { name?: string }): Worker;
};
export default workerConstructor;
}
declare module '*?worker&url' {
const src: string;
export default src;
}
declare module '*?sharedworker' {
const sharedWorkerConstructor: {
new(options?: { name?: string }): SharedWorker;
};
export default sharedWorkerConstructor;
}
declare module '*?sharedworker&inline' {
const sharedWorkerConstructor: {
new(options?: { name?: string }): SharedWorker;
};
export default sharedWorkerConstructor;
}
declare module '*?sharedworker&url' {
const src: string;
export default src;
}
declare module '*?raw' {
const src: string;
export default src;
}
declare module '*?url' {
const src: string;
export default src;
}
declare module '*?inline' {
const src: string;
export default src;
}

View File

@ -0,0 +1,31 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Plugin } from '@nocobase/client';
import { SortFieldInterface } from './sort-interface';
export class PluginFieldSortClient extends Plugin {
async afterAdd() {
// await this.app.pm.add()
}
async beforeLoad() {}
// You can get and modify the app instance here
async load() {
this.app.addFieldInterfaces([SortFieldInterface]);
// this.app.addComponents({})
// this.app.addScopes({})
// this.app.addProvider()
// this.app.addProviders()
// this.app.router.add()
}
}
export default PluginFieldSortClient;

View File

@ -0,0 +1,21 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
// @ts-ignore
import pkg from './../../package.json';
import { useApp } from '@nocobase/client';
export function useT() {
const app = useApp();
return (str: string) => app.i18n.t(str, { ns: [pkg.name, 'client'] });
}
export function tStr(key: string) {
return `{{t(${JSON.stringify(key)}, { ns: ['${pkg.name}', 'client'], nsMode: 'fallback' })}}`;
}

View File

@ -7,9 +7,7 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface'; import { CollectionFieldInterface, i18n, defaultProps, operators } from '@nocobase/client';
import { i18n } from '../../i18n';
import { defaultProps, operators } from './properties';
export class SortFieldInterface extends CollectionFieldInterface { export class SortFieldInterface extends CollectionFieldInterface {
name = 'sort'; name = 'sort';
type = 'object'; type = 'object';

View File

@ -0,0 +1,11 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
export * from './server';
export { default } from './server';

View File

@ -7,9 +7,8 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import { Database } from '../../database'; import { Database, mockDatabase } from '@nocobase/database';
import { mockDatabase } from '../'; import { SortField } from '../sort-field';
import { SortField } from '../../fields';
describe('string field', () => { describe('string field', () => {
let db: Database; let db: Database;

View File

@ -0,0 +1,10 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
export { default } from './plugin';

View File

@ -0,0 +1,36 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Plugin } from '@nocobase/server';
import { SortField } from './sort-field';
export class PluginFieldSortServer extends Plugin {
async afterAdd() {}
async beforeLoad() {
const { lockManager } = this.app;
class SortFieldClass extends SortField {}
SortFieldClass.lockManager = lockManager;
this.app.db.registerFieldTypes({
sort: SortFieldClass,
});
}
async load() {}
async install() {}
async afterEnable() {}
async afterDisable() {}
async remove() {}
}
export default PluginFieldSortServer;

View File

@ -9,9 +9,12 @@
import { isNumber } from 'lodash'; import { isNumber } from 'lodash';
import { DataTypes } from 'sequelize'; import { DataTypes } from 'sequelize';
import { BaseColumnFieldOptions, Field } from './field'; import { BaseColumnFieldOptions, Field } from '@nocobase/database';
import { LockManager } from '@nocobase/lock-manager';
export class SortField extends Field { export class SortField extends Field {
static lockManager: LockManager;
get dataType() { get dataType() {
return DataTypes.BIGINT; return DataTypes.BIGINT;
} }
@ -33,7 +36,7 @@ export class SortField extends Field {
} }
} }
await this.database.lockManager.runExclusive( await (<typeof SortField>this.constructor).lockManager.runExclusive(
this.context.collection.name, this.context.collection.name,
async () => { async () => {
const max = await model.max<number, any>(name, { ...options, where }); const max = await model.max<number, any>(name, { ...options, where });

View File

@ -22,7 +22,7 @@ describe('multiple apps', () => {
beforeEach(async () => { beforeEach(async () => {
app = await createMockServer({ app = await createMockServer({
plugins: ['nocobase', 'multi-app-manager'], plugins: ['nocobase', 'field-sort', 'multi-app-manager'],
}); });
db = app.db; db = app.db;
}); });

View File

@ -24,7 +24,15 @@ describe('server hooks', () => {
beforeEach(async () => { beforeEach(async () => {
app = await createMockServer({ app = await createMockServer({
registerActions: true, registerActions: true,
plugins: ['ui-schema-storage', 'data-source-main', 'error-handler', 'users', 'acl', 'data-source-manager'], plugins: [
'ui-schema-storage',
'data-source-main',
'field-sort',
'error-handler',
'users',
'acl',
'data-source-manager',
],
}); });
await app.runCommand('install', '-f'); await app.runCommand('install', '-f');
db = app.db; db = app.db;

View File

@ -35,6 +35,7 @@
"@nocobase/plugin-field-m2m-array": "1.4.0-alpha", "@nocobase/plugin-field-m2m-array": "1.4.0-alpha",
"@nocobase/plugin-field-markdown-vditor": "1.4.0-alpha", "@nocobase/plugin-field-markdown-vditor": "1.4.0-alpha",
"@nocobase/plugin-field-sequence": "1.4.0-alpha", "@nocobase/plugin-field-sequence": "1.4.0-alpha",
"@nocobase/plugin-field-sort": "1.4.0-alpha",
"@nocobase/plugin-file-manager": "1.4.0-alpha", "@nocobase/plugin-file-manager": "1.4.0-alpha",
"@nocobase/plugin-gantt": "1.4.0-alpha", "@nocobase/plugin-gantt": "1.4.0-alpha",
"@nocobase/plugin-graph-collection-manager": "1.4.0-alpha", "@nocobase/plugin-graph-collection-manager": "1.4.0-alpha",

View File

@ -20,6 +20,7 @@ export class PresetNocoBase extends Plugin {
'file-manager', 'file-manager',
'system-settings', 'system-settings',
'field-sequence', 'field-sequence',
'field-sort',
'verification', 'verification',
'users', 'users',
'acl', 'acl',

View File

@ -0,0 +1,35 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Migration } from '@nocobase/server';
export default class extends Migration {
on = 'beforeLoad'; // 'beforeLoad' or 'afterLoad'
async up() {
const existed = await this.pm.repository.findOne({
filter: {
packageName: '@nocobase/plugin-field-sort',
},
});
if (!existed) {
await this.pm.repository.create({
values: {
name: 'field-sort',
packageName: '@nocobase/plugin-field-sort',
version: this.appVersion,
enabled: true,
installed: true,
builtIn: true,
},
});
}
}
}