mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-10 18:03:01 +00:00
feat: improve lowcode component error state in simulator renderer (#1818)
* feat: improve lowcode component error state in simulator renderer * chore: use faultComponentMap instead of ComponentRender.FaultComponent
This commit is contained in:
parent
d0c3c0f13c
commit
d64da1e065
@ -52,6 +52,8 @@ module.exports = {
|
|||||||
'error',
|
'error',
|
||||||
{ default: ['signature', 'field', 'constructor', 'method'] }
|
{ default: ['signature', 'field', 'constructor', 'method'] }
|
||||||
],
|
],
|
||||||
'@typescript-eslint/no-unused-vars': ['error']
|
'@typescript-eslint/no-unused-vars': ['error'],
|
||||||
|
'no-redeclare': 0,
|
||||||
|
'@typescript-eslint/no-redeclare': 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -234,6 +234,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
|||||||
return engineConfig.get('faultComponent') ?? null;
|
return engineConfig.get('faultComponent') ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get faultComponentMap(): any {
|
||||||
|
return engineConfig.get('faultComponentMap') ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
@computed get componentsAsset(): Asset | undefined {
|
@computed get componentsAsset(): Asset | undefined {
|
||||||
return this.get('componentsAsset');
|
return this.get('componentsAsset');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -195,6 +195,7 @@ class Renderer extends Component<{
|
|||||||
thisRequiredInJSE={host.thisRequiredInJSE}
|
thisRequiredInJSE={host.thisRequiredInJSE}
|
||||||
notFoundComponent={host.notFoundComponent}
|
notFoundComponent={host.notFoundComponent}
|
||||||
faultComponent={host.faultComponent}
|
faultComponent={host.faultComponent}
|
||||||
|
faultComponentMap={host.faultComponentMap}
|
||||||
customCreateElement={(Component: any, props: any, children: any) => {
|
customCreateElement={(Component: any, props: any, children: any) => {
|
||||||
const { __id, ...viewProps } = props;
|
const { __id, ...viewProps } = props;
|
||||||
viewProps.componentId = __id;
|
viewProps.componentId = __id;
|
||||||
|
|||||||
@ -465,6 +465,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
|||||||
rendererName: 'LowCodeRenderer',
|
rendererName: 'LowCodeRenderer',
|
||||||
thisRequiredInJSE: host.thisRequiredInJSE,
|
thisRequiredInJSE: host.thisRequiredInJSE,
|
||||||
faultComponent: host.faultComponent,
|
faultComponent: host.faultComponent,
|
||||||
|
faultComponentMap: host.faultComponentMap,
|
||||||
customCreateElement: (Comp: any, props: any, children: any) => {
|
customCreateElement: (Comp: any, props: any, children: any) => {
|
||||||
const componentMeta = host.currentDocument?.getComponentMeta(Comp.displayName);
|
const componentMeta = host.currentDocument?.getComponentMeta(Comp.displayName);
|
||||||
if (componentMeta?.isModal) {
|
if (componentMeta?.isModal) {
|
||||||
@ -629,6 +630,7 @@ function getLowCodeComponentProps(props: any) {
|
|||||||
}
|
}
|
||||||
newProps[k] = props[k];
|
newProps[k] = props[k];
|
||||||
});
|
});
|
||||||
|
newProps['componentName'] = props['_componentName'];
|
||||||
return newProps;
|
return newProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -161,7 +161,9 @@ export default function baseRendererFactory(): IBaseRenderComponent {
|
|||||||
constructor(props: IBaseRendererProps, context: IBaseRendererContext) {
|
constructor(props: IBaseRendererProps, context: IBaseRendererContext) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.__parseExpression = props?.thisRequiredInJSE ? parseThisRequiredExpression : parseExpression;
|
this.__parseExpression = (str: string, self: any) => {
|
||||||
|
return parseExpression({ str, self, thisRequired: props?.thisRequiredInJSE, logScope: props.componentName });
|
||||||
|
};
|
||||||
this.__beforeInit(props);
|
this.__beforeInit(props);
|
||||||
this.__init(props);
|
this.__init(props);
|
||||||
this.__afterInit(props);
|
this.__afterInit(props);
|
||||||
@ -299,8 +301,8 @@ export default function baseRendererFactory(): IBaseRenderComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
__parseData = (data: any, ctx?: Record<string, any>) => {
|
__parseData = (data: any, ctx?: Record<string, any>) => {
|
||||||
const { __ctx, thisRequiredInJSE } = this.props;
|
const { __ctx, thisRequiredInJSE, componentName } = this.props;
|
||||||
return parseData(data, ctx || __ctx || this, { thisRequiredInJSE });
|
return parseData(data, ctx || __ctx || this, { thisRequiredInJSE, logScope: componentName });
|
||||||
};
|
};
|
||||||
|
|
||||||
__initDataSource = (props: IBaseRendererProps) => {
|
__initDataSource = (props: IBaseRendererProps) => {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export default function rendererFactory(): IRenderComponent {
|
|||||||
|
|
||||||
class FaultComponent extends PureComponent<IPublicTypeNodeSchema | any> {
|
class FaultComponent extends PureComponent<IPublicTypeNodeSchema | any> {
|
||||||
render() {
|
render() {
|
||||||
logger.error(`%c组件渲染异常, 异常原因: ${this.props.error?.message || this.props.error || '未知'}`, 'color: #ff0000;');
|
logger.error(`%c${this.props.componentName || ''} 组件渲染异常, 异常原因: ${this.props.error?.message || this.props.error || '未知'}`, 'color: #ff0000;');
|
||||||
return createElement(Div, {
|
return createElement(Div, {
|
||||||
style: {
|
style: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@ -159,7 +159,25 @@ export default function rendererFactory(): IRenderComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFaultComponent() {
|
getFaultComponent() {
|
||||||
return this.props.faultComponent || FaultComponent;
|
const { faultComponent, faultComponentMap, schema } = this.props;
|
||||||
|
if (faultComponentMap) {
|
||||||
|
const { componentName } = schema;
|
||||||
|
return faultComponentMap[componentName] || faultComponent || FaultComponent;
|
||||||
|
}
|
||||||
|
return faultComponent || FaultComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
getComp() {
|
||||||
|
const { schema, components } = this.props;
|
||||||
|
const { componentName } = schema;
|
||||||
|
const allComponents = { ...RENDERER_COMPS, ...components };
|
||||||
|
let Comp = allComponents[componentName] || RENDERER_COMPS[`${componentName}Renderer`];
|
||||||
|
if (Comp && Comp.prototype) {
|
||||||
|
if (!(Comp.prototype instanceof BaseRenderer)) {
|
||||||
|
Comp = RENDERER_COMPS[`${componentName}Renderer`];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -173,14 +191,8 @@ export default function rendererFactory(): IRenderComponent {
|
|||||||
return '模型结构异常';
|
return '模型结构异常';
|
||||||
}
|
}
|
||||||
debug('entry.render');
|
debug('entry.render');
|
||||||
const { componentName } = schema;
|
|
||||||
const allComponents = { ...RENDERER_COMPS, ...components };
|
const allComponents = { ...RENDERER_COMPS, ...components };
|
||||||
let Comp = allComponents[componentName] || RENDERER_COMPS[`${componentName}Renderer`];
|
let Comp = this.getComp();
|
||||||
if (Comp && Comp.prototype) {
|
|
||||||
if (!(Comp.prototype instanceof BaseRenderer)) {
|
|
||||||
Comp = RENDERER_COMPS[`${componentName}Renderer`];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state && this.state.engineRenderError) {
|
if (this.state && this.state.engineRenderError) {
|
||||||
return createElement(this.getFaultComponent(), {
|
return createElement(this.getFaultComponent(), {
|
||||||
@ -190,11 +202,13 @@ export default function rendererFactory(): IRenderComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Comp) {
|
if (Comp) {
|
||||||
return createElement(AppContext.Provider, { value: {
|
return createElement(AppContext.Provider, {
|
||||||
appHelper,
|
value: {
|
||||||
components: allComponents,
|
appHelper,
|
||||||
engine: this,
|
components: allComponents,
|
||||||
} }, createElement(ConfigProvider, {
|
engine: this,
|
||||||
|
},
|
||||||
|
}, createElement(ConfigProvider, {
|
||||||
device: this.props.device,
|
device: this.props.device,
|
||||||
locale: this.props.locale,
|
locale: this.props.locale,
|
||||||
}, createElement(Comp, {
|
}, createElement(Comp, {
|
||||||
|
|||||||
@ -160,6 +160,11 @@ export interface IRendererProps {
|
|||||||
/** 当组件渲染异常时,显示的组件 */
|
/** 当组件渲染异常时,显示的组件 */
|
||||||
faultComponent?: IGeneralComponent;
|
faultComponent?: IGeneralComponent;
|
||||||
|
|
||||||
|
/** */
|
||||||
|
faultComponentMap?: {
|
||||||
|
[prop: string]: IGeneralComponent;
|
||||||
|
};
|
||||||
|
|
||||||
/** 设备信息 */
|
/** 设备信息 */
|
||||||
device?: string;
|
device?: string;
|
||||||
|
|
||||||
@ -208,6 +213,7 @@ export interface IBaseRendererProps {
|
|||||||
* 设备类型,默认值:'default'
|
* 设备类型,默认值:'default'
|
||||||
*/
|
*/
|
||||||
device?: 'default' | 'mobile' | string;
|
device?: 'default' | 'mobile' | string;
|
||||||
|
componentName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INodeInfo {
|
export interface INodeInfo {
|
||||||
|
|||||||
@ -157,6 +157,7 @@ export function canAcceptsRef(Comp: any) {
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
return Comp?.$$typeof === REACT_FORWARD_REF_TYPE || Comp?.prototype?.isReactComponent || Comp?.prototype?.setState || Comp._forwardRef;
|
return Comp?.$$typeof === REACT_FORWARD_REF_TYPE || Comp?.prototype?.isReactComponent || Comp?.prototype?.setState || Comp._forwardRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* transform array to a object
|
* transform array to a object
|
||||||
* @param arr array to be transformed
|
* @param arr array to be transformed
|
||||||
@ -207,7 +208,6 @@ export function checkPropTypes(value: any, name: string, rule: any, componentNam
|
|||||||
return !err;
|
return !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* transform string to a function
|
* transform string to a function
|
||||||
* @param str function in string form
|
* @param str function in string form
|
||||||
@ -230,7 +230,26 @@ export function transformStringToFunction(str: string) {
|
|||||||
* @param self scope object
|
* @param self scope object
|
||||||
* @returns funtion
|
* @returns funtion
|
||||||
*/
|
*/
|
||||||
export function parseExpression(str: any, self: any, thisRequired = false) {
|
|
||||||
|
function parseExpression(options: {
|
||||||
|
str: any; self: any; thisRequired?: boolean; logScope?: string;
|
||||||
|
}): any;
|
||||||
|
function parseExpression(str: any, self: any, thisRequired?: boolean): any;
|
||||||
|
function parseExpression(a: any, b?: any, c = false) {
|
||||||
|
let str;
|
||||||
|
let self;
|
||||||
|
let thisRequired;
|
||||||
|
let logScope;
|
||||||
|
if (typeof a === 'object' && b === undefined) {
|
||||||
|
str = a.str;
|
||||||
|
self = a.self;
|
||||||
|
thisRequired = a.thisRequired;
|
||||||
|
logScope = a.logScope;
|
||||||
|
} else {
|
||||||
|
str = a;
|
||||||
|
self = b;
|
||||||
|
thisRequired = c;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const contextArr = ['"use strict";', 'var __self = arguments[0];'];
|
const contextArr = ['"use strict";', 'var __self = arguments[0];'];
|
||||||
contextArr.push('return ');
|
contextArr.push('return ');
|
||||||
@ -250,11 +269,15 @@ export function parseExpression(str: any, self: any, thisRequired = false) {
|
|||||||
const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`;
|
const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`;
|
||||||
return new Function('$scope', code)(self);
|
return new Function('$scope', code)(self);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('parseExpression.error', err, str, self?.__self ?? self);
|
logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
parseExpression,
|
||||||
|
};
|
||||||
|
|
||||||
export function parseThisRequiredExpression(str: any, self: any) {
|
export function parseThisRequiredExpression(str: any, self: any) {
|
||||||
return parseExpression(str, self, true);
|
return parseExpression(str, self, true);
|
||||||
}
|
}
|
||||||
@ -320,11 +343,17 @@ export function forEach(targetObj: any, fn: any, context?: any) {
|
|||||||
|
|
||||||
interface IParseOptions {
|
interface IParseOptions {
|
||||||
thisRequiredInJSE?: boolean;
|
thisRequiredInJSE?: boolean;
|
||||||
|
logScope?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseData(schema: unknown, self: any, options: IParseOptions = {}): any {
|
export function parseData(schema: unknown, self: any, options: IParseOptions = {}): any {
|
||||||
if (isJSExpression(schema)) {
|
if (isJSExpression(schema)) {
|
||||||
return parseExpression(schema, self, options.thisRequiredInJSE);
|
return parseExpression({
|
||||||
|
str: schema,
|
||||||
|
self,
|
||||||
|
thisRequired: options.thisRequiredInJSE,
|
||||||
|
logScope: options.logScope,
|
||||||
|
});
|
||||||
} else if (isI18nData(schema)) {
|
} else if (isI18nData(schema)) {
|
||||||
return parseI18n(schema, self);
|
return parseI18n(schema, self);
|
||||||
} else if (typeof schema === 'string') {
|
} else if (typeof schema === 'string') {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user