feat: improve code
This commit is contained in:
parent
aa1c84e72a
commit
afab15327e
@ -1,5 +1,5 @@
|
|||||||
import { mockServer } from './index';
|
|
||||||
import { registerActions } from '@nocobase/actions';
|
import { registerActions } from '@nocobase/actions';
|
||||||
|
import { mockServer } from './index';
|
||||||
|
|
||||||
describe('list action', () => {
|
describe('list action', () => {
|
||||||
let app;
|
let app;
|
||||||
@ -112,7 +112,7 @@ describe('list action', () => {
|
|||||||
const response = await app
|
const response = await app
|
||||||
.agent()
|
.agent()
|
||||||
.resource('posts.tags', 1)
|
.resource('posts.tags', 1)
|
||||||
.list({ fields: ['id', 'posts_tags.createdAt'], sort: ['id'] });
|
.list({ fields: ['id', 'postsTags.createdAt'], sort: ['id'] });
|
||||||
|
|
||||||
const body = response.body;
|
const body = response.body;
|
||||||
expect(body.count).toEqual(2);
|
expect(body.count).toEqual(2);
|
||||||
|
@ -101,13 +101,13 @@ export class APIClient {
|
|||||||
} else {
|
} else {
|
||||||
config['method'] = 'post';
|
config['method'] = 'post';
|
||||||
}
|
}
|
||||||
return (params?: ActionParams) => {
|
return async (params?: ActionParams) => {
|
||||||
const { values, ...others } = params || {};
|
const { values, ...others } = params || {};
|
||||||
config['params'] = others;
|
config['params'] = others;
|
||||||
if (config.method !== 'get') {
|
if (config.method !== 'get') {
|
||||||
config['data'] = values || {};
|
config['data'] = values || {};
|
||||||
}
|
}
|
||||||
return this.request(config);
|
return await this.request(config);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@ export const updatedAt: IField = {
|
|||||||
sortable: true,
|
sortable: true,
|
||||||
default: {
|
default: {
|
||||||
type: 'date',
|
type: 'date',
|
||||||
field: 'updated_at',
|
field: 'updatedAt',
|
||||||
// name,
|
// name,
|
||||||
uiSchema: {
|
uiSchema: {
|
||||||
type: 'datetime',
|
type: 'datetime',
|
||||||
|
@ -34,7 +34,7 @@ const InternalAdminLayout = (props: any) => {
|
|||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Layout.Header style={{ height: 46, lineHeight: '46px', position: 'relative', paddingLeft: 0 }}>
|
<Layout.Header style={{ height: 46, lineHeight: '46px', position: 'relative', paddingLeft: 0 }}>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex', height: '100%' }}>
|
||||||
<div style={{ width: 200, display: 'inline-flex', color: '#fff', padding: '0', alignItems: 'center' }}>
|
<div style={{ width: 200, display: 'inline-flex', color: '#fff', padding: '0', alignItems: 'center' }}>
|
||||||
<img
|
<img
|
||||||
className={css`
|
className={css`
|
||||||
|
@ -11,6 +11,7 @@ export const LinkToFieldInitializer = (props) => {
|
|||||||
item.find,
|
item.find,
|
||||||
item.remove,
|
item.remove,
|
||||||
);
|
);
|
||||||
|
const targetKey = item.field.targetKey || 'id';
|
||||||
return (
|
return (
|
||||||
<SchemaInitializer.Item
|
<SchemaInitializer.Item
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -20,17 +21,17 @@ export const LinkToFieldInitializer = (props) => {
|
|||||||
}
|
}
|
||||||
insert({
|
insert({
|
||||||
...item.schema,
|
...item.schema,
|
||||||
default: [
|
// default: [
|
||||||
{ id: 1, name: 'name1' },
|
// { id: 1, name: 'name1' },
|
||||||
{ id: 2, name: 'name2' },
|
// { id: 2, name: 'name2' },
|
||||||
],
|
// ],
|
||||||
// 'x-decorator': 'FormItem',
|
// 'x-decorator': 'FormItem',
|
||||||
'x-component': 'CollectionField',
|
'x-component': 'CollectionField',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
mode: 'tags',
|
mode: 'tags',
|
||||||
fieldNames: {
|
fieldNames: {
|
||||||
label: 'name',
|
label: targetKey,
|
||||||
value: 'id',
|
value: targetKey,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
@ -59,22 +60,22 @@ export const LinkToFieldInitializer = (props) => {
|
|||||||
'x-designer': 'Table.Void.Designer',
|
'x-designer': 'Table.Void.Designer',
|
||||||
'x-component': 'CardItem',
|
'x-component': 'CardItem',
|
||||||
properties: {
|
properties: {
|
||||||
actions: {
|
// actions: {
|
||||||
type: 'void',
|
// type: 'void',
|
||||||
'x-initializer': 'TableActionInitializers',
|
// 'x-initializer': 'TableActionInitializers',
|
||||||
'x-component': 'ActionBar',
|
// 'x-component': 'ActionBar',
|
||||||
'x-component-props': {
|
// 'x-component-props': {
|
||||||
style: {
|
// style: {
|
||||||
marginBottom: 16,
|
// marginBottom: 16,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
properties: {},
|
// properties: {},
|
||||||
},
|
// },
|
||||||
table: {
|
table: {
|
||||||
// type: 'void',
|
// type: 'void',
|
||||||
'x-component': 'Table.RowSelection',
|
'x-component': 'Table.RowSelection',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
rowKey: 'id',
|
rowKey: targetKey,
|
||||||
objectValue: true,
|
objectValue: true,
|
||||||
rowSelection: {
|
rowSelection: {
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
@ -83,60 +84,29 @@ export const LinkToFieldInitializer = (props) => {
|
|||||||
},
|
},
|
||||||
'x-initializer': 'TableColumnInitializers',
|
'x-initializer': 'TableColumnInitializers',
|
||||||
properties: {
|
properties: {
|
||||||
actions: {
|
// actions: {
|
||||||
type: 'void',
|
// type: 'void',
|
||||||
title: '{{ t("Actions") }}',
|
// title: '{{ t("Actions") }}',
|
||||||
'x-decorator': 'Table.Column.ActionBar',
|
// 'x-decorator': 'Table.Column.ActionBar',
|
||||||
'x-component': 'Table.Column',
|
// 'x-component': 'Table.Column',
|
||||||
'x-designer': 'Table.RowActionDesigner',
|
// 'x-designer': 'Table.RowActionDesigner',
|
||||||
'x-initializer': 'TableRecordActionInitializers',
|
// 'x-initializer': 'TableRecordActionInitializers',
|
||||||
properties: {
|
// properties: {
|
||||||
actions: {
|
// actions: {
|
||||||
type: 'void',
|
// type: 'void',
|
||||||
'x-decorator': 'DndContext',
|
// 'x-decorator': 'DndContext',
|
||||||
'x-component': 'Space',
|
// 'x-component': 'Space',
|
||||||
'x-component-props': {
|
// 'x-component-props': {
|
||||||
split: '|',
|
// split: '|',
|
||||||
},
|
// },
|
||||||
properties: {},
|
// properties: {},
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// input: {
|
|
||||||
// type: 'array',
|
|
||||||
// title: `编辑模式`,
|
|
||||||
// 'x-component': 'Table.RowSelection',
|
|
||||||
// 'x-component-props': {
|
|
||||||
// rowKey: 'id',
|
|
||||||
// objectValue: true,
|
|
||||||
// rowSelection: {
|
|
||||||
// type: 'checkbox',
|
|
||||||
// },
|
|
||||||
// dataSource: [
|
|
||||||
// { id: 1, name: 'Name1' },
|
|
||||||
// { id: 2, name: 'Name2' },
|
|
||||||
// { id: 3, name: 'Name3' },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// properties: {
|
|
||||||
// column1: {
|
|
||||||
// type: 'void',
|
|
||||||
// title: 'Name',
|
|
||||||
// 'x-component': 'Table.Column',
|
|
||||||
// properties: {
|
|
||||||
// name: {
|
|
||||||
// type: 'string',
|
|
||||||
// 'x-component': 'Input',
|
|
||||||
// 'x-read-pretty': true,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
item: {
|
item: {
|
||||||
|
@ -4,7 +4,7 @@ import { useField, useFieldSchema } from '@formily/react';
|
|||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DragHandler, useDesignable } from '../schema-component';
|
import { DragHandler, useCompile, useDesignable } from '../schema-component';
|
||||||
import { SchemaSettings } from './SchemaSettings';
|
import { SchemaSettings } from './SchemaSettings';
|
||||||
|
|
||||||
const titleCss = css`
|
const titleCss = css`
|
||||||
@ -27,6 +27,7 @@ export const GeneralSchemaDesigner = (props: any) => {
|
|||||||
const { dn, designable } = useDesignable();
|
const { dn, designable } = useDesignable();
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
|
const compile = useCompile();
|
||||||
const schemaSettingsProps = {
|
const schemaSettingsProps = {
|
||||||
dn,
|
dn,
|
||||||
field,
|
field,
|
||||||
@ -37,7 +38,7 @@ export const GeneralSchemaDesigner = (props: any) => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className={'general-schema-designer'}>
|
<div className={'general-schema-designer'}>
|
||||||
{title && <div className={classNames('general-schema-designer-title', titleCss)}>{title}</div>}
|
{title && <div className={classNames('general-schema-designer-title', titleCss)}>{compile(title)}</div>}
|
||||||
<div className={'general-schema-designer-icons'}>
|
<div className={'general-schema-designer-icons'}>
|
||||||
<Space size={2} align={'center'}>
|
<Space size={2} align={'center'}>
|
||||||
<DragHandler>
|
<DragHandler>
|
||||||
|
@ -91,15 +91,13 @@ const useSignup = () => {
|
|||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
await form.submit();
|
await form.submit();
|
||||||
const response = await api.resource('users').signup({
|
await api.resource('users').signup({
|
||||||
values: form.values,
|
values: form.values,
|
||||||
});
|
});
|
||||||
if (response?.data) {
|
message.success('注册成功,即将跳转登录页');
|
||||||
message.success('注册成功,即将跳转登录页');
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
history.push('/signin');
|
||||||
history.push('/signin');
|
}, 2000);
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -184,7 +184,7 @@ describe('collection sync', () => {
|
|||||||
|
|
||||||
const tableFields = await (<any>model).queryInterface.describeTable(`${db.getTablePrefix()}posts`);
|
const tableFields = await (<any>model).queryInterface.describeTable(`${db.getTablePrefix()}posts`);
|
||||||
|
|
||||||
expect(tableFields['user_id']).toBeUndefined();
|
expect(tableFields['userId']).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sync with association', async () => {
|
test('sync with association', async () => {
|
||||||
@ -211,7 +211,7 @@ describe('collection sync', () => {
|
|||||||
|
|
||||||
const model = collection.model;
|
const model = collection.model;
|
||||||
await collection.sync();
|
await collection.sync();
|
||||||
const tableFields = await (<any>model).queryInterface.describeTable(`${db.getTablePrefix()}posts_tags`);
|
const tableFields = await (<any>model).queryInterface.describeTable(`${db.getTablePrefix()}postsTags`);
|
||||||
expect(tableFields['postId']).toBeDefined();
|
expect(tableFields['postId']).toBeDefined();
|
||||||
expect(tableFields['tagId']).toBeDefined();
|
expect(tableFields['tagId']).toBeDefined();
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Database } from '../../database';
|
|
||||||
import { mockDatabase } from '../';
|
import { mockDatabase } from '../';
|
||||||
|
import { Database } from '../../database';
|
||||||
|
|
||||||
describe('belongs to many field', () => {
|
describe('belongs to many field', () => {
|
||||||
let db: Database;
|
let db: Database;
|
||||||
@ -22,14 +22,14 @@ describe('belongs to many field', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(Post.model.associations.tags).toBeUndefined();
|
expect(Post.model.associations.tags).toBeUndefined();
|
||||||
expect(db.getCollection('posts_tags')).toBeUndefined();
|
expect(db.getCollection('postsTags')).toBeUndefined();
|
||||||
|
|
||||||
const Tag = db.collection({
|
const Tag = db.collection({
|
||||||
name: 'tags',
|
name: 'tags',
|
||||||
fields: [{ type: 'string', name: 'name' }],
|
fields: [{ type: 'string', name: 'name' }],
|
||||||
});
|
});
|
||||||
expect(Post.model.associations.tags).toBeDefined();
|
expect(Post.model.associations.tags).toBeDefined();
|
||||||
const Through = db.getCollection('posts_tags');
|
const Through = db.getCollection('postsTags');
|
||||||
expect(Through).toBeDefined();
|
expect(Through).toBeDefined();
|
||||||
|
|
||||||
expect(Through.model.rawAttributes['postId']).toBeDefined();
|
expect(Through.model.rawAttributes['postId']).toBeDefined();
|
||||||
@ -46,14 +46,14 @@ describe('belongs to many field', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(Post.model.associations.tags).toBeUndefined();
|
expect(Post.model.associations.tags).toBeUndefined();
|
||||||
expect(db.getCollection('posts_tags')).toBeUndefined();
|
expect(db.getCollection('postsTags')).toBeUndefined();
|
||||||
|
|
||||||
const Tag = db.collection({
|
const Tag = db.collection({
|
||||||
name: 'tags',
|
name: 'tags',
|
||||||
fields: [{ type: 'string', name: 'name' }],
|
fields: [{ type: 'string', name: 'name' }],
|
||||||
});
|
});
|
||||||
|
|
||||||
const PostTag = db.collection({ name: 'posts_tags' });
|
const PostTag = db.collection({ name: 'postsTags' });
|
||||||
|
|
||||||
expect(PostTag.model.rawAttributes['postId']).toBeDefined();
|
expect(PostTag.model.rawAttributes['postId']).toBeDefined();
|
||||||
expect(PostTag.model.rawAttributes['tagId']).toBeDefined();
|
expect(PostTag.model.rawAttributes['tagId']).toBeDefined();
|
||||||
|
@ -159,7 +159,7 @@ export class Collection<
|
|||||||
collection: this,
|
collection: this,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
this.removeField(name);
|
||||||
this.fields.set(name, field);
|
this.fields.set(name, field);
|
||||||
this.emit('field.afterAdd', field);
|
this.emit('field.afterAdd', field);
|
||||||
return field;
|
return field;
|
||||||
@ -187,6 +187,9 @@ export class Collection<
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeField(name) {
|
removeField(name) {
|
||||||
|
if (!this.fields.has(name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const field = this.fields.get(name);
|
const field = this.fields.get(name);
|
||||||
const bool = this.fields.delete(name);
|
const bool = this.fields.delete(name);
|
||||||
if (bool) {
|
if (bool) {
|
||||||
|
@ -158,10 +158,10 @@ export class Database extends EventEmitter implements AsyncEmitter {
|
|||||||
getRepository<R extends RelationRepository>(name: string, relationId?: string | number): Repository | R {
|
getRepository<R extends RelationRepository>(name: string, relationId?: string | number): Repository | R {
|
||||||
if (relationId) {
|
if (relationId) {
|
||||||
const [collection, relation] = name.split('.');
|
const [collection, relation] = name.split('.');
|
||||||
return this.getRepository(collection).relation(relation).of(relationId) as R;
|
return this.getRepository(collection)?.relation(relation)?.of(relationId) as R;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getCollection(name).repository;
|
return this.getCollection(name)?.repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
addPendingField(field: RelationField) {
|
addPendingField(field: RelationField) {
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
import { BelongsToManyOptions as SequelizeBelongsToManyOptions } from 'sequelize';
|
import { BelongsToManyOptions as SequelizeBelongsToManyOptions, Utils } from 'sequelize';
|
||||||
import { Collection } from '../collection';
|
import { Collection } from '../collection';
|
||||||
import { BaseRelationFieldOptions, MultipleRelationFieldOptions, RelationField } from './relation-field';
|
import { MultipleRelationFieldOptions, RelationField } from './relation-field';
|
||||||
|
|
||||||
export class BelongsToManyField extends RelationField {
|
export class BelongsToManyField extends RelationField {
|
||||||
get through() {
|
get through() {
|
||||||
return (
|
return (
|
||||||
this.options.through ||
|
this.options.through ||
|
||||||
[this.context.collection.model.name, this.target]
|
Utils.camelize(
|
||||||
.map((name) => name.toLowerCase())
|
[this.context.collection.model.name, this.target]
|
||||||
.sort()
|
.map((name) => name.toLowerCase())
|
||||||
.join('_')
|
.sort()
|
||||||
|
.join('_'),
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +51,12 @@ export class BelongsToManyField extends RelationField {
|
|||||||
if (!this.options.sourceKey) {
|
if (!this.options.sourceKey) {
|
||||||
this.options.sourceKey = association.sourceKey;
|
this.options.sourceKey = association.sourceKey;
|
||||||
}
|
}
|
||||||
|
if (!this.options.otherKey) {
|
||||||
|
this.options.otherKey = association.otherKey;
|
||||||
|
}
|
||||||
|
if (!this.options.through) {
|
||||||
|
this.options.through = this.through;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { mockServer } from '@nocobase/test';
|
|
||||||
import PluginUiSchema from '@nocobase/plugin-ui-schema-storage';
|
|
||||||
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
||||||
|
import PluginUiSchema from '@nocobase/plugin-ui-schema-storage';
|
||||||
|
import { mockServer } from '@nocobase/test';
|
||||||
import PluginACL from '../server';
|
import PluginACL from '../server';
|
||||||
|
|
||||||
let mockRole: string = 'admin';
|
let mockRole: string = 'admin';
|
||||||
@ -33,5 +33,7 @@ export async function prepareApp() {
|
|||||||
app.plugin(PluginACL);
|
app.plugin(PluginACL);
|
||||||
await app.loadAndInstall();
|
await app.loadAndInstall();
|
||||||
|
|
||||||
|
await app.db.sync();
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { MockServer } from '@nocobase/test';
|
|
||||||
import { Database, Model } from '@nocobase/database';
|
import { Database, Model } from '@nocobase/database';
|
||||||
import { prepareApp } from './prepare';
|
|
||||||
import { CollectionRepository } from '@nocobase/plugin-collection-manager';
|
import { CollectionRepository } from '@nocobase/plugin-collection-manager';
|
||||||
|
import { MockServer } from '@nocobase/test';
|
||||||
|
import { prepareApp } from './prepare';
|
||||||
|
|
||||||
describe('role resource api', () => {
|
describe('role resource api', () => {
|
||||||
let app: MockServer;
|
let app: MockServer;
|
||||||
@ -54,6 +54,9 @@ describe('role resource api', () => {
|
|||||||
.agent()
|
.agent()
|
||||||
.resource('roles.collections', 'admin')
|
.resource('roles.collections', 'admin')
|
||||||
.list({
|
.list({
|
||||||
|
filter: {
|
||||||
|
$or: [{ name: 'c1' }, { name: 'c2' }],
|
||||||
|
},
|
||||||
sort: ['sort'],
|
sort: ['sort'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ const roleCollectionsResource = {
|
|||||||
const collectionRepository = db.getRepository('collections');
|
const collectionRepository = db.getRepository('collections');
|
||||||
|
|
||||||
// all collections
|
// all collections
|
||||||
const collections = await collectionRepository.find();
|
const collections = await collectionRepository.find({
|
||||||
|
filter: ctx.action.params.filter,
|
||||||
|
});
|
||||||
|
|
||||||
// role collections
|
// role collections
|
||||||
const roleResources = await db.getRepository('rolesResources').find({
|
const roleResources = await db.getRepository('rolesResources').find({
|
||||||
|
@ -2,6 +2,7 @@ import { CollectionOptions } from '@nocobase/database';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'roles',
|
name: 'roles',
|
||||||
|
title: '{{t("Roles")}}',
|
||||||
autoGenId: false,
|
autoGenId: false,
|
||||||
model: 'RoleModel',
|
model: 'RoleModel',
|
||||||
fields: [
|
fields: [
|
||||||
@ -10,11 +11,21 @@ export default {
|
|||||||
name: 'name',
|
name: 'name',
|
||||||
prefix: 'r_',
|
prefix: 'r_',
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
|
uiSchema: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Role UID")}}',
|
||||||
|
'x-component': 'Input',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
name: 'title',
|
name: 'title',
|
||||||
unique: true,
|
unique: true,
|
||||||
|
uiSchema: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Role name")}}',
|
||||||
|
'x-component': 'Input',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
@ -45,6 +56,7 @@ export default {
|
|||||||
type: 'belongsToMany',
|
type: 'belongsToMany',
|
||||||
name: 'menuUiSchemas',
|
name: 'menuUiSchemas',
|
||||||
target: 'uiSchemas',
|
target: 'uiSchemas',
|
||||||
|
targetKey: 'x-uid',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
|
@ -259,6 +259,13 @@ export class PluginACL extends Plugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async install() {
|
||||||
|
const repo = this.db.getRepository<any>('collections');
|
||||||
|
if (repo) {
|
||||||
|
await repo.db2cm('roles');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
await this.app.db.import({
|
await this.app.db.import({
|
||||||
directory: resolve(__dirname, 'collections'),
|
directory: resolve(__dirname, 'collections'),
|
||||||
|
@ -14,4 +14,22 @@ export class CollectionRepository extends Repository {
|
|||||||
await instance.load({ skipExist });
|
await instance.load({ skipExist });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async db2cm(collectionName: string) {
|
||||||
|
const collection = this.database.getCollection(collectionName);
|
||||||
|
const options = collection.options;
|
||||||
|
const fields = [];
|
||||||
|
for (const [name, field] of collection.fields) {
|
||||||
|
fields.push({
|
||||||
|
name,
|
||||||
|
...field.options,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await this.create({
|
||||||
|
values: {
|
||||||
|
...options,
|
||||||
|
fields,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ export default {
|
|||||||
sortable: 'sort',
|
sortable: 'sort',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
interface: 'string',
|
interface: 'input',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
name: 'nickname',
|
name: 'nickname',
|
||||||
uiSchema: {
|
uiSchema: {
|
||||||
@ -47,10 +47,11 @@ export default {
|
|||||||
otherKey: 'roleName',
|
otherKey: 'roleName',
|
||||||
sourceKey: 'id',
|
sourceKey: 'id',
|
||||||
targetKey: 'name',
|
targetKey: 'name',
|
||||||
|
through: 'rolesUsers',
|
||||||
uiSchema: {
|
uiSchema: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
title: '{{t("Roles")}}',
|
title: '{{t("Roles")}}',
|
||||||
'x-component': 'Select.Drawer',
|
'x-component': 'RecordPicker',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
multiple: true,
|
multiple: true,
|
||||||
fieldNames: {
|
fieldNames: {
|
||||||
@ -58,12 +59,9 @@ export default {
|
|||||||
value: 'name',
|
value: 'name',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-designable-bar': 'Select.Drawer.DesignableBar',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
interface: 'select',
|
|
||||||
type: 'string',
|
type: 'string',
|
||||||
name: 'appLang',
|
name: 'appLang',
|
||||||
},
|
},
|
||||||
|
@ -83,5 +83,9 @@ export default class UsersPlugin extends Plugin {
|
|||||||
roles: ['admin'],
|
roles: ['admin'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const repo = this.db.getRepository<any>('collections');
|
||||||
|
if (repo) {
|
||||||
|
await repo.db2cm('users');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user