fix: postgres sort with appends issue (#198)
* fix: postgres sort with appends issue * fix: role menus api error * feat: add exists params in roles.collections api * refactor: remove uid field on uiSchemas table * test: toggle role menus * fix: plugin-acl test * feat: sync data to acl before app start * fix: mysql ui-schema sql compatibility * feat: writeRolesToACL in plugin-acl
This commit is contained in:
parent
7be30b5b95
commit
000587380b
@ -8,7 +8,7 @@ import {
|
|||||||
} from './multiple-relation-repository';
|
} from './multiple-relation-repository';
|
||||||
import { CreateOptions, DestroyOptions, FindOptions, TK, TargetKey, UpdateOptions } from '../repository';
|
import { CreateOptions, DestroyOptions, FindOptions, TK, TargetKey, UpdateOptions } from '../repository';
|
||||||
import { transaction } from './relation-repository';
|
import { transaction } from './relation-repository';
|
||||||
import lodash from 'lodash';
|
import lodash, { omit } from 'lodash';
|
||||||
|
|
||||||
interface IHasManyRepository<M extends Model> {
|
interface IHasManyRepository<M extends Model> {
|
||||||
find(options?: FindOptions): Promise<M>;
|
find(options?: FindOptions): Promise<M>;
|
||||||
@ -29,6 +29,25 @@ interface IHasManyRepository<M extends Model> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class HasManyRepository extends MultipleRelationRepository implements IHasManyRepository<any> {
|
export class HasManyRepository extends MultipleRelationRepository implements IHasManyRepository<any> {
|
||||||
|
async find(options?: FindOptions): Promise<any> {
|
||||||
|
const targetRepository = this.targetCollection.repository;
|
||||||
|
|
||||||
|
const addFilter = {
|
||||||
|
[this.association.foreignKey]: this.sourceKeyValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options?.filterByTk) {
|
||||||
|
addFilter[this.associationField.targetKey] = options.filterByTk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await targetRepository.find({
|
||||||
|
...omit(options, ['filterByTk']),
|
||||||
|
filter: {
|
||||||
|
$and: [options.filter || {}, addFilter],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@transaction((args, transaction) => {
|
@transaction((args, transaction) => {
|
||||||
return {
|
return {
|
||||||
filterByTk: args[0],
|
filterByTk: args[0],
|
||||||
|
@ -44,7 +44,7 @@ export abstract class MultipleRelationRepository extends RelationRepository {
|
|||||||
if (findOptions.include && findOptions.include.length > 0) {
|
if (findOptions.include && findOptions.include.length > 0) {
|
||||||
const ids = (
|
const ids = (
|
||||||
await sourceModel[getAccessor]({
|
await sourceModel[getAccessor]({
|
||||||
...findOptions,
|
...omit(findOptions, 'order'),
|
||||||
includeIgnoreAttributes: false,
|
includeIgnoreAttributes: false,
|
||||||
attributes: [this.targetKey()],
|
attributes: [this.targetKey()],
|
||||||
group: `${this.targetModel.name}.${this.targetKey()}`,
|
group: `${this.targetModel.name}.${this.targetKey()}`,
|
||||||
|
@ -207,6 +207,7 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|||||||
async find(options?: FindOptions) {
|
async find(options?: FindOptions) {
|
||||||
const model = this.collection.model;
|
const model = this.collection.model;
|
||||||
const transaction = await this.getTransaction(options);
|
const transaction = await this.getTransaction(options);
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
subQuery: false,
|
subQuery: false,
|
||||||
...this.buildQueryOptions(options),
|
...this.buildQueryOptions(options),
|
||||||
@ -215,6 +216,7 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|||||||
if (opts.include && opts.include.length > 0) {
|
if (opts.include && opts.include.length > 0) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const primaryKeyField = model.primaryKeyField || model.primaryKeyAttribute;
|
const primaryKeyField = model.primaryKeyField || model.primaryKeyAttribute;
|
||||||
|
|
||||||
const ids = (
|
const ids = (
|
||||||
await model.findAll({
|
await model.findAll({
|
||||||
...opts,
|
...opts,
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { ACL } from '@nocobase/acl';
|
import { ACL } from '@nocobase/acl';
|
||||||
import { Database } from '@nocobase/database';
|
import { Database } from '@nocobase/database';
|
||||||
import { MockServer } from '@nocobase/test';
|
import { MockServer } from '@nocobase/test';
|
||||||
import { prepareApp } from './prepare';
|
import { changeMockRole, prepareApp } from './prepare';
|
||||||
|
import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
|
||||||
|
|
||||||
describe('acl', () => {
|
describe('acl', () => {
|
||||||
let app: MockServer;
|
let app: MockServer;
|
||||||
let db: Database;
|
let db: Database;
|
||||||
let acl: ACL;
|
let acl: ACL;
|
||||||
|
|
||||||
|
let uiSchemaRepository: UiSchemaRepository;
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await app.destroy();
|
await app.destroy();
|
||||||
});
|
});
|
||||||
@ -16,6 +19,8 @@ describe('acl', () => {
|
|||||||
app = await prepareApp();
|
app = await prepareApp();
|
||||||
db = app.db;
|
db = app.db;
|
||||||
acl = app.acl;
|
acl = app.acl;
|
||||||
|
|
||||||
|
uiSchemaRepository = db.getRepository('uiSchemas');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should works with universal actions', async () => {
|
it('should works with universal actions', async () => {
|
||||||
@ -68,20 +73,20 @@ describe('acl', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should works with resources actions', async () => {
|
it('should works with resources actions', async () => {
|
||||||
await db.getRepository('roles').create({
|
const role = await db.getRepository('roles').create({
|
||||||
values: {
|
values: {
|
||||||
name: 'admin',
|
name: 'admin',
|
||||||
title: 'Admin User',
|
title: 'Admin User',
|
||||||
allowConfigure: true,
|
allowConfigure: true,
|
||||||
|
strategy: {
|
||||||
|
actions: ['list'],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const role = await db.getRepository('roles').findOne({
|
changeMockRole('admin');
|
||||||
filter: {
|
|
||||||
name: 'admin',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// create c1 collection
|
||||||
await db.getRepository('collections').create({
|
await db.getRepository('collections').create({
|
||||||
values: {
|
values: {
|
||||||
name: 'c1',
|
name: 'c1',
|
||||||
@ -89,6 +94,7 @@ describe('acl', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// create c2 collection
|
||||||
await db.getRepository('collections').create({
|
await db.getRepository('collections').create({
|
||||||
values: {
|
values: {
|
||||||
name: 'c2',
|
name: 'c2',
|
||||||
@ -96,6 +102,7 @@ describe('acl', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// create c1 published scope
|
||||||
await app
|
await app
|
||||||
.agent()
|
.agent()
|
||||||
.resource('rolesResourcesScopes')
|
.resource('rolesResourcesScopes')
|
||||||
@ -111,11 +118,11 @@ describe('acl', () => {
|
|||||||
|
|
||||||
const publishedScope = await db.getRepository('rolesResourcesScopes').findOne();
|
const publishedScope = await db.getRepository('rolesResourcesScopes').findOne();
|
||||||
|
|
||||||
|
// set admin resources
|
||||||
await app
|
await app
|
||||||
.agent()
|
.agent()
|
||||||
.resource('roles.resources')
|
.resource('roles.resources', 'admin')
|
||||||
.create({
|
.create({
|
||||||
associatedIndex: role.get('name') as string,
|
|
||||||
values: {
|
values: {
|
||||||
name: 'c1',
|
name: 'c1',
|
||||||
usingActionsConfig: true,
|
usingActionsConfig: true,
|
||||||
@ -170,11 +177,11 @@ describe('acl', () => {
|
|||||||
appends: ['actions'],
|
appends: ['actions'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toEqual(200);
|
||||||
|
|
||||||
const actions = response.body.data[0].actions;
|
const actions = response.body.data[0].actions;
|
||||||
const collectionName = response.body.data[0].name;
|
const collectionName = response.body.data[0].name;
|
||||||
|
|
||||||
const viewActionId = actions.find((action) => action.name === 'view').id;
|
|
||||||
|
|
||||||
await app
|
await app
|
||||||
.agent()
|
.agent()
|
||||||
.resource('roles.resources', role.get('name'))
|
.resource('roles.resources', role.get('name'))
|
||||||
@ -185,7 +192,6 @@ describe('acl', () => {
|
|||||||
usingActionsConfig: true,
|
usingActionsConfig: true,
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
id: viewActionId,
|
|
||||||
name: 'view',
|
name: 'view',
|
||||||
fields: ['title', 'age'],
|
fields: ['title', 'age'],
|
||||||
},
|
},
|
||||||
@ -434,4 +440,94 @@ describe('acl', () => {
|
|||||||
|
|
||||||
expect(newAllowFields.includes('description')).toBeTruthy();
|
expect(newAllowFields.includes('description')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get role menus', async () => {
|
||||||
|
const role = await db.getRepository('roles').create({
|
||||||
|
values: {
|
||||||
|
name: 'admin',
|
||||||
|
title: 'Admin User',
|
||||||
|
allowConfigure: true,
|
||||||
|
strategy: {
|
||||||
|
actions: ['view'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
changeMockRole('admin');
|
||||||
|
|
||||||
|
const menuResponse = await app.agent().resource('roles.menuUiSchemas', 'admin').list();
|
||||||
|
|
||||||
|
expect(menuResponse.statusCode).toEqual(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should toggle role menus', async () => {
|
||||||
|
const role = await db.getRepository('roles').create({
|
||||||
|
values: {
|
||||||
|
name: 'admin',
|
||||||
|
title: 'Admin User',
|
||||||
|
allowConfigure: true,
|
||||||
|
strategy: {
|
||||||
|
actions: ['*'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
changeMockRole('admin');
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
'x-uid': 'test',
|
||||||
|
};
|
||||||
|
|
||||||
|
await uiSchemaRepository.insert(schema);
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.agent()
|
||||||
|
.resource('roles.menuUiSchemas', 'admin')
|
||||||
|
.toggle({
|
||||||
|
values: { tk: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toEqual(200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sync data to acl before app start', async () => {
|
||||||
|
const role = await db.getRepository('roles').create({
|
||||||
|
values: {
|
||||||
|
name: 'admin',
|
||||||
|
title: 'Admin User',
|
||||||
|
allowConfigure: true,
|
||||||
|
resources: [
|
||||||
|
{
|
||||||
|
name: 'posts',
|
||||||
|
usingActionsConfig: true,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
name: 'view',
|
||||||
|
fields: ['title'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hooks: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(acl.getRole('admin')).toBeUndefined();
|
||||||
|
|
||||||
|
await app.start();
|
||||||
|
|
||||||
|
expect(acl.getRole('admin')).toBeDefined();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
acl.can({
|
||||||
|
role: 'admin',
|
||||||
|
resource: 'posts',
|
||||||
|
action: 'view',
|
||||||
|
}),
|
||||||
|
).toMatchObject({
|
||||||
|
role: 'admin',
|
||||||
|
resource: 'posts',
|
||||||
|
action: 'view',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -52,9 +52,8 @@ describe('role resource api', () => {
|
|||||||
// get collections list
|
// get collections list
|
||||||
let response = await app
|
let response = await app
|
||||||
.agent()
|
.agent()
|
||||||
.resource('roles.collections')
|
.resource('roles.collections', 'admin')
|
||||||
.list({
|
.list({
|
||||||
associatedIndex: role.get('name') as string,
|
|
||||||
sort: ['sort'],
|
sort: ['sort'],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,20 +64,21 @@ describe('role resource api', () => {
|
|||||||
name: 'c1',
|
name: 'c1',
|
||||||
title: 'table1',
|
title: 'table1',
|
||||||
usingConfig: 'strategy',
|
usingConfig: 'strategy',
|
||||||
|
exists: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'c2',
|
name: 'c2',
|
||||||
title: 'table2',
|
title: 'table2',
|
||||||
usingConfig: 'strategy',
|
usingConfig: 'strategy',
|
||||||
|
exists: false,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// set resource actions
|
// set resource actions
|
||||||
response = await app
|
response = await app
|
||||||
.agent()
|
.agent()
|
||||||
.resource('roles.resources')
|
.resource('roles.resources', 'admin')
|
||||||
.create({
|
.create({
|
||||||
associatedIndex: role.get('name') as string,
|
|
||||||
values: {
|
values: {
|
||||||
name: 'c1',
|
name: 'c1',
|
||||||
usingActionsConfig: true,
|
usingActionsConfig: true,
|
||||||
|
@ -10,20 +10,28 @@ const roleCollectionsResource = {
|
|||||||
|
|
||||||
const db: Database = ctx.db;
|
const db: Database = ctx.db;
|
||||||
const collectionRepository = db.getRepository('collections');
|
const collectionRepository = db.getRepository('collections');
|
||||||
|
|
||||||
|
// all collections
|
||||||
const collections = await collectionRepository.find();
|
const collections = await collectionRepository.find();
|
||||||
|
|
||||||
|
// role collections
|
||||||
const roleResources = await db.getRepository('rolesResources').find({
|
const roleResources = await db.getRepository('rolesResources').find({
|
||||||
filter: {
|
filter: {
|
||||||
roleName: role,
|
roleName: role,
|
||||||
usingActionsConfig: true,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// role collections
|
||||||
const roleResourcesNames = roleResources.map((roleResource) => roleResource.get('name'));
|
const roleResourcesNames = roleResources.map((roleResource) => roleResource.get('name'));
|
||||||
|
const roleResourceActionResourceNames = roleResources
|
||||||
|
.filter((roleResources) => roleResources.get('usingActionsConfig'))
|
||||||
|
.map((roleResources) => roleResources.get('name'));
|
||||||
|
|
||||||
ctx.body = collections
|
ctx.body = collections
|
||||||
.map((collection) => {
|
.map((collection) => {
|
||||||
const usingConfig: UsingConfigType = roleResourcesNames.includes(collection.get('name'))
|
const exists = roleResourcesNames.includes(collection.get('name'));
|
||||||
|
|
||||||
|
const usingConfig: UsingConfigType = roleResourceActionResourceNames.includes(collection.get('name'))
|
||||||
? 'resourceAction'
|
? 'resourceAction'
|
||||||
: 'strategy';
|
: 'strategy';
|
||||||
|
|
||||||
@ -32,6 +40,7 @@ const roleCollectionsResource = {
|
|||||||
title: collection.get('title') as string,
|
title: collection.get('title') as string,
|
||||||
roleName: role,
|
roleName: role,
|
||||||
usingConfig,
|
usingConfig,
|
||||||
|
exists,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => (a.name > b.name ? 1 : -1));
|
.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||||
|
@ -3,6 +3,7 @@ import { CollectionOptions } from '@nocobase/database';
|
|||||||
export default {
|
export default {
|
||||||
name: 'roles',
|
name: 'roles',
|
||||||
autoGenId: false,
|
autoGenId: false,
|
||||||
|
model: 'RoleModel',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
type: 'uid',
|
type: 'uid',
|
||||||
@ -44,7 +45,6 @@ export default {
|
|||||||
type: 'belongsToMany',
|
type: 'belongsToMany',
|
||||||
name: 'menuUiSchemas',
|
name: 'menuUiSchemas',
|
||||||
target: 'uiSchemas',
|
target: 'uiSchemas',
|
||||||
targetKey: 'uid',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
|
21
packages/plugin-acl/src/model/RoleModel.ts
Normal file
21
packages/plugin-acl/src/model/RoleModel.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Model } from '@nocobase/database';
|
||||||
|
import { ACL } from '@nocobase/acl';
|
||||||
|
|
||||||
|
export class RoleModel extends Model {
|
||||||
|
writeToAcl(options: { acl: ACL }) {
|
||||||
|
const { acl } = options;
|
||||||
|
const roleName = this.get('name') as string;
|
||||||
|
let role = acl.getRole(roleName);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
role = acl.define({
|
||||||
|
role: roleName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
role.setStrategy({
|
||||||
|
...((this.get('strategy') as object) || {}),
|
||||||
|
allowConfigure: this.get('allowConfigure') as boolean,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { availableActionResource } from './actions/available-actions';
|
|||||||
import { roleCollectionsResource } from './actions/role-collections';
|
import { roleCollectionsResource } from './actions/role-collections';
|
||||||
import { RoleResourceActionModel } from './model/RoleResourceActionModel';
|
import { RoleResourceActionModel } from './model/RoleResourceActionModel';
|
||||||
import { RoleResourceModel } from './model/RoleResourceModel';
|
import { RoleResourceModel } from './model/RoleResourceModel';
|
||||||
|
import { RoleModel } from './model/RoleModel';
|
||||||
|
|
||||||
export interface AssociationFieldAction {
|
export interface AssociationFieldAction {
|
||||||
associationActions: string[];
|
associationActions: string[];
|
||||||
@ -26,7 +27,6 @@ export class GrantHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PluginACL extends Plugin {
|
export class PluginACL extends Plugin {
|
||||||
|
|
||||||
associationFieldsActions: AssociationFieldsActions = {};
|
associationFieldsActions: AssociationFieldsActions = {};
|
||||||
|
|
||||||
grantHelper = new GrantHelper();
|
grantHelper = new GrantHelper();
|
||||||
@ -100,11 +100,23 @@ export class PluginACL extends Plugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async beforeLoad() {
|
async writeRolesToACL() {
|
||||||
|
const roles = (await this.app.db.getRepository('roles').find({
|
||||||
|
appends: ['resources', 'resources.actions'],
|
||||||
|
})) as RoleModel[];
|
||||||
|
for (const role of roles) {
|
||||||
|
role.writeToAcl({ acl: this.acl });
|
||||||
|
for (const resource of role.get('resources') as RoleResourceModel[]) {
|
||||||
|
await this.writeResourceToACL(resource, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async beforeLoad() {
|
||||||
this.app.db.registerModels({
|
this.app.db.registerModels({
|
||||||
RoleResourceActionModel,
|
RoleResourceActionModel,
|
||||||
RoleResourceModel,
|
RoleResourceModel,
|
||||||
|
RoleModel,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.registerAssociationFieldsActions();
|
this.registerAssociationFieldsActions();
|
||||||
@ -114,18 +126,9 @@ export class PluginACL extends Plugin {
|
|||||||
|
|
||||||
this.app.db.on('roles.afterSave', async (model, options) => {
|
this.app.db.on('roles.afterSave', async (model, options) => {
|
||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
const roleName = model.get('name');
|
|
||||||
let role = this.acl.getRole(roleName);
|
|
||||||
|
|
||||||
if (!role) {
|
model.writeToAcl({
|
||||||
role = this.acl.define({
|
acl: this.acl,
|
||||||
role: model.get('name'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
role.setStrategy({
|
|
||||||
...(model.get('strategy') || {}),
|
|
||||||
allowConfigure: model.get('allowConfigure'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// model is default
|
// model is default
|
||||||
@ -229,6 +232,11 @@ export class PluginACL extends Plugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// sync database role data to acl
|
||||||
|
this.app.on('beforeStart', async () => {
|
||||||
|
await this.writeRolesToACL();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
import { Database } from '@nocobase/database';
|
||||||
|
import { mockServer, MockServer } from '@nocobase/test';
|
||||||
|
import CollectionManagerPlugin from '@nocobase/plugin-collection-manager';
|
||||||
|
import { UiSchemaStoragePlugin } from '@nocobase/plugin-ui-schema-storage';
|
||||||
|
|
||||||
|
describe('action test', () => {
|
||||||
|
let db: Database;
|
||||||
|
let app: MockServer;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
app = mockServer();
|
||||||
|
app.plugin(CollectionManagerPlugin);
|
||||||
|
app.plugin(UiSchemaStoragePlugin);
|
||||||
|
|
||||||
|
db = app.db;
|
||||||
|
await db.clean({ drop: true });
|
||||||
|
await app.loadAndInstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await app.destroy();
|
||||||
|
});
|
||||||
|
it('should append uiSchema', async () => {
|
||||||
|
await db.getRepository('collections').create({
|
||||||
|
values: {
|
||||||
|
name: 'posts',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.getRepository('fields').create({
|
||||||
|
values: {
|
||||||
|
name: 'title',
|
||||||
|
collectionName: 'posts',
|
||||||
|
type: 'string',
|
||||||
|
uiSchema: {
|
||||||
|
'x-uid': 'test',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
await db.getRepository('collections').load();
|
||||||
|
await db.sync();
|
||||||
|
|
||||||
|
const response = await app
|
||||||
|
.agent()
|
||||||
|
.resource('collections.fields', 'posts')
|
||||||
|
.list({
|
||||||
|
pageSize: 5,
|
||||||
|
appends: ['uiSchema'],
|
||||||
|
sort: ['sort'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response.statusCode).toEqual(200);
|
||||||
|
});
|
||||||
|
});
|
@ -70,7 +70,7 @@ describe('ui schema model', () => {
|
|||||||
properties: {
|
properties: {
|
||||||
child1: {
|
child1: {
|
||||||
title: 'child1',
|
title: 'child1',
|
||||||
'x-uid': child1.get('uid'),
|
'x-uid': child1.get('x-uid'),
|
||||||
'x-async': false,
|
'x-async': false,
|
||||||
'x-index': 1,
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
@ -129,7 +129,7 @@ describe('ui schema model', () => {
|
|||||||
properties: {
|
properties: {
|
||||||
child1: {
|
child1: {
|
||||||
title: 'new-child1-title',
|
title: 'new-child1-title',
|
||||||
'x-uid': child1.get('uid'),
|
'x-uid': child1.get('x-uid'),
|
||||||
'x-async': false,
|
'x-async': false,
|
||||||
'x-index': 1,
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
|
@ -56,7 +56,7 @@ describe('ui_schema repository', () => {
|
|||||||
// it should save in ui schema tables
|
// it should save in ui schema tables
|
||||||
const testNode = await repository.findOne({
|
const testNode = await repository.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
uid: 'test',
|
'x-uid': 'test',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -277,8 +277,8 @@ describe('ui_schema repository', () => {
|
|||||||
(
|
(
|
||||||
await treePathCollection.repository.findOne({
|
await treePathCollection.repository.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
ancestor: root.get('uid'),
|
ancestor: root.get('x-uid'),
|
||||||
descendant: a1.get('uid'),
|
descendant: a1.get('x-uid'),
|
||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -289,8 +289,8 @@ describe('ui_schema repository', () => {
|
|||||||
(
|
(
|
||||||
await treePathCollection.repository.findOne({
|
await treePathCollection.repository.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
ancestor: root.get('uid'),
|
ancestor: root.get('x-uid'),
|
||||||
descendant: b1.get('uid'),
|
descendant: b1.get('x-uid'),
|
||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -301,8 +301,8 @@ describe('ui_schema repository', () => {
|
|||||||
(
|
(
|
||||||
await treePathCollection.repository.findOne({
|
await treePathCollection.repository.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
ancestor: b1.get('uid'),
|
ancestor: b1.get('x-uid'),
|
||||||
descendant: c1.get('uid'),
|
descendant: c1.get('x-uid'),
|
||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -313,8 +313,8 @@ describe('ui_schema repository', () => {
|
|||||||
(
|
(
|
||||||
await treePathCollection.repository.findOne({
|
await treePathCollection.repository.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
ancestor: b1.get('uid'),
|
ancestor: b1.get('x-uid'),
|
||||||
descendant: d1.get('uid'),
|
descendant: d1.get('x-uid'),
|
||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -330,7 +330,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = await repository.getJsonSchema(rootNode.get('uid') as string);
|
const results = await repository.getJsonSchema(rootNode.get('x-uid') as string);
|
||||||
|
|
||||||
expect(results).toMatchObject({
|
expect(results).toMatchObject({
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@ -375,7 +375,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = await repository.getProperties(rootNode.get('uid') as string);
|
const results = await repository.getProperties(rootNode.get('x-uid') as string);
|
||||||
|
|
||||||
expect(results).toMatchObject({
|
expect(results).toMatchObject({
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@ -468,7 +468,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
rootUid = rootNode.get('uid') as string;
|
rootUid = rootNode.get('x-uid') as string;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should insertAfterBegin', async () => {
|
it('should insertAfterBegin', async () => {
|
||||||
@ -506,7 +506,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await repository.insertBeforeBegin(b1Node.get('uid') as string, newNode);
|
await repository.insertBeforeBegin(b1Node.get('x-uid') as string, newNode);
|
||||||
|
|
||||||
const schema = await repository.getJsonSchema(rootUid);
|
const schema = await repository.getJsonSchema(rootUid);
|
||||||
expect(schema.properties['newNode']['x-index']).toEqual(2);
|
expect(schema.properties['newNode']['x-index']).toEqual(2);
|
||||||
@ -525,7 +525,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await repository.insertAfterEnd(a1Node.get('uid') as string, newNode);
|
await repository.insertAfterEnd(a1Node.get('x-uid') as string, newNode);
|
||||||
|
|
||||||
const schema = await repository.getJsonSchema(rootUid);
|
const schema = await repository.getJsonSchema(rootUid);
|
||||||
expect(schema.properties['newNode']['x-index']).toEqual(2);
|
expect(schema.properties['newNode']['x-index']).toEqual(2);
|
||||||
@ -544,7 +544,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await repository.insertAfterEnd(b1Node.get('uid') as string, newNode);
|
await repository.insertAfterEnd(b1Node.get('x-uid') as string, newNode);
|
||||||
|
|
||||||
const schema = await repository.getJsonSchema(rootUid);
|
const schema = await repository.getJsonSchema(rootUid);
|
||||||
expect(schema.properties['newNode']['x-index']).toEqual(3);
|
expect(schema.properties['newNode']['x-index']).toEqual(3);
|
||||||
@ -705,7 +705,7 @@ describe('ui_schema repository', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
rootUid = rootNode.get('uid') as string;
|
rootUid = rootNode.get('x-uid') as string;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should patch root ui schema', async () => {
|
it('should patch root ui schema', async () => {
|
||||||
@ -924,6 +924,7 @@ describe('ui_schema repository', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const A = await repository.getJsonSchema('A');
|
const A = await repository.getJsonSchema('A');
|
||||||
|
|
||||||
expect(A).toEqual({
|
expect(A).toEqual({
|
||||||
properties: {
|
properties: {
|
||||||
E: {
|
E: {
|
||||||
|
@ -12,13 +12,6 @@ export default {
|
|||||||
{
|
{
|
||||||
type: 'uid',
|
type: 'uid',
|
||||||
name: 'x-uid',
|
name: 'x-uid',
|
||||||
field: 'uid',
|
|
||||||
primaryKey: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'string',
|
|
||||||
name: 'uid',
|
|
||||||
field: 'uid',
|
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,14 @@ export class UiSchemaRepository extends Repository {
|
|||||||
return model.tableName;
|
return model.tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sqlAdapter(sql: string) {
|
||||||
|
if (this.database.sequelize.getDialect() === 'mysql') {
|
||||||
|
return lodash.replace(sql, /"/g, '`');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
static schemaToSingleNodes(schema: any, carry: SchemaNode[] = [], childOptions: ChildOptions = null): SchemaNode[] {
|
static schemaToSingleNodes(schema: any, carry: SchemaNode[] = [], childOptions: ChildOptions = null): SchemaNode[] {
|
||||||
const node = lodash.cloneDeep(
|
const node = lodash.cloneDeep(
|
||||||
lodash.isString(schema)
|
lodash.isString(schema)
|
||||||
@ -99,16 +107,16 @@ export class UiSchemaRepository extends Repository {
|
|||||||
const db = this.database;
|
const db = this.database;
|
||||||
|
|
||||||
const rawSql = `
|
const rawSql = `
|
||||||
SELECT SchemaTable.uid as uid, SchemaTable.name as name, SchemaTable.schema as "schema",
|
SELECT "SchemaTable"."x-uid" as "x-uid", "SchemaTable"."name" as "name", "SchemaTable"."schema" as "schema",
|
||||||
TreePath.depth as depth,
|
TreePath.depth as depth,
|
||||||
NodeInfo.type as type, NodeInfo.async as async, ParentPath.ancestor as parent, ParentPath.sort as sort
|
NodeInfo.type as type, NodeInfo.async as async, ParentPath.ancestor as parent, ParentPath.sort as sort
|
||||||
FROM ${this.uiSchemaTreePathTableName} as TreePath
|
FROM ${this.uiSchemaTreePathTableName} as TreePath
|
||||||
LEFT JOIN ${this.uiSchemasTableName} as SchemaTable ON SchemaTable.uid = TreePath.descendant
|
LEFT JOIN ${this.uiSchemasTableName} as "SchemaTable" ON "SchemaTable"."x-uid" = TreePath.descendant
|
||||||
LEFT JOIN ${this.uiSchemaTreePathTableName} as NodeInfo ON NodeInfo.descendant = SchemaTable.uid and NodeInfo.descendant = NodeInfo.ancestor and NodeInfo.depth = 0
|
LEFT JOIN ${this.uiSchemaTreePathTableName} as NodeInfo ON NodeInfo.descendant = "SchemaTable"."x-uid" and NodeInfo.descendant = NodeInfo.ancestor and NodeInfo.depth = 0
|
||||||
LEFT JOIN ${this.uiSchemaTreePathTableName} as ParentPath ON (ParentPath.descendant = SchemaTable.uid AND ParentPath.depth = 1)
|
LEFT JOIN ${this.uiSchemaTreePathTableName} as ParentPath ON (ParentPath.descendant = "SchemaTable"."x-uid" AND ParentPath.depth = 1)
|
||||||
WHERE TreePath.ancestor = :ancestor AND (NodeInfo.async = false or TreePath.depth = 1)`;
|
WHERE TreePath.ancestor = :ancestor AND (NodeInfo.async = false or TreePath.depth = 1)`;
|
||||||
|
|
||||||
const nodes = await db.sequelize.query(rawSql, {
|
const nodes = await db.sequelize.query(this.sqlAdapter(rawSql), {
|
||||||
replacements: {
|
replacements: {
|
||||||
ancestor: uid,
|
ancestor: uid,
|
||||||
},
|
},
|
||||||
@ -128,17 +136,17 @@ export class UiSchemaRepository extends Repository {
|
|||||||
const treeTable = this.uiSchemaTreePathTableName;
|
const treeTable = this.uiSchemaTreePathTableName;
|
||||||
|
|
||||||
const rawSql = `
|
const rawSql = `
|
||||||
SELECT SchemaTable.uid as uid, SchemaTable.name as name, SchemaTable.schema as "schema" ,
|
SELECT "SchemaTable"."x-uid" as "x-uid", "SchemaTable"."name" as name, "SchemaTable"."schema" as "schema" ,
|
||||||
TreePath.depth as depth,
|
TreePath.depth as depth,
|
||||||
NodeInfo.type as type, NodeInfo.async as async, ParentPath.ancestor as parent, ParentPath.sort as sort
|
NodeInfo.type as type, NodeInfo.async as async, ParentPath.ancestor as parent, ParentPath.sort as sort
|
||||||
FROM ${treeTable} as TreePath
|
FROM ${treeTable} as TreePath
|
||||||
LEFT JOIN ${this.uiSchemasTableName} as SchemaTable ON SchemaTable.uid = TreePath.descendant
|
LEFT JOIN ${this.uiSchemasTableName} as "SchemaTable" ON "SchemaTable"."x-uid" = TreePath.descendant
|
||||||
LEFT JOIN ${treeTable} as NodeInfo ON NodeInfo.descendant = SchemaTable.uid and NodeInfo.descendant = NodeInfo.ancestor and NodeInfo.depth = 0
|
LEFT JOIN ${treeTable} as NodeInfo ON NodeInfo.descendant = "SchemaTable"."x-uid" and NodeInfo.descendant = NodeInfo.ancestor and NodeInfo.depth = 0
|
||||||
LEFT JOIN ${treeTable} as ParentPath ON (ParentPath.descendant = SchemaTable.uid AND ParentPath.depth = 1)
|
LEFT JOIN ${treeTable} as ParentPath ON (ParentPath.descendant = "SchemaTable"."x-uid" AND ParentPath.depth = 1)
|
||||||
WHERE TreePath.ancestor = :ancestor ${options?.includeAsyncNode ? '' : 'AND (NodeInfo.async != true )'}
|
WHERE TreePath.ancestor = :ancestor ${options?.includeAsyncNode ? '' : 'AND (NodeInfo.async != true )'}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const nodes = await db.sequelize.query(rawSql, {
|
const nodes = await db.sequelize.query(this.sqlAdapter(rawSql), {
|
||||||
replacements: {
|
replacements: {
|
||||||
ancestor: uid,
|
ancestor: uid,
|
||||||
},
|
},
|
||||||
@ -158,7 +166,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
const schema = {
|
const schema = {
|
||||||
...(lodash.isPlainObject(node.schema) ? node.schema : JSON.parse(node.schema)),
|
...(lodash.isPlainObject(node.schema) ? node.schema : JSON.parse(node.schema)),
|
||||||
...lodash.pick(node, [...nodeKeys, 'name']),
|
...lodash.pick(node, [...nodeKeys, 'name']),
|
||||||
['x-uid']: node.uid,
|
['x-uid']: node['x-uid'],
|
||||||
['x-async']: !!node.async,
|
['x-async']: !!node.async,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -170,7 +178,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const buildTree = (rootNode) => {
|
const buildTree = (rootNode) => {
|
||||||
const children = nodes.filter((node) => node.parent == rootNode.uid);
|
const children = nodes.filter((node) => node.parent == rootNode['x-uid']);
|
||||||
|
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
const childrenGroupByType = lodash.groupBy(children, 'type');
|
const childrenGroupByType = lodash.groupBy(children, 'type');
|
||||||
@ -196,7 +204,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
return nodeAttributeSanitize(rootNode);
|
return nodeAttributeSanitize(rootNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
return buildTree(nodes.find((node) => node.uid == rootUid));
|
return buildTree(nodes.find((node) => node['x-uid'] == rootUid));
|
||||||
}
|
}
|
||||||
|
|
||||||
treeCollection() {
|
treeCollection() {
|
||||||
@ -244,7 +252,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
async updateNode(uid: string, schema: any, transaction?: Transaction) {
|
async updateNode(uid: string, schema: any, transaction?: Transaction) {
|
||||||
const nodeModel = await this.findOne({
|
const nodeModel = await this.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
uid,
|
'x-uid': uid,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -299,7 +307,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
protected async findNodeSchemaWithParent(uid, transaction) {
|
protected async findNodeSchemaWithParent(uid, transaction) {
|
||||||
const schema = await this.database.getRepository('uiSchemas').findOne({
|
const schema = await this.database.getRepository('uiSchemas').findOne({
|
||||||
filter: {
|
filter: {
|
||||||
uid,
|
'x-uid': uid,
|
||||||
},
|
},
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
@ -324,7 +332,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
if (parentChildrenCount == 1) {
|
if (parentChildrenCount == 1) {
|
||||||
const schema = await db.getRepository('uiSchemas').findOne({
|
const schema = await db.getRepository('uiSchemas').findOne({
|
||||||
filter: {
|
filter: {
|
||||||
uid: parent,
|
'x-uid': parent,
|
||||||
},
|
},
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
@ -342,7 +350,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
const parent = await this.isSingleChild(nodeUid, transaction);
|
const parent = await this.isSingleChild(nodeUid, transaction);
|
||||||
|
|
||||||
if (parent && !this.breakOnMatched(parent, breakRemoveOn)) {
|
if (parent && !this.breakOnMatched(parent, breakRemoveOn)) {
|
||||||
await removeParent(parent.get('uid') as string);
|
await removeParent(parent.get('x-uid') as string);
|
||||||
} else {
|
} else {
|
||||||
await this.remove(nodeUid, { transaction });
|
await this.remove(nodeUid, { transaction });
|
||||||
}
|
}
|
||||||
@ -416,7 +424,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.database.sequelize.query(
|
await this.database.sequelize.query(
|
||||||
`DELETE FROM ${this.uiSchemasTableName} WHERE uid IN (
|
`DELETE FROM ${this.uiSchemasTableName} WHERE 'x-uid' IN (
|
||||||
SELECT descendant FROM ${treePathTable} WHERE ancestor = :uid
|
SELECT descendant FROM ${treePathTable} WHERE ancestor = :uid
|
||||||
)
|
)
|
||||||
`,
|
`,
|
||||||
@ -482,7 +490,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const insertedNodes = await this.insertNodes(nodes, options);
|
const insertedNodes = await this.insertNodes(nodes, options);
|
||||||
return await this.getJsonSchema(insertedNodes[0].get('uid'));
|
return await this.getJsonSchema(insertedNodes[0].get('x-uid'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async insertInner(targetUid: string, schema: any, position: 'first' | 'last', options?: InsertAdjacentOptions) {
|
async insertInner(targetUid: string, schema: any, position: 'first' | 'last', options?: InsertAdjacentOptions) {
|
||||||
@ -496,7 +504,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const insertedNodes = await this.insertNodes(nodes, options);
|
const insertedNodes = await this.insertNodes(nodes, options);
|
||||||
return await this.getJsonSchema(insertedNodes[0].get('uid'));
|
return await this.getJsonSchema(insertedNodes[0].get('x-uid'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async insertAdjacent(
|
async insertAdjacent(
|
||||||
@ -563,7 +571,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
async insert(schema: any, options?: TransactionAble) {
|
async insert(schema: any, options?: TransactionAble) {
|
||||||
const nodes = UiSchemaRepository.schemaToSingleNodes(schema);
|
const nodes = UiSchemaRepository.schemaToSingleNodes(schema);
|
||||||
const insertedNodes = await this.insertNodes(nodes, options);
|
const insertedNodes = await this.insertNodes(nodes, options);
|
||||||
return this.getJsonSchema(insertedNodes[0].get('uid'), {
|
return this.getJsonSchema(insertedNodes[0].get('x-uid'), {
|
||||||
transaction: options?.transaction,
|
transaction: options?.transaction,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -575,7 +583,6 @@ export class UiSchemaRepository extends Repository {
|
|||||||
values: {
|
values: {
|
||||||
name,
|
name,
|
||||||
['x-uid']: uid,
|
['x-uid']: uid,
|
||||||
uid,
|
|
||||||
schema,
|
schema,
|
||||||
serverHooks,
|
serverHooks,
|
||||||
},
|
},
|
||||||
@ -592,7 +599,6 @@ export class UiSchemaRepository extends Repository {
|
|||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
|
|
||||||
const db = this.database;
|
const db = this.database;
|
||||||
const treeCollection = db.getCollection('uiSchemaTreePath');
|
|
||||||
|
|
||||||
const uid = schema['x-uid'];
|
const uid = schema['x-uid'];
|
||||||
const name = schema['name'];
|
const name = schema['name'];
|
||||||
@ -609,7 +615,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
// check node exists or not
|
// check node exists or not
|
||||||
const existsNode = await this.findOne({
|
const existsNode = await this.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
uid,
|
'x-uid': uid,
|
||||||
},
|
},
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
@ -695,7 +701,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
type: 'INSERT',
|
type: 'INSERT',
|
||||||
transaction,
|
transaction,
|
||||||
replacements: {
|
replacements: {
|
||||||
modelKey: savedNode.get('uid'),
|
modelKey: savedNode.get('x-uid'),
|
||||||
modelParentKey: parentUid,
|
modelParentKey: parentUid,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -709,7 +715,7 @@ export class UiSchemaRepository extends Repository {
|
|||||||
{
|
{
|
||||||
type: 'INSERT',
|
type: 'INSERT',
|
||||||
replacements: {
|
replacements: {
|
||||||
modelKey: savedNode.get('uid'),
|
modelKey: savedNode.get('x-uid'),
|
||||||
type: childOptions.type,
|
type: childOptions.type,
|
||||||
async,
|
async,
|
||||||
},
|
},
|
||||||
@ -858,7 +864,7 @@ WHERE TreeTable.depth = 1 AND TreeTable.ancestor = :ancestor and TreeTable.sort
|
|||||||
{
|
{
|
||||||
type: 'INSERT',
|
type: 'INSERT',
|
||||||
replacements: {
|
replacements: {
|
||||||
modelKey: savedNode.get('uid'),
|
modelKey: savedNode.get('x-uid'),
|
||||||
async,
|
async,
|
||||||
},
|
},
|
||||||
transaction,
|
transaction,
|
||||||
|
@ -8,7 +8,7 @@ export async function bindMenuToRole({ schemaInstance, db, options }) {
|
|||||||
|
|
||||||
for (const role of addNewMenuRoles) {
|
for (const role of addNewMenuRoles) {
|
||||||
await db.getRepository('roles.menuUiSchemas', role.get('name')).add({
|
await db.getRepository('roles.menuUiSchemas', role.get('name')).add({
|
||||||
tk: schemaInstance.get('uid'),
|
tk: schemaInstance.get('x-uid'),
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { UiSchemaRepository } from '../../repository';
|
|||||||
export async function removeSchema({ schemaInstance, options, db, params }) {
|
export async function removeSchema({ schemaInstance, options, db, params }) {
|
||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
const uiSchemaRepository: UiSchemaRepository = db.getRepository('uiSchemas');
|
const uiSchemaRepository: UiSchemaRepository = db.getRepository('uiSchemas');
|
||||||
const uid = schemaInstance.get('uid') as string;
|
const uid = schemaInstance.get('x-uid') as string;
|
||||||
|
|
||||||
if (params?.removeParentsIfNoChildren) {
|
if (params?.removeParentsIfNoChildren) {
|
||||||
await uiSchemaRepository.removeEmptyParents({
|
await uiSchemaRepository.removeEmptyParents({
|
||||||
|
@ -27,7 +27,6 @@ export class UiSchemaStoragePlugin extends Plugin {
|
|||||||
this.registerRepository();
|
this.registerRepository();
|
||||||
|
|
||||||
db.on('uiSchemas.beforeCreate', function setUid(model) {
|
db.on('uiSchemas.beforeCreate', function setUid(model) {
|
||||||
model.set('uid', model.get('x-uid'));
|
|
||||||
if (!model.get('name')) {
|
if (!model.get('name')) {
|
||||||
model.set('name', uid());
|
model.set('name', uid());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user