mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-20 15:38:32 +00:00
Merge branch 'release/1.0.35' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into release/1.0.35
This commit is contained in:
commit
b8f1a3678a
@ -236,7 +236,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
readonly componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
readonly componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
||||||
|
|
||||||
readonly injectionConsumer = new ResourceConsumer(() => {
|
readonly injectionConsumer = new ResourceConsumer(() => {
|
||||||
return {};
|
return {
|
||||||
|
i18n: this.project.i18n,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
readonly asyncLibraryMap: { [key: string]: {} } = {};
|
readonly asyncLibraryMap: { [key: string]: {} } = {};
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export class Project {
|
|||||||
|
|
||||||
@obx.val readonly documents: DocumentModel[] = [];
|
@obx.val readonly documents: DocumentModel[] = [];
|
||||||
|
|
||||||
private data: ProjectSchema = { version: '1.0.0', componentsMap: [], componentsTree: [] };
|
private data: ProjectSchema = { version: '1.0.0', componentsMap: [], componentsTree: [], i18n: {} };
|
||||||
|
|
||||||
private _simulator?: ISimulatorHost;
|
private _simulator?: ISimulatorHost;
|
||||||
|
|
||||||
@ -40,15 +40,24 @@ export class Project {
|
|||||||
this._config = value;
|
this._config = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@obx.ref private _i18n: any = {};
|
||||||
|
get i18n(): any {
|
||||||
|
return this._i18n;
|
||||||
|
}
|
||||||
|
set i18n(value: any) {
|
||||||
|
this._i18n = value || {};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目整体 schema
|
* 获取项目整体 schema
|
||||||
*/
|
*/
|
||||||
getSchema(): ProjectSchema {
|
getSchema(): ProjectSchema {
|
||||||
return {
|
return {
|
||||||
...this.data,
|
...this.data,
|
||||||
// todo: future change this filter
|
// TODO: future change this filter
|
||||||
componentsMap: this.currentDocument?.getComponentsMap(),
|
componentsMap: this.currentDocument?.getComponentsMap(),
|
||||||
componentsTree: this.documents.filter((doc) => !doc.isBlank()).map((doc) => doc.schema),
|
componentsTree: this.documents.filter((doc) => !doc.isBlank()).map((doc) => doc.schema),
|
||||||
|
i18n: this._i18n || {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +66,7 @@ export class Project {
|
|||||||
* @param schema
|
* @param schema
|
||||||
*/
|
*/
|
||||||
setSchema(schema?: ProjectSchema) {
|
setSchema(schema?: ProjectSchema) {
|
||||||
|
// FIXME: 这里的行为和 getSchema 并不对等,感觉不太对
|
||||||
const doc = this.documents.find((doc) => doc.actived);
|
const doc = this.documents.find((doc) => doc.actived);
|
||||||
doc && doc.import(schema?.componentsTree[0]);
|
doc && doc.import(schema?.componentsTree[0]);
|
||||||
}
|
}
|
||||||
@ -73,9 +83,11 @@ export class Project {
|
|||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
componentsMap: [],
|
componentsMap: [],
|
||||||
componentsTree: [],
|
componentsTree: [],
|
||||||
|
i18n: {},
|
||||||
...schema,
|
...schema,
|
||||||
};
|
};
|
||||||
this.config = schema?.config || this.config;
|
this.config = schema?.config || this.config;
|
||||||
|
this.i18n = schema?.i18n || this.i18n;
|
||||||
|
|
||||||
if (autoOpen) {
|
if (autoOpen) {
|
||||||
if (autoOpen === true) {
|
if (autoOpen === true) {
|
||||||
@ -137,6 +149,9 @@ export class Project {
|
|||||||
if (key === 'config') {
|
if (key === 'config') {
|
||||||
this.config = value;
|
this.config = value;
|
||||||
}
|
}
|
||||||
|
if (key === 'i18n') {
|
||||||
|
this.i18n = value;
|
||||||
|
}
|
||||||
Object.assign(this.data, { [key]: value });
|
Object.assign(this.data, { [key]: value });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +175,9 @@ export class Project {
|
|||||||
if (key === 'config') {
|
if (key === 'config') {
|
||||||
return this.config;
|
return this.config;
|
||||||
}
|
}
|
||||||
|
if (key === 'i18n') {
|
||||||
|
return this.i18n;
|
||||||
|
}
|
||||||
return Reflect.get(this.data, key);
|
return Reflect.get(this.data, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
|||||||
import { Router, Route, Switch } from 'react-router';
|
import { Router, Route, Switch } from 'react-router';
|
||||||
import './renderer.less';
|
import './renderer.less';
|
||||||
|
|
||||||
|
const DEFAULT_SIMULATOR_LOCALE = 'zh-CN';
|
||||||
|
|
||||||
// patch cloneElement avoid lost keyProps
|
// patch cloneElement avoid lost keyProps
|
||||||
const originCloneElement = window.React.cloneElement;
|
const originCloneElement = window.React.cloneElement;
|
||||||
(window as any).React.cloneElement = (child: any, { _leaf, ...props }: any = {}, ...rest: any[]) => {
|
(window as any).React.cloneElement = (child: any, { _leaf, ...props }: any = {}, ...rest: any[]) => {
|
||||||
@ -137,8 +139,13 @@ class Renderer extends Component<{
|
|||||||
const { documentInstance, rendererContainer: renderer } = this.props;
|
const { documentInstance, rendererContainer: renderer } = this.props;
|
||||||
const { container } = documentInstance;
|
const { container } = documentInstance;
|
||||||
const { designMode, device } = container;
|
const { designMode, device } = container;
|
||||||
|
const messages = container.context?.utils?.i18n?.messages || {};
|
||||||
|
const locale = container.context?.utils?.i18n?.currentLocale || Object.keys(messages)[0] || DEFAULT_SIMULATOR_LOCALE;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LowCodeRenderer
|
<LowCodeRenderer
|
||||||
|
locale={locale}
|
||||||
|
messages={messages}
|
||||||
schema={documentInstance.schema}
|
schema={documentInstance.schema}
|
||||||
components={container.components}
|
components={container.components}
|
||||||
appHelper={container.context}
|
appHelper={container.context}
|
||||||
|
|||||||
@ -267,12 +267,28 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
|||||||
return parseQuery(search);
|
return parseQuery(search);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
i18n: {
|
||||||
|
setLocale: (loc: string) => {
|
||||||
|
const newCtx = {
|
||||||
|
...this._appContext,
|
||||||
|
};
|
||||||
|
newCtx.utils.i18n.currentLocale = loc;
|
||||||
|
this._appContext = newCtx;
|
||||||
|
},
|
||||||
|
currentLocale: undefined,
|
||||||
|
messages: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
constants: {},
|
constants: {},
|
||||||
requestHandlersMap: this._requestHandlersMap,
|
requestHandlersMap: this._requestHandlersMap,
|
||||||
};
|
};
|
||||||
host.injectionConsumer.consume((data) => {
|
host.injectionConsumer.consume((data) => {
|
||||||
// sync utils, i18n, contants,... config
|
// TODO: sync utils, i18n, contants,... config
|
||||||
|
const newCtx = {
|
||||||
|
...this._appContext,
|
||||||
|
};
|
||||||
|
newCtx.utils.i18n.messages = data.i18n || {};
|
||||||
|
this._appContext = newCtx;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
getValue,
|
getValue,
|
||||||
parseData,
|
parseData,
|
||||||
parseExpression,
|
parseExpression,
|
||||||
|
parseI18n,
|
||||||
isEmpty,
|
isEmpty,
|
||||||
isSchema,
|
isSchema,
|
||||||
isFileSchema,
|
isFileSchema,
|
||||||
@ -19,7 +20,7 @@ import {
|
|||||||
transformArrayToMap,
|
transformArrayToMap,
|
||||||
transformStringToFunction,
|
transformStringToFunction,
|
||||||
checkPropTypes,
|
checkPropTypes,
|
||||||
generateI18n,
|
getI18n,
|
||||||
acceptsRef,
|
acceptsRef,
|
||||||
getFileCssName,
|
getFileCssName,
|
||||||
capitalizeFirstLetter,
|
capitalizeFirstLetter,
|
||||||
@ -77,9 +78,8 @@ export default function baseRenererFactory() {
|
|||||||
this.appHelper = props.__appHelper;
|
this.appHelper = props.__appHelper;
|
||||||
this.__compScopes = {};
|
this.__compScopes = {};
|
||||||
this.__instanceMap = {};
|
this.__instanceMap = {};
|
||||||
const { locale, messages } = props;
|
|
||||||
this.i18n = generateI18n(locale, messages);
|
|
||||||
this.__bindCustomMethods(props);
|
this.__bindCustomMethods(props);
|
||||||
|
this.__initI18nAPIs(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
__afterInit(props: IRendererProps) { }
|
__afterInit(props: IRendererProps) { }
|
||||||
@ -259,6 +259,15 @@ export default function baseRenererFactory() {
|
|||||||
); */
|
); */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__initI18nAPIs = () => {
|
||||||
|
this.i18n = (key: string, values = {}) => {
|
||||||
|
const { locale, messages } = this.props;
|
||||||
|
return getI18n(key, values, locale, messages);
|
||||||
|
};
|
||||||
|
this.getLocale = () => this.props.locale;
|
||||||
|
this.setLocale = (loc: string) => this.appHelper?.utils?.i18n?.setLocale && this.appHelper?.utils?.i18n?.setLocale(loc);
|
||||||
|
};
|
||||||
|
|
||||||
__render = () => {
|
__render = () => {
|
||||||
const schema = this.props.__schema;
|
const schema = this.props.__schema;
|
||||||
this.__setLifeCycleMethods('render');
|
this.__setLifeCycleMethods('render');
|
||||||
@ -328,6 +337,9 @@ export default function baseRenererFactory() {
|
|||||||
if (isJSExpression(schema)) {
|
if (isJSExpression(schema)) {
|
||||||
return parseExpression(schema, self);
|
return parseExpression(schema, self);
|
||||||
}
|
}
|
||||||
|
if (isI18n(schema)) {
|
||||||
|
return parseI18n(schema, self);
|
||||||
|
}
|
||||||
if (isJSSlot(schema)) {
|
if (isJSSlot(schema)) {
|
||||||
return this.__createVirtualDom(schema.value, self, parentInfo);
|
return this.__createVirtualDom(schema.value, self, parentInfo);
|
||||||
}
|
}
|
||||||
@ -581,11 +593,16 @@ export default function baseRenererFactory() {
|
|||||||
if (!isSchema(props) && !isJSSlot(props)) return checkProps(props);
|
if (!isSchema(props) && !isJSSlot(props)) return checkProps(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleI18n = (props: any) => props[props.use || 'zh_CN'];
|
const handleLegaoI18n = (props: any) => props[props.use || 'zh_CN'];
|
||||||
|
|
||||||
// 兼容乐高设计态 i18n 数据
|
// 兼容乐高设计态 i18n 数据
|
||||||
if (isI18n(props)) {
|
if (isI18n(props)) {
|
||||||
props = handleI18n(props);
|
const i18nProp = handleLegaoI18n(props);
|
||||||
|
if (i18nProp) {
|
||||||
|
props = i18nProp;
|
||||||
|
} else {
|
||||||
|
return parseI18n(props, self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 兼容乐高设计态的变量绑定
|
// 兼容乐高设计态的变量绑定
|
||||||
|
|||||||
@ -46,7 +46,8 @@ const EXPRESSION_TYPE = {
|
|||||||
JSEXPRESSION: 'JSExpression',
|
JSEXPRESSION: 'JSExpression',
|
||||||
JSFUNCTION: 'JSFunction',
|
JSFUNCTION: 'JSFunction',
|
||||||
JSSLOT: 'JSSlot',
|
JSSLOT: 'JSSlot',
|
||||||
JSBLOCK: 'JSBlock'
|
JSBLOCK: 'JSBlock',
|
||||||
|
I18N: 'i18n',
|
||||||
};
|
};
|
||||||
const EXPRESSION_REG = /^\{\{(\{.*\}|.*?)\}\}$/;
|
const EXPRESSION_REG = /^\{\{(\{.*\}|.*?)\}\}$/;
|
||||||
const hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
const hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
||||||
@ -112,6 +113,10 @@ export function isJSExpression(obj: any) {
|
|||||||
return isJSExpressionObj || isJSExpressionStr;
|
return isJSExpressionObj || isJSExpressionStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isI18n(obj) {
|
||||||
|
return obj && typeof obj === 'object' && EXPRESSION_TYPE.I18N === obj.type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name wait
|
* @name wait
|
||||||
* @description 等待函数
|
* @description 等待函数
|
||||||
@ -180,6 +185,19 @@ export function generateI18n(locale = 'zh-CN', messages: any = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于处理国际化字符串
|
||||||
|
* @param {*} key 语料标识
|
||||||
|
* @param {*} values 字符串模版变量
|
||||||
|
* @param {*} locale 国际化标识,例如 zh-CN、en-US
|
||||||
|
* @param {*} messages 国际化语言包
|
||||||
|
*/
|
||||||
|
export function getI18n(key: string, values = {}, locale = 'zh-CN', messages = {}) {
|
||||||
|
if (!messages || !messages[locale] || !messages[locale][key]) return '';
|
||||||
|
const formater = new IntlMessageFormat(messages[locale][key], locale);
|
||||||
|
return formater.format(values);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断当前组件是否能够设置ref
|
* 判断当前组件是否能够设置ref
|
||||||
* @param {*} Comp 需要判断的组件
|
* @param {*} Comp 需要判断的组件
|
||||||
@ -373,6 +391,8 @@ export function transformStringToFunction(str: string) {
|
|||||||
export function parseData(schema: any, self: any): any {
|
export function parseData(schema: any, self: any): any {
|
||||||
if (isJSExpression(schema)) {
|
if (isJSExpression(schema)) {
|
||||||
return parseExpression(schema, self);
|
return parseExpression(schema, self);
|
||||||
|
} else if (isI18n(schema)) {
|
||||||
|
return parseI18n(schema, self);
|
||||||
} else if (typeof schema === 'string') {
|
} else if (typeof schema === 'string') {
|
||||||
return schema.trim();
|
return schema.trim();
|
||||||
} else if (Array.isArray(schema)) {
|
} else if (Array.isArray(schema)) {
|
||||||
@ -423,10 +443,14 @@ export function capitalizeFirstLetter(word: string) {
|
|||||||
return word[0].toUpperCase() + word.slice(1);
|
return word[0].toUpperCase() + word.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isI18n(obj: any) {
|
|
||||||
return obj && typeof obj === 'object' && obj?.type === 'i18n';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isVariable(obj: any) {
|
export function isVariable(obj: any) {
|
||||||
return obj && typeof obj === 'object' && obj?.type === 'variable';
|
return obj && typeof obj === 'object' && obj?.type === 'variable';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 将 i18n 结构,降级解释为对 i18n 接口的调用 */
|
||||||
|
export function parseI18n(i18nInfo: any, self: any) {
|
||||||
|
return parseExpression({
|
||||||
|
type: EXPRESSION_TYPE.JSEXPRESSION,
|
||||||
|
value: `this.i18n('${i18nInfo.key}')`,
|
||||||
|
}, self);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user