mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 09:41:57 +00:00
fix: convertI18nObject
fix: initialChildren 传入 settingTopEntry 参数
This commit is contained in:
parent
4f16d363a8
commit
66d43f2103
@ -42,7 +42,7 @@
|
||||
"xima": "^0.2.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"tnpm": {
|
||||
"mode": "yarn",
|
||||
|
||||
@ -12,5 +12,6 @@ module.exports = {
|
||||
'no-prototype-builtins': 1,
|
||||
'no-useless-constructor': 1,
|
||||
'no-empty-function': 1,
|
||||
'@typescript-eslint/member-ordering': 0,
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
"plugins": [
|
||||
[
|
||||
"build-plugin-component"
|
||||
]
|
||||
],
|
||||
"./build.plugin.js"
|
||||
]
|
||||
}
|
||||
|
||||
7
packages/designer/build.plugin.js
Normal file
7
packages/designer/build.plugin.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = ({ onGetJestConfig }) => {
|
||||
// console.log('== test ==');
|
||||
onGetJestConfig((jestConfig) => {
|
||||
// console.log(jestConfig);
|
||||
return jestConfig;
|
||||
});
|
||||
};
|
||||
26
packages/designer/jest.config.js
Normal file
26
packages/designer/jest.config.js
Normal file
@ -0,0 +1,26 @@
|
||||
// jest.config.js
|
||||
const { pathsToModuleNameMapper } = require('ts-jest/utils');
|
||||
// In the following statement, replace `./tsconfig` with the path to your `tsconfig` file
|
||||
// which contains the path mapping (ie the `compilerOptions.paths` option):
|
||||
|
||||
const esModules = ['@recore/obx-react'].join('|');
|
||||
// console.log('>>> compilerOptions', compilerOptions);
|
||||
// console.log('>>> compilerOptions', pathsToModuleNameMapper(compilerOptions.paths));
|
||||
module.exports = {
|
||||
/* transform: {
|
||||
'^.+\\.[jt]sx?$': 'babel-jest',
|
||||
// '^.+\\.(ts|tsx)$': 'ts-jest',
|
||||
// '^.+\\.(js|jsx)$': 'babel-jest',
|
||||
}, */
|
||||
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
||||
transformIgnorePatterns: [
|
||||
`/node_modules/(?!${esModules})/`,
|
||||
],
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
||||
collectCoverage: false,
|
||||
collectCoverageFrom: [
|
||||
'src/**/*.{ts,tsx}',
|
||||
'!**/node_modules/**',
|
||||
'!**/vendor/**',
|
||||
],
|
||||
};
|
||||
@ -10,7 +10,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "build-scripts build --skip-demo",
|
||||
"test": "jest -c jest.config.js"
|
||||
"test": "build-scripts test"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@ -31,6 +31,10 @@ function combineTransducer(transducer, arr, context) {
|
||||
}
|
||||
|
||||
export class Transducer {
|
||||
setterTransducer: any;
|
||||
|
||||
context: any;
|
||||
|
||||
constructor(context, config) {
|
||||
let { setter } = config;
|
||||
|
||||
|
||||
@ -115,6 +115,7 @@ export class NodeChildren {
|
||||
}
|
||||
this.children.splice(i, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个节点
|
||||
*/
|
||||
@ -122,18 +123,21 @@ export class NodeChildren {
|
||||
if (node.isParental()) {
|
||||
foreachReverse(node.children, (subNode: Node) => {
|
||||
subNode.remove(useMutator, purge);
|
||||
});
|
||||
}, (iterable, idx) => (iterable as NodeChildren).get(idx));
|
||||
foreachReverse(node.slots, (slotNode: Node) => {
|
||||
slotNode.remove(useMutator, purge);
|
||||
}, (iterable, idx) => (iterable as [])[idx]);
|
||||
}
|
||||
if (purge) {
|
||||
// should set parent null
|
||||
node.internalSetParent(null, useMutator);
|
||||
try {
|
||||
node.purge(useMutator);
|
||||
node.purge();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
const document = node.document;
|
||||
const { document } = node;
|
||||
document.unlinkNode(node);
|
||||
document.selection.remove(node.id);
|
||||
document.destroyNode(node);
|
||||
|
||||
@ -162,18 +162,19 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this.props = new Props(this, {
|
||||
children: isDOMText(children) || isJSExpression(children) ? children : '',
|
||||
});
|
||||
this.settingEntry = this.document.designer.createSettingEntry([this]);
|
||||
} else {
|
||||
// 这里 props 被初始化两次,一次 new,一次 import,new 的实例需要给 propsReducer 的钩子去使用,
|
||||
// import 是为了使用钩子返回的值,并非完全幂等的操作,部分行为执行两次会有 bug,
|
||||
// 所以在 props 里会对 new / import 做一些区别化的解析
|
||||
this.props = new Props(this, props, extras);
|
||||
this.settingEntry = this.document.designer.createSettingEntry([this]);
|
||||
this._children = new NodeChildren(this as ParentalNode, this.initialChildren(children));
|
||||
this._children.internalInitParent();
|
||||
this.props.import(this.upgradeProps(this.initProps(props || {})), this.upgradeProps(extras || {}));
|
||||
this.setupAutoruns();
|
||||
}
|
||||
|
||||
this.settingEntry = this.document.designer.createSettingEntry([this]);
|
||||
this.emitter = new EventEmitter();
|
||||
}
|
||||
|
||||
@ -317,6 +318,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
if (this.parent) {
|
||||
if (this.isSlot()) {
|
||||
this.parent.removeSlot(this, purge);
|
||||
this.parent.children.delete(this, purge, useMutator);
|
||||
} else {
|
||||
this.parent.children.delete(this, purge, useMutator);
|
||||
}
|
||||
@ -677,13 +679,13 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
* 删除一个Slot节点
|
||||
*/
|
||||
removeSlot(slotNode: Node, purge = false): boolean {
|
||||
if (purge) {
|
||||
// should set parent null
|
||||
slotNode?.internalSetParent(null, false);
|
||||
slotNode?.purge();
|
||||
}
|
||||
this.document.unlinkNode(slotNode);
|
||||
this.document.selection.remove(slotNode.id);
|
||||
// if (purge) {
|
||||
// // should set parent null
|
||||
// slotNode?.internalSetParent(null, false);
|
||||
// slotNode?.purge();
|
||||
// }
|
||||
// this.document.unlinkNode(slotNode);
|
||||
// this.document.selection.remove(slotNode.id);
|
||||
const i = this._slots.indexOf(slotNode);
|
||||
if (i < 0) {
|
||||
return false;
|
||||
|
||||
@ -6,6 +6,7 @@ import { valueToSource } from './value-to-source';
|
||||
import { Props } from './props';
|
||||
import { SlotNode, Node } from '../node';
|
||||
import { TransformStage } from '../transform-stage';
|
||||
import { includesSlot } from '../../../utils/slot';
|
||||
|
||||
export const UNSET = Symbol.for('unset');
|
||||
export type UNSET = typeof UNSET;
|
||||
@ -231,7 +232,7 @@ export class Prop implements IPropParent {
|
||||
} else if (Array.isArray(val)) {
|
||||
this._type = 'list';
|
||||
} else if (isPlainObject(val)) {
|
||||
if (isJSSlot(val) && this.options.propsMode !== 'init') {
|
||||
if (isJSSlot(val) && this.options.skipSetSlot !== true) {
|
||||
this.setAsSlot(val);
|
||||
return;
|
||||
}
|
||||
@ -293,9 +294,11 @@ export class Prop implements IPropParent {
|
||||
this._slotNode.import(slotSchema);
|
||||
} else {
|
||||
const { owner } = this.props;
|
||||
this._slotNode = owner.document.createNode<SlotNode>(slotSchema);
|
||||
owner.addSlot(this._slotNode);
|
||||
this._slotNode.internalSetSlotFor(this);
|
||||
if (!includesSlot(owner, data.name)) {
|
||||
this._slotNode = owner.document.createNode<SlotNode>(slotSchema);
|
||||
owner.addSlot(this._slotNode);
|
||||
this._slotNode.internalSetSlotFor(this);
|
||||
}
|
||||
}
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
@ -59,9 +59,9 @@ export class Props implements IPropParent {
|
||||
constructor(readonly owner: Node, value?: PropsMap | PropsList | null, extras?: object) {
|
||||
if (Array.isArray(value)) {
|
||||
this.type = 'list';
|
||||
this.items = value.map(item => new Prop(this, item.value, item.name, item.spread, { propsMode: 'init' }));
|
||||
this.items = value.map(item => new Prop(this, item.value, item.name, item.spread, { skipSetSlot: true }));
|
||||
} else if (value != null) {
|
||||
this.items = Object.keys(value).map(key => new Prop(this, value[key], key, false, { propsMode: 'init' }));
|
||||
this.items = Object.keys(value).map(key => new Prop(this, value[key], key, false, { skipSetSlot: true }));
|
||||
}
|
||||
if (extras) {
|
||||
Object.keys(extras).forEach(key => {
|
||||
@ -241,8 +241,8 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 添加值
|
||||
*/
|
||||
add(value: CompositeValue | null, key?: string | number, spread = false): Prop {
|
||||
const prop = new Prop(this, value, key, spread);
|
||||
add(value: CompositeValue | null, key?: string | number, spread = false, options: any = {}): Prop {
|
||||
const prop = new Prop(this, value, key, spread, options);
|
||||
this.items.push(prop);
|
||||
return prop;
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ export class Project {
|
||||
}
|
||||
|
||||
createDocument(data?: RootSchema): DocumentModel {
|
||||
const doc = new DocumentModel(this, data);
|
||||
const doc = new DocumentModel(this, data || this?.data?.componentsTree?.[0]);
|
||||
this.documents.push(doc);
|
||||
this.documentsMap.set(doc.id, doc);
|
||||
return doc;
|
||||
|
||||
8
packages/designer/src/utils/slot.ts
Normal file
8
packages/designer/src/utils/slot.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Node } from '../document/node/node';
|
||||
|
||||
export function includesSlot(node: Node, slotName: string | undefined): boolean {
|
||||
const { slots = [] } = node;
|
||||
return slots.some(slot => {
|
||||
return slotName && slotName === slot?.getExtraProp('name')?.getAsString();
|
||||
});
|
||||
}
|
||||
@ -1,7 +1,14 @@
|
||||
import { NodeChildren } from '../document/node/node-children';
|
||||
|
||||
export function foreachReverse(arr: NodeChildren, fn: Function, context: any = {}) {
|
||||
type IterableArray = NodeChildren | any[];
|
||||
|
||||
export function foreachReverse(
|
||||
arr: IterableArray,
|
||||
action: (item: any) => void,
|
||||
getter: (arr: IterableArray, index: number) => any,
|
||||
context: any = {},
|
||||
) {
|
||||
for (let i = arr.length - 1; i >= 0; i--) {
|
||||
fn.call(context, arr.get(i));
|
||||
action.call(context, getter(arr, i));
|
||||
}
|
||||
}
|
||||
10
packages/designer/tests/__mocks__/document-model.ts
Normal file
10
packages/designer/tests/__mocks__/document-model.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export class DocumentModel {
|
||||
a = 1;
|
||||
c = {};
|
||||
constructor() {
|
||||
console.log('xxxxxxxxxxxxxxxxxxxx');
|
||||
const b = { x: { y: 2 } };
|
||||
const c: number = 2;
|
||||
this.a = b?.x?.y;
|
||||
}
|
||||
}
|
||||
9
packages/designer/tests/__mocks__/node.ts
Normal file
9
packages/designer/tests/__mocks__/node.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export class Node2 {
|
||||
a = 1;
|
||||
c = {};
|
||||
constructor() {
|
||||
const b = { x: { y: 2 } };
|
||||
const c: number = 2;
|
||||
this.a = b?.x?.y;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
import '../../fixtures/window';
|
||||
console.log('window.matchMedia', window.matchMedia);
|
||||
window.matchMedia('width=600px');
|
||||
import { DocumentModel } from '../../../src/document/document-model';
|
||||
// const { DocumentModel } = require('../../../src/document/document-model');
|
||||
// const { Node } = require('../__mocks__/node');
|
||||
|
||||
describe('basic utility', () => {
|
||||
test.only('delegateMethod - useOriginMethodName', () => {
|
||||
|
||||
const node = new DocumentModel({}, {
|
||||
componentName: 'Component',
|
||||
});
|
||||
console.log(node);
|
||||
expect(1).toBe(1);
|
||||
});
|
||||
});
|
||||
28
packages/designer/tests/document/document-model/node.test.ts
Normal file
28
packages/designer/tests/document/document-model/node.test.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import '../../fixtures/window';
|
||||
import { DocumentModel } from '../../../src/document/document-model';
|
||||
import { Node } from '../../../src/document/node/node';
|
||||
// import { Node2 } from './__mocks__/node';
|
||||
|
||||
jest.mock('../../../src/document/document-model', () => {
|
||||
return {
|
||||
DocumentModel: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
project: {
|
||||
designer: { createSettingEntry() {}, transformProps() {} },
|
||||
getSchema() {},
|
||||
},
|
||||
nextId() {},
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('basic utility', () => {
|
||||
test('delegateMethod - useOriginMethodName', () => {
|
||||
const dm = new DocumentModel({} as any, {} as any);
|
||||
console.log(dm.nextId);
|
||||
const node = new Node(dm, { componentName: 'Leaf' });
|
||||
console.log(node);
|
||||
expect(1).toBe(1);
|
||||
});
|
||||
});
|
||||
968
packages/designer/tests/fixtures/schema/form.js
vendored
Normal file
968
packages/designer/tests/fixtures/schema/form.js
vendored
Normal file
@ -0,0 +1,968 @@
|
||||
export default {
|
||||
componentName: 'Page',
|
||||
id: 'node_k1ow3cb9',
|
||||
props: {
|
||||
extensions: {
|
||||
启用页头: true,
|
||||
},
|
||||
pageStyle: {
|
||||
backgroundColor: '#f2f3f5',
|
||||
},
|
||||
containerStyle: {},
|
||||
className: 'page_kgaqfbm4',
|
||||
templateVersion: '1.0.0',
|
||||
},
|
||||
lifeCycles: {
|
||||
constructor: {
|
||||
type: 'js',
|
||||
compiled:
|
||||
"function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",
|
||||
source:
|
||||
"function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
css:
|
||||
'body{background-color:#f2f3f5}.card_kgaqfbm5 {\n margin-bottom: 12px;\n}.card_kgaqfbm6 {\n margin-bottom: 12px;\n}.button_kgaqfbm7 {\n margin-right: 16px;\n width: 80px\n}.button_kgaqfbm8 {\n width: 80px;\n}.div_kgaqfbm9 {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background: #fff;\n padding: 20px 0;\n}',
|
||||
methods: {
|
||||
__initMethods__: {
|
||||
type: 'js',
|
||||
source: 'function (exports, module) { /*set actions code here*/ }',
|
||||
compiled: 'function (exports, module) { /*set actions code here*/ }',
|
||||
},
|
||||
},
|
||||
dataSource: {
|
||||
offline: [],
|
||||
globalConfig: {
|
||||
fit: {
|
||||
compiled: '',
|
||||
source: '',
|
||||
type: 'js',
|
||||
error: {},
|
||||
},
|
||||
},
|
||||
online: [],
|
||||
sync: true,
|
||||
list: [],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
componentName: 'RootHeader',
|
||||
id: 'node_k1ow3cba',
|
||||
props: {},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'PageHeader',
|
||||
id: 'node_k1ow3cbd',
|
||||
props: {
|
||||
extraContent: '',
|
||||
__slot__extraContent: false,
|
||||
__slot__action: false,
|
||||
title: {
|
||||
// type: 'JSSlot',
|
||||
value: [
|
||||
{
|
||||
componentName: 'Text',
|
||||
id: 'node_k1ow3cbf',
|
||||
props: {
|
||||
showTitle: false,
|
||||
behavior: 'NORMAL',
|
||||
content: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'Title',
|
||||
zh_CN: '个人信息',
|
||||
type: 'i18n',
|
||||
},
|
||||
__style__: {},
|
||||
fieldId: 'text_k1ow3h1j',
|
||||
maxLine: 0,
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
content: '',
|
||||
__slot__logo: false,
|
||||
__slot__crumb: false,
|
||||
crumb: '',
|
||||
tab: '',
|
||||
logo: '',
|
||||
action: '',
|
||||
__slot__tab: false,
|
||||
__style__: {},
|
||||
__slot__content: false,
|
||||
fieldId: 'pageHeader_k1ow3h1i',
|
||||
subTitle: false,
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'RootContent',
|
||||
id: 'node_k1ow3cbb',
|
||||
props: {
|
||||
contentBgColor: 'transparent',
|
||||
contentPadding: '0',
|
||||
contentMargin: '20',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'Form',
|
||||
id: 'node_k1ow3cbq',
|
||||
props: {
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
autoValidate: true,
|
||||
scrollToFirstError: true,
|
||||
autoUnmount: true,
|
||||
behavior: 'NORMAL',
|
||||
dataSource: {
|
||||
type: 'variable',
|
||||
variable: 'state.formData',
|
||||
},
|
||||
__style__: {},
|
||||
fieldId: 'form',
|
||||
fieldOptions: {},
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'Card',
|
||||
id: 'node_k1ow3cbj',
|
||||
props: {
|
||||
__slot__title: false,
|
||||
subTitle: {
|
||||
use: 'zh_CN',
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
__slot__subTitle: false,
|
||||
extra: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
className: 'card_kgaqfbm5',
|
||||
title: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'Title',
|
||||
zh_CN: '基本信息',
|
||||
type: 'i18n',
|
||||
},
|
||||
__slot__extra: false,
|
||||
showHeadDivider: true,
|
||||
__style__: ':root {\n margin-bottom: 12px;\n}',
|
||||
showTitleBullet: true,
|
||||
contentHeight: '',
|
||||
fieldId: 'card_k1ow3h1l',
|
||||
dividerNoInset: false,
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'CardContent',
|
||||
id: 'node_k1ow3cbk',
|
||||
props: {},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'ColumnsLayout',
|
||||
id: 'node_k1ow3cbw',
|
||||
props: {
|
||||
layout: '6:6',
|
||||
columnGap: '20',
|
||||
rowGap: 0,
|
||||
__style__: {},
|
||||
fieldId: 'columns_k1ow3h1v',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'Column',
|
||||
id: 'node_k1ow3cbx',
|
||||
props: {
|
||||
colSpan: '',
|
||||
__style__: {},
|
||||
fieldId: 'column_k1p1bnjm',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cbz',
|
||||
props: {
|
||||
fieldName: 'name',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [
|
||||
{
|
||||
type: 'required',
|
||||
},
|
||||
],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h1w',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: '姓名',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cc1',
|
||||
props: {
|
||||
fieldName: 'englishName',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h1y',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: '英文名',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cc3',
|
||||
props: {
|
||||
fieldName: 'jobTitle',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h20',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: '职位',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'Column',
|
||||
id: 'node_k1ow3cby',
|
||||
props: {
|
||||
colSpan: '',
|
||||
__style__: {},
|
||||
fieldId: 'column_k1p1bnjn',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cc2',
|
||||
props: {
|
||||
fieldName: 'nickName',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h1z',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: '花名',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
componentName: 'SelectField',
|
||||
id: 'node_k1ow3cc0',
|
||||
props: {
|
||||
fieldName: 'gender',
|
||||
hasClear: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
mode: 'single',
|
||||
showSearch: false,
|
||||
autoWidth: true,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please select',
|
||||
zh_CN: '请选择',
|
||||
type: 'i18n',
|
||||
},
|
||||
hasBorder: true,
|
||||
behavior: 'NORMAL',
|
||||
value: '',
|
||||
validation: [
|
||||
{
|
||||
type: 'required',
|
||||
},
|
||||
],
|
||||
__style__: {},
|
||||
fieldId: 'select_k1ow3h1x',
|
||||
notFoundContent: {
|
||||
use: 'zh_CN',
|
||||
type: 'i18n',
|
||||
},
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'SelectField',
|
||||
zh_CN: '性别',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
wrapperColOffset: 0,
|
||||
hasSelectAll: false,
|
||||
hasArrow: true,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
filterLocal: true,
|
||||
dataSource: [
|
||||
{
|
||||
defaultChecked: false,
|
||||
text: {
|
||||
en_US: 'Option 1',
|
||||
zh_CN: '男',
|
||||
type: 'i18n',
|
||||
__sid__: 'param_k1owc4tb',
|
||||
},
|
||||
__sid__: 'serial_k1owc4t1',
|
||||
value: 'M',
|
||||
sid: 'opt_k1owc4t2',
|
||||
},
|
||||
{
|
||||
defaultChecked: false,
|
||||
text: {
|
||||
en_US: 'Option 2',
|
||||
zh_CN: '女',
|
||||
type: 'i18n',
|
||||
__sid__: 'param_k1owc4tf',
|
||||
},
|
||||
__sid__: 'serial_k1owc4t2',
|
||||
value: 'F',
|
||||
sid: 'opt_k1owc4t3',
|
||||
},
|
||||
],
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
searchDelay: 300,
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'Card',
|
||||
id: 'node_k1ow3cbl',
|
||||
props: {
|
||||
__slot__title: false,
|
||||
subTitle: {
|
||||
use: 'zh_CN',
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
__slot__subTitle: false,
|
||||
extra: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
className: 'card_kgaqfbm6',
|
||||
title: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'Title',
|
||||
zh_CN: '部门信息',
|
||||
type: 'i18n',
|
||||
},
|
||||
__slot__extra: false,
|
||||
showHeadDivider: true,
|
||||
__style__: ':root {\n margin-bottom: 12px;\n}',
|
||||
showTitleBullet: true,
|
||||
contentHeight: '',
|
||||
fieldId: 'card_k1ow3h1m',
|
||||
dividerNoInset: false,
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'CardContent',
|
||||
id: 'node_k1ow3cbm',
|
||||
props: {},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cc4',
|
||||
props: {
|
||||
fieldName: 'department',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h21',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: '所属部门',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
componentName: 'ColumnsLayout',
|
||||
id: 'node_k1ow3cc5',
|
||||
props: {
|
||||
layout: '6:6',
|
||||
columnGap: '20',
|
||||
rowGap: 0,
|
||||
__style__: {},
|
||||
fieldId: 'columns_k1ow3h22',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'Column',
|
||||
id: 'node_k1ow3cc6',
|
||||
props: {
|
||||
colSpan: '',
|
||||
__style__: {},
|
||||
fieldId: 'column_k1p1bnjo',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cc8',
|
||||
props: {
|
||||
fieldName: 'leader',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h23',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: '主管',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'Column',
|
||||
id: 'node_k1ow3cc7',
|
||||
props: {
|
||||
colSpan: '',
|
||||
__style__: {},
|
||||
fieldId: 'column_k1p1bnjp',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'TextField',
|
||||
id: 'node_k1ow3cc9',
|
||||
props: {
|
||||
fieldName: 'hrg',
|
||||
hasClear: false,
|
||||
autoFocus: false,
|
||||
tips: {
|
||||
en_US: '',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
trim: false,
|
||||
labelTextAlign: 'right',
|
||||
placeholder: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'please input',
|
||||
zh_CN: '请输入',
|
||||
type: 'i18n',
|
||||
},
|
||||
state: '',
|
||||
behavior: 'NORMAL',
|
||||
value: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
addonBefore: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
validation: [],
|
||||
hasLimitHint: false,
|
||||
cutString: false,
|
||||
__style__: {},
|
||||
fieldId: 'textField_k1ow3h24',
|
||||
htmlType: 'input',
|
||||
autoHeight: false,
|
||||
labelColOffset: 0,
|
||||
label: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'TextField',
|
||||
zh_CN: 'HRG',
|
||||
type: 'i18n',
|
||||
},
|
||||
__category__: 'form',
|
||||
labelColSpan: 4,
|
||||
wrapperColSpan: 0,
|
||||
rows: 4,
|
||||
addonAfter: {
|
||||
use: 'zh_CN',
|
||||
zh_CN: '',
|
||||
type: 'i18n',
|
||||
},
|
||||
wrapperColOffset: 0,
|
||||
size: 'medium',
|
||||
labelAlign: 'top',
|
||||
__useMediator: 'value',
|
||||
labelTipsTypes: 'none',
|
||||
labelTipsIcon: '',
|
||||
labelTipsText: {
|
||||
type: 'i18n',
|
||||
use: 'zh_CN',
|
||||
en_US: null,
|
||||
zh_CN: '',
|
||||
},
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'Div',
|
||||
id: 'node_k1ow3cbo',
|
||||
props: {
|
||||
className: 'div_kgaqfbm9',
|
||||
behavior: 'NORMAL',
|
||||
__style__:
|
||||
':root {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n background: #fff;\n padding: 20px 0;\n}',
|
||||
events: {},
|
||||
fieldId: 'div_k1ow3h1o',
|
||||
useFieldIdAsDomId: false,
|
||||
customClassName: '',
|
||||
},
|
||||
condition: true,
|
||||
children: [
|
||||
{
|
||||
componentName: 'Button',
|
||||
id: 'node_k1ow3cbn',
|
||||
props: {
|
||||
triggerEventsWhenLoading: false,
|
||||
onClick: {
|
||||
rawType: 'events',
|
||||
type: 'JSExpression',
|
||||
value: 'this.utils.legaoBuiltin.execEventFlow.bind(this, [this.submit])',
|
||||
events: [
|
||||
{
|
||||
name: 'submit',
|
||||
id: 'submit',
|
||||
params: {},
|
||||
type: 'actionRef',
|
||||
uuid: '1570966253282_0',
|
||||
},
|
||||
],
|
||||
},
|
||||
size: 'medium',
|
||||
baseIcon: '',
|
||||
otherIcon: '',
|
||||
className: 'button_kgaqfbm7',
|
||||
type: 'primary',
|
||||
behavior: 'NORMAL',
|
||||
loading: false,
|
||||
content: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'Button',
|
||||
zh_CN: '提交',
|
||||
type: 'i18n',
|
||||
},
|
||||
__style__: ':root {\n margin-right: 16px;\n width: 80px\n}',
|
||||
fieldId: 'button_k1ow3h1n',
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
{
|
||||
componentName: 'Button',
|
||||
id: 'node_k1ow3cbp',
|
||||
props: {
|
||||
triggerEventsWhenLoading: false,
|
||||
size: 'medium',
|
||||
baseIcon: '',
|
||||
otherIcon: '',
|
||||
className: 'button_kgaqfbm8',
|
||||
type: 'normal',
|
||||
behavior: 'NORMAL',
|
||||
loading: false,
|
||||
content: {
|
||||
use: 'zh_CN',
|
||||
en_US: 'Button',
|
||||
zh_CN: '取消',
|
||||
type: 'i18n',
|
||||
},
|
||||
__style__: ':root {\n width: 80px;\n}',
|
||||
fieldId: 'button_k1ow3h1p',
|
||||
},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
componentName: 'RootFooter',
|
||||
id: 'node_k1ow3cbc',
|
||||
props: {},
|
||||
condition: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
18
packages/designer/tests/fixtures/window.ts
vendored
Normal file
18
packages/designer/tests/fixtures/window.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest.fn().mockImplementation(query => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // deprecated
|
||||
removeListener: jest.fn(), // deprecated
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
dispatchEvent: jest.fn(),
|
||||
})),
|
||||
});
|
||||
|
||||
Object.defineProperty(window, 'React', {
|
||||
writable: true,
|
||||
value: {},
|
||||
});
|
||||
86
packages/designer/tests/project/project.test.js
Normal file
86
packages/designer/tests/project/project.test.js
Normal file
@ -0,0 +1,86 @@
|
||||
import '../fixtures/window';
|
||||
import { Project } from '../../src/project/project';
|
||||
// import { Node } from '../../../src/document/node/node';
|
||||
import { Designer } from '../../src/designer/designer';
|
||||
import formSchema from '../fixtures/schema/form';
|
||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
||||
|
||||
const mockCreateSettingEntry = jest.fn();
|
||||
jest.mock('../../src/designer/designer', () => {
|
||||
return {
|
||||
Designer: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
getComponentMeta() {
|
||||
return {
|
||||
getMetadata() {
|
||||
return { experimental: null };
|
||||
},
|
||||
};
|
||||
},
|
||||
transformProps(props) { return props; },
|
||||
createSettingEntry: mockCreateSettingEntry,
|
||||
postEvent() {},
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
let designer = null;
|
||||
beforeAll(() => {
|
||||
designer = new Designer({});
|
||||
});
|
||||
|
||||
describe('schema 渲染测试', () => {
|
||||
it('最简单的例子,练手用', () => {
|
||||
const project = new Project(designer, {
|
||||
componentsTree: [{
|
||||
componentName: 'Page',
|
||||
id: 'page_id',
|
||||
props: {
|
||||
name: 'haha',
|
||||
},
|
||||
children: [{
|
||||
componentName: 'Div',
|
||||
id: 'div_id',
|
||||
props: {
|
||||
name: 'div from haha',
|
||||
},
|
||||
}],
|
||||
}],
|
||||
});
|
||||
project.open();
|
||||
expect(project).toBeTruthy();
|
||||
const { currentDocument } = project;
|
||||
const { nodesMap } = currentDocument;
|
||||
// console.log(project.currentDocument.nodesMap.get('div_id').props.items);
|
||||
expect(nodesMap.has('page_id')).toBeTruthy;
|
||||
expect(nodesMap.has('div_id')).toBeTruthy;
|
||||
expect(mockCreateSettingEntry).toBeCalledTimes(2);
|
||||
// console.log(currentDocument.export(3));
|
||||
});
|
||||
|
||||
it.only('普通场景,无 block / component,无 slot', () => {
|
||||
const project = new Project(designer, {
|
||||
componentsTree: [
|
||||
formSchema,
|
||||
],
|
||||
});
|
||||
project.open();
|
||||
expect(project).toBeTruthy();
|
||||
const { currentDocument } = project;
|
||||
const { nodesMap } = currentDocument;
|
||||
const ids = getIdsFromSchema(formSchema);
|
||||
ids.forEach(id => {
|
||||
expect(nodesMap.get(id).componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
||||
});
|
||||
// console.log(nodesMap.get('node_k1ow3cb9').componentName, getNodeFromSchemaById(formSchema, 'node_k1ow3cb9').componentName)
|
||||
console.log(nodesMap.size);
|
||||
// expect(nodesMap.has('page_id')).toBeTruthy;
|
||||
// expect(nodesMap.has('div_id')).toBeTruthy;
|
||||
// expect(mockCreateSettingEntry).toBeCalledTimes(2);
|
||||
// console.log(currentDocument.export(3));
|
||||
});
|
||||
|
||||
it('普通场景,无 block / component,有 slot', () => {});
|
||||
it('普通场景,无 block / component,有 slot', () => {});
|
||||
});
|
||||
28
packages/designer/tests/utils/index.js
Normal file
28
packages/designer/tests/utils/index.js
Normal file
@ -0,0 +1,28 @@
|
||||
export function getIdsFromSchema(schema, ids = []) {
|
||||
if (!schema) return ids;
|
||||
const { componentName, id, children } = schema;
|
||||
if (componentName) {
|
||||
ids.push(id);
|
||||
}
|
||||
if (Array.isArray(children) && children.length > 0) {
|
||||
children.forEach(node => getIdsFromSchema(node, ids));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
export function getNodeFromSchemaById(schema, _id) {
|
||||
if (!schema) return null;
|
||||
const { id, children } = schema;
|
||||
let retNode = null;
|
||||
if (_id === id) return schema;
|
||||
if (Array.isArray(children) && children.length > 0) {
|
||||
children.some(node => {
|
||||
retNode = getNodeFromSchemaById(node, _id);
|
||||
if (retNode) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return retNode;
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": [
|
||||
"./src/"
|
||||
]
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ designer.addPropsReducer((props, node) => {
|
||||
!isI18NObject(ov) &&
|
||||
!isJSExpression(ov) &&
|
||||
!isVariable(ov)) {
|
||||
newProps[item.name] = v;
|
||||
newProps[item.name] = convertToI18NObject(v);
|
||||
}
|
||||
} catch (e) {
|
||||
if (hasOwnProperty(props, item.name)) {
|
||||
@ -133,7 +133,7 @@ designer.addPropsReducer((props, node) => {
|
||||
}
|
||||
}
|
||||
if (newProps[item.name] && !node.props.has(item.name)) {
|
||||
node.props.add(newProps[item.name], item.name);
|
||||
node.props.add(newProps[item.name], item.name, false, { skipSetSlot: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -54,5 +54,5 @@
|
||||
"publishConfig": {
|
||||
"registry": "http://registry.npm.alibaba-inc.com"
|
||||
},
|
||||
"homepage": "https://unpkg.alibaba-inc.com/@ali/lowcode-react-renderer@0.12.1-3/build/index.html"
|
||||
"homepage": "https://unpkg.alibaba-inc.com/@ali/lowcode-react-renderer@0.13.1-1/build/index.html"
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
|
||||
import { isI18NObject } from './is-object';
|
||||
|
||||
export function isUseI18NSetter(prototype: any, propName: string) {
|
||||
const configure = prototype?.options?.configure;
|
||||
@ -10,6 +11,7 @@ export function isUseI18NSetter(prototype: any, propName: string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function convertToI18NObject(v: string, locale: string = 'zh_CN') {
|
||||
export function convertToI18NObject(v: string | object, locale: string = 'zh_CN') {
|
||||
if (isI18NObject(v)) return v;
|
||||
return { type: 'i18n', use: locale, [locale]: v };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user