wuji.xwt 5d259055fb refactor: code style
Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3681622

* chore: remove unnecessary code

* refactor: react-render using TypeScript

* chore: build-script

* refactor: editor-skeleton

* refactor: designer

* refactor: material-parser

* refactor: editor-setters

* refactor: js to ts for rax-provider 

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3678180

* refactor: rax-provider

* feat: add build command

* chore: compilerOptions for rax-provider

* refactor: JS to TS for Rax Renderer 

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3678935

* refactor: rax-renderer

* Merge remote-tracking branch 'origin/refactor/js-to-ts' into refactor/js2ts-rax-renderer

* Merge remote-tracking branch 'origin/refactor/js-to-ts' into refactor/js2ts-rax-renderer

* refactor: ts-nocheck

* chore: ts compile error

* fix: ts rootDir

* fix: compile error

* chore: using same tsconfig for rax component

* refactor: ts compile rax-renderer && rax-provider

* Merge remote-tracking branch 'origin/release/1.0.0' into refactor/js-to-ts

# Conflicts:
#	packages/rax-render/src/utils/appHelper.js
#	packages/rax-render/src/utils/appHelper.ts
#	packages/utils/src/appHelper.ts

* refactor: no JS file

* refactor: remove lint

* feat: add xima

* feat: add eslint ignore

* style: fix by lint

* feat: lint command

* fix: using the same eslint config

* style: eslint settings

* Merge remote-tracking branch 'origin/release/1.0.0' into refactor/code-style

# Conflicts:
#	packages/plugin-event-bind-dialog/src/index.tsx
#	packages/plugin-source-editor/src/index.tsx
#	packages/runtime/src/core/container.ts
#	packages/runtime/src/core/provider.ts

* Merge remote-tracking branch 'origin/release/1.0.0' into refactor/code-style

# Conflicts:
#	packages/designer/src/document/document-model.ts
#	packages/designer/src/document/node/node-children.ts
#	packages/designer/src/document/node/props/prop.ts
#	packages/plugin-source-editor/src/index.tsx

* fix: 修改dataSource items -> list

* Merge remote-tracking branch 'origin/relase/1.0.0' into refactor/code-style

# Conflicts:
#	packages/react-renderer/package.json

* refactor: component-panel 

plugin-component-pane 代码规范化

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3703771

* feat: support bizcomps

* refactor: component-panel

* style: eslint

* Merge branch 'refactor/code-style' into fix/ducheng-source-style

* style: code style

* Merge branch 'fix/ducheng-source-style' into 'refactor/code-style'
Code review title: Fix/ducheng source style
Code review Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3705972

* style: for demo

* style: for demo-server

* style: for plugin-event-bind-dialog

* style: for plugin-sample-preview

* style: for plugin-undo-redo

* style: plugin-variable-bind-dialog

* style: types

* style: for utils

* Merge remote-tracking branch 'origin/release/1.0.0' into refactor/code-style

# Conflicts:
#	packages/editor-setters/src/expression-setter/locale/snippets.ts
#	packages/editor-setters/src/json-setter/locale/snippets.ts
#	packages/editor-setters/src/locale/snippets.ts
#	packages/plugin-components-pane/package.json
#	packages/rax-render/src/hoc/compWrapper.tsx
#	packages/rax-render/src/utils/index.ts
#	packages/react-renderer/src/context/appContext.ts

* style: editor-preset-general 

editor-preset-general 代码规范化

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3707974

* style: editor-preset-general

* fix: should set field

* fix: should set field - demo-server

* refactor(style): fix code style for designer

refactor(style): fix code style for editor-core

refactor(style): fix code style for editor-skeleton

refactor(style): fix code style for react-simulator-renderer

refactor(style): fix code style for rax-simulator-renderer

* Merge branch 'refactor/lihao-code-style' into 'refactor/code-style'
Code review title: refactor(style): fix code style for designer
Code review description: refactor(style): fix code style for editor-core

refactor(style): fix code style for editor-skeleton

refactor(style): fix code style for react-simulator-renderer

refactor(style): fix code style for rax-simulator-renderer
Code review Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3709472

* style: react/no-multi-comp set to 0 for designer

* style: ignore editor-prset-vision

* style: fix for plugin-outline-pane

* style: fix for rax-provider

* style: react-provider

* style: runtime

* style: rax-render

* Merge remote-tracking branch 'origin/release/1.0.0' into refactor/code-style

# Conflicts:
#	packages/editor-setters/src/expression-setter/index.tsx
#	packages/plugin-source-editor/src/index.tsx
#	packages/plugin-source-editor/src/transform.ts

* refactor: material parser code style 

1. 修复eslint问题
2. instanceOf => any
3. 修复node类型解析失败问题

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3716330

* refactor: material parser code style

* refactor: code-generator code style 

1. rax 出码合并
2. code style 修复

注:合并的代码中带了 datasource 的

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3717159

* Merge branch 'feat/rax-code-generator' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into feat/rax-code-generator

# Conflicts:
#	packages/code-generator/src/generator/ProjectBuilder.ts
#	packages/code-generator/src/parser/SchemaParser.ts
#	packages/code-generator/src/plugins/component/rax/jsx.ts
#	packages/code-generator/src/plugins/project/constants.ts
#	packages/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts
#	packages/code-generator/src/plugins/project/i18n.ts
#	packages/code-generator/src/publisher/disk/index.ts
#	packages/code-generator/src/publisher/disk/utils.ts
#	packages/code-generator/src/types/core.ts
#	packages/code-generator/src/types/schema.ts
#	packages/code-generator/src/utils/compositeType.ts
#	packages/code-generator/src/utils/nodeToJSX.ts

* refactor: code-generator

* Merge remote-tracking branch 'origin/refactor/code-style' into refactor/code-style-code-generator

# Conflicts:
#	.vscode/launch.json

* Revert "refactor: code-generator code style "

This reverts commit ebc78e8788f83e8fda0e146758af43b878125c10.

* chore: eslintrc && eslintignore

* style: for plugin-source-editor

* style: fix by eslint --fix

* style: scripts/

* style: datasource-engine

* feat: pre-commit

* Merge branch 'refactor/code-style' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into refactor/code-style

# Conflicts:
#	.eslintignore
#	packages/code-generator/src/parser/SchemaParser.ts
#	packages/code-generator/src/plugins/component/rax/containerInitState.ts
#	packages/code-generator/src/plugins/component/rax/containerInjectDataSourceEngine.ts
#	packages/code-generator/src/plugins/component/rax/containerLifeCycle.ts
#	packages/code-generator/src/plugins/project/framework/rax/plugins/buildConfig.ts
#	packages/code-generator/src/utils/OrderedSet.ts
#	packages/code-generator/src/utils/ScopeBindings.ts
#	packages/code-generator/src/utils/expressionParser.ts
#	packages/code-generator/src/utils/schema.ts
#	packages/datasource-engine/src/core/DataSourceEngine.ts
#	packages/datasource-engine/src/core/RuntimeDataSource.ts
#	packages/datasource-engine/src/types/IRuntimeContext.ts
#	packages/datasource-engine/src/types/index.ts

* refactor: code style code-generator 

对 code style 分支上次合并的  code-generator 修改做了 revert

重新在 code style 分支基础上对代码样式做了修复

rax 合并分支会另行 fix 后向 release 分支提 MR

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/3719702

* refactor: code style fix

* style: for code-generator

* Merge remote-tracking branch 'origin/release/1.0.0' into refactor/code-style

# Conflicts:
#	packages/editor-skeleton/src/transducers/addon-combine.ts
#	packages/plugin-components-pane/package.json
#	packages/plugin-components-pane/src/components/base/index.tsx
#	packages/plugin-components-pane/src/components/component-list/index.tsx
#	packages/plugin-components-pane/src/i18n/index.ts
#	packages/plugin-components-pane/src/i18n/strings/index.ts
#	packages/plugin-components-pane/src/index.tsx
#	packages/plugin-event-bind-dialog/src/index.tsx
#	packages/plugin-source-editor/src/index.tsx
#	packages/plugin-source-editor/src/transform.ts

* style: auto fix
2020-09-15 19:06:35 +08:00

630 lines
15 KiB
TypeScript

import { Component } from 'react';
import { EventEmitter } from 'events';
import { fromJS, Iterable, Map as IMMap } from 'immutable';
import logger from '@ali/vu-logger';
import { cloneDeep, isDataEqual, combineInitial, Transducer } from '@ali/ve-utils';
import I18nUtil from '@ali/ve-i18n-util';
import { getSetter } from '@ali/lowcode-editor-core';
import { editor } from './editor';
import { OldPropConfig, DISPLAY_TYPE } from './bundle/upgrade-metadata';
import { uniqueId } from '@ali/lowcode-utils';
type IPropConfig = OldPropConfig;
// 1: chain -1: start 0: discard
const CHAIN_START = -1;
const CHAIN_HAS_REACH = 0;
export enum PROP_VALUE_CHANGED_TYPE {
/**
* normal set value
*/
SET_VALUE = 'SET_VALUE',
/**
* value changed caused by sub-prop value change
*/
SUB_VALUE_CHANGE = 'SUB_VALUE_CHANGE',
}
/**
* Dynamic setter will use 've.plugin.setterProvider' to
* calculate setter type in runtime
*/
let dynamicSetterProvider: any;
export interface IHotDataMap extends IMMap<string, any> {
value: any;
hotValue: any;
}
export interface ISetValueOptions {
disableMutator?: boolean;
type?: PROP_VALUE_CHANGED_TYPE;
}
export interface IVariableSettable {
useVariable?: boolean;
variableValue: string;
isUseVariable: () => boolean;
isSupportVariable: () => boolean;
setVariableValue: (value: string) => void;
setUseVariable: (flag?: boolean) => void;
getVariableValue: () => string;
onUseVariableChange: (func: (data: { isUseVariable: boolean }) => any) => void;
}
export default class Prop implements IVariableSettable {
/**
* Setters predefined as default options
* can by selected by user for every prop
*
* @static
* @memberof Prop
*/
public static INSET_SETTER = {};
public id: string;
public emitter: EventEmitter;
public inited: boolean;
public i18nLink: any;
public loopLock: boolean;
public props: any;
public parent: any;
public config: IPropConfig;
public initial: any;
public initialData: any;
public expanded: boolean;
public useVariable?: boolean;
/**
* value to be saved in schema it is usually JSON serialized
* prototype.js can config Transducer.toNative to generate value
*/
public value: any;
/**
* value to be used in VisualDesigner more flexible
* prototype.js can config Transducer.toHot to generate hotValue
*/
public hotValue: any;
/**
* 启用变量之后,变量表达式字符串值
*/
public variableValue: string;
public hotData: IMMap<string, IHotDataMap>;
public defaultValue: any;
public transducer: any;
public inGroup: boolean;
constructor(parent: any, config: IPropConfig, data?: any) {
if (parent.isProps) {
this.props = parent;
this.parent = null;
} else {
this.props = parent.getProps();
this.parent = parent;
}
this.id = uniqueId('prop');
if (typeof config.setter === 'string') {
config.setter = getSetter(config.setter)?.component as any;
}
this.config = config;
this.emitter = new EventEmitter();
this.emitter.setMaxListeners(100);
this.initialData = data;
this.useVariable = false;
dynamicSetterProvider = editor.get('ve.plugin.setterProvider');
this.beforeInit();
}
public getId() {
return this.id;
}
public isTab() {
return this.getDisplay() === 'tab';
}
public isGroup() {
return false;
}
public beforeInit() {
if (IMMap.isMap(this.initialData)) {
this.value = this.initialData.get('value');
if (this.value && typeof this.value.toJS === 'function') {
this.value = this.value.toJS();
}
this.hotData = this.initialData;
} else {
this.value = this.initialData;
}
this.resolveValue();
let defaultValue = null;
if (this.config.defaultValue !== undefined) {
defaultValue = this.config.defaultValue;
} else if (typeof this.config.initialValue !== 'function') {
defaultValue = this.config.initialValue;
}
this.defaultValue = defaultValue;
this.transducer = new Transducer(this, this.config);
this.initial = combineInitial(this, this.config);
}
public resolveValue() {
if (this.value && this.value.type === 'variable') {
const { value, variable } = this.value;
this.value = value;
this.variableValue = variable;
this.useVariable = this.isSupportVariable();
} else {
this.useVariable = false;
}
}
public init(defaultValue?: any) {
if (this.inited) { return; }
this.value = this.initial(this.value,
this.defaultValue != null ? this.defaultValue : defaultValue);
if (this.hotData) {
const tempVal = this.hotData.get('value');
// if we create a prop from runtime data, we don't need initial() or set with defaultValue process
// but if we got an empty value, we fill with the initial() process and default value
if (Iterable.isIterable(tempVal)) {
this.value = tempVal.toJS() || this.value;
} else {
this.value = tempVal || this.value;
}
this.resolveValue();
}
this.i18nLink = I18nUtil.attach(this, this.value,
((val: any) => { this.setValue(val, false, true); }) as any);
// call config.accessor
const value = this.getValue();
if (this.hotData) {
this.hotValue = this.hotData.get('hotValue');
if (this.hotValue && Iterable.isIterable(this.hotValue)) {
this.hotValue = this.hotValue.toJS();
}
} else {
try {
this.hotValue = this.transducer.toHot(value);
} catch (e) {
logger.log('ERROR_PROP_VALUE');
logger.warn('属性初始化错误:', this);
}
this.hotData = fromJS({
hotValue: this.hotValue,
value: this.getMixValue(value),
});
}
this.inited = true;
}
public isInited() {
return this.inited;
}
public getHotData() {
return this.hotData;
}
public getProps() {
return this.props;
}
public getNode(): any {
return this.getProps().getNode();
}
/**
* 获得属性名称
*
* @returns {string}
*/
public getName(): string {
const ns = this.parent ? `${this.parent.getName()}.` : '';
return ns + this.config.name;
}
public getKey() {
return this.config.name;
}
/**
* 获得属性标题
*
* @returns {string}
*/
public getTitle() {
return this.config.title || this.getName();
}
public getTip() {
return this.config.tip || null;
}
public getValue(disableCache?: boolean, options?: {
disableAccessor?: boolean;
}) {
const { accessor } = this.config;
if (accessor && (!options || !options.disableAccessor)) {
const value = accessor.call(this as any, this.value);
if (!disableCache) {
this.value = value;
}
return value;
}
return this.value;
}
public getMixValue(value?: any) {
if (value == null) {
value = this.getValue();
}
if (this.isUseVariable()) {
value = {
type: 'variable',
value,
variable: this.getVariableValue(),
};
}
return value;
}
public toData() {
return cloneDeep(this.getMixValue());
}
public getDefaultValue() {
return this.defaultValue;
}
public getHotValue() {
return this.hotValue;
}
public getConfig<K extends keyof IPropConfig>(configName?: K): IPropConfig[K] | IPropConfig {
if (configName) {
return this.config[configName];
}
return this.config;
}
public sync() {
if (this.props.hasReach(this)) {
return;
}
const { sync } = this.config;
if (sync) {
const value = sync.call(this as any, this.getValue(true));
if (value !== undefined) {
this.setValue(value);
}
} else {
// sync 的时候不再需要调用经过 accessor 处理之后的值了
// 这里之所以需要 setValue 是为了过 getValue() 中的 accessor 修饰函数
this.setValue(this.getValue(true), false, false, {
disableMutator: true,
});
}
}
public isUseVariable() {
return this.useVariable || false;
}
public isSupportVariable() {
return this.config.supportVariable || false;
}
public setVariableValue(value: string) {
if (!this.isUseVariable()) { return; }
const state = this.props.chainReach(this);
if (state === CHAIN_HAS_REACH) {
return;
}
this.variableValue = value;
if (this.modify()) {
this.valueChange();
this.props.syncPass(this);
}
if (state === CHAIN_START) {
this.props.endChain();
}
}
public setUseVariable(flag = false) {
if (this.useVariable === flag) { return; }
const state = this.props.chainReach(this);
if (state === CHAIN_HAS_REACH) {
return;
}
this.useVariable = flag;
this.expanded = true;
if (this.modify()) {
this.valueChange();
this.props.syncPass(this);
}
if (state === CHAIN_START) {
this.props.endChain();
}
this.emitter.emit('ve.prop.useVariableChange', { isUseVariable: flag });
if (this.config.useVariableChange) {
this.config.useVariableChange.call(this as any, { isUseVariable: flag });
}
}
public getVariableValue() {
return this.variableValue;
}
/**
* @param value
* @param isHotValue 是否为设计器热状态值
* @param force 是否强制触发更新
*/
public setValue(value: any, isHotValue?: boolean, force?: boolean, extraOptions?: ISetValueOptions) {
const state = this.props.chainReach(this);
if (state === CHAIN_HAS_REACH) {
return;
}
const preValue = this.value;
const preHotValue = this.hotValue;
if (isHotValue) {
this.hotValue = value;
this.value = this.transducer.toNative(this.hotValue);
} else {
if (!isDataEqual(value, this.value)) {
this.hotValue = this.transducer.toHot(value);
}
this.value = value;
}
this.i18nLink = I18nUtil.attach(this, this.value, ((val: any) => this.setValue(val, false, true)) as any);
const { mutator } = this.config;
if (!extraOptions) {
extraOptions = {};
}
if (mutator && !extraOptions.disableMutator) {
mutator.call(this as any, this.value);
}
if (this.modify(force)) {
this.valueChange(extraOptions);
this.props.syncPass(this);
}
if (state === CHAIN_START) {
this.props.endChain();
}
}
public setHotValue(hotValue: any, options?: ISetValueOptions) {
try {
this.setValue(hotValue, true, false, options);
} catch (e) {
logger.log('ERROR_PROP_VALUE');
logger.warn('属性值设置错误:', e, hotValue);
}
}
/**
* 验证是否存在变更
* @param force 是否强制返回已变更
*/
public modify(force?: boolean) {
const hotData = this.hotData.merge(fromJS({
hotValue: this.getHotValue(),
value: this.getMixValue(),
}));
if (!force && hotData.equals(this.hotData)) {
return false;
}
this.hotData = hotData;
(this.parent || this.props).modify(this.getName());
return true;
}
public setHotData(hotData: IMMap<string, IHotDataMap>, options?: ISetValueOptions) {
if (!IMMap.isMap(hotData)) {
return;
}
this.hotData = hotData;
let value = hotData.get('value');
if (value && typeof value.toJS === 'function') {
value = value.toJS();
}
let hotValue = hotData.get('hotValue');
if (hotValue && typeof hotValue.toJS === 'function') {
hotValue = hotValue.toJS();
}
const preValue = value;
const preHotValue = hotValue;
this.value = value;
this.hotValue = hotValue;
this.resolveValue();
if (!options || !options.disableMutator) {
const { mutator } = this.config;
if (mutator) {
mutator.call(this as any, value);
}
}
this.valueChange();
}
public valueChange(options?: ISetValueOptions) {
if (this.loopLock) { return; }
this.emitter.emit('valuechange', options);
if (this.parent) {
this.parent.valueChange(options);
}
}
public getDisplay() {
return this.config.display || this.config.fieldStyle || 'block';
}
public isHidden() {
if (!this.isInited() || this.getDisplay() === DISPLAY_TYPE.NONE || this.isDisabled()) {
return true;
}
let { hidden } = this.config;
if (typeof hidden === 'function') {
hidden = hidden.call(this as any, this.getValue());
}
return hidden === true;
}
public isDisabled() {
let { disabled } = this.config;
if (typeof disabled === 'function') {
disabled = disabled.call(this as any, this.getValue());
}
return disabled === true;
}
public isIgnore() {
if (this.isDisabled()) { return true; }
let { ignore } = this.config;
if (typeof ignore === 'function') {
ignore = ignore.call(this as any, this.getValue());
}
return ignore === true;
}
public isExpand() {
if (this.expanded == null) {
this.expanded = !(this.config.collapsed || this.config.fieldCollapsed);
}
return this.expanded;
}
public toggleExpand() {
if (this.expanded) {
this.expanded = false;
} else {
this.expanded = true;
}
this.emitter.emit('expandchange', this.expanded);
}
public getSetter() {
if (dynamicSetterProvider) {
const setter = dynamicSetterProvider.call(this, this, this.getNode().getPrototype());
if (setter) {
return setter;
}
}
const setterConfig = this.config.setter;
if (typeof setterConfig === 'function' && !(setterConfig.prototype instanceof Component)) {
return (setterConfig as any).call(this, this.getValue());
}
if (Array.isArray(setterConfig)) {
let item;
for (item of setterConfig) {
if (item.condition?.call(this, this.getValue())) {
return item.setter;
}
}
return setterConfig[0].setter;
}
return setterConfig;
}
public getSetterData(): any {
if (Array.isArray(this.config.setter)) {
let item;
for (item of this.config.setter) {
if (item.condition?.call(this, this.getValue())) {
return item;
}
}
return this.config.setter[0];
}
return { };
}
public destroy() {
if (this.i18nLink) {
this.i18nLink.detach();
}
}
public onValueChange(func: () => any) {
this.emitter.on('valuechange', func);
return () => {
this.emitter.removeListener('valuechange', func);
};
}
public onExpandChange(func: () => any) {
this.emitter.on('expandchange', func);
return () => {
this.emitter.removeListener('expandchange', func);
};
}
public onUseVariableChange(func: (data: { isUseVariable: boolean }) => any) {
this.emitter.on('ve.prop.useVariableChange', func);
return () => {
this.emitter.removeListener('ve.prop.useVariableChange', func);
};
}
}