From d3c891e2a46d138e31c81a7f9b804a8240154df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Fri, 23 Sep 2022 15:32:23 +0800 Subject: [PATCH] feat: support for NotFoundComponent design state is optional (#1013) --- .../designer/src/builtin-simulator/host.ts | 4 ++++ packages/designer/src/component-meta.ts | 21 ++++++++++++++-- .../tests/builtin-simulator/host.test.ts | 10 ++++++++ packages/editor-core/src/config.ts | 10 ++++++++ .../src/renderer-view.tsx | 1 + .../renderer/__snapshots__/demo.test.tsx.snap | 2 +- packages/renderer-core/src/adapter/index.ts | 12 +++++----- packages/renderer-core/src/renderer/base.tsx | 14 +++++------ .../renderer-core/src/renderer/renderer.tsx | 24 ++++++++++--------- packages/renderer-core/src/types/index.ts | 11 ++++++--- 10 files changed, 78 insertions(+), 31 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 2fadbbf1a..db8625adb 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -232,6 +232,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost false, + }, + }, + }, + }; + } this._npm = npm || this._npm; this._componentName = componentName; // 额外转换逻辑 - this._transformedMetadata = this.transformMetadata(metadata); + this._transformedMetadata = this.transformMetadata(_metadata); const { title } = this._transformedMetadata; if (title) { diff --git a/packages/designer/tests/builtin-simulator/host.test.ts b/packages/designer/tests/builtin-simulator/host.test.ts index 0329f06cb..746134c36 100644 --- a/packages/designer/tests/builtin-simulator/host.test.ts +++ b/packages/designer/tests/builtin-simulator/host.test.ts @@ -23,6 +23,7 @@ import { setShaken, } from '../../src/designer/dragon'; import { Project } from '../../src/project/project'; +import pageMetadata from '../fixtures/component-metadata/page'; import { Node } from '../../src/document/node/node'; import { Designer } from '../../src/designer/designer'; import { DocumentModel } from '../../src/document/document-model'; @@ -46,6 +47,7 @@ describe('Host 测试', () => { beforeEach(() => { designer = new Designer({ editor }); project = designer.project; + designer.createComponentMeta(pageMetadata); doc = project.createDocument(formSchema); host = new BuiltinSimulatorHost(designer.project); }); @@ -373,6 +375,14 @@ describe('Host 测试', () => { }, })).toBeNull(); }); + it('notFoundComponent', () => { + expect(host.locate({ + dragObject: { + type: DragObjectType.Node, + nodes: [doc.getNode('form')], + }, + })).toBeUndefined(); + }) it('locate', () => { host.locate({ dragObject: { diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 985980673..06600fd01 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -137,6 +137,10 @@ const VALID_ENGINE_OPTIONS = { type: 'boolean', description: 'JSExpression 是否只支持使用 this 来访问上下文变量', }, + enableStrictNotFoundMode: { + type: 'boolean', + description: '当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件', + }, }; export interface EngineOptions { /** @@ -258,6 +262,12 @@ export interface EngineOptions { * JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false */ thisRequiredInJSE?: boolean; + + /** + * @default false + * 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 + */ + enableStrictNotFoundMode?: boolean; } const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean): boolean => { diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx index d042a4fa9..e68d9c401 100644 --- a/packages/react-simulator-renderer/src/renderer-view.tsx +++ b/packages/react-simulator-renderer/src/renderer-view.tsx @@ -255,6 +255,7 @@ class Renderer extends Component<{ onCompGetRef={(schema: any, ref: ReactInstance | null) => { documentInstance.mountInstance(schema.id, ref); }} + enableStrictNotFoundMode={host.enableStrictNotFoundMode} /> ); } diff --git a/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap b/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap index afccf6241..0ebb606da 100644 --- a/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap +++ b/packages/react-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap @@ -11,7 +11,7 @@ exports[`Base should be render NotFoundComponent 1`] = `
- Component Not Found + Text Component Not Found
diff --git a/packages/renderer-core/src/adapter/index.ts b/packages/renderer-core/src/adapter/index.ts index 661b3c17f..12896b137 100644 --- a/packages/renderer-core/src/adapter/index.ts +++ b/packages/renderer-core/src/adapter/index.ts @@ -21,21 +21,21 @@ class Adapter { } initRuntime() { - const Component: IGeneralConstructor = class { + const Component: IGeneralConstructor = class { setState() {} forceUpdate() {} render() {} - state: Record; - props: Record; + state: Readonly; + props: Readonly & Readonly<{ children?: any | undefined }>; refs: Record; context: Record; }; - const PureComponent: IGeneralConstructor = class { + const PureComponent = class { setState() {} forceUpdate() {} render() {} - state: Record; - props: Record; + state: Readonly; + props: Readonly & Readonly<{ children?: any | undefined }>; refs: Record; context: Record; }; diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index aae951409..2d58cac76 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -104,13 +104,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { return customBaseRenderer; } - const runtime = adapter.getRuntime(); - const Component = runtime.Component as IGeneralConstructor< - IBaseRendererProps, - Record, - any - >; - const { createElement } = runtime; + const { Component, createElement } = adapter.getRuntime(); const Div = divFactory(); const VisualDom = visualDomFactory(); const AppContext = contextFactory(); @@ -125,7 +119,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const DEFAULT_LOOP_ARG_INDEX = 'index'; let scopeIdx = 0; - return class BaseRenderer extends Component { + return class BaseRenderer extends Component> { static displayName = 'BaseRenderer'; static defaultProps = { @@ -533,6 +527,10 @@ export default function baseRendererFactory(): IBaseRenderComponent { { componentName: schema.componentName, componentId: schema.id, + enableStrictNotFoundMode: engine.props.enableStrictNotFoundMode, + ref: (ref: any) => { + ref && engine.props?.onCompGetRef(schema, ref); + }, }, this.__getSchemaChildrenVirtualDom(schema, scope, Comp), ); diff --git a/packages/renderer-core/src/renderer/renderer.tsx b/packages/renderer-core/src/renderer/renderer.tsx index 8db681a5f..b308c251b 100644 --- a/packages/renderer-core/src/renderer/renderer.tsx +++ b/packages/renderer-core/src/renderer/renderer.tsx @@ -4,14 +4,11 @@ import contextFactory from '../context'; import { isFileSchema, isEmpty } from '../utils'; import baseRendererFactory from './base'; import divFactory from '../components/Div'; -import { IGeneralConstructor, IRenderComponent, IRendererProps, IRendererState } from '../types'; -import { RootSchema } from '@alilc/lowcode-types'; +import { IRenderComponent, IRendererProps, IRendererState } from '../types'; +import { NodeSchema, RootSchema } from '@alilc/lowcode-types'; export default function rendererFactory(): IRenderComponent { - const runtime = adapter.getRuntime(); - const Component = runtime.Component as IGeneralConstructor>; - const PureComponent = runtime.PureComponent as IGeneralConstructor>; - const { createElement, findDOMNode } = runtime; + const { PureComponent, Component, createElement, findDOMNode } = adapter.getRuntime(); const RENDERER_COMPS: any = adapter.getRenderers(); const BaseRenderer = baseRendererFactory(); const AppContext = contextFactory(); @@ -21,7 +18,7 @@ export default function rendererFactory(): IRenderComponent { const debug = Debug('renderer:entry'); - class FaultComponent extends PureComponent { + class FaultComponent extends PureComponent { render() { // FIXME: errorlog console.error('render error', this.props); @@ -35,17 +32,22 @@ export default function rendererFactory(): IRenderComponent { color: '#ff0000', border: '2px solid #ff0000', }, - }, '组件渲染异常,请查看控制台日志'); + }, `${this.props.componentName || ''} 组件渲染异常,请查看控制台日志`); } } - class NotFoundComponent extends PureComponent { + class NotFoundComponent extends PureComponent<{ + componentName: string; + } & IRendererProps> { render() { - return createElement(Div, this.props, this.props.children || 'Component Not Found'); + if (this.props.enableStrictNotFoundMode) { + return `${this.props.componentName || ''} Component Not Found`; + } + return createElement(Div, this.props, this.props.children || `${this.props.componentName || ''} Component Not Found`); } } - return class Renderer extends Component { + return class Renderer extends Component { static displayName = 'Renderer'; state: Partial = {}; diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index 9f0880633..2a4c0975e 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -21,12 +21,12 @@ interface IGeneralComponent

extends ComponentLifecycle } export type IGeneralConstructor< - P = { + T = { [key: string]: any; }, S = { [key: string]: any; - }, SS = any -> = new (props: any, context: any) => IGeneralComponent; + }, D = any +> = new (props: TT, context: any) => IGeneralComponent; /** * duck-typed History @@ -133,6 +133,11 @@ export interface IRendererProps { * JSExpression 是否只支持使用 this 来访问上下文变量 */ thisRequiredInJSE?: boolean; + /** + * @default false + * 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 + */ + enableStrictNotFoundMode?: boolean; } export interface IRendererState {