From f5438ff1abe6067ddb2e267fa8b905dca589138e Mon Sep 17 00:00:00 2001 From: Minglong Li <790669171@qq.com> Date: Fri, 12 May 2023 21:50:44 +0800 Subject: [PATCH 001/361] fix: return first if input schema is a react dom --- packages/renderer-core/src/renderer/base.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 56f58599b0..99a9a40cfa 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -493,6 +493,11 @@ export default function baseRendererFactory(): IBaseRenderComponent { return schema.map((item, idy) => this.__createVirtualDom(item, scope, parentInfo, (item as IPublicTypeNodeSchema)?.__ctx?.lceKey ? '' : String(idy))); } + // @ts-expect-error 如果直接转换好了,可以返回 + if (schema.$$typeof) { + return schema; + } + const _children = getSchemaChildren(schema); if (!schema.componentName) { logger.error('The componentName in the schema is invalid, please check the schema: ', schema); @@ -510,11 +515,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { schema.children = [text]; } - // @ts-expect-error 如果直接转换好了,可以返回 - if (schema.$$typeof) { - return schema; - } - if (!isSchema(schema)) { return null; } From ee80fb12b864f2ddd657fe1503e57f755697d07a Mon Sep 17 00:00:00 2001 From: liujuping Date: Tue, 16 May 2023 18:05:16 +0800 Subject: [PATCH 002/361] feat: workspace add some features --- packages/editor-core/src/config.ts | 5 +++++ packages/shell/src/api/workspace.ts | 4 ++-- packages/types/src/shell/api/workspace.ts | 8 +++++++- packages/types/src/shell/model/plugin-context.ts | 4 +++- packages/workspace/src/workspace.ts | 6 +++--- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 4f0f708e7d..c325c2bb85 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -150,6 +150,11 @@ const VALID_ENGINE_OPTIONS = { description: '应用级设计模式下,自动打开第一个窗口', default: true, }, + enableWorkspaceMode: { + type: 'boolean', + description: '是否开启应用级设计模式', + default: false, + }, }; const getStrictModeValue = (engineOptions: IPublicTypeEngineOptions, defaultValue: boolean): boolean => { diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index bfc7b27e1e..8192ac67d4 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -42,8 +42,8 @@ export class Workspace implements IPublicApiWorkspace { this[workspaceSymbol].registerResourceType(resourceTypeModel); } - openEditorWindow(resourceName: string, title: string, extra: object, viewName?: string, sleep?: boolean): void { - this[workspaceSymbol].openEditorWindow(resourceName, title, extra, viewName, sleep); + async openEditorWindow(resourceName: string, title: string, extra: object, viewName?: string, sleep?: boolean): Promise { + await this[workspaceSymbol].openEditorWindow(resourceName, title, extra, viewName, sleep); } openEditorWindowById(id: string) { diff --git a/packages/types/src/shell/api/workspace.ts b/packages/types/src/shell/api/workspace.ts index 8904a8231c..8ae2434bc5 100644 --- a/packages/types/src/shell/api/workspace.ts +++ b/packages/types/src/shell/api/workspace.ts @@ -30,7 +30,7 @@ export interface IPublicApiWorkspace< registerResourceType(resourceTypeModel: IPublicTypeResourceType): void; /** 打开视图窗口 */ - openEditorWindow(resourceName: string, title: string, extra: Object, viewName?: string, sleep?: boolean): void; + openEditorWindow(resourceName: string, title: string, extra: Object, viewName?: string, sleep?: boolean): Promise; /** 通过视图 id 打开窗口 */ openEditorWindowById(id: string): void; @@ -47,6 +47,12 @@ export interface IPublicApiWorkspace< /** active 窗口变更事件 */ onChangeActiveWindow(fn: () => void): IPublicTypeDisposable; + /** + * active 视图变更事件 + * @since v1.1.7 + */ + onChangeActiveEditorView(fn: () => void): IPublicTypeDisposable; + /** * window 下的所有视图 renderer ready 事件 * @since v1.1.7 diff --git a/packages/types/src/shell/model/plugin-context.ts b/packages/types/src/shell/model/plugin-context.ts index e670e54ea3..ea6fb71023 100644 --- a/packages/types/src/shell/model/plugin-context.ts +++ b/packages/types/src/shell/model/plugin-context.ts @@ -13,7 +13,7 @@ import { IPublicApiWorkspace, } from '../api'; import { IPublicEnumPluginRegisterLevel } from '../enum'; -import { IPublicModelEngineConfig } from './'; +import { IPublicModelEngineConfig, IPublicModelEditorView } from './'; export interface IPublicModelPluginContext { @@ -107,6 +107,8 @@ export interface IPublicModelPluginContext { * @since v1.1.7 */ get registerLevel(): IPublicEnumPluginRegisterLevel; + + get editorWindow(): IPublicModelEditorView; } /** diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 33daf064a1..ba3d91c41d 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -128,7 +128,7 @@ export class Workspace implements IWorkspace { title: resource.title, }); this.editorWindowMap.set(this.window.id, this.window); - this.windows.push(this.window); + this.windows = [...this.windows, this.window]; this.emitChangeWindow(); this.emitChangeActiveWindow(); } @@ -214,7 +214,7 @@ export class Workspace implements IWorkspace { } } - openEditorWindow(name: string, title: string, options: Object, viewType?: string, sleep?: boolean) { + async openEditorWindow(name: string, title: string, options: Object, viewType?: string, sleep?: boolean) { if (this.window && !this.window?.initReady && !sleep) { this.windowQueue.push({ name, title, options, viewType, @@ -230,7 +230,7 @@ export class Workspace implements IWorkspace { if (filterWindows && filterWindows.length) { this.window = filterWindows[0]; if (!sleep && this.window.sleep) { - this.window.init(); + await this.window.init(); } else { this.checkWindowQueue(); } From 2b3d96cedada3f3c3f91f16129aadee466052b9b Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 17 May 2023 18:57:09 +0800 Subject: [PATCH 003/361] feat: canvas.activeTracker add targer prop --- .../designer/src/designer/active-tracker.ts | 6 ++-- .../src/controllers/tree-master.ts | 36 ++++++++++--------- packages/shell/src/model/active-tracker.ts | 10 ++++++ .../types/src/shell/model/active-tracker.ts | 6 ++++ packages/workspace/src/resource.ts | 5 ++- 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/packages/designer/src/designer/active-tracker.ts b/packages/designer/src/designer/active-tracker.ts index 27a7090f8e..74d865673f 100644 --- a/packages/designer/src/designer/active-tracker.ts +++ b/packages/designer/src/designer/active-tracker.ts @@ -7,6 +7,8 @@ import { import { isNode } from '@alilc/lowcode-utils'; export interface IActiveTracker extends Omit< IPublicModelActiveTracker, 'track' | 'onChange' > { + _target: ActiveTarget | INode; + track(originalTarget: ActiveTarget | INode): void; onChange(fn: (target: ActiveTarget) => void): () => void; @@ -17,10 +19,10 @@ export interface ActiveTarget extends Omit< IPublicTypeActiveTarget, 'node' > { } export class ActiveTracker implements IActiveTracker { - private emitter: IEventBus = createModuleEventBus('ActiveTracker'); - @obx.ref private _target?: ActiveTarget | INode; + private emitter: IEventBus = createModuleEventBus('ActiveTracker'); + track(originalTarget: ActiveTarget | INode) { let target = originalTarget; if (isNode(originalTarget)) { diff --git a/packages/plugin-outline-pane/src/controllers/tree-master.ts b/packages/plugin-outline-pane/src/controllers/tree-master.ts index cb62980482..40162d808f 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-master.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-master.ts @@ -90,28 +90,29 @@ export class TreeMaster { private initEvent() { let startTime: any; const { event, project, canvas } = this.pluginContext; + const setExpandByActiveTracker = (target: IPublicTypeActiveTarget) => { + const { node, detail } = target; + const tree = this.currentTree; + if (!tree/* || node.document !== tree.document */) { + return; + } + const treeNode = tree.getTreeNode(node); + if (detail && isLocationChildrenDetail(detail)) { + treeNode.expand(true); + } else { + treeNode.expandParents(); + } + this.boards.forEach((board) => { + board.scrollToNode(treeNode, detail); + }); + }; this.disposeEvents = [ canvas.dragon?.onDragstart(() => { startTime = Date.now() / 1000; // needs? this.toVision(); }), - canvas.activeTracker?.onChange((target: IPublicTypeActiveTarget) => { - const { node, detail } = target; - const tree = this.currentTree; - if (!tree/* || node.document !== tree.document */) { - return; - } - const treeNode = tree.getTreeNode(node); - if (detail && isLocationChildrenDetail(detail)) { - treeNode.expand(true); - } else { - treeNode.expandParents(); - } - this.boards.forEach((board) => { - board.scrollToNode(treeNode, detail); - }); - }), + canvas.activeTracker?.onChange(setExpandByActiveTracker), canvas.dragon?.onDragend(() => { const endTime: any = Date.now() / 1000; const nodes = project.currentDocument?.selection?.getNodes(); @@ -135,6 +136,9 @@ export class TreeMaster { this.treeMap.delete(id); }), ]; + if (canvas.activeTracker?.target) { + setExpandByActiveTracker(canvas.activeTracker?.target); + } } private toVision() { diff --git a/packages/shell/src/model/active-tracker.ts b/packages/shell/src/model/active-tracker.ts index 41871aacba..e6170b7a68 100644 --- a/packages/shell/src/model/active-tracker.ts +++ b/packages/shell/src/model/active-tracker.ts @@ -12,6 +12,16 @@ export class ActiveTracker implements IPublicModelActiveTracker { this[activeTrackerSymbol] = innerTracker; } + get target() { + const { node: innerNode, detail, instance } = this[activeTrackerSymbol]._target; + const publicNode = ShellNode.create(innerNode); + return { + node: publicNode!, + detail, + instance, + }; + } + onChange(fn: (target: IPublicTypeActiveTarget) => void): () => void { if (!fn) { return () => {}; diff --git a/packages/types/src/shell/model/active-tracker.ts b/packages/types/src/shell/model/active-tracker.ts index b0ceec11fb..2538a26017 100644 --- a/packages/types/src/shell/model/active-tracker.ts +++ b/packages/types/src/shell/model/active-tracker.ts @@ -2,6 +2,12 @@ import { IPublicTypeActiveTarget } from '../type'; import { IPublicModelNode } from './node'; export interface IPublicModelActiveTracker { + + /** + * @since 1.1.7 + */ + target: IPublicTypeActiveTarget; + onChange(fn: (target: IPublicTypeActiveTarget) => void): () => void; track(node: IPublicModelNode): void; diff --git a/packages/workspace/src/resource.ts b/packages/workspace/src/resource.ts index 8c59aed1ef..4b695d036d 100644 --- a/packages/workspace/src/resource.ts +++ b/packages/workspace/src/resource.ts @@ -70,9 +70,7 @@ export class Resource implements IResource { return this.context.innerSkeleton; } - get children(): IResource[] { - return this.resourceData?.children?.map(d => new Resource(d, this.workspace.getResourceType(d.resourceName || this.resourceType.name), this.workspace)) || []; - } + children: IResource[]; get config() { return this.resourceData.config; @@ -92,6 +90,7 @@ export class Resource implements IResource { if (!resourceType) { logger.error(`resourceType[${resourceType}] is unValid.`); } + this.children = this.resourceData?.children?.map(d => new Resource(d, this.workspace.getResourceType(d.resourceName || this.resourceType.name), this.workspace)) || []; } async init() { From 059ffe0eaac7c82ca3a97789a25a0eed0f57a2c3 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 17 May 2023 17:22:10 +0800 Subject: [PATCH 004/361] feat: improve the workspace sleep scene --- packages/workspace/src/window.ts | 6 ++---- packages/workspace/src/workspace.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index 41b9c53ea2..0e37b4986e 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -51,9 +51,6 @@ export class EditorWindow implements IEditorWindow { this.title = config.title; this.icon = resource.icon; this.sleep = config.sleep; - if (!config.sleep) { - this.init(); - } } async importSchema(schema: any) { @@ -155,6 +152,8 @@ export class EditorWindow implements IEditorWindow { return; } + this.editorView.setActivate(true); + if (!ignoreEmit) { this.emitter.emit('window.change.view.type', name); @@ -162,7 +161,6 @@ export class EditorWindow implements IEditorWindow { this.workspace.emitChangeActiveEditorView(); } } - this.editorView.setActivate(true); }; get project() { diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index ba3d91c41d..46c8c4a0e1 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -115,7 +115,7 @@ export class Workspace implements IWorkspace { } } - initWindow() { + async initWindow() { if (!this.defaultResourceType || this.enableAutoOpenFirstWindow === false) { return; } @@ -127,6 +127,7 @@ export class Workspace implements IWorkspace { this.window = new EditorWindow(resource, this, { title: resource.title, }); + await this.window.init(); this.editorWindowMap.set(this.window.id, this.window); this.windows = [...this.windows, this.window]; this.emitChangeWindow(); @@ -196,6 +197,9 @@ export class Workspace implements IWorkspace { this.windows.splice(index, 1); if (this.window === window) { this.window = this.windows[index] || this.windows[index + 1] || this.windows[index - 1]; + if (this.window.sleep) { + this.window.init(); + } this.emitChangeActiveWindow(); } this.emitChangeWindow(); @@ -206,10 +210,13 @@ export class Workspace implements IWorkspace { this.remove(index); } - openEditorWindowById(id: string) { + async openEditorWindowById(id: string) { const window = this.editorWindowMap.get(id); if (window) { this.window = window; + if (window.sleep) { + await window.init(); + } this.emitChangeActiveWindow(); } } @@ -252,6 +259,7 @@ export class Workspace implements IWorkspace { this.editorWindowMap.set(window.id, window); if (!sleep) { this.window = window; + await this.window.init(); } this.emitChangeWindow(); this.emitChangeActiveWindow(); From 8b44ed44295aa66105c9799fcd41f360c411e324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E6=9E=97?= Date: Wed, 17 May 2023 19:57:15 +0800 Subject: [PATCH 005/361] fix: fix outlinePane treeView render only once --- .../plugin-outline-pane/src/views/pane.tsx | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/plugin-outline-pane/src/views/pane.tsx b/packages/plugin-outline-pane/src/views/pane.tsx index 36a2bfa0b7..4b807ca180 100644 --- a/packages/plugin-outline-pane/src/views/pane.tsx +++ b/packages/plugin-outline-pane/src/views/pane.tsx @@ -17,7 +17,9 @@ export class Pane extends PureComponent<{ }> { private controller; - private dispose: IPublicTypeDisposable; + private simulatorRendererReadyDispose: IPublicTypeDisposable; + private changeDocumentDispose: IPublicTypeDisposable; + private removeDocumentDispose: IPublicTypeDisposable; constructor(props: any) { super(props); @@ -26,16 +28,22 @@ export class Pane extends PureComponent<{ this.state = { tree: treeMaster.currentTree, }; - this.dispose = this.props.treeMaster.pluginContext?.project?.onSimulatorRendererReady(() => { - this.setState({ - tree: this.props.treeMaster.currentTree, - }); - }); + this.simulatorRendererReadyDispose = this.props.treeMaster.pluginContext?.project?.onSimulatorRendererReady(this.changeTree); + this.changeDocumentDispose = this.props.treeMaster.pluginContext?.project?.onChangeDocument(this.changeTree); + this.removeDocumentDispose = this.props.treeMaster.pluginContext?.project?.onRemoveDocument(this.changeTree); } + changeTree = () => { + this.setState({ + tree: this.props.treeMaster.currentTree, + }); + }; + componentWillUnmount() { this.controller.purge(); - this.dispose && this.dispose(); + this.simulatorRendererReadyDispose?.(); + this.changeDocumentDispose?.(); + this.removeDocumentDispose?.(); } render() { From be4b16440ec7a6597c72112d75df389e2bcd18b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 18 May 2023 17:25:08 +0800 Subject: [PATCH 006/361] fix: skip internal dep when type is pages, closes #2049 --- modules/code-generator/src/parser/SchemaParser.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index c6263877c1..b4f7424ce5 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -106,6 +106,11 @@ function processChildren(schema: IPublicTypeNodeSchema): void { } } +function getInternalDep(internalDeps: Record, depName: string) { + const dep = internalDeps[depName]; + return (dep && dep.type !== InternalDependencyType.PAGE) ? dep : null; +} + export class SchemaParser implements ISchemaParser { validate(schema: IPublicTypeProjectSchema): boolean { if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) { @@ -221,12 +226,11 @@ export class SchemaParser implements ISchemaParser { } }); - // 分析容器内部组件依赖 containers.forEach((container) => { const depNames = this.getComponentNames(container); // eslint-disable-next-line no-param-reassign container.deps = uniqueArray(depNames, (i: string) => i) - .map((depName) => internalDeps[depName] || compDeps[depName]) + .map((depName) => getInternalDep(internalDeps, depName) || compDeps[depName]) .filter(Boolean); // container.deps = Object.keys(compDeps).map((depName) => compDeps[depName]); }); From fa5168b4a824feee0ee9522990ba65e0583d3a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 19 May 2023 11:23:05 +0800 Subject: [PATCH 007/361] fix: add Fusion-UI style for code generation --- .../code-generator/src/plugins/common/styleImport.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/code-generator/src/plugins/common/styleImport.ts b/modules/code-generator/src/plugins/common/styleImport.ts index c340900eab..23e1293025 100644 --- a/modules/code-generator/src/plugins/common/styleImport.ts +++ b/modules/code-generator/src/plugins/common/styleImport.ts @@ -21,6 +21,7 @@ const pluginFactory: BuilderComponentPluginFactory = () => { if (ir && ir.deps && ir.deps.length > 0) { let lowcodeMaterialsStyleAdded = false; + let fusionUIStyleAdded = false; let nextStyleAddedMap: Record = {}; ir.deps.forEach((dep: any) => { if (dep.package === '@alifd/next' && !nextStyleAddedMap[dep.exportName]) { @@ -41,6 +42,15 @@ const pluginFactory: BuilderComponentPluginFactory = () => { linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport], }); lowcodeMaterialsStyleAdded = true; + } else if (dep.package === '@alifd/fusion-ui' && !fusionUIStyleAdded) { + chunks.push({ + type: ChunkType.STRING, + fileType: FileType.JSX, + name: COMMON_CHUNK_NAME.InternalDepsImport, + content: 'import \'@alifd/fusion-ui/lib/style\';', + linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport], + }); + fusionUIStyleAdded = true; } }); } From ee8717bb97b4ebd815197355d278909e77fd54a7 Mon Sep 17 00:00:00 2001 From: LiGuangNian <792841450@qq.com> Date: Fri, 19 May 2023 16:09:56 +0800 Subject: [PATCH 008/361] Update node-children.md --- docs/docs/api/model/node-children.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/api/model/node-children.md b/docs/docs/api/model/node-children.md index 219e6bbc18..5507fcbfb8 100644 --- a/docs/docs/api/model/node-children.md +++ b/docs/docs/api/model/node-children.md @@ -62,11 +62,11 @@ delete(node: IPublicModelNode): boolean; ```typescript /** - * 删除指定节点 - * delete the node + * 插入一个节点 + * insert the node * @param node */ -delete(node: IPublicModelNode): boolean; +insert(node: IPublicModelNode): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) From 62288a139f6fc550e91c9ffbf0cc7fc1c6e64188 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 18 May 2023 10:43:58 +0800 Subject: [PATCH 009/361] feat: canvas.activeTracker.target returns add null --- packages/shell/src/model/active-tracker.ts | 8 +++++++- packages/types/src/shell/model/active-tracker.ts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/shell/src/model/active-tracker.ts b/packages/shell/src/model/active-tracker.ts index e6170b7a68..32d4c04eb9 100644 --- a/packages/shell/src/model/active-tracker.ts +++ b/packages/shell/src/model/active-tracker.ts @@ -13,7 +13,13 @@ export class ActiveTracker implements IPublicModelActiveTracker { } get target() { - const { node: innerNode, detail, instance } = this[activeTrackerSymbol]._target; + const _target = this[activeTrackerSymbol]._target; + + if (!_target) { + return null; + } + + const { node: innerNode, detail, instance } = _target; const publicNode = ShellNode.create(innerNode); return { node: publicNode!, diff --git a/packages/types/src/shell/model/active-tracker.ts b/packages/types/src/shell/model/active-tracker.ts index 2538a26017..ac116a9473 100644 --- a/packages/types/src/shell/model/active-tracker.ts +++ b/packages/types/src/shell/model/active-tracker.ts @@ -6,7 +6,7 @@ export interface IPublicModelActiveTracker { /** * @since 1.1.7 */ - target: IPublicTypeActiveTarget; + target: IPublicTypeActiveTarget | null; onChange(fn: (target: IPublicTypeActiveTarget) => void): () => void; From b984ef72d28f98a6e7a72ea3d051dc254f402749 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 19 May 2023 17:19:31 +0800 Subject: [PATCH 010/361] feat: workspace window add onSave api --- docs/docs/api/model/window.md | 15 +++++++++++++++ packages/plugin-outline-pane/src/index.tsx | 10 ++++++---- packages/shell/src/model/window.ts | 4 ++++ packages/types/src/shell/model/plugin-context.ts | 4 ++-- packages/types/src/shell/model/window.ts | 6 ++++++ packages/workspace/src/window.ts | 13 ++++++++++++- 6 files changed, 45 insertions(+), 7 deletions(-) diff --git a/docs/docs/api/model/window.md b/docs/docs/api/model/window.md index 3cc8b5d5e7..9db39996fa 100644 --- a/docs/docs/api/model/window.md +++ b/docs/docs/api/model/window.md @@ -45,6 +45,8 @@ sidebar_position: 12 关联模型 [IPublicModelEditorView](./editor-view) +**@since v1.1.7** + ### editorViews 窗口所有视图 @@ -53,6 +55,7 @@ sidebar_position: 12 关联模型 [IPublicModelEditorView](./editor-view) +**@since v1.1.7** ## 方法 @@ -90,3 +93,15 @@ onChangeViewType(fn: (viewName: string) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + +### onSave + +窗口视图保存事件 + +``` +onSave(fn: () => void): IPublicTypeDisposable; +``` + +相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + +**@since v1.1.7** diff --git a/packages/plugin-outline-pane/src/index.tsx b/packages/plugin-outline-pane/src/index.tsx index 95b219a4b1..180b424ea5 100644 --- a/packages/plugin-outline-pane/src/index.tsx +++ b/packages/plugin-outline-pane/src/index.tsx @@ -4,7 +4,7 @@ import { IPublicModelPluginContext, IPublicModelDocumentModel } from '@alilc/low import { MasterPaneName, BackupPaneName } from './helper/consts'; import { TreeMaster } from './controllers/tree-master'; import { PaneController } from './controllers/pane-controller'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; export function OutlinePaneContext(props: { treeMaster?: TreeMaster; @@ -19,9 +19,11 @@ export function OutlinePaneContext(props: { }) { const treeMaster = props.treeMaster || new TreeMaster(props.pluginContext, props.options); const [masterPaneController, setMasterPaneController] = useState(new PaneController(props.paneName || MasterPaneName, treeMaster)); - treeMaster.onPluginContextChange(() => { - setMasterPaneController(new PaneController(props.paneName || MasterPaneName, treeMaster)); - }); + useEffect(() => { + return treeMaster.onPluginContextChange(() => { + setMasterPaneController(new PaneController(props.paneName || MasterPaneName, treeMaster)); + }); + }, []); return ( void) { + return this[windowSymbol].onSave(fn); + } + get currentEditorView() { if (this[windowSymbol].editorView) { return new EditorView(this[windowSymbol].editorView).toProxy() as any; diff --git a/packages/types/src/shell/model/plugin-context.ts b/packages/types/src/shell/model/plugin-context.ts index ea6fb71023..1f3d3b5e85 100644 --- a/packages/types/src/shell/model/plugin-context.ts +++ b/packages/types/src/shell/model/plugin-context.ts @@ -13,7 +13,7 @@ import { IPublicApiWorkspace, } from '../api'; import { IPublicEnumPluginRegisterLevel } from '../enum'; -import { IPublicModelEngineConfig, IPublicModelEditorView } from './'; +import { IPublicModelEngineConfig, IPublicModelWindow } from './'; export interface IPublicModelPluginContext { @@ -108,7 +108,7 @@ export interface IPublicModelPluginContext { */ get registerLevel(): IPublicEnumPluginRegisterLevel; - get editorWindow(): IPublicModelEditorView; + get editorWindow(): IPublicModelWindow; } /** diff --git a/packages/types/src/shell/model/window.ts b/packages/types/src/shell/model/window.ts index a33be6ceb1..95ab738bc1 100644 --- a/packages/types/src/shell/model/window.ts +++ b/packages/types/src/shell/model/window.ts @@ -42,4 +42,10 @@ export interface IPublicModelWindow< /** 窗口视图变更事件 */ onChangeViewType(fn: (viewName: string) => void): IPublicTypeDisposable; + + /** + * 窗口视图保存事件 + * @since 1.1.7 + */ + onSave(fn: () => void): IPublicTypeDisposable; } \ No newline at end of file diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index 0e37b4986e..6fb706632a 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -77,7 +77,18 @@ export class EditorWindow implements IEditorWindow { const saveResult = await this.editorViews.get(name)?.save(); value[name] = saveResult; } - return await this.resource.save(value); + const result = await this.resource.save(value); + this.emitter.emit('handle.save'); + + return result; + } + + onSave(fn: () => void) { + this.emitter.on('handle.save', fn); + + return () => { + this.emitter.off('handle.save', fn); + }; } async init() { From 5dcd946dcaef10da291c686a6e22e99190f6d6ed Mon Sep 17 00:00:00 2001 From: Justin-lu Date: Mon, 22 May 2023 16:22:46 +0800 Subject: [PATCH 011/361] fix: this bind error --- packages/shell/src/api/setters.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/shell/src/api/setters.ts b/packages/shell/src/api/setters.ts index 56f42d18ba..7750a5152e 100644 --- a/packages/shell/src/api/setters.ts +++ b/packages/shell/src/api/setters.ts @@ -47,11 +47,11 @@ export class Setters implements IPublicApiSetters { * 获取已注册的所有 settersMap * @returns */ - getSettersMap(): Map { + }> => { return this[settersSymbol].getSettersMap(); - } + }; /** * 注册一个 setter From c78dd80c289495799f76709d7dde60b170b3a56e Mon Sep 17 00:00:00 2001 From: liujuping Date: Tue, 23 May 2023 17:37:29 +0800 Subject: [PATCH 012/361] feat: update modals visible state in outline pane --- .../plugin-outline-pane/src/controllers/tree-node.ts | 4 +++- packages/plugin-outline-pane/src/controllers/tree.ts | 5 +++++ .../plugin-outline-pane/src/views/tree-title.tsx | 12 +++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/plugin-outline-pane/src/controllers/tree-node.ts b/packages/plugin-outline-pane/src/controllers/tree-node.ts index af82904ee1..079ed77d65 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-node.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-node.ts @@ -244,7 +244,9 @@ export default class TreeNode { if (this.node.conditionGroup) { return; } - this.node.visible = !flag; + if (this.node.visible !== !flag) { + this.node.visible = !flag; + } this.event.emit(EVENT_NAMES.hiddenChanged, flag); } diff --git a/packages/plugin-outline-pane/src/controllers/tree.ts b/packages/plugin-outline-pane/src/controllers/tree.ts index 7b9ad0593f..ab0d64b0f5 100644 --- a/packages/plugin-outline-pane/src/controllers/tree.ts +++ b/packages/plugin-outline-pane/src/controllers/tree.ts @@ -40,6 +40,11 @@ export class Tree { treeNode?.notifyConditionChanged(); } }); + + doc?.onChangeNodeVisible((node: IPublicModelNode, visible: boolean) => { + const treeNode = this.getTreeNodeById(node.id); + treeNode?.setHidden(!visible); + }); } setNodeSelected(nodeId: string): void { diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 9232132383..6f35c6a614 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -28,6 +28,7 @@ export default class TreeTitle extends PureComponent<{ editing: boolean; title: string; condition?: boolean; + visible?: boolean; } = { editing: false, title: '', @@ -93,6 +94,11 @@ export default class TreeTitle extends PureComponent<{ condition: treeNode.condition, }); }); + treeNode.onHiddenChanged((hidden: boolean) => { + this.setState({ + visible: !hidden, + }); + }); } render() { @@ -132,7 +138,7 @@ export default class TreeTitle extends PureComponent<{ data-id={treeNode.id} onClick={() => { if (isModal) { - if (node.visible) { + if (this.state.visible) { node.document?.modalNodesManager?.setInvisible(node); } else { node.document?.modalNodesManager?.setVisible(node); @@ -144,7 +150,7 @@ export default class TreeTitle extends PureComponent<{ } }} > - {isModal && node.visible && ( + {isModal && this.state.visible && (
{ node.document?.modalNodesManager?.setInvisible(node); }} @@ -152,7 +158,7 @@ export default class TreeTitle extends PureComponent<{
)} - {isModal && !node.visible && ( + {isModal && !this.state.visible && (
{ node.document?.modalNodesManager?.setVisible(node); }} From addcdeb9d7f77a550921a5543b9676e9a968d412 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 23 May 2023 18:19:38 +0800 Subject: [PATCH 013/361] chore(docs): publish 1.0.29 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 80f146513f..676c727911 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.28", + "version": "1.0.29", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 878a934511da58343478a913a9ad30045a4d77fc Mon Sep 17 00:00:00 2001 From: lukeup Date: Thu, 25 May 2023 14:16:42 +0800 Subject: [PATCH 014/361] =?UTF-8?q?docs:=20=E5=8A=A0=E5=85=A5=E5=9B=BE?= =?UTF-8?q?=E7=BC=96=E6=8E=92=E6=89=A9=E5=B1=95=E4=BD=BF=E7=94=A8=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/guide/expand/editor/graph.md | 155 +++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 docs/docs/guide/expand/editor/graph.md diff --git a/docs/docs/guide/expand/editor/graph.md b/docs/docs/guide/expand/editor/graph.md new file mode 100644 index 0000000000..2d5127054e --- /dev/null +++ b/docs/docs/guide/expand/editor/graph.md @@ -0,0 +1,155 @@ +--- +title: 图编排扩展 +sidebar_position: 9 +--- +## 项目运行 +### 前置准备 +1. 参考 https://lowcode-engine.cn/site/docs/guide/quickStart/start +2. 参考至Demo下载 https://lowcode-engine.cn/site/docs/guide/quickStart/start#%E4%B8%8B%E8%BD%BD-demo +### 选择demo-graph-x6 +在根目录下执行: +```bash +cd demo-graph-x6 +``` +### 安装依赖 +在 lowcode-demo/demo-graph-x6目录下执行: +```bash +npm install +``` +### 启动Demo +在 lowcode-demo/demo-graph-x6 目录下执行: +```bash +npm run start +``` +之后就可以通过 http://localhost:5556/ 来访问我们的 DEMO 了。 + +## 认识Demo +这里的Demo即通过图编排引擎加入了几个简单的物料而来,已经是可以面向真是用户的产品界面。 +![image.png](https://img.alicdn.com/imgextra/i1/O1CN016TbCI31hM2sJy8qkR_!!6000000004262-2-tps-5120-2726.png) +### 区域组成 +#### 顶部:操作区​ +- 右侧:保存到本地、重置页面、自定义按钮 +#### 顶部:工具区 +- 左侧:删除、撤销、重做、放大、缩小 +#### 左侧:面板与操作区​ +- 物料面板:可以查找节点,并在此拖动节点到编辑器画布中 +#### 中部:可视化页面编辑画布区域​ +- 点击节点/边在右侧面板中能够显示出对应组件的属性配置选项 +- 拖拽修改节点的排列顺序 +#### 右侧:组件级别配置​ +- 选中的组件:从页面开始一直到当前选中的节点/边位置,点击对应的名称可以切换到对应的节点上 +- 选中组件的配置:属性:节点的基础属性值设置 + +> 每个区域的组成都可以被替换和自定义来生成开发者需要的业务产品。 + +## 目录介绍 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Luc8gr1tLq5QTbpb9_!!6000000005886-0-tps-832-1522.jpg) + +- public:与其他demo保持一致,均是lowcode engine所必要依赖 +- src + - plugins::自定义插件,完成了x6的切面回调处理功能 + - services:mock数据,真实场景中可能为异步获取数据 + +## 开发插件 +```typescript +function pluginX6DesignerExtension(ctx: IPublicModelPluginContext) { + return { + init() { + // 获取 x6 designer 内置插件的导出 api + const x6Designer = ctx.plugins['plugin-x6-designer'] as IDesigner; + + x6Designer.onNodeRender((model, node) => { + // @ts-ignore + // 自定义 node 渲染逻辑 + const { name, title } = model.propsData; + node.attr('text/textWrap/text', title || name); + }); + + x6Designer.onEdgeRender((model, edge) => { + // @ts-ignore + const { source, target, sourcePortId, targetPortId } = model.propsData; + console.log(sourcePortId, targetPortId); + requestAnimationFrame(() => { + edge.setSource({ cell: source, port: sourcePortId }); + edge.setTarget({ cell: target, port: targetPortId }); + }); + + // https://x6.antv.vision/zh/docs/tutorial/intermediate/edge-labels x6 标签模块 + // appendLabel 会触发 onEdgeLabelRender + edge.appendLabel({ + markup: Markup.getForeignObjectMarkup(), + attrs: { + fo: { + width: 120, + height: 30, + x: -60, + y: -15, + }, + }, + }); + }); + + x6Designer.onEdgeLabelRender((args) => { + const { selectors } = args + const content = selectors.foContent as HTMLDivElement + if (content) { + ReactDOM.render(
自定义 react 标签
, content) + } + }) + } + } +} + +pluginX6DesignerExtension.pluginName = 'plugin-x6-designer-extension'; + +export default pluginX6DesignerExtension; +``` +x6Designer为图实例暴露出来的一些接口,可基于此进行一些图的必要插件的封装,整个插件的封装完全follow低代码引擎的插件,详情可参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/pluginWidget + +## 开发物料 +```bash +npm init @alilc/element your-material-demo +``` +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01DCCqO82ADuhS8ztCt_!!6000000008170-2-tps-546-208.png) + +仓库初始化完成 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01qK2rUe1JNpdqbdhoW_!!6000000001017-0-tps-5120-2830.jpg) + +接下来即可编写物料内容了 +图物料与低代码的dom场景存在画布的差异,因此暂不支持物料单独调试,须通过项目demo进行物料调试 + +### 资产描述 +```bash +npm run lowcode:build +``` +如果物料是个React组件,则在执行上述命令时会自动生成对应的meta.ts,但图物料很多时候并非一个React组件,因此须手动生产meta.ts + +可参考: https://github.com/alibaba/lowcode-materials/blob/main/packages/graph-x6-materials/lowcode/send-email/meta.ts +同时会自动生成物料描述文件 + +### 物料调试 +#### 物料侧 +物料想要支持被项目动态inject调试,须在build.lowcode.js中加入 +```javascript +[ + '@alilc/build-plugin-alt', + { + type: 'component', + inject: true, + library + }, +] +``` +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01HyXfL12992sDkOmOg_!!6000000008024-0-tps-5120-2824.jpg) + +本地启动 +```bash +npm run lowcode:dev +``` +#### 项目侧 +通过@alilc/lce-graph-core加载物料的天然支持了debug,因此无须特殊处理。 +若项目中自行加载,则参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/cli +项目访问地址后拼接query "?debug"即可进入物料调试 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01ke58hT1aRoYJzkutk_!!6000000003327-2-tps-5120-2790.png) + + From 9d2214e0fc3b70adad1717b3e2ea5281a0ad23aa Mon Sep 17 00:00:00 2001 From: JackLian Date: Thu, 25 May 2023 16:23:34 +0800 Subject: [PATCH 015/361] =?UTF-8?q?Revert=20"docs:=20=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E5=9B=BE=E7=BC=96=E6=8E=92=E6=89=A9=E5=B1=95=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=AF=B4=E6=98=8E"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 878a934511da58343478a913a9ad30045a4d77fc. --- docs/docs/guide/expand/editor/graph.md | 155 ------------------------- 1 file changed, 155 deletions(-) delete mode 100644 docs/docs/guide/expand/editor/graph.md diff --git a/docs/docs/guide/expand/editor/graph.md b/docs/docs/guide/expand/editor/graph.md deleted file mode 100644 index 2d5127054e..0000000000 --- a/docs/docs/guide/expand/editor/graph.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: 图编排扩展 -sidebar_position: 9 ---- -## 项目运行 -### 前置准备 -1. 参考 https://lowcode-engine.cn/site/docs/guide/quickStart/start -2. 参考至Demo下载 https://lowcode-engine.cn/site/docs/guide/quickStart/start#%E4%B8%8B%E8%BD%BD-demo -### 选择demo-graph-x6 -在根目录下执行: -```bash -cd demo-graph-x6 -``` -### 安装依赖 -在 lowcode-demo/demo-graph-x6目录下执行: -```bash -npm install -``` -### 启动Demo -在 lowcode-demo/demo-graph-x6 目录下执行: -```bash -npm run start -``` -之后就可以通过 http://localhost:5556/ 来访问我们的 DEMO 了。 - -## 认识Demo -这里的Demo即通过图编排引擎加入了几个简单的物料而来,已经是可以面向真是用户的产品界面。 -![image.png](https://img.alicdn.com/imgextra/i1/O1CN016TbCI31hM2sJy8qkR_!!6000000004262-2-tps-5120-2726.png) -### 区域组成 -#### 顶部:操作区​ -- 右侧:保存到本地、重置页面、自定义按钮 -#### 顶部:工具区 -- 左侧:删除、撤销、重做、放大、缩小 -#### 左侧:面板与操作区​ -- 物料面板:可以查找节点,并在此拖动节点到编辑器画布中 -#### 中部:可视化页面编辑画布区域​ -- 点击节点/边在右侧面板中能够显示出对应组件的属性配置选项 -- 拖拽修改节点的排列顺序 -#### 右侧:组件级别配置​ -- 选中的组件:从页面开始一直到当前选中的节点/边位置,点击对应的名称可以切换到对应的节点上 -- 选中组件的配置:属性:节点的基础属性值设置 - -> 每个区域的组成都可以被替换和自定义来生成开发者需要的业务产品。 - -## 目录介绍 -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Luc8gr1tLq5QTbpb9_!!6000000005886-0-tps-832-1522.jpg) - -- public:与其他demo保持一致,均是lowcode engine所必要依赖 -- src - - plugins::自定义插件,完成了x6的切面回调处理功能 - - services:mock数据,真实场景中可能为异步获取数据 - -## 开发插件 -```typescript -function pluginX6DesignerExtension(ctx: IPublicModelPluginContext) { - return { - init() { - // 获取 x6 designer 内置插件的导出 api - const x6Designer = ctx.plugins['plugin-x6-designer'] as IDesigner; - - x6Designer.onNodeRender((model, node) => { - // @ts-ignore - // 自定义 node 渲染逻辑 - const { name, title } = model.propsData; - node.attr('text/textWrap/text', title || name); - }); - - x6Designer.onEdgeRender((model, edge) => { - // @ts-ignore - const { source, target, sourcePortId, targetPortId } = model.propsData; - console.log(sourcePortId, targetPortId); - requestAnimationFrame(() => { - edge.setSource({ cell: source, port: sourcePortId }); - edge.setTarget({ cell: target, port: targetPortId }); - }); - - // https://x6.antv.vision/zh/docs/tutorial/intermediate/edge-labels x6 标签模块 - // appendLabel 会触发 onEdgeLabelRender - edge.appendLabel({ - markup: Markup.getForeignObjectMarkup(), - attrs: { - fo: { - width: 120, - height: 30, - x: -60, - y: -15, - }, - }, - }); - }); - - x6Designer.onEdgeLabelRender((args) => { - const { selectors } = args - const content = selectors.foContent as HTMLDivElement - if (content) { - ReactDOM.render(
自定义 react 标签
, content) - } - }) - } - } -} - -pluginX6DesignerExtension.pluginName = 'plugin-x6-designer-extension'; - -export default pluginX6DesignerExtension; -``` -x6Designer为图实例暴露出来的一些接口,可基于此进行一些图的必要插件的封装,整个插件的封装完全follow低代码引擎的插件,详情可参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/pluginWidget - -## 开发物料 -```bash -npm init @alilc/element your-material-demo -``` -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01DCCqO82ADuhS8ztCt_!!6000000008170-2-tps-546-208.png) - -仓库初始化完成 -![image.png](https://img.alicdn.com/imgextra/i2/O1CN01qK2rUe1JNpdqbdhoW_!!6000000001017-0-tps-5120-2830.jpg) - -接下来即可编写物料内容了 -图物料与低代码的dom场景存在画布的差异,因此暂不支持物料单独调试,须通过项目demo进行物料调试 - -### 资产描述 -```bash -npm run lowcode:build -``` -如果物料是个React组件,则在执行上述命令时会自动生成对应的meta.ts,但图物料很多时候并非一个React组件,因此须手动生产meta.ts - -可参考: https://github.com/alibaba/lowcode-materials/blob/main/packages/graph-x6-materials/lowcode/send-email/meta.ts -同时会自动生成物料描述文件 - -### 物料调试 -#### 物料侧 -物料想要支持被项目动态inject调试,须在build.lowcode.js中加入 -```javascript -[ - '@alilc/build-plugin-alt', - { - type: 'component', - inject: true, - library - }, -] -``` -![image.png](https://img.alicdn.com/imgextra/i4/O1CN01HyXfL12992sDkOmOg_!!6000000008024-0-tps-5120-2824.jpg) - -本地启动 -```bash -npm run lowcode:dev -``` -#### 项目侧 -通过@alilc/lce-graph-core加载物料的天然支持了debug,因此无须特殊处理。 -若项目中自行加载,则参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/cli -项目访问地址后拼接query "?debug"即可进入物料调试 -![image.png](https://img.alicdn.com/imgextra/i2/O1CN01ke58hT1aRoYJzkutk_!!6000000003327-2-tps-5120-2790.png) - - From ea073d7fdaedab8bdf8eabafc597b153e20eed56 Mon Sep 17 00:00:00 2001 From: lukeup Date: Thu, 25 May 2023 16:33:22 +0800 Subject: [PATCH 016/361] =?UTF-8?q?docs:=20=E5=8A=A0=E5=85=A5=E5=9B=BE?= =?UTF-8?q?=E7=BC=96=E6=8E=92=E6=89=A9=E5=B1=95=E4=BD=BF=E7=94=A8=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/guide/expand/editor/graph.md | 155 +++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 docs/docs/guide/expand/editor/graph.md diff --git a/docs/docs/guide/expand/editor/graph.md b/docs/docs/guide/expand/editor/graph.md new file mode 100644 index 0000000000..2d5127054e --- /dev/null +++ b/docs/docs/guide/expand/editor/graph.md @@ -0,0 +1,155 @@ +--- +title: 图编排扩展 +sidebar_position: 9 +--- +## 项目运行 +### 前置准备 +1. 参考 https://lowcode-engine.cn/site/docs/guide/quickStart/start +2. 参考至Demo下载 https://lowcode-engine.cn/site/docs/guide/quickStart/start#%E4%B8%8B%E8%BD%BD-demo +### 选择demo-graph-x6 +在根目录下执行: +```bash +cd demo-graph-x6 +``` +### 安装依赖 +在 lowcode-demo/demo-graph-x6目录下执行: +```bash +npm install +``` +### 启动Demo +在 lowcode-demo/demo-graph-x6 目录下执行: +```bash +npm run start +``` +之后就可以通过 http://localhost:5556/ 来访问我们的 DEMO 了。 + +## 认识Demo +这里的Demo即通过图编排引擎加入了几个简单的物料而来,已经是可以面向真是用户的产品界面。 +![image.png](https://img.alicdn.com/imgextra/i1/O1CN016TbCI31hM2sJy8qkR_!!6000000004262-2-tps-5120-2726.png) +### 区域组成 +#### 顶部:操作区​ +- 右侧:保存到本地、重置页面、自定义按钮 +#### 顶部:工具区 +- 左侧:删除、撤销、重做、放大、缩小 +#### 左侧:面板与操作区​ +- 物料面板:可以查找节点,并在此拖动节点到编辑器画布中 +#### 中部:可视化页面编辑画布区域​ +- 点击节点/边在右侧面板中能够显示出对应组件的属性配置选项 +- 拖拽修改节点的排列顺序 +#### 右侧:组件级别配置​ +- 选中的组件:从页面开始一直到当前选中的节点/边位置,点击对应的名称可以切换到对应的节点上 +- 选中组件的配置:属性:节点的基础属性值设置 + +> 每个区域的组成都可以被替换和自定义来生成开发者需要的业务产品。 + +## 目录介绍 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Luc8gr1tLq5QTbpb9_!!6000000005886-0-tps-832-1522.jpg) + +- public:与其他demo保持一致,均是lowcode engine所必要依赖 +- src + - plugins::自定义插件,完成了x6的切面回调处理功能 + - services:mock数据,真实场景中可能为异步获取数据 + +## 开发插件 +```typescript +function pluginX6DesignerExtension(ctx: IPublicModelPluginContext) { + return { + init() { + // 获取 x6 designer 内置插件的导出 api + const x6Designer = ctx.plugins['plugin-x6-designer'] as IDesigner; + + x6Designer.onNodeRender((model, node) => { + // @ts-ignore + // 自定义 node 渲染逻辑 + const { name, title } = model.propsData; + node.attr('text/textWrap/text', title || name); + }); + + x6Designer.onEdgeRender((model, edge) => { + // @ts-ignore + const { source, target, sourcePortId, targetPortId } = model.propsData; + console.log(sourcePortId, targetPortId); + requestAnimationFrame(() => { + edge.setSource({ cell: source, port: sourcePortId }); + edge.setTarget({ cell: target, port: targetPortId }); + }); + + // https://x6.antv.vision/zh/docs/tutorial/intermediate/edge-labels x6 标签模块 + // appendLabel 会触发 onEdgeLabelRender + edge.appendLabel({ + markup: Markup.getForeignObjectMarkup(), + attrs: { + fo: { + width: 120, + height: 30, + x: -60, + y: -15, + }, + }, + }); + }); + + x6Designer.onEdgeLabelRender((args) => { + const { selectors } = args + const content = selectors.foContent as HTMLDivElement + if (content) { + ReactDOM.render(
自定义 react 标签
, content) + } + }) + } + } +} + +pluginX6DesignerExtension.pluginName = 'plugin-x6-designer-extension'; + +export default pluginX6DesignerExtension; +``` +x6Designer为图实例暴露出来的一些接口,可基于此进行一些图的必要插件的封装,整个插件的封装完全follow低代码引擎的插件,详情可参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/pluginWidget + +## 开发物料 +```bash +npm init @alilc/element your-material-demo +``` +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01DCCqO82ADuhS8ztCt_!!6000000008170-2-tps-546-208.png) + +仓库初始化完成 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01qK2rUe1JNpdqbdhoW_!!6000000001017-0-tps-5120-2830.jpg) + +接下来即可编写物料内容了 +图物料与低代码的dom场景存在画布的差异,因此暂不支持物料单独调试,须通过项目demo进行物料调试 + +### 资产描述 +```bash +npm run lowcode:build +``` +如果物料是个React组件,则在执行上述命令时会自动生成对应的meta.ts,但图物料很多时候并非一个React组件,因此须手动生产meta.ts + +可参考: https://github.com/alibaba/lowcode-materials/blob/main/packages/graph-x6-materials/lowcode/send-email/meta.ts +同时会自动生成物料描述文件 + +### 物料调试 +#### 物料侧 +物料想要支持被项目动态inject调试,须在build.lowcode.js中加入 +```javascript +[ + '@alilc/build-plugin-alt', + { + type: 'component', + inject: true, + library + }, +] +``` +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01HyXfL12992sDkOmOg_!!6000000008024-0-tps-5120-2824.jpg) + +本地启动 +```bash +npm run lowcode:dev +``` +#### 项目侧 +通过@alilc/lce-graph-core加载物料的天然支持了debug,因此无须特殊处理。 +若项目中自行加载,则参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/cli +项目访问地址后拼接query "?debug"即可进入物料调试 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01ke58hT1aRoYJzkutk_!!6000000003327-2-tps-5120-2790.png) + + From 2004350c0d981f9bdccf2b78370fb3761eb2cc1b Mon Sep 17 00:00:00 2001 From: JackLian Date: Thu, 25 May 2023 16:37:29 +0800 Subject: [PATCH 017/361] chore(docs): publish 1.0.30 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 676c727911..efac589fa9 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.29", + "version": "1.0.30", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From ecca076d502c51e42c275632bcb03fe057b04bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 26 May 2023 14:20:14 +0800 Subject: [PATCH 018/361] fix: comp which has no npm info should be regarded as lowCode comp --- .../designer/src/document/document-model.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 2d39ed1151..9521fef383 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -839,13 +839,18 @@ export class DocumentModel implements IDocumentModel { } // 合并外界传入的自定义渲染的组件 if (Array.isArray(extraComps)) { - extraComps.forEach(c => { - if (c && !exsitingMap[c]) { - const m = this.getComponentMeta(c); - if (m && m.npm?.package) { + extraComps.forEach((componentName) => { + if (componentName && !exsitingMap[componentName]) { + const meta = this.getComponentMeta(componentName); + if (meta?.npm?.package) { componentsMap.push({ - ...m?.npm, - componentName: c, + ...meta?.npm, + componentName, + }); + } else { + componentsMap.push({ + devMode: 'lowCode', + componentName, }); } } From 503793fdfc4ccc76fe190fad4ba841f86496037d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 29 May 2023 10:12:42 +0800 Subject: [PATCH 019/361] fix: supportVariable SHOULD take precedence over supportVariableGlobally (#1997) * fix: supportVariable should take precedence over supportVariableGlobally --- .../src/components/settings/settings-pane.tsx | 38 +++++++++++-------- packages/utils/src/misc.ts | 15 ++++++++ packages/utils/test/src/misc.test.ts | 9 +++++ 3 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 packages/utils/test/src/misc.test.ts diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index 9cc8d9caed..1d651bb5a3 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -1,6 +1,6 @@ import { Component, MouseEvent, Fragment, ReactNode } from 'react'; import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core'; -import { createContent, isJSSlot, isSetterConfig } from '@alilc/lowcode-utils'; +import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter } from '@alilc/lowcode-utils'; import { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton'; import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeDynamicProps } from '@alilc/lowcode-types'; import { ISettingEntry, IComponentMeta, ISettingField, isSettingField, ISettingTopEntry } from '@alilc/lowcode-designer'; @@ -155,23 +155,29 @@ class SettingFieldView extends Component { + expect(shouldUseVariableSetter(false, true)).toBeFalsy(); + expect(shouldUseVariableSetter(true, true)).toBeTruthy(); + expect(shouldUseVariableSetter(true, false)).toBeTruthy(); + expect(shouldUseVariableSetter(undefined, false)).toBeFalsy(); + expect(shouldUseVariableSetter(undefined, true)).toBeTruthy(); +}); \ No newline at end of file From 75a4a80935ea69cff8c179a08119bbad833d3988 Mon Sep 17 00:00:00 2001 From: AprChell Date: Mon, 29 May 2023 14:11:12 +0800 Subject: [PATCH 020/361] =?UTF-8?q?feat(code-gen):=20=E5=87=BA=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84*.ts=E5=92=8C*.tsx=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8babel=E6=A0=BC=E5=BC=8F=E5=8C=96=20(#2088)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/code-generator/src/postprocessor/prettier/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/src/postprocessor/prettier/index.ts b/modules/code-generator/src/postprocessor/prettier/index.ts index b4c3188f3f..075fc66e7a 100644 --- a/modules/code-generator/src/postprocessor/prettier/index.ts +++ b/modules/code-generator/src/postprocessor/prettier/index.ts @@ -20,7 +20,7 @@ const factory: PostProcessorFactory = (config?: ProcessorConfig const codePrettier: PostProcessor = (content: string, fileType: string) => { let parser: prettier.BuiltInParserName | any; - if (fileType === 'js' || fileType === 'jsx') { + if (fileType === 'js' || fileType === 'jsx' || fileType === 'ts' || fileType === 'tsx') { parser = 'babel'; } else if (fileType === 'json') { parser = 'json-stringify'; From 9695add27cc1b8b30cc7b2d7eff147f25c72f159 Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 31 May 2023 14:48:47 +0800 Subject: [PATCH 021/361] chore(release): publish 1.1.7 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index dd7f87e45e..67ffb648e2 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.1.6", + "version": "1.1.7", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index e3b5ca968c..cb73cdeb92 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.1.6", + "version": "1.1.7", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.1.6", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-editor-core": "1.1.7", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 2701199d57..efb73bb2ca 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.1.6", + "version": "1.1.7", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index ff9c9a782b..9199e1cb3d 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.1.6", + "version": "1.1.7", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-editor-core": "1.1.6", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-editor-core": "1.1.7", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index ca63f42f4a..4a2d7f07a3 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.1.6", + "version": "1.1.7", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-editor-core": "1.1.6", - "@alilc/lowcode-editor-skeleton": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-editor-core": "1.1.7", + "@alilc/lowcode-editor-skeleton": "1.1.7", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.1.6", - "@alilc/lowcode-plugin-outline-pane": "1.1.6", - "@alilc/lowcode-shell": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", - "@alilc/lowcode-workspace": "1.1.6", + "@alilc/lowcode-plugin-designer": "1.1.7", + "@alilc/lowcode-plugin-outline-pane": "1.1.7", + "@alilc/lowcode-shell": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-workspace": "1.1.7", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 7fa6ab0730..2448ce0fc0 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.1.6", + "version": "1.1.7", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 5ffc7e96f3..302d224915 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.1.6", + "version": "1.1.7", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-editor-core": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-editor-core": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index cbba2bc456..b191969208 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.1.6", + "version": "1.1.7", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 489cf14093..3910afe41e 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.1.6", + "version": "1.1.7", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-renderer-core": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 4f8bc7ad18..0e29b10919 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.1.6", + "version": "1.1.7", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-rax-renderer": "1.1.6", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-rax-renderer": "1.1.7", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 744c1cac09..451ef1ee3d 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.1.6", + "version": "1.1.7", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.1.6" + "@alilc/lowcode-renderer-core": "1.1.7" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index ad7673b620..adb5526c73 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.1.6", + "version": "1.1.7", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-react-renderer": "1.1.6", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-react-renderer": "1.1.7", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 1a6fd6090a..ce633dd546 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.1.6", + "version": "1.1.7", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 521befb2eb..9ec85ec5c2 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.1.6", + "version": "1.1.7", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-editor-core": "1.1.6", - "@alilc/lowcode-editor-skeleton": "1.1.6", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", - "@alilc/lowcode-workspace": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-editor-core": "1.1.7", + "@alilc/lowcode-editor-skeleton": "1.1.7", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-workspace": "1.1.7", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index b92d2efb66..0b05893ca1 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.1.6", + "version": "1.1.7", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index d52f6deef2..6a0880b007 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.1.6", + "version": "1.1.7", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.6", + "@alilc/lowcode-types": "1.1.7", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 52a45567d4..569d652037 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.1.6", + "version": "1.1.7", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.6", - "@alilc/lowcode-editor-core": "1.1.6", - "@alilc/lowcode-editor-skeleton": "1.1.6", - "@alilc/lowcode-types": "1.1.6", - "@alilc/lowcode-utils": "1.1.6", + "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-editor-core": "1.1.7", + "@alilc/lowcode-editor-skeleton": "1.1.7", + "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-utils": "1.1.7", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From f10b694c42ae97ebdd337758361031d8745349d8 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 31 May 2023 18:01:00 +0800 Subject: [PATCH 022/361] feat(renderer-core): optimize the judgment of whether leaf hoc has children --- packages/renderer-core/src/hoc/leaf.tsx | 17 +++++---- .../renderer-core/tests/hoc/leaf.test.tsx | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index 98b2674750..432f22a5e5 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -521,16 +521,11 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { } get hasChildren(): boolean { - let { children } = this.props; - if (this.state.childrenInState) { - children = this.state.nodeChildren; - } - - if (Array.isArray(children)) { - return Boolean(children && children.length); + if (!this.state.childrenInState) { + return 'children' in this.props; } - return Boolean(children); + return true; } get children(): any { @@ -576,7 +571,11 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { delete compProps.__inner__; - return engine.createElement(Comp, compProps, this.hasChildren ? this.children : null); + if (this.hasChildren) { + return engine.createElement(Comp, compProps, this.children); + } + + return engine.createElement(Comp, compProps); } } diff --git a/packages/renderer-core/tests/hoc/leaf.test.tsx b/packages/renderer-core/tests/hoc/leaf.test.tsx index d4a65e578a..c21a10be92 100644 --- a/packages/renderer-core/tests/hoc/leaf.test.tsx +++ b/packages/renderer-core/tests/hoc/leaf.test.tsx @@ -504,6 +504,41 @@ describe('onChildrenChange', () => { DivNode.emitChildrenChange(); makeSnapshot(component); }); + + it('children is 0', () => { + DivNode.schema.children = 0 + DivNode.emitChildrenChange(); + const componentInstance = component.root; + expect(componentInstance.findByType(components.Div).props.children).toEqual(0); + }); + + it('children is false', () => { + DivNode.schema.children = false + DivNode.emitChildrenChange(); + const componentInstance = component.root; + expect(componentInstance.findByType(components.Div).props.children).toEqual(false); + }); + + it('children is []', () => { + DivNode.schema.children = [] + DivNode.emitChildrenChange(); + const componentInstance = component.root; + expect(componentInstance.findByType(components.Div).props.children).toEqual([]); + }); + + it('children is null', () => { + DivNode.schema.children = null + DivNode.emitChildrenChange(); + const componentInstance = component.root; + expect(componentInstance.findByType(components.Div).props.children).toEqual(null); + }); + + it('children is undefined', () => { + DivNode.schema.children = undefined; + DivNode.emitChildrenChange(); + const componentInstance = component.root; + expect(componentInstance.findByType(components.Div).props.children).toEqual(undefined); + }); }); describe('not render leaf', () => { From d82bcfdf2a4d469fe844632cb0683945ff7aadb9 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 31 May 2023 18:12:28 +0800 Subject: [PATCH 023/361] feat(renderer-core): optimize the judgment of whether leaf hoc has children --- packages/renderer-core/jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/renderer-core/jest.config.js b/packages/renderer-core/jest.config.js index 2489490fa2..e3267c5177 100644 --- a/packages/renderer-core/jest.config.js +++ b/packages/renderer-core/jest.config.js @@ -12,6 +12,7 @@ const jestConfig = { // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], // testMatch: ['**/*/base.test.tsx'], // testMatch: ['**/utils/common.test.ts'], + // testMatch: ['**/*/leaf.test.tsx'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], From 035c213b1681bddee5d9c00c9fe3240910dc0e80 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 31 May 2023 18:18:52 +0800 Subject: [PATCH 024/361] fix: fix that the prop model is not reused and the update is not triggered --- packages/designer/package.json | 1 + .../designer/src/document/node/props/prop.ts | 16 ++++++---------- .../tests/document/node/props/prop.test.ts | 1 - 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/designer/package.json b/packages/designer/package.json index cb73cdeb92..4deaa27219 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -15,6 +15,7 @@ }, "license": "MIT", "dependencies": { + "@alilc/build-plugin-lce": "^0.0.4-beta.2", "@alilc/lowcode-editor-core": "1.1.7", "@alilc/lowcode-types": "1.1.7", "@alilc/lowcode-utils": "1.1.7", diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 37017d72d8..01b2dc26b9 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -148,15 +148,13 @@ export class Prop implements IProp, IPropParent { @obx.shallow private _items: IProp[] | null = null; - @obx.shallow private _maps: Map | null = null; - /** - * 作为 _maps 的一层缓存机制,主要是复用部分已存在的 Prop,保持响应式关系,比如: + * 作为一层缓存机制,主要是复用部分已存在的 Prop,保持响应式关系,比如: * 当前 Prop#_value 值为 { a: 1 },当调用 setValue({ a: 2 }) 时,所有原来的子 Prop 均被销毁, * 导致假如外部有 mobx reaction(常见于 observer),此时响应式链路会被打断, * 因为 reaction 监听的是原 Prop(a) 的 _value,而不是新 Prop(a) 的 _value。 */ - private _prevMaps: Map | null = null; + @obx.shallow private _maps: Map | null = null; /** * 构造 items 属性,同时构造 maps 属性 @@ -171,8 +169,8 @@ export class Prop implements IProp, IPropParent { data.forEach((item: any, idx: number) => { items = items || []; let prop; - if (this._prevMaps?.has(idx.toString())) { - prop = this._prevMaps.get(idx.toString())!; + if (this._maps?.has(idx.toString())) { + prop = this._maps.get(idx.toString())!; prop.setValue(item); } else { prop = new Prop(this, item, idx); @@ -187,8 +185,8 @@ export class Prop implements IProp, IPropParent { const keys = Object.keys(data); for (const key of keys) { let prop: IProp; - if (this._prevMaps?.has(key)) { - prop = this._prevMaps.get(key)!; + if (this._maps?.has(key)) { + prop = this._maps.get(key)!; prop.setValue(data[key]); } else { prop = new Prop(this, data[key], key); @@ -419,8 +417,6 @@ export class Prop implements IProp, IPropParent { items.forEach((prop) => prop.purge()); } this._items = null; - this._prevMaps = this._maps; - this._maps = null; if (this._type !== 'slot' && this._slotNode) { this._slotNode.remove(); this._slotNode = undefined; diff --git a/packages/designer/tests/document/node/props/prop.test.ts b/packages/designer/tests/document/node/props/prop.test.ts index 177bc5247f..58c24a4ea4 100644 --- a/packages/designer/tests/document/node/props/prop.test.ts +++ b/packages/designer/tests/document/node/props/prop.test.ts @@ -379,7 +379,6 @@ describe('Prop 类测试', () => { prop.dispose(); expect(prop._items).toBeNull(); - expect(prop._maps).toBeNull(); }); }); From 980957f3adabaef76fd7e42a9162661904f4db36 Mon Sep 17 00:00:00 2001 From: "knight.chen" Date: Wed, 31 May 2023 22:48:49 +0800 Subject: [PATCH 025/361] feat: extract simulator type --- .../src/builtin-simulator/renderer.ts | 26 ++------------- packages/types/src/shell/type/index.ts | 1 + .../src/shell/type/simulator-renderer.ts | 32 +++++++++++++++++++ 3 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 packages/types/src/shell/type/simulator-renderer.ts diff --git a/packages/designer/src/builtin-simulator/renderer.ts b/packages/designer/src/builtin-simulator/renderer.ts index bd94f24f65..15664757bc 100644 --- a/packages/designer/src/builtin-simulator/renderer.ts +++ b/packages/designer/src/builtin-simulator/renderer.ts @@ -1,29 +1,7 @@ import { Component } from '../simulator'; -import { IPublicTypeComponentInstance, IPublicTypeNodeInstance, Asset, IPublicTypeComponentSchema, IPublicTypeProjectSchema, IPublicTypeLowCodeComponent } from '@alilc/lowcode-types'; +import { IPublicTypeComponentInstance, IPublicTypeSimulatorRenderer } from '@alilc/lowcode-types'; -export interface BuiltinSimulatorRenderer { - readonly isSimulatorRenderer: true; - autoRepaintNode?: boolean; - components: Record; - rerender: () => void; - createComponent(schema: IPublicTypeProjectSchema): Component | null; - getComponent(componentName: string): Component; - getClosestNodeInstance( - from: IPublicTypeComponentInstance, - nodeId?: string, - ): IPublicTypeNodeInstance | null; - findDOMNodes(instance: IPublicTypeComponentInstance): Array | null; - getClientRects(element: Element | Text): DOMRect[]; - setNativeSelection(enableFlag: boolean): void; - setDraggingState(state: boolean): void; - setCopyState(state: boolean): void; - loadAsyncLibrary(asyncMap: { [index: string]: any }): void; - clearState(): void; - stopAutoRepaintNode(): void; - enableAutoRepaintNode(): void; - run(): void; - load(asset: Asset): Promise; -} +export type BuiltinSimulatorRenderer = IPublicTypeSimulatorRenderer; export function isSimulatorRenderer(obj: any): obj is BuiltinSimulatorRenderer { return obj && obj.isSimulatorRenderer; diff --git a/packages/types/src/shell/type/index.ts b/packages/types/src/shell/type/index.ts index b5dad9bb61..7232ffbbdc 100644 --- a/packages/types/src/shell/type/index.ts +++ b/packages/types/src/shell/type/index.ts @@ -90,3 +90,4 @@ export * from './editor-view-config'; export * from './hotkey-callback-config'; export * from './hotkey-callbacks'; export * from './scrollable'; +export * from './simulator-renderer'; diff --git a/packages/types/src/shell/type/simulator-renderer.ts b/packages/types/src/shell/type/simulator-renderer.ts new file mode 100644 index 0000000000..14aa16ab88 --- /dev/null +++ b/packages/types/src/shell/type/simulator-renderer.ts @@ -0,0 +1,32 @@ +import { Asset } from '../../assets'; +import { + IPublicTypeNodeInstance, + IPublicTypeProjectSchema, + IPublicTypeComponentSchema, +} from './'; + +export interface IPublicTypeSimulatorRenderer { + readonly isSimulatorRenderer: true; + autoRepaintNode?: boolean; + components: Record; + rerender: () => void; + createComponent( + schema: IPublicTypeProjectSchema, + ): Component | null; + getComponent(componentName: string): Component; + getClosestNodeInstance( + from: ComponentInstance, + nodeId?: string, + ): IPublicTypeNodeInstance | null; + findDOMNodes(instance: ComponentInstance): Array | null; + getClientRects(element: Element | Text): DOMRect[]; + setNativeSelection(enableFlag: boolean): void; + setDraggingState(state: boolean): void; + setCopyState(state: boolean): void; + loadAsyncLibrary(asyncMap: { [index: string]: any }): void; + clearState(): void; + stopAutoRepaintNode(): void; + enableAutoRepaintNode(): void; + run(): void; + load(asset: Asset): Promise; +} From 5feeab5aecb07071923f5b26ce22e3f72911be28 Mon Sep 17 00:00:00 2001 From: Cai HongYuan Date: Thu, 1 Jun 2023 14:46:38 +0800 Subject: [PATCH 026/361] Update pluginContextMenu.md (#2108) * update pluginContextMenu.md --- docs/docs/guide/expand/editor/pluginContextMenu.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/docs/guide/expand/editor/pluginContextMenu.md b/docs/docs/guide/expand/editor/pluginContextMenu.md index e9dbdf3c48..cd293b73e7 100644 --- a/docs/docs/guide/expand/editor/pluginContextMenu.md +++ b/docs/docs/guide/expand/editor/pluginContextMenu.md @@ -18,8 +18,7 @@ import { Icon, Message } from '@alifd/next'; const addHelloAction = (ctx: IPublicModelPluginContext) => { return { async init() { - const { addBuiltinComponentAction } = ctx.material; - addBuiltinComponentAction({ + ctx.material.addBuiltinComponentAction({ name: 'hello', content: { icon: , @@ -54,8 +53,7 @@ import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const removeCopyAction = (ctx: IPublicModelPluginContext) => { return { async init() { - const { removeBuiltinComponentAction } = ctx.material; - removeBuiltinComponentAction('copy'); + ctx.material.removeBuiltinComponentAction('copy'); } } }; From 03495ba9efd2c7b950b52756022c2ca2807dc085 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 1 Jun 2023 14:39:17 +0800 Subject: [PATCH 027/361] feat: add componentMeta?.advanced?.callbacks?.onSelectHook api --- packages/designer/jest.config.js | 1 + packages/designer/src/document/node/node.ts | 9 +++++++++ packages/designer/src/document/selection.ts | 19 ++++++++++++++++++- .../designer/tests/document/selection.test.ts | 9 +-------- packages/types/src/shell/type/metadata.ts | 3 +++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 82c76fad88..1ecebd9388 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -19,6 +19,7 @@ const jestConfig = { // testMatch: ['**/setting-field.test.ts'], // testMatch: ['**/node.test.ts'], // testMatch: ['**/builtin-hotkey.test.ts'], + // testMatch: ['**/selection.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 456595b048..b0e509bce8 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -159,6 +159,9 @@ export interface IBaseNode return !!this.getExtraProp('isLocked')?.getValue(); } + canSelect(): boolean { + const onSelectHook = this.componentMeta?.advanced?.callbacks?.onSelectHook; + const canSelect = typeof onSelectHook === 'function' ? onSelectHook(this.internalToShellNode()!) : true; + return canSelect; + } + /** * 选择当前节点 */ diff --git a/packages/designer/src/document/selection.ts b/packages/designer/src/document/selection.ts index 93ec04ffe9..6147e188d8 100644 --- a/packages/designer/src/document/selection.ts +++ b/packages/designer/src/document/selection.ts @@ -32,6 +32,12 @@ export class Selection implements ISelection { return; } + const node = this.doc.getNode(id); + + if (!node?.canSelect()) { + return; + } + this._selected = [id]; this.emitter.emit('selectionchange', this._selected); } @@ -40,7 +46,18 @@ export class Selection implements ISelection { * 批量选中 */ selectAll(ids: string[]) { - this._selected = ids; + const selectIds: string[] = []; + + ids.forEach(d => { + const node = this.doc.getNode(d); + + if (node?.canSelect()) { + selectIds.push(d); + } + }); + + this._selected = selectIds; + this.emitter.emit('selectionchange', this._selected); } diff --git a/packages/designer/tests/document/selection.test.ts b/packages/designer/tests/document/selection.test.ts index b8b5ad4343..0af22b5cef 100644 --- a/packages/designer/tests/document/selection.test.ts +++ b/packages/designer/tests/document/selection.test.ts @@ -122,7 +122,7 @@ describe('选择区测试', () => { selectionChangeHandler.mockClear(); }); - it('dispose 方法', () => { + it('selectAll 包含不存在的 id', () => { const project = new Project(designer, { componentsTree: [ formSchema, @@ -135,14 +135,7 @@ describe('选择区测试', () => { selection.selectAll(['form', 'node_k1ow3cbj', 'form2']); - const selectionChangeHandler = jest.fn(); - selection.onSelectionChange(selectionChangeHandler); - selection.dispose(); - - expect(selectionChangeHandler).toHaveBeenCalledTimes(1); - expect(selectionChangeHandler.mock.calls[0][0]).toEqual(['form', 'node_k1ow3cbj']); expect(selection.selected).toEqual(['form', 'node_k1ow3cbj']); - selectionChangeHandler.mockClear(); }); it('dispose 方法 - 选中的节点没有被删除的', () => { diff --git a/packages/types/src/shell/type/metadata.ts b/packages/types/src/shell/type/metadata.ts index 3122ab7d7d..573be16899 100644 --- a/packages/types/src/shell/type/metadata.ts +++ b/packages/types/src/shell/type/metadata.ts @@ -195,6 +195,9 @@ export interface IPublicTypeCallbacks { onMoveHook?: (currentNode: IPublicModelNode) => boolean; // thinkof 限制性拖拽 onHoverHook?: (currentNode: IPublicModelNode) => boolean; + + /** 选中 hook,如果返回值是 false,可以控制组件不可被选中 */ + onSelectHook?: (currentNode: IPublicModelNode) => boolean; onChildMoveHook?: (childNode: IPublicModelNode, currentNode: IPublicModelNode) => boolean; // events From 622806f59c31c7a615f01552e61c9ac8f379cd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 5 Jun 2023 16:10:35 +0800 Subject: [PATCH 028/361] fix(code-gen): fix types error --- modules/code-generator/src/utils/expressionParser.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/code-generator/src/utils/expressionParser.ts b/modules/code-generator/src/utils/expressionParser.ts index cbc950bbc8..15320b9637 100644 --- a/modules/code-generator/src/utils/expressionParser.ts +++ b/modules/code-generator/src/utils/expressionParser.ts @@ -167,7 +167,7 @@ export function parseExpressionGetKeywords(expr: string | null | undefined): str ], }); - const addIdentifierIfNeeded = (x: Record | number | null | undefined) => { + const addIdentifierIfNeeded = (x: Node | null | undefined) => { if (typeof x === 'object' && isIdentifier(x) && JS_KEYWORDS.includes(x.name)) { keywordVars.add(x.name); } @@ -189,7 +189,7 @@ export function parseExpressionGetKeywords(expr: string | null | undefined): str addIdentifierIfNeeded(item); }); } else { - addIdentifierIfNeeded(fieldValue as Record | null); + addIdentifierIfNeeded(fieldValue as any); } } }); @@ -217,7 +217,7 @@ export function parseExpressionGetGlobalVariables( const ast = parser.parse(`!(${expr});`); const addUndeclaredIdentifierIfNeeded = ( - x: Record | number | null | undefined, + x: Node | null | undefined, path: NodePath, ) => { if (typeof x === 'object' && isIdentifier(x) && !path.scope.hasBinding(x.name)) { @@ -241,7 +241,7 @@ export function parseExpressionGetGlobalVariables( addUndeclaredIdentifierIfNeeded(item, path); }); } else { - addUndeclaredIdentifierIfNeeded(fieldValue as Record | null, path); + addUndeclaredIdentifierIfNeeded(fieldValue as any, path); } } }); From 33efde964bc9d820183adf3f152ef88ee6498b54 Mon Sep 17 00:00:00 2001 From: eternalsky Date: Mon, 5 Jun 2023 18:52:41 +0800 Subject: [PATCH 029/361] fix: invalid jsx attr name error (#2131) --- modules/code-generator/src/utils/nodeToJSX.ts | 7 +- .../p0-condition-at-root.test.ts.snap | 72 +++++++++++++++++++ .../plugins/jsx/p0-condition-at-root.test.ts | 18 +++++ 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/src/utils/nodeToJSX.ts b/modules/code-generator/src/utils/nodeToJSX.ts index ad79288bab..d29f28762c 100644 --- a/modules/code-generator/src/utils/nodeToJSX.ts +++ b/modules/code-generator/src/utils/nodeToJSX.ts @@ -19,6 +19,7 @@ import { executeFunctionStack } from './aopHelper'; import { encodeJsxStringNode } from './encodeJsxAttrString'; import { unwrapJsExprQuoteInJsx } from './jsxHelpers'; import { transformThis2Context } from '../core/jsx/handlers/transformThis2Context'; +import { isValidIdentifier } from './validate'; function mergeNodeGeneratorConfig( cfg1: NodeGeneratorConfig, @@ -126,11 +127,13 @@ function generateAttrs( if (props) { if (!Array.isArray(props)) { Object.keys(props).forEach((propName: string) => { - pieces = pieces.concat(generateAttr(propName, props[propName] as IPublicTypeCompositeValue, scope, config)); + if (isValidIdentifier(propName)) { + pieces = pieces.concat(generateAttr(propName, props[propName] as IPublicTypeCompositeValue, scope, config)); + } }); } else { props.forEach((prop) => { - if (prop.name && !prop.spread) { + if (prop.name && isValidIdentifier(prop.name) && !prop.spread) { pieces = pieces.concat(generateAttr(prop.name, prop.value, scope, config)); } diff --git a/modules/code-generator/tests/plugins/jsx/__snapshots__/p0-condition-at-root.test.ts.snap b/modules/code-generator/tests/plugins/jsx/__snapshots__/p0-condition-at-root.test.ts.snap index 391e492f6e..8bce3cc106 100644 --- a/modules/code-generator/tests/plugins/jsx/__snapshots__/p0-condition-at-root.test.ts.snap +++ b/modules/code-generator/tests/plugins/jsx/__snapshots__/p0-condition-at-root.test.ts.snap @@ -281,3 +281,75 @@ Object { }, } `; + +exports[`condition at root invalid attr name should not be generated 1`] = ` +Object { + "chunks": Array [ + Object { + "content": " + const __$$context = this._context || this; + const { state } = __$$context; + return Hello world!; + ", + "fileType": "jsx", + "linkAfter": Array [ + "ReactComponentClassRenderStart", + "ReactComponentClassRenderPre", + ], + "name": "ReactComponentClassRenderJSX", + "type": "string", + }, + Object { + "content": " + function __$$eval(expr) { + try { + return expr(); + } catch (error) { + + } + } + + function __$$evalArray(expr) { + const res = __$$eval(expr); + return Array.isArray(res) ? res : []; + } + + + function __$$createChildContext(oldContext, ext) { + const childContext = { + ...oldContext, + ...ext, + }; + childContext.__proto__ = oldContext; + return childContext; + } + ", + "fileType": "jsx", + "linkAfter": Array [ + "CommonFileExport", + ], + "name": "CommonCustomContent", + "type": "string", + }, + ], + "contextData": Object {}, + "depNames": Array [], + "ir": Object { + "children": Array [ + Object { + "children": "Hello world!", + "componentName": "Text", + "props": Object { + "a": 1, + "a.b": 2, + }, + }, + ], + "componentName": "Page", + "condition": null, + "containerType": "Page", + "fileName": "test", + "moduleName": "test", + }, +} +`; diff --git a/modules/code-generator/tests/plugins/jsx/p0-condition-at-root.test.ts b/modules/code-generator/tests/plugins/jsx/p0-condition-at-root.test.ts index 984c848303..31e73d63ea 100644 --- a/modules/code-generator/tests/plugins/jsx/p0-condition-at-root.test.ts +++ b/modules/code-generator/tests/plugins/jsx/p0-condition-at-root.test.ts @@ -83,4 +83,22 @@ describe('condition at root', () => { }); expect(result).toMatchSnapshot(); }); + + test('invalid attr name should not be generated', async () => { + const containerIr: IContainerInfo = { + containerType: 'Page', + moduleName: 'test', + componentName: 'Page', + fileName: 'test', + condition: null, + children: [{ componentName: 'Text', children: 'Hello world!', props: { 'a': 1, 'a.b': 2 } }], + }; + const result = await jsx()({ + ir: containerIr, + contextData: {}, + chunks: [], + depNames: [], + }); + expect(result).toMatchSnapshot(); + }) }); From 76686370b98feee70c9260ebcd7334b5d6121ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 5 Jun 2023 18:59:52 +0800 Subject: [PATCH 030/361] chore(release): code-generator - 1.1.3 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index f830b23ede..80b2c13f2f 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-code-generator", - "version": "1.1.2", + "version": "1.1.3", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From b50f7e1e624fad6708f3ebd42aecf826d209c610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=A9?= <1277180540@qq.com> Date: Tue, 6 Jun 2023 14:15:28 +0800 Subject: [PATCH 031/361] docs: fix link issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit markdown语法少了个[ --- docs/docs/guide/design/renderer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/design/renderer.md b/docs/docs/guide/design/renderer.md index bef13694a1..4c3021b54e 100644 --- a/docs/docs/guide/design/renderer.md +++ b/docs/docs/guide/design/renderer.md @@ -22,7 +22,7 @@ sidebar_position: 4 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01i4IiSR1cMtUFXaWQq_!!6000000003587-2-tps-1686-1062.png) -- 协议层:基于《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec) 产出的 Schema 作为我们的规范协议。 +- 协议层:基于[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec) 产出的 Schema 作为我们的规范协议。 - 能力层:提供组件、区块、页面等渲染所需的核心能力,包括 Props 解析、样式注入、条件渲染等。 - 适配层:由于我们使用的运行时框架不是统一的,所以统一使用适配层将不同运行框架的差异部分,通过接口对外,让渲染层注册/适配对应所需的方法。能保障渲染层和能力层直接通过适配层连接起来,能起到独立可扩展的作用。 - 渲染层:提供核心的渲染方法,由于不同运行时框架提供的渲染方法是不同的,所以其通过适配层进行注入,只需要提供适配层所需的接口,即可实现渲染。 From ee0d120bbdc2c0bceb3829a2a4c3e4ca05d51e1d 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: Wed, 7 Jun 2023 17:20:28 +0800 Subject: [PATCH 032/361] feat: add config.customPluginTransducer to debugger plugins (#2147) --- packages/designer/src/plugin/plugin-manager.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/designer/src/plugin/plugin-manager.ts b/packages/designer/src/plugin/plugin-manager.ts index 071bfa9d14..f30ccdc8f3 100644 --- a/packages/designer/src/plugin/plugin-manager.ts +++ b/packages/designer/src/plugin/plugin-manager.ts @@ -83,7 +83,10 @@ export class LowCodePluginManager implements ILowCodePluginManager { } const ctx = this._getLowCodePluginContext({ pluginName, meta }); const customFilterValidOptions = engineConfig.get('customPluginFilterOptions', filterValidOptions); - const config = pluginModel(ctx, customFilterValidOptions(options, preferenceDeclaration!)); + const pluginTransducer = engineConfig.get('customPluginTransducer', null); + const newOptions = customFilterValidOptions(options, preferenceDeclaration!); + const newPluginModel = pluginTransducer ? await pluginTransducer(pluginModel, ctx, newOptions) : pluginModel; + const config = newPluginModel(ctx, newOptions); // compat the legacy way to declare pluginName // @ts-ignore pluginName = pluginName || config.name; From dc029c252a5a135ffbce17c66040f72ea4b7fe00 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: Wed, 7 Jun 2023 17:21:10 +0800 Subject: [PATCH 033/361] feat(workspace): add resourceTypeList api (#2148) --- packages/shell/src/api/workspace.ts | 15 +++++++++++++++ packages/shell/src/model/resource.ts | 4 ++++ packages/types/src/shell/model/resource.ts | 2 ++ packages/workspace/src/resource.ts | 2 ++ packages/workspace/src/workspace.ts | 6 ++++-- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index 8192ac67d4..d51f670e9d 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -34,6 +34,21 @@ export class Workspace implements IPublicApiWorkspace { return new ShellWindow(this[workspaceSymbol].window); } + get resourceTypeList() { + return Array.from(this[workspaceSymbol].resourceTypeMap.values()).map((d) => { + const { name: resourceName, type: resourceType } = d; + const { + description, + } = d.resourceTypeModel({} as any, {}); + + return { + resourceName, + resourceType, + description, + }; + }); + } + onWindowRendererReady(fn: () => void): IPublicTypeDisposable { return this[workspaceSymbol].onWindowRendererReady(fn); } diff --git a/packages/shell/src/model/resource.ts b/packages/shell/src/model/resource.ts index 43f28fbd8d..6a1a07e499 100644 --- a/packages/shell/src/model/resource.ts +++ b/packages/shell/src/model/resource.ts @@ -37,6 +37,10 @@ export class Resource implements IPublicModelResource { return this[resourceSymbol].category; } + get description() { + return this[resourceSymbol].description; + } + get children() { return this[resourceSymbol].children.map((child) => new Resource(child)); } diff --git a/packages/types/src/shell/model/resource.ts b/packages/types/src/shell/model/resource.ts index 1f59845e69..0d791412b9 100644 --- a/packages/types/src/shell/model/resource.ts +++ b/packages/types/src/shell/model/resource.ts @@ -19,6 +19,8 @@ export interface IBaseModelResource< get viewName(): string | undefined; + get description(): string | undefined; + get config(): { disableBehaviors?: ('copy' | 'remove')[]; } | undefined; diff --git a/packages/workspace/src/resource.ts b/packages/workspace/src/resource.ts index 4b695d036d..1d328b6c6c 100644 --- a/packages/workspace/src/resource.ts +++ b/packages/workspace/src/resource.ts @@ -12,6 +12,8 @@ export interface IBaseResource extends IBaseModelResource { skeleton: ISkeleton; + description?: string; + get editorViews(): IPublicTypeEditorView[]; get defaultViewType(): string; diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 46c8c4a0e1..bedae86801 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -33,6 +33,8 @@ export interface IWorkspace extends Omit; + getResourceList(): IResource[]; getResourceType(resourceName: string): IResourceType; @@ -55,12 +57,12 @@ export class Workspace implements IWorkspace { enableAutoOpenFirstWindow: boolean; + resourceTypeMap: Map = new Map(); + private emitter: IEventBus = createModuleEventBus('workspace'); private _isActive = false; - private resourceTypeMap: Map = new Map(); - private resourceList: IResource[] = []; get skeleton() { From 182fdae78f5a37c8979d70d6f582b7bdf528d628 Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 7 Jun 2023 17:31:00 +0800 Subject: [PATCH 034/361] chore(docs): publish 1.0.31 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index efac589fa9..20efc6c630 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.30", + "version": "1.0.31", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 6015c5d1d16db21f6f6f5bbd1ac9d307c5246daa Mon Sep 17 00:00:00 2001 From: xiaohuoni Date: Wed, 7 Jun 2023 17:51:30 +0800 Subject: [PATCH 035/361] chore: set repo --- modules/code-generator/package.json | 7 ++- modules/material-parser/package.json | 8 +++- packages/designer/package.json | 4 +- packages/editor-core/package.json | 4 +- packages/editor-skeleton/package.json | 4 +- packages/engine/package.json | 4 +- packages/ignitor/package.json | 8 +++- packages/plugin-designer/package.json | 4 +- packages/plugin-outline-pane/package.json | 4 +- packages/rax-renderer/package.json | 5 ++- packages/rax-simulator-renderer/package.json | 5 ++- packages/react-renderer/package.json | 5 ++- .../react-simulator-renderer/package.json | 4 +- packages/renderer-core/package.json | 4 +- packages/shell/package.json | 4 +- packages/types/package.json | 4 +- packages/utils/package.json | 4 +- packages/workspace/package.json | 6 ++- scripts/set-repo.js | 45 +++++++++++++++++++ 19 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 scripts/set-repo.js diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 80b2c13f2f..7bcf9b1739 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -144,5 +144,10 @@ "access": "public", "registry": "https://registry.npmjs.org/" }, - "repository": "git@github.com:alibaba/lowcode-engine.git" + "repository": { + "type": "http", + "url": "https://github.com/alibaba/lowcode-engine/tree/main/modules/code-generator" + }, + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/modules/material-parser/package.json b/modules/material-parser/package.json index 7d7ea57c25..8b68c02955 100644 --- a/modules/material-parser/package.json +++ b/modules/material-parser/package.json @@ -66,5 +66,11 @@ }, "engines": { "node": ">=10.0.0" - } + }, + "repository": { + "type": "http", + "url": "https://github.com/alibaba/lowcode-engine/tree/main/modules/material-parser" + }, + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/designer/package.json b/packages/designer/package.json index 4deaa27219..fe25d1818d 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -53,5 +53,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/designer" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index efb73bb2ca..64720bc033 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -47,5 +47,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/editor-core" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 9199e1cb3d..cbec0fc0b2 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -42,5 +42,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/editor-skeleton" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/engine/package.json b/packages/engine/package.json index 4a2d7f07a3..0df6fb6332 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -53,5 +53,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/engine" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 2448ce0fc0..d81489d2d8 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -16,5 +16,11 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "fs-extra": "^10.0.0" - } + }, + "repository": { + "type": "http", + "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/ignitor" + }, + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 302d224915..65e45d9aab 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -37,5 +37,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/plugin-designer" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index b191969208..74875dc9d4 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -38,5 +38,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/plugin-outline-pane" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 3910afe41e..0af3a5eecf 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -48,6 +48,7 @@ "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/rax-renderer" }, "license": "MIT", - "homepage": "https://unpkg.alibaba-inc.com/@alilc/lowcode-rax-renderer@0.1.2/build/index.html", - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "homepage": "https://github.com/alibaba/lowcode-engine/#readme", + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues" } diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 0e29b10919..8513b30d39 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -49,6 +49,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/rax-simulator-renderer" }, - "homepage": "https://unpkg.alibaba-inc.com/@alilc/lowcode-rax-simulator-renderer@1.0.73/build/index.html", - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "homepage": "https://github.com/alibaba/lowcode-engine/#readme", + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues" } diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 451ef1ee3d..6039d4ceae 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -41,6 +41,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer" }, - "homepage": "https://unpkg.alibaba-inc.com/@alilc/lowcode-react-renderer@1.0.21/build/index.html", - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "homepage": "https://github.com/alibaba/lowcode-engine/#readme", + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues" } diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index adb5526c73..2d56ffef5f 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -43,5 +43,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/react-simulator-renderer" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index ce633dd546..9d5a3f3f25 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -55,5 +55,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/renderer-core" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/shell/package.json b/packages/shell/package.json index 9ec85ec5c2..a885e34e7f 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -48,5 +48,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/shell" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/types/package.json b/packages/types/package.json index 0b05893ca1..2888420177 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -29,5 +29,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/types" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/utils/package.json b/packages/utils/package.json index 6a0880b007..cf253042f2 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -32,5 +32,7 @@ "type": "http", "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/utils" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 569d652037..e0721c797e 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -47,7 +47,9 @@ }, "repository": { "type": "http", - "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/shell" + "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/workspace" }, - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", + "bugs": "https://github.com/alibaba/lowcode-engine/issues", + "homepage": "https://github.com/alibaba/lowcode-engine/#readme" } diff --git a/scripts/set-repo.js b/scripts/set-repo.js new file mode 100644 index 0000000000..9bae66d053 --- /dev/null +++ b/scripts/set-repo.js @@ -0,0 +1,45 @@ +#!/usr/bin/env node + +const path = require('path'); +const fs = require('fs-extra'); + +(async () => { + const root = path.join(__dirname, '../'); + const workspaces = ['modules', 'packages']; + for (const workspace of workspaces) { + const pkgDir = path.join(root, workspace); + const pkgs = await fs.readdir(pkgDir); + for (const pkg of pkgs) { + if (pkg.charAt(0) === '.') continue; + if (!(await fs.statSync(path.join(pkgDir, pkg))).isDirectory()) continue; + await setRepo({ + workspace, + pkgDir, + pkg, + }); + } + } + + async function setRepo(opts) { + const pkgDir = path.join(opts.pkgDir, opts.pkg); + const pkgPkgJSONPath = path.join(pkgDir, 'package.json'); + if (!fs.existsSync(pkgPkgJSONPath)) { + console.log(`${opts.pkg} exists`); + } else { + const pkgPkgJSON = require(pkgPkgJSONPath); + fs.writeJSONSync( + pkgPkgJSONPath, + Object.assign(pkgPkgJSON, { + repository: { + type: 'http', + url: `https://github.com/alibaba/lowcode-engine/tree/main/${opts.workspace}/${opts.pkg}`, + }, + bugs: 'https://github.com/alibaba/lowcode-engine/issues', + homepage: 'https://github.com/alibaba/lowcode-engine/#readme', + }), + { spaces: ' ' }, + ); + console.log(`[Write] ${opts.pkg}`); + } + } +})(); From 7eed0966e9dded8c9024525771bf0d986e6d49c8 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 7 Jun 2023 17:58:54 +0800 Subject: [PATCH 036/361] fix(outline-pane): tree does not change when doc.importSchema call --- .../src/controllers/pane-controller.ts | 8 ++++---- .../plugin-outline-pane/src/controllers/tree-node.ts | 10 ++++++---- packages/plugin-outline-pane/src/controllers/tree.ts | 4 ++++ .../plugin-outline-pane/src/views/tree-branches.tsx | 8 ++++---- packages/plugin-outline-pane/src/views/tree-node.tsx | 2 +- packages/plugin-outline-pane/src/views/tree-title.tsx | 2 +- packages/plugin-outline-pane/src/views/tree.tsx | 7 ++++++- 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/packages/plugin-outline-pane/src/controllers/pane-controller.ts b/packages/plugin-outline-pane/src/controllers/pane-controller.ts index e7c41892c6..6a9ae7c40c 100644 --- a/packages/plugin-outline-pane/src/controllers/pane-controller.ts +++ b/packages/plugin-outline-pane/src/controllers/pane-controller.ts @@ -593,7 +593,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy // at this moment, it is possible that pane is not ready yet, so // put ui related operations to the next loop setTimeout(() => { - tree.setNodeSelected(treeNode.id); + tree.setNodeSelected(treeNode.nodeId); this.scrollToNode(treeNode, null, 4); }, 0); } @@ -615,21 +615,21 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy if (!this._shell) { return undefined; } - return this._shell.querySelector(`.tree-node[data-id="${treeNode.id}"]`)?.getBoundingClientRect(); + return this._shell.querySelector(`.tree-node[data-id="${treeNode.nodeId}"]`)?.getBoundingClientRect(); } private getTreeTitleRect(treeNode: TreeNode): DOMRect | undefined { if (!this._shell) { return undefined; } - return this._shell.querySelector(`.tree-node-title[data-id="${treeNode.id}"]`)?.getBoundingClientRect(); + return this._shell.querySelector(`.tree-node-title[data-id="${treeNode.nodeId}"]`)?.getBoundingClientRect(); } private getTreeSlotsRect(treeNode: TreeNode): DOMRect | undefined { if (!this._shell) { return undefined; } - return this._shell.querySelector(`.tree-node-slots[data-id="${treeNode.id}"]`)?.getBoundingClientRect(); + return this._shell.querySelector(`.tree-node-slots[data-id="${treeNode.nodeId}"]`)?.getBoundingClientRect(); } } diff --git a/packages/plugin-outline-pane/src/controllers/tree-node.ts b/packages/plugin-outline-pane/src/controllers/tree-node.ts index 079ed77d65..92bf374d86 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-node.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-node.ts @@ -4,7 +4,7 @@ import { IPublicModelNode, IPublicTypeDisposable, } from '@alilc/lowcode-types'; -import { isI18nData, isLocationChildrenDetail } from '@alilc/lowcode-utils'; +import { isI18nData, isLocationChildrenDetail, uniqueId } from '@alilc/lowcode-utils'; import EventEmitter from 'events'; import { Tree } from './tree'; import { IOutlinePanelPluginContext } from './tree-master'; @@ -60,7 +60,9 @@ export default class TreeNode { */ private _expanded = false; - get id(): string { + id = uniqueId('treeNode'); + + get nodeId(): string { return this.node.id; } @@ -256,7 +258,7 @@ export default class TreeNode { return false; } return ( - isLocationChildrenDetail(loc.detail) && loc.detail.focus?.type === 'node' && loc.detail?.focus?.node.id === this.id + isLocationChildrenDetail(loc.detail) && loc.detail.focus?.type === 'node' && loc.detail?.focus?.node.id === this.nodeId ); } @@ -278,7 +280,7 @@ export default class TreeNode { if (!loc) { return false; } - return loc.target?.id === this.id; + return loc.target?.id === this.nodeId; } setTitleLabel(label: string) { diff --git a/packages/plugin-outline-pane/src/controllers/tree.ts b/packages/plugin-outline-pane/src/controllers/tree.ts index ab0d64b0f5..463c7919f3 100644 --- a/packages/plugin-outline-pane/src/controllers/tree.ts +++ b/packages/plugin-outline-pane/src/controllers/tree.ts @@ -45,6 +45,10 @@ export class Tree { const treeNode = this.getTreeNodeById(node.id); treeNode?.setHidden(!visible); }); + + doc?.onImportSchema(() => { + this.treeNodesMap = new Map(); + }); } setNodeSelected(nodeId: string): void { diff --git a/packages/plugin-outline-pane/src/views/tree-branches.tsx b/packages/plugin-outline-pane/src/views/tree-branches.tsx index 2e281071bb..41bd694812 100644 --- a/packages/plugin-outline-pane/src/views/tree-branches.tsx +++ b/packages/plugin-outline-pane/src/views/tree-branches.tsx @@ -169,12 +169,12 @@ class TreeNodeChildren extends PureComponent<{ children.push(insertion); } } - groupContents.push(); + groupContents.push(); } else { if (index === dropIndex) { children.push(insertion); } - children.push(); + children.push(); } }); endGroup(); @@ -201,14 +201,14 @@ class TreeNodeSlots extends PureComponent<{ className={classNames('tree-node-slots', { 'insertion-at-slots': treeNode.dropDetail?.focus?.type === 'slots', })} - data-id={treeNode.id} + data-id={treeNode.nodeId} >
{/* @ts-ignore */} </div> {treeNode.slots.map(tnode => ( - <TreeNodeView key={tnode.id} treeNode={tnode} /> + <TreeNodeView key={tnode.nodeId} treeNode={tnode} /> ))} </div> ); diff --git a/packages/plugin-outline-pane/src/views/tree-node.tsx b/packages/plugin-outline-pane/src/views/tree-node.tsx index 882fe15b1a..be6e6ae2c8 100644 --- a/packages/plugin-outline-pane/src/views/tree-node.tsx +++ b/packages/plugin-outline-pane/src/views/tree-node.tsx @@ -225,7 +225,7 @@ export default class TreeNodeView extends PureComponent<{ return ( <div className={className} - data-id={treeNode.id} + data-id={treeNode.nodeId} > <TreeTitle treeNode={treeNode} diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 6f35c6a614..6686ea3cf7 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -135,7 +135,7 @@ export default class TreeTitle extends PureComponent<{ <div className={classNames('tree-node-title', { editing })} style={style} - data-id={treeNode.id} + data-id={treeNode.nodeId} onClick={() => { if (isModal) { if (this.state.visible) { diff --git a/packages/plugin-outline-pane/src/views/tree.tsx b/packages/plugin-outline-pane/src/views/tree.tsx index 4bc5028861..675f70c2b3 100644 --- a/packages/plugin-outline-pane/src/views/tree.tsx +++ b/packages/plugin-outline-pane/src/views/tree.tsx @@ -91,7 +91,7 @@ export default class TreeView extends PureComponent<{ private onDoubleClick = (e: ReactMouseEvent) => { e.preventDefault(); const treeNode = this.getTreeNodeFromEvent(e); - if (treeNode?.id === this.state.root?.id) { + if (treeNode?.nodeId === this.state.root?.nodeId) { return; } if (!treeNode?.expanded) { @@ -188,6 +188,11 @@ export default class TreeView extends PureComponent<{ root: tree.root, }); }); + doc?.onImportSchema(() => { + this.setState({ + root: tree.root, + }); + }); } render() { From 723eb3d4d73f92d0720d0ae5208f2d37326b8677 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 8 Jun 2023 10:50:01 +0800 Subject: [PATCH 037/361] fix: fix the problem caused by props.children is [] by default in leaf --- packages/renderer-core/src/hoc/leaf.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index 432f22a5e5..bb81e88e37 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -538,7 +538,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { if (this.props.children && this.props.children.length) { return this.props.children; } - return []; + return this.props.children; } get leaf(): INode | undefined { From 0dc8120f80b50e0f2cff9bea1de21f036b54bc53 Mon Sep 17 00:00:00 2001 From: yifanwww <yifanw1101@gmail.com> Date: Fri, 9 Jun 2023 11:00:31 +0800 Subject: [PATCH 038/361] fix(lowcode-types): allow `template` field in supports.events --- packages/types/src/shell/type/metadata.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/types/src/shell/type/metadata.ts b/packages/types/src/shell/type/metadata.ts index 573be16899..c07d9802e1 100644 --- a/packages/types/src/shell/type/metadata.ts +++ b/packages/types/src/shell/type/metadata.ts @@ -139,6 +139,7 @@ export interface ConfigureSupportEventConfig { name: string; propType?: IPublicTypePropType; description?: string; + template?: string; } /** From 343954009e920e5db5139df5b9267eae2babb291 Mon Sep 17 00:00:00 2001 From: ChiZng <smile_zchi@163.com> Date: Fri, 9 Jun 2023 15:52:27 +0800 Subject: [PATCH 039/361] =?UTF-8?q?doc(projectapi):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E7=9A=84getCurrentDocument=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/api/project.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index e31672e25f..7998228e2b 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -182,19 +182,6 @@ importSchema(schema?: IPublicTypeProjectSchema): void; ``` 相关类型:[IPublicTypeProjectSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/project-schema.ts) -### getCurrentDocument -获取当前的 document - -```typescript -/** - * 获取当前的 document - * get current document - * @returns - */ -getCurrentDocument(): IPublicModelDocumentModel | null; -``` -相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) - ### addPropsTransducer 增加一个属性的管道处理函数 From 3a21709e585f6af7dc8ead1f5beb4c15cd5a2eb9 Mon Sep 17 00:00:00 2001 From: eternalsky <wsj7552715@hotmail.com> Date: Fri, 9 Jun 2023 17:26:02 +0800 Subject: [PATCH 040/361] fix(code-generator): upgrade prettier parser from babel to babel-ts, fix some ts parse error (#2166) --- modules/code-generator/src/postprocessor/prettier/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/src/postprocessor/prettier/index.ts b/modules/code-generator/src/postprocessor/prettier/index.ts index 075fc66e7a..079c45582e 100644 --- a/modules/code-generator/src/postprocessor/prettier/index.ts +++ b/modules/code-generator/src/postprocessor/prettier/index.ts @@ -21,7 +21,7 @@ const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig const codePrettier: PostProcessor = (content: string, fileType: string) => { let parser: prettier.BuiltInParserName | any; if (fileType === 'js' || fileType === 'jsx' || fileType === 'ts' || fileType === 'tsx') { - parser = 'babel'; + parser = 'babel-ts'; } else if (fileType === 'json') { parser = 'json-stringify'; } else if (PARSERS.indexOf(fileType) >= 0) { From 9ccf8536244dc20e4029819ed50c7263d0c8f640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= <yuanlihao1988@gmail.com> Date: Fri, 9 Jun 2023 17:26:51 +0800 Subject: [PATCH 041/361] chore(release): code-generator - 1.1.4 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 7bcf9b1739..ce01f5e4e1 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-code-generator", - "version": "1.1.3", + "version": "1.1.4", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From 16f5ee71e4e897228e288d3bd832f13e6dce8639 Mon Sep 17 00:00:00 2001 From: stefan-ysh <58702199+stefan-ysh@users.noreply.github.com> Date: Sun, 11 Jun 2023 18:24:02 +0800 Subject: [PATCH 042/361] fix: Corrected a misspelling in the docs --- docs/docs/guide/design/setter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/design/setter.md b/docs/docs/guide/design/setter.md index 968e7bbf8c..7afbbf034f 100644 --- a/docs/docs/guide/design/setter.md +++ b/docs/docs/guide/design/setter.md @@ -32,7 +32,7 @@ sidebar_position: 6 ### SettingTarget 抽象 -如果不是多选,可以直接暴露 `Node` 给到这,但涉及多选编辑的时候,大家的值时通常是不一样的,设置的时候需要批量设置进去,这里主要封装这些逻辑,把多选编辑的复杂性屏蔽掉。 +如果不是多选,可以直接暴露 `Node` 给到这,但涉及多选编辑的时候,大家的值通常是不一样的,设置的时候需要批量设置进去,这里主要封装这些逻辑,把多选编辑的复杂性屏蔽掉。 所选节点所构成的**设置对象**抽象如下: From c838dc70eb71e4aaae37494baf7f3a1d3fec8340 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 12 Jun 2023 11:29:22 +0800 Subject: [PATCH 043/361] feat(workspace): add editorViews to resourceTypeList api --- packages/shell/src/api/workspace.ts | 7 +++++++ packages/shell/src/model/editor-view.ts | 8 ++++++++ packages/types/src/shell/model/editor-view.ts | 6 +++++- packages/workspace/src/context/view-context.ts | 2 ++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index d51f670e9d..1a16d31ce8 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -39,12 +39,19 @@ export class Workspace implements IPublicApiWorkspace { const { name: resourceName, type: resourceType } = d; const { description, + editorViews, } = d.resourceTypeModel({} as any, {}); return { resourceName, resourceType, description, + editorViews: editorViews.map(d => ( + { + viewName: d.viewName, + viewType: d.viewType || 'editor', + } + )), }; }); } diff --git a/packages/shell/src/model/editor-view.ts b/packages/shell/src/model/editor-view.ts index d70a109b1d..92d1a57726 100644 --- a/packages/shell/src/model/editor-view.ts +++ b/packages/shell/src/model/editor-view.ts @@ -24,4 +24,12 @@ export class EditorView { }, }); } + + get viewName() { + return this[editorViewSymbol].viewName; + } + + get viewType() { + return this[editorViewSymbol].viewType; + } } diff --git a/packages/types/src/shell/model/editor-view.ts b/packages/types/src/shell/model/editor-view.ts index 793417845b..d51e4f9ff2 100644 --- a/packages/types/src/shell/model/editor-view.ts +++ b/packages/types/src/shell/model/editor-view.ts @@ -1,3 +1,7 @@ import { IPublicModelPluginContext } from './plugin-context'; -export interface IPublicModelEditorView extends IPublicModelPluginContext {} \ No newline at end of file +export interface IPublicModelEditorView extends IPublicModelPluginContext { + viewName: string; + + viewType: 'editor' | 'webview'; +} \ No newline at end of file diff --git a/packages/workspace/src/context/view-context.ts b/packages/workspace/src/context/view-context.ts index ff4c12eeea..0542f83a95 100644 --- a/packages/workspace/src/context/view-context.ts +++ b/packages/workspace/src/context/view-context.ts @@ -10,6 +10,8 @@ export interface IViewContext extends IBasicContext { editorWindow: IEditorWindow; viewName: string; + + viewType: 'editor' | 'webview'; } export class Context extends BasicContext implements IViewContext { From 11b929b42fb3baf76daed473fa3f76cb431c56f8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 12 Jun 2023 14:45:10 +0800 Subject: [PATCH 044/361] fix(render-core): fix when designMode is false & loop is null, isUseLoop should return true --- packages/renderer-core/jest.config.js | 1 + packages/renderer-core/src/utils/is-use-loop.ts | 8 ++++---- packages/renderer-core/tests/utils/is-use-loop.test.ts | 6 ++++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/renderer-core/jest.config.js b/packages/renderer-core/jest.config.js index e3267c5177..1ea4204de5 100644 --- a/packages/renderer-core/jest.config.js +++ b/packages/renderer-core/jest.config.js @@ -13,6 +13,7 @@ const jestConfig = { // testMatch: ['**/*/base.test.tsx'], // testMatch: ['**/utils/common.test.ts'], // testMatch: ['**/*/leaf.test.tsx'], + // testMatch: ['**/*/is-use-loop.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/renderer-core/src/utils/is-use-loop.ts b/packages/renderer-core/src/utils/is-use-loop.ts index 509450d942..b6d67a802a 100644 --- a/packages/renderer-core/src/utils/is-use-loop.ts +++ b/packages/renderer-core/src/utils/is-use-loop.ts @@ -8,13 +8,13 @@ export default function isUseLoop(loop: null | any[] | IPublicTypeJSExpression, return true; } - if (!Array.isArray(loop)) { - return false; - } - if (!isDesignMode) { return true; } + if (!Array.isArray(loop)) { + return false; + } + return loop.length > 0; } diff --git a/packages/renderer-core/tests/utils/is-use-loop.test.ts b/packages/renderer-core/tests/utils/is-use-loop.test.ts index 5f502a2e5b..b0a614f2ee 100644 --- a/packages/renderer-core/tests/utils/is-use-loop.test.ts +++ b/packages/renderer-core/tests/utils/is-use-loop.test.ts @@ -5,6 +5,9 @@ describe('base test', () => { it('designMode is true', () => { expect(isUseLoop([], true)).toBeFalsy(); expect(isUseLoop([{}], true)).toBeTruthy(); + expect(isUseLoop(null, true)).toBeFalsy(); + expect(isUseLoop(undefined, true)).toBeFalsy(); + expect(isUseLoop(0, true)).toBeFalsy(); }); it('loop is expression', () => { @@ -21,5 +24,8 @@ describe('base test', () => { it('designMode is false', () => { expect(isUseLoop([], false)).toBeTruthy(); expect(isUseLoop([{}], false)).toBeTruthy(); + expect(isUseLoop(null, false)).toBeTruthy(); + expect(isUseLoop(undefined, false)).toBeTruthy(); + expect(isUseLoop(0, false)).toBeTruthy(); }); }); From f81954fda5113255e0581542e9668aa264b798a8 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 13 Jun 2023 11:38:35 +0800 Subject: [PATCH 045/361] chore(docs): publish 1.0.32 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 20efc6c630..f8617eac0a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.31", + "version": "1.0.32", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 48acc2d2e8c5180a240b9be705fe090274fc82be Mon Sep 17 00:00:00 2001 From: eightHundreds <mingoing@outlook.com> Date: Thu, 15 Jun 2023 09:59:53 +0800 Subject: [PATCH 046/361] feat: make appHelper observable (#2186) * feat: make appHelper observable --- .../designer/src/builtin-simulator/host.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index fdf26c06c1..cdb7642a5a 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -14,6 +14,7 @@ import { createModuleEventBus, IEventBus, } from '@alilc/lowcode-editor-core'; + import { ISimulatorHost, Component, @@ -265,6 +266,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp @obx.ref private _contentDocument?: Document; + @obx.ref private _appHelper?: any; + get contentDocument() { return this._contentDocument; } @@ -310,13 +313,19 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp this.designer = designer; this.scroller = this.designer.createScroller(this.viewport); this.autoRender = !engineConfig.get('disableAutoRender', false); + this._appHelper = engineConfig.get('appHelper'); this.componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset); this.injectionConsumer = new ResourceConsumer(() => { return { - appHelper: engineConfig.get('appHelper'), + appHelper: this._appHelper, }; }); + engineConfig.onGot('appHelper', (data) => { + // appHelper被config.set修改后触发injectionConsumer.consume回调 + this._appHelper = data; + }); + this.i18nConsumer = new ResourceConsumer(() => this.project.i18n); transactionManager.onStartTransaction(() => { @@ -384,6 +393,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp purge(): void { // todo + } mountViewport(viewport: HTMLElement | null) { @@ -494,7 +504,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp if (Object.keys(this.asyncLibraryMap).length > 0) { // 加载异步 Library await renderer.loadAsyncLibrary(this.asyncLibraryMap); - Object.keys(this.asyncLibraryMap).forEach(key => { + Object.keys(this.asyncLibraryMap).forEach((key) => { delete this.asyncLibraryMap[key]; }); } @@ -521,7 +531,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp if (Object.keys(this.asyncLibraryMap).length > 0) { // 加载异步 Library await this.renderer?.loadAsyncLibrary(this.asyncLibraryMap); - Object.keys(this.asyncLibraryMap).forEach(key => { + Object.keys(this.asyncLibraryMap).forEach((key) => { delete this.asyncLibraryMap[key]; }); } @@ -680,7 +690,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp const x = new Event('click'); x.initEvent('click', true); this._iframe?.dispatchEvent(x); - const target = e.target; + const { target } = e; const customizeIgnoreSelectors = engineConfig.get('customizeIgnoreSelectors'); // TODO: need more elegant solution to ignore click events of components in designer @@ -1497,7 +1507,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp handleAccept({ container }: DropContainer, e: ILocateEvent): boolean { const { dragObject } = e; const document = this.currentDocument!; - const focusNode = document.focusNode; + const { focusNode } = document; if (isRootNode(container) || container.contains(focusNode)) { return document.checkNesting(focusNode!, dragObject as any); } From b6313c0460f9f825920594329c53502fa93233e5 Mon Sep 17 00:00:00 2001 From: LiGuangNian <792841450@qq.com> Date: Mon, 26 Jun 2023 12:19:13 +0800 Subject: [PATCH 047/361] Update material.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit loadIncrementalAssets返回的应当是Promise<void> --- docs/docs/api/material.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 5a5502fda6..2bf99577cb 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -102,7 +102,7 @@ material.getAssets(); * @param incrementalAssets * @returns */ -loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): void; +loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): Promise<void>; ``` 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) From 88008a7933a6a829233d770544bf82249f2dd290 Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Mon, 26 Jun 2023 17:24:23 +0800 Subject: [PATCH 048/361] remove duplicate code --- packages/engine/src/engine-core.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 84dfd67aa8..204b9b30ab 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -83,7 +83,6 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins plugins.delete(componentMetaParserPlugin.pluginName); plugins.delete(setterRegistry.pluginName); plugins.delete(defaultPanelRegistryPlugin.pluginName); - plugins.delete(defaultPanelRegistryPlugin.pluginName); plugins.delete(builtinHotkey.pluginName); plugins.delete(registerDefaults.pluginName); }; From 731dc58649ffa68a528c7b97e770f03e4252c2c8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 27 Jun 2023 14:07:07 +0800 Subject: [PATCH 049/361] fix: lerna version to 4.0.0 --- packages/types/src/shell/type/node-schema.ts | 11 +++++++---- scripts/setup-skip-build.sh | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/types/src/shell/type/node-schema.ts b/packages/types/src/shell/type/node-schema.ts index b2520ee385..9cbd0a81ac 100644 --- a/packages/types/src/shell/type/node-schema.ts +++ b/packages/types/src/shell/type/node-schema.ts @@ -5,11 +5,14 @@ import { IPublicTypeCompositeValue, IPublicTypePropsMap, IPublicTypeNodeData } f * 搭建基础协议 - 单个组件树节点描述 */ export interface IPublicTypeNodeSchema { + id?: string; + /** * 组件名称 必填、首字母大写 */ componentName: string; + /** * 组件属性对象 */ @@ -17,26 +20,26 @@ export interface IPublicTypeNodeSchema { children?: IPublicTypeNodeData | IPublicTypeNodeData[]; } & IPublicTypePropsMap; // | PropsList; - /** - * 组件属性对象 - */ - leadingComponents?: string; /** * 渲染条件 */ condition?: IPublicTypeCompositeValue; + /** * 循环数据 */ loop?: IPublicTypeCompositeValue; + /** * 循环迭代对象、索引名称 ["item", "index"] */ loopArgs?: [string, string]; + /** * 子节点 */ children?: IPublicTypeNodeData | IPublicTypeNodeData[]; + /** * 是否锁定 */ diff --git a/scripts/setup-skip-build.sh b/scripts/setup-skip-build.sh index d51c33c417..7c0ff6a273 100755 --- a/scripts/setup-skip-build.sh +++ b/scripts/setup-skip-build.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash rm -rf node_modules package-lock.json yarn.lock + +npm i lerna@4.0.0 + lerna clean -y find ./packages -type f -name "package-lock.json" -exec rm -f {} \; From 30686a5bb8b99ee984d22d2de0d5f79849764624 Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Tue, 27 Jun 2023 17:28:13 +0800 Subject: [PATCH 050/361] fix: the selectionDispose function is never executed --- packages/designer/src/designer/designer.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 74c1f51b25..784ebf57bc 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -144,6 +144,8 @@ export class Designer implements IDesigner { private oobxList: OffsetObserver[] = []; + private selectionDispose: undefined | (() => void); + @obx.ref private _componentMetasMap = new Map<string, IComponentMeta>(); @obx.ref private _simulatorComponent?: ComponentType<any>; @@ -265,10 +267,9 @@ export class Designer implements IDesigner { } setupSelection = () => { - let selectionDispose: undefined | (() => void); - if (selectionDispose) { - selectionDispose(); - selectionDispose = undefined; + if (this.selectionDispose) { + this.selectionDispose(); + this.selectionDispose = undefined; } const { currentSelection } = this; // TODO: 避免选中 Page 组件,默认选中第一个子节点;新增规则 或 判断 Live 模式 @@ -284,7 +285,7 @@ export class Designer implements IDesigner { } this.postEvent('selection.change', currentSelection); if (currentSelection) { - selectionDispose = currentSelection.onSelectionChange(() => { + this.selectionDispose = currentSelection.onSelectionChange(() => { this.postEvent('selection.change', currentSelection); }); } From a1a50f25704a56e045d6d645eea4179c25ee60ac Mon Sep 17 00:00:00 2001 From: eightHundreds <mingoing@outlook.com> Date: Fri, 30 Jun 2023 14:27:50 +0800 Subject: [PATCH 051/361] fix: change the return result type to Promise --- packages/types/src/shell/type/plugin-config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/types/src/shell/type/plugin-config.ts b/packages/types/src/shell/type/plugin-config.ts index 8a533f8fe1..e9e65192e0 100644 --- a/packages/types/src/shell/type/plugin-config.ts +++ b/packages/types/src/shell/type/plugin-config.ts @@ -1,5 +1,5 @@ export interface IPublicTypePluginConfig { - init(): void; - destroy?(): void; + init(): Promise<void>; + destroy?(): Promise<void>; exports?(): any; } From cb2e05046f417422d9da98a9e255e9f49a895d6d Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 4 Jul 2023 09:51:17 +0800 Subject: [PATCH 052/361] feat: add document-model shell return types --- docs/docs/api/model/document-model.md | 6 ++++-- packages/shell/src/model/document-model.ts | 2 +- packages/types/src/shell/model/document-model.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/docs/api/model/document-model.md b/docs/docs/api/model/document-model.md index b609f00504..8d813e7678 100644 --- a/docs/docs/api/model/document-model.md +++ b/docs/docs/api/model/document-model.md @@ -139,10 +139,12 @@ importSchema(schema: IPublicTypeRootSchema): void; * @param stage * @returns */ -exportSchema(stage: IPublicEnumTransformStage): any; +exportSchema(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined; ``` -相关类型:[IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) +相关类型: +- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) +- [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) ### insertNode diff --git a/packages/shell/src/model/document-model.ts b/packages/shell/src/model/document-model.ts index 06f3cebcd9..2c5c7b632e 100644 --- a/packages/shell/src/model/document-model.ts +++ b/packages/shell/src/model/document-model.ts @@ -164,7 +164,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @param stage * @returns */ - exportSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render): any { + exportSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render): IPublicTypeRootSchema | undefined { return this[documentSymbol].export(stage); } diff --git a/packages/types/src/shell/model/document-model.ts b/packages/types/src/shell/model/document-model.ts index 2ef0b532be..4c9344eb48 100644 --- a/packages/types/src/shell/model/document-model.ts +++ b/packages/types/src/shell/model/document-model.ts @@ -89,7 +89,7 @@ export interface IPublicModelDocumentModel< * @param stage * @returns */ - exportSchema(stage: IPublicEnumTransformStage): any; + exportSchema(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined; /** * 插入节点 From 323e85f595e3efb5f54caf3ec8350108465df531 Mon Sep 17 00:00:00 2001 From: BARM <chenglin@dian.so> Date: Thu, 6 Jul 2023 11:18:31 +0800 Subject: [PATCH 053/361] fix(code-gen): fix example-solution.ts format problem (#2207) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 林熠 <jack.lianjie@gmail.com> --- modules/code-generator/src/cli/solutions/example-solution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/src/cli/solutions/example-solution.ts b/modules/code-generator/src/cli/solutions/example-solution.ts index fe303f360f..0314151c6e 100644 --- a/modules/code-generator/src/cli/solutions/example-solution.ts +++ b/modules/code-generator/src/cli/solutions/example-solution.ts @@ -289,8 +289,8 @@ codealike.json }, "lifeCycles": { "componentDidMount": { - "type": "JSExpression", - "value": "function() { console.log('componentDidMount'); }" + "type": "JSFunction", + "value": "function componentDidMount() {\\n console.log('componentDidMount');\\n}" } }, "methodsModule": { From 11501e836d150d444c0d6370e6d5f533132a3738 Mon Sep 17 00:00:00 2001 From: BARM <chenglin@dian.so> Date: Thu, 6 Jul 2023 11:20:07 +0800 Subject: [PATCH 054/361] chore(code-gen): export containerInjectConstants function (#2206) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 林熠 <jack.lianjie@gmail.com> --- modules/code-generator/src/solutions/icejs.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/src/solutions/icejs.ts b/modules/code-generator/src/solutions/icejs.ts index 6f5bdde599..7dc44f4bec 100644 --- a/modules/code-generator/src/solutions/icejs.ts +++ b/modules/code-generator/src/solutions/icejs.ts @@ -100,11 +100,12 @@ export default function createIceJsProjectBuilder( export const plugins = { containerClass, - containerInitState, containerInjectContext, containerInjectUtils, - containerInjectI18n, containerInjectDataSourceEngine, + containerInjectI18n, + containerInjectConstants, + containerInitState, containerLifeCycle, containerMethod, jsx, From 5cc4715daf510a64b6bf10c51b3a12df2bc62a36 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 7 Jul 2023 17:34:57 +0800 Subject: [PATCH 055/361] chore(release): publish 1.1.8 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 67ffb648e2..52ee714c28 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.1.7", + "version": "1.1.8", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index fe25d1818d..e3d1535aa5 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.1.7", + "version": "1.1.8", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -16,9 +16,9 @@ "license": "MIT", "dependencies": { "@alilc/build-plugin-lce": "^0.0.4-beta.2", - "@alilc/lowcode-editor-core": "1.1.7", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-editor-core": "1.1.8", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 64720bc033..939a73183b 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.1.7", + "version": "1.1.8", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index cbec0fc0b2..16cc1cc098 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.1.7", + "version": "1.1.8", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-editor-core": "1.1.7", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-editor-core": "1.1.8", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 0df6fb6332..030f14a764 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.1.7", + "version": "1.1.8", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-editor-core": "1.1.7", - "@alilc/lowcode-editor-skeleton": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-editor-core": "1.1.8", + "@alilc/lowcode-editor-skeleton": "1.1.8", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.1.7", - "@alilc/lowcode-plugin-outline-pane": "1.1.7", - "@alilc/lowcode-shell": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", - "@alilc/lowcode-workspace": "1.1.7", + "@alilc/lowcode-plugin-designer": "1.1.8", + "@alilc/lowcode-plugin-outline-pane": "1.1.8", + "@alilc/lowcode-shell": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-workspace": "1.1.8", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index d81489d2d8..d7796db32f 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.1.7", + "version": "1.1.8", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 65e45d9aab..7d5a434811 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.1.7", + "version": "1.1.8", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-editor-core": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-editor-core": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 74875dc9d4..f6a4aea0a5 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.1.7", + "version": "1.1.8", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 0af3a5eecf..b91511afd7 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.1.7", + "version": "1.1.8", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-renderer-core": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 8513b30d39..8a456b6cf4 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.1.7", + "version": "1.1.8", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-rax-renderer": "1.1.7", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-rax-renderer": "1.1.8", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 6039d4ceae..4af63fa78b 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.1.7", + "version": "1.1.8", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.1.7" + "@alilc/lowcode-renderer-core": "1.1.8" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 2d56ffef5f..43bfd47a87 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.1.7", + "version": "1.1.8", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-react-renderer": "1.1.7", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-react-renderer": "1.1.8", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 9d5a3f3f25..f0b4b3e9cb 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.1.7", + "version": "1.1.8", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index a885e34e7f..c24113d0fe 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.1.7", + "version": "1.1.8", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-editor-core": "1.1.7", - "@alilc/lowcode-editor-skeleton": "1.1.7", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", - "@alilc/lowcode-workspace": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-editor-core": "1.1.8", + "@alilc/lowcode-editor-skeleton": "1.1.8", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-workspace": "1.1.8", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 2888420177..2aef9019c3 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.1.7", + "version": "1.1.8", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index cf253042f2..1e4e9fb9f9 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.1.7", + "version": "1.1.8", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.7", + "@alilc/lowcode-types": "1.1.8", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index e0721c797e..b04a05cf94 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.1.7", + "version": "1.1.8", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.7", - "@alilc/lowcode-editor-core": "1.1.7", - "@alilc/lowcode-editor-skeleton": "1.1.7", - "@alilc/lowcode-types": "1.1.7", - "@alilc/lowcode-utils": "1.1.7", + "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-editor-core": "1.1.8", + "@alilc/lowcode-editor-skeleton": "1.1.8", + "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-utils": "1.1.8", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From eb3b5709c597276075ac928a1f0f2e82e6adad38 Mon Sep 17 00:00:00 2001 From: liangzr <1668890395@qq.com> Date: Fri, 7 Jul 2023 11:28:02 +0800 Subject: [PATCH 056/361] feat: listen for the logic of requestHandlersMap config update --- packages/plugin-designer/src/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/plugin-designer/src/index.tsx b/packages/plugin-designer/src/index.tsx index 54eda13651..90eefaaba5 100644 --- a/packages/plugin-designer/src/index.tsx +++ b/packages/plugin-designer/src/index.tsx @@ -67,6 +67,11 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP locale, }); }); + engineConfig.onGot('requestHandlersMap', (requestHandlersMap) => { + this.setState({ + requestHandlersMap, + }); + }); const { components, packages, extraEnvironment, utils } = assets; const state = { componentMetadatas: components || [], From 7b6181719e28b3b56e71f84266a550d14f8d9bba Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 10 Jul 2023 15:36:34 +0800 Subject: [PATCH 057/361] feat(workspace): add multi foces-tracker in workspace mode --- packages/designer/src/builtin-simulator/host.ts | 4 ++-- .../designer/tests/builtin-simulator/host.test.ts | 5 +++++ packages/editor-core/src/utils/focus-tracker.ts | 12 ++++-------- .../editor-skeleton/src/layouts/left-float-pane.tsx | 4 ++-- packages/editor-skeleton/src/skeleton.ts | 7 ++++++- packages/workspace/src/layouts/left-float-pane.tsx | 4 ++-- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index cdb7642a5a..5e6fc06a62 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -4,7 +4,6 @@ import { reaction, computed, getPublicPath, - focusTracker, engineConfig, globalLocale, IReactionPublic, @@ -519,7 +518,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp // bind hotkey & clipboard const hotkey = this.designer.editor.get('innerHotkey'); hotkey.mount(this._contentWindow); - focusTracker.mount(this._contentWindow); + const innerSkeleton = this.designer.editor.get('skeleton'); + innerSkeleton.focusTracker.mount(this._contentWindow); clipboard.injectCopyPaster(this._contentDocument); // TODO: dispose the bindings diff --git a/packages/designer/tests/builtin-simulator/host.test.ts b/packages/designer/tests/builtin-simulator/host.test.ts index 57e74be579..d74c31d42c 100644 --- a/packages/designer/tests/builtin-simulator/host.test.ts +++ b/packages/designer/tests/builtin-simulator/host.test.ts @@ -24,6 +24,9 @@ import { fireEvent } from '@testing-library/react'; import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; import { Setters, Workspace } from '@alilc/lowcode-shell'; import { ILowCodePluginContextApiAssembler, ILowCodePluginContextPrivate, LowCodePluginManager } from '@alilc/lowcode-designer'; +import { + Skeleton as InnerSkeleton, +} from '@alilc/lowcode-editor-skeleton'; describe('Host 测试', () => { let editor: Editor; @@ -45,6 +48,8 @@ describe('Host 测试', () => { const innerPlugins = new LowCodePluginManager(pluginContextApiAssembler); const innerWorkspace = new InnerWorkspace(() => {}, {}); const workspace = new Workspace(innerWorkspace); + const innerSkeleton = new InnerSkeleton(editor); + editor.set('skeleton' as any, innerSkeleton); editor.set('innerHotkey', new InnerHotkey()) editor.set('setters', new Setters(new InnerSetters())); editor.set('innerPlugins' as any, innerPlugins); diff --git a/packages/editor-core/src/utils/focus-tracker.ts b/packages/editor-core/src/utils/focus-tracker.ts index cb88dfc567..23d509053b 100644 --- a/packages/editor-core/src/utils/focus-tracker.ts +++ b/packages/editor-core/src/utils/focus-tracker.ts @@ -1,4 +1,8 @@ export class FocusTracker { + private actives: Focusable[] = []; + + private modals: Array<{ checkDown: (e: MouseEvent) => boolean; checkOpen: () => boolean }> = []; + mount(win: Window) { const checkDown = (e: MouseEvent) => { if (this.checkModalDown(e)) { @@ -16,14 +20,10 @@ export class FocusTracker { }; } - private actives: Focusable[] = []; - get first() { return this.actives[0]; } - private modals: Array<{ checkDown: (e: MouseEvent) => boolean; checkOpen: () => boolean }> = []; - addModal(checkDown: (e: MouseEvent) => boolean, checkOpen: () => boolean) { this.modals.push({ checkDown, @@ -154,7 +154,3 @@ export class Focusable { } } } - -export const focusTracker = new FocusTracker(); - -focusTracker.mount(window); diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx index 0be5ea6c3f..7df6993bb5 100644 --- a/packages/editor-skeleton/src/layouts/left-float-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -1,6 +1,6 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; -import { observer, Focusable, focusTracker } from '@alilc/lowcode-editor-core'; +import { observer, Focusable } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; import { Panel } from '../widget/panel'; import { PanelConfig } from '../types'; @@ -31,7 +31,7 @@ export default class LeftFloatPane extends Component<{ area: Area<PanelConfig, P area.skeleton.editor.removeListener('designer.drag', triggerClose); }; - this.focusing = focusTracker.create({ + this.focusing = area.skeleton.focusTracker.create({ range: (e) => { const target = e.target as HTMLElement; if (!target) { diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 616e7f0172..8836434049 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -1,4 +1,4 @@ -import { action, makeObservable, obx, engineConfig, IEditor } from '@alilc/lowcode-editor-core'; +import { action, makeObservable, obx, engineConfig, IEditor, FocusTracker } from '@alilc/lowcode-editor-core'; import { DockConfig, PanelConfig, @@ -83,6 +83,8 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton, readonly widgets: IWidget[]; + readonly focusTracker: FocusTracker; + getPanel(name: string): Panel | undefined; getWidget(name: string): IWidget | undefined; @@ -133,6 +135,8 @@ export class Skeleton { readonly widgets: IWidget[] = []; + readonly focusTracker = new FocusTracker(); + constructor(readonly editor: IEditor, readonly viewName: string = 'global') { makeObservable(this); this.leftArea = new Area( @@ -245,6 +249,7 @@ export class Skeleton { this.setupPlugins(); this.setupEvents(); + this.focusTracker.mount(window); } /** diff --git a/packages/workspace/src/layouts/left-float-pane.tsx b/packages/workspace/src/layouts/left-float-pane.tsx index 832c2598ca..38f70b386d 100644 --- a/packages/workspace/src/layouts/left-float-pane.tsx +++ b/packages/workspace/src/layouts/left-float-pane.tsx @@ -1,6 +1,6 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; -import { observer, Focusable, focusTracker } from '@alilc/lowcode-editor-core'; +import { observer, Focusable } from '@alilc/lowcode-editor-core'; import { Area, Panel } from '@alilc/lowcode-editor-skeleton'; @observer @@ -29,7 +29,7 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> area.skeleton.editor.removeListener('designer.drag', triggerClose); }; - this.focusing = focusTracker.create({ + this.focusing = area.skeleton.focusTracker.create({ range: (e) => { const target = e.target as HTMLElement; if (!target) { From 7d7042f79921283e8d04aa5ff8d9aebe622bcc26 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 10 Jul 2023 16:51:39 +0800 Subject: [PATCH 058/361] chore(docs): publish 1.0.33 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index f8617eac0a..269bd2df64 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.32", + "version": "1.0.33", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 38dc561b6a04e3267a5f20c175923f41765bd2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E6=9E=97?= <chenglin@dian.so> Date: Tue, 11 Jul 2023 11:06:21 +0800 Subject: [PATCH 059/361] chore(code-gen): replace deprecated api --- .../src/cli/solutions/example-solution.ts | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/modules/code-generator/src/cli/solutions/example-solution.ts b/modules/code-generator/src/cli/solutions/example-solution.ts index 0314151c6e..fd34c36781 100644 --- a/modules/code-generator/src/cli/solutions/example-solution.ts +++ b/modules/code-generator/src/cli/solutions/example-solution.ts @@ -635,18 +635,18 @@ export default function createHelloWorldProjectBuilder() { template: CodeGen.solutionParts.icejs.template, plugins: { components: [ - CodeGen.plugins.react.reactCommonDeps(), - CodeGen.plugins.common.esmodule({ fileType: 'jsx' }), - CodeGen.plugins.react.containerClass(), - CodeGen.plugins.react.containerInjectContext(), - CodeGen.plugins.react.containerInjectUtils(), - CodeGen.plugins.react.containerInjectDataSourceEngine(), - CodeGen.plugins.react.containerInjectI18n(), - CodeGen.plugins.react.containerInitState(), - CodeGen.plugins.react.containerLifeCycle(), - CodeGen.plugins.react.containerMethod(), + CodeGen.plugins.icejs.reactCommonDeps(), + CodeGen.plugins.common.esModule({ fileType: 'jsx' }), + CodeGen.plugins.icejs.containerClass(), + CodeGen.plugins.icejs.containerInjectContext(), + CodeGen.plugins.icejs.containerInjectUtils(), + CodeGen.plugins.icejs.containerInjectDataSourceEngine(), + CodeGen.plugins.icejs.containerInjectI18n(), + CodeGen.plugins.icejs.containerInitState(), + CodeGen.plugins.icejs.containerLifeCycle(), + CodeGen.plugins.icejs.containerMethod(), examplePlugin(), - CodeGen.plugins.react.jsx({ + CodeGen.plugins.icejs.jsx({ nodeTypeMapping: { Div: 'div', Component: 'div', @@ -657,18 +657,18 @@ export default function createHelloWorldProjectBuilder() { CodeGen.plugins.style.css(), ], pages: [ - CodeGen.plugins.react.reactCommonDeps(), - CodeGen.plugins.common.esmodule({ fileType: 'jsx' }), - CodeGen.plugins.react.containerClass(), - CodeGen.plugins.react.containerInjectContext(), - CodeGen.plugins.react.containerInjectUtils(), - CodeGen.plugins.react.containerInjectDataSourceEngine(), - CodeGen.plugins.react.containerInjectI18n(), - CodeGen.plugins.react.containerInitState(), - CodeGen.plugins.react.containerLifeCycle(), - CodeGen.plugins.react.containerMethod(), + CodeGen.plugins.icejs.reactCommonDeps(), + CodeGen.plugins.common.esModule({ fileType: 'jsx' }), + CodeGen.plugins.icejs.containerClass(), + CodeGen.plugins.icejs.containerInjectContext(), + CodeGen.plugins.icejs.containerInjectUtils(), + CodeGen.plugins.icejs.containerInjectDataSourceEngine(), + CodeGen.plugins.icejs.containerInjectI18n(), + CodeGen.plugins.icejs.containerInitState(), + CodeGen.plugins.icejs.containerLifeCycle(), + CodeGen.plugins.icejs.containerMethod(), examplePlugin(), - CodeGen.plugins.react.jsx({ + CodeGen.plugins.icejs.jsx({ nodeTypeMapping: { Div: 'div', Component: 'div', @@ -679,13 +679,13 @@ export default function createHelloWorldProjectBuilder() { CodeGen.plugins.style.css(), ], router: [ - CodeGen.plugins.common.esmodule(), + CodeGen.plugins.common.esModule(), CodeGen.solutionParts.icejs.plugins.router(), ], entry: [CodeGen.solutionParts.icejs.plugins.entry()], constants: [CodeGen.plugins.project.constants()], utils: [ - CodeGen.plugins.common.esmodule(), + CodeGen.plugins.common.esModule(), CodeGen.plugins.project.utils('react'), ], i18n: [CodeGen.plugins.project.i18n()], From 4e24d512d12f8f9aa77261ba63d4345d43d6d31f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E6=9E=97?= <chenglin@dian.so> Date: Tue, 11 Jul 2023 11:15:52 +0800 Subject: [PATCH 060/361] =?UTF-8?q?chore(code-gen):=20icejs=E3=80=81icejs3?= =?UTF-8?q?=20solutions=20plugins.components=20add=20containerInjectConsta?= =?UTF-8?q?nts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/code-generator/src/solutions/icejs.ts | 1 + modules/code-generator/src/solutions/icejs3.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/code-generator/src/solutions/icejs.ts b/modules/code-generator/src/solutions/icejs.ts index 7dc44f4bec..1149098ecb 100644 --- a/modules/code-generator/src/solutions/icejs.ts +++ b/modules/code-generator/src/solutions/icejs.ts @@ -45,6 +45,7 @@ export default function createIceJsProjectBuilder( containerInjectUtils(), containerInjectDataSourceEngine(), containerInjectI18n(), + containerInjectConstants(), containerInitState(), containerLifeCycle(), containerMethod(), diff --git a/modules/code-generator/src/solutions/icejs3.ts b/modules/code-generator/src/solutions/icejs3.ts index c6870dfd07..a8622e74ab 100644 --- a/modules/code-generator/src/solutions/icejs3.ts +++ b/modules/code-generator/src/solutions/icejs3.ts @@ -45,6 +45,7 @@ export default function createIceJsProjectBuilder( containerInjectUtils(), containerInjectDataSourceEngine(), containerInjectI18n(), + containerInjectConstants(), containerInitState(), containerLifeCycle(), containerMethod(), From 7decc3a8db1bd81b09a51c36e50c3099b9f394d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E6=9E=97?= <chenglin@dian.so> Date: Tue, 11 Jul 2023 11:16:28 +0800 Subject: [PATCH 061/361] chore(code-gen): template sync icejs --- modules/code-generator/src/cli/solutions/example-solution.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/code-generator/src/cli/solutions/example-solution.ts b/modules/code-generator/src/cli/solutions/example-solution.ts index fd34c36781..bfb9d079b1 100644 --- a/modules/code-generator/src/cli/solutions/example-solution.ts +++ b/modules/code-generator/src/cli/solutions/example-solution.ts @@ -637,11 +637,13 @@ export default function createHelloWorldProjectBuilder() { components: [ CodeGen.plugins.icejs.reactCommonDeps(), CodeGen.plugins.common.esModule({ fileType: 'jsx' }), + CodeGen.plugins.common.styleImport(), CodeGen.plugins.icejs.containerClass(), CodeGen.plugins.icejs.containerInjectContext(), CodeGen.plugins.icejs.containerInjectUtils(), CodeGen.plugins.icejs.containerInjectDataSourceEngine(), CodeGen.plugins.icejs.containerInjectI18n(), + CodeGen.plugins.icejs.containerInjectConstants(), CodeGen.plugins.icejs.containerInitState(), CodeGen.plugins.icejs.containerLifeCycle(), CodeGen.plugins.icejs.containerMethod(), @@ -659,11 +661,13 @@ export default function createHelloWorldProjectBuilder() { pages: [ CodeGen.plugins.icejs.reactCommonDeps(), CodeGen.plugins.common.esModule({ fileType: 'jsx' }), + CodeGen.plugins.common.styleImport(), CodeGen.plugins.icejs.containerClass(), CodeGen.plugins.icejs.containerInjectContext(), CodeGen.plugins.icejs.containerInjectUtils(), CodeGen.plugins.icejs.containerInjectDataSourceEngine(), CodeGen.plugins.icejs.containerInjectI18n(), + CodeGen.plugins.icejs.containerInjectConstants(), CodeGen.plugins.icejs.containerInitState(), CodeGen.plugins.icejs.containerLifeCycle(), CodeGen.plugins.icejs.containerMethod(), From 19935cfc93de111e82691502eaf4f186a84cae37 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 11 Jul 2023 16:14:55 +0800 Subject: [PATCH 062/361] feat: add new cache from diff origin component --- packages/renderer-core/src/hoc/leaf.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index bb81e88e37..1ff91cb147 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -193,8 +193,8 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { getNode, }); - if (curDocumentId && cache.component.has(componentCacheId)) { - return cache.component.get(componentCacheId); + if (curDocumentId && cache.component.has(componentCacheId) && (cache.component.get(componentCacheId).Comp === Comp)) { + return cache.component.get(componentCacheId).LeafWrapper; } class LeafHoc extends Component { @@ -590,7 +590,10 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { LeafWrapper.displayName = (Comp as any).displayName; - cache.component.set(componentCacheId, LeafWrapper); + cache.component.set(componentCacheId, { + LeafWrapper, + Comp, + }); return LeafWrapper; } \ No newline at end of file From 2d98f1c9b5d8c8bbda5100ddecb83ceb08943b36 Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Wed, 12 Jul 2023 11:27:37 +0800 Subject: [PATCH 063/361] fix: the action of history would not update outline tree --- packages/plugin-outline-pane/src/controllers/tree.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/plugin-outline-pane/src/controllers/tree.ts b/packages/plugin-outline-pane/src/controllers/tree.ts index 463c7919f3..ca5a43c554 100644 --- a/packages/plugin-outline-pane/src/controllers/tree.ts +++ b/packages/plugin-outline-pane/src/controllers/tree.ts @@ -30,6 +30,10 @@ export class Tree { treeNode?.notifyExpandableChanged(); }); + doc?.history.onChangeCursor(() => { + this.root?.notifyExpandableChanged(); + }); + doc?.onChangeNodeProp((info: IPublicTypePropChangeOptions) => { const { node, key } = info; if (key === '___title___') { From c805bba0c73e80b9d1083ed0b4a05eaabf264d88 Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Wed, 12 Jul 2023 16:22:08 +0800 Subject: [PATCH 064/361] fix: keep `this` in parse expression function 1. Wrong work when function has `__self` 2. All `this` will replaced anyway --- packages/renderer-core/src/utils/common.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 29381b5473..262231eefb 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -251,23 +251,21 @@ function parseExpression(a: any, b?: any, c = false) { thisRequired = c; } try { - const contextArr = ['"use strict";', 'var __self = arguments[0];']; - contextArr.push('return '); let tarStr: string; tarStr = (str.value || '').trim(); - // NOTE: use __self replace 'this' in the original function str - // may be wrong in extreme case which contains '__self' already - tarStr = tarStr.replace(/this(\W|$)/g, (_a: any, b: any) => `__self${b}`); - tarStr = contextArr.join('\n') + tarStr; + let code = `"use strict"; function __wrapper(){ return ${tarStr}} return __wrapper.call(arguments[0])`; // 默认调用顶层窗口的parseObj, 保障new Function的window对象是顶层的window对象 if (inSameDomain() && (window.parent as any).__newFunc) { - return (window.parent as any).__newFunc(tarStr)(self); + return (window.parent as any).__newFunc(code)(self); } - const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`; - return new Function('$scope', code)(self); + if (!thisRequired) { + code = `with($scope){${code}}`; + } + const result = new Function('$scope', code)(self); + return typeof result === "function" ? result.bind(self): result; } catch (err) { logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self); return undefined; From aa1bb1c0d720d972e64049f92358456b14069310 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 12 Jul 2023 18:01:45 +0800 Subject: [PATCH 065/361] feat: add config.workspaceEmptyComponent --- packages/editor-core/src/config.ts | 4 ++++ packages/workspace/src/layouts/workbench.tsx | 18 +++++++++++++++++- packages/workspace/src/workspace.ts | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index c325c2bb85..85e6097801 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -155,6 +155,10 @@ const VALID_ENGINE_OPTIONS = { description: '是否开启应用级设计模式', default: false, }, + workspaceEmptyComponent: { + type: 'function', + description: '应用级设计模式下,窗口为空时展示的占位组件', + }, }; const getStrictModeValue = (engineOptions: IPublicTypeEngineOptions, defaultValue: boolean): boolean => { diff --git a/packages/workspace/src/layouts/workbench.tsx b/packages/workspace/src/layouts/workbench.tsx index 0c69f9717c..08d6dc1a93 100644 --- a/packages/workspace/src/layouts/workbench.tsx +++ b/packages/workspace/src/layouts/workbench.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { TipContainer, observer } from '@alilc/lowcode-editor-core'; +import { TipContainer, engineConfig, observer } from '@alilc/lowcode-editor-core'; import { WindowView } from '../view/window-view'; import classNames from 'classnames'; import TopArea from './top-area'; @@ -21,17 +21,29 @@ export class Workbench extends Component<{ components?: PluginClassSet; className?: string; topAreaItemClassName?: string; +}, { + workspaceEmptyComponent: any; }> { constructor(props: any) { super(props); const { config, components, workspace } = this.props; const { skeleton } = workspace; skeleton.buildFromConfig(config, components); + engineConfig.onGot('workspaceEmptyComponent', (workspaceEmptyComponent) => { + this.setState({ + workspaceEmptyComponent, + }); + }); + this.state = { + workspaceEmptyComponent: engineConfig.get('workspaceEmptyComponent'), + }; } render() { const { workspace, className, topAreaItemClassName } = this.props; const { skeleton } = workspace; + const WorkspaceEmptyComponent = this.state.workspaceEmptyComponent; + return ( <div className={classNames('lc-workspace-workbench', className)}> <SkeletonContext.Provider value={skeleton}> @@ -53,6 +65,10 @@ export class Workbench extends Component<{ /> )) } + + { + !workspace.windows.length && WorkspaceEmptyComponent ? <WorkspaceEmptyComponent /> : null + } </div> </div> <MainArea area={skeleton.mainArea} /> diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index bedae86801..6c35d8b35c 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -199,7 +199,7 @@ export class Workspace implements IWorkspace { this.windows.splice(index, 1); if (this.window === window) { this.window = this.windows[index] || this.windows[index + 1] || this.windows[index - 1]; - if (this.window.sleep) { + if (this.window?.sleep) { this.window.init(); } this.emitChangeActiveWindow(); From 7a1b9802a4ff695094e7277ce8a1a1ee1c88c6ed Mon Sep 17 00:00:00 2001 From: eternalsky <wsj7552715@hotmail.com> Date: Thu, 13 Jul 2023 15:33:35 +0800 Subject: [PATCH 066/361] feat(codegen): add new option exclude for plugin containerLifeCycle --- .../plugins/component/react/containerLifeCycle.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts b/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts index 75dcada63d..5f7d6d22a7 100644 --- a/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts +++ b/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts @@ -16,13 +16,14 @@ import { isJSFunction, isJSExpression } from '@alilc/lowcode-types'; import { isJSExpressionFn } from '../../../utils/common'; export interface PluginConfig { - fileType: string; - exportNameMapping: Record<string, string>; - normalizeNameMapping: Record<string, string>; + fileType?: string; + exportNameMapping?: Record<string, string>; + normalizeNameMapping?: Record<string, string>; + exclude?: string[]; } const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => { - const cfg: PluginConfig = { + const cfg = { fileType: FileType.JSX, exportNameMapping: {}, normalizeNameMapping: {}, @@ -56,6 +57,10 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName; } + if (cfg?.exclude?.includes(normalizeName)) { + return null; + } + const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName; if (normalizeName === 'constructor') { return { @@ -97,7 +102,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => }), linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]], }; - }); + }).filter((i) => !!i); next.chunks.push(...chunks.filter((x): x is ICodeChunk => x !== null)); } From 87a40764273a63bb3775b78e248d8993a3c45845 Mon Sep 17 00:00:00 2001 From: eternalsky <wsj7552715@hotmail.com> Date: Thu, 13 Jul 2023 17:47:12 +0800 Subject: [PATCH 067/361] chore(release): code-generator - 1.1.5 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index ce01f5e4e1..193951fb03 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-code-generator", - "version": "1.1.4", + "version": "1.1.5", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From 841442574080d6399d549a1a974c71d5b4a572f0 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 14 Jul 2023 12:25:12 +0800 Subject: [PATCH 068/361] feat: add hotkey in workspace plugins --- packages/editor-core/src/hotkey.ts | 4 ++-- packages/workspace/src/workspace.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index adc74262a8..d0dd40cc24 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -317,8 +317,8 @@ function getKeyInfo(combination: string, action?: string): KeyInfo { function fireCallback(callback: IPublicTypeHotkeyCallback, e: KeyboardEvent, combo?: string, sequence?: string): void { try { const workspace = globalContext.get('workspace'); - const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor'); - const designer = editor.get('designer'); + const editor = workspace.isActive ? workspace.window?.editor : globalContext.get('editor'); + const designer = editor?.get('designer'); const node = designer?.currentSelection?.getNodes()?.[0]; const npm = node?.componentMeta?.npm; const selected = diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 6c35d8b35c..6410c6e207 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -103,6 +103,7 @@ export class Workspace implements IWorkspace { readonly shellModelFactory: any, ) { this.context = new BasicContext(this, '', IPublicEnumPluginRegisterLevel.Workspace); + this.context.innerHotkey.activate(true); makeObservable(this); } From 412cb16628222d529fc67ac1180598c6d51e3900 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 17 Jul 2023 14:18:15 +0800 Subject: [PATCH 069/361] fix: fix left-pane cant hidden when iframe click --- packages/editor-skeleton/src/layouts/left-float-pane.tsx | 6 ++++++ packages/workspace/src/layouts/left-float-pane.tsx | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx index 7df6993bb5..15f4926199 100644 --- a/packages/editor-skeleton/src/layouts/left-float-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -4,6 +4,7 @@ import { observer, Focusable } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; import { Panel } from '../widget/panel'; import { PanelConfig } from '../types'; +import { IPublicApiProject } from '@alilc/lowcode-types'; @observer export default class LeftFloatPane extends Component<{ area: Area<PanelConfig, Panel> }> { @@ -31,6 +32,8 @@ export default class LeftFloatPane extends Component<{ area: Area<PanelConfig, P area.skeleton.editor.removeListener('designer.drag', triggerClose); }; + const project: IPublicApiProject | undefined = area.skeleton.editor.get('project'); + this.focusing = area.skeleton.focusTracker.create({ range: (e) => { const target = e.target as HTMLElement; @@ -44,6 +47,9 @@ export default class LeftFloatPane extends Component<{ area: Area<PanelConfig, P if ((document.querySelector('.lc-simulator-content-frame') as HTMLIFrameElement)?.contentWindow?.document.documentElement.contains(target)) { return false; } + if (project?.simulatorHost?.contentWindow?.document.documentElement.contains(target)) { + return false; + } // 点击设置区 if (document.querySelector('.lc-right-area')?.contains(target)) { return false; diff --git a/packages/workspace/src/layouts/left-float-pane.tsx b/packages/workspace/src/layouts/left-float-pane.tsx index 38f70b386d..3df3e197c2 100644 --- a/packages/workspace/src/layouts/left-float-pane.tsx +++ b/packages/workspace/src/layouts/left-float-pane.tsx @@ -2,6 +2,7 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer, Focusable } from '@alilc/lowcode-editor-core'; import { Area, Panel } from '@alilc/lowcode-editor-skeleton'; +import { IPublicApiProject } from '@alilc/lowcode-types'; @observer export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> { @@ -29,6 +30,8 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> area.skeleton.editor.removeListener('designer.drag', triggerClose); }; + const project: IPublicApiProject | undefined = area.skeleton.editor.get('project'); + this.focusing = area.skeleton.focusTracker.create({ range: (e) => { const target = e.target as HTMLElement; @@ -42,6 +45,9 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> if ((document.querySelector('.lc-simulator-content-frame') as HTMLIFrameElement)?.contentWindow?.document.documentElement.contains(target)) { return false; } + if (project?.simulatorHost?.contentWindow?.document.documentElement.contains(target)) { + return false; + } // 点击设置区 if (document.querySelector('.lc-right-area')?.contains(target)) { return false; From fc947d2feb0411223430ab154398cfcd83c11dcb Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Tue, 18 Jul 2023 10:37:46 +0800 Subject: [PATCH 070/361] fix: remove function bind If the returned function is bound to a context, there is no way to call it with `call` and `apply`. --- packages/renderer-core/src/utils/common.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 262231eefb..3439bf2978 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -264,8 +264,7 @@ function parseExpression(a: any, b?: any, c = false) { if (!thisRequired) { code = `with($scope){${code}}`; } - const result = new Function('$scope', code)(self); - return typeof result === "function" ? result.bind(self): result; + return new Function('$scope', code)(self); } catch (err) { logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self); return undefined; From 16fde64deea5e3ccc53eb9410cdc8f31f59db9d8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 19 Jul 2023 11:16:17 +0800 Subject: [PATCH 071/361] style: update workbench styles --- packages/editor-skeleton/src/layouts/workbench.less | 2 +- packages/shell/src/api/setters.ts | 2 +- packages/shell/src/api/skeleton.ts | 2 +- packages/workspace/src/layouts/workbench.less | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index f97e1f46f2..fccdad4c2d 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -318,7 +318,7 @@ body { align-items: center; .lc-title { flex-direction: column; - width: 46px; + width: calc(var(--left-area-width) - 2px); height: 46px; display: flex; align-items: center; diff --git a/packages/shell/src/api/setters.ts b/packages/shell/src/api/setters.ts index 7750a5152e..b7f2d40ecf 100644 --- a/packages/shell/src/api/setters.ts +++ b/packages/shell/src/api/setters.ts @@ -19,7 +19,7 @@ export class Setters implements IPublicApiSetters { const workspace = globalContext.get('workspace'); if (workspace.isActive) { return untracked(() => { - if (!workspace.window.innerSetters) { + if (!workspace.window?.innerSetters) { logger.error('setter api 调用时机出现问题,请检查'); return this[innerSettersSymbol]; } diff --git a/packages/shell/src/api/skeleton.ts b/packages/shell/src/api/skeleton.ts index b48747598e..238931a25e 100644 --- a/packages/shell/src/api/skeleton.ts +++ b/packages/shell/src/api/skeleton.ts @@ -22,7 +22,7 @@ export class Skeleton implements IPublicApiSkeleton { } const workspace = globalContext.get('workspace'); if (workspace.isActive) { - if (!workspace.window.innerSkeleton) { + if (!workspace.window?.innerSkeleton) { logger.error('skeleton api 调用时机出现问题,请检查'); return this[innerSkeletonSymbol]; } diff --git a/packages/workspace/src/layouts/workbench.less b/packages/workspace/src/layouts/workbench.less index c8c89d6f0f..05eb5f513b 100644 --- a/packages/workspace/src/layouts/workbench.less +++ b/packages/workspace/src/layouts/workbench.less @@ -276,7 +276,7 @@ body { align-items: center; .lc-title { flex-direction: column; - width: 46px; + width: calc(var(--left-area-width) - 2px); height: 46px; display: flex; align-items: center; From 02a3361f4104b8cfa00149199bea89504581b584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= <yuanlihao1988@gmail.com> Date: Wed, 19 Jul 2023 14:34:15 +0800 Subject: [PATCH 072/361] fix: lock some ice libs && next resource 404 --- .../plugins/project/framework/icejs3/plugins/packageJSON.ts | 4 ++-- .../project/framework/icejs3/template/files/document.ts | 2 +- .../icejs3-app/demo1/expected/demo-project/package.json | 4 ++-- .../icejs3-app/demo1/expected/demo-project/src/document.tsx | 2 +- .../demo2-utils-name-alias/expected/demo-project/package.json | 4 ++-- .../expected/demo-project/src/document.tsx | 2 +- .../icejs3-app/demo2/expected/demo-project/package.json | 4 ++-- .../icejs3-app/demo2/expected/demo-project/src/document.tsx | 2 +- .../icejs3-app/demo3/expected/demo-project/package.json | 4 ++-- .../icejs3-app/demo3/expected/demo-project/src/document.tsx | 2 +- .../icejs3-app/demo4/expected/demo-project/package.json | 4 ++-- .../icejs3-app/demo4/expected/demo-project/src/document.tsx | 2 +- .../icejs3-app/demo5/expected/demo-project/package.json | 4 ++-- .../icejs3-app/demo5/expected/demo-project/src/document.tsx | 2 +- .../expected/demo-project/package.json | 4 ++-- .../expected/demo-project/src/document.tsx | 2 +- .../expected/demo-project/package.json | 4 ++-- .../expected/demo-project/src/document.tsx | 2 +- .../demo8-datasource-prop/expected/demo-project/package.json | 4 ++-- .../expected/demo-project/src/document.tsx | 2 +- .../expected/demo-project/package.json | 4 ++-- .../expected/demo-project/src/document.tsx | 2 +- .../demo_10-jsslot/expected/demo-project/package.json | 4 ++-- .../demo_10-jsslot/expected/demo-project/src/document.tsx | 2 +- .../demo_11-jsslot-2/expected/demo-project/package.json | 4 ++-- .../demo_11-jsslot-2/expected/demo-project/src/document.tsx | 2 +- 26 files changed, 39 insertions(+), 39 deletions(-) diff --git a/modules/code-generator/src/plugins/project/framework/icejs3/plugins/packageJSON.ts b/modules/code-generator/src/plugins/project/framework/icejs3/plugins/packageJSON.ts index 11248a0b5d..3c39ba7399 100644 --- a/modules/code-generator/src/plugins/project/framework/icejs3/plugins/packageJSON.ts +++ b/modules/code-generator/src/plugins/project/framework/icejs3/plugins/packageJSON.ts @@ -67,12 +67,12 @@ const pluginFactory: BuilderComponentPluginFactory<IceJs3PackageJsonPluginConfig 'react-router-dom': '^6.9.0', 'intl-messageformat': '^9.3.6', '@alifd/next': '1.26.15', - '@ice/runtime': '^1.0.0', + '@ice/runtime': '~1.1.0', // 数据源相关的依赖: ...buildDataSourceDependencies(ir, cfg?.datasourceConfig), }, devDependencies: { - '@ice/app': '^3.0.0', + '@ice/app': '~3.1.0', '@types/react': '^18.0.0', '@types/react-dom': '^18.0.0', '@types/node': '^18.11.17', diff --git a/modules/code-generator/src/plugins/project/framework/icejs3/template/files/document.ts b/modules/code-generator/src/plugins/project/framework/icejs3/template/files/document.ts index 17978b20dc..3345625557 100644 --- a/modules/code-generator/src/plugins/project/framework/icejs3/template/files/document.ts +++ b/modules/code-generator/src/plugins/project/framework/icejs3/template/files/document.ts @@ -27,7 +27,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/package.json index 54a1e4e121..38f24df0b1 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/package.json @@ -10,13 +10,13 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.19.18", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-url-params-handler": "^1.0.0", "@alilc/lowcode-datasource-fetch-handler": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo1/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/package.json index e234f0da02..3a0015c9bd 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/package.json @@ -10,7 +10,7 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-url-params-handler": "^1.0.0", "@alilc/b6-page": "^0.1.0", @@ -20,7 +20,7 @@ "@alilc/b6-util-mocks": "1.x" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2-utils-name-alias/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/package.json index 63717e3193..8f02ff1c7e 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/package.json @@ -10,11 +10,11 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.19.18", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo2/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/package.json index 63717e3193..8f02ff1c7e 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/package.json @@ -10,11 +10,11 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.19.18", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo3/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/package.json index 43f4440856..393be4663e 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/package.json @@ -10,14 +10,14 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-fetch-handler": "^1.0.0", "@alife/container": "^1.0.0", "@alife/mc-assets-1935": "0.1.9" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo4/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/package.json index a62526e762..d007025a60 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/package.json @@ -10,7 +10,7 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "undefined": "*", "@alife/container": "0.3.7", @@ -18,7 +18,7 @@ "@alife/mc-assets-1935": "0.1.16" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo5/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/package.json index 54a1e4e121..38f24df0b1 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/package.json @@ -10,13 +10,13 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.19.18", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-url-params-handler": "^1.0.0", "@alilc/lowcode-datasource-fetch-handler": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo6-literal-condition/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/package.json index 399ff4333b..fcdfc7bd4b 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/package.json @@ -10,14 +10,14 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "undefined": "*", "@alilc/antd-lowcode": "0.8.0", "@alife/container": "0.3.7" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo7-literal-condition2/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/package.json index 45c8e304a9..342a5a0774 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/package.json @@ -10,13 +10,13 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-http-handler": "^1.0.0", "@alilc/lowcode-components": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo8-datasource-prop/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/package.json index 87ad385141..d7d07dc6ed 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/package.json @@ -10,12 +10,12 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.19.18", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "@alilc/lowcode-datasource-jsonp-handler": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo9-datasource-engine/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/package.json index cad3038d99..fb35f3cf46 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/package.json @@ -10,7 +10,7 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "undefined": "*", "@alilc/antd-lowcode-materials": "0.9.4", @@ -18,7 +18,7 @@ "@alife/container": "0.3.7" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_10-jsslot/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/package.json index 32b4ea8772..89f693efcb 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/package.json @@ -10,7 +10,7 @@ "react-router-dom": "^6.9.0", "intl-messageformat": "^9.3.6", "@alifd/next": "1.26.15", - "@ice/runtime": "^1.0.0", + "@ice/runtime": "~1.1.0", "@alilc/lowcode-datasource-engine": "^1.0.0", "undefined": "*", "@alilc/antd-lowcode-materials": "0.11.0", @@ -18,7 +18,7 @@ "@alife/container": "0.3.7" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "~3.1.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@types/node": "^18.11.17", diff --git a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/src/document.tsx b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/src/document.tsx index 286be9f8ca..aff0231d95 100644 --- a/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/src/document.tsx +++ b/modules/code-generator/tests/fixtures/test-cases/icejs3-app/demo_11-jsslot-2/expected/demo-project/src/document.tsx @@ -19,7 +19,7 @@ export default function Document() { <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react/18.2.0/umd/react.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/react-dom/18.2.0/umd/react-dom.development.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/??react-router/6.9.0/react-router.production.min.js,react-router-dom/6.9.0/react-router-dom.production.min.js" /> - <script crossOrigin="anonymous" src="//alifd.alicdn.com/npm/@alifd/next/1.26.15/next.min.js" /> + <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/alifd__next/1.26.22/next.min.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/code/lib/prop-types/15.7.2/prop-types.js" /> <script crossOrigin="anonymous" src="//g.alicdn.com/platform/c/??lodash/4.6.1/lodash.min.js,immutable/3.7.6/dist/immutable.min.js" /> <Scripts /> From e875e33dc543f64010ad033a97856b08275edba2 Mon Sep 17 00:00:00 2001 From: liangzr <1668890395@qq.com> Date: Thu, 20 Jul 2023 10:36:10 +0800 Subject: [PATCH 073/361] feat: generateTemplate fun support context --- modules/code-generator/src/generator/ProjectBuilder.ts | 5 +++-- modules/code-generator/src/types/core.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index c1db28fe9d..a910b49002 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -111,8 +111,6 @@ export class ProjectBuilder implements IProjectBuilder { // Init const { schemaParser } = this; - const projectRoot = await this.template.generateTemplate(); - let schema: IPublicTypeProjectSchema = typeof originalSchema === 'string' ? JSON.parse(originalSchema) : originalSchema; @@ -131,6 +129,9 @@ export class ProjectBuilder implements IProjectBuilder { // Collect Deps // Parse JSExpression const parseResult: IParseResult = schemaParser.parse(schema); + + const projectRoot = await this.template.generateTemplate(parseResult); + let buildResult: IModuleInfo[] = []; const builders = this.createModuleBuilders({ diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index fb2a780c10..1219a1e767 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -127,7 +127,7 @@ export interface ISchemaParser { export interface IProjectTemplate { slots: Record<string, IProjectSlot>; - generateTemplate: () => ResultDir | Promise<ResultDir>; + generateTemplate: (data: IParseResult) => ResultDir | Promise<ResultDir>; } export interface IProjectSlot { From d267fecc67f3c3eec08c224aeb62c1957ff39187 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 25 Jul 2023 10:28:05 +0800 Subject: [PATCH 074/361] feat: add state for workspace windows --- packages/workspace/src/window.ts | 33 +++++++++++++++++++++++++++++ packages/workspace/src/workspace.ts | 9 +++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index 6fb706632a..b6e345f19e 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -26,6 +26,22 @@ export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'chan sleep?: boolean; init(): void; + + updateState(state: WINDOW_STATE): void; +} + +export enum WINDOW_STATE { + // 睡眠 + sleep = 'sleep', + + // 激活 + active = 'active', + + // 未激活 + inactive = 'inactive', + + // 销毁 + destroyed = 'destroyed' } export class EditorWindow implements IEditorWindow { @@ -51,6 +67,22 @@ export class EditorWindow implements IEditorWindow { this.title = config.title; this.icon = resource.icon; this.sleep = config.sleep; + if (config.sleep) { + this.updateState(WINDOW_STATE.sleep); + } + } + + updateState(state: WINDOW_STATE): void { + switch (state) { + case WINDOW_STATE.active: + this.editorView?.setActivate(true); + break; + case WINDOW_STATE.inactive: + this.editorView?.setActivate(false); + break; + case WINDOW_STATE.destroyed: + break; + } } async importSchema(schema: any) { @@ -102,6 +134,7 @@ export class EditorWindow implements IEditorWindow { this.initReady = true; this.workspace.checkWindowQueue(); this.sleep = false; + this.updateState(WINDOW_STATE.active); } initViewTypes = async () => { diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 6410c6e207..e180d4a2fb 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -2,7 +2,7 @@ import { IDesigner, ILowCodePluginManager, LowCodePluginManager } from '@alilc/l import { createModuleEventBus, Editor, IEditor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core'; import { IPublicApiPlugins, IPublicApiWorkspace, IPublicEnumPluginRegisterLevel, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types'; import { BasicContext } from './context/base-context'; -import { EditorWindow } from './window'; +import { EditorWindow, WINDOW_STATE } from './window'; import type { IEditorWindow } from './window'; import { IResource, Resource } from './resource'; import { IResourceType, ResourceType } from './resource-type'; @@ -198,6 +198,7 @@ export class Workspace implements IWorkspace { } const window = this.windows[index]; this.windows.splice(index, 1); + this.window?.updateState(WINDOW_STATE.destroyed); if (this.window === window) { this.window = this.windows[index] || this.windows[index + 1] || this.windows[index - 1]; if (this.window?.sleep) { @@ -206,6 +207,7 @@ export class Workspace implements IWorkspace { this.emitChangeActiveWindow(); } this.emitChangeWindow(); + this.window?.updateState(WINDOW_STATE.active); } removeEditorWindow(resourceName: string, title: string) { @@ -215,6 +217,7 @@ export class Workspace implements IWorkspace { async openEditorWindowById(id: string) { const window = this.editorWindowMap.get(id); + this.window?.updateState(WINDOW_STATE.inactive); if (window) { this.window = window; if (window.sleep) { @@ -222,6 +225,7 @@ export class Workspace implements IWorkspace { } this.emitChangeActiveWindow(); } + this.window?.updateState(WINDOW_STATE.active); } async openEditorWindow(name: string, title: string, options: Object, viewType?: string, sleep?: boolean) { @@ -236,6 +240,7 @@ export class Workspace implements IWorkspace { console.error(`${name} resourceType is not available`); return; } + this.window?.updateState(WINDOW_STATE.inactive); const filterWindows = this.windows.filter(d => (d.resource?.name === name && d.resource.title == title)); if (filterWindows && filterWindows.length) { this.window = filterWindows[0]; @@ -245,6 +250,7 @@ export class Workspace implements IWorkspace { this.checkWindowQueue(); } this.emitChangeActiveWindow(); + this.window?.updateState(WINDOW_STATE.active); return; } const resource = new Resource({ @@ -266,6 +272,7 @@ export class Workspace implements IWorkspace { } this.emitChangeWindow(); this.emitChangeActiveWindow(); + this.window?.updateState(WINDOW_STATE.active); } onChangeWindows(fn: () => void) { From e578f82272affec3871b580ad68787c55da0dab0 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 25 Jul 2023 15:27:07 +0800 Subject: [PATCH 075/361] feat: skeleton item add visible prop --- packages/shell/src/model/skeleton-item.ts | 4 ++++ packages/types/src/shell/model/skeleton-item.ts | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/shell/src/model/skeleton-item.ts b/packages/shell/src/model/skeleton-item.ts index b91e5a19a0..cda8486ad0 100644 --- a/packages/shell/src/model/skeleton-item.ts +++ b/packages/shell/src/model/skeleton-item.ts @@ -13,6 +13,10 @@ export class SkeletonItem implements IPublicModelSkeletonItem { return this[skeletonItemSymbol].name; } + get visible() { + return this[skeletonItemSymbol].visible; + } + disable() { this[skeletonItemSymbol].disable?.(); } diff --git a/packages/types/src/shell/model/skeleton-item.ts b/packages/types/src/shell/model/skeleton-item.ts index ca262ccbf0..c505a677c6 100644 --- a/packages/types/src/shell/model/skeleton-item.ts +++ b/packages/types/src/shell/model/skeleton-item.ts @@ -2,5 +2,15 @@ * @since 1.1.7 */ export interface IPublicModelSkeletonItem { + name: string; + visible: boolean; + + disable(): void; + + enable(): void; + + hide(): void; + + show(): void; } \ No newline at end of file From 288dbd63948884666a4582efab14d260be315cca Mon Sep 17 00:00:00 2001 From: eternalsky <wsj7552715@hotmail.com> Date: Tue, 25 Jul 2023 20:00:04 +0800 Subject: [PATCH 076/361] chore(release): code-generator - 1.1.6 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 193951fb03..6ff1ecb63f 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-code-generator", - "version": "1.1.5", + "version": "1.1.6", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From d67eab0041aa0344cf3e1f9b5cbaa74dc3d4f3b9 Mon Sep 17 00:00:00 2001 From: keuby <knightchen@knx.com.cn> Date: Wed, 26 Jul 2023 14:04:19 +0800 Subject: [PATCH 077/361] feat(designer): add setRendererReady declaration (#2320) --- packages/designer/src/project/project.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 75e621d5e2..94913d9fa7 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -2,14 +2,13 @@ import { obx, computed, makeObservable, action, IEventBus, createModuleEventBus import { IDesigner } from '../designer'; import { DocumentModel, isDocumentModel } from '../document'; import type { IDocumentModel } from '../document'; -import { - IPublicTypeComponentsMap, - IPublicEnumTransformStage, - IBaseApiProject, -} from '@alilc/lowcode-types'; +import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; import type { + IBaseApiProject, IPublicTypeProjectSchema, IPublicTypeRootSchema, + IPublicTypeComponentsMap, + IPublicTypeSimulatorRenderer, } from '@alilc/lowcode-types'; import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils'; import { ISimulatorHost } from '../simulator'; @@ -87,6 +86,8 @@ export interface IProject extends Omit<IBaseApiProject< get(key: string): unknown; checkExclusive(activeDoc: DocumentModel): void; + + setRendererReady(renderer: IPublicTypeSimulatorRenderer<any, any>): void; } export class Project implements IProject { From 561598c7a219dfd460f322ba80c6e37f8edb713c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= <yuanlihao1988@gmail.com> Date: Wed, 26 Jul 2023 17:07:01 +0800 Subject: [PATCH 078/361] chore: fix window typo --- docs/docs/guide/quickStart/start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/quickStart/start.md b/docs/docs/guide/quickStart/start.md index 7999d1701a..b2b728b9fe 100644 --- a/docs/docs/guide/quickStart/start.md +++ b/docs/docs/guide/quickStart/start.md @@ -11,7 +11,7 @@ title: 快速开始 ## 环境准备 -### WSL(Window 电脑) +### WSL(Windows 电脑) Window 环境需要使用 WSL 在 windows 下进行低代码引擎相关的开发。安装教程 ➡️ [WSL 安装教程](https://docs.microsoft.com/zh-cn/windows/wsl/install)。<br />**对于 Window 环境来说,之后所有需要执行命令的操作都是在 WSL 终端执行的。** From d08aa67b0a62475b1bd9979e02e2ce02233a6d57 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 27 Jul 2023 09:49:02 +0800 Subject: [PATCH 079/361] chore(release): publish 1.1.9 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 52ee714c28..9d3eb758a1 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.1.8", + "version": "1.1.9", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index e3d1535aa5..0b2178c3b8 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.1.8", + "version": "1.1.9", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -16,9 +16,9 @@ "license": "MIT", "dependencies": { "@alilc/build-plugin-lce": "^0.0.4-beta.2", - "@alilc/lowcode-editor-core": "1.1.8", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-editor-core": "1.1.9", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 939a73183b..58e8eb4814 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.1.8", + "version": "1.1.9", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 16cc1cc098..b1802795dd 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.1.8", + "version": "1.1.9", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-editor-core": "1.1.8", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-editor-core": "1.1.9", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 030f14a764..4d5e4681f6 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.1.8", + "version": "1.1.9", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-editor-core": "1.1.8", - "@alilc/lowcode-editor-skeleton": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-editor-core": "1.1.9", + "@alilc/lowcode-editor-skeleton": "1.1.9", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.1.8", - "@alilc/lowcode-plugin-outline-pane": "1.1.8", - "@alilc/lowcode-shell": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", - "@alilc/lowcode-workspace": "1.1.8", + "@alilc/lowcode-plugin-designer": "1.1.9", + "@alilc/lowcode-plugin-outline-pane": "1.1.9", + "@alilc/lowcode-shell": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-workspace": "1.1.9", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index d7796db32f..4064e585bf 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.1.8", + "version": "1.1.9", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 7d5a434811..16905f6159 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.1.8", + "version": "1.1.9", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-editor-core": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-editor-core": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index f6a4aea0a5..c49e11c2ef 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.1.8", + "version": "1.1.9", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index b91511afd7..ddd160f004 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.1.8", + "version": "1.1.9", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-renderer-core": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 8a456b6cf4..d2c39c0c81 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.1.8", + "version": "1.1.9", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-rax-renderer": "1.1.8", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-rax-renderer": "1.1.9", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 4af63fa78b..410d24a6bf 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.1.8", + "version": "1.1.9", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.1.8" + "@alilc/lowcode-renderer-core": "1.1.9" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 43bfd47a87..8fb1e979b3 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.1.8", + "version": "1.1.9", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-react-renderer": "1.1.8", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-react-renderer": "1.1.9", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index f0b4b3e9cb..49c9d30fe5 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.1.8", + "version": "1.1.9", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index c24113d0fe..c9663e4a77 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.1.8", + "version": "1.1.9", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-editor-core": "1.1.8", - "@alilc/lowcode-editor-skeleton": "1.1.8", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", - "@alilc/lowcode-workspace": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-editor-core": "1.1.9", + "@alilc/lowcode-editor-skeleton": "1.1.9", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-workspace": "1.1.9", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 2aef9019c3..317fbbeb73 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.1.8", + "version": "1.1.9", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 1e4e9fb9f9..dcc1ccdd21 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.1.8", + "version": "1.1.9", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.8", + "@alilc/lowcode-types": "1.1.9", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index b04a05cf94..36e8dac0f1 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.1.8", + "version": "1.1.9", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.8", - "@alilc/lowcode-editor-core": "1.1.8", - "@alilc/lowcode-editor-skeleton": "1.1.8", - "@alilc/lowcode-types": "1.1.8", - "@alilc/lowcode-utils": "1.1.8", + "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-editor-core": "1.1.9", + "@alilc/lowcode-editor-skeleton": "1.1.9", + "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-utils": "1.1.9", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 1e3fd1951b17f3344fcd17754dedf87050f98e8f Mon Sep 17 00:00:00 2001 From: 1ncounter <1ncounter.100@gmail.com> Date: Thu, 27 Jul 2023 14:08:20 +0800 Subject: [PATCH 080/361] feat: add application level specs (#2325) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add application level specs:router,pages,etc * fix: add description to change parts --------- Co-authored-by: 林熠 <jack.lianjie@gmail.com> --- docs/docs/specs/lowcode-spec.md | 289 +++++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 8 deletions(-) diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index 297381fe69..59ff85586c 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -25,7 +25,7 @@ sidebar_position: 0 ### 1.3 版本号 -1.0.0 +1.1.0 ### 1.4 协议版本号规范(A) @@ -124,7 +124,8 @@ sidebar_position: 0 - config: { Object } 当前应用配置信息 - meta: { Object } 当前应用元数据信息 - dataSource: { Array } 当前应用的公共数据源 - +- router: { Object } 当前应用的路由配置信息 +- pages: { Array } 当前应用的所有页面信息 描述举例: @@ -163,6 +164,7 @@ sidebar_position: 0 } }], "componentsTree": [{ // 描述内容,值类型 Array + "id": "page1", "componentName": "Page", // 单个页面,枚举类型 Page|Block|Component "fileName": "Page1", "props": {}, @@ -213,7 +215,7 @@ sidebar_position: 0 "css": "body {font-size: 12px;} .table { width: 100px;}", "config": { // 当前应用配置信息 "sdkVersion": "1.0.3", // 渲染模块版本 - "historyMode": "hash", // 浏览器路由:browser 哈希路由:hash + "historyMode": "hash", // 不推荐,推荐在 router 字段中配置 "targetRootID": "J_Container", "layout": { "componentName": "BasicLayout", @@ -250,7 +252,23 @@ sidebar_position: 0 "i18n-jwg27yo4": "Hello", "i18n-jwg27yo3": "China" } - } + }, + "router": { + "baseUrl": "/", + "historyMode": "hash", // 浏览器路由:browser 哈希路由:hash + "routes": [ + { + "path": "home", + "page": "page1" + } + ] + }, + "pages": [ + { + "id": "page1", + "treeId": "page1" + } + ] } ``` @@ -1252,7 +1270,7 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { ### 2.8 当前应用配置信息(AA) -用于描述当前应用的配置信息,比如当前应用的路由模式、Shell/Layout、主题等。 +用于描述当前应用的配置信息,比如当前应用的 Shell/Layout、主题等。 > 注意:该字段为扩展字段,消费方式由各自场景自己决定,包括运行时和出码。 @@ -1267,6 +1285,192 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { 用于描述当前应用的公共数据源,数据结构跟容器结构里的 ComponentDataSource 保持一致。 在运行时 / 出码使用时,API 和应用级数据源 API 保持一致,都是 `this.dataSourceMap['globalDSName'].load()` +### 2.11 当前应用的路由信息(AA) + +用于描述当前应用的路径 - 页面的关系。通过声明路由信息,应用能够在不同的路径里显示对应的页面。 + +##### 2.11.1 Router (应用路由配置)结构描述 + +路由配置的结构说明: + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | 备注 | +| ----------- | ---------------------- | ------------------------------- | ------ | --------- | ------ | +| baseName | 应用根路径 | String | - | '/' | 选填| | +| historyMode | history 模式 | 枚举类型,包括'browser'、'hash' | - | 'browser' | 选填| | +| routes | 路由对象组,路径与页面的关系对照组 | Route[] | - | - | 必填| | + + +##### 2.11.2 Route (路由记录)结构描述 + +路由记录,路径与页面的关系对照。Route 的结构说明: + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | 备注 | +| -------- | ---------------------------- | ---------------------------- | ------ | ------ | ---------------------------------------------------------------------- | +| name | 该路径项的名称 | String | - | - | 选填 | +| path | 路径 | String | - | - | 必填,路径规则详见下面说明 | +| query | 路径的 query 参数 | Object | - | - | 选填 | +| page | 路径对应的页面 ID | String | - | - | 选填,page 与 redirect 字段中必须要有有一个存在 | +| redirect | 此路径需要重定向到的路由信息 | String \| Object \| Function | - | - | 选填,page 与 redirect 字段中必须要有有一个存在,详见下文 **redirect** | +| meta | 路由元数据 | Object | - | - | 选填 | +| children | 子路由 | Route[] | - | - | 选填 | + +以上结构仅说明了路由记录需要的必需字段,如果需要更多的信息字段可以自行实现。 + +关于 **path** 字段的详细说明: + +路由记录通常通过声明 path 字段来匹配对应的浏览器 URL 来确认是否满足匹配条件,如 `path=abc` 能匹配到 `/abc` 这个 URL。 + +> 在声明 path 字段的时候,可省略 `/`,只声明后面的字符,如 `/abc` 可声明为 `abc`。 + +path(页面路径)是浏览器URL的组成部分,同时大部分网站的 URL 也都受到了 Restful 思想的影响,所以我们也是用类似的形式作为路径的规则基底。 +路径规则是路由配置的重要组成部分,我们希望一个路径配置的基本能力需要支持具体的路径(/xxx)与路径参数 (/:abc)。 + +以一个 `/one/:two?/three/:four?/:five?` 路径为例,它能够解析以下路径: +- `/one/three` +- `/one/:two/three` +- `/one/three/:four` +- `/one/three/:five` +- `/one/:two/three/:four` +- `/one/:two/three/:five` +- `/one/three/:four/:five` +- `/one/:two/three/:four/:five` + +更多的路径规则,如路径中的通配符、多次匹配等能力如有需要可自行实现。 + +关于 **redirect** 字段的详细说明: + +**redirect** 字段有三种填入类型,分别是 `String`、`Object`、`Function`: +1. 字符串(`String`)格式下默认处理为重定向到路径,支持传入 '/xxx'、'/xxx?ab=c'。 +2. 对象(`String`)格式下可传入路由对象,如 { name: 'xxx' }、{ path: '/xxx' },可重定向到对应的路由对象。 +3. 函数`Function`格式为`(to) => Route`,它的入参为当前路由项信息,支持返回一个 Route 对象或者字符串,存在一些特殊情况,在重定向的时候需要对重定向之后的路径进行处理的情况下,需要使用函数声明。 + +```json +{ + "redirect": { + "type": "JSFunction", + "value": "(to) => { return { path: '/a', query: { fromPath: to.path } } }", + } +} +``` + +##### 完整描述示例 + +``` json +{ + "router": { + "baseName": "/", + "historyMode": "hash", + "routes": [ + { + "path": "home", + "page": "home" + }, + { + "path": "/*", + "redirect": "notFound" + } + ] + }, + "componentsTree": [ + { + "id": "home", + ... + }, + { + "id": "notFound", + ... + } + ] +} +``` + +### 2.12 当前应用的页面信息(AA) + +用于描述当前应用的页面信息,比如页面对应的低代码搭建内容、页面标题、页面配置等。 +在一些比较复杂的场景下,允许声明一层页面映射关系,以支持页面声明更多信息与配置,同时能够支持不同类型的产物。 + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | 备注 | +| ------- | --------------------- | ------ | ------ | ------ | -------------------------------------------------------- | +| id | 页面 id | String | - | - | 必填 | +| type | 页面类型 | String | - | - | 选填,可用来区分页面的类型 | +| treeId | 对应的低代码树中的 id | String | - | - | 选填,页面对应的 componentsTree 中的子项 id | +| packageId | 对应的资产包对象 | String | - | - | 选填,页面对应的资产包对象,一般用于微应用场景下,当路由匹配到当前页面的时候,会加载 `packageId` 对应的微应用进行渲染。 | +| meta | 页面元信息 | Object | - | - | 选填,用于描述当前应用的配置信息 | +| config | 页面配置 | Object | - | - | 选填,用于描述当前应用的元数据信息 | + + +#### 2.12.1 微应用(低代码+)相关说明 + +在开发过程中,我们经常会遇到一些特殊的情况,比如一个低代码应用想要集成一些别的系统的页面或者系统中的一些页面只能是源码开发(与低代码相对的纯工程代码形式),为了满足更多的使用场景,应用级渲染引擎引入了微应用(微前端)的概念,使低代码页面与其他的页面结合成为可能。 + +微应用对象通过资产包加载,需要暴露两个生命周期方法: +- mount(container: HTMLElement, props: any) + - 说明:微应用挂载到 container(dom 节点)的调用方法,会在渲染微应用时调用 +- unmout(container: HTMLElement, props: any) + - 说明:微应用从容器节点(container)卸载的调用方法,会在卸载微应用时调用 + +> 在微应用的场景下,可能会存在多个页面路由到同一个应用,应用可通过资产包加载,所以需要将对应的页面配置指向对应的微应用(资产包)对象。 + +**描述示例** + +```json +{ + "router": { + "baseName": "/", + "historyMode": "hash", + "routes": [ + { + "path": "home", + "page": "home" + }, + { + "page": "guide", + "page": "guide" + }, + { + "path": "/*", + "redirect": "notFound" + } + ] + }, + "pages": [ + { + "id": "home", + "treeId": "home", + "meta": { + "title": "首页" + } + }, + { + "id": "notFound", + "treeId": "notFound", + "meta": { + "title": "404页面" + } + }, + { + "id": "guide", + "packagId": "microApp" + } + ] +} + +// 资产包 +[ + { + "id": "microApp", + "package": "microApp", + "version": "1.23.0", + "urls": [ + "https://g.alicdn.com/code/lib/microApp.min.css", + "https://g.alicdn.com/code/lib/microApp.min.js" + ], + "library": "microApp" + }, +] +``` + + ## 3 应用描述 ### 3.1 文件目录 @@ -1320,9 +1524,78 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { ### 3.2 应用级别 APIs > 下文中 `xxx` 代指任意 API #### 3.2.1 路由 Router API - - this.location.`xxx` - - this.history.`xxx` - - this.match.`xxx` + - this.location.`xxx` 「不推荐,推荐统一通过 this.router api」 + - this.history.`xxx` 「不推荐,推荐统一通过 this.router api」 + - this.match.`xxx` 「不推荐,推荐统一通过 this.router api」 + - this.router.`xxx` + +##### Router 结构说明 + +| API | 函数签名 | 说明 | +| -------------- | ---------------------------------------------------------- | -------------------------------------------------------------- | +| getCurrentRoute | () => RouteLocation | 获取当前解析后的路由信息,RouteLocation 结构详见下面说明 | +| push | (target: string \| Route) => void | 路由跳转方法,跳转到指定的路径或者 Route | +| replace | (target: string \| Route) => void | 路由跳转方法,与 `push` 的区别在于不会增加一条历史记录而是替换当前的历史记录 | +| beforeRouteLeave | (guard: (to: RouteLocation, from: RouteLocation) => boolean \| Route) => void | 路由跳转前的守卫方法,详见下面说明 | +| afterRouteChange | (fn: (to: RouteLocation, from: RouteLocation) => void) => void | 路由跳转后的钩子函数,会在每次路由改变后执行 | + +##### 3.2.1.1 RouteLocation(路由信息)结构说明 + +**RouteLocation** 是路由控制器匹配到对应的路由记录后进行解析产生的对象,它的结构如下: + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | 备注 | +| -------------- | ---------------------- | ------ | ------ | ------ | ------ | +| path | 当前解析后的路径 | String | - | - | 必填 | +| hash | 当前路径的 hash 值,以 # 开头 | String | - | - | 必填 | +| href | 当前的全部路径 | String | - | - | 必填 | +| params | 匹配到的路径参数 | Object | - | - | 必填 | +| query | 当前的路径 query 对象 | Object | - | - | 必填,代表当前地址的 search 属性的对象 | +| name | 匹配到的路由记录名 | String | - | - | 选填 | +| meta | 匹配到的路由记录元数据 | Object | - | - | 选填 | +| redirectedFrom | 原本指向向的路由记录 | Route | - | - | 选填,在重定向到当前地址之前,原先想访问的地址 | +| fullPath | 包括 search 和 hash 在内的完整地址 | String | - | - | 选填 | + + +##### beforeRouteLeave +通过 beforeRouteLeave 注册的路由守卫方法会在每次路由跳转前执行。该方法一般会在应用鉴权,路由重定向等场景下使用。 + +> `beforeRouteLeave` 只在 `router.push/replace` 的方法调用时生效。 + +传入守卫的入参为: +* to: 即将要进入的目标路由(RouteLocation) +* from: 当前导航正要离开的路由(RouteLocation) + +该守卫返回一个 `boolean` 或者路由对象来告知路由控制器接下来的行为。 +* 如果返回 `false`, 则停止跳转 +* 如果返回 `true`,则继续跳转 +* 如果返回路由对象,则重定向至对应的路由 + +**使用范例:** + +```json +{ + "componentsTree": [{ + "componentName": "Page", + "fileName": "Page1", + "props": {}, + "children": [{ + "componentName": "Div", + "props": {}, + "children": [{ + "componentName": "Button", + "props": { + "text": "跳转到首页", + "onClick": { + "type": "JSFunction", + "value": "function () { this.router.push('/home'); }" + } + }, + }] + }], + }] +} +``` + #### 3.2.2 应用级别的公共函数或第三方扩展 - this.utils.`xxx` From 2bbb4099e315d9b075afc45a51b5d9b5a106fdcb Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 27 Jul 2023 14:16:33 +0800 Subject: [PATCH 081/361] chore(docs): publish docs 1.1.0, which upgrade lowcode-spec --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 269bd2df64..a2299251e4 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.33", + "version": "1.1.0", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 14390f000d93f7fc2e1f09e54d3d972a39593ca5 Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Tue, 1 Aug 2023 09:54:14 +0800 Subject: [PATCH 082/361] fix: Optimize the initialization method for masterPaneController (#2333) --- packages/plugin-outline-pane/src/index.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/plugin-outline-pane/src/index.tsx b/packages/plugin-outline-pane/src/index.tsx index 180b424ea5..addebbb402 100644 --- a/packages/plugin-outline-pane/src/index.tsx +++ b/packages/plugin-outline-pane/src/index.tsx @@ -18,7 +18,9 @@ export function OutlinePaneContext(props: { hideFilter?: boolean; }) { const treeMaster = props.treeMaster || new TreeMaster(props.pluginContext, props.options); - const [masterPaneController, setMasterPaneController] = useState(new PaneController(props.paneName || MasterPaneName, treeMaster)); + const [masterPaneController, setMasterPaneController] = useState( + () => new PaneController(props.paneName || MasterPaneName, treeMaster), + ); useEffect(() => { return treeMaster.onPluginContextChange(() => { setMasterPaneController(new PaneController(props.paneName || MasterPaneName, treeMaster)); @@ -40,7 +42,9 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => { const { skeleton, config, canvas, project } = ctx; let isInFloatArea = true; - const hasPreferenceForOutline = config.getPreference().contains('outline-pane-pinned-status-isFloat', 'skeleton'); + const hasPreferenceForOutline = config + .getPreference() + .contains('outline-pane-pinned-status-isFloat', 'skeleton'); if (hasPreferenceForOutline) { isInFloatArea = config.getPreference().get('outline-pane-pinned-status-isFloat', 'skeleton'); } @@ -160,4 +164,4 @@ OutlinePlugin.meta = { ], }, }; -OutlinePlugin.pluginName = 'OutlinePlugin'; \ No newline at end of file +OutlinePlugin.pluginName = 'OutlinePlugin'; From 8117b450baa6a25412707797eccdc749b89960b9 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 1 Aug 2023 14:45:31 +0800 Subject: [PATCH 083/361] docs: add setterDetails category --- docs/config/sidebars.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/config/sidebars.js b/docs/config/sidebars.js index 77a2e1f22d..b8a7587d91 100644 --- a/docs/config/sidebars.js +++ b/docs/config/sidebars.js @@ -64,6 +64,11 @@ module.exports = { href: 'https://github.com/alibaba/lowcode-engine/releases', }, ...getDocsFromDir('guide/appendix'), + { + type: 'category', + label: '预置设置器详情', + items: getDocsFromDir('guide/appendix/setterDetails'), + }, ], }, { From 89b666dab85174d3521a17cc1aaedf13b59be4d9 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 10 Aug 2023 15:50:08 +0800 Subject: [PATCH 084/361] refactor: defaultViewType renamed to defaultViewName --- packages/shell/src/model/window.ts | 2 +- .../types/src/shell/type/resource-type-config.ts | 8 +++++++- packages/workspace/src/resource.ts | 8 ++++---- packages/workspace/src/window.ts | 16 ++++++++-------- packages/workspace/src/workspace.ts | 10 +++++----- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/shell/src/model/window.ts b/packages/shell/src/model/window.ts index 3e6bd64507..2b5e0dd8c3 100644 --- a/packages/shell/src/model/window.ts +++ b/packages/shell/src/model/window.ts @@ -32,7 +32,7 @@ export class Window implements IPublicModelWindow { } changeViewType(viewName: string) { - this[windowSymbol].changeViewType(viewName, false); + this[windowSymbol].changeViewName(viewName, false); } onChangeViewType(fun: (viewName: string) => void): IPublicTypeDisposable { diff --git a/packages/types/src/shell/type/resource-type-config.ts b/packages/types/src/shell/type/resource-type-config.ts index e47afb53d5..474987b529 100644 --- a/packages/types/src/shell/type/resource-type-config.ts +++ b/packages/types/src/shell/type/resource-type-config.ts @@ -8,8 +8,14 @@ export interface IPublicResourceTypeConfig { /** 资源 icon 标识 */ icon?: React.ReactElement; + /** + * 默认视图类型 + * @deprecated + */ + defaultViewType?: string; + /** 默认视图类型 */ - defaultViewType: string; + defaultViewName: string; /** 资源视图 */ editorViews: IPublicTypeEditorView[]; diff --git a/packages/workspace/src/resource.ts b/packages/workspace/src/resource.ts index 1d328b6c6c..a7ecc59b2e 100644 --- a/packages/workspace/src/resource.ts +++ b/packages/workspace/src/resource.ts @@ -16,7 +16,7 @@ export interface IBaseResource<T> extends IBaseModelResource<T> { get editorViews(): IPublicTypeEditorView[]; - get defaultViewType(): string; + get defaultViewName(): string | undefined; getEditorView(name: string): IPublicTypeEditorView | undefined; @@ -41,7 +41,7 @@ export class Resource implements IResource { } get viewName() { - return this.resourceData.viewName || (this.resourceData as any).viewType || this.defaultViewType; + return this.resourceData.viewName || (this.resourceData as any).viewType || this.defaultViewName; } get description() { @@ -116,8 +116,8 @@ export class Resource implements IResource { return this.resourceTypeInstance.editorViews; } - get defaultViewType() { - return this.resourceTypeInstance.defaultViewType; + get defaultViewName() { + return this.resourceTypeInstance.defaultViewName || this.resourceTypeInstance.defaultViewType; } getEditorView(name: string) { diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index b6e345f19e..2c670346fb 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -8,7 +8,7 @@ import { IPublicModelWindow, IPublicTypeDisposable } from '@alilc/lowcode-types' interface IWindowCOnfig { title: string | undefined; options?: Object; - viewType?: string | undefined; + viewName?: string | undefined; sleep?: boolean; } @@ -19,7 +19,7 @@ export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'chan editorView: IViewContext; - changeViewType: (name: string, ignoreEmit?: boolean) => void; + changeViewName: (name: string, ignoreEmit?: boolean) => void; initReady: boolean; @@ -130,7 +130,7 @@ export class EditorWindow implements IEditorWindow { this.workspace.emitWindowRendererReady(); }); this.url = await this.resource.url(); - this.setDefaultViewType(); + this.setDefaultViewName(); this.initReady = true; this.workspace.checkWindowQueue(); this.sleep = false; @@ -146,7 +146,7 @@ export class EditorWindow implements IEditorWindow { const name = editorViews[i].viewName; await this.initViewType(name); if (!this.editorView) { - this.changeViewType(name); + this.changeViewName(name); } } }; @@ -166,13 +166,13 @@ export class EditorWindow implements IEditorWindow { } for (let i = 0; i < editorViews.length; i++) { const name = editorViews[i].viewName; - this.changeViewType(name); + this.changeViewName(name); await this.editorViews.get(name)?.init(); } }; - setDefaultViewType = () => { - this.changeViewType(this.config.viewType ?? this.resource.defaultViewType); + setDefaultViewName = () => { + this.changeViewName(this.config.viewName ?? this.resource.defaultViewName!); }; get resourceType() { @@ -188,7 +188,7 @@ export class EditorWindow implements IEditorWindow { this.editorViews.set(name, editorView); }; - changeViewType = (name: string, ignoreEmit: boolean = true) => { + changeViewName = (name: string, ignoreEmit: boolean = true) => { this.editorView?.setActivate(false); this.editorView = this.editorViews.get(name)!; diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index e180d4a2fb..41be09fcf3 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -95,7 +95,7 @@ export class Workspace implements IWorkspace { name: string; title: string; options: Object; - viewType?: string; + viewName?: string; }[] = []; constructor( @@ -114,7 +114,7 @@ export class Workspace implements IWorkspace { const windowInfo = this.windowQueue.shift(); if (windowInfo) { - this.openEditorWindow(windowInfo.name, windowInfo.title, windowInfo.options, windowInfo.viewType); + this.openEditorWindow(windowInfo.name, windowInfo.title, windowInfo.options, windowInfo.viewName); } } @@ -228,10 +228,10 @@ export class Workspace implements IWorkspace { this.window?.updateState(WINDOW_STATE.active); } - async openEditorWindow(name: string, title: string, options: Object, viewType?: string, sleep?: boolean) { + async openEditorWindow(name: string, title: string, options: Object, viewName?: string, sleep?: boolean) { if (this.window && !this.window?.initReady && !sleep) { this.windowQueue.push({ - name, title, options, viewType, + name, title, options, viewName, }); return; } @@ -261,7 +261,7 @@ export class Workspace implements IWorkspace { const window = new EditorWindow(resource, this, { title, options, - viewType, + viewName, sleep, }); this.windows = [...this.windows, window]; From 0eeee1feee3268ca5f970250fda1cfb52725191f Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 11 Aug 2023 16:35:30 +0800 Subject: [PATCH 085/361] feat(skeleton): add skeleton.getPanel api --- docs/docs/api/skeleton.md | 15 +++++++++++++++ packages/shell/src/api/skeleton.ts | 9 +++++++++ packages/shell/src/model/skeleton-item.ts | 4 ++++ packages/types/src/shell/api/skeleton.ts | 7 +++++++ packages/types/src/shell/model/skeleton-item.ts | 5 +++++ 5 files changed, 40 insertions(+) diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index bcf4225db0..c378792de0 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -178,6 +178,21 @@ IWidgetBaseConfig 定义如下: remove(config: IPublicTypeWidgetBaseConfig): number | undefined; ``` +### getPanel + +获取面板实例 + +```typescript +/** + * 获取面板实例 + * @param name 面板名称 + */ +getPanel(name: string): IPublicModelSkeletonItem | undefined; +``` + +相关类型:[IPublicModelSkeletonItem](https://github.com/alibaba/lowcode-engine/blob/main/packages/shell/src/model/skeleton-item.ts) + +@since v1.1.10 ### showPanel diff --git a/packages/shell/src/api/skeleton.ts b/packages/shell/src/api/skeleton.ts index 238931a25e..0d17075257 100644 --- a/packages/shell/src/api/skeleton.ts +++ b/packages/shell/src/api/skeleton.ts @@ -76,6 +76,15 @@ export class Skeleton implements IPublicApiSkeleton { return this[skeletonSymbol][normalizeArea(areaName)].container.items?.map(d => new SkeletonItem(d)); } + getPanel(name: string) { + const item = this[skeletonSymbol].getPanel(name); + if (!item) { + return; + } + + return new SkeletonItem(item); + } + /** * 显示面板 * @param name diff --git a/packages/shell/src/model/skeleton-item.ts b/packages/shell/src/model/skeleton-item.ts index cda8486ad0..7f1224c0d9 100644 --- a/packages/shell/src/model/skeleton-item.ts +++ b/packages/shell/src/model/skeleton-item.ts @@ -32,4 +32,8 @@ export class SkeletonItem implements IPublicModelSkeletonItem { show() { this[skeletonItemSymbol].show(); } + + toggle() { + this[skeletonItemSymbol].toggle(); + } } \ No newline at end of file diff --git a/packages/types/src/shell/api/skeleton.ts b/packages/types/src/shell/api/skeleton.ts index 13ba3468b4..2ad561518b 100644 --- a/packages/types/src/shell/api/skeleton.ts +++ b/packages/types/src/shell/api/skeleton.ts @@ -20,6 +20,13 @@ export interface IPublicApiSkeleton { */ remove(config: IPublicTypeSkeletonConfig): number | undefined; + /** + * 获取面板实例 + * @param name 面板名称 + * @since v1.1.10 + */ + getPanel(name: string): IPublicModelSkeletonItem | undefined; + /** * 展示指定 Panel 实例 * show panel by name diff --git a/packages/types/src/shell/model/skeleton-item.ts b/packages/types/src/shell/model/skeleton-item.ts index c505a677c6..beb18f2228 100644 --- a/packages/types/src/shell/model/skeleton-item.ts +++ b/packages/types/src/shell/model/skeleton-item.ts @@ -13,4 +13,9 @@ export interface IPublicModelSkeletonItem { hide(): void; show(): void; + + /** + * @since v1.1.10 + */ + toggle(): void; } \ No newline at end of file From c458b1b2ec657d98d60638678fe718ea0e908820 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 11 Aug 2023 17:20:32 +0800 Subject: [PATCH 086/361] fix(material): when the assets exist, use onChangeAssets api, the callback is called immediately --- packages/editor-core/src/editor.ts | 10 ++++++++++ packages/shell/src/api/material.ts | 2 +- packages/types/src/shell/model/editor.ts | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index e1d25bdfff..de2191f18f 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -222,6 +222,16 @@ export class Editor extends EventEmitter implements IEditor { }; } + onChange<T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>( + keyOrType: KeyOrType, + fn: (data: IPublicTypeEditorGetResult<T, KeyOrType>) => void, + ): () => void { + this.setWait(keyOrType, fn); + return () => { + this.delWait(keyOrType, fn); + }; + } + register(data: any, key?: IPublicTypeEditorValueKey): void { this.context.set(key || data, data); this.notifyGot(key || data); diff --git a/packages/shell/src/api/material.ts b/packages/shell/src/api/material.ts index ea9d6e01ba..39b21848e0 100644 --- a/packages/shell/src/api/material.ts +++ b/packages/shell/src/api/material.ts @@ -181,7 +181,7 @@ export class Material implements IPublicApiMaterial { onChangeAssets(fn: () => void): IPublicTypeDisposable { const dispose = [ // 设置 assets,经过 setAssets 赋值 - this[editorSymbol].onGot('assets', fn), + this[editorSymbol].onChange('assets', fn), // 增量设置 assets,经过 loadIncrementalAssets 赋值 this[editorSymbol].eventBus.on('designer.incrementalAssetsReady', fn), ]; diff --git a/packages/types/src/shell/model/editor.ts b/packages/types/src/shell/model/editor.ts index 11d75aac75..e6171f0312 100644 --- a/packages/types/src/shell/model/editor.ts +++ b/packages/types/src/shell/model/editor.ts @@ -15,13 +15,27 @@ export interface IPublicModelEditor extends StrictEventEmitter<EventEmitter, Glo set: (key: IPublicTypeEditorValueKey, data: any) => void | Promise<void>; + /** + * 获取 keyOrType 一次 + */ onceGot: <T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>(keyOrType: KeyOrType) => Promise<IPublicTypeEditorGetResult<T, KeyOrType>>; + /** + * 获取 keyOrType 多次 + */ onGot: <T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>( keyOrType: KeyOrType, fn: (data: IPublicTypeEditorGetResult<T, KeyOrType>) => void ) => () => void; + /** + * 监听 keyOrType 变化 + */ + onChange: <T = undefined, KeyOrType extends IPublicTypeEditorValueKey = any>( + keyOrType: KeyOrType, + fn: (data: IPublicTypeEditorGetResult<T, KeyOrType>) => void + ) => () => void; + register: (data: any, key?: IPublicTypeEditorValueKey, options?: IPublicTypeEditorRegisterOptions) => void; get eventBus(): IPublicApiEvent; From abd9ed3adc1ea2871b702faf2ce88657dc08b8cb 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?= <liujup@foxmail.com> Date: Tue, 15 Aug 2023 12:04:34 +0800 Subject: [PATCH 087/361] =?UTF-8?q?docs:=20update=20init.md,=20add=20devic?= =?UTF-8?q?e=20=E5=8F=82=E6=95=B0=E8=AF=A6=E7=BB=86=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/api/init.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 9917d1f72d..10e7541765 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -118,7 +118,7 @@ init(document.getElementById('engine'), { enableCondition: false, }); ``` -### + ### 默认打开移动端画布 ```typescript import { init } from '@alilc/lowcode-engine'; @@ -126,6 +126,25 @@ import { init } from '@alilc/lowcode-engine'; init({ device: 'mobile', }); +``` +### device 参数详细说明 + +引擎默认支持的 device 类型有 `default`、`mobile`、`iphonex`、`iphone6`。 + +插件 `@alilc/lowcode-plugin-simulator-select` 支持的 device 类型有 `default`、`phone`、`tablet`、`desktop`。 + +如果需要自定义的 device 类型,需要补充 device 类型对应的样式,例如 device 为 phone 时,需要补充样式如下: + +```css +.lc-simulator-device-phone { + top: 16px; + bottom: 16px; + left: 50%; + width: 375px; + transform: translateX(-50%); + margin: auto; +} + ``` ### 使用 utils 第三方工具扩展 From 7c8652057ff6e2679bf249550f8b77acb906d0b8 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 15 Aug 2023 12:56:42 +0800 Subject: [PATCH 088/361] docs: publish docs 1.1.1 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index a2299251e4..02fa91b7c2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.0", + "version": "1.1.1", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 5738394a2e04d44e4b1d3db6b6b314b17699334a Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 15 Aug 2023 15:25:21 +0800 Subject: [PATCH 089/361] feat: remove IPublicTypeFieldExtraProps.virtual definition --- docs/docs/guide/expand/editor/metaSpec.md | 1 - packages/types/src/shell/type/field-extra-props.ts | 5 ----- 2 files changed, 6 deletions(-) diff --git a/docs/docs/guide/expand/editor/metaSpec.md b/docs/docs/guide/expand/editor/metaSpec.md index 2f874925fd..dda16a9cb3 100644 --- a/docs/docs/guide/expand/editor/metaSpec.md +++ b/docs/docs/guide/expand/editor/metaSpec.md @@ -460,7 +460,6 @@ import parse from '@alilc/lowcode-material-parser'; { name: 'back', title: ' ', - virtual: () => true, display: 'plain', setter: BackwardSetter, } diff --git a/packages/types/src/shell/type/field-extra-props.ts b/packages/types/src/shell/type/field-extra-props.ts index bfaff1a468..3e2df280b7 100644 --- a/packages/types/src/shell/type/field-extra-props.ts +++ b/packages/types/src/shell/type/field-extra-props.ts @@ -43,11 +43,6 @@ export interface IPublicTypeFieldExtraProps { */ autorun?: (target: IPublicModelSettingField) => void; - /** - * is this field is a virtual field that not save to schema - */ - virtual?: (target: IPublicModelSettingField) => boolean; - /** * default collapsed when display accordion */ From 942972c593cbdafb282e0a7fbddafa2ba1e9461e Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 15 Aug 2023 17:38:06 +0800 Subject: [PATCH 090/361] fix(node-children): solve the crash of null in schema.children --- packages/designer/src/document/node/node-children.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 4fb1c3d226..bf982cbfa7 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -102,7 +102,7 @@ export class NodeChildren implements INodeChildren { options: any = {}, ) { makeObservable(this); - this.children = (Array.isArray(data) ? data : [data]).map((child) => { + this.children = (Array.isArray(data) ? data : [data]).filter(child => !!child).map((child) => { return this.owner.document?.createNode(child, options.checkId); }); } @@ -127,7 +127,7 @@ export class NodeChildren implements INodeChildren { } import(data?: IPublicTypeNodeData | IPublicTypeNodeData[], checkId = false) { - data = data ? (Array.isArray(data) ? data : [data]) : []; + data = (data ? (Array.isArray(data) ? data : [data]) : []).filter(d => !!d); const originChildren = this.children.slice(); this.children.forEach((child) => child.internalSetParent(null)); From f7c1f1e716c855c3e8725cb5acd4ea124a841713 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 16 Aug 2023 11:34:56 +0800 Subject: [PATCH 091/361] feat(event): add event.prependListener api --- docs/docs/api/event.md | 13 +++++++++++++ packages/editor-core/src/event-bus.ts | 8 ++++++++ packages/shell/src/api/event.ts | 14 ++++++++++++++ packages/types/src/shell/api/event.ts | 7 +++++++ 4 files changed, 42 insertions(+) diff --git a/docs/docs/api/event.md b/docs/docs/api/event.md index 9e2bdf641b..0919b41fd2 100644 --- a/docs/docs/api/event.md +++ b/docs/docs/api/event.md @@ -25,6 +25,19 @@ on(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) +### prependListener +监听事件,会在其他回调函数之前执行 + +```typescript +/** + * 监听事件,会在其他回调函数之前执行 + * @param event 事件名称 + * @param listener 事件回调 + */ +prependListener(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable; +``` +相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + ### off 取消监听事件 diff --git a/packages/editor-core/src/event-bus.ts b/packages/editor-core/src/event-bus.ts index 95f26f77ec..ae9d28905b 100644 --- a/packages/editor-core/src/event-bus.ts +++ b/packages/editor-core/src/event-bus.ts @@ -55,6 +55,14 @@ export class EventBus implements IEventBus { }; } + prependListener(event: string, listener: (...args: any[]) => void): () => void { + this.eventEmitter.prependListener(event, listener); + this.getLogger().debug(`${this.getMsgPrefix('prependListener')} ${event}`); + return () => { + this.off(event, listener); + }; + } + /** * 取消监听事件 * @param event 事件名称 diff --git a/packages/shell/src/api/event.ts b/packages/shell/src/api/event.ts index 0fb41966e7..f2adca98c1 100644 --- a/packages/shell/src/api/event.ts +++ b/packages/shell/src/api/event.ts @@ -36,6 +36,20 @@ export class Event implements IPublicApiEvent { } } + /** + * 监听事件,会在其他回调函数之前执行 + * @param event 事件名称 + * @param listener 事件回调 + */ + prependListener(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable { + if (isPluginEventName(event)) { + return this[eventBusSymbol].prependListener(event, listener); + } else { + logger.warn(`fail to prependListener event ${event}, event should have a prefix like 'somePrefix:eventName'`); + return () => {}; + } + } + /** * 取消监听事件 * @param event 事件名称 diff --git a/packages/types/src/shell/api/event.ts b/packages/types/src/shell/api/event.ts index 02b8bc5b3f..5b8c59e139 100644 --- a/packages/types/src/shell/api/event.ts +++ b/packages/types/src/shell/api/event.ts @@ -10,6 +10,13 @@ export interface IPublicApiEvent { */ on(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable; + /** + * 监听事件,会在其他回调函数之前执行 + * add monitor to a event + * @param event 事件名称 + * @param listener 事件回调 + */ + prependListener(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable; /** * 取消监听事件 From bc0b94007a92b2f32fe6692b709019f87bd14f51 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?= <liujup@foxmail.com> Date: Wed, 16 Aug 2023 16:43:15 +0800 Subject: [PATCH 092/361] docs: update faq009.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完善“物料出现 Component Not Found 相关报错” FAQ --- docs/docs/faq/faq009.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/docs/faq/faq009.md b/docs/docs/faq/faq009.md index f1247bfa41..4115384353 100644 --- a/docs/docs/faq/faq009.md +++ b/docs/docs/faq/faq009.md @@ -28,6 +28,28 @@ AliLowCodeEngine.project.simulator.renderer.components ``` 看看对应的物料是否存在,如果不存在,排查物料问题。 +如果不正常,查看资产包配置,其中资产包中的 `components` 和 `material.componentsMap` 生成有关系。 + +例如,物料配置信息在 @alilc/lowcode-materials 包里面,即需要在 components 中加上下面的代码 + +```javascript +"components": [{ + "exportName": "AlilcLowcodeMaterialsMeta", + "npm": { + "package": "@alilc/lowcode-materials" + }, + "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.js", + "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.design.js" + } +}] +``` + +`material.componentsMap` 不存在相关的组件信息,原因有两个: +- 没有添加对应的物料到 components 字段中 +- components 配置不正确,需要查看 url 是否正常加载,查看 exportName 是否配置正确,即 `window.${exportName}` 是否存在。 + 2.选中组件,在控制台中输入 ```json AliLowCodeEngine.project.currentDocument.selection.getNodes()[0].exportSchema('render') From 67a0c9ebdb9c121e08492a780f661e770ee437bc Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Wed, 16 Aug 2023 16:46:01 +0800 Subject: [PATCH 093/361] docs: publish docs 1.1.2 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 02fa91b7c2..45704074da 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.1", + "version": "1.1.2", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From a389ec184ce88cac229a2e9129103ec8a6f0e367 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 17 Aug 2023 15:18:31 +0800 Subject: [PATCH 094/361] feat: mark the loaded remote description descriptions to reduce loading --- packages/editor-core/src/editor.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index de2191f18f..f31a2a2dda 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -35,6 +35,10 @@ const keyBlacklist = [ 'innerPlugins', ]; +const AssetsCache: { + [key: string]: IPublicTypeRemoteComponentDescription; +} = {}; + export declare interface Editor extends StrictEventEmitter<EventEmitter, GlobalEvent.EventConfig> { addListener(event: string | symbol, listener: (...args: any[]) => void): this; once(event: string | symbol, listener: (...args: any[]) => void): this; @@ -143,9 +147,15 @@ export class Editor extends EventEmitter implements IEditor { // 如果有远程组件描述协议,则自动加载并补充到资产包中,同时出发 designer.incrementalAssetsReady 通知组件面板更新数据 if (remoteComponentDescriptions && remoteComponentDescriptions.length) { await Promise.all( - remoteComponentDescriptions.map(async (component: any) => { + remoteComponentDescriptions.map(async (component: IPublicTypeRemoteComponentDescription) => { const { exportName, url, npm } = component; - await (new AssetLoader()).load(url); + if (!url || !exportName) { + return; + } + if (!AssetsCache[exportName] || !npm?.version || AssetsCache[exportName].npm?.version !== npm?.version) { + await (new AssetLoader()).load(url); + } + AssetsCache[exportName] = component; function setAssetsComponent(component: any, extraNpmInfo: any = {}) { const components = component.components; assets.componentList = assets.componentList?.concat(component.componentList || []); @@ -181,14 +191,14 @@ export class Editor extends EventEmitter implements IEditor { }); }); } - if (window[exportName]) { - if (Array.isArray(window[exportName])) { - setArrayAssets(window[exportName] as any); + if ((window as any)[exportName]) { + if (Array.isArray((window as any)[exportName])) { + setArrayAssets((window as any)[exportName] as any); } else { - setAssetsComponent(window[exportName] as any); + setAssetsComponent((window as any)[exportName] as any); } } - return window[exportName]; + return (window as any)[exportName]; }), ); } From 494017a095a3ab0ec4aff4b70c69fd10d043f584 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?= <liujup@foxmail.com> Date: Thu, 17 Aug 2023 16:25:40 +0800 Subject: [PATCH 095/361] docs: update faq013.md --- docs/docs/faq/faq013.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/docs/faq/faq013.md b/docs/docs/faq/faq013.md index bf073e7334..a8f86b2948 100644 --- a/docs/docs/faq/faq013.md +++ b/docs/docs/faq/faq013.md @@ -10,9 +10,28 @@ tags: [FAQ] ## 处理方式 ### 【推荐】升级到 Engine Verison 1.0.11 以上 ### 新增 save propsReducer -通过新增 Save 态的 propsReducer,将 hidden props 去掉。 -参考: -[https://github.com/alibaba/lowcode-demo/blob/main/src/sample-plugins/delete-hidden-transducer/index.ts](https://github.com/alibaba/lowcode-demo/blob/main/src/sample-plugins/delete-hidden-transducer/index.ts) + +通过新增 Save 态的 propsReducer,将 hidden props 去掉。可以参考下面的代码: + +```typescript +import { project } from '@alilc/lowcode-engine'; +import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; + +export const deleteHiddenTransducer = (ctx: any) => { + return { + name: 'deleteHiddenTransducer', + async init() { + project.addPropsTransducer((props: any): any => { + delete props.hidden; + return props; + }, IPublicEnumTransformStage.Save); + }, + }; +} + +deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer'; + +``` ### 导出 schema 使用 Save 态 ```typescript From 7b85128ee52c4326bbdbd2a48d88bb91525688de Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 17 Aug 2023 16:37:07 +0800 Subject: [PATCH 096/361] docs: publish docs 1.1.3 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 45704074da..6267047000 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.2", + "version": "1.1.3", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 3b36926c7083572f6f3b96435da73e646ffbcb94 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 17 Aug 2023 17:26:02 +0800 Subject: [PATCH 097/361] feat: after the component title is modified, update the title of the ComponentAction area --- .../designer/src/builtin-simulator/node-selector/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/designer/src/builtin-simulator/node-selector/index.tsx b/packages/designer/src/builtin-simulator/node-selector/index.tsx index 07ae754aae..0723115da2 100644 --- a/packages/designer/src/builtin-simulator/node-selector/index.tsx +++ b/packages/designer/src/builtin-simulator/node-selector/index.tsx @@ -1,6 +1,6 @@ import { Overlay } from '@alifd/next'; import React, { MouseEvent } from 'react'; -import { Title } from '@alilc/lowcode-editor-core'; +import { Title, observer } from '@alilc/lowcode-editor-core'; import { canClickNode } from '@alilc/lowcode-utils'; import './index.less'; @@ -18,6 +18,7 @@ export interface IState { type UnionNode = INode | null; +@observer export default class InstanceNodeSelector extends React.Component<IProps, IState> { state: IState = { parentNodes: [], From e1dd8e0c5a78c0aed62067bf259bd593fad7f5fa Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 17 Aug 2023 18:55:40 +0800 Subject: [PATCH 098/361] docs: add config options doc --- docs/docs/api/configOptions.md | 285 +++++++++++++++++++++++++++++++++ docs/docs/api/init.md | 111 +------------ 2 files changed, 286 insertions(+), 110 deletions(-) create mode 100644 docs/docs/api/configOptions.md diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md new file mode 100644 index 0000000000..3f8e75df29 --- /dev/null +++ b/docs/docs/api/configOptions.md @@ -0,0 +1,285 @@ +--- +title: config options - 配置列表 +sidebar_position: 13 +--- + +> **@types** [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts)<br/> + +## 配置方式 + +#### init API + +```javascript +import { init } from '@alilc/lowcode-engine'; + +init(document.getElementById('engine'), { + enableCondition: false, +}); +``` + +[**init api**](./init) + +#### config API + +```javascript +import { config } from '@alilc/lowcode-engine'; + +config.set('enableCondition', false) +``` + +[**config api**](./config) + +## 配置详情 + +> 源码详见 [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts) + + +### 画布 + +#### locale - 语言 + +`@type {string}`、`@default {zh-CN}` + +语言 + +#### device - 设备类型 + +`@type {string}` + +引擎默认支持的 device 类型有 `default`、`mobile`、`iphonex`、`iphone6`。 + +插件 `@alilc/lowcode-plugin-simulator-select` 支持的 device 类型有 `default`、`phone`、`tablet`、`desktop`。 + +如果需要自定义的 device 类型,需要补充 device 类型对应的样式,例如 device 为 phone 时,需要补充样式如下: + +```css +.lc-simulator-device-phone { + top: 16px; + bottom: 16px; + left: 50%; + width: 375px; + transform: translateX(-50%); + margin: auto; +} +``` + +#### deviceClassName + +`@type {string}` + +指定初始化的 deviceClassName,挂载到画布的顶层节点上 + +#### appHelper + +与 react-renderer 的 appHelper 一致,https://lowcode-engine.cn/site/docs/guide/expand/runtime/renderer#apphelper + + +#### enableCondition + +`@type {boolean}` + +是否开启 condition 的能力,默认在设计器中不管 condition 是啥都正常展示 + +#### disableAutoRender + +`@type {boolean}` `@default {false}` + +关闭画布自动渲染,在资产包多重异步加载的场景有效 + +#### renderEnv - 渲染器类型 + +渲染器类型 + +`@type {string}`、`@default {react}` + +#### simulatorUrl + +`@type {string[]}` + +设置 simulator 相关的 url + +#### enableStrictNotFoundMode + +`@type {boolean}` `@default {false}` + +当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 + +### 编排 + +#### focusNodeSelector - 指定根组件 + +配置指定节点为根组件 + +类型定义 + +```typescript + focusNodeSelector?: (rootNode: Node) => Node; +``` + +#### supportVariableGlobally - 全局变量配置 + +`@type {boolean}` `@default {false}` + +设置所有属性支持变量配置 + +开启拖拽组件时,即将被放入的容器是否有视觉反馈 + +#### customizeIgnoreSelectors - 点击忽略 + +定制画布中点击被忽略的 selectors + +类型定义: + +```typescript + customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[], e: MouseEvent) => string[]; +``` + +默认值: + +```javascript +() => { + return [ + '.next-input-group', + '.next-checkbox-group', + '.next-checkbox-wrapper', + '.next-date-picker', + '.next-input', + '.next-month-picker', + '.next-number-picker', + '.next-radio-group', + '.next-range', + '.next-range-picker', + '.next-rating', + '.next-select', + '.next-switch', + '.next-time-picker', + '.next-upload', + '.next-year-picker', + '.next-breadcrumb-item', + '.next-calendar-header', + '.next-calendar-table', + '.editor-container', // 富文本组件 + ] +} +``` + +#### enableCanvasLock + +`@type {boolean}` `@default {false}` + +打开画布的锁定操作 + +#### enableLockedNodeSetting + +`@type {boolean}` `@default {false}` + +容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效 + +#### enableMouseEventPropagationInCanvas + +`@type {boolean}` `@default {false}` + +鼠标事件在画布中是否允许冒泡 + +#### enableReactiveContainer + +`@type {boolean}` `@default {false}` + +#### disableDetecting + +`@type {boolean}` `@default {false}` + +关闭拖拽组件时的虚线响应,性能考虑 + + +#### disableDefaultSettingPanel + +`@type {boolean}` `@default {false}` + +禁止默认的设置面板 + +#### disableDefaultSetters + +`@type {boolean}` `@default {false}` + +禁止默认的设置器 + +#### stayOnTheSameSettingTab + +`@type {boolean}` `@default {false}` + +当选中节点切换时,是否停留在相同的设置 tab 上 + +#### hideSettingsTabsWhenOnlyOneItem + +`@type {boolean}` `@default {false}` + +是否在只有一个 item 的时候隐藏设置 tabs + +#### thisRequiredInJSE + +`@type {boolean}` `@default {true}` + +JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false + +### 应用级设计器 + +#### enableWorkspaceMode - 应用级设计模式 + +`@type {boolean}` `@default {false}` + +开启应用级设计模式 + +#### enableAutoOpenFirstWindow + +`@type {boolean}` `@default {true}` + +应用级设计模式下,自动打开第一个窗口 + +#### workspaceEmptyComponent + +应用级设计模式下,当窗口为空时,展示的占位组件 + +### 定制组件 + +#### faultComponent + +组件渲染错误时的占位组件 + +#### notFoundComponent + +组件不存在时的占位组件 + +#### loadingComponent - loading 组件 + +自定义 loading 组件 + +### 其他 + +#### enableStrictPluginMode + +`@type {boolean}` + +开启严格插件模式,默认值:STRICT_PLUGIN_MODE_DEFAULT , 严格模式下,插件将无法通过 engineOptions 传递自定义配置项 + +#### requestHandlersMap + +数据源引擎的请求处理器映射 + +#### customPluginTransducer + +插件处理中间件,方便提供插件调试能力 + +类型定义 + +```typescript +customPluginTransducer: async (originPlugin: IPublicTypePlugin, ctx: IPublicModelPluginContext, options): IPublicTypePlugin; +``` + +#### defaultOutlinePaneProps + +`@type {object}` + +大纲树插件面板默认 props + + diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 10e7541765..55b116a579 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -17,97 +17,7 @@ sidebar_position: 10 function init(container?: Element, options?: IPublicTypeEngineOptions): void ``` -**初始化引擎的参数** - -```typescript -interface IPublicTypeEngineOptions { - /** - * 指定初始化的 device - */ - device?: 'default' | 'mobile'; - /** - * 指定初始化的 deviceClassName,挂载到画布的顶层节点上 - */ - deviceClassName?: string; - /** - * 是否开启 condition 的能力,默认在设计器中不管 condition 是啥都正常展示 - */ - enableCondition?: boolean; - /** - * 开启拖拽组件时,即将被放入的容器是否有视觉反馈,默认值:false - */ - enableReactiveContainer?: boolean; - /** - * 关闭画布自动渲染,在资产包多重异步加载的场景有效,默认值:false - */ - disableAutoRender?: boolean; - /** - * 打开画布的锁定操作,默认值:false - */ - enableCanvasLock?: boolean; - /** - * 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效,默认值为:false - */ - enableLockedNodeSetting?: boolean; - /** - * 开启画布上的鼠标事件的冒泡,默认值:false - */ - enableMouseEventPropagationInCanvas?: boolean; - /** - * 关闭拖拽组件时的虚线响应,性能考虑,默认值:false - */ - disableDetecting?: boolean; - /** - * 定制画布中点击被忽略的 selectors,默认值:undefined - */ - customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[]) => string[]; - /** - * 禁止默认的设置面板,默认值:false - */ - disableDefaultSettingPanel?: boolean; - /** - * 禁止默认的设置器,默认值:false - */ - disableDefaultSetters?: boolean; - /** - * 当选中节点切换时,是否停留在相同的设置 tab 上,默认值:false - */ - stayOnTheSameSettingTab?: boolean; - /** - * 自定义 loading 组件 - */ - loadingComponent?: ComponentType; - - /** - * @default true - * JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false - */ - thisRequiredInJSE?: boolean; - - /** - * @default false - * >= 1.0.14 - * 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 - */ - enableStrictNotFoundMode?: boolean; - - /** - * 配置指定节点为根组件 - * >= 1.0.15 - */ - focusNodeSelector?: (rootNode: Node) => Node; - - /** - * 工具类扩展 - */ - appHelper?: { - utils?: {}; - } - - [key: string]: any; -} -``` -> 源码详见 [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts) +[**初始化引擎配置参数列表**](./configOptions) ## 使用示例 @@ -126,25 +36,6 @@ import { init } from '@alilc/lowcode-engine'; init({ device: 'mobile', }); -``` -### device 参数详细说明 - -引擎默认支持的 device 类型有 `default`、`mobile`、`iphonex`、`iphone6`。 - -插件 `@alilc/lowcode-plugin-simulator-select` 支持的 device 类型有 `default`、`phone`、`tablet`、`desktop`。 - -如果需要自定义的 device 类型,需要补充 device 类型对应的样式,例如 device 为 phone 时,需要补充样式如下: - -```css -.lc-simulator-device-phone { - top: 16px; - bottom: 16px; - left: 50%; - width: 375px; - transform: translateX(-50%); - margin: auto; -} - ``` ### 使用 utils 第三方工具扩展 From 82ecee98c5e64a6f41467de2fd666bab26cd8d81 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 18 Aug 2023 09:34:43 +0800 Subject: [PATCH 099/361] docs: publish docs 1.1.4 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 6267047000..c454117331 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.3", + "version": "1.1.4", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 4128654347d06406a385a724028f90640cbfb07c Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Fri, 18 Aug 2023 15:01:11 +0800 Subject: [PATCH 100/361] fix: default FaultComponent can not get componentName (#2385) --- .../renderer-core/src/renderer/renderer.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/renderer-core/src/renderer/renderer.tsx b/packages/renderer-core/src/renderer/renderer.tsx index 88cc0ce025..09559b6f89 100644 --- a/packages/renderer-core/src/renderer/renderer.tsx +++ b/packages/renderer-core/src/renderer/renderer.tsx @@ -135,17 +135,20 @@ export default function rendererFactory(): IRenderComponent { return engine.createElement(engine.getFaultComponent(), { ...this.props, error: this.state.error, + componentName: this.props._componentName }); } return originRender.call(this); }; - const originShouldComponentUpdate = SetComponent.prototype.shouldComponentUpdate; - SetComponent.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) { - if (nextState && nextState.engineRenderError) { - return true; - } - return originShouldComponentUpdate ? originShouldComponentUpdate.call(this, nextProps, nextState) : true; - }; + if(!(SetComponent.prototype instanceof PureComponent)) { + const originShouldComponentUpdate = SetComponent.prototype.shouldComponentUpdate; + SetComponent.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) { + if (nextState && nextState.engineRenderError) { + return true; + } + return originShouldComponentUpdate ? originShouldComponentUpdate.call(this, nextProps, nextState) : true; + }; + } } createElement(SetComponent: any, props: any, children?: any) { From 15f5675ddd75b453249ec388164767a0412444d9 Mon Sep 17 00:00:00 2001 From: kyoonart <pengtaocc@foxmail.com> Date: Fri, 18 Aug 2023 15:17:00 +0800 Subject: [PATCH 101/361] feat: outline-plugin-pane support overflow-x scroll & delete node (#2376) --- .../src/controllers/tree-node.ts | 4 ++- .../plugin-outline-pane/src/icons/delete.tsx | 11 +++++++ .../plugin-outline-pane/src/icons/index.ts | 1 + .../plugin-outline-pane/src/locale/en-US.json | 3 +- .../plugin-outline-pane/src/locale/zh-CN.json | 3 +- .../plugin-outline-pane/src/views/style.less | 32 +++++++++++++------ .../src/views/tree-title.tsx | 32 ++++++++++++++++--- 7 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 packages/plugin-outline-pane/src/icons/delete.tsx diff --git a/packages/plugin-outline-pane/src/controllers/tree-node.ts b/packages/plugin-outline-pane/src/controllers/tree-node.ts index 92bf374d86..34d06fee0b 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-node.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-node.ts @@ -178,7 +178,9 @@ export default class TreeNode { this.node.lock(flag); this.event.emit(EVENT_NAMES.lockedChanged, flag); } - + deleteNode(node: IPublicModelNode) { + node && node.remove(); + } onFilterResultChanged(fn: () => void): IPublicTypeDisposable { this.event.on(EVENT_NAMES.filterResultChanged, fn); return () => { diff --git a/packages/plugin-outline-pane/src/icons/delete.tsx b/packages/plugin-outline-pane/src/icons/delete.tsx new file mode 100644 index 0000000000..1f93600196 --- /dev/null +++ b/packages/plugin-outline-pane/src/icons/delete.tsx @@ -0,0 +1,11 @@ +import { SVGIcon, IconProps } from '@alilc/lowcode-utils'; + +export function IconDelete(props: IconProps) { + return ( + <SVGIcon viewBox="0 0 1024 1024" {...props}> + <path d="M224 256v639.84A64 64 0 0 0 287.84 960h448.32A64 64 0 0 0 800 895.84V256h64a32 32 0 1 0 0-64H160a32 32 0 1 0 0 64h64zM384 96c0-17.664 14.496-32 31.904-32h192.192C625.696 64 640 78.208 640 96c0 17.664-14.496 32-31.904 32H415.904A31.872 31.872 0 0 1 384 96z m-96 191.744C288 270.208 302.4 256 320.224 256h383.552C721.6 256 736 270.56 736 287.744v576.512C736 881.792 721.6 896 703.776 896H320.224A32.224 32.224 0 0 1 288 864.256V287.744zM352 352c0-17.696 14.208-32.032 32-32.032 17.664 0 32 14.24 32 32v448c0 17.664-14.208 32-32 32-17.664 0-32-14.24-32-32V352z m128 0c0-17.696 14.208-32.032 32-32.032 17.664 0 32 14.24 32 32v448c0 17.664-14.208 32-32 32-17.664 0-32-14.24-32-32V352z m128 0c0-17.696 14.208-32.032 32-32.032 17.664 0 32 14.24 32 32v448c0 17.664-14.208 32-32 32-17.664 0-32-14.24-32-32V352z" /> + </SVGIcon> + ); +} + +IconDelete.displayName = 'IconDelete'; diff --git a/packages/plugin-outline-pane/src/icons/index.ts b/packages/plugin-outline-pane/src/icons/index.ts index ad90250818..d28f61dd28 100644 --- a/packages/plugin-outline-pane/src/icons/index.ts +++ b/packages/plugin-outline-pane/src/icons/index.ts @@ -9,3 +9,4 @@ export * from './loop'; export * from './radio-active'; export * from './radio'; export * from './setting'; +export * from './delete'; diff --git a/packages/plugin-outline-pane/src/locale/en-US.json b/packages/plugin-outline-pane/src/locale/en-US.json index b0f3d3e4a3..9ade9e66f4 100644 --- a/packages/plugin-outline-pane/src/locale/en-US.json +++ b/packages/plugin-outline-pane/src/locale/en-US.json @@ -18,5 +18,6 @@ "Locked": "Locked", "Hidden": "Hidden", "Modal View": "Modal View", - "Rename": "Rename" + "Rename": "Rename", + "Delete": "Delete" } diff --git a/packages/plugin-outline-pane/src/locale/zh-CN.json b/packages/plugin-outline-pane/src/locale/zh-CN.json index 8036688f22..9070d17715 100644 --- a/packages/plugin-outline-pane/src/locale/zh-CN.json +++ b/packages/plugin-outline-pane/src/locale/zh-CN.json @@ -18,5 +18,6 @@ "Locked": "已锁定", "Hidden": "已隐藏", "Modal View": "模态视图层", - "Rename": "重命名" + "Rename": "重命名", + "Delete": "删除" } diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index f343fba170..254b639d62 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -51,6 +51,7 @@ overflow: hidden; margin-bottom: @treeNodeHeight; user-select: none; + overflow-x: scroll; .tree-node-modal { margin: 5px; @@ -80,7 +81,8 @@ } } - .tree-node-modal-radio, .tree-node-modal-radio-active { + .tree-node-modal-radio, + .tree-node-modal-radio-active { margin-right: 4px; opacity: 0.8; position: absolute; @@ -139,7 +141,7 @@ content: ' '; z-index: 2; } - >.condition-group-title { + > .condition-group-title { text-align: center; background-color: #7b605b; height: 14px; @@ -167,7 +169,7 @@ content: ' '; z-index: 2; } - >.tree-node-slots-title { + > .tree-node-slots-title { text-align: center; background-color: rgb(144, 94, 190); height: 14px; @@ -183,7 +185,7 @@ &.insertion-at-slots { padding-bottom: @treeNodeHeight; border-bottom-color: rgb(182, 55, 55); - >.tree-node-slots-title { + > .tree-node-slots-title { background-color: rgb(182, 55, 55); } &::before { @@ -279,7 +281,10 @@ } } - .tree-node-hide-btn, .tree-node-lock-btn, .tree-node-rename-btn { + .tree-node-hide-btn, + .tree-node-lock-btn, + .tree-node-rename-btn, + .tree-node-delete-btn { opacity: 0; color: var(--color-text); line-height: 0; @@ -293,18 +298,26 @@ } } &:hover { - .tree-node-hide-btn, .tree-node-lock-btn, .tree-node-rename-btn { + .tree-node-hide-btn, + .tree-node-lock-btn, + .tree-node-rename-btn, + .tree-node-delete-btn { opacity: 0.5; } } html.lc-cursor-dragging & { // FIXME: only hide hover shows - .tree-node-hide-btn, .tree-node-lock-btn, .tree-node-rename-btn { + .tree-node-hide-btn, + .tree-node-lock-btn, + .tree-node-rename-btn { display: none; } } &.editing { - & > .tree-node-hide-btn, & >.tree-node-lock-btn, & >.tree-node-rename-btn { + & > .tree-node-hide-btn, + & > .tree-node-lock-btn, + & > .tree-node-rename-btn, + & > .tree-node-delete-btn { display: none; } } @@ -381,7 +394,8 @@ opacity: 0.8; } .tree-node-branches { - .tree-node-lock-btn, .tree-node-hide-btn { + .tree-node-lock-btn, + .tree-node-hide-btn { opacity: 0; } } diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 6686ea3cf7..02ac94ae69 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import { createIcon } from '@alilc/lowcode-utils'; import { IPublicApiEvent } from '@alilc/lowcode-types'; import TreeNode from '../controllers/tree-node'; -import { IconLock, IconUnlock, IconArrowRight, IconEyeClose, IconEye, IconCond, IconLoop, IconRadioActive, IconRadio, IconSetting } from '../icons'; +import { IconLock, IconUnlock, IconArrowRight, IconEyeClose, IconEye, IconCond, IconLoop, IconRadioActive, IconRadio, IconSetting, IconDelete } from '../icons'; function emitOutlineEvent(event: IPublicApiEvent, type: string, treeNode: TreeNode, rest?: Record<string, unknown>) { const node = treeNode?.node; @@ -100,7 +100,11 @@ export default class TreeTitle extends PureComponent<{ }); }); } - + deleteClick = () => { + const { treeNode } = this.props; + const { node } = treeNode; + treeNode.deleteNode(node); + }; render() { const { treeNode, isModal } = this.props; const { pluginContext } = treeNode; @@ -131,6 +135,7 @@ export default class TreeTitle extends PureComponent<{ const shouldShowHideBtn = isCNode && isNodeParent && !isModal && couldHide; const shouldShowLockBtn = config.get('enableCanvasLock', false) && isContainer && isCNode && isNodeParent && ((couldLock && !node.isLocked) || (couldUnlock && node.isLocked)); const shouldEditBtn = isCNode && isNodeParent; + const shouldDeleteBtn = isCNode && isNodeParent && node?.canPerformAction('remove'); return ( <div className={classNames('tree-node-title', { editing })} @@ -214,8 +219,28 @@ export default class TreeTitle extends PureComponent<{ </div> {shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} />} {shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} />} - {shouldEditBtn && <RenameBtn treeNode={treeNode} onClick={this.enableEdit} /> } + {shouldEditBtn && <RenameBtn treeNode={treeNode} onClick={this.enableEdit} />} + {shouldDeleteBtn && <DeleteBtn treeNode={treeNode} onClick={this.deleteClick} />} + </div> + ); + } +} +class DeleteBtn extends PureComponent<{ + treeNode: TreeNode; + onClick: () => void; +}> { + render() { + const { intl, common } = this.props.treeNode.pluginContext; + const { Tip } = common.editorCabin; + return ( + <div + className="tree-node-delete-btn" + onClick={this.props.onClick} + > + <IconDelete /> + {/* @ts-ignore */} + <Tip>{intl('Delete')}</Tip> </div> ); } @@ -297,7 +322,6 @@ class ExpandBtn extends PureComponent<{ expanded: boolean; expandable: boolean; }> { - render() { const { treeNode, expanded, expandable } = this.props; if (!expandable) { From cf3d7a86429f5bd7d9c8ff59162b208b272c627e Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 2 Aug 2023 10:51:55 +0800 Subject: [PATCH 102/361] feat(workspace): when the sleep window is opened, the active window event is not triggered --- packages/workspace/src/workspace.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 41be09fcf3..b12fbb65ba 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -266,10 +266,12 @@ export class Workspace implements IWorkspace { }); this.windows = [...this.windows, window]; this.editorWindowMap.set(window.id, window); - if (!sleep) { - this.window = window; - await this.window.init(); + if (sleep) { + this.emitChangeWindow(); + return; } + this.window = window; + await this.window.init(); this.emitChangeWindow(); this.emitChangeActiveWindow(); this.window?.updateState(WINDOW_STATE.active); From 8b5e2b47c6668817e365b31277f2b2d6c9313cca Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 18 Aug 2023 16:45:35 +0800 Subject: [PATCH 103/361] fix(material): fix rendering is blocked, when the url in the asset fails to load --- packages/editor-core/src/editor.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index f31a2a2dda..10aa0bea1c 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -153,7 +153,11 @@ export class Editor extends EventEmitter implements IEditor { return; } if (!AssetsCache[exportName] || !npm?.version || AssetsCache[exportName].npm?.version !== npm?.version) { - await (new AssetLoader()).load(url); + try { + await (new AssetLoader()).load(url); + } catch (error) { + console.error(`${url} load error: `, error); + } } AssetsCache[exportName] = component; function setAssetsComponent(component: any, extraNpmInfo: any = {}) { From 9ddda1db9e50f91c3865d841e81da0f52599b498 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 18 Aug 2023 17:00:56 +0800 Subject: [PATCH 104/361] feat(config): add onGot in config.device --- packages/plugin-designer/src/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/plugin-designer/src/index.tsx b/packages/plugin-designer/src/index.tsx index 90eefaaba5..51b81ff9d0 100644 --- a/packages/plugin-designer/src/index.tsx +++ b/packages/plugin-designer/src/index.tsx @@ -72,6 +72,11 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP requestHandlersMap, }); }); + engineConfig.onGot('device', (device) => { + this.setState({ + device, + }); + }); const { components, packages, extraEnvironment, utils } = assets; const state = { componentMetadatas: components || [], From 899ffa15541164c31e2e3688344639046df282ec Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 21 Aug 2023 10:56:03 +0800 Subject: [PATCH 105/361] feat(workspace): update openEditorWindow api --- docs/docs/api/workspace.md | 11 +++- .../designer/src/plugin/plugin-manager.ts | 4 +- packages/shell/src/api/workspace.ts | 14 +++-- packages/shell/src/model/resource.ts | 4 ++ packages/types/src/shell/api/workspace.ts | 13 ++++- packages/types/src/shell/model/resource.ts | 2 + .../types/src/shell/type/resource-list.ts | 7 +-- packages/workspace/src/resource.ts | 4 ++ packages/workspace/src/workspace.ts | 55 +++++++++++++++++-- 9 files changed, 92 insertions(+), 22 deletions(-) diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 9d99609270..5e0f7acd2f 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -84,7 +84,14 @@ setResourceList(resourceList: IPublicResourceList) {} 打开视图窗口 ```typescript -openEditorWindow(resourceName: string, title: string, options: Object, viewName?: string): void; +/** + * 打开视图窗口 + * @deprecated + */ +openEditorWindow(resourceName: string, id: string, extra: Object, viewName?: string, sleep?: boolean): Promise<void>; + +/** 打开视图窗口 */ +openEditorWindow(resource: Resource, sleep?: boolean): Promise<void>; ``` ### openEditorWindowById @@ -100,7 +107,7 @@ openEditorWindowById(id: string): void; 移除视图窗口 ```typescript -removeEditorWindow(resourceName: string, title: string): void; +removeEditorWindow(resourceName: string, id: string): void; ``` ### removeEditorWindowById diff --git a/packages/designer/src/plugin/plugin-manager.ts b/packages/designer/src/plugin/plugin-manager.ts index f30ccdc8f3..f6b325dc0d 100644 --- a/packages/designer/src/plugin/plugin-manager.ts +++ b/packages/designer/src/plugin/plugin-manager.ts @@ -84,8 +84,8 @@ export class LowCodePluginManager implements ILowCodePluginManager { const ctx = this._getLowCodePluginContext({ pluginName, meta }); const customFilterValidOptions = engineConfig.get('customPluginFilterOptions', filterValidOptions); const pluginTransducer = engineConfig.get('customPluginTransducer', null); - const newOptions = customFilterValidOptions(options, preferenceDeclaration!); - const newPluginModel = pluginTransducer ? await pluginTransducer(pluginModel, ctx, newOptions) : pluginModel; + const newPluginModel = pluginTransducer ? await pluginTransducer(pluginModel, ctx, options) : pluginModel; + const newOptions = customFilterValidOptions(options, newPluginModel.meta?.preferenceDeclaration); const config = newPluginModel(ctx, newOptions); // compat the legacy way to declare pluginName // @ts-ignore diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index 1a16d31ce8..b19638ec76 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -1,6 +1,6 @@ import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; import { IWorkspace } from '@alilc/lowcode-workspace'; -import { workspaceSymbol } from '../symbols'; +import { resourceSymbol, workspaceSymbol } from '../symbols'; import { Resource as ShellResource, Window as ShellWindow } from '../model'; import { Plugins } from './plugins'; @@ -64,16 +64,20 @@ export class Workspace implements IPublicApiWorkspace { this[workspaceSymbol].registerResourceType(resourceTypeModel); } - async openEditorWindow(resourceName: string, title: string, extra: object, viewName?: string, sleep?: boolean): Promise<void> { - await this[workspaceSymbol].openEditorWindow(resourceName, title, extra, viewName, sleep); + async openEditorWindow(): Promise<void> { + if (typeof arguments[0] === 'string') { + await this[workspaceSymbol].openEditorWindow(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); + } else { + await this[workspaceSymbol].openEditorWindowByResource(arguments[0]?.[resourceSymbol], arguments[1]); + } } openEditorWindowById(id: string) { this[workspaceSymbol].openEditorWindowById(id); } - removeEditorWindow(resourceName: string, title: string) { - this[workspaceSymbol].removeEditorWindow(resourceName, title); + removeEditorWindow(resourceName: string, id: string) { + this[workspaceSymbol].removeEditorWindow(resourceName, id); } removeEditorWindowById(id: string) { diff --git a/packages/shell/src/model/resource.ts b/packages/shell/src/model/resource.ts index 6a1a07e499..29a385b993 100644 --- a/packages/shell/src/model/resource.ts +++ b/packages/shell/src/model/resource.ts @@ -13,6 +13,10 @@ export class Resource implements IPublicModelResource { return this[resourceSymbol].title; } + get id() { + return this[resourceSymbol].id; + } + get icon() { return this[resourceSymbol].icon; } diff --git a/packages/types/src/shell/api/workspace.ts b/packages/types/src/shell/api/workspace.ts index 8ae2434bc5..d4232d9a14 100644 --- a/packages/types/src/shell/api/workspace.ts +++ b/packages/types/src/shell/api/workspace.ts @@ -3,7 +3,8 @@ import { IPublicApiPlugins, IPublicModelResource, IPublicResourceList, IPublicTy export interface IPublicApiWorkspace< Plugins = IPublicApiPlugins, - ModelWindow = IPublicModelWindow + ModelWindow = IPublicModelWindow, + Resource = IPublicModelResource, > { /** 是否启用 workspace 模式 */ @@ -29,14 +30,20 @@ export interface IPublicApiWorkspace< /** 注册资源 */ registerResourceType(resourceTypeModel: IPublicTypeResourceType): void; + /** + * 打开视图窗口 + * @deprecated + */ + openEditorWindow(resourceName: string, id: string, extra: Object, viewName?: string, sleep?: boolean): Promise<void>; + /** 打开视图窗口 */ - openEditorWindow(resourceName: string, title: string, extra: Object, viewName?: string, sleep?: boolean): Promise<void>; + openEditorWindow(resource: Resource, sleep?: boolean): Promise<void>; /** 通过视图 id 打开窗口 */ openEditorWindowById(id: string): void; /** 移除视图窗口 */ - removeEditorWindow(resourceName: string, title: string): void; + removeEditorWindow(resourceName: string, id: string): void; /** 通过视图 id 移除窗口 */ removeEditorWindowById(id: string): void; diff --git a/packages/types/src/shell/model/resource.ts b/packages/types/src/shell/model/resource.ts index 0d791412b9..b79b6acfcc 100644 --- a/packages/types/src/shell/model/resource.ts +++ b/packages/types/src/shell/model/resource.ts @@ -5,6 +5,8 @@ export interface IBaseModelResource< > { get title(): string | undefined; + get id(): string | undefined; + get icon(): ReactElement | undefined; get options(): Record<string, any>; diff --git a/packages/types/src/shell/type/resource-list.ts b/packages/types/src/shell/type/resource-list.ts index 7abdcc7b13..ec998a95be 100644 --- a/packages/types/src/shell/type/resource-list.ts +++ b/packages/types/src/shell/type/resource-list.ts @@ -8,6 +8,9 @@ export interface IPublicResourceData { /** 资源标题 */ title?: string; + /** 资源 Id */ + id?: string; + /** 分类 */ category?: string; @@ -24,10 +27,6 @@ export interface IPublicResourceData { /** 资源子元素 */ children?: IPublicResourceData[]; - - config?: { - disableBehaviors?: ('copy' | 'remove')[]; - }; } export type IPublicResourceList = IPublicResourceData[]; \ No newline at end of file diff --git a/packages/workspace/src/resource.ts b/packages/workspace/src/resource.ts index a7ecc59b2e..6e85183853 100644 --- a/packages/workspace/src/resource.ts +++ b/packages/workspace/src/resource.ts @@ -60,6 +60,10 @@ export class Resource implements IResource { return this.resourceData.title || this.resourceTypeInstance.defaultTitle; } + get id(): string | undefined { + return this.resourceData.id; + } + get options() { return this.resourceData.options; } diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index b12fbb65ba..50255b7dbf 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -50,6 +50,8 @@ export interface IWorkspace extends Omit<IPublicApiWorkspace< onChangeActiveEditorView(fn: () => void): IPublicTypeDisposable; emitChangeActiveEditorView(): void; + + openEditorWindowByResource(resource: IResource, sleep: boolean): Promise<void>; } export class Workspace implements IWorkspace { @@ -91,12 +93,12 @@ export class Workspace implements IWorkspace { @obx.ref window: IEditorWindow; - windowQueue: { + windowQueue: ({ name: string; title: string; options: Object; viewName?: string; - }[] = []; + } | IResource)[] = []; constructor( readonly registryInnerPlugin: (designer: IDesigner, editor: IEditor, plugins: IPublicApiPlugins) => Promise<IPublicTypeDisposable>, @@ -192,7 +194,7 @@ export class Workspace implements IWorkspace { this.remove(index); } - private remove(index: number) { + private async remove(index: number) { if (index < 0) { return; } @@ -202,7 +204,7 @@ export class Workspace implements IWorkspace { if (this.window === window) { this.window = this.windows[index] || this.windows[index + 1] || this.windows[index - 1]; if (this.window?.sleep) { - this.window.init(); + await this.window.init(); } this.emitChangeActiveWindow(); } @@ -210,8 +212,8 @@ export class Workspace implements IWorkspace { this.window?.updateState(WINDOW_STATE.active); } - removeEditorWindow(resourceName: string, title: string) { - const index = this.windows.findIndex(d => (d.resource?.name === resourceName && d.title === title)); + removeEditorWindow(resourceName: string, id: string) { + const index = this.windows.findIndex(d => (d.resource?.name === resourceName && d.title === id)); this.remove(index); } @@ -228,6 +230,47 @@ export class Workspace implements IWorkspace { this.window?.updateState(WINDOW_STATE.active); } + async openEditorWindowByResource(resource: IResource, sleep: boolean = false): Promise<void> { + if (this.window && !this.window?.initReady && !sleep) { + this.windowQueue.push(resource); + return; + } + + this.window?.updateState(WINDOW_STATE.inactive); + + const filterWindows = this.windows.filter(d => (d.resource?.id === resource.id)); + if (filterWindows && filterWindows.length) { + this.window = filterWindows[0]; + if (!sleep && this.window.sleep) { + await this.window.init(); + } else { + this.checkWindowQueue(); + } + this.emitChangeActiveWindow(); + this.window?.updateState(WINDOW_STATE.active); + return; + } + + const window = new EditorWindow(resource, this, { + title: resource.title, + options: resource.options, + viewName: resource.viewName, + sleep, + }); + + this.windows = [...this.windows, window]; + this.editorWindowMap.set(window.id, window); + if (sleep) { + this.emitChangeWindow(); + return; + } + this.window = window; + await this.window.init(); + this.emitChangeWindow(); + this.emitChangeActiveWindow(); + this.window?.updateState(WINDOW_STATE.active); + } + async openEditorWindow(name: string, title: string, options: Object, viewName?: string, sleep?: boolean) { if (this.window && !this.window?.initReady && !sleep) { this.windowQueue.push({ From 5a4e43a7d7c031985c14b75bc7adde077b8def76 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 21 Aug 2023 11:43:07 +0800 Subject: [PATCH 106/361] chore(docs): publish docs 1.1.5 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index c454117331..998d9daf9c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.4", + "version": "1.1.5", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From b4c20b181fb19827a6f5c5492a3a6cc804fe74d4 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 21 Aug 2023 15:00:57 +0800 Subject: [PATCH 107/361] fix: logger is not defined error in transformStringToFunction --- packages/editor-skeleton/src/transducers/parse-func.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor-skeleton/src/transducers/parse-func.ts b/packages/editor-skeleton/src/transducers/parse-func.ts index b253103504..bc52deec35 100644 --- a/packages/editor-skeleton/src/transducers/parse-func.ts +++ b/packages/editor-skeleton/src/transducers/parse-func.ts @@ -26,7 +26,7 @@ function transformStringToFunction(str: string) { try { return (${str}).apply(self, arguments); } catch(e) { - logger.warn('call function which parsed by lowcode failed: ', e); + console.warn('call function which parsed by lowcode failed: ', e); return e.message; } }; From 14d294c92c662d00350e87d8cf6ec57beee325f6 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 22 Aug 2023 17:59:35 +0800 Subject: [PATCH 108/361] feat: when field rendering error, output error log --- .../src/components/field/fields.tsx | 22 ++++++++++++++----- packages/types/src/shell/model/resource.ts | 2 +- .../types/src/shell/type/resource-list.ts | 7 +++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/editor-skeleton/src/components/field/fields.tsx b/packages/editor-skeleton/src/components/field/fields.tsx index 84ac56f48b..b773995e3a 100644 --- a/packages/editor-skeleton/src/components/field/fields.tsx +++ b/packages/editor-skeleton/src/components/field/fields.tsx @@ -1,5 +1,5 @@ /* eslint-disable react/no-unused-prop-types */ -import { Component, MouseEvent } from 'react'; +import { Component, ErrorInfo, MouseEvent } from 'react'; import { isObject } from 'lodash'; import classNames from 'classnames'; import { Icon } from '@alifd/next'; @@ -9,6 +9,9 @@ import { PopupPipe, PopupContext } from '../popup'; import './index.less'; import InlineTip from './inlinetip'; import { intl } from '../../locale'; +import { Logger } from '@alilc/lowcode-utils'; + +const logger = new Logger({ level: 'warn', bizName: 'skeleton:field' }); export interface FieldProps { className?: string; @@ -31,6 +34,10 @@ export class Field extends Component<FieldProps> { hasError: false, }; + private body: HTMLDivElement | null = null; + + private dispose?: () => void; + constructor(props: any) { super(props); this.handleClear = this.handleClear.bind(this); @@ -47,10 +54,6 @@ export class Field extends Component<FieldProps> { onExpandChange && onExpandChange(!collapsed); }; - private body: HTMLDivElement | null = null; - - private dispose?: () => void; - private deployBlockTesting() { if (this.dispose) { this.dispose(); @@ -101,7 +104,13 @@ export class Field extends Component<FieldProps> { } static getDerivedStateFromError() { - return { hasError: true }; + return { + hasError: true, + }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + logger.error(`${this.props.title} has error`, error, errorInfo); } getTipContent(propName: string, tip?: any): any { @@ -194,6 +203,7 @@ export class Field extends Component<FieldProps> { */ function createValueState(/* valueState?: number, onClear?: (e: React.MouseEvent) => void */) { return null; + /* let tip: any = null; let className = 'lc-valuestate'; diff --git a/packages/types/src/shell/model/resource.ts b/packages/types/src/shell/model/resource.ts index b79b6acfcc..acd7d056f5 100644 --- a/packages/types/src/shell/model/resource.ts +++ b/packages/types/src/shell/model/resource.ts @@ -24,7 +24,7 @@ export interface IBaseModelResource< get description(): string | undefined; get config(): { - disableBehaviors?: ('copy' | 'remove')[]; + [key: string]: any; } | undefined; } diff --git a/packages/types/src/shell/type/resource-list.ts b/packages/types/src/shell/type/resource-list.ts index ec998a95be..1d7c34232a 100644 --- a/packages/types/src/shell/type/resource-list.ts +++ b/packages/types/src/shell/type/resource-list.ts @@ -5,6 +5,11 @@ export interface IPublicResourceData { /** 资源名字 */ resourceName: string; + /** 资源扩展配置 */ + config?: { + [key: string]: any; + }; + /** 资源标题 */ title?: string; @@ -20,7 +25,7 @@ export interface IPublicResourceData { /** 资源 icon */ icon?: ReactElement; - /** 资源其他配置 */ + /** 资源其他配置,资源初始化时的第二个参数 */ options: { [key: string]: any; }; From 547bbf4ddc0377c15f3e348d49d86eaa49de17ca Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 23 Aug 2023 14:20:08 +0800 Subject: [PATCH 109/361] feat(workspace): update removeEditorWindow api --- docs/docs/api/workspace.md | 9 +++++++++ packages/shell/src/api/workspace.ts | 8 ++++++-- packages/types/src/shell/api/workspace.ts | 10 +++++++++- packages/workspace/src/workspace.ts | 21 +++++++++++++++++++-- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 5e0f7acd2f..3c13b00aa0 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -107,7 +107,16 @@ openEditorWindowById(id: string): void; 移除视图窗口 ```typescript +/** + * 移除视图窗口 + * @deprecated + */ removeEditorWindow(resourceName: string, id: string): void; + +/** + * 移除视图窗口 + */ +removeEditorWindow(resource: Resource): void; ``` ### removeEditorWindowById diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index b19638ec76..8737e37bd7 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -76,8 +76,12 @@ export class Workspace implements IPublicApiWorkspace { this[workspaceSymbol].openEditorWindowById(id); } - removeEditorWindow(resourceName: string, id: string) { - this[workspaceSymbol].removeEditorWindow(resourceName, id); + removeEditorWindow() { + if (typeof arguments[0] === 'string') { + this[workspaceSymbol].removeEditorWindow(arguments[0], arguments[1]); + } else { + this[workspaceSymbol].removeEditorWindowByResource(arguments[0]?.[resourceSymbol]); + } } removeEditorWindowById(id: string) { diff --git a/packages/types/src/shell/api/workspace.ts b/packages/types/src/shell/api/workspace.ts index d4232d9a14..9e1080b31e 100644 --- a/packages/types/src/shell/api/workspace.ts +++ b/packages/types/src/shell/api/workspace.ts @@ -42,9 +42,17 @@ export interface IPublicApiWorkspace< /** 通过视图 id 打开窗口 */ openEditorWindowById(id: string): void; - /** 移除视图窗口 */ + /** + * 移除视图窗口 + * @deprecated + */ removeEditorWindow(resourceName: string, id: string): void; + /** + * 移除视图窗口 + */ + removeEditorWindow(resource: Resource): void; + /** 通过视图 id 移除窗口 */ removeEditorWindowById(id: string): void; diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 50255b7dbf..22eb9ede2b 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -22,7 +22,7 @@ const CHANGE_EVENT = 'resource.list.change'; export interface IWorkspace extends Omit<IPublicApiWorkspace< LowCodePluginManager, IEditorWindow ->, 'resourceList' | 'plugins'> { +>, 'resourceList' | 'plugins' | 'openEditorWindow' | 'removeEditorWindow'> { readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<IPublicTypeDisposable>; readonly shellModelFactory: IShellModelFactory; @@ -52,6 +52,18 @@ export interface IWorkspace extends Omit<IPublicApiWorkspace< emitChangeActiveEditorView(): void; openEditorWindowByResource(resource: IResource, sleep: boolean): Promise<void>; + + /** + * @deprecated + */ + removeEditorWindow(resourceName: string, id: string): void; + + removeEditorWindowByResource(resource: IResource): void; + + /** + * @deprecated + */ + openEditorWindow(name: string, title: string, options: Object, viewName?: string, sleep?: boolean): Promise<void>; } export class Workspace implements IWorkspace { @@ -213,7 +225,12 @@ export class Workspace implements IWorkspace { } removeEditorWindow(resourceName: string, id: string) { - const index = this.windows.findIndex(d => (d.resource?.name === resourceName && d.title === id)); + const index = this.windows.findIndex(d => (d.resource?.name === resourceName && (d.title === id || d.resource.id === id))); + this.remove(index); + } + + removeEditorWindowByResource(resource: IResource) { + const index = this.windows.findIndex(d => (d.resource?.id === resource.id)); this.remove(index); } From 58628c583bf26bde2fcc4d70dae45cf6067a4a16 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Wed, 23 Aug 2023 15:10:09 +0800 Subject: [PATCH 110/361] chore(docs): publish docs 1.1.6 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 998d9daf9c..e7d3311853 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.5", + "version": "1.1.6", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 379d51d61ffb75eab4889316e82ceb2f7cd353bc 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?= <liujup@foxmail.com> Date: Thu, 24 Aug 2023 17:34:07 +0800 Subject: [PATCH 111/361] docs: update configOptions.md --- docs/docs/api/configOptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index 3f8e75df29..cc606a91ee 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -179,7 +179,7 @@ config.set('enableCondition', false) `@type {boolean}` `@default {false}` -鼠标事件在画布中是否允许冒泡 +鼠标事件(mouseover、mouseleave、mousemove)在画布中是否允许冒泡,默认不允许。 #### enableReactiveContainer From f9898d483c8dd078565f444dbfb92376aa3a8ba5 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?= <liujup@foxmail.com> Date: Thu, 24 Aug 2023 17:29:29 +0800 Subject: [PATCH 112/361] docs: update configOptions.md --- docs/docs/api/configOptions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index cc606a91ee..4127576569 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -126,7 +126,7 @@ config.set('enableCondition', false) #### customizeIgnoreSelectors - 点击忽略 -定制画布中点击被忽略的 selectors +配置画布中,需要屏蔽点击事件的元素,即配置的元素默认点击行为均不生效。 类型定义: From 0da46fffb7fc99c2f4703eee9bfbf72be729e6ab Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 24 Aug 2023 17:44:16 +0800 Subject: [PATCH 113/361] chore(docs): publish docs 1.1.7 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index e7d3311853..012ef49d04 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.6", + "version": "1.1.7", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From bf980c98ea62eb969af29cfc810f497c3f772509 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 25 Aug 2023 11:29:01 +0800 Subject: [PATCH 114/361] chore(release): publish 1.1.10 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 9d3eb758a1..0bb34d1aee 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.1.9", + "version": "1.1.10", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 0b2178c3b8..274d266fc0 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.1.9", + "version": "1.1.10", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -16,9 +16,9 @@ "license": "MIT", "dependencies": { "@alilc/build-plugin-lce": "^0.0.4-beta.2", - "@alilc/lowcode-editor-core": "1.1.9", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-editor-core": "1.1.10", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 58e8eb4814..e05002469e 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.1.9", + "version": "1.1.10", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index b1802795dd..2c8efccebf 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.1.9", + "version": "1.1.10", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-editor-core": "1.1.9", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-editor-core": "1.1.10", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 4d5e4681f6..a9521d486b 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.1.9", + "version": "1.1.10", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-editor-core": "1.1.9", - "@alilc/lowcode-editor-skeleton": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-editor-core": "1.1.10", + "@alilc/lowcode-editor-skeleton": "1.1.10", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.1.9", - "@alilc/lowcode-plugin-outline-pane": "1.1.9", - "@alilc/lowcode-shell": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", - "@alilc/lowcode-workspace": "1.1.9", + "@alilc/lowcode-plugin-designer": "1.1.10", + "@alilc/lowcode-plugin-outline-pane": "1.1.10", + "@alilc/lowcode-shell": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-workspace": "1.1.10", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 4064e585bf..116f98e5d5 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.1.9", + "version": "1.1.10", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 16905f6159..760d57a133 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.1.9", + "version": "1.1.10", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-editor-core": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-editor-core": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index c49e11c2ef..4a71eb26b8 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.1.9", + "version": "1.1.10", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index ddd160f004..90a9b7e08e 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.1.9", + "version": "1.1.10", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-renderer-core": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index d2c39c0c81..8ff7f1f0a4 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.1.9", + "version": "1.1.10", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-rax-renderer": "1.1.9", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-rax-renderer": "1.1.10", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 410d24a6bf..1535cb2088 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.1.9", + "version": "1.1.10", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.1.9" + "@alilc/lowcode-renderer-core": "1.1.10" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 8fb1e979b3..ffb8228dfd 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.1.9", + "version": "1.1.10", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-react-renderer": "1.1.9", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-react-renderer": "1.1.10", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 49c9d30fe5..52b13b86c6 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.1.9", + "version": "1.1.10", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index c9663e4a77..09768a06a7 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.1.9", + "version": "1.1.10", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-editor-core": "1.1.9", - "@alilc/lowcode-editor-skeleton": "1.1.9", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", - "@alilc/lowcode-workspace": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-editor-core": "1.1.10", + "@alilc/lowcode-editor-skeleton": "1.1.10", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-workspace": "1.1.10", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 317fbbeb73..fe9cd51235 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.1.9", + "version": "1.1.10", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index dcc1ccdd21..ecf6bff3c0 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.1.9", + "version": "1.1.10", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.9", + "@alilc/lowcode-types": "1.1.10", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 36e8dac0f1..8802691d60 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.1.9", + "version": "1.1.10", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.9", - "@alilc/lowcode-editor-core": "1.1.9", - "@alilc/lowcode-editor-skeleton": "1.1.9", - "@alilc/lowcode-types": "1.1.9", - "@alilc/lowcode-utils": "1.1.9", + "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-editor-core": "1.1.10", + "@alilc/lowcode-editor-skeleton": "1.1.10", + "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-utils": "1.1.10", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From e3842b05310010ac0d4899e524b7932b4948d337 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 25 Aug 2023 16:43:16 +0800 Subject: [PATCH 115/361] feat: add editorCabinSymbol and skeletonCabinSymbol --- packages/engine/src/modules/symbols.ts | 4 +++ packages/shell/src/api/common.tsx | 49 +++++++++++++++++++++++++- packages/shell/src/symbols.ts | 2 ++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/modules/symbols.ts b/packages/engine/src/modules/symbols.ts index a0371abf98..435e8cbc2c 100644 --- a/packages/engine/src/modules/symbols.ts +++ b/packages/engine/src/modules/symbols.ts @@ -12,6 +12,8 @@ import { propSymbol, simulatorHostSymbol, skeletonItemSymbol, + editorCabinSymbol, + skeletonCabinSymbol, } from '@alilc/lowcode-shell'; export default { @@ -25,6 +27,8 @@ export default { settingPropEntrySymbol: settingFieldSymbol, settingTopEntrySymbol, designerCabinSymbol, + editorCabinSymbol, + skeletonCabinSymbol, propSymbol, simulatorHostSymbol, skeletonItemSymbol, diff --git a/packages/shell/src/api/common.tsx b/packages/shell/src/api/common.tsx index 9f38cf1091..3c2d2e5cce 100644 --- a/packages/shell/src/api/common.tsx +++ b/packages/shell/src/api/common.tsx @@ -1,4 +1,4 @@ -import { editorSymbol, skeletonSymbol, designerCabinSymbol, designerSymbol, settingFieldSymbol } from '../symbols'; +import { editorSymbol, skeletonSymbol, designerCabinSymbol, designerSymbol, settingFieldSymbol, editorCabinSymbol, skeletonCabinSymbol } from '../symbols'; import { isFormEvent as innerIsFormEvent, compatibleLegaoSchema as innerCompatibleLegaoSchema, @@ -36,6 +36,10 @@ import { getConvertedExtraKey as innerGetConvertedExtraKey, getOriginalExtraKey as innerGetOriginalExtraKey, IDesigner, + DropLocation as InnerDropLocation, + Designer as InnerDesigner, + Node as InnerNode, + LowCodePluginManager as InnerLowCodePluginManager, } from '@alilc/lowcode-designer'; import { Skeleton as InnerSkeleton, @@ -43,6 +47,8 @@ import { PopupContext as InnerPopupContext, PopupPipe as InnerPopupPipe, Workbench as InnerWorkbench, + SettingsPrimaryPane as InnerSettingsPrimaryPane, + registerDefaults as InnerRegisterDefaults, } from '@alilc/lowcode-editor-skeleton'; import { Editor, @@ -61,6 +67,7 @@ import { action as innerAction, runInAction as innerRunInAction, engineConfig as innerEngineConfig, + globalContext, } from '@alilc/lowcode-editor-core'; import { Dragon as ShellDragon } from '../model'; import { ReactNode } from 'react'; @@ -94,6 +101,10 @@ class DesignerCabin implements IPublicApiCommonDesignerCabin { DragObjectType: InnerDragObjectType, isDragNodeDataObject: innerIsDragNodeDataObject, isNode: innerIsNode, + DropLocation: InnerDropLocation, + Designer: InnerDesigner, + Node: InnerNode, + LowCodePluginManager: InnerLowCodePluginManager, }; } @@ -160,8 +171,19 @@ class DesignerCabin implements IPublicApiCommonDesignerCabin { class SkeletonCabin implements IPublicApiCommonSkeletonCabin { private readonly [skeletonSymbol]: InnerSkeleton; + readonly [skeletonCabinSymbol]: any; + constructor(skeleton: InnerSkeleton) { this[skeletonSymbol] = skeleton; + this[skeletonCabinSymbol] = { + Workbench: this.Workbench, + createSettingFieldView: this.createSettingFieldView, + PopupContext: InnerPopupContext, + PopupPipe: InnerPopupPipe, + SettingsPrimaryPane: InnerSettingsPrimaryPane, + registerDefaults: InnerRegisterDefaults, + Skeleton: InnerSkeleton, + }; } get Workbench(): any { @@ -242,8 +264,33 @@ class Utils implements IPublicApiCommonUtils { class EditorCabin implements IPublicApiCommonEditorCabin { private readonly [editorSymbol]: Editor; + /** + * @deprecated + */ + readonly [editorCabinSymbol]: any; + constructor(editor: Editor) { this[editorSymbol] = editor; + this[editorCabinSymbol] = { + Editor, + globalContext, + runInAction: innerRunInAction, + Title: InnerTitle, + Tip: InnerTip, + shallowIntl: innerShallowIntl, + createIntl: innerCreateIntl, + intl: innerIntl, + createSetterContent: this.createSetterContent.bind(this), + globalLocale: innerGlobalLocale, + obx: innerObx, + action: innerAction, + engineConfig: innerEngineConfig, + observable: innerObservable, + makeObservable: innerMakeObservable, + untracked: innerUntracked, + computed: innerComputed, + observer: innerObserver, + }; } /** diff --git a/packages/shell/src/symbols.ts b/packages/shell/src/symbols.ts index b4ec01c7ec..cc1be48560 100644 --- a/packages/shell/src/symbols.ts +++ b/packages/shell/src/symbols.ts @@ -24,6 +24,8 @@ export const simulatorHostSymbol = Symbol('simulatorHost'); export const dragObjectSymbol = Symbol('dragObject'); export const locateEventSymbol = Symbol('locateEvent'); export const designerCabinSymbol = Symbol('designerCabin'); +export const editorCabinSymbol = Symbol('editorCabin'); +export const skeletonCabinSymbol = Symbol('skeletonCabin'); export const hotkeySymbol = Symbol('hotkey'); export const pluginsSymbol = Symbol('plugins'); export const workspaceSymbol = Symbol('workspace'); From 857685a3b412c0155a22f1da4c0a95138544df0b Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 28 Aug 2023 16:54:11 +0800 Subject: [PATCH 116/361] feat(node): add getRGL api --- docs/docs/api/model/node.md | 18 ++++++++ packages/designer/src/component-actions.ts | 47 ++++++++++----------- packages/designer/src/document/node/node.ts | 2 +- packages/shell/src/model/node.ts | 20 +++++++++ packages/types/src/shell/model/node.ts | 12 ++++++ 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/docs/docs/api/model/node.md b/docs/docs/api/model/node.md index c10af34660..697eefd088 100644 --- a/docs/docs/api/model/node.md +++ b/docs/docs/api/model/node.md @@ -657,4 +657,22 @@ setConditionalVisible(): void; */ getDOMNode(): HTMLElement; +``` + +### getRGL + +获取磁贴相关信息 + +```typescript +/** + * 获取磁贴相关信息 + */ +getRGL(): { + isContainerNode: boolean; + isEmptyNode: boolean; + isRGLContainerNode: boolean; + isRGLNode: boolean; + isRGL: boolean; + rglNode: Node | null; +} ``` \ No newline at end of file diff --git a/packages/designer/src/component-actions.ts b/packages/designer/src/component-actions.ts index a7a690a44d..76ead7d9a6 100644 --- a/packages/designer/src/component-actions.ts +++ b/packages/designer/src/component-actions.ts @@ -1,4 +1,4 @@ -import { IPublicTypeComponentAction, IPublicTypeMetadataTransducer } from '@alilc/lowcode-types'; +import { IPublicModelNode, IPublicTypeComponentAction, IPublicTypeMetadataTransducer } from '@alilc/lowcode-types'; import { engineConfig } from '@alilc/lowcode-editor-core'; import { intlNode } from './locale'; import { @@ -8,10 +8,11 @@ import { IconClone, IconHidden, } from './icons'; -import { Node } from './document'; import { componentDefaults, legacyIssues } from './transducers'; export class ComponentActions { + private metadataTransducers: IPublicTypeMetadataTransducer[] = []; + actions: IPublicTypeComponentAction[] = [ { name: 'remove', @@ -19,7 +20,7 @@ export class ComponentActions { icon: IconRemove, title: intlNode('remove'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { node.remove(); }, }, @@ -31,13 +32,13 @@ export class ComponentActions { icon: IconHidden, title: intlNode('hide'), /* istanbul ignore next */ - action(node: Node) { - node.setVisible(false); + action(node: IPublicModelNode) { + node.visible = false; }, }, /* istanbul ignore next */ - condition: (node: Node) => { - return node.componentMeta.isModal; + condition: (node: IPublicModelNode) => { + return node.componentMeta?.isModal; }, important: true, }, @@ -47,25 +48,25 @@ export class ComponentActions { icon: IconClone, title: intlNode('copy'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { // node.remove(); const { document: doc, parent, index } = node; if (parent) { - const newNode = doc.insertNode(parent, node, index + 1, true); - newNode.select(); - const { isRGL, rglNode } = node.getRGL(); + const newNode = doc?.insertNode(parent, node, (index ?? 0) + 1, true); + newNode?.select(); + const { isRGL, rglNode } = node?.getRGL(); if (isRGL) { // 复制 layout 信息 - const layout = rglNode.getPropValue('layout') || []; - const curLayout = layout.filter((item) => item.i === node.getPropValue('fieldId')); + const layout: any = rglNode?.getPropValue('layout') || []; + const curLayout = layout.filter((item: any) => item.i === node.getPropValue('fieldId')); if (curLayout && curLayout[0]) { layout.push({ ...curLayout[0], - i: newNode.getPropValue('fieldId'), + i: newNode?.getPropValue('fieldId'), }); - rglNode.setPropValue('layout', layout); + rglNode?.setPropValue('layout', layout); // 如果是磁贴块复制,则需要滚动到影响位置 - setTimeout(() => newNode.document.simulator?.scrollToNode(newNode), 10); + setTimeout(() => newNode?.document?.project?.simulatorHost?.scrollToNode(newNode), 10); } } } @@ -79,13 +80,13 @@ export class ComponentActions { icon: IconLock, // 锁定 icon title: intlNode('lock'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { node.lock(); }, }, /* istanbul ignore next */ - condition: (node: Node) => { - return engineConfig.get('enableCanvasLock', false) && node.isContainer() && !node.isLocked; + condition: (node: IPublicModelNode) => { + return engineConfig.get('enableCanvasLock', false) && node.isContainerNode && !node.isLocked; }, important: true, }, @@ -95,13 +96,13 @@ export class ComponentActions { icon: IconUnlock, // 解锁 icon title: intlNode('unlock'), /* istanbul ignore next */ - action(node: Node) { + action(node: IPublicModelNode) { node.lock(false); }, }, /* istanbul ignore next */ - condition: (node: Node) => { - return engineConfig.get('enableCanvasLock', false) && node.isContainer() && node.isLocked; + condition: (node: IPublicModelNode) => { + return engineConfig.get('enableCanvasLock', false) && node.isContainerNode && node.isLocked; }, important: true, }, @@ -132,8 +133,6 @@ export class ComponentActions { } } - private metadataTransducers: IPublicTypeMetadataTransducer[] = []; - registerMetadataTransducer( transducer: IPublicTypeMetadataTransducer, level = 100, diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index b0e509bce8..9effc341dd 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -1225,7 +1225,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> const isRGLContainerNode = this.isRGLContainer; const isRGLNode = this.getParent()?.isRGLContainer; const isRGL = isRGLContainerNode || (isRGLNode && (!isContainerNode || !isEmptyNode)); - let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : {}; + let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null; return { isContainerNode, isEmptyNode, isRGLContainerNode, isRGLNode, isRGL, rglNode }; } diff --git a/packages/shell/src/model/node.ts b/packages/shell/src/model/node.ts index f2cddd1ab8..29d24232eb 100644 --- a/packages/shell/src/model/node.ts +++ b/packages/shell/src/model/node.ts @@ -655,4 +655,24 @@ export class Node implements IPublicModelNode { setConditionalVisible(): void { this[nodeSymbol].setConditionalVisible(); } + + getRGL() { + const { + isContainerNode, + isEmptyNode, + isRGLContainerNode, + isRGLNode, + isRGL, + rglNode, + } = this[nodeSymbol].getRGL(); + + return { + isContainerNode, + isEmptyNode, + isRGLContainerNode, + isRGLNode, + isRGL, + rglNode: Node.create(rglNode), + }; + } } diff --git a/packages/types/src/shell/model/node.ts b/packages/types/src/shell/model/node.ts index 0255376aec..9d8cec3647 100644 --- a/packages/types/src/shell/model/node.ts +++ b/packages/types/src/shell/model/node.ts @@ -490,6 +490,18 @@ export interface IBaseModelNode< * 获取节点实例对应的 dom 节点 */ getDOMNode(): HTMLElement; + + /** + * 获取磁贴相关信息 + */ + getRGL(): { + isContainerNode: boolean; + isEmptyNode: boolean; + isRGLContainerNode: boolean; + isRGLNode: boolean; + isRGL: boolean; + rglNode: Node | null; + }; } export interface IPublicModelNode extends IBaseModelNode<IPublicModelDocumentModel, IPublicModelNode> {} \ No newline at end of file From dc0cf5f62c7671d6743d225fac63691f58027009 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 28 Aug 2023 15:51:50 +0800 Subject: [PATCH 117/361] fix: fix utils under appHelper will not be updated when props.appHelper is updated --- packages/renderer-core/src/renderer/base.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 99a9a40cfa..89dc143d5f 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -131,7 +131,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { static contextType = AppContext; - appHelper?: IRendererAppHelper; i18n: any; getLocale: any; setLocale: any; @@ -174,7 +173,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { __beforeInit(_props: IBaseRendererProps) { } __init(props: IBaseRendererProps) { - this.appHelper = props.__appHelper; this.__compScopes = {}; this.__instanceMap = {}; this.__bindCustomMethods(props); @@ -1019,6 +1017,10 @@ export default function baseRendererFactory(): IBaseRenderComponent { return !isSchema(schema) || !componentNames.includes(schema?.componentName ?? ''); }; + get appHelper(): IRendererAppHelper { + return this.props.__appHelper; + } + get requestHandlersMap() { return this.appHelper?.requestHandlersMap; } From a3b9d6ff48995e5580fe42b2507388a2e3ae03e2 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 29 Aug 2023 14:17:42 +0800 Subject: [PATCH 118/361] fix(outline-pane): when dialog is dragged, the outline pane is not displayed visible state --- packages/plugin-outline-pane/src/views/tree-title.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 02ac94ae69..c8c0e75b09 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -83,6 +83,7 @@ export default class TreeTitle extends PureComponent<{ editing: false, title: treeNode.titleLabel, condition: treeNode.condition, + visible: !treeNode.hidden, }); treeNode.onTitleLabelChanged(() => { this.setState({ From 1d572ccc0b42bd7771b7503058fdfe729f814cf6 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 31 Aug 2023 17:15:40 +0800 Subject: [PATCH 119/361] style: udpate some style for multi theme --- packages/designer/src/project/project.less | 2 +- .../editor-core/src/widgets/tip/style.less | 2 +- .../src/components/settings/style.less | 1 - packages/editor-skeleton/src/index.ts | 1 + packages/editor-skeleton/src/layouts/index.ts | 7 + .../editor-skeleton/src/layouts/left-area.tsx | 7 +- .../src/layouts/sub-top-area.tsx | 0 .../editor-skeleton/src/layouts/theme.less | 2 + .../src/layouts/workbench.less | 136 ++++-- .../plugin-outline-pane/src/views/style.less | 6 +- .../workspace/src/layouts/bottom-area.tsx | 34 -- packages/workspace/src/layouts/left-area.tsx | 50 --- .../workspace/src/layouts/left-fixed-pane.tsx | 42 -- .../workspace/src/layouts/left-float-pane.tsx | 136 ------ packages/workspace/src/layouts/main-area.tsx | 16 - packages/workspace/src/layouts/theme.less | 62 --- packages/workspace/src/layouts/top-area.tsx | 60 --- packages/workspace/src/layouts/workbench.less | 421 ------------------ packages/workspace/src/layouts/workbench.tsx | 22 +- packages/workspace/src/view/resource-view.tsx | 2 +- 20 files changed, 138 insertions(+), 871 deletions(-) create mode 100644 packages/editor-skeleton/src/layouts/index.ts rename packages/{workspace => editor-skeleton}/src/layouts/sub-top-area.tsx (100%) delete mode 100644 packages/workspace/src/layouts/bottom-area.tsx delete mode 100644 packages/workspace/src/layouts/left-area.tsx delete mode 100644 packages/workspace/src/layouts/left-fixed-pane.tsx delete mode 100644 packages/workspace/src/layouts/left-float-pane.tsx delete mode 100644 packages/workspace/src/layouts/main-area.tsx delete mode 100644 packages/workspace/src/layouts/theme.less delete mode 100644 packages/workspace/src/layouts/top-area.tsx delete mode 100644 packages/workspace/src/layouts/workbench.less diff --git a/packages/designer/src/project/project.less b/packages/designer/src/project/project.less index 9d37c73fb4..38f1f74428 100644 --- a/packages/designer/src/project/project.less +++ b/packages/designer/src/project/project.less @@ -14,7 +14,7 @@ } .lc-simulator { - background: rgb(237, 239, 243); + background-color: var(--color-background, rgb(237, 239, 243)); } .lc-simulator-shell { diff --git a/packages/editor-core/src/widgets/tip/style.less b/packages/editor-core/src/widgets/tip/style.less index 3c02e5313e..21b60b9b5d 100644 --- a/packages/editor-core/src/widgets/tip/style.less +++ b/packages/editor-core/src/widgets/tip/style.less @@ -147,7 +147,7 @@ z-index: 2; position: fixed; box-sizing: border-box; - background: rgba(0, 0, 0, 0.7); + background: var(--color-layer-tooltip-background); max-height: 400px; color: var(--color-text-reverse, rgba(255, 255, 255, 0.8)); left: 0; diff --git a/packages/editor-skeleton/src/components/settings/style.less b/packages/editor-skeleton/src/components/settings/style.less index 23b707afd8..57a7c9357f 100644 --- a/packages/editor-skeleton/src/components/settings/style.less +++ b/packages/editor-skeleton/src/components/settings/style.less @@ -143,7 +143,6 @@ .lc-outline-pane { position: absolute; z-index: 100; - background-color: white; top: 0; bottom: 0; display: none; diff --git a/packages/editor-skeleton/src/index.ts b/packages/editor-skeleton/src/index.ts index d4851ff5b0..a39b445d1f 100644 --- a/packages/editor-skeleton/src/index.ts +++ b/packages/editor-skeleton/src/index.ts @@ -8,3 +8,4 @@ export * from './components/popup'; export * from './context'; export * from './register-defaults'; export * from './widget'; +export * from './layouts'; diff --git a/packages/editor-skeleton/src/layouts/index.ts b/packages/editor-skeleton/src/layouts/index.ts new file mode 100644 index 0000000000..b3c7a10580 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/index.ts @@ -0,0 +1,7 @@ +export { default as LeftArea } from './left-area'; +export { default as LeftFloatPane } from './left-float-pane'; +export { default as LeftFixedPane } from './left-fixed-pane'; +export { default as MainArea } from './main-area'; +export { default as BottomArea } from './bottom-area'; +export { default as TopArea } from './top-area'; +export { default as SubTopArea } from './sub-top-area'; \ No newline at end of file diff --git a/packages/editor-skeleton/src/layouts/left-area.tsx b/packages/editor-skeleton/src/layouts/left-area.tsx index cbeba5a5c8..d30dcfa863 100644 --- a/packages/editor-skeleton/src/layouts/left-area.tsx +++ b/packages/editor-skeleton/src/layouts/left-area.tsx @@ -4,14 +4,14 @@ import { observer } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; @observer -export default class LeftArea extends Component<{ area: Area }> { +export default class LeftArea extends Component<{ area: Area; className?: string }> { render() { - const { area } = this.props; + const { area, className = 'lc-left-area' } = this.props; if (area.isEmpty()) { return null; } return ( - <div className={classNames('lc-left-area', { + <div className={classNames(className, { 'lc-area-visible': area.visible, })} > @@ -21,7 +21,6 @@ export default class LeftArea extends Component<{ area: Area }> { } } - @observer class Contents extends Component<{ area: Area }> { render() { diff --git a/packages/workspace/src/layouts/sub-top-area.tsx b/packages/editor-skeleton/src/layouts/sub-top-area.tsx similarity index 100% rename from packages/workspace/src/layouts/sub-top-area.tsx rename to packages/editor-skeleton/src/layouts/sub-top-area.tsx diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index b0da053db1..53afb69328 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -16,6 +16,7 @@ --color-icon-hover: @normal-alpha-3; --color-icon-active: @brand-color-1; --color-icon-reverse: @white-alpha-1; + --color-icon-pane: @dark-alpha-3; --color-line-normal: @normal-alpha-7; --color-line-darken: darken(@normal-alpha-7, 10%); @@ -57,6 +58,7 @@ --color-block-background-deep-dark: @normal-5; --color-layer-mask-background: @dark-alpha-7; --color-layer-tooltip-background: rgba(44,47,51,0.8); + --color-background: #edeff3; --pane-title-bg-color: rgba(31,56,88,.04); } diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index fccdad4c2d..0a034822f4 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -38,7 +38,7 @@ body { font-family: var(--font-family); font-size: var(--font-size-text); color: var(--color-text); - background-color: #edeff3; + background-color: var(--color-background); } * { @@ -49,13 +49,10 @@ body { width: 100%; height: 100%; position: relative; - background-color: #fff; - background-color: var(--color-pane-background); &.hidden { display: none; } .lc-panel-title { - // background-color: var(--pane-title-bg-color,rgba(31,56,88,.04)); display: flex; align-items: center; justify-content: flex-start; @@ -71,7 +68,6 @@ body { height: 48px; font-size: 16px; padding: 0 15px; - // border-bottom: 1px solid var(--color-line-normal,rgba(31,56,88,.1)); color: #0f1726; font-weight: bold; } @@ -125,9 +121,6 @@ body { height: 100%; width: 100%; position: relative; - background-color: #fff; - background-color: var(--color-pane-background); - // overflow: auto; &.hidden { display: none; } @@ -137,7 +130,7 @@ body { height: 100%; display: flex; flex-direction: column; - background-color: #edeff3; + background-color: var(--color-background); position: absolute; left: 0; top: 0; @@ -164,47 +157,58 @@ body { &.active { z-index: 999; - background: #edeff3; + background: var(--color-background); } } } -.lc-workbench { +.lc-workbench, .lc-workspace-workbench { height: 100%; display: flex; flex-direction: column; - background-color: #edeff3; + background-color: var(--color-background); &.engine-main { height: 100%; display: flex; flex-direction: column; - background-color: #edeff3; + background-color: var(--color-background); } - .lc-top-area { - height: var(--top-area-height); - background-color: var(--color-pane-background); + .lc-top-area, .lc-sub-top-area { width: 100%; display: none; margin-bottom: 2px; padding: 8px 12px 8px 16px; + &.lc-top-area { + background-color: var(--color-top-area-background, var(--color-pane-background)); + height: var(--top-area-height); + } + + &.lc-sub-top-area { + background-color: var(--color-sub-top-area-background, var(--color-pane-background)); + height: var(--sub-top-area-height, var(--top-area-height)); + margin: var(--sub-top-area-margin, 0px 0px 2px 0px); + padding: var(--sub-top-area-padding, 8px 12px 8px 16px); + } + &.lc-area-visible { display: flex; } - .lc-top-area-left { + .lc-top-area-left, .lc-sub-top-area-left { display: flex; align-items: center; + max-width: 100%; } - .lc-top-area-center { + .lc-top-area-center, .lc-sub-top-area-center { flex: 1; display: flex; justify-content: center; margin: 0 8px; } - .lc-top-area-right { + .lc-top-area-right, .lc-sub-top-area-right { display: flex; align-items: center; > * { @@ -216,7 +220,7 @@ body { } } } - .lc-workbench-body { + .lc-workbench-body, .lc-workspace-workbench-body { flex: 1; display: flex; min-height: 0; @@ -264,7 +268,7 @@ body { z-index: 2; .next-icon { line-height: 1; - color: rgba(0, 0, 0, 0.6); + color: var(--color-icon-pane); } } @@ -277,7 +281,7 @@ body { z-index: 2; svg { vertical-align: middle; - color: rgba(0, 0, 0, 0.6); + color: var(--color-icon-pane); } } @@ -288,7 +292,7 @@ body { width: var(--dock-pane-width); // min-width: var(--dock-fixed-pane-width); left: calc(var(--left-area-width) + 1px); - background-color: var(--color-pane-background); + background-color: var(--color-left-float-pane-background, var(--color-pane-background)); box-shadow: 4px 6px 6px 0 rgba(31, 50, 88, 0.08); z-index: 820; display: none; @@ -297,15 +301,20 @@ body { display: block; } } - .lc-left-area { + .lc-left-area, .lc-workspace-left-area { height: 100%; width: var(--left-area-width); - background-color: var(--color-pane-background); display: none; flex-shrink: 0; flex-direction: column; justify-content: space-between; overflow: hidden; + &.lc-left-area { + background-color: var(--color-left-area-background, var(--color-pane-background)); + } + &.lc-workspace-left-area { + background-color: var(--color-workspace-left-area-background, var(--color-pane-background)); + } &.lc-area-visible { display: flex; } @@ -316,6 +325,8 @@ body { flex-direction: column; justify-content: flex-start; align-items: center; + color: var(--color-text); + .lc-title { flex-direction: column; width: calc(var(--left-area-width) - 2px); @@ -325,6 +336,9 @@ body { justify-content: center; cursor: pointer; + &.has-tip { + cursor: pointer; + } &.actived { color: #0079f2; } @@ -366,6 +380,9 @@ body { .lc-left-area.lc-area-visible ~ .lc-workbench-center { margin-left: 2px; } + .lc-workspace-left-area.lc-area-visible ~ .lc-workspace-workbench-center { + margin-left: 2px; + } .lc-outline-pane { .lc-outline-tree .tree-node .tree-node-title { border-bottom: none; @@ -390,7 +407,7 @@ body { } .lc-main-area { flex: 1; - background-color: #edeff3; + background-color: var(--color-background); } .lc-bottom-area { height: var(--bottom-area-height); @@ -404,13 +421,14 @@ body { .lc-right-area { height: 100%; width: var(--right-area-width); - background-color: var(--color-pane-background); + background-color: var(--color-right-area-background, var(--color-pane-background)); display: none; flex-shrink: 0; margin-left: 2px; position: relative; > .lc-panel { position: absolute; + background-color: var(--color-right-area-background, var(--color-pane-background, #fff)); left: 0; top: 0; } @@ -437,4 +455,68 @@ body { } } } + .engine-actionitem { + max-width: 100%; + color: var(--color-text); + } +} + +.lc-workspace-workbench { + height: 100%; + display: flex; + flex-direction: column; + background-color: var(--color-background); + .lc-workspace-workbench-body { + flex: 1; + display: flex; + min-height: 0; + position: relative; + + .lc-workspace-workbench-center { + flex: 1; + display: flex; + flex-direction: column; + z-index: 10; + position: relative; + .lc-toolbar { + display: flex; + height: var(--toolbar-height); + background-color: var(--color-pane-background); + padding: 8px 16px; + .lc-toolbar-center { + display: flex; + justify-content: center; + align-items: center; + flex: 1; + } + } + .lc-main-area { + flex: 1; + } + .lc-bottom-area { + height: var(--bottom-area-height); + background-color: var(--color-pane-background); + display: none; + &.lc-area-visible { + display: block; + } + } + } + + .lc-workspace-workbench-center-content { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + flex-direction: column; + display: flex; + align-content: stretch; + } + + .lc-workspace-workbench-window { + position: relative; + height: 100%; + } + } } diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index 254b639d62..406a5b5da4 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -3,7 +3,6 @@ width: 100%; position: relative; z-index: 200; - background-color: white; > .lc-outline-tree-container { top: 52px; @@ -29,8 +28,8 @@ } .lc-outline-filter-icon { - background: #ebecf0; - border: 1px solid #c4c6cf; + background: var(--color-block-background-shallow, #ebecf0); + border: 1px solid var(--color-field-border, #c4c6cf); display: flex; align-items: center; border-radius: 0 2px 2px 0; @@ -245,7 +244,6 @@ .tree-node-title { font-size: var(--font-size-text); cursor: pointer; - background: var(--color-pane-background); border-bottom: 1px solid var(--color-line-normal, rgba(31, 56, 88, 0.1)); display: flex; align-items: center; diff --git a/packages/workspace/src/layouts/bottom-area.tsx b/packages/workspace/src/layouts/bottom-area.tsx deleted file mode 100644 index 5fc4d815bc..0000000000 --- a/packages/workspace/src/layouts/bottom-area.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area, Panel } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class BottomArea extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - if (area.isEmpty()) { - return null; - } - return ( - <div className={classNames('lc-bottom-area', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((item) => item.content)} - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/left-area.tsx b/packages/workspace/src/layouts/left-area.tsx deleted file mode 100644 index 3057386eda..0000000000 --- a/packages/workspace/src/layouts/left-area.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class LeftArea extends Component<{ area: Area }> { - render() { - const { area } = this.props; - if (area.isEmpty()) { - return null; - } - return ( - <div className={classNames('lc-left-area', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} /> - </div> - ); - } -} - - -@observer -class Contents extends Component<{ area: Area }> { - render() { - const { area } = this.props; - const top: any[] = []; - const bottom: any[] = []; - area.container.items.slice().sort((a, b) => { - const index1 = a.config?.index || 0; - const index2 = b.config?.index || 0; - return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); - }).forEach((item) => { - const content = <div key={`left-area-${item.name}`}>{item.content}</div>; - if (item.align === 'bottom') { - bottom.push(content); - } else { - top.push(content); - } - }); - return ( - <Fragment> - <div className="lc-left-area-top">{top}</div> - <div className="lc-left-area-bottom">{bottom}</div> - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/left-fixed-pane.tsx b/packages/workspace/src/layouts/left-fixed-pane.tsx deleted file mode 100644 index e0c01c5109..0000000000 --- a/packages/workspace/src/layouts/left-fixed-pane.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area, Panel, PanelConfig } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> { - componentDidUpdate() { - // FIXME: dirty fix, need deep think - this.props.area.skeleton.editor.get('designer')?.touchOffsetObserver(); - } - - - render() { - const { area } = this.props; - const width = area.current?.config.props?.width; - const style = width - ? { - width, - } - : undefined; - - return ( - <div - className={classNames('lc-left-fixed-pane', { - 'lc-area-visible': area.visible, - })} - style={style} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<PanelConfig, Panel> }> { - render() { - const { area } = this.props; - return <Fragment>{area.container.items.map((panel) => panel.content)}</Fragment>; - } -} diff --git a/packages/workspace/src/layouts/left-float-pane.tsx b/packages/workspace/src/layouts/left-float-pane.tsx deleted file mode 100644 index 3df3e197c2..0000000000 --- a/packages/workspace/src/layouts/left-float-pane.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer, Focusable } from '@alilc/lowcode-editor-core'; -import { Area, Panel } from '@alilc/lowcode-editor-skeleton'; -import { IPublicApiProject } from '@alilc/lowcode-types'; - -@observer -export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> { - private dispose?: () => void; - - private focusing?: Focusable; - - private shell: HTMLElement | null = null; - - componentDidMount() { - const { area } = this.props; - const triggerClose = (e: any) => { - if (!area.visible) return; - // 当 MouseEvent 的 target 为「插入占位符」时,不关闭当前 panel - if (e.originalEvent?.target?.classList.contains('insertion')) return; - // 假如当前操作 target 祖先节点中有属性 data-keep-visible-while-dragging="true" 代表该 target 所属 panel - // 不希望 target 在 panel 范围内拖拽时关闭 panel - const panelElem = e.originalEvent?.target.closest('div[data-keep-visible-while-dragging="true"]'); - if (panelElem) return; - area.setVisible(false); - }; - area.skeleton.editor.eventBus.on('designer.drag', triggerClose); - - this.dispose = () => { - area.skeleton.editor.removeListener('designer.drag', triggerClose); - }; - - const project: IPublicApiProject | undefined = area.skeleton.editor.get('project'); - - this.focusing = area.skeleton.focusTracker.create({ - range: (e) => { - const target = e.target as HTMLElement; - if (!target) { - return false; - } - if (this.shell?.contains(target)) { - return true; - } - // 点击了 iframe 内容,算失焦 - if ((document.querySelector('.lc-simulator-content-frame') as HTMLIFrameElement)?.contentWindow?.document.documentElement.contains(target)) { - return false; - } - if (project?.simulatorHost?.contentWindow?.document.documentElement.contains(target)) { - return false; - } - // 点击设置区 - if (document.querySelector('.lc-right-area')?.contains(target)) { - return false; - } - // 点击非编辑区域的popup/dialog,插件栏左侧等不触发失焦 - if (!document.querySelector('.lc-workbench')?.contains(target)) { - return true; - } - // 排除设置区,iframe 之后,都不算失焦 - if (document.querySelector('.lc-workbench-body')?.contains(target)) { - return true; - } - const docks = area.current?.getAssocDocks(); - if (docks && docks?.length) { - return docks.some(dock => dock.getDOMNode()?.contains(target)); - } - return false; - }, - onEsc: () => { - this.props.area.setVisible(false); - }, - onBlur: () => { - this.props.area.setVisible(false); - }, - }); - - this.onEffect(); - } - - onEffect() { - const { area } = this.props; - if (area.visible) { - this.focusing?.active(); - // 关闭当前fixed区域的面板 - // TODO: 看看有没有更合适的地方 - const fixedContainer = area?.skeleton?.leftFixedArea?.container; - const currentFixed = fixedContainer?.current; - if (currentFixed) { - fixedContainer.unactive(currentFixed); - } - } else { - this.focusing?.suspense(); - } - } - - componentDidUpdate() { - this.onEffect(); - } - - componentWillUnmount() { - this.focusing?.purge(); - this.dispose?.(); - } - - render() { - const { area } = this.props; - const width = area.current?.config.props?.width; - - const style = width ? { - width, - } : undefined; - return ( - <div - ref={(ref) => { this.shell = ref; }} - className={classNames('lc-left-float-pane', { - 'lc-area-visible': area.visible, - })} - style={style} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((panel) => panel.content)} - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/main-area.tsx b/packages/workspace/src/layouts/main-area.tsx deleted file mode 100644 index 5313d7007e..0000000000 --- a/packages/workspace/src/layouts/main-area.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Component } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area, Panel, Widget } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> { - render() { - const { area } = this.props; - return ( - <div className={classNames('lc-main-area engine-workspacepane')}> - {area.container.items.map((item) => item.content)} - </div> - ); - } -} diff --git a/packages/workspace/src/layouts/theme.less b/packages/workspace/src/layouts/theme.less deleted file mode 100644 index b0da053db1..0000000000 --- a/packages/workspace/src/layouts/theme.less +++ /dev/null @@ -1,62 +0,0 @@ -@import '../less-variables.less'; - -/* - * Theme Colors - * - * 乐高设计器的主要主题色变量 - */ -:root { - --color-brand: @brand-color-1; - --color-brand-light: @brand-color-2; - --color-brand-dark: @brand-color-3; - - --color-canvas-background: @normal-alpha-8; - - --color-icon-normal: @normal-alpha-4; - --color-icon-hover: @normal-alpha-3; - --color-icon-active: @brand-color-1; - --color-icon-reverse: @white-alpha-1; - - --color-line-normal: @normal-alpha-7; - --color-line-darken: darken(@normal-alpha-7, 10%); - - --color-title: @dark-alpha-2; - --color-text: @dark-alpha-3; - --color-text-dark: darken(@dark-alpha-3, 10%); - --color-text-light: lighten(@dark-alpha-3, 10%); - --color-text-reverse: @white-alpha-2; - --color-text-regular: @normal-alpha-2; - - --color-field-label: @dark-alpha-4; - --color-field-text: @dark-alpha-3; - --color-field-placeholder: @normal-alpha-5; - --color-field-border: @normal-alpha-5; - --color-field-border-hover: @normal-alpha-4; - --color-field-border-active: @normal-alpha-3; - --color-field-background: @white-alpha-1; - - --color-function-success: @brand-success; - --color-function-success-dark: darken(@brand-success, 10%); - --color-function-success-light: lighten(@brand-success, 10%); - --color-function-warning: @brand-warning; - --color-function-warning-dark: darken(@brand-warning, 10%); - --color-function-warning-light: lighten(@brand-warning, 10%); - --color-function-information: @brand-link-hover; - --color-function-information-dark: darken(@brand-link-hover, 10%); - --color-function-information-light: lighten(@brand-link-hover, 10%); - --color-function-error: @brand-danger; - --color-function-error-dark: darken(@brand-danger, 10%); - --color-function-error-light: lighten(@brand-danger, 10%); - - --color-pane-background: @white-alpha-1; - --color-block-background-normal: @white-alpha-1; - --color-block-background-light: @normal-alpha-9; - --color-block-background-shallow: @normal-alpha-8; - --color-block-background-dark: @normal-alpha-7; - --color-block-background-disabled: @normal-alpha-6; - --color-block-background-deep-dark: @normal-5; - --color-layer-mask-background: @dark-alpha-7; - --color-layer-tooltip-background: rgba(44,47,51,0.8); - - --pane-title-bg-color: rgba(31,56,88,.04); -} diff --git a/packages/workspace/src/layouts/top-area.tsx b/packages/workspace/src/layouts/top-area.tsx deleted file mode 100644 index cecaee2a71..0000000000 --- a/packages/workspace/src/layouts/top-area.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@alilc/lowcode-editor-core'; -import { Area } from '@alilc/lowcode-editor-skeleton'; - -@observer -export default class TopArea extends Component<{ area: Area; itemClassName?: string }> { - render() { - const { area, itemClassName } = this.props; - - if (area.isEmpty()) { - return null; - } - - return ( - <div className={classNames('lc-top-area engine-actionpane', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} itemClassName={itemClassName} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area; itemClassName?: string }> { - render() { - const { area, itemClassName } = this.props; - const left: any[] = []; - const center: any[] = []; - const right: any[] = []; - area.container.items.slice().sort((a, b) => { - const index1 = a.config?.index || 0; - const index2 = b.config?.index || 0; - return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); - }).forEach(item => { - const content = ( - <div className={itemClassName || ''} key={`top-area-${item.name}`}> - {item.content} - </div> - ); - if (item.align === 'center') { - center.push(content); - } else if (item.align === 'left') { - left.push(content); - } else { - right.push(content); - } - }); - - return ( - <Fragment> - <div className="lc-top-area-left">{left}</div> - <div className="lc-top-area-center">{center}</div> - <div className="lc-top-area-right">{right}</div> - </Fragment> - ); - } -} diff --git a/packages/workspace/src/layouts/workbench.less b/packages/workspace/src/layouts/workbench.less deleted file mode 100644 index 05eb5f513b..0000000000 --- a/packages/workspace/src/layouts/workbench.less +++ /dev/null @@ -1,421 +0,0 @@ -@import './theme.less'; - -:root { - --font-family: @font-family; - --font-size-label: @fontSize-4; - --font-size-text: @fontSize-5; - --font-size-btn-large: @fontSize-3; - --font-size-btn-medium: @fontSize-4; - --font-size-btn-small: @fontSize-5; - - --global-border-radius: @global-border-radius; - --input-border-radius: @input-border-radius; - --popup-border-radius: @popup-border-radius; - - --left-area-width: 48px; - --right-area-width: 300px; - --top-area-height: 48px; - --toolbar-height: 36px; - --dock-pane-width: 300px; - --dock-fixed-pane-width: 300px; -} - -@media (min-width: 1860px) { - :root { - --right-area-width: 400px; - --dock-pane-width: 452px; - --dock-fixed-pane-width: 350px; - } -} - -html, -body { - height: 100%; - overflow: hidden; - padding: 0; - margin: 0; - position: relative; - font-family: var(--font-family); - font-size: var(--font-size-text); - color: var(--color-text); - background-color: #edeff3; -} - -* { - box-sizing: border-box; -} - -.lc-titled-panel { - width: 100%; - height: 100%; - position: relative; - background-color: #fff; - background-color: var(--color-pane-background); - &.hidden { - display: none; - } - .lc-panel-title { - // background-color: var(--pane-title-bg-color,rgba(31,56,88,.04)); - display: flex; - align-items: center; - justify-content: flex-start; - padding: 0 15px; - - .lc-help-tip { - margin-left: 4px; - color: rgba(0, 0, 0, 0.4); - cursor: pointer; - } - } - > .lc-panel-title { - height: 48px; - font-size: 16px; - padding: 0 15px; - // border-bottom: 1px solid var(--color-line-normal,rgba(31,56,88,.1)); - color: #0f1726; - font-weight: bold; - } - - .lc-panel-body { - position: absolute; - top: 48px; - bottom: 0; - left: 0; - right: 0; - overflow: visible; - /* - .my-tabs { - width: 100%; - height: 100%; - position: relative; - .tabs-title { - display: flex; - height: var(--pane-title-height); - > .tab-title { - cursor: pointer; - padding: 0; - flex: 1; - min-width: 0; - justify-content: center; - border-bottom: 2px solid transparent; - &.actived { - cursor: default; - color: var(--color-text-avtived); - border-bottom-color: #3896ee; - } - } - } - .tabs-content { - position: absolute; - top: var(--pane-title-height); - bottom: 0; - left: 0; - right: 0; - height: calc(100% - var(--pane-title-height)); - overflow: hidden; - } - } - */ - } - .lc-outline-tree-container { - border-top: 1px solid var(--color-line-normal, rgba(31, 56, 88, 0.1)); - } -} -.lc-panel { - height: 100%; - width: 100%; - position: relative; - background-color: #fff; - background-color: var(--color-pane-background); - // overflow: auto; - &.hidden { - display: none; - } -} - -.lc-workspace-workbench { - height: 100%; - display: flex; - flex-direction: column; - background-color: #edeff3; - .lc-top-area, .lc-sub-top-area { - height: var(--top-area-height); - background-color: var(--color-pane-background); - width: 100%; - display: none; - margin-bottom: 2px; - padding: 8px 12px 8px 16px; - - &.lc-area-visible { - display: flex; - } - - .lc-top-area-left, .lc-sub-top-area-left { - display: flex; - align-items: center; - max-width: 100%; - } - - .lc-top-area-center, .lc-sub-top-area-center { - flex: 1; - display: flex; - justify-content: center; - margin: 0 8px; - } - .lc-top-area-right, .lc-sub-top-area-right { - display: flex; - align-items: center; - > * { - margin-left: 4px; - margin-right: 4px; - } - .ve-quick-search-trigger { - display: flex; - } - } - } - .lc-workspace-workbench-body { - flex: 1; - display: flex; - min-height: 0; - position: relative; - - .lc-tabs-title { - width: 100%; - height: 32px; - position: relative; - display: center; - display: flex; - justify-content: center; - align-items: center; - // background: rgba(31,56,88,0.04); - border-bottom: 1px solid #edeff3; - .lc-tab-title { - flex: 1; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - border-bottom: 2px solid transparent; - cursor: pointer; - font-size: 12px; - &.actived { - color: #0079f2; - border-bottom-color: #0079f2; - } - } - } - - .lc-tabs-content { - position: absolute; - top: 32px; - bottom: 0; - left: 0; - right: 0; - } - - .lc-pane-icon-close { - position: absolute; - right: 16px; - top: 14px; - height: auto; - z-index: 2; - .next-icon { - line-height: 1; - color: rgba(0, 0, 0, 0.6); - } - } - - .lc-pane-icon-fix, - .lc-pane-icon-float { - position: absolute; - right: 38px; - top: 14px; - height: auto; - z-index: 2; - svg { - vertical-align: middle; - color: rgba(0, 0, 0, 0.6); - } - } - - .lc-left-float-pane { - position: absolute; - top: 0; - bottom: 0; - width: var(--dock-pane-width); - // min-width: var(--dock-fixed-pane-width); - left: calc(var(--left-area-width) + 1px); - background-color: var(--color-pane-background); - box-shadow: 4px 6px 6px 0 rgba(31, 50, 88, 0.08); - z-index: 820; - display: none; - // padding-top: 36px; - &.lc-area-visible { - display: block; - } - } - .lc-left-area { - height: 100%; - width: var(--left-area-width); - background-color: var(--color-pane-background); - display: none; - flex-shrink: 0; - flex-direction: column; - justify-content: space-between; - overflow: hidden; - &.lc-area-visible { - display: flex; - } - .lc-left-area-top, - .lc-left-area-bottom { - width: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - .lc-title { - flex-direction: column; - width: calc(var(--left-area-width) - 2px); - height: 46px; - display: flex; - align-items: center; - justify-content: center; - - &.has-tip { - cursor: pointer; - } - &.actived { - color: #0079f2; - } - &.disabled { - opacity: 0.4; - } - .lc-title-icon { - height: 20px; - width: 20px; - margin: 0; - .next-icon:before { - line-height: 1 !important; - } - } - } - } - .lc-left-area-top { - padding-top: 12px; - } - .lc-left-area-bottom { - padding-bottom: 12px; - } - } - .lc-left-fixed-pane { - width: var(--dock-fixed-pane-width); - background-color: var(--color-pane-background); - height: 100%; - display: none; - flex-shrink: 0; - position: relative; - z-index: 820; - &.lc-area-visible { - display: block; - } - } - .lc-left-area.lc-area-visible ~ .lc-left-fixed-pane { - margin-left: 1px; - } - .lc-left-area.lc-area-visible ~ .lc-workspace-workbench-center { - margin-left: 2px; - } - .lc-outline-pane { - .lc-outline-tree .tree-node .tree-node-title { - border-bottom: none; - } - } - .lc-workspace-workbench-center { - flex: 1; - display: flex; - flex-direction: column; - z-index: 10; - position: relative; - .lc-toolbar { - display: flex; - height: var(--toolbar-height); - background-color: var(--color-pane-background); - padding: 8px 16px; - .lc-toolbar-center { - display: flex; - justify-content: center; - align-items: center; - flex: 1; - } - } - .lc-main-area { - flex: 1; - } - .lc-bottom-area { - height: var(--bottom-area-height); - background-color: var(--color-pane-background); - display: none; - &.lc-area-visible { - display: block; - } - } - } - - .lc-workspace-workbench-center-content { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - flex-direction: column; - display: flex; - align-content: stretch; - } - - .engine-actionitem { - max-width: 100%; - } - - .lc-workspace-workbench-window { - position: relative; - height: 100%; - } - - .lc-right-area { - height: 100%; - width: var(--right-area-width); - background-color: var(--color-pane-background); - display: none; - flex-shrink: 0; - margin-left: 2px; - position: relative; - > .lc-panel { - position: absolute; - left: 0; - top: 0; - } - &.lc-area-visible { - display: block; - } - .lc-settings-tabs { - > .next-tabs-nav-extra { - top: 36px !important; - } - .lc-settings-tab-item { - .next-tabs-tab-inner { - font-size: 12px; - line-height: 12px; - } - } - .lc-title { - color: inherit; - line-height: inherit !important; - } - } - .lc-settings-tabs-content { - top: 66px; - } - } - } -} diff --git a/packages/workspace/src/layouts/workbench.tsx b/packages/workspace/src/layouts/workbench.tsx index 08d6dc1a93..7d2d96df12 100644 --- a/packages/workspace/src/layouts/workbench.tsx +++ b/packages/workspace/src/layouts/workbench.tsx @@ -2,17 +2,10 @@ import { Component } from 'react'; import { TipContainer, engineConfig, observer } from '@alilc/lowcode-editor-core'; import { WindowView } from '../view/window-view'; import classNames from 'classnames'; -import TopArea from './top-area'; -import LeftArea from './left-area'; -import LeftFixedPane from './left-fixed-pane'; -import LeftFloatPane from './left-float-pane'; -import MainArea from './main-area'; -import BottomArea from './bottom-area'; -import './workbench.less'; import { SkeletonContext } from '../skeleton-context'; import { EditorConfig, PluginClassSet } from '@alilc/lowcode-types'; import { Workspace } from '../workspace'; -import SubTopArea from './sub-top-area'; +import { BottomArea, LeftArea, LeftFixedPane, LeftFloatPane, MainArea, SubTopArea, TopArea } from '@alilc/lowcode-editor-skeleton'; @observer export class Workbench extends Component<{ @@ -23,12 +16,18 @@ export class Workbench extends Component<{ topAreaItemClassName?: string; }, { workspaceEmptyComponent: any; + theme?: string; }> { constructor(props: any) { super(props); const { config, components, workspace } = this.props; const { skeleton } = workspace; skeleton.buildFromConfig(config, components); + engineConfig.onGot('theme', (theme) => { + this.setState({ + theme, + }); + }); engineConfig.onGot('workspaceEmptyComponent', (workspaceEmptyComponent) => { this.setState({ workspaceEmptyComponent, @@ -36,20 +35,21 @@ export class Workbench extends Component<{ }); this.state = { workspaceEmptyComponent: engineConfig.get('workspaceEmptyComponent'), + theme: engineConfig.get('theme'), }; } render() { const { workspace, className, topAreaItemClassName } = this.props; const { skeleton } = workspace; - const WorkspaceEmptyComponent = this.state.workspaceEmptyComponent; + const { workspaceEmptyComponent: WorkspaceEmptyComponent, theme } = this.state; return ( - <div className={classNames('lc-workspace-workbench', className)}> + <div className={classNames('lc-workspace-workbench', className, theme)}> <SkeletonContext.Provider value={skeleton}> <TopArea area={skeleton.topArea} itemClassName={topAreaItemClassName} /> <div className="lc-workspace-workbench-body"> - <LeftArea area={skeleton.leftArea} /> + <LeftArea className="lc-workspace-left-area" area={skeleton.leftArea} /> <LeftFloatPane area={skeleton.leftFloatArea} /> <LeftFixedPane area={skeleton.leftFixedArea} /> <div className="lc-workspace-workbench-center"> diff --git a/packages/workspace/src/view/resource-view.tsx b/packages/workspace/src/view/resource-view.tsx index 9ef30af092..e2204dd505 100644 --- a/packages/workspace/src/view/resource-view.tsx +++ b/packages/workspace/src/view/resource-view.tsx @@ -1,10 +1,10 @@ import { PureComponent } from 'react'; import { EditorView } from './editor-view'; import { observer } from '@alilc/lowcode-editor-core'; -import TopArea from '../layouts/top-area'; import { IResource } from '../resource'; import { IEditorWindow } from '../window'; import './resource-view.less'; +import { TopArea } from '@alilc/lowcode-editor-skeleton'; @observer export class ResourceView extends PureComponent<{ From f48c49c21f72c34cb3b0791baa39ba7e8629c74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=BE=E5=B8=85?= <21106848+sdshaoda@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:26:30 +0800 Subject: [PATCH 120/361] docs: Update summary.md add material spec link --- docs/docs/guide/design/summary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/design/summary.md b/docs/docs/guide/design/summary.md index cd5edfd886..38d523cac9 100644 --- a/docs/docs/guide/design/summary.md +++ b/docs/docs/guide/design/summary.md @@ -20,7 +20,7 @@ sidebar_position: 0 低代码引擎分为 4 大模块,入料 - 编排 - 渲染 - 出码: -- 入料模块就是将外部的物料,比如海量的 npm 组件,按照《物料描述协议》进行描述。将描述后的数据通过引擎 API 注册后,在编辑器中使用。 +- 入料模块就是将外部的物料,比如海量的 npm 组件,按照[《低代码引擎物料协议规范》](/site/docs/specs/material-spec)进行描述。将描述后的数据通过引擎 API 注册后,在编辑器中使用。 > **注意,这里仅是增加描述,而非重写一套,这样我们能最大程度复用 ProCode 体系已沉淀的组件。** - 编排,本质上来讲,就是**不断在生成符合[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)的页面描述,将编辑器中的所有物料,进行布局设置、组件 CRUD 操作、以及 JS / CSS 编写/ 逻辑编排 **等,最终转换成页面描述,技术细节后文会展开。 - 渲染,顾名思义,就是**将编排生成的页面描述结构渲染成视图的过程**,视图是面向用户的,所以必须处理好内部数据流、生命周期、事件绑定、国际化等。 From 2c2241ef73d5582084202e562dd82f551c8367f3 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?= <liujup@foxmail.com> Date: Mon, 4 Sep 2023 11:44:36 +0800 Subject: [PATCH 121/361] Revert "fix(material): fix rendering is blocked, when the url in the asset fails to load" This reverts commit 8b5e2b47c6668817e365b31277f2b2d6c9313cca. --- packages/editor-core/src/editor.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index 10aa0bea1c..f31a2a2dda 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -153,11 +153,7 @@ export class Editor extends EventEmitter implements IEditor { return; } if (!AssetsCache[exportName] || !npm?.version || AssetsCache[exportName].npm?.version !== npm?.version) { - try { - await (new AssetLoader()).load(url); - } catch (error) { - console.error(`${url} load error: `, error); - } + await (new AssetLoader()).load(url); } AssetsCache[exportName] = component; function setAssetsComponent(component: any, extraNpmInfo: any = {}) { From bfdc7a277ba4713dbfdd1c9efe01bbd9126a4219 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 4 Sep 2023 11:51:18 +0800 Subject: [PATCH 122/361] feat(workspace): fix onWindowRendererReady api --- packages/workspace/src/layouts/workbench.tsx | 2 +- packages/workspace/src/window.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/workspace/src/layouts/workbench.tsx b/packages/workspace/src/layouts/workbench.tsx index 7d2d96df12..9bdbe3f932 100644 --- a/packages/workspace/src/layouts/workbench.tsx +++ b/packages/workspace/src/layouts/workbench.tsx @@ -49,7 +49,7 @@ export class Workbench extends Component<{ <SkeletonContext.Provider value={skeleton}> <TopArea area={skeleton.topArea} itemClassName={topAreaItemClassName} /> <div className="lc-workspace-workbench-body"> - <LeftArea className="lc-workspace-left-area" area={skeleton.leftArea} /> + <LeftArea className="lc-workspace-left-area lc-left-area" area={skeleton.leftArea} /> <LeftFloatPane area={skeleton.leftFloatArea} /> <LeftFixedPane area={skeleton.leftFixedArea} /> <div className="lc-workspace-workbench-center"> diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index 2c670346fb..ce5aab4142 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -126,9 +126,10 @@ export class EditorWindow implements IEditorWindow { async init() { await this.initViewTypes(); await this.execViewTypesInit(); - Promise.all(Array.from(this.editorViews.values()).map((d) => d.onSimulatorRendererReady)).then(() => { - this.workspace.emitWindowRendererReady(); - }); + Promise.all(Array.from(this.editorViews.values()).map((d) => d.onSimulatorRendererReady())) + .then(() => { + this.workspace.emitWindowRendererReady(); + }); this.url = await this.resource.url(); this.setDefaultViewName(); this.initReady = true; From 4677d99127f25f202805b23f661c7f1cc1fc5a3a Mon Sep 17 00:00:00 2001 From: "chenkeyao.chenkeya" <chenkeyao.chenkeya@alibaba-inc.com> Date: Tue, 5 Sep 2023 14:53:30 +0800 Subject: [PATCH 123/361] feat: Modify the content of the article menu and add a video menu --- docs/config/navbar.js | 6 ++++++ docs/docs/article/index.md | 32 ++------------------------------ docs/docs/video/index.md | 13 +++++++++++++ 3 files changed, 21 insertions(+), 30 deletions(-) create mode 100644 docs/docs/video/index.md diff --git a/docs/config/navbar.js b/docs/config/navbar.js index 20d5e5f90c..24f8a39376 100644 --- a/docs/config/navbar.js +++ b/docs/config/navbar.js @@ -39,6 +39,12 @@ module.exports = { position: 'left', label: '文章', }, + { + type: 'doc', + docId: 'video/index', + position: 'left', + label: '视频', + }, { type: 'doc', docId: 'demoUsage/intro', diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index 8ff76ff476..2f6f2cee3f 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -1,8 +1,4 @@ ---- -title: 低代码引擎相关文章资料 ---- - -## 官方文章 +# 官方文章 - [2023/04/04 什么?低代码引擎可以开发应用了](https://mp.weixin.qq.com/s/dwi40gJjGBHW9MVpag5Oxg) - [2023/03/23 低代码引擎 LowCodeEngine 茁壮成长的一年](https://mp.weixin.qq.com/s/DDt4LQLFUBQ2-F5ehZGBKg) - [2023/02/21 基于 LowCodeEngine 的低代码组件体系的建设和实践](https://mp.weixin.qq.com/s/rnvbGHImGt6oJuX2wCtaqw) @@ -14,28 +10,4 @@ title: 低代码引擎相关文章资料 - [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) - [2022/03/23 阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA) - [2022/01/10 阿里低代码引擎和生态建设实战及思考](https://mp.weixin.qq.com/s/MI6MrUKKydtnSdO4xq6jwA) -- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) - -## Portal 设计项目实战 -#### 直播回放 -[https://www.bilibili.com/video/BV1AS4y1K7DP/](https://www.bilibili.com/video/BV1AS4y1K7DP/) - -#### 示例项目 -- 前端: [https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) -- 后端: [https://github.com/mark-ck/document-solution-site](https://github.com/mark-ck/document-solution-site) -- 组件库:[https://github.com/mark-ck/portal-components](https://github.com/mark-ck/portal-components) - -**注意** -1. 前端项目要把代码里请求接口的域名改成本地或者自己的域名; -2. 后端项目要把 config.default.js 里的 yuque 和 oss 配置补全; - -#### 视频链接 -- [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) -- [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) -- [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) -- [阿里低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/) -- [阿里低代码引擎项目实战 (4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) -- [【有翻车】阿里低代码引擎项目实战 (5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/) -- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) -- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) -- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/) +- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) \ No newline at end of file diff --git a/docs/docs/video/index.md b/docs/docs/video/index.md new file mode 100644 index 0000000000..9f348e4e65 --- /dev/null +++ b/docs/docs/video/index.md @@ -0,0 +1,13 @@ +# 官方视频 +- [2023/08/03 初识低代码引擎](https://www.bilibili.com/video/BV1gu411p7TC) + +# 社区视频 +- [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) +- [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) +- [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) +- [阿里低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/) +- [阿里低代码引擎项目实战 (4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) +- [【有翻车】阿里低代码引擎项目实战 (5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/) +- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) +- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) +- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/) From 70df59a2ce82f1d9fe59c8177ae1b9782465d83e Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 5 Sep 2023 15:41:14 +0800 Subject: [PATCH 124/361] style(outline-pane): fix outline-pane styles --- packages/editor-skeleton/src/layouts/right-area.tsx | 13 +++++++++++-- packages/editor-skeleton/src/layouts/workbench.less | 1 + packages/plugin-outline-pane/src/index.tsx | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/editor-skeleton/src/layouts/right-area.tsx b/packages/editor-skeleton/src/layouts/right-area.tsx index 4393eef55f..f00ae1461a 100644 --- a/packages/editor-skeleton/src/layouts/right-area.tsx +++ b/packages/editor-skeleton/src/layouts/right-area.tsx @@ -22,14 +22,23 @@ export default class RightArea extends Component<{ area: Area<any, Panel> }> { } } - @observer class Contents extends Component<{ area: Area<any, Panel> }> { render() { const { area } = this.props; + return ( <Fragment> - {area.container.items.map((item) => item.content)} + { + area.container.items + .slice() + .sort((a, b) => { + const index1 = a.config?.index || 0; + const index2 = b.config?.index || 0; + return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); + }) + .map((item) => item.content) + } </Fragment> ); } diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 0a034822f4..38cbcfae09 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -431,6 +431,7 @@ body { background-color: var(--color-right-area-background, var(--color-pane-background, #fff)); left: 0; top: 0; + z-index: 1; } &.lc-area-visible { display: block; diff --git a/packages/plugin-outline-pane/src/index.tsx b/packages/plugin-outline-pane/src/index.tsx index addebbb402..822c503f27 100644 --- a/packages/plugin-outline-pane/src/index.tsx +++ b/packages/plugin-outline-pane/src/index.tsx @@ -92,6 +92,7 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => { paneName: BackupPaneName, treeMaster, }, + index: 1, }); // 处理 master pane 和 backup pane 切换 From 34acd70659880409416add185926e874d179876d Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 5 Sep 2023 15:50:33 +0800 Subject: [PATCH 125/361] chore(docs): publish docs 1.1.8 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 012ef49d04..45c645bc09 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.7", + "version": "1.1.8", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 7ef62308d7a53c62feef8da92c1c0374f89b9412 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 6 Sep 2023 17:17:35 +0800 Subject: [PATCH 126/361] feat(common): update skeletonCabinSymbol exports --- packages/shell/src/api/common.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shell/src/api/common.tsx b/packages/shell/src/api/common.tsx index 3c2d2e5cce..605d2fb077 100644 --- a/packages/shell/src/api/common.tsx +++ b/packages/shell/src/api/common.tsx @@ -176,7 +176,7 @@ class SkeletonCabin implements IPublicApiCommonSkeletonCabin { constructor(skeleton: InnerSkeleton) { this[skeletonSymbol] = skeleton; this[skeletonCabinSymbol] = { - Workbench: this.Workbench, + Workbench: InnerWorkbench, createSettingFieldView: this.createSettingFieldView, PopupContext: InnerPopupContext, PopupPipe: InnerPopupPipe, From 4507e83d7da87a9a4e759caa237e4b59e9fdef6d Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 7 Sep 2023 10:06:50 +0800 Subject: [PATCH 127/361] feat(common): update designerCabinSymbol exports --- packages/shell/src/api/common.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/shell/src/api/common.tsx b/packages/shell/src/api/common.tsx index 605d2fb077..a2e4d8c4fa 100644 --- a/packages/shell/src/api/common.tsx +++ b/packages/shell/src/api/common.tsx @@ -40,6 +40,7 @@ import { Designer as InnerDesigner, Node as InnerNode, LowCodePluginManager as InnerLowCodePluginManager, + DesignerView as InnerDesignerView, } from '@alilc/lowcode-designer'; import { Skeleton as InnerSkeleton, @@ -105,6 +106,7 @@ class DesignerCabin implements IPublicApiCommonDesignerCabin { Designer: InnerDesigner, Node: InnerNode, LowCodePluginManager: InnerLowCodePluginManager, + DesignerView: InnerDesignerView, }; } From 4e0b2fae5d2a59f068b1d5315f3fab6134e4d203 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 7 Sep 2023 10:09:40 +0800 Subject: [PATCH 128/361] feat(hotkey): when text is selected, allow the default copy and paste behavior --- packages/engine/src/inner-plugins/builtin-hotkey.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/engine/src/inner-plugins/builtin-hotkey.ts b/packages/engine/src/inner-plugins/builtin-hotkey.ts index 692773a756..1a1f3a9c44 100644 --- a/packages/engine/src/inner-plugins/builtin-hotkey.ts +++ b/packages/engine/src/inner-plugins/builtin-hotkey.ts @@ -277,6 +277,10 @@ export const builtinHotkey = (ctx: IPublicModelPluginContext) => { if (isFormEvent(e) || !doc) { return; } + const anchorValue = document.getSelection()?.anchorNode?.nodeValue; + if (anchorValue && typeof anchorValue === 'string') { + return; + } e.preventDefault(); let selected = doc.selection.getTopNodes(true); From 24cac48a3252c3cfe7e0c382e3a859c6b6f4194f 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?= <liujup@foxmail.com> Date: Fri, 8 Sep 2023 10:56:44 +0800 Subject: [PATCH 129/361] docs: update loop.md --- docs/docs/demoUsage/appendix/loop.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/docs/demoUsage/appendix/loop.md b/docs/docs/demoUsage/appendix/loop.md index 8b364ecf4f..46f39398af 100644 --- a/docs/docs/demoUsage/appendix/loop.md +++ b/docs/docs/demoUsage/appendix/loop.md @@ -15,3 +15,14 @@ sidebar_position: 0 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XQfnYL1P4wxn01oXv_!!6000000001788-2-tps-3840-1896.png) this.index 是当前循环的索引值。 + +3.在事件绑定函数中使用 + +在事件绑定函数中使用扩展参数设置 +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/7274506e-decd-497a-b07f-c95941a706b4) + +绑定之后在函数中使用 +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/9d52ee5c-9959-4991-91be-9391e639bb7e) + +按钮点击效果 +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/6ca590c9-1f5f-4d48-94a5-439130a22e92) From a560830db652713e29e209fb03a0ea6a6d7e9d40 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 8 Sep 2023 14:16:07 +0800 Subject: [PATCH 130/361] chore(docs): publish docs 1.1.9 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 45c645bc09..773f549cba 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.8", + "version": "1.1.9", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 6b14986e8f6cab6af5bc580c9f1a2a4fa925ef5f Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 11 Sep 2023 11:23:36 +0800 Subject: [PATCH 131/361] feat(config): add defaultSettingPanelProps config --- docs/docs/api/configOptions.md | 11 ++++++++++- .../src/inner-plugins/default-panel-registry.tsx | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index 4127576569..467655f68c 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -254,6 +254,16 @@ JSExpression 是否只支持使用 this 来访问上下文变量,假如需要 自定义 loading 组件 +### 插件 + +#### defaultSettingPanelProps + +内置设置面板插件的 panelProps + +#### defaultOutlinePaneProps + +内置大纲树面板插件的 panelProps + ### 其他 #### enableStrictPluginMode @@ -282,4 +292,3 @@ customPluginTransducer: async (originPlugin: IPublicTypePlugin, ctx: IPublicMode 大纲树插件面板默认 props - diff --git a/packages/engine/src/inner-plugins/default-panel-registry.tsx b/packages/engine/src/inner-plugins/default-panel-registry.tsx index d7549d764b..b5f538d44c 100644 --- a/packages/engine/src/inner-plugins/default-panel-registry.tsx +++ b/packages/engine/src/inner-plugins/default-panel-registry.tsx @@ -28,6 +28,9 @@ export const defaultPanelRegistry = (editor: any) => { props: { ignoreRoot: true, }, + panelProps: { + ...(config.get('defaultSettingPanelProps') || {}), + }, }); } }, @@ -39,5 +42,4 @@ export const defaultPanelRegistry = (editor: any) => { return fun; }; - export default defaultPanelRegistry; From 1072ff36fb6be0743ae199e9a48eeaa38bd8e0d1 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 13 Sep 2023 11:02:15 +0800 Subject: [PATCH 132/361] feat(workspace): add workspace.skeleton api --- docs/docs/api/workspace.md | 10 ++++++++++ packages/editor-skeleton/src/skeleton.ts | 2 +- packages/shell/src/api/workspace.ts | 5 +++++ packages/workspace/src/workspace.ts | 3 +++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 3c13b00aa0..9911dc93ad 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -37,6 +37,16 @@ get plugins(): IPublicApiPlugins 关联模型 [IPublicApiPlugins](./plugins) +### skeleton + +应用级别的面板管理 + +```typescript +get skeleton(): IPublicApiSkeleton +``` + +关联模型 [IPublicApiSkeleton](./skeleton) + ### windows 当前设计器的编辑窗口 diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 8836434049..89bffc4cfe 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -108,7 +108,7 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton, add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined; } -export class Skeleton { +export class Skeleton implements ISkeleton { private panels = new Map<string, Panel>(); private containers = new Map<string, WidgetContainer<any>>(); diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index 8737e37bd7..fd3e82fa90 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -3,6 +3,7 @@ import { IWorkspace } from '@alilc/lowcode-workspace'; import { resourceSymbol, workspaceSymbol } from '../symbols'; import { Resource as ShellResource, Window as ShellWindow } from '../model'; import { Plugins } from './plugins'; +import { Skeleton } from './skeleton'; export class Workspace implements IPublicApiWorkspace { readonly [workspaceSymbol]: IWorkspace; @@ -92,6 +93,10 @@ export class Workspace implements IPublicApiWorkspace { return new Plugins(this[workspaceSymbol].plugins, true); } + get skeleton() { + return new Skeleton(this[workspaceSymbol].skeleton, 'workspace', true); + } + get windows() { return this[workspaceSymbol].windows.map((d) => new ShellWindow(d)); } diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 22eb9ede2b..59b9e866b2 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -6,6 +6,7 @@ import { EditorWindow, WINDOW_STATE } from './window'; import type { IEditorWindow } from './window'; import { IResource, Resource } from './resource'; import { IResourceType, ResourceType } from './resource-type'; +import { ISkeleton } from '@alilc/lowcode-editor-skeleton'; enum EVENT { CHANGE_WINDOW = 'change_window', @@ -33,6 +34,8 @@ export interface IWorkspace extends Omit<IPublicApiWorkspace< plugins: ILowCodePluginManager; + skeleton: ISkeleton; + resourceTypeMap: Map<string, ResourceType>; getResourceList(): IResource[]; From cf2f5c29bce5917e56e774843266f1b5801fd1c3 Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Wed, 13 Sep 2023 21:32:38 -0500 Subject: [PATCH 133/361] fix: do not parse props when condition is false or loop data is empty (#2477) * fix: do not parse children props when condition is falsy * fix: skip parsing children when loop data is empty --- packages/renderer-core/src/renderer/base.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 89dc143d5f..216735edcf 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -545,6 +545,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (schema.loop != null) { const loop = this.__parseData(schema.loop, scope); + if (Array.isArray(loop) && loop.length === 0) return null; const useLoop = isUseLoop(loop, this.__designModeIsDesign); if (useLoop) { return this.__createLoopVirtualDom( @@ -649,7 +650,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { props.key = props.__id; } - let child = this.__getSchemaChildrenVirtualDom(schema, scope, Comp); + let child = this.__getSchemaChildrenVirtualDom(schema, scope, Comp, condition); const renderComp = (innerProps: any) => engine.createElement(Comp, innerProps, child); // 设计模式下的特殊处理 if (engine && [DESIGN_MODE.EXTEND, DESIGN_MODE.BORDER].includes(engine.props.designMode)) { @@ -709,8 +710,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { return []; } - __getSchemaChildrenVirtualDom = (schema: IPublicTypeNodeSchema | undefined, scope: any, Comp: any) => { - let children = getSchemaChildren(schema); + __getSchemaChildrenVirtualDom = (schema: IPublicTypeNodeSchema | undefined, scope: any, Comp: any, condition = true) => { + let children = condition ? getSchemaChildren(schema) : null; // @todo 补完这里的 Element 定义 @承虎 let result: any = []; From cfc22f7ecc666ae8258013634c3aa17958299b90 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 18 Sep 2023 15:48:32 +0800 Subject: [PATCH 134/361] feat: add simulatorRender shell --- docs/docs/api/model/simulatorRender.md | 38 +++++++++++++++++++ docs/docs/api/simulatorHost.md | 4 +- packages/engine/src/modules/symbols.ts | 2 + packages/shell/src/api/simulator-host.ts | 13 +++++-- packages/shell/src/model/simulator-render.ts | 23 +++++++++++ packages/shell/src/symbols.ts | 1 + .../types/src/shell/api/simulator-host.ts | 6 +-- packages/types/src/shell/model/index.ts | 1 + .../types/src/shell/model/simulator-render.ts | 14 +++++++ 9 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 docs/docs/api/model/simulatorRender.md create mode 100644 packages/shell/src/model/simulator-render.ts create mode 100644 packages/types/src/shell/model/simulator-render.ts diff --git a/docs/docs/api/model/simulatorRender.md b/docs/docs/api/model/simulatorRender.md new file mode 100644 index 0000000000..f5bacec493 --- /dev/null +++ b/docs/docs/api/model/simulatorRender.md @@ -0,0 +1,38 @@ +--- +title: SimulatorRender +sidebar_position: 6 +--- +> **@types** [IPublicModelSimulatorRender](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/simulator-render.ts)<br/> +> **@since** v1.0.0 + +## 基本介绍 + +画布节点选中模型 + +## 属性 +### components + +画布组件列表 + +```typescript +/** + * 画布组件列表 + */ +components: { + [key: string]: any; +} +``` + +## 方法 + +### rerender + +触发画布重新渲染 + +```typescript +/** + * 触发画布重新渲染 + */ +rerender: () => void; +``` + diff --git a/docs/docs/api/simulatorHost.md b/docs/docs/api/simulatorHost.md index b30a614992..ee8f038fc3 100644 --- a/docs/docs/api/simulatorHost.md +++ b/docs/docs/api/simulatorHost.md @@ -50,11 +50,11 @@ get(key: string): any; ``` ### rerender -刷新渲染画布 +触发组件构建,并刷新渲染画布 ```typescript /** - * 刷新渲染画布 + * 触发组件构建,并刷新渲染画布 * make simulator render again */ rerender(): void; diff --git a/packages/engine/src/modules/symbols.ts b/packages/engine/src/modules/symbols.ts index 435e8cbc2c..55c70e5dcb 100644 --- a/packages/engine/src/modules/symbols.ts +++ b/packages/engine/src/modules/symbols.ts @@ -14,6 +14,7 @@ import { skeletonItemSymbol, editorCabinSymbol, skeletonCabinSymbol, + simulatorRenderSymbol, } from '@alilc/lowcode-shell'; export default { @@ -32,4 +33,5 @@ export default { propSymbol, simulatorHostSymbol, skeletonItemSymbol, + simulatorRenderSymbol, }; diff --git a/packages/shell/src/api/simulator-host.ts b/packages/shell/src/api/simulator-host.ts index 3ed7448905..663ba0c668 100644 --- a/packages/shell/src/api/simulator-host.ts +++ b/packages/shell/src/api/simulator-host.ts @@ -2,7 +2,8 @@ import { BuiltinSimulatorHost, } from '@alilc/lowcode-designer'; import { simulatorHostSymbol, nodeSymbol } from '../symbols'; -import { IPublicApiSimulatorHost, IPublicModelNode } from '@alilc/lowcode-types'; +import { IPublicApiSimulatorHost, IPublicModelNode, IPublicModelSimulatorRender } from '@alilc/lowcode-types'; +import { SimulatorRender } from '../model/simulator-render'; export class SimulatorHost implements IPublicApiSimulatorHost { private readonly [simulatorHostSymbol]: BuiltinSimulatorHost; @@ -30,8 +31,12 @@ export class SimulatorHost implements IPublicApiSimulatorHost { return this[simulatorHostSymbol].contentDocument; } - get renderer(): any { - return this[simulatorHostSymbol].renderer; + get renderer(): IPublicModelSimulatorRender | undefined { + if (this[simulatorHostSymbol].renderer) { + return SimulatorRender.create(this[simulatorHostSymbol].renderer); + } + + return undefined; } /** @@ -61,7 +66,7 @@ export class SimulatorHost implements IPublicApiSimulatorHost { } /** - * 刷新渲染画布 + * 触发组件构建,并刷新渲染画布 */ rerender(): void { this[simulatorHostSymbol].rerender(); diff --git a/packages/shell/src/model/simulator-render.ts b/packages/shell/src/model/simulator-render.ts new file mode 100644 index 0000000000..f6ae47996c --- /dev/null +++ b/packages/shell/src/model/simulator-render.ts @@ -0,0 +1,23 @@ +import { IPublicModelSimulatorRender } from '@alilc/lowcode-types'; +import { simulatorRenderSymbol } from '../symbols'; +import { BuiltinSimulatorRenderer } from '@alilc/lowcode-designer'; + +export class SimulatorRender implements IPublicModelSimulatorRender { + private readonly [simulatorRenderSymbol]: BuiltinSimulatorRenderer; + + constructor(simulatorRender: BuiltinSimulatorRenderer) { + this[simulatorRenderSymbol] = simulatorRender; + } + + static create(simulatorRender: BuiltinSimulatorRenderer): IPublicModelSimulatorRender { + return new SimulatorRender(simulatorRender); + } + + get components() { + return this[simulatorRenderSymbol].components; + } + + rerender() { + return this[simulatorRenderSymbol].rerender(); + } +} \ No newline at end of file diff --git a/packages/shell/src/symbols.ts b/packages/shell/src/symbols.ts index cc1be48560..8e2962a24f 100644 --- a/packages/shell/src/symbols.ts +++ b/packages/shell/src/symbols.ts @@ -21,6 +21,7 @@ export const dragonSymbol = Symbol('dragon'); export const componentMetaSymbol = Symbol('componentMeta'); export const dropLocationSymbol = Symbol('dropLocation'); export const simulatorHostSymbol = Symbol('simulatorHost'); +export const simulatorRenderSymbol = Symbol('simulatorRender'); export const dragObjectSymbol = Symbol('dragObject'); export const locateEventSymbol = Symbol('locateEvent'); export const designerCabinSymbol = Symbol('designerCabin'); diff --git a/packages/types/src/shell/api/simulator-host.ts b/packages/types/src/shell/api/simulator-host.ts index 1c0f5dec35..9137067951 100644 --- a/packages/types/src/shell/api/simulator-host.ts +++ b/packages/types/src/shell/api/simulator-host.ts @@ -1,7 +1,7 @@ -import { IPublicModelNode } from '../model'; - +import { IPublicModelNode, IPublicModelSimulatorRender } from '../model'; export interface IPublicApiSimulatorHost { + /** * 获取 contentWindow * @experimental unstable api, pay extra caution when trying to use it @@ -17,7 +17,7 @@ export interface IPublicApiSimulatorHost { /** * @experimental unstable api, pay extra caution when trying to use it */ - get renderer(): any; + get renderer(): IPublicModelSimulatorRender | undefined; /** * 设置若干用于画布渲染的变量,比如画布大小、locale 等。 diff --git a/packages/types/src/shell/model/index.ts b/packages/types/src/shell/model/index.ts index 1924f11215..ffe6347ac2 100644 --- a/packages/types/src/shell/model/index.ts +++ b/packages/types/src/shell/model/index.ts @@ -32,3 +32,4 @@ export * from './clipboard'; export * from './setting-field'; export * from './editor-view'; export * from './skeleton-item'; +export * from './simulator-render'; diff --git a/packages/types/src/shell/model/simulator-render.ts b/packages/types/src/shell/model/simulator-render.ts new file mode 100644 index 0000000000..8cf3a03c55 --- /dev/null +++ b/packages/types/src/shell/model/simulator-render.ts @@ -0,0 +1,14 @@ +export interface IPublicModelSimulatorRender { + + /** + * 画布组件列表 + */ + components: { + [key: string]: any; + }; + + /** + * 触发画布重新渲染 + */ + rerender: () => void; +} From 3e75af171d75b44c213242f6f9d0bda85c4e4cd0 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 19 Sep 2023 09:33:40 +0800 Subject: [PATCH 135/361] chore(docs): publish docs 1.1.10 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 773f549cba..3950b35c9c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.9", + "version": "1.1.10", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 3658bac27feb8b9f7b0c71a579ad9c4b6fb52214 Mon Sep 17 00:00:00 2001 From: zsynuting <zsynuting@163.com> Date: Mon, 18 Sep 2023 16:27:21 +0800 Subject: [PATCH 136/361] remove unnecessary dep --- packages/designer/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/designer/package.json b/packages/designer/package.json index 274d266fc0..1081aef8ff 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -15,7 +15,6 @@ }, "license": "MIT", "dependencies": { - "@alilc/build-plugin-lce": "^0.0.4-beta.2", "@alilc/lowcode-editor-core": "1.1.10", "@alilc/lowcode-types": "1.1.10", "@alilc/lowcode-utils": "1.1.10", From 7a40aff277bba2969242a2d5780dd6e032714cd7 Mon Sep 17 00:00:00 2001 From: iChengbo <chengbo_x@163.com> Date: Mon, 25 Sep 2023 15:02:37 +0800 Subject: [PATCH 137/361] fix: make the color of the logger more highlighted --- packages/utils/src/logger.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 032b54bdc4..58c7d23b19 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -52,11 +52,11 @@ const bizNameColors = [ '#2e8b57', ]; const bodyColors: Record<string, string> = { - debug: '#666666', - log: '#bbbbbb', - info: '#ffffff', - warn: '#bbbbbb', - error: '#bbbbbb', + debug: '#fadb14', + log: '#8c8c8c', + info: '#52c41a', + warn: '#fa8c16', + error: '#ff4d4f', }; const levelMarks: Record<string, string> = { debug: 'debug', From 4728484e7e449b8af4d66b414bdb474608bc95e0 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 25 Sep 2023 18:09:57 +0800 Subject: [PATCH 138/361] feat: suport more locale config --- packages/react-simulator-renderer/src/locale/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-simulator-renderer/src/locale/index.ts b/packages/react-simulator-renderer/src/locale/index.ts index e4b39a347c..5f4ef01505 100644 --- a/packages/react-simulator-renderer/src/locale/index.ts +++ b/packages/react-simulator-renderer/src/locale/index.ts @@ -9,10 +9,10 @@ const instance: Record<string, Record<string, string>> = { export function createIntl(locale: string = 'zh-CN') { const intl = (id: string) => { - return instance[locale][id]; + return instance[locale]?.[id] || id; }; - const intlNode = (id: string) => createElement('span', instance[locale][id]); + const intlNode = (id: string) => createElement('span', instance[locale]?.[id] || id); return { intl, From 5c139181b6b0e1a542e0babc9cb63e7938306079 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 26 Sep 2023 17:21:01 +0800 Subject: [PATCH 139/361] fix: fix workspace openEditorWindow API bugs --- packages/workspace/src/workspace.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 59b9e866b2..9f1abaa0fb 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -130,7 +130,9 @@ export class Workspace implements IWorkspace { } const windowInfo = this.windowQueue.shift(); - if (windowInfo) { + if (windowInfo instanceof Resource) { + this.openEditorWindowByResource(windowInfo); + } else if (windowInfo) { this.openEditorWindow(windowInfo.name, windowInfo.title, windowInfo.options, windowInfo.viewName); } } @@ -251,7 +253,7 @@ export class Workspace implements IWorkspace { } async openEditorWindowByResource(resource: IResource, sleep: boolean = false): Promise<void> { - if (this.window && !this.window?.initReady && !sleep) { + if (this.window && !this.window.sleep && !this.window?.initReady && !sleep) { this.windowQueue.push(resource); return; } @@ -292,7 +294,7 @@ export class Workspace implements IWorkspace { } async openEditorWindow(name: string, title: string, options: Object, viewName?: string, sleep?: boolean) { - if (this.window && !this.window?.initReady && !sleep) { + if (this.window && !this.window.sleep && !this.window?.initReady && !sleep) { this.windowQueue.push({ name, title, options, viewName, }); @@ -304,7 +306,7 @@ export class Workspace implements IWorkspace { return; } this.window?.updateState(WINDOW_STATE.inactive); - const filterWindows = this.windows.filter(d => (d.resource?.name === name && d.resource.title == title)); + const filterWindows = this.windows.filter(d => (d.resource?.name === name && d.resource.title == title) || (d.resource.id == title)); if (filterWindows && filterWindows.length) { this.window = filterWindows[0]; if (!sleep && this.window.sleep) { @@ -320,6 +322,7 @@ export class Workspace implements IWorkspace { resourceName: name, title, options, + id: title?.toString(), }, resourceType, this); const window = new EditorWindow(resource, this, { title, From e3e5123b3173cd0999ace99278e904391baa3aa4 Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Mon, 25 Sep 2023 21:27:23 -0500 Subject: [PATCH 140/361] fix: remove `class` prop --- .../src/components/settings/settings-primary-pane.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 800719588f..a68647ed0d 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -64,7 +64,6 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { <div className="lc-settings-navigator"> {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon', - class: 'lc-settings-navigator-icon', })} <Title title={settings.componentMeta!.title} /> <span> x {settings.nodes.length}</span> From f50410ae7a51b6c4d7ad18f4146c462beb2cfb51 Mon Sep 17 00:00:00 2001 From: iChengbo <chengbo_x@163.com> Date: Thu, 5 Oct 2023 12:31:45 +0800 Subject: [PATCH 141/361] fix: some spell error --- .../designer/src/builtin-simulator/host.ts | 10 +++++----- packages/designer/src/designer/designer.ts | 4 ++-- packages/designer/src/designer/scroller.ts | 18 +++++++++--------- packages/utils/src/app-helper.ts | 12 ++++++------ packages/utils/src/asset.ts | 8 ++++---- packages/utils/src/logger.ts | 4 ++-- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 5e6fc06a62..eb855e4498 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -1069,15 +1069,15 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp return null; } - const nodeIntance = this.getClosestNodeInstance(target); - if (!nodeIntance) { + const nodeInstance = this.getClosestNodeInstance(target); + if (!nodeInstance) { return null; } - const { docId } = nodeIntance; + const { docId } = nodeInstance; const doc = this.project.getDocument(docId)!; - const node = doc.getNode(nodeIntance.nodeId); + const node = doc.getNode(nodeInstance.nodeId); return { - ...nodeIntance, + ...nodeInstance, node, }; } diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 784ebf57bc..d7e17e84ca 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -18,7 +18,7 @@ import { IPublicEnumTransformStage, IPublicModelLocateEvent, } from '@alilc/lowcode-types'; -import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; +import { mergeAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { IProject, Project } from '../project'; import { Node, DocumentModel, insertChildren, INode } from '../document'; import { ComponentMeta, IComponentMeta } from '../component-meta'; @@ -458,7 +458,7 @@ export class Designer implements IDesigner { if (components) { // 合并 assets let assets = this.editor.get('assets') || {}; - let newAssets = megreAssets(assets, incrementalAssets); + let newAssets = mergeAssets(assets, incrementalAssets); // 对于 assets 存在需要二次网络下载的过程,必须 await 等待结束之后,再进行事件触发 await this.editor.set('assets', newAssets); } diff --git a/packages/designer/src/designer/scroller.ts b/packages/designer/src/designer/scroller.ts index 67efe7f444..7391c39fab 100644 --- a/packages/designer/src/designer/scroller.ts +++ b/packages/designer/src/designer/scroller.ts @@ -46,7 +46,7 @@ function easing(n: number) { return Math.sin((n * Math.PI) / 2); } -const SCROLL_ACCURCY = 30; +const SCROLL_ACCURACY = 30; export interface IScroller extends IPublicModelScroller { @@ -142,15 +142,15 @@ export class Scroller implements IScroller { let sy = scrollTarget.top; let ax = 0; let ay = 0; - if (y < bounds.top + SCROLL_ACCURCY) { - ay = -Math.min(Math.max(bounds.top + SCROLL_ACCURCY - y, 10), 50) / scale; - } else if (y > bounds.bottom - SCROLL_ACCURCY) { - ay = Math.min(Math.max(y + SCROLL_ACCURCY - bounds.bottom, 10), 50) / scale; + if (y < bounds.top + SCROLL_ACCURACY) { + ay = -Math.min(Math.max(bounds.top + SCROLL_ACCURACY - y, 10), 50) / scale; + } else if (y > bounds.bottom - SCROLL_ACCURACY) { + ay = Math.min(Math.max(y + SCROLL_ACCURACY - bounds.bottom, 10), 50) / scale; } - if (x < bounds.left + SCROLL_ACCURCY) { - ax = -Math.min(Math.max(bounds.top + SCROLL_ACCURCY - y, 10), 50) / scale; - } else if (x > bounds.right - SCROLL_ACCURCY) { - ax = Math.min(Math.max(x + SCROLL_ACCURCY - bounds.right, 10), 50) / scale; + if (x < bounds.left + SCROLL_ACCURACY) { + ax = -Math.min(Math.max(bounds.top + SCROLL_ACCURACY - y, 10), 50) / scale; + } else if (x > bounds.right - SCROLL_ACCURACY) { + ax = Math.min(Math.max(x + SCROLL_ACCURACY - bounds.right, 10), 50) / scale; } if (!ax && !ay) { diff --git a/packages/utils/src/app-helper.ts b/packages/utils/src/app-helper.ts index d5eb2072b3..86b535c592 100644 --- a/packages/utils/src/app-helper.ts +++ b/packages/utils/src/app-helper.ts @@ -34,18 +34,18 @@ export class AppHelper extends EventEmitter { } } - batchOn(events: Array<string | symbol>, lisenter: (...args: any[]) => void) { + batchOn(events: Array<string | symbol>, listener: (...args: any[]) => void) { if (!Array.isArray(events)) return; - events.forEach((event) => this.on(event, lisenter)); + events.forEach((event) => this.on(event, listener)); } - batchOnce(events: Array<string | symbol>, lisenter: (...args: any[]) => void) { + batchOnce(events: Array<string | symbol>, listener: (...args: any[]) => void) { if (!Array.isArray(events)) return; - events.forEach((event) => this.once(event, lisenter)); + events.forEach((event) => this.once(event, listener)); } - batchOff(events: Array<string | symbol>, lisenter: (...args: any[]) => void) { + batchOff(events: Array<string | symbol>, listener: (...args: any[]) => void) { if (!Array.isArray(events)) return; - events.forEach((event) => this.off(event, lisenter)); + events.forEach((event) => this.off(event, listener)); } } diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index 4e5a360b86..ad05221248 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -50,7 +50,7 @@ export function assetItem(type: AssetType, content?: string | null, level?: Asse }; } -export function megreAssets(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson): IPublicTypeAssetsJson { +export function mergeAssets(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson): IPublicTypeAssetsJson { if (incrementalAssets.packages) { assets.packages = [...(assets.packages || []), ...incrementalAssets.packages]; } @@ -59,13 +59,13 @@ export function megreAssets(assets: IPublicTypeAssetsJson, incrementalAssets: IP assets.components = [...(assets.components || []), ...incrementalAssets.components]; } - megreAssetsComponentList(assets, incrementalAssets, 'componentList'); - megreAssetsComponentList(assets, incrementalAssets, 'bizComponentList'); + mergeAssetsComponentList(assets, incrementalAssets, 'componentList'); + mergeAssetsComponentList(assets, incrementalAssets, 'bizComponentList'); return assets; } -function megreAssetsComponentList(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson, listName: keyof IPublicTypeAssetsJson): void { +function mergeAssetsComponentList(assets: IPublicTypeAssetsJson, incrementalAssets: IPublicTypeAssetsJson, listName: keyof IPublicTypeAssetsJson): void { if (incrementalAssets[listName]) { if (assets[listName]) { // 根据title进行合并 diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 58c7d23b19..4c8f375ecd 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -65,7 +65,7 @@ const levelMarks: Record<string, string> = { warn: 'warn', error: 'error', }; -const outputFuntion: Record<string, any> = { +const outputFunction: Record<string, any> = { debug: console.log, log: console.log, info: console.log, @@ -88,7 +88,7 @@ const shouldOutput = ( const output = (logLevel: string, bizName: string) => { return (...args: any[]) => { - return outputFuntion[logLevel].apply(console, getLogArgs(args, bizName, logLevel)); + return outputFunction[logLevel].apply(console, getLogArgs(args, bizName, logLevel)); }; }; From fc31145f89d6ca1b1377db044cbed0ebe436d268 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Sat, 7 Oct 2023 17:00:45 +0800 Subject: [PATCH 142/361] style: add style varibles and update some styles --- .../builtin-simulator/bem-tools/borders.less | 57 ++------- .../bem-tools/insertion.less | 2 +- .../designer/src/builtin-simulator/host.less | 6 +- .../node-selector/index.less | 2 +- .../src/designer/drag-ghost/ghost.less | 4 +- packages/designer/src/less-variables.less | 8 +- .../editor-core/src/widgets/tip/style.less | 12 +- .../editor-core/src/widgets/title/title.less | 2 +- .../src/components/field/fields.tsx | 34 ----- .../src/components/field/index.less | 117 +----------------- .../src/components/settings/style.less | 8 -- .../editor-skeleton/src/layouts/theme.less | 8 ++ .../src/layouts/workbench.less | 48 ++----- .../editor-skeleton/src/less-variables.less | 8 +- .../plugin-outline-pane/src/views/style.less | 48 +++---- packages/utils/src/create-icon.tsx | 6 +- packages/workspace/src/less-variables.less | 8 +- 17 files changed, 81 insertions(+), 297 deletions(-) diff --git a/packages/designer/src/builtin-simulator/bem-tools/borders.less b/packages/designer/src/builtin-simulator/bem-tools/borders.less index 2cdc9fb403..43fba6a2b8 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/borders.less +++ b/packages/designer/src/builtin-simulator/bem-tools/borders.less @@ -17,7 +17,7 @@ } & > &-status { margin-left: 5px; - color: #3c3c3c; + color: var(--color-text, #3c3c3c); transform: translateY(-100%); font-weight: lighter; } @@ -46,7 +46,7 @@ opacity: 1; max-height: 100%; overflow: hidden; - color: white; + color: var(--color-icon-reverse, white); &:hover { background: var(--color-brand-light, #006cff); } @@ -56,8 +56,8 @@ display: inline-block; width: 8px; height: 8px; - border: 1px solid #197aff; - background: #fff; + border: 1px solid var(--color-brand, #197aff); + background: var(--color-block-background-normal, #fff); pointer-events: auto; z-index: 2; } @@ -73,11 +73,9 @@ &:after { content: ""; display: block; - border: 1px solid #197aff; - background: #fff; - // background: #738397; + border: 1px solid var(--color-brand, #197aff); + background: var(--color-block-background-normal, #fff); border-radius: 2px; - // animation: flashing 1.5s infinite linear; } &.e, @@ -85,7 +83,6 @@ cursor: ew-resize; &:after { width: 4px; - // height: calc(100% - 20px); min-height: 50%; } } @@ -94,62 +91,24 @@ &.s { cursor: ns-resize; &:after { - // width: calc(100% - 20px); min-width: 50%; height: 4px; } } } - // &&-hovering { &&-detecting { z-index: 1; border-style: dashed; - background: rgba(0,121,242,.04); - - &.x-loop { - border-color: rgba(138, 93, 226, 0.8); - background: rgba(138, 93, 226, 0.04); - - >.@{scope}-title { - color: rgba(138, 93, 226, 1.0); - } - } - - &.x-condition { - border-color: rgba(255, 99, 8, 0.8); - background: rgba(255, 99, 8, 0.04); - >.@{scope}-title { - color: rgb(255, 99, 8); - } - } + background: var(--color-block-background-light, rgba(0,121,242,.04)); } &&-selecting { z-index: 2; border-width: 2px; - &.x-loop { - border-color: rgba(147, 112, 219, 1.0); - background: rgba(147, 112, 219, 0.04); - - >@{scope}-title { - color: rgba(147, 112, 219, 1.0); - } - &.highlight { - background: transparent; - } - } - - &.x-condition { - border-color: rgb(255, 99, 8); - >@{scope}-title { - color: rgb(255, 99, 8); - } - } - &.dragging { - background: rgba(182, 178, 178, 0.8); + background: var(--color-layer-mask-background, rgba(182, 178, 178, 0.8)); border: none; } } diff --git a/packages/designer/src/builtin-simulator/bem-tools/insertion.less b/packages/designer/src/builtin-simulator/bem-tools/insertion.less index 770d3893ca..c51e73106f 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/insertion.less +++ b/packages/designer/src/builtin-simulator/bem-tools/insertion.less @@ -23,6 +23,6 @@ } &.invalid { - background-color: red; + background-color: var(--color-function-error, red); } } diff --git a/packages/designer/src/builtin-simulator/host.less b/packages/designer/src/builtin-simulator/host.less index 5e230c4007..7130c42972 100644 --- a/packages/designer/src/builtin-simulator/host.less +++ b/packages/designer/src/builtin-simulator/host.less @@ -31,7 +31,7 @@ max-height: calc(100% - 32px); max-width: calc(100% - 32px); transform: translateX(-50%); - box-shadow: 0 2px 10px 0 rgba(31,56,88,.15); + box-shadow: 0 2px 10px 0 var(--color-block-background-shallow, rgba(31,56,88,.15)); } &-device-iphonex { // 增加默认的小程序的壳 @@ -44,7 +44,7 @@ background: url(https://img.alicdn.com/tfs/TB1b4DHilFR4u4jSZFPXXanzFXa-750-1574.png) no-repeat top; background-size: 375px 812px; border-radius: 44px; - box-shadow: rgba(0, 0, 0, 0.1) 0 36px 42px; + box-shadow: var(--color-block-background-shallow, rgba(0, 0, 0, 0.1)) 0 36px 42px; .@{scope}-canvas-viewport { width: auto; top: 50px; @@ -78,7 +78,7 @@ bottom: 16px; left: 16px; width: auto; - box-shadow: 0 1px 4px 0 rgba(31, 50, 88, 0.125); + box-shadow: 0 1px 4px 0 var(--color-block-background-shallow, rgba(31, 50, 88, 0.125)); } &-content { diff --git a/packages/designer/src/builtin-simulator/node-selector/index.less b/packages/designer/src/builtin-simulator/node-selector/index.less index c0335734e0..01552a2510 100644 --- a/packages/designer/src/builtin-simulator/node-selector/index.less +++ b/packages/designer/src/builtin-simulator/node-selector/index.less @@ -48,7 +48,7 @@ margin-top: 2px; &-content { padding-left: 6px; - background: #78869a; + background: var(--color-layer-tooltip-background, #78869a); display: inline-flex; border-radius: 3px; align-items: center; diff --git a/packages/designer/src/designer/drag-ghost/ghost.less b/packages/designer/src/designer/drag-ghost/ghost.less index 7ab61b41d6..1d9c03552f 100644 --- a/packages/designer/src/designer/drag-ghost/ghost.less +++ b/packages/designer/src/designer/drag-ghost/ghost.less @@ -7,8 +7,8 @@ flex-direction: column; align-items: center; pointer-events: none; - background-color: rgba(0, 0, 0, 0.4); - box-shadow: 0 0 6px grey; + background-color: var(--color-block-background-deep-dark, rgba(0, 0, 0, 0.4)); + box-shadow: 0 0 6px var(--color-block-background-shallow, grey); transform: translate(-10%, -50%); .lc-ghost { .lc-ghost-title { diff --git a/packages/designer/src/less-variables.less b/packages/designer/src/less-variables.less index c44fc196e2..017e432ce6 100644 --- a/packages/designer/src/less-variables.less +++ b/packages/designer/src/less-variables.less @@ -99,19 +99,19 @@ @brand-link-hover: #2e76a6; // F1-1-7 A10 -@brand-danger-alpha-7: rgba(240, 70, 49, 0.9); +@brand-danger-alpha-7: rgba(240, 70, 49, 0.1); // F1-1-8 A6 @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); // F2-1-2 A80 @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); // F2-1-7 A10 -@brand-warning-alpha-7: rgba(250, 189, 14, 0.9); +@brand-warning-alpha-7: rgba(250, 189, 14, 0.1); // F3-1-2 A80 @brand-success-alpha-2: rgba(102, 188, 92, 0.8); // F3-1-7 A10 -@brand-success-alpha-7: rgba(102, 188, 92, 0.9); +@brand-success-alpha-7: rgba(102, 188, 92, 0.1); // F4-1-7 A10 -@brand-link-alpha-7: rgba(102, 188, 92, 0.9); +@brand-link-alpha-7: rgba(102, 188, 92, 0.1); // 文本色 @text-primary-color: @dark-alpha-3; diff --git a/packages/editor-core/src/widgets/tip/style.less b/packages/editor-core/src/widgets/tip/style.less index 21b60b9b5d..aa5327f3d4 100644 --- a/packages/editor-core/src/widgets/tip/style.less +++ b/packages/editor-core/src/widgets/tip/style.less @@ -156,7 +156,7 @@ opacity: 0; border-radius: 3px; padding: 6px 8px; - text-shadow: 0 -1px rgba(0, 0, 0, 0.3); + text-shadow: 0 -1px var(--color-field-label, rgba(0, 0, 0, 0.3)); font-size: var(--font-size-text); line-height: 14px; max-width: 200px; @@ -178,19 +178,19 @@ height: 8px; &:after { border: 6px solid transparent; - border-top-color: rgba(0, 0, 0, 0.7); + border-top-color: var(--color-layer-tooltip-background, rgba(0, 0, 0, 0.7)); } } &.lc-theme-black { - background: rgba(0, 0, 0, 0.7); + background: var(--color-icon-pane, rgba(0, 0, 0, 0.7)); .lc-arrow:after { - border-top-color: rgba(0, 0, 0, 0.7); + border-top-color: var(--color-layer-tooltip-background, rgba(0, 0, 0, 0.7)); } } &.lc-theme-green { - background: #57a672; + background: var(--color-function-success-dark, #57a672); .lc-arrow:after { - border-top-color: #57a672; + border-top-color: var(--color-function-success-dark, #57a672); } } &.lc-visible { diff --git a/packages/editor-core/src/widgets/title/title.less b/packages/editor-core/src/widgets/title/title.less index e9d0765522..f6747ef474 100644 --- a/packages/editor-core/src/widgets/title/title.less +++ b/packages/editor-core/src/widgets/title/title.less @@ -21,7 +21,7 @@ cursor: help; text-decoration-line: underline; text-decoration-style: dashed; - text-decoration-color: rgba(31, 56, 88, .3); + text-decoration-color: var(--color-text-light, rgba(31, 56, 88, .3)); } line-height: initial !important; word-break: break-all; diff --git a/packages/editor-skeleton/src/components/field/fields.tsx b/packages/editor-skeleton/src/components/field/fields.tsx index b773995e3a..21ae93eb25 100644 --- a/packages/editor-skeleton/src/components/field/fields.tsx +++ b/packages/editor-skeleton/src/components/field/fields.tsx @@ -203,40 +203,6 @@ export class Field extends Component<FieldProps> { */ function createValueState(/* valueState?: number, onClear?: (e: React.MouseEvent) => void */) { return null; - - /* - let tip: any = null; - let className = 'lc-valuestate'; - let icon: any = null; - if (valueState) { - if (valueState < 0) { - // multiple value 橘黄色点: tip:多种值,点击清除 - tip = intlNode('Multiple Value, Click to Clear'); - className += ' valuestate-multiple'; - icon = <IconClear size={6} />; - } else if (valueState === 10) { - // isset orangered tip: 必填项 - tip = intlNode('Required'); - className += ' valuestate-required'; - onClear = undefined; - } else if (valueState > 0) { - // isset 蓝点 tip: 已设置值,点击清除 - tip = intlNode('Setted Value, Click to Clear'); - className += ' valuestate-isset'; - icon = <IconClear size={6} />; - } - } else { - onClear = undefined; - // unset 占位空间 - } - - return ( - <i className={className} onClick={onClear}> - {icon} - {tip && <Tip>{tip}</Tip>} - </i> - ); - */ } export interface PopupFieldProps extends FieldProps { diff --git a/packages/editor-skeleton/src/components/field/index.less b/packages/editor-skeleton/src/components/field/index.less index 249abef570..8c1facfbaf 100644 --- a/packages/editor-skeleton/src/components/field/index.less +++ b/packages/editor-skeleton/src/components/field/index.less @@ -14,54 +14,6 @@ .lc-field-title { display: flex; align-items: center; - .lc-valuestate { - height: 6px; - width: 6px; - min-width: 6px; - border-radius: 100%; - margin-right: 2px; - pointer-events: none; - display: inline-flex; - align-items: center; - justify-content: center; - color: white; - > svg { - display: none; - } - &.valuestate-multiple { - background-color: rgb(232, 145, 83); - pointer-events: auto; - &:hover { - background-color: rgb(223, 139, 30); - cursor: pointer; - transform: scale(2); - transform-origin: center; - > svg { - display: block; - } - } - } - &.valuestate-isset { - background-color: rgba(124, 177, 238, 0.6); - pointer-events: auto; - &:hover { - background-color: rgb(45, 126, 219); - cursor: pointer; - transform: scale(2); - transform-origin: center; - > svg { - display: block; - } - } - } - &.valuestate-required { - background-color: rgb(250, 82, 76); - pointer-events: auto; - &:hover { - background-color: rgb(224, 46, 40); - } - } - } } .lc-field-icon { transform-origin: center; @@ -92,11 +44,7 @@ &.lc-block-field, &.lc-accordion-field, &.lc-entry-field { display: block; - &:first-child { - > .lc-field-head { - // border-top: none; - } - } + > .lc-field-head { height: 32px; display: flex; @@ -110,7 +58,7 @@ user-select: none; > .lc-field-icon { - color: #8f9bb3; + color: var(--color-icon-normal, #8f9bb3); } } @@ -128,10 +76,6 @@ } } } - - // + .lc-inline-field { - // border-top: 1px solid var(--color-line-normal); - // } } &.lc-entry-field { @@ -163,15 +107,11 @@ > .lc-field-head { cursor: pointer; } - + &.lc-field-is-collapsed { margin-bottom: 6px; } - // collapsed - // &:last-child.lc-field-is-collapsed{ - // border-bottom: 1px solid var(--color-line-normal); - // } &.lc-field-is-collapsed { > .lc-field-head .lc-field-icon { transform: rotate(180deg); @@ -180,56 +120,5 @@ display: none; } } - - // 邻近的保持上下距离 - + .lc-field { - // margin-top: @y-gap; - } - } - - // 2rd level reset - .lc-field-body { - // .lc-inline-field { - // &:first-child { - // padding-top: 0; - // } - // + .lc-accordion-field, +.lc-block-field { - // margin-top: @y-gap; - // } - // } - - // .lc-field { - // border-top: none !important; - // } - - // .lc-accordion-field, .lc-block-field { - // > .lc-field-head { - // padding-left: @x-gap; - // background: var(--color-block-background-light); - // border-bottom: none; - // border-top: none; - // > .lc-field-icon { - // // margin-right: @x-gap/2; - // margin-right: 0; - // } - // } - - // > .lc-field-body { - // padding: 8px; - // } - // } - - // 3rd level field title width should short - // .lc-field-body .lc-inline-field { - // > .lc-field-head { - // width: 50px; - // .lc-title-label { - // width: 50px; - // } - // } - // } - // >.lc-block-setter { - // flex: 1; - // } } } diff --git a/packages/editor-skeleton/src/components/settings/style.less b/packages/editor-skeleton/src/components/settings/style.less index 57a7c9357f..4599ed55c2 100644 --- a/packages/editor-skeleton/src/components/settings/style.less +++ b/packages/editor-skeleton/src/components/settings/style.less @@ -33,14 +33,6 @@ position: relative; margin-bottom: 4px; position: absolute; - - .lc-setting-stage-back-icon { - position: absolute; - left: 8px; - top: 8px; - color: #8f9bb3; - cursor: pointer; - } } .lc-settings-notice { diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index 53afb69328..13fc19c847 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -16,6 +16,7 @@ --color-icon-hover: @normal-alpha-3; --color-icon-active: @brand-color-1; --color-icon-reverse: @white-alpha-1; + --color-icon-disabled: @normal-alpha-6; --color-icon-pane: @dark-alpha-3; --color-line-normal: @normal-alpha-7; @@ -27,6 +28,7 @@ --color-text-light: lighten(@dark-alpha-3, 10%); --color-text-reverse: @white-alpha-2; --color-text-regular: @normal-alpha-2; + --color-text-disabled: @gray-light; --color-field-label: @dark-alpha-4; --color-field-text: @dark-alpha-3; @@ -48,6 +50,8 @@ --color-function-error: @brand-danger; --color-function-error-dark: darken(@brand-danger, 10%); --color-function-error-light: lighten(@brand-danger, 10%); + --color-function-purple: rgb(144, 94, 190); + --color-function-brown: #7b605b; --color-pane-background: @white-alpha-1; --color-block-background-normal: @white-alpha-1; @@ -55,6 +59,10 @@ --color-block-background-shallow: @normal-alpha-8; --color-block-background-dark: @normal-alpha-7; --color-block-background-disabled: @normal-alpha-6; + --color-block-background-active: @brand-color-1-7; + --color-block-background-warning: @brand-warning-alpha-7; + --color-block-background-error: @brand-danger-alpha-7; + --color-block-background-success: @brand-success-alpha-7; --color-block-background-deep-dark: @normal-5; --color-layer-mask-background: @dark-alpha-7; --color-layer-tooltip-background: rgba(44,47,51,0.8); diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 38cbcfae09..58123ea464 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -60,7 +60,7 @@ body { .lc-help-tip { margin-left: 4px; - color: rgba(0, 0, 0, 0.4); + color: var(--color-icon-normal, rgba(0, 0, 0, 0.4)); cursor: pointer; } } @@ -68,7 +68,7 @@ body { height: 48px; font-size: 16px; padding: 0 15px; - color: #0f1726; + color: var(--color-title, #0f1726); font-weight: bold; } @@ -79,39 +79,6 @@ body { left: 0; right: 0; overflow: visible; - /* - .my-tabs { - width: 100%; - height: 100%; - position: relative; - .tabs-title { - display: flex; - height: var(--pane-title-height); - > .tab-title { - cursor: pointer; - padding: 0; - flex: 1; - min-width: 0; - justify-content: center; - border-bottom: 2px solid transparent; - &.actived { - cursor: default; - color: var(--color-text-avtived); - border-bottom-color: #3896ee; - } - } - } - .tabs-content { - position: absolute; - top: var(--pane-title-height); - bottom: 0; - left: 0; - right: 0; - height: calc(100% - var(--pane-title-height)); - overflow: hidden; - } - } - */ } .lc-outline-tree-container { border-top: 1px solid var(--color-line-normal, rgba(31, 56, 88, 0.1)); @@ -234,8 +201,7 @@ body { display: flex; justify-content: center; align-items: center; - // background: rgba(31,56,88,0.04); - border-bottom: 1px solid #edeff3; + border-bottom: 1px solid var(--color-line-normal, #edeff3); .lc-tab-title { flex: 1; height: 32px; @@ -246,8 +212,8 @@ body { cursor: pointer; font-size: 12px; &.actived { - color: #0079f2; - border-bottom-color: #0079f2; + color: var(--color-brand, #0079f2); + border-bottom-color: var(--color-brand, #0079f2); } } } @@ -293,7 +259,7 @@ body { // min-width: var(--dock-fixed-pane-width); left: calc(var(--left-area-width) + 1px); background-color: var(--color-left-float-pane-background, var(--color-pane-background)); - box-shadow: 4px 6px 6px 0 rgba(31, 50, 88, 0.08); + box-shadow: 4px 6px 6px 0 var(--color-block-background-shallow, rgba(31, 50, 88, 0.08)); z-index: 820; display: none; // padding-top: 36px; @@ -340,7 +306,7 @@ body { cursor: pointer; } &.actived { - color: #0079f2; + color: var(--color-brand, #0079f2); } &.disabled { opacity: 0.4; diff --git a/packages/editor-skeleton/src/less-variables.less b/packages/editor-skeleton/src/less-variables.less index c44fc196e2..017e432ce6 100644 --- a/packages/editor-skeleton/src/less-variables.less +++ b/packages/editor-skeleton/src/less-variables.less @@ -99,19 +99,19 @@ @brand-link-hover: #2e76a6; // F1-1-7 A10 -@brand-danger-alpha-7: rgba(240, 70, 49, 0.9); +@brand-danger-alpha-7: rgba(240, 70, 49, 0.1); // F1-1-8 A6 @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); // F2-1-2 A80 @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); // F2-1-7 A10 -@brand-warning-alpha-7: rgba(250, 189, 14, 0.9); +@brand-warning-alpha-7: rgba(250, 189, 14, 0.1); // F3-1-2 A80 @brand-success-alpha-2: rgba(102, 188, 92, 0.8); // F3-1-7 A10 -@brand-success-alpha-7: rgba(102, 188, 92, 0.9); +@brand-success-alpha-7: rgba(102, 188, 92, 0.1); // F4-1-7 A10 -@brand-link-alpha-7: rgba(102, 188, 92, 0.9); +@brand-link-alpha-7: rgba(102, 188, 92, 0.1); // 文本色 @text-primary-color: @dark-alpha-3; diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index 406a5b5da4..37f51a170d 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -54,17 +54,17 @@ .tree-node-modal { margin: 5px; - border: 1px solid rgba(31, 56, 88, 0.2); + border: 1px solid var(--color-field-border, rgba(31, 56, 88, 0.2)); border-radius: 3px; - box-shadow: 0 1px 4px 0 rgba(31, 56, 88, 0.15); + box-shadow: 0 1px 4px 0 var(--color-block-background-shallow, rgba(31, 56, 88, 0.15)); .tree-node-modal-title { position: relative; - background: rgba(31, 56, 88, 0.04); + background: var(--color-block-background-light, rgba(31, 56, 88, 0.04)); padding: 0 10px; height: 32px; line-height: 32px; - border-bottom: 1px solid rgba(31, 56, 88, 0.2); + border-bottom: 1px solid var(--color-field-border, rgba(31, 56, 88, 0.2)); .tree-node-modal-title-visible-icon { position: absolute; @@ -89,7 +89,7 @@ left: 6px; } .tree-node-modal-radio-active { - color: #006cff; + color: var(--color-brand, #006cff); } } @@ -108,7 +108,7 @@ &:hover { .tree-node-branches::before { - border-left-color: #ddd; + border-left-color: var(--color-line-darken, #ddd); } } @@ -120,20 +120,20 @@ transform: translateZ(0); transition: all 0.2s ease-in-out; &.invalid { - border-color: red; - background-color: rgba(240, 154, 154, 0.719); + border-color: var(--color-function-error, red); + background-color: var(--color-block-background-error, rgba(240, 154, 154, 0.719)); } } .condition-group-container { - border-bottom: 1px solid #7b605b; + border-bottom: 1px solid var(--color-function-brown, #7b605b); position: relative; &:before { position: absolute; display: block; width: 0; - border-left: 0.5px solid #7b605b; + border-left: 0.5px solid var(--color-function-brown, #7b605b); height: 100%; top: 0; left: 0; @@ -142,26 +142,26 @@ } > .condition-group-title { text-align: center; - background-color: #7b605b; + background-color: var(--color-function-brown, #7b605b); height: 14px; > .lc-title { font-size: 12px; transform: scale(0.8); transform-origin: top; - color: white; - text-shadow: 0 0 2px black; + color: var(--color-text-reverse, white); + text-shadow: 0 0 2px var(--color-block-background-shallow, black); display: block; } } } .tree-node-slots { - border-bottom: 1px solid rgb(144, 94, 190); + border-bottom: 1px solid var(--color-function-purple, rgb(144, 94, 190)); position: relative; &::before { position: absolute; display: block; width: 0; - border-left: 0.5px solid rgb(144, 94, 190); + border-left: 0.5px solid var(--color-function-purple, rgb(144, 94, 190)); height: 100%; top: 0; left: 0; @@ -170,25 +170,25 @@ } > .tree-node-slots-title { text-align: center; - background-color: rgb(144, 94, 190); + background-color: var(--color-function-purple, rgb(144, 94, 190)); height: 14px; > .lc-title { font-size: 12px; transform: scale(0.8); transform-origin: top; - color: white; + color: var(--color-text-reverse, white); text-shadow: 0 0 2px black; display: block; } } &.insertion-at-slots { padding-bottom: @treeNodeHeight; - border-bottom-color: rgb(182, 55, 55); + border-bottom-color: var(--color-function-error-dark, rgb(182, 55, 55)); > .tree-node-slots-title { - background-color: rgb(182, 55, 55); + background-color: var(--color-function-error-dark, rgb(182, 55, 55)); } &::before { - border-left-color: rgb(182, 55, 55); + border-left-color: var(--color-function-error-dark, rgb(182, 55, 55)); } } } @@ -326,13 +326,13 @@ align-items: center; line-height: 0; &.cond { - color: rgb(179, 52, 6); + color: var(--color-function-error, rgb(179, 52, 6)); } &.loop { - color: rgb(103, 187, 187); + color: var(--color-function-success, rgb(103, 187, 187)); } &.slot { - color: rgb(211, 90, 211); + color: var(--color-function-purple, rgb(211, 90, 211)); } } } @@ -366,7 +366,7 @@ &.hidden { .tree-node-title-label { - color: #9b9b9b; + color: var(--color-text-disabled, #9b9b9b); } & > .tree-node-title > .tree-node-hide-btn { opacity: 0.8; diff --git a/packages/utils/src/create-icon.tsx b/packages/utils/src/create-icon.tsx index 0f25005298..0a5d6c1ff7 100644 --- a/packages/utils/src/create-icon.tsx +++ b/packages/utils/src/create-icon.tsx @@ -18,7 +18,11 @@ export function createIcon( } if (typeof icon === 'string') { if (URL_RE.test(icon)) { - return <img src={icon} {...props} />; + return createElement('img', { + src: icon, + class: props?.className, + ...props, + }); } return <Icon type={icon} {...props} />; } diff --git a/packages/workspace/src/less-variables.less b/packages/workspace/src/less-variables.less index c44fc196e2..017e432ce6 100644 --- a/packages/workspace/src/less-variables.less +++ b/packages/workspace/src/less-variables.less @@ -99,19 +99,19 @@ @brand-link-hover: #2e76a6; // F1-1-7 A10 -@brand-danger-alpha-7: rgba(240, 70, 49, 0.9); +@brand-danger-alpha-7: rgba(240, 70, 49, 0.1); // F1-1-8 A6 @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); // F2-1-2 A80 @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); // F2-1-7 A10 -@brand-warning-alpha-7: rgba(250, 189, 14, 0.9); +@brand-warning-alpha-7: rgba(250, 189, 14, 0.1); // F3-1-2 A80 @brand-success-alpha-2: rgba(102, 188, 92, 0.8); // F3-1-7 A10 -@brand-success-alpha-7: rgba(102, 188, 92, 0.9); +@brand-success-alpha-7: rgba(102, 188, 92, 0.1); // F4-1-7 A10 -@brand-link-alpha-7: rgba(102, 188, 92, 0.9); +@brand-link-alpha-7: rgba(102, 188, 92, 0.1); // 文本色 @text-primary-color: @dark-alpha-3; From 82d82b9d0596f75080d4bde1bfea5ef86a47ad19 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Sun, 8 Oct 2023 18:04:33 +0800 Subject: [PATCH 143/361] feat: update Outline Tree to Component Tree --- packages/plugin-outline-pane/src/locale/en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-outline-pane/src/locale/en-US.json b/packages/plugin-outline-pane/src/locale/en-US.json index 9ade9e66f4..b86a7859bb 100644 --- a/packages/plugin-outline-pane/src/locale/en-US.json +++ b/packages/plugin-outline-pane/src/locale/en-US.json @@ -10,7 +10,7 @@ "Loop": "Loop", "Slots": "Slots", "Slot for {prop}": "Slot for {prop}", - "Outline Tree": "Outline Tree", + "Outline Tree": "Component Tree", "Filter Node": "Filter Node", "Check All": "Check All", "Conditional rendering": "Conditional rendering", From 4684d3171797765fe4a480a4ce23503747663da7 Mon Sep 17 00:00:00 2001 From: rainke <woshihepeng520@163.com> Date: Mon, 9 Oct 2023 09:59:39 +0800 Subject: [PATCH 144/361] chore: resolve react-error-overlay to 6.0.9 --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a650c49b6..aded2a3015 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,8 @@ "lockfile": "enable" }, "resolutions": { - "typescript": "4.6.2" + "typescript": "4.6.2", + "react-error-overlay": "6.0.9" }, "repository": "git@github.com:alibaba/lowcode-engine.git" } From 30f8066332b277335b67b681da9fe263d9a15e38 Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Thu, 12 Oct 2023 08:45:34 +0800 Subject: [PATCH 145/361] fix: fix rendering failure when children is number 0 --- packages/renderer-core/src/renderer/base.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 216735edcf..72821cfd38 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -453,7 +453,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { * @param idx 为循环渲染的循环Index */ __createVirtualDom = (originalSchema: IPublicTypeNodeData | IPublicTypeNodeData[] | undefined, originalScope: any, parentInfo: INodeInfo, idx: string | number = ''): any => { - if (!originalSchema) { + if (originalSchema === null || originalSchema === undefined) { return null; } let scope = originalScope; From 3129445d60935db69bf14b81bee5e302f22053db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=AD=A3?= <lizhengnacl@163.com> Date: Tue, 10 Oct 2023 17:11:07 +0800 Subject: [PATCH 146/361] Update specs.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 去掉重复内容 --- docs/docs/guide/design/specs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/design/specs.md b/docs/docs/guide/design/specs.md index 0d97f5cc08..2e8e4c195c 100644 --- a/docs/docs/guide/design/specs.md +++ b/docs/docs/guide/design/specs.md @@ -58,7 +58,7 @@ sidebar_position: 1 ## 协议的作用 -基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。 +基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。 ### 打破物料孤岛 From ca6fe7c335b5035eba18a8681a4bb7a5ccac83b3 Mon Sep 17 00:00:00 2001 From: rainke <woshihepeng520@163.com> Date: Wed, 11 Oct 2023 14:55:05 +0800 Subject: [PATCH 147/361] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20forwardRef?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6=E7=9A=84=E9=94=99=E8=AF=AF=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=8D=95=E8=8E=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../renderer/__snapshots__/demo.test.tsx.snap | 1 + packages/renderer-core/src/hoc/index.tsx | 70 ++++++++++++++++--- packages/renderer-core/src/renderer/base.tsx | 8 +-- .../renderer-core/src/renderer/renderer.tsx | 48 ------------- packages/renderer-core/src/types/index.ts | 1 - packages/utils/src/is-react.ts | 13 +++- 6 files changed, 75 insertions(+), 66 deletions(-) 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 0ebb606dac..2f2d19f269 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 @@ -31,6 +31,7 @@ exports[`Base should be render Text 1`] = ` behavior="NORMAL" componentId="node_ockvuu8u916" fieldId="text_kvuu9gl2" + forwardRef={[Function]} maxLine={0} showTitle={false} > diff --git a/packages/renderer-core/src/hoc/index.tsx b/packages/renderer-core/src/hoc/index.tsx index a9314060f3..aae03045ec 100644 --- a/packages/renderer-core/src/hoc/index.tsx +++ b/packages/renderer-core/src/hoc/index.tsx @@ -1,20 +1,72 @@ import { cloneEnumerableProperty } from '@alilc/lowcode-utils'; import adapter from '../adapter'; +import { IBaseRendererInstance, IRendererProps } from '../types'; -export function compWrapper(Comp: any) { +function patchDidCatch(Comp: any, { baseRenderer }: { baseRenderer: IBaseRendererInstance }) { + if (Comp.patchedCatch) { + return; + } + Comp.patchedCatch = true; + const { PureComponent } = adapter.getRuntime(); + // Rax 的 getDerivedStateFromError 有 BUG,这里先用 componentDidCatch 来替代 + // @see https://github.com/alibaba/rax/issues/2211 + const originalDidCatch = Comp.prototype.componentDidCatch; + Comp.prototype.componentDidCatch = function didCatch(this: any, error: Error, errorInfo: any) { + this.setState({ engineRenderError: true, error }); + if (originalDidCatch && typeof originalDidCatch === 'function') { + originalDidCatch.call(this, error, errorInfo); + } + }; + + const { engine } = baseRenderer.context; + const originRender = Comp.prototype.render; + Comp.prototype.render = function () { + if (this.state && this.state.engineRenderError) { + this.state.engineRenderError = false; + return engine.createElement(engine.getFaultComponent(), { + ...this.props, + error: this.state.error, + componentName: this.props._componentName, + }); + } + return originRender.call(this); + }; + if (!(Comp.prototype instanceof PureComponent)) { + const originShouldComponentUpdate = Comp.prototype.shouldComponentUpdate; + Comp.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) { + if (nextState && nextState.engineRenderError) { + return true; + } + return originShouldComponentUpdate + ? originShouldComponentUpdate.call(this, nextProps, nextState) + : true; + }; + } +} + +export function compWrapper(Comp: any, options: { baseRenderer: IBaseRendererInstance }) { const { createElement, Component, forwardRef } = adapter.getRuntime(); + if ( + Comp?.prototype?.isReactComponent || // react + Comp?.prototype?.setState || // rax + Comp?.prototype instanceof Component + ) { + patchDidCatch(Comp, options); + return Comp; + } class Wrapper extends Component { - // constructor(props: any, context: any) { - // super(props, context); - // } - render() { - return createElement(Comp, this.props); + return createElement(Comp, { ...this.props, ref: this.props.forwardRef }); } } (Wrapper as any).displayName = Comp.displayName; - return cloneEnumerableProperty(forwardRef((props: any, ref: any) => { - return createElement(Wrapper, { ...props, forwardRef: ref }); - }), Comp); + patchDidCatch(Wrapper, options); + + return cloneEnumerableProperty( + forwardRef((props: any, ref: any) => { + return createElement(Wrapper, { ...props, forwardRef: ref }); + }), + Comp, + ); } diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 72821cfd38..2ed476b1c4 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -23,7 +23,6 @@ import { transformStringToFunction, checkPropTypes, getI18n, - canAcceptsRef, getFileCssName, capitalizeFirstLetter, DataHelper, @@ -616,11 +615,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); }); - // 对于不可以接收到 ref 的组件需要做特殊处理 - if (!canAcceptsRef(Comp)) { - Comp = compWrapper(Comp); - components[schema.componentName] = Comp; - } + Comp = compWrapper(Comp, { baseRenderer: this }); + components[schema.componentName] = Comp; otherProps.ref = (ref: any) => { this.$(props.fieldId || props.ref, ref); // 收集ref diff --git a/packages/renderer-core/src/renderer/renderer.tsx b/packages/renderer-core/src/renderer/renderer.tsx index 09559b6f89..300b1cd164 100644 --- a/packages/renderer-core/src/renderer/renderer.tsx +++ b/packages/renderer-core/src/renderer/renderer.tsx @@ -105,55 +105,7 @@ export default function rendererFactory(): IRenderComponent { return SetComponent; } - patchDidCatch(SetComponent: any) { - if (!this.isValidComponent(SetComponent)) { - return; - } - if (SetComponent.patchedCatch) { - return; - } - if (!SetComponent.prototype) { - return; - } - SetComponent.patchedCatch = true; - - // Rax 的 getDerivedStateFromError 有 BUG,这里先用 componentDidCatch 来替代 - // @see https://github.com/alibaba/rax/issues/2211 - const originalDidCatch = SetComponent.prototype.componentDidCatch; - SetComponent.prototype.componentDidCatch = function didCatch(this: any, error: Error, errorInfo: any) { - this.setState({ engineRenderError: true, error }); - if (originalDidCatch && typeof originalDidCatch === 'function') { - originalDidCatch.call(this, error, errorInfo); - } - }; - - const engine = this; - const originRender = SetComponent.prototype.render; - SetComponent.prototype.render = function () { - if (this.state && this.state.engineRenderError) { - this.state.engineRenderError = false; - return engine.createElement(engine.getFaultComponent(), { - ...this.props, - error: this.state.error, - componentName: this.props._componentName - }); - } - return originRender.call(this); - }; - if(!(SetComponent.prototype instanceof PureComponent)) { - const originShouldComponentUpdate = SetComponent.prototype.shouldComponentUpdate; - SetComponent.prototype.shouldComponentUpdate = function (nextProps: IRendererProps, nextState: any) { - if (nextState && nextState.engineRenderError) { - return true; - } - return originShouldComponentUpdate ? originShouldComponentUpdate.call(this, nextProps, nextState) : true; - }; - } - } - createElement(SetComponent: any, props: any, children?: any) { - // TODO: enable in runtime mode? - this.patchDidCatch(SetComponent); return (this.props.customCreateElement || createElement)(SetComponent, props, children); } diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index a49fe89920..afbec272ab 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -335,7 +335,6 @@ export interface IRenderComponent { componentDidCatch(e: any): Promise<void> | void; shouldComponentUpdate(nextProps: IRendererProps): boolean; isValidComponent(SetComponent: any): any; - patchDidCatch(SetComponent: any): void; createElement(SetComponent: any, props: any, children?: any): any; getNotFoundComponent(): any; getFaultComponent(): any; diff --git a/packages/utils/src/is-react.ts b/packages/utils/src/is-react.ts index 07568db981..b19f043f14 100644 --- a/packages/utils/src/is-react.ts +++ b/packages/utils/src/is-react.ts @@ -10,10 +10,10 @@ export function isReactClass(obj: any): obj is ComponentClass<any> { } export function acceptsRef(obj: any): boolean { - return obj?.prototype?.isReactComponent || (obj.$$typeof && obj.$$typeof === REACT_FORWARD_REF_TYPE); + return obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj); } -function isForwardRefType(obj: any): boolean { +export function isForwardRefType(obj: any): boolean { return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE; } @@ -21,6 +21,15 @@ function isMemoType(obj: any): boolean { return obj?.$$typeof && obj.$$typeof === REACT_MEMO_TYPE; } +export function isForwardOrMemoForward(obj: any): boolean { + return obj?.$$typeof && ( + // React.forwardRef(..) + isForwardRefType(obj) || + // React.memo(React.forwardRef(..)) + (isMemoType(obj) && isForwardRefType(obj.type)) + ); +} + export function isReactComponent(obj: any): obj is ComponentType<any> { if (!obj) { return false; From a96961f588971805ef0cdb5e07af2ab14475ac74 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 16 Oct 2023 14:35:10 +0800 Subject: [PATCH 148/361] docs: publish docs 1.1.11 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 3950b35c9c..6c43fe1d0f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.10", + "version": "1.1.11", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 7677ad0166f479fa78c78dfb6d69fb8a3617cbd9 Mon Sep 17 00:00:00 2001 From: rainke <woshihepeng520@163.com> Date: Tue, 17 Oct 2023 17:33:07 +0800 Subject: [PATCH 149/361] =?UTF-8?q?fix:=20hoc=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderer-core/src/hoc/index.tsx | 22 +++++++++++++++++--- packages/renderer-core/src/renderer/base.tsx | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/renderer-core/src/hoc/index.tsx b/packages/renderer-core/src/hoc/index.tsx index aae03045ec..3e7f5ec6a1 100644 --- a/packages/renderer-core/src/hoc/index.tsx +++ b/packages/renderer-core/src/hoc/index.tsx @@ -2,7 +2,12 @@ import { cloneEnumerableProperty } from '@alilc/lowcode-utils'; import adapter from '../adapter'; import { IBaseRendererInstance, IRendererProps } from '../types'; -function patchDidCatch(Comp: any, { baseRenderer }: { baseRenderer: IBaseRendererInstance }) { +interface Options { + baseRenderer: IBaseRendererInstance; + schema: any; +} + +function patchDidCatch(Comp: any, { baseRenderer }: Options) { if (Comp.patchedCatch) { return; } @@ -44,7 +49,9 @@ function patchDidCatch(Comp: any, { baseRenderer }: { baseRenderer: IBaseRendere } } -export function compWrapper(Comp: any, options: { baseRenderer: IBaseRendererInstance }) { +const cache = new Map(); + +export function compWrapper(Comp: any, options: Options) { const { createElement, Component, forwardRef } = adapter.getRuntime(); if ( Comp?.prototype?.isReactComponent || // react @@ -54,6 +61,11 @@ export function compWrapper(Comp: any, options: { baseRenderer: IBaseRendererIns patchDidCatch(Comp, options); return Comp; } + + if (cache.has(options.schema.id)) { + return cache.get(options.schema.id); + } + class Wrapper extends Component { render() { return createElement(Comp, { ...this.props, ref: this.props.forwardRef }); @@ -63,10 +75,14 @@ export function compWrapper(Comp: any, options: { baseRenderer: IBaseRendererIns patchDidCatch(Wrapper, options); - return cloneEnumerableProperty( + const WrapperComponent = cloneEnumerableProperty( forwardRef((props: any, ref: any) => { return createElement(Wrapper, { ...props, forwardRef: ref }); }), Comp, ); + + cache.set(options.schema.id, WrapperComponent); + + return WrapperComponent; } diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 2ed476b1c4..7b9562fcc6 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -615,7 +615,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); }); - Comp = compWrapper(Comp, { baseRenderer: this }); + Comp = compWrapper(Comp, { baseRenderer: this, schema }); components[schema.componentName] = Comp; otherProps.ref = (ref: any) => { From d56ed6bff172f3833f5321073310fac5d54bd247 Mon Sep 17 00:00:00 2001 From: rainke <woshihepeng520@163.com> Date: Mon, 16 Oct 2023 16:59:03 +0800 Subject: [PATCH 150/361] feat: make asset support es module --- packages/designer/src/builtin-simulator/create-simulator.ts | 5 +++-- packages/types/src/assets.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/builtin-simulator/create-simulator.ts b/packages/designer/src/builtin-simulator/create-simulator.ts index 15ab3507b5..57369efd89 100644 --- a/packages/designer/src/builtin-simulator/create-simulator.ts +++ b/packages/designer/src/builtin-simulator/create-simulator.ts @@ -56,12 +56,13 @@ export function createSimulator( } const id = asset.id ? ` data-id="${asset.id}"` : ''; const lv = asset.level || level || AssetLevel.Environment; + const scriptType = asset.scriptType ? ` type="${asset.scriptType}"` : ''; if (asset.type === AssetType.JSUrl) { scripts[lv].push( - `<script src="${asset.content}"${id}></script>`, + `<script src="${asset.content}"${id}${scriptType}></script>`, ); } else if (asset.type === AssetType.JSText) { - scripts[lv].push(`<script${id}>${asset.content}</script>`); + scripts[lv].push(`<script${id}${scriptType}>${asset.content}</script>`); } else if (asset.type === AssetType.CSSUrl) { styles[lv].push( `<link rel="stylesheet" href="${asset.content}"${id} />`, diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index 852ed00380..f0e6d35396 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -38,6 +38,7 @@ export interface AssetItem { device?: string; level?: AssetLevel; id?: string; + scriptType?: string; } export type AssetList = Array<Asset | undefined | null>; From 96fe876e331d91f36989e9660b86f72b223dc5a4 Mon Sep 17 00:00:00 2001 From: rainke <woshihepeng520@163.com> Date: Fri, 13 Oct 2023 16:57:26 +0800 Subject: [PATCH 151/361] =?UTF-8?q?fix:=20=E5=A4=8D=E5=88=B6=E6=97=B6?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=20ref=20=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/src/component-actions.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/designer/src/component-actions.ts b/packages/designer/src/component-actions.ts index 76ead7d9a6..57ad30bf25 100644 --- a/packages/designer/src/component-actions.ts +++ b/packages/designer/src/component-actions.ts @@ -10,6 +10,14 @@ import { } from './icons'; import { componentDefaults, legacyIssues } from './transducers'; +function deduplicateRef(node: IPublicModelNode | null | undefined) { + const currentRef = node?.getPropValue('ref'); + if (currentRef) { + node?.setPropValue('ref', `${node.componentName.toLowerCase()}-${Math.random().toString(36).slice(2, 9)}`); + } + node?.children?.forEach(deduplicateRef); +} + export class ComponentActions { private metadataTransducers: IPublicTypeMetadataTransducer[] = []; @@ -53,6 +61,7 @@ export class ComponentActions { const { document: doc, parent, index } = node; if (parent) { const newNode = doc?.insertNode(parent, node, (index ?? 0) + 1, true); + deduplicateRef(newNode); newNode?.select(); const { isRGL, rglNode } = node?.getRGL(); if (isRGL) { From 79b9a6efa57d1a30559ea8476bbb380b5957d968 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 19 Oct 2023 11:05:41 +0800 Subject: [PATCH 152/361] feat: add theme color document & optimize some theme colors --- docs/docs/guide/expand/editor/cli.md | 2 +- docs/docs/guide/expand/editor/graph.md | 2 +- docs/docs/guide/expand/editor/setter.md | 2 +- docs/docs/guide/expand/editor/theme.md | 91 +++++++++++++++++++ .../bem-tools/insertion.less | 2 +- .../editor-core/src/widgets/tip/style.less | 4 +- .../src/layouts/sub-top-area.tsx | 8 +- .../editor-skeleton/src/layouts/theme.less | 46 +++++++--- .../editor-skeleton/src/layouts/top-area.tsx | 6 +- .../src/layouts/workbench.less | 27 +++--- .../plugin-outline-pane/src/views/style.less | 26 +++--- packages/workspace/src/layouts/workbench.tsx | 2 +- 12 files changed, 165 insertions(+), 53 deletions(-) create mode 100644 docs/docs/guide/expand/editor/theme.md diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index 60f44ce875..0577a181db 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -1,6 +1,6 @@ --- title: 低代码生态脚手架 & 调试机制 -sidebar_position: 8 +sidebar_position: 10 --- ## 脚手架简述 diff --git a/docs/docs/guide/expand/editor/graph.md b/docs/docs/guide/expand/editor/graph.md index 2d5127054e..a45f34baf0 100644 --- a/docs/docs/guide/expand/editor/graph.md +++ b/docs/docs/guide/expand/editor/graph.md @@ -1,6 +1,6 @@ --- title: 图编排扩展 -sidebar_position: 9 +sidebar_position: 8 --- ## 项目运行 ### 前置准备 diff --git a/docs/docs/guide/expand/editor/setter.md b/docs/docs/guide/expand/editor/setter.md index 01fd949bbd..4f0e0219fc 100644 --- a/docs/docs/guide/expand/editor/setter.md +++ b/docs/docs/guide/expand/editor/setter.md @@ -1,6 +1,6 @@ --- title: 设置器扩展 -sidebar_position: 5 +sidebar_position: 7 --- ## 设置器简述 diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md new file mode 100644 index 0000000000..b62fb4f28c --- /dev/null +++ b/docs/docs/guide/expand/editor/theme.md @@ -0,0 +1,91 @@ +--- +title: 主题色扩展 +sidebar_position: 9 +--- + +## 主题色扩展简述 + +通过主题色扩展,可以定制多种设计器主题。 + +## 主题色扩展说明 + +### 主题色变量 + +- `--color-brand`: 品牌色 +- `--color-brand-light`: 品牌色(light) +- `--color-brand-dark`: 品牌色(dark) +- `--color-icon-normal`: 正常 icon 颜色 +- `--color-icon-hover`: icon hover 态颜色 +- `--color-icon-active`: icon active 态颜色 +- `--color-icon-reverse`: icon 反色 +- `--color-icon-disabled`: icon 禁用态颜色 +- `--color-icon-pane`: icon 面板颜色 +- `--color-line-normal`: 线条颜色 +- `--color-line-darken`: 线条颜色(darken) +- `--color-title`: 标题颜色 +- `--color-text`: 文字颜色 +- `--color-text-dark`: 文字颜色(dark) +- `--color-text-light`: 文字颜色(light) +- `--color-text-reverse`: 反色情况下,文字颜色 +- `--color-text-regular`: 文字颜色(regular) +- `--color-text-disabled`: 禁用态文字颜色 +- `--color-field-label`: field 标签颜色 +- `--color-field-text`: field 文本颜色 +- `--color-field-placeholder`: field placeholder 颜色 +- `--color-field-border`: field 边框颜色 +- `--color-field-border-hover`: hover 态下,field 边框颜色 +- `--color-field-border-active`: active 态下,field 边框颜色 +- `--color-field-background`: field 背景色 +- `--color-success`: success 颜色 +- `--colo-success-dark`: success 颜色(dark) +- `--color-success-light`: success 颜色(light) +- `--color-warning`: warning 颜色 +- `--color-warning-dark`: warning 颜色(dark) +- `--color-warning-light`: warning 颜色(light) +- `--color-information`: information 颜色 +- `--color-information-dark`: information 颜色(dark) +- `--color-information-light`: information 颜色(light) +- `--color-error`: error 颜色 +- `--color-error-dark`: error 颜色(dark) +- `--color-error-light`: error 颜色(light) +- `--color-purple`: purple 颜色 +- `--color-brown`: brown 颜色 +- `--color-pane-background`: 面板背景色 +- `--color-block-background-normal`: 区块背景色 +- `--color-block-background-light`: 区块背景色(light), 作用于画布组件 hover 时遮罩背景色。 +- `--color-block-background-shallow`: 区块背景色 shallow +- `--color-block-background-dark`: 区块背景色(dark) +- `--color-block-background-disabled`: 区块背景色(disabled) +- `--color-block-background-active`: 区块背景色(active) +- `--color-block-background-warning`: 区块背景色(warning) +- `--color-block-background-error`: 区块背景色(error) +- `--color-block-background-success`: 区块背景色(success) +- `--color-block-background-deep-dark`: 区块背景色(deep-dark),作用于多个组件同时拖拽的背景色。 +- `--color-layer-mask-background`: 拖拽元素时,元素原来位置的遮罩背景色 +- `--color-layer-tooltip-background`: tooltip 背景色 +- `--color-background`: 设计器主要背景色 +- `--color-top-area-background`: topArea 背景色,优先级大于 `--color-pane-background` +- `--color-left-area-background`: leftArea 背景色,优先级大于 `--color-pane-background` +- `--color-workspace-left-area-background`: 应用级 leftArea 背景色,优先级大于 `--color-pane-background` +- `--color-workspace-top-area-background`: 应用级 topArea 背景色,优先级大于 `--color-pane-background` +- `--color-workspace-sub-top-area-background`: 应用级二级 topArea 背景色,优先级大于 `--color-pane-background` +- `--workspace-sub-top-area-height`: 应用级二级 topArea 高度 +- `--workspace-sub-top-area-margin`: 应用级二级 topArea margin +- `--workspace-sub-top-area-padding`: 应用级二级 topArea padding + +### 生态使用主题色变量 + +插件、物料、设置器等生态为了支持主题色需要对样式进行改造,需要对生态中的样式升级为 css 变量。例如: + +```css +/* before */ +background: #006cff; + +/* after */ +background: var(--color-brand, #006cff); + +``` + +### fusion 物料进行主题色扩展 + +如果使用了 fusion 组件,可以通过 https://fusion.alibaba-inc.com/ 平台进行主题色定制。 \ No newline at end of file diff --git a/packages/designer/src/builtin-simulator/bem-tools/insertion.less b/packages/designer/src/builtin-simulator/bem-tools/insertion.less index c51e73106f..fff045631a 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/insertion.less +++ b/packages/designer/src/builtin-simulator/bem-tools/insertion.less @@ -23,6 +23,6 @@ } &.invalid { - background-color: var(--color-function-error, red); + background-color: var(--color-error, var(--color-function-error, red)); } } diff --git a/packages/editor-core/src/widgets/tip/style.less b/packages/editor-core/src/widgets/tip/style.less index aa5327f3d4..602886d060 100644 --- a/packages/editor-core/src/widgets/tip/style.less +++ b/packages/editor-core/src/widgets/tip/style.less @@ -188,9 +188,9 @@ } } &.lc-theme-green { - background: var(--color-function-success-dark, #57a672); + background: var(--color-success-dark, var(--color-function-success-dark, #57a672)); .lc-arrow:after { - border-top-color: var(--color-function-success-dark, #57a672); + border-top-color: var(--color-success-dark, var(--color-function-success-dark, #57a672)); } } &.lc-visible { diff --git a/packages/editor-skeleton/src/layouts/sub-top-area.tsx b/packages/editor-skeleton/src/layouts/sub-top-area.tsx index e6bf61871a..cef6aa5b02 100644 --- a/packages/editor-skeleton/src/layouts/sub-top-area.tsx +++ b/packages/editor-skeleton/src/layouts/sub-top-area.tsx @@ -13,7 +13,7 @@ export default class SubTopArea extends Component<{ area: Area; itemClassName?: } return ( - <div className={classNames('lc-sub-top-area engine-actionpane', { + <div className={classNames('lc-workspace-sub-top-area lc-sub-top-area engine-actionpane', { 'lc-area-visible': area.visible, })} > @@ -50,13 +50,13 @@ class Contents extends Component<{ area: Area; itemClassName?: string }> { }); let children = []; if (left && left.length) { - children.push(<div className="lc-sub-top-area-left">{left}</div>); + children.push(<div className="lc-workspace-sub-top-area-left lc-sub-top-area-left">{left}</div>); } if (center && center.length) { - children.push(<div className="lc-sub-top-area-center">{center}</div>); + children.push(<div className="lc-workspace-sub-top-area-center lc-sub-top-area-center">{center}</div>); } if (right && right.length) { - children.push(<div className="lc-sub-top-area-right">{right}</div>); + children.push(<div className="lc-workspace-sub-top-area-right lc-sub-top-area-right">{right}</div>); } return ( <Fragment> diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index 13fc19c847..716ab3a99e 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -38,20 +38,20 @@ --color-field-border-active: @normal-alpha-3; --color-field-background: @white-alpha-1; - --color-function-success: @brand-success; - --color-function-success-dark: darken(@brand-success, 10%); - --color-function-success-light: lighten(@brand-success, 10%); - --color-function-warning: @brand-warning; - --color-function-warning-dark: darken(@brand-warning, 10%); - --color-function-warning-light: lighten(@brand-warning, 10%); - --color-function-information: @brand-link-hover; - --color-function-information-dark: darken(@brand-link-hover, 10%); - --color-function-information-light: lighten(@brand-link-hover, 10%); - --color-function-error: @brand-danger; - --color-function-error-dark: darken(@brand-danger, 10%); - --color-function-error-light: lighten(@brand-danger, 10%); - --color-function-purple: rgb(144, 94, 190); - --color-function-brown: #7b605b; + --color-success: @brand-success; + --colo-success-dark: darken(@brand-success, 10%); + --color-success-light: lighten(@brand-success, 10%); + --color-warning: @brand-warning; + --color-warning-dark: darken(@brand-warning, 10%); + --color-warning-light: lighten(@brand-warning, 10%); + --color-information: @brand-link-hover; + --color-information-dark: darken(@brand-link-hover, 10%); + --color-information-light: lighten(@brand-link-hover, 10%); + --color-error: @brand-danger; + --color-error-dark: darken(@brand-danger, 10%); + --color-error-light: lighten(@brand-danger, 10%); + --color-purple: rgb(144, 94, 190); + --color-brown: #7b605b; --color-pane-background: @white-alpha-1; --color-block-background-normal: @white-alpha-1; @@ -70,3 +70,21 @@ --pane-title-bg-color: rgba(31,56,88,.04); } + +// @deprecated 变量 +:root { + --color-function-success: @brand-success; + --color-function-success-dark: darken(@brand-success, 10%); + --color-function-success-light: lighten(@brand-success, 10%); + --color-function-warning: @brand-warning; + --color-function-warning-dark: darken(@brand-warning, 10%); + --color-function-warning-light: lighten(@brand-warning, 10%); + --color-function-information: @brand-link-hover; + --color-function-information-dark: darken(@brand-link-hover, 10%); + --color-function-information-light: lighten(@brand-link-hover, 10%); + --color-function-error: @brand-danger; + --color-function-error-dark: darken(@brand-danger, 10%); + --color-function-error-light: lighten(@brand-danger, 10%); + --color-function-purple: rgb(144, 94, 190); + --color-function-brown: #7b605b; +} diff --git a/packages/editor-skeleton/src/layouts/top-area.tsx b/packages/editor-skeleton/src/layouts/top-area.tsx index 56949cbb7f..f6b84b3e6f 100644 --- a/packages/editor-skeleton/src/layouts/top-area.tsx +++ b/packages/editor-skeleton/src/layouts/top-area.tsx @@ -4,14 +4,14 @@ import { observer } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; @observer -export default class TopArea extends Component<{ area: Area; itemClassName?: string }> { +export default class TopArea extends Component<{ area: Area; itemClassName?: string; className?: string }> { render() { - const { area, itemClassName } = this.props; + const { area, itemClassName, className } = this.props; if (area.isEmpty()) { return null; } return ( - <div className={classNames('lc-top-area engine-actionpane', { + <div className={classNames(className, 'lc-top-area engine-actionpane', { 'lc-area-visible': area.visible, })} > diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 58123ea464..6d0604a1f1 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -141,7 +141,7 @@ body { flex-direction: column; background-color: var(--color-background); } - .lc-top-area, .lc-sub-top-area { + .lc-top-area, .lc-workspace-sub-top-area { width: 100%; display: none; margin-bottom: 2px; @@ -152,30 +152,34 @@ body { height: var(--top-area-height); } - &.lc-sub-top-area { - background-color: var(--color-sub-top-area-background, var(--color-pane-background)); - height: var(--sub-top-area-height, var(--top-area-height)); - margin: var(--sub-top-area-margin, 0px 0px 2px 0px); - padding: var(--sub-top-area-padding, 8px 12px 8px 16px); + &.lc-workspace-top-area { + background-color: var(--color-workspace-top-area-background, var(--color-pane-background)); + } + + &.lc-workspace-sub-top-area { + background-color: var(--color-workspace-sub-top-area-background, var(--color-pane-background)); + height: var(--workspace-sub-top-area-height, var(--top-area-height)); + margin: var(--workspace-sub-top-area-margin, 0px 0px 2px 0px); + padding: var(--workspace-sub-top-area-padding, 8px 12px 8px 16px); } &.lc-area-visible { display: flex; } - .lc-top-area-left, .lc-sub-top-area-left { + .lc-top-area-left, .lc-workspace-sub-top-area-left { display: flex; align-items: center; max-width: 100%; } - .lc-top-area-center, .lc-sub-top-area-center { + .lc-top-area-center, .lc-workspace-sub-top-area-center { flex: 1; display: flex; justify-content: center; margin: 0 8px; } - .lc-top-area-right, .lc-sub-top-area-right { + .lc-top-area-right, .lc-workspace-sub-top-area-right { display: flex; align-items: center; > * { @@ -275,9 +279,8 @@ body { flex-direction: column; justify-content: space-between; overflow: hidden; - &.lc-left-area { - background-color: var(--color-left-area-background, var(--color-pane-background)); - } + background-color: var(--color-left-area-background, var(--color-pane-background)); + &.lc-workspace-left-area { background-color: var(--color-workspace-left-area-background, var(--color-pane-background)); } diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index 37f51a170d..15f115ea6b 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -120,20 +120,20 @@ transform: translateZ(0); transition: all 0.2s ease-in-out; &.invalid { - border-color: var(--color-function-error, red); + border-color: var(--color-error, var(--color-function-error, red)); background-color: var(--color-block-background-error, rgba(240, 154, 154, 0.719)); } } .condition-group-container { - border-bottom: 1px solid var(--color-function-brown, #7b605b); + border-bottom: 1px solid var(--color-brown, var(--color-function-brown, #7b605b)); position: relative; &:before { position: absolute; display: block; width: 0; - border-left: 0.5px solid var(--color-function-brown, #7b605b); + border-left: 0.5px solid var(--color-brown, var(--color-function-brown, #7b605b)); height: 100%; top: 0; left: 0; @@ -142,7 +142,7 @@ } > .condition-group-title { text-align: center; - background-color: var(--color-function-brown, #7b605b); + background-color: var(--color-brown, var(--color-function-brown, #7b605b)); height: 14px; > .lc-title { font-size: 12px; @@ -155,13 +155,13 @@ } } .tree-node-slots { - border-bottom: 1px solid var(--color-function-purple, rgb(144, 94, 190)); + border-bottom: 1px solid var(--color-purple, var(--color-function-purple, rgb(144, 94, 190))); position: relative; &::before { position: absolute; display: block; width: 0; - border-left: 0.5px solid var(--color-function-purple, rgb(144, 94, 190)); + border-left: 0.5px solid var(--color-purple, var(--color-function-purple, rgb(144, 94, 190))); height: 100%; top: 0; left: 0; @@ -170,7 +170,7 @@ } > .tree-node-slots-title { text-align: center; - background-color: var(--color-function-purple, rgb(144, 94, 190)); + background-color: var(--color-purple, var(--color-function-purple, rgb(144, 94, 190))); height: 14px; > .lc-title { font-size: 12px; @@ -183,12 +183,12 @@ } &.insertion-at-slots { padding-bottom: @treeNodeHeight; - border-bottom-color: var(--color-function-error-dark, rgb(182, 55, 55)); + border-bottom-color: var(--color-error-dark, var(--color-function-error-dark, rgb(182, 55, 55))); > .tree-node-slots-title { - background-color: var(--color-function-error-dark, rgb(182, 55, 55)); + background-color: var(--color-error-dark, var(--color-function-error-dark, rgb(182, 55, 55))); } &::before { - border-left-color: var(--color-function-error-dark, rgb(182, 55, 55)); + border-left-color: var(--color-error-dark, var(--color-function-error-dark, rgb(182, 55, 55))); } } } @@ -326,13 +326,13 @@ align-items: center; line-height: 0; &.cond { - color: var(--color-function-error, rgb(179, 52, 6)); + color: var(--color-error, var(--color-function-error, rgb(179, 52, 6))); } &.loop { - color: var(--color-function-success, rgb(103, 187, 187)); + color: var(--color-success, var(--color-function-success, rgb(103, 187, 187))); } &.slot { - color: var(--color-function-purple, rgb(211, 90, 211)); + color: var(--color-purple, var(--color-function-purple, rgb(211, 90, 211))); } } } diff --git a/packages/workspace/src/layouts/workbench.tsx b/packages/workspace/src/layouts/workbench.tsx index 9bdbe3f932..2913576e1c 100644 --- a/packages/workspace/src/layouts/workbench.tsx +++ b/packages/workspace/src/layouts/workbench.tsx @@ -47,7 +47,7 @@ export class Workbench extends Component<{ return ( <div className={classNames('lc-workspace-workbench', className, theme)}> <SkeletonContext.Provider value={skeleton}> - <TopArea area={skeleton.topArea} itemClassName={topAreaItemClassName} /> + <TopArea className="lc-workspace-top-area" area={skeleton.topArea} itemClassName={topAreaItemClassName} /> <div className="lc-workspace-workbench-body"> <LeftArea className="lc-workspace-left-area lc-left-area" area={skeleton.leftArea} /> <LeftFloatPane area={skeleton.leftFloatArea} /> From e7a3ba9e9aae210cb67c565c37038373731ea256 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 19 Oct 2023 14:19:47 +0800 Subject: [PATCH 153/361] chore(docs): publish docs 1.1.12 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 6c43fe1d0f..177226a287 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.11", + "version": "1.1.12", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 0f02080035923db7b5c39644ad4a41da0f56c892 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 20 Oct 2023 15:52:31 +0800 Subject: [PATCH 154/361] chore(release): publish 1.2.0 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 0bb34d1aee..b76ff2ae85 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.1.10", + "version": "1.2.0", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 1081aef8ff..c32b54a778 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.1.10", + "version": "1.2.0", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index e05002469e..bd4899c9a5 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.1.10", + "version": "1.2.0", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 2c8efccebf..0b23435f91 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.1.10", + "version": "1.2.0", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index a9521d486b..59ecb02610 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.1.10", + "version": "1.2.0", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-editor-skeleton": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-editor-skeleton": "1.2.0", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.1.10", - "@alilc/lowcode-plugin-outline-pane": "1.1.10", - "@alilc/lowcode-shell": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", - "@alilc/lowcode-workspace": "1.1.10", + "@alilc/lowcode-plugin-designer": "1.2.0", + "@alilc/lowcode-plugin-outline-pane": "1.2.0", + "@alilc/lowcode-shell": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-workspace": "1.2.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 116f98e5d5..f524eba845 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.1.10", + "version": "1.2.0", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 760d57a133..65c931ef37 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.1.10", + "version": "1.2.0", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 4a71eb26b8..e933128018 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.1.10", + "version": "1.2.0", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 90a9b7e08e..7d55b5ae6c 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-renderer-core": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 8ff7f1f0a4..69a029578c 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-rax-renderer": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-rax-renderer": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 1535cb2088..f1d8b5ea54 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.1.10" + "@alilc/lowcode-renderer-core": "1.2.0" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index ffb8228dfd..a265c3e88f 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.1.10", + "version": "1.2.0", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-react-renderer": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-react-renderer": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 52b13b86c6..ecfd233809 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.1.10", + "version": "1.2.0", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 09768a06a7..884915877c 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.1.10", + "version": "1.2.0", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-editor-skeleton": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", - "@alilc/lowcode-workspace": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-editor-skeleton": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-workspace": "1.2.0", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index fe9cd51235..155242712a 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.1.10", + "version": "1.2.0", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index ecf6bff3c0..f9c0005b4d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.1.10", + "version": "1.2.0", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.1.10", + "@alilc/lowcode-types": "1.2.0", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 8802691d60..7e662af378 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.1.10", + "version": "1.2.0", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.1.10", - "@alilc/lowcode-editor-core": "1.1.10", - "@alilc/lowcode-editor-skeleton": "1.1.10", - "@alilc/lowcode-types": "1.1.10", - "@alilc/lowcode-utils": "1.1.10", + "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.0", + "@alilc/lowcode-editor-skeleton": "1.2.0", + "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-utils": "1.2.0", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 11ee97c6dafe1ecb60402488ad72b722005cda55 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 26 Oct 2023 11:24:17 +0800 Subject: [PATCH 155/361] fix: fixed the problem caused by component list being overwritten by Hoc --- packages/renderer-core/src/renderer/base.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 7b9562fcc6..1980734e43 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -615,9 +615,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); }); - Comp = compWrapper(Comp, { baseRenderer: this, schema }); - components[schema.componentName] = Comp; - otherProps.ref = (ref: any) => { this.$(props.fieldId || props.ref, ref); // 收集ref const refProps = props.ref; @@ -701,9 +698,9 @@ export default function baseRendererFactory(): IBaseRenderComponent { */ get __componentHOCs(): IComponentConstruct[] { if (this.__designModeIsDesign) { - return [leafWrapper]; + return [leafWrapper, compWrapper]; } - return []; + return [compWrapper]; } __getSchemaChildrenVirtualDom = (schema: IPublicTypeNodeSchema | undefined, scope: any, Comp: any, condition = true) => { From 055ab68a4b110385d737c0aafd4362d9c86c96e4 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 26 Oct 2023 11:37:30 +0800 Subject: [PATCH 156/361] fix: fix document.onMountNode parameters --- packages/designer/src/document/document-model.ts | 9 ++++++++- packages/shell/src/model/document-model.ts | 9 +++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 9521fef383..edca8fd818 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -74,7 +74,6 @@ export interface IDocumentModel extends Omit<IPublicModelDocumentModel< 'onRemoveNode' | 'onChangeDetecting' | 'onChangeSelection' | - 'onMountNode' | 'onChangeNodeProp' | 'onImportSchema' | 'isDetectingNode' | @@ -414,6 +413,14 @@ export class DocumentModel implements IDocumentModel { return node ? !node.isPurged : false; } + onMountNode(fn: (payload: { node: INode }) => void) { + this.designer.editor.eventBus.on('node.add', fn as any); + + return () => { + this.designer.editor.eventBus.off('node.add', fn as any); + }; + } + /** * 根据 schema 创建一个节点 */ diff --git a/packages/shell/src/model/document-model.ts b/packages/shell/src/model/document-model.ts index 2c5c7b632e..bd0ccaf75e 100644 --- a/packages/shell/src/model/document-model.ts +++ b/packages/shell/src/model/document-model.ts @@ -252,10 +252,11 @@ export class DocumentModel implements IPublicModelDocumentModel { * 当前 document 新增节点事件,此时节点已经挂载到 document 上 */ onMountNode(fn: (payload: { node: IPublicModelNode }) => void): IPublicTypeDisposable { - this[editorSymbol].eventBus.on('node.add', fn as any); - return () => { - this[editorSymbol].eventBus.off('node.add', fn as any); - }; + return this[documentSymbol].onMountNode(({ + node, + }) => { + fn({ node: ShellNode.create(node)! }); + }); } /** From b3b2a03642da21f4747108d1da77488f9655dcfc Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 27 Oct 2023 13:14:57 +0800 Subject: [PATCH 157/361] chore(release): publish 1.2.1 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index b76ff2ae85..8201f484d6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.2.0", + "version": "1.2.1", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index c32b54a778..2f57c80c38 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.2.0", + "version": "1.2.1", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.2.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-editor-core": "1.2.1", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index bd4899c9a5..060f986ed3 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.2.0", + "version": "1.2.1", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 0b23435f91..0f55e637db 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.2.0", + "version": "1.2.1", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-editor-core": "1.2.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-editor-core": "1.2.1", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 59ecb02610..29ba8c36f6 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.2.0", + "version": "1.2.1", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-editor-core": "1.2.0", - "@alilc/lowcode-editor-skeleton": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-editor-core": "1.2.1", + "@alilc/lowcode-editor-skeleton": "1.2.1", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.2.0", - "@alilc/lowcode-plugin-outline-pane": "1.2.0", - "@alilc/lowcode-shell": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", - "@alilc/lowcode-workspace": "1.2.0", + "@alilc/lowcode-plugin-designer": "1.2.1", + "@alilc/lowcode-plugin-outline-pane": "1.2.1", + "@alilc/lowcode-shell": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-workspace": "1.2.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index f524eba845..cdf2928b56 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.2.0", + "version": "1.2.1", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 65c931ef37..9b64b0709f 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.2.0", + "version": "1.2.1", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-editor-core": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-editor-core": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index e933128018..8295094fe0 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.2.0", + "version": "1.2.1", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 7d55b5ae6c..ed7434b942 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.2.0", + "version": "1.2.1", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-renderer-core": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 69a029578c..383cc29895 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.2.0", + "version": "1.2.1", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-rax-renderer": "1.2.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-rax-renderer": "1.2.1", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index f1d8b5ea54..142e90ebb6 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.2.0", + "version": "1.2.1", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.2.0" + "@alilc/lowcode-renderer-core": "1.2.1" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index a265c3e88f..18b57e28fe 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.2.0", + "version": "1.2.1", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-react-renderer": "1.2.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-react-renderer": "1.2.1", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index ecfd233809..3d4e3c7e09 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.2.0", + "version": "1.2.1", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 884915877c..36ea05d7b1 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.2.0", + "version": "1.2.1", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-editor-core": "1.2.0", - "@alilc/lowcode-editor-skeleton": "1.2.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", - "@alilc/lowcode-workspace": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-editor-core": "1.2.1", + "@alilc/lowcode-editor-skeleton": "1.2.1", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-workspace": "1.2.1", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 155242712a..2d66d2f621 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.2.0", + "version": "1.2.1", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index f9c0005b4d..c2433f1521 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.2.0", + "version": "1.2.1", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.0", + "@alilc/lowcode-types": "1.2.1", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 7e662af378..a5d7d4ceae 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.2.0", + "version": "1.2.1", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.0", - "@alilc/lowcode-editor-core": "1.2.0", - "@alilc/lowcode-editor-skeleton": "1.2.0", - "@alilc/lowcode-types": "1.2.0", - "@alilc/lowcode-utils": "1.2.0", + "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-editor-core": "1.2.1", + "@alilc/lowcode-editor-skeleton": "1.2.1", + "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-utils": "1.2.1", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 95a48e057f856201cb3cbf7c5046128da7e64df6 Mon Sep 17 00:00:00 2001 From: Rainke <woshihepeng520@163.com> Date: Wed, 1 Nov 2023 10:37:14 +0800 Subject: [PATCH 158/361] =?UTF-8?q?fix:=20import=20schema=20=E4=B9=8B?= =?UTF-8?q?=E5=90=8E=20cache=20=E5=88=A4=E6=96=AD=E9=94=99=E8=AF=AF(#2596)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderer-core/src/hoc/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/renderer-core/src/hoc/index.tsx b/packages/renderer-core/src/hoc/index.tsx index 3e7f5ec6a1..4851ea486f 100644 --- a/packages/renderer-core/src/hoc/index.tsx +++ b/packages/renderer-core/src/hoc/index.tsx @@ -49,7 +49,7 @@ function patchDidCatch(Comp: any, { baseRenderer }: Options) { } } -const cache = new Map(); +const cache = new Map<string, { Comp: any; WrapperComponent: any }>(); export function compWrapper(Comp: any, options: Options) { const { createElement, Component, forwardRef } = adapter.getRuntime(); @@ -62,8 +62,8 @@ export function compWrapper(Comp: any, options: Options) { return Comp; } - if (cache.has(options.schema.id)) { - return cache.get(options.schema.id); + if (cache.has(options.schema.id) && cache.get(options.schema.id)?.Comp === Comp) { + return cache.get(options.schema.id)?.WrapperComponent; } class Wrapper extends Component { @@ -82,7 +82,7 @@ export function compWrapper(Comp: any, options: Options) { Comp, ); - cache.set(options.schema.id, WrapperComponent); + cache.set(options.schema.id, { WrapperComponent, Comp }); return WrapperComponent; } From c5ba2f3ef1ce52f7a2fae9743a2cd11022563f7e 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?= <liujup@foxmail.com> Date: Fri, 3 Nov 2023 14:01:58 +0800 Subject: [PATCH 159/361] docs: update useEditor.md --- docs/docs/guide/create/useEditor.md | 56 ----------------------------- 1 file changed, 56 deletions(-) diff --git a/docs/docs/guide/create/useEditor.md b/docs/docs/guide/create/useEditor.md index cbb38f77de..8df4158a6c 100644 --- a/docs/docs/guide/create/useEditor.md +++ b/docs/docs/guide/create/useEditor.md @@ -105,8 +105,6 @@ sidebar_position: 0 ### 初始化低代码编辑器 -#### 方法 2.1 使用 init 进行初始化 - 正确引入后,我们可以直接通过 window 上的变量进行引用,如 `window.AliLowCodeEngine.init`。您可以直接通过此方式初始化低代码引擎: ```javascript @@ -144,59 +142,5 @@ init 的功能包括但不限于: > 本节中的低代码编辑器例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/index.ts](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/index.ts) - -#### 方法 2.2 使用 skeletonCabin.Workbench 方式初始化 - -`init()` 内部会调用 `ReactDOM.render()` 函数,因此这样初始化的内容没有办法与外部的 React 组件进行通信,也就没有办法在一些自定义的 plugin 中获取 redux 上的全局数据等内容。 - -因此,这种场景下您可以通过 `skeletonCabin.Workbench` 进行初始化。 - -> 注:**不需要**同时使用 2.1 和 2.2 的方法。根据使用场景,当且只当有需要插件和外界进行一定通信时,才需要使用 2.2 提供的方法。 - - -```javascript -import React, { useState, useEffect } from 'react'; -import { project, plugins, common, skeleton } from '@alilc/lowcode-engine'; - -// 此处略去若干依赖引用 - -async function registerPlugins() { - // 此处略去若干插件注册 -} -function EditorView() { - /** 插件是否已初始化成功,因为必须要等插件初始化后才能渲染 Workbench */ - const [hasPluginInited, setHasPluginInited] = useState(false); - - useEffect(() => { - plugins.init().then(() => { - setHasPluginInited(true); - }).catch(err => console.error(err)); - }, []); - - if (!hasPluginInited) { - return null; - } - const Workbench = common.skeletonCabin.Workbench; - return <Workbench />; -} - -(async function main() { - await registerPlugins(); - config.setConfig({ - enableCondition: true, - enableCanvasLock: true, - supportVariableGlobally: true, - requestHandlersMap: { - fetch: createFetchHandler() - } - }); - - ReactDOM.render(<EditorView />, document.getElementById('lce-container')!); -})(); -``` - -> 本节中的低代码编辑器类似的例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/demo-custom-initialization/src/index.tsx](https://github.com/alibaba/lowcode-demo/blob/main/demo-custom-initialization/src/index.tsx) - - ## 配置低代码编辑器 详见[低代码扩展简述](/site/docs/guide/expand/editor/summary)章节。 From c65c17f779fc38648e76dc033c19bffc85365a5c Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 3 Nov 2023 14:05:04 +0800 Subject: [PATCH 160/361] docs: publish docs 1.1.13 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 177226a287..bdc734c71e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.12", + "version": "1.1.13", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 97eb477746c95eab15dccc6ec728159e9edb19a3 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 7 Nov 2023 16:05:50 +0800 Subject: [PATCH 161/361] feat: update engine classes exports --- packages/engine/src/modules/classes.ts | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/packages/engine/src/modules/classes.ts b/packages/engine/src/modules/classes.ts index d68ea43de2..3b7627deb0 100644 --- a/packages/engine/src/modules/classes.ts +++ b/packages/engine/src/modules/classes.ts @@ -1,4 +1,4 @@ -import { +export { Project, Skeleton, DocumentModel, @@ -12,20 +12,5 @@ import { SimulatorHost, SkeletonItem, } from '@alilc/lowcode-shell'; -import { Node as InnerNode } from '@alilc/lowcode-designer'; +export { Node as InnerNode } from '@alilc/lowcode-designer'; -export default { - Project, - Skeleton, - DocumentModel, - Node, - NodeChildren, - History, - SettingPropEntry, - SettingTopEntry, - InnerNode, - Selection, - Prop, - SimulatorHost, - SkeletonItem, -}; From e3611dcf06a0a24b691fab00734ce4cecb501f25 Mon Sep 17 00:00:00 2001 From: keuby <knightchen@knx.com.cn> Date: Tue, 7 Nov 2023 17:20:13 +0800 Subject: [PATCH 162/361] feat(utils|types): add esmodule support for component meta resources (#2603) * feat(utils): support script type param for assest loader * feat(types): update AssestsJson type --- .../src/shell/type/remote-component-description.ts | 6 +++++- packages/utils/src/asset.ts | 10 +++++----- packages/utils/src/script.ts | 9 ++++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/types/src/shell/type/remote-component-description.ts b/packages/types/src/shell/type/remote-component-description.ts index 7ba5324391..2337203657 100644 --- a/packages/types/src/shell/type/remote-component-description.ts +++ b/packages/types/src/shell/type/remote-component-description.ts @@ -1,17 +1,21 @@ +import { Asset } from '../../assets'; import { IPublicTypeComponentMetadata, IPublicTypeReference } from './'; /** * 远程物料描述 */ export interface IPublicTypeRemoteComponentDescription extends IPublicTypeComponentMetadata { + /** * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; */ exportName?: string; + /** * 组件描述的资源链接; */ - url?: string; + url?: Asset; + /** * 组件 (库) 的 npm 信息; */ diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index ad05221248..3400f965b4 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -214,6 +214,8 @@ function parseAsset(scripts: any, styles: any, asset: Asset | undefined | null, } export class AssetLoader { + private stylePoints = new Map<string, StylePoint>(); + async load(asset: Asset) { const styles: any = {}; const scripts: any = {}; @@ -237,11 +239,9 @@ export class AssetLoader { await Promise.all( styleQueue.map(({ content, level, type, id }) => this.loadStyle(content, level!, type === AssetType.CSSUrl, id)), ); - await Promise.all(scriptQueue.map(({ content, type }) => this.loadScript(content, type === AssetType.JSUrl))); + await Promise.all(scriptQueue.map(({ content, type, scriptType }) => this.loadScript(content, type === AssetType.JSUrl, scriptType))); } - private stylePoints = new Map<string, StylePoint>(); - private loadStyle(content: string | undefined | null, level: AssetLevel, isUrl?: boolean, id?: string) { if (!content) { return; @@ -259,11 +259,11 @@ export class AssetLoader { return isUrl ? point.applyUrl(content) : point.applyText(content); } - private loadScript(content: string | undefined | null, isUrl?: boolean) { + private loadScript(content: string | undefined | null, isUrl?: boolean, scriptType?: string) { if (!content) { return; } - return isUrl ? load(content) : evaluate(content); + return isUrl ? load(content, scriptType) : evaluate(content, scriptType); } // todo 补充类型 diff --git a/packages/utils/src/script.ts b/packages/utils/src/script.ts index 7c772f03f9..25159b198c 100644 --- a/packages/utils/src/script.ts +++ b/packages/utils/src/script.ts @@ -1,14 +1,15 @@ import { createDefer } from './create-defer'; -export function evaluate(script: string) { +export function evaluate(script: string, scriptType?: string) { const scriptEl = document.createElement('script'); + scriptType && (scriptEl.type = scriptType); scriptEl.text = script; document.head.appendChild(scriptEl); document.head.removeChild(scriptEl); } -export function load(url: string) { - const node: any = document.createElement('script'); +export function load(url: string, scriptType?: string) { + const node = document.createElement('script'); // node.setAttribute('crossorigin', 'anonymous'); @@ -34,6 +35,8 @@ export function load(url: string) { // `async=false` is required to make sure all js resources execute sequentially. node.async = false; + scriptType && (node.type = scriptType); + document.head.appendChild(node); return i.promise(); From de8dab5cb38b6c1c248e35f9c445d24bdbf1babb 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?= <liujup@foxmail.com> Date: Thu, 9 Nov 2023 18:15:39 +0800 Subject: [PATCH 163/361] docs: update index.md --- docs/docs/article/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index 2f6f2cee3f..e62f8f9d87 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -1,4 +1,5 @@ # 官方文章 +- [2023/11/09 UIPaaS | 基于 LowCodeEngine 的低代码平台孵化器](https://mp.weixin.qq.com/s/mKuv3_Wvgt5T3AGErUGBQQ) - [2023/04/04 什么?低代码引擎可以开发应用了](https://mp.weixin.qq.com/s/dwi40gJjGBHW9MVpag5Oxg) - [2023/03/23 低代码引擎 LowCodeEngine 茁壮成长的一年](https://mp.weixin.qq.com/s/DDt4LQLFUBQ2-F5ehZGBKg) - [2023/02/21 基于 LowCodeEngine 的低代码组件体系的建设和实践](https://mp.weixin.qq.com/s/rnvbGHImGt6oJuX2wCtaqw) @@ -10,4 +11,4 @@ - [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) - [2022/03/23 阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA) - [2022/01/10 阿里低代码引擎和生态建设实战及思考](https://mp.weixin.qq.com/s/MI6MrUKKydtnSdO4xq6jwA) -- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) \ No newline at end of file +- [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) From 9f78f8c54a697a2d7b4102474fd2c0eb9c956e63 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?= <liujup@foxmail.com> Date: Thu, 9 Nov 2023 16:22:24 +0800 Subject: [PATCH 164/361] Update material.md --- docs/docs/api/material.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 2bf99577cb..8b1214476b 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -340,6 +340,31 @@ function addonCombine(metadata: TransformedComponentMetadata) { material.registerMetadataTransducer(addonCombine, 1, 'parse-func'); ``` +删除高级 Tab + +```typescript +import { material } from '@alilc/lowcode-engine'; +import { IPublicTypeFieldConfig } from '@alilc/lowcode-types'; + +material.registerMetadataTransducer((transducer) => { + const combined: IPublicTypeFieldConfig[] = []; + + transducer.configure.combined?.forEach(d => { + if (d.name !== '#advanced') { + combined.push(d); + } + }); + + return { + ...transducer, + configure: { + ...transducer.configure, + combined, + } + }; +}, 111, 'parse-func'); +``` + #### getRegisteredMetadataTransducers 获取所有物料元数据管道函数 From f5c874b4bfb3c8859750911609f0b6bb3670d8bf Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 9 Nov 2023 11:30:02 +0800 Subject: [PATCH 165/361] chore(ignitor): change build config --- packages/ignitor/build.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ignitor/build.json b/packages/ignitor/build.json index a29eaf0266..218373247c 100644 --- a/packages/ignitor/build.json +++ b/packages/ignitor/build.json @@ -1,15 +1,15 @@ { "entry": { - "engine-core": "../engine/src/index.ts", - "react-simulator-renderer": "../react-simulator-renderer/src/index.ts", - "rax-simulator-renderer": "../rax-simulator-renderer/src/index.ts" + "AliLowCodeEngine": "../engine/src/index.ts", + "ReactSimulatorRenderer": "../react-simulator-renderer/src/index.ts", + "RaxSimulatorRenderer": "../rax-simulator-renderer/src/index.ts" }, "vendor": false, "devServer": { "liveReload": false, "hot": false }, - "library": "AliLowCodeEngine", + "library": "[name]", "publicPath": "/", "externals": { "react": "var window.React", From 3b14a79d1b474e538e8fae33ca38c9920ebebc31 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Fri, 10 Nov 2023 10:03:01 +0800 Subject: [PATCH 166/361] docs: publish docs 1.1.14 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index bdc734c71e..7479c7c84e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.13", + "version": "1.1.14", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 6320867cada5e0b851a2836aeadbb3b54f8f7f6d Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 10 Nov 2023 14:20:24 +0800 Subject: [PATCH 167/361] docs: update Node to IPublicModelNode --- docs/docs/api/configOptions.md | 2 +- docs/docs/api/model/dragon.md | 2 +- docs/docs/api/model/modal-nodes-manager.md | 4 ++-- docs/docs/api/model/node.md | 2 +- docs/docs/guide/expand/editor/pluginContextMenu.md | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index 467655f68c..aaea28261d 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -113,7 +113,7 @@ config.set('enableCondition', false) 类型定义 ```typescript - focusNodeSelector?: (rootNode: Node) => Node; + focusNodeSelector?: (rootNode: IPublicModelNode) => Node; ``` #### supportVariableGlobally - 全局变量配置 diff --git a/docs/docs/api/model/dragon.md b/docs/docs/api/model/dragon.md index 995fd1b1f4..c6feca4329 100644 --- a/docs/docs/api/model/dragon.md +++ b/docs/docs/api/model/dragon.md @@ -101,7 +101,7 @@ from(shell: Element, boost: (e: MouseEvent) => IPublicTypeDragNodeDataObject | n * @param dragObject 拖拽对象 * @param boostEvent 拖拽初始时事件 */ -boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | IPublicModelNode): void; +boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: IPublicModelNode): void; ``` ### addSensor diff --git a/docs/docs/api/model/modal-nodes-manager.md b/docs/docs/api/model/modal-nodes-manager.md index fbab6a83a5..fead53f0a1 100644 --- a/docs/docs/api/model/modal-nodes-manager.md +++ b/docs/docs/api/model/modal-nodes-manager.md @@ -71,7 +71,7 @@ hideModalNodes(): void; /** * 设置指定节点为可见态 * set specific model node as visible - * @param node Node + * @param node IPublicModelNode */ setVisible(node: IPublicModelNode): void; ``` @@ -86,7 +86,7 @@ setVisible(node: IPublicModelNode): void; /** * 设置指定节点为不可见态 * set specific model node as invisible - * @param node Node + * @param node IPublicModelNode */ setInvisible(node: IPublicModelNode): void; ``` diff --git a/docs/docs/api/model/node.md b/docs/docs/api/model/node.md index 697eefd088..43de96a33d 100644 --- a/docs/docs/api/model/node.md +++ b/docs/docs/api/model/node.md @@ -673,6 +673,6 @@ getRGL(): { isRGLContainerNode: boolean; isRGLNode: boolean; isRGL: boolean; - rglNode: Node | null; + rglNode: IPublicModelNode | null; } ``` \ No newline at end of file diff --git a/docs/docs/guide/expand/editor/pluginContextMenu.md b/docs/docs/guide/expand/editor/pluginContextMenu.md index cd293b73e7..962c913e7e 100644 --- a/docs/docs/guide/expand/editor/pluginContextMenu.md +++ b/docs/docs/guide/expand/editor/pluginContextMenu.md @@ -12,7 +12,7 @@ sidebar_position: 6 ```typescript import { plugins } from '@alilc/lowcode-engine'; -import { IPublicModelPluginContext } from '@alilc/lowcode-types'; +import { IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types'; import { Icon, Message } from '@alifd/next'; const addHelloAction = (ctx: IPublicModelPluginContext) => { @@ -23,11 +23,11 @@ const addHelloAction = (ctx: IPublicModelPluginContext) => { content: { icon: <Icon type="atm" />, title: 'hello', - action(node: Node) { + action(node: IPublicModelNode) { Message.show('Welcome to Low-Code engine'); }, }, - condition: (node: Node) => { + condition: (node: IPublicModelNode) => { return node.componentMeta.componentName === 'NextTable'; }, important: true, From d64c7d56dfc5ac67be56039a124ae897555569de Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 13 Nov 2023 12:41:45 +0800 Subject: [PATCH 168/361] chore(release): publish 1.2.2 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 8201f484d6..34be89faa8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.2.1", + "version": "1.2.2", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 2f57c80c38..69a402ed22 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.2.1", + "version": "1.2.2", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.2.1", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-editor-core": "1.2.2", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 060f986ed3..de9d30bc8b 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.2.1", + "version": "1.2.2", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 0f55e637db..fe2d0d43ff 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.2.1", + "version": "1.2.2", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-editor-core": "1.2.1", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-editor-core": "1.2.2", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 29ba8c36f6..3ea47f79da 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.2.1", + "version": "1.2.2", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-editor-core": "1.2.1", - "@alilc/lowcode-editor-skeleton": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-editor-core": "1.2.2", + "@alilc/lowcode-editor-skeleton": "1.2.2", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.2.1", - "@alilc/lowcode-plugin-outline-pane": "1.2.1", - "@alilc/lowcode-shell": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", - "@alilc/lowcode-workspace": "1.2.1", + "@alilc/lowcode-plugin-designer": "1.2.2", + "@alilc/lowcode-plugin-outline-pane": "1.2.2", + "@alilc/lowcode-shell": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-workspace": "1.2.2", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index cdf2928b56..d737a7c868 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.2.1", + "version": "1.2.2", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 9b64b0709f..fe653568bb 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.2.1", + "version": "1.2.2", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-editor-core": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-editor-core": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 8295094fe0..2540ca5ad4 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.2.1", + "version": "1.2.2", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index ed7434b942..60ea0c6981 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.2.1", + "version": "1.2.2", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-renderer-core": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 383cc29895..520ff32c89 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.2.1", + "version": "1.2.2", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-rax-renderer": "1.2.1", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-rax-renderer": "1.2.2", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 142e90ebb6..a35039fc3c 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.2.1", + "version": "1.2.2", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.2.1" + "@alilc/lowcode-renderer-core": "1.2.2" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 18b57e28fe..413b1825f8 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.2.1", + "version": "1.2.2", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-react-renderer": "1.2.1", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-react-renderer": "1.2.2", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 3d4e3c7e09..3b96ef40b3 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.2.1", + "version": "1.2.2", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 36ea05d7b1..7e20192352 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.2.1", + "version": "1.2.2", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-editor-core": "1.2.1", - "@alilc/lowcode-editor-skeleton": "1.2.1", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", - "@alilc/lowcode-workspace": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-editor-core": "1.2.2", + "@alilc/lowcode-editor-skeleton": "1.2.2", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-workspace": "1.2.2", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 2d66d2f621..c4fa290036 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.2.1", + "version": "1.2.2", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index c2433f1521..fab7828f13 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.2.1", + "version": "1.2.2", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.1", + "@alilc/lowcode-types": "1.2.2", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index a5d7d4ceae..4724323797 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.2.1", + "version": "1.2.2", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.1", - "@alilc/lowcode-editor-core": "1.2.1", - "@alilc/lowcode-editor-skeleton": "1.2.1", - "@alilc/lowcode-types": "1.2.1", - "@alilc/lowcode-utils": "1.2.1", + "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-editor-core": "1.2.2", + "@alilc/lowcode-editor-skeleton": "1.2.2", + "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-utils": "1.2.2", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 04adda02fb415e2f56e6ee3e7f20652c2de20668 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 13 Nov 2023 12:30:47 +0800 Subject: [PATCH 169/361] =?UTF-8?q?docs:=20add=20faq-Slot=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=B8=B2=E6=9F=93=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/faq/faq023.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 docs/docs/faq/faq023.md diff --git a/docs/docs/faq/faq023.md b/docs/docs/faq/faq023.md new file mode 100644 index 0000000000..e03f7118e0 --- /dev/null +++ b/docs/docs/faq/faq023.md @@ -0,0 +1,31 @@ +--- +title: Slot组件渲染报错问题 +sidebar_position: 23 +tags: [FAQ] +--- + +## 问题描述 +在低代码引擎的页面渲染过程中,可能会遇到一个关于Slot组件的报错,提示“Slot找不到”。实际上,在渲染态时不应使用Slot组件。 + +## 问题原因 +低代码引擎渲染分为两个状态:设计态和渲染态。 +- **设计态**:为了帮助插槽进行可视化设计,引入了Slot组件。 +- **渲染态**:在此状态下,不需要使用Slot组件。 + +这个问题通常是因为在渲染态错误地使用了设计态的schema。 + +## 解决方案 +1. **区分设计态和渲染态**:通过`project.exportSchema(TransformStage.Save)`的参数来区分。 + - `TransformStage.Save`代表渲染态的schema,其中不包含Slot组件。 + - 【默认值】`TransformStage.Render`代表设计态的schema,其中包含Slot组件。 +2. **使用正确的API和参数**:确保在渲染态使用正确的schema,避免引用设计态的Slot组件。 +3. **处理脏数据问题**:如果问题是由脏数据导致,清除数据并重新拖拽组件以恢复正常。 + +## 注意事项 +- 确保在代码和配置中正确区分设计态和渲染态。 +- 如果遇到持续的问题,检查是否有脏数据或配置错误,并进行相应的清理和调整。 + +## 相关链接 +- Issue链接:[Issue #1798](https://github.com/alibaba/lowcode-engine/issues/1798) + +--- From 938c71fb462b37fb154e1b8fdfaa0319d4f0f075 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 13 Nov 2023 12:57:02 +0800 Subject: [PATCH 170/361] chore(docs): publish docs 1.1.15 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 7479c7c84e..27d1a17d04 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.14", + "version": "1.1.15", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 621245393f5ca405d86c90501e51288f2f324d5c Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 13 Nov 2023 12:25:50 +0800 Subject: [PATCH 171/361] test(utils): add ut to package/utils --- packages/utils/jest.config.js | 1 + packages/utils/jest.setup.js | 1 + packages/utils/package.json | 7 +- .../check-types/is-action-content-object.ts | 3 +- .../utils/src/check-types/is-custom-view.ts | 6 +- .../src/check-types/is-drag-any-object.ts | 6 +- .../check-types/is-drag-node-data-object.ts | 6 +- .../src/check-types/is-drag-node-object.ts | 6 +- .../src/check-types/is-dynamic-setter.ts | 7 +- packages/utils/src/check-types/is-function.ts | 3 + .../utils/src/check-types/is-i18n-data.ts | 11 +- .../utils/src/check-types/is-isfunction.ts | 24 +- packages/utils/src/check-types/is-jsblock.ts | 9 +- .../utils/src/check-types/is-jsexpression.ts | 6 +- packages/utils/src/check-types/is-jsslot.ts | 6 +- .../is-location-children-detail.ts | 6 +- .../utils/src/check-types/is-location-data.ts | 6 +- .../check-types/is-lowcode-project-schema.ts | 15 +- .../utils/src/check-types/is-node-schema.ts | 6 +- packages/utils/src/check-types/is-node.ts | 6 +- packages/utils/src/check-types/is-object.ts | 3 + .../check-types/is-procode-component-type.ts | 6 +- .../src/check-types/is-project-schema.ts | 8 +- .../utils/src/check-types/is-setter-config.ts | 7 +- .../utils/src/check-types/is-setting-field.ts | 9 +- .../utils/src/clone-enumerable-property.ts | 4 +- packages/utils/src/is-object.ts | 2 +- packages/utils/src/is-react.ts | 38 +- packages/utils/src/logger.ts | 4 +- packages/utils/src/misc.ts | 15 +- packages/utils/src/navtive-selection.ts | 3 +- packages/utils/src/script.ts | 5 +- packages/utils/src/svg-icon.tsx | 2 +- .../src/__snapshots__/is-react.test.tsx.snap | 10 + .../build-components/buildComponents.test.ts | 342 ---------- .../build-components/buildComponents.test.tsx | 616 ++++++++++++++++++ .../is-action-content-object.test.ts | 20 + .../src/check-types/is-custom-view.test.tsx | 26 + .../test/src/check-types/is-dom-text.test.ts | 13 + .../check-types/is-drag-any-object.test.ts | 32 + .../is-drag-node-data-object.test.ts | 29 + .../check-types/is-drag-node-object.test.ts | 36 + .../src/check-types/is-dynamic-setter.test.ts | 28 + .../test/src/check-types/is-i18n-data.test.ts | 27 + .../src/check-types/is-isfunction.test.ts | 61 ++ .../test/src/check-types/is-jsblock.test.ts | 22 + .../src/check-types/is-jsexpression.test.ts | 39 ++ .../test/src/check-types/is-jsslot.test.ts | 37 ++ .../is-location-children-detail.test.ts | 27 + .../src/check-types/is-location-data.test.ts | 44 ++ .../is-lowcode-component-type.test.ts | 21 + .../is-lowcode-project-schema.test.ts | 42 ++ .../src/check-types/is-node-schema.test.ts | 43 ++ .../test/src/check-types/is-node.test.ts | 19 + .../is-procode-component-type.test.ts | 13 + .../src/check-types/is-project-schema.test.ts | 28 + .../src/check-types/is-setter-config.test.ts | 26 + .../src/check-types/is-setting-field.test.ts | 18 + .../src/check-types/is-title-config.test.ts | 18 + packages/utils/test/src/clone-deep.test.ts | 30 + .../src/clone-enumerable-property.test.ts | 30 + .../utils/test/src/create-content.test.tsx | 38 ++ packages/utils/test/src/create-defer.test.ts | 16 + packages/utils/test/src/is-object.test.ts | 45 ++ packages/utils/test/src/is-react.test.ts | 38 -- packages/utils/test/src/is-react.test.tsx | 316 +++++++++ packages/utils/test/src/is-shaken.test.ts | 45 ++ packages/utils/test/src/misc.test.ts | 319 ++++++++- .../utils/test/src/navtive-selection.test.ts | 18 + packages/utils/test/src/schema.test.ts | 130 +++- packages/utils/test/src/script.test.ts | 47 ++ packages/utils/test/src/svg-icon.test.tsx | 35 + .../test/src/transaction-manager.test.ts | 58 ++ packages/utils/test/src/unique-id.test.ts | 11 + 74 files changed, 2621 insertions(+), 439 deletions(-) create mode 100644 packages/utils/jest.setup.js create mode 100644 packages/utils/src/check-types/is-function.ts create mode 100644 packages/utils/src/check-types/is-object.ts create mode 100644 packages/utils/test/src/__snapshots__/is-react.test.tsx.snap delete mode 100644 packages/utils/test/src/build-components/buildComponents.test.ts create mode 100644 packages/utils/test/src/build-components/buildComponents.test.tsx create mode 100644 packages/utils/test/src/check-types/is-action-content-object.test.ts create mode 100644 packages/utils/test/src/check-types/is-custom-view.test.tsx create mode 100644 packages/utils/test/src/check-types/is-dom-text.test.ts create mode 100644 packages/utils/test/src/check-types/is-drag-any-object.test.ts create mode 100644 packages/utils/test/src/check-types/is-drag-node-data-object.test.ts create mode 100644 packages/utils/test/src/check-types/is-drag-node-object.test.ts create mode 100644 packages/utils/test/src/check-types/is-dynamic-setter.test.ts create mode 100644 packages/utils/test/src/check-types/is-i18n-data.test.ts create mode 100644 packages/utils/test/src/check-types/is-isfunction.test.ts create mode 100644 packages/utils/test/src/check-types/is-jsblock.test.ts create mode 100644 packages/utils/test/src/check-types/is-jsexpression.test.ts create mode 100644 packages/utils/test/src/check-types/is-jsslot.test.ts create mode 100644 packages/utils/test/src/check-types/is-location-children-detail.test.ts create mode 100644 packages/utils/test/src/check-types/is-location-data.test.ts create mode 100644 packages/utils/test/src/check-types/is-lowcode-component-type.test.ts create mode 100644 packages/utils/test/src/check-types/is-lowcode-project-schema.test.ts create mode 100644 packages/utils/test/src/check-types/is-node-schema.test.ts create mode 100644 packages/utils/test/src/check-types/is-node.test.ts create mode 100644 packages/utils/test/src/check-types/is-procode-component-type.test.ts create mode 100644 packages/utils/test/src/check-types/is-project-schema.test.ts create mode 100644 packages/utils/test/src/check-types/is-setter-config.test.ts create mode 100644 packages/utils/test/src/check-types/is-setting-field.test.ts create mode 100644 packages/utils/test/src/check-types/is-title-config.test.ts create mode 100644 packages/utils/test/src/clone-deep.test.ts create mode 100644 packages/utils/test/src/clone-enumerable-property.test.ts create mode 100644 packages/utils/test/src/create-content.test.tsx create mode 100644 packages/utils/test/src/create-defer.test.ts create mode 100644 packages/utils/test/src/is-object.test.ts delete mode 100644 packages/utils/test/src/is-react.test.ts create mode 100644 packages/utils/test/src/is-react.test.tsx create mode 100644 packages/utils/test/src/is-shaken.test.ts create mode 100644 packages/utils/test/src/navtive-selection.test.ts create mode 100644 packages/utils/test/src/script.test.ts create mode 100644 packages/utils/test/src/svg-icon.test.tsx create mode 100644 packages/utils/test/src/transaction-manager.test.ts create mode 100644 packages/utils/test/src/unique-id.test.ts diff --git a/packages/utils/jest.config.js b/packages/utils/jest.config.js index 328ea622eb..0631fa00c9 100644 --- a/packages/utils/jest.config.js +++ b/packages/utils/jest.config.js @@ -11,6 +11,7 @@ const jestConfig = { '!**/node_modules/**', '!**/vendor/**', ], + setupFilesAfterEnv: ['./jest.setup.js'], }; // 只对本仓库内的 pkg 做 mapping diff --git a/packages/utils/jest.setup.js b/packages/utils/jest.setup.js new file mode 100644 index 0000000000..7b0828bfa8 --- /dev/null +++ b/packages/utils/jest.setup.js @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/packages/utils/package.json b/packages/utils/package.json index fab7828f13..af76e9e2f6 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -9,7 +9,7 @@ "main": "lib/index.js", "module": "es/index.js", "scripts": { - "test": "build-scripts test --config build.test.json", + "test": "build-scripts test --config build.test.json --jest-coverage", "build": "build-scripts build" }, "dependencies": { @@ -21,8 +21,11 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", + "@testing-library/jest-dom": "^6.1.4", + "@testing-library/react": "^11.2.7", "@types/node": "^13.7.1", - "@types/react": "^16" + "@types/react": "^16", + "react-dom": "^16.14.0" }, "publishConfig": { "access": "public", diff --git a/packages/utils/src/check-types/is-action-content-object.ts b/packages/utils/src/check-types/is-action-content-object.ts index 4e9a6545a4..8fe31b5bd7 100644 --- a/packages/utils/src/check-types/is-action-content-object.ts +++ b/packages/utils/src/check-types/is-action-content-object.ts @@ -1,5 +1,6 @@ import { IPublicTypeActionContentObject } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isActionContentObject(obj: any): obj is IPublicTypeActionContentObject { - return obj && typeof obj === 'object'; + return isObject(obj); } diff --git a/packages/utils/src/check-types/is-custom-view.ts b/packages/utils/src/check-types/is-custom-view.ts index 89ea9f10e4..4cf921d9c5 100644 --- a/packages/utils/src/check-types/is-custom-view.ts +++ b/packages/utils/src/check-types/is-custom-view.ts @@ -2,7 +2,9 @@ import { isValidElement } from 'react'; import { isReactComponent } from '../is-react'; import { IPublicTypeCustomView } from '@alilc/lowcode-types'; - export function isCustomView(obj: any): obj is IPublicTypeCustomView { - return obj && (isValidElement(obj) || isReactComponent(obj)); + if (!obj) { + return false; + } + return isValidElement(obj) || isReactComponent(obj); } diff --git a/packages/utils/src/check-types/is-drag-any-object.ts b/packages/utils/src/check-types/is-drag-any-object.ts index 34f140f4a5..8711b4e333 100644 --- a/packages/utils/src/check-types/is-drag-any-object.ts +++ b/packages/utils/src/check-types/is-drag-any-object.ts @@ -1,5 +1,9 @@ import { IPublicEnumDragObjectType } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isDragAnyObject(obj: any): boolean { - return obj && obj.type !== IPublicEnumDragObjectType.NodeData && obj.type !== IPublicEnumDragObjectType.Node; + if (!isObject(obj)) { + return false; + } + return obj.type !== IPublicEnumDragObjectType.NodeData && obj.type !== IPublicEnumDragObjectType.Node; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-drag-node-data-object.ts b/packages/utils/src/check-types/is-drag-node-data-object.ts index 4b08f67fa6..aa62f5b1c9 100644 --- a/packages/utils/src/check-types/is-drag-node-data-object.ts +++ b/packages/utils/src/check-types/is-drag-node-data-object.ts @@ -1,5 +1,9 @@ import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataObject { - return obj && obj.type === IPublicEnumDragObjectType.NodeData; + if (!isObject(obj)) { + return false; + } + return obj.type === IPublicEnumDragObjectType.NodeData; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-drag-node-object.ts b/packages/utils/src/check-types/is-drag-node-object.ts index 1b6c131e93..3a29ec967f 100644 --- a/packages/utils/src/check-types/is-drag-node-object.ts +++ b/packages/utils/src/check-types/is-drag-node-object.ts @@ -1,5 +1,9 @@ import { IPublicEnumDragObjectType, IPublicModelNode, IPublicTypeDragNodeObject } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isDragNodeObject<Node = IPublicModelNode>(obj: any): obj is IPublicTypeDragNodeObject<Node> { - return obj && obj.type === IPublicEnumDragObjectType.Node; + if (!isObject(obj)) { + return false; + } + return obj.type === IPublicEnumDragObjectType.Node; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-dynamic-setter.ts b/packages/utils/src/check-types/is-dynamic-setter.ts index 43a8cb8beb..35f8ff3892 100644 --- a/packages/utils/src/check-types/is-dynamic-setter.ts +++ b/packages/utils/src/check-types/is-dynamic-setter.ts @@ -1,7 +1,10 @@ +import { isFunction } from '../is-function'; import { isReactClass } from '../is-react'; import { IPublicTypeDynamicSetter } from '@alilc/lowcode-types'; - export function isDynamicSetter(obj: any): obj is IPublicTypeDynamicSetter { - return obj && typeof obj === 'function' && !isReactClass(obj); + if (!isFunction(obj)) { + return false; + } + return !isReactClass(obj); } diff --git a/packages/utils/src/check-types/is-function.ts b/packages/utils/src/check-types/is-function.ts new file mode 100644 index 0000000000..d7d3b4c27d --- /dev/null +++ b/packages/utils/src/check-types/is-function.ts @@ -0,0 +1,3 @@ +export function isFunction(obj: any): obj is Function { + return obj && typeof obj === 'function'; +} \ No newline at end of file diff --git a/packages/utils/src/check-types/is-i18n-data.ts b/packages/utils/src/check-types/is-i18n-data.ts index f4a7b6f7aa..793295d240 100644 --- a/packages/utils/src/check-types/is-i18n-data.ts +++ b/packages/utils/src/check-types/is-i18n-data.ts @@ -1,8 +1,9 @@ - -// type checks - -import { IPublicTypeI18nData } from "@alilc/lowcode-types"; +import { IPublicTypeI18nData } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isI18nData(obj: any): obj is IPublicTypeI18nData { - return obj && obj.type === 'i18n'; + if (!isObject(obj)) { + return false; + } + return obj.type === 'i18n'; } diff --git a/packages/utils/src/check-types/is-isfunction.ts b/packages/utils/src/check-types/is-isfunction.ts index a6d5da9008..64b8676637 100644 --- a/packages/utils/src/check-types/is-isfunction.ts +++ b/packages/utils/src/check-types/is-isfunction.ts @@ -1,10 +1,26 @@ +import { IPublicTypeJSFunction } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; + +interface InnerJsFunction { + type: 'JSExpression'; + source: string; + value: string; + extType: 'function'; +} + /** * 内部版本 的 { type: 'JSExpression', source: '', value: '', extType: 'function' } 能力上等同于 JSFunction */ -export function isInnerJsFunction(data: any) { - return data && data.type === 'JSExpression' && data.extType === 'function'; +export function isInnerJsFunction(data: any): data is InnerJsFunction { + if (!isObject(data)) { + return false; + } + return data.type === 'JSExpression' && data.extType === 'function'; } -export function isJSFunction(data: any): boolean { - return typeof data === 'object' && data && data.type === 'JSFunction' || isInnerJsFunction(data); +export function isJSFunction(data: any): data is IPublicTypeJSFunction { + if (!isObject(data)) { + return false; + } + return data.type === 'JSFunction' || isInnerJsFunction(data); } diff --git a/packages/utils/src/check-types/is-jsblock.ts b/packages/utils/src/check-types/is-jsblock.ts index 4c3b28f525..858f5c09cd 100644 --- a/packages/utils/src/check-types/is-jsblock.ts +++ b/packages/utils/src/check-types/is-jsblock.ts @@ -1,4 +1,9 @@ +import { IPublicTypeJSBlock } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; -export function isJSBlock(data: any): boolean { - return data && data.type === 'JSBlock'; +export function isJSBlock(data: any): data is IPublicTypeJSBlock { + if (!isObject(data)) { + return false; + } + return data.type === 'JSBlock'; } diff --git a/packages/utils/src/check-types/is-jsexpression.ts b/packages/utils/src/check-types/is-jsexpression.ts index 949d0f00da..16b8f4ac2a 100644 --- a/packages/utils/src/check-types/is-jsexpression.ts +++ b/packages/utils/src/check-types/is-jsexpression.ts @@ -1,4 +1,5 @@ import { IPublicTypeJSExpression } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; /** * 为了避免把 { type: 'JSExpression', extType: 'function' } 误判为表达式,故增加如下逻辑。 @@ -11,5 +12,8 @@ import { IPublicTypeJSExpression } from '@alilc/lowcode-types'; * @returns */ export function isJSExpression(data: any): data is IPublicTypeJSExpression { - return data && data.type === 'JSExpression' && data.extType !== 'function'; + if (!isObject(data)) { + return false; + } + return data.type === 'JSExpression' && data.extType !== 'function'; } diff --git a/packages/utils/src/check-types/is-jsslot.ts b/packages/utils/src/check-types/is-jsslot.ts index 1a8f09def5..1fb1d819d7 100644 --- a/packages/utils/src/check-types/is-jsslot.ts +++ b/packages/utils/src/check-types/is-jsslot.ts @@ -1,5 +1,9 @@ import { IPublicTypeJSSlot } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isJSSlot(data: any): data is IPublicTypeJSSlot { - return data && data.type === 'JSSlot'; + if (!isObject(data)) { + return false; + } + return data.type === 'JSSlot'; } diff --git a/packages/utils/src/check-types/is-location-children-detail.ts b/packages/utils/src/check-types/is-location-children-detail.ts index c6d2819d30..cc093c4e4a 100644 --- a/packages/utils/src/check-types/is-location-children-detail.ts +++ b/packages/utils/src/check-types/is-location-children-detail.ts @@ -1,5 +1,9 @@ import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isLocationChildrenDetail(obj: any): obj is IPublicTypeLocationChildrenDetail { - return obj && obj.type === IPublicTypeLocationDetailType.Children; + if (!isObject(obj)) { + return false; + } + return obj.type === IPublicTypeLocationDetailType.Children; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-location-data.ts b/packages/utils/src/check-types/is-location-data.ts index 8bb3103461..dabd493fa8 100644 --- a/packages/utils/src/check-types/is-location-data.ts +++ b/packages/utils/src/check-types/is-location-data.ts @@ -1,5 +1,9 @@ import { IPublicTypeLocationData } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isLocationData(obj: any): obj is IPublicTypeLocationData { - return obj && obj.target && obj.detail; + if (!isObject(obj)) { + return false; + } + return 'target' in obj && 'detail' in obj; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-lowcode-project-schema.ts b/packages/utils/src/check-types/is-lowcode-project-schema.ts index 0fffaea2fc..230911f0f3 100644 --- a/packages/utils/src/check-types/is-lowcode-project-schema.ts +++ b/packages/utils/src/check-types/is-lowcode-project-schema.ts @@ -1,6 +1,15 @@ -import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from "@alilc/lowcode-types"; -import { isComponentSchema } from "./is-component-schema"; +import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from '@alilc/lowcode-types'; +import { isComponentSchema } from './is-component-schema'; +import { isObject } from '../is-object'; export function isLowcodeProjectSchema(data: any): data is IPublicTypeProjectSchema<IPublicTypeComponentSchema> { - return data && data.componentsTree && data.componentsTree.length && isComponentSchema(data.componentsTree[0]); + if (!isObject(data)) { + return false; + } + + if (!('componentsTree' in data) || data.componentsTree.length === 0) { + return false; + } + + return isComponentSchema(data.componentsTree[0]); } diff --git a/packages/utils/src/check-types/is-node-schema.ts b/packages/utils/src/check-types/is-node-schema.ts index bfc3ff3f2b..253c05a080 100644 --- a/packages/utils/src/check-types/is-node-schema.ts +++ b/packages/utils/src/check-types/is-node-schema.ts @@ -1,5 +1,9 @@ import { IPublicTypeNodeSchema } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isNodeSchema(data: any): data is IPublicTypeNodeSchema { - return data && data.componentName && !data.isNode; + if (!isObject(data)) { + return false; + } + return 'componentName' in data && !data.isNode; } diff --git a/packages/utils/src/check-types/is-node.ts b/packages/utils/src/check-types/is-node.ts index 14c2e2f74e..b4690ddff9 100644 --- a/packages/utils/src/check-types/is-node.ts +++ b/packages/utils/src/check-types/is-node.ts @@ -1,5 +1,9 @@ import { IPublicModelNode } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isNode<Node = IPublicModelNode>(node: any): node is Node { - return node && node.isNode; + if (!isObject(node)) { + return false; + } + return node.isNode; } \ No newline at end of file diff --git a/packages/utils/src/check-types/is-object.ts b/packages/utils/src/check-types/is-object.ts new file mode 100644 index 0000000000..56ceb7d979 --- /dev/null +++ b/packages/utils/src/check-types/is-object.ts @@ -0,0 +1,3 @@ +export function isObject(obj: any): boolean { + return obj && typeof obj === 'object'; +} \ No newline at end of file diff --git a/packages/utils/src/check-types/is-procode-component-type.ts b/packages/utils/src/check-types/is-procode-component-type.ts index 5c768dd943..46618dcd5a 100644 --- a/packages/utils/src/check-types/is-procode-component-type.ts +++ b/packages/utils/src/check-types/is-procode-component-type.ts @@ -1,6 +1,10 @@ import { IPublicTypeComponentMap, IPublicTypeProCodeComponent } from '@alilc/lowcode-types'; - +import { isObject } from '../is-object'; export function isProCodeComponentType(desc: IPublicTypeComponentMap): desc is IPublicTypeProCodeComponent { + if (!isObject(desc)) { + return false; + } + return 'package' in desc; } diff --git a/packages/utils/src/check-types/is-project-schema.ts b/packages/utils/src/check-types/is-project-schema.ts index b228d481e0..d217acd9ee 100644 --- a/packages/utils/src/check-types/is-project-schema.ts +++ b/packages/utils/src/check-types/is-project-schema.ts @@ -1,5 +1,9 @@ -import { IPublicTypeProjectSchema } from "@alilc/lowcode-types"; +import { IPublicTypeProjectSchema } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isProjectSchema(data: any): data is IPublicTypeProjectSchema { - return data && data.componentsTree; + if (!isObject(data)) { + return false; + } + return 'componentsTree' in data; } diff --git a/packages/utils/src/check-types/is-setter-config.ts b/packages/utils/src/check-types/is-setter-config.ts index d631d237f1..98d835f32c 100644 --- a/packages/utils/src/check-types/is-setter-config.ts +++ b/packages/utils/src/check-types/is-setter-config.ts @@ -1,7 +1,10 @@ import { IPublicTypeSetterConfig } from '@alilc/lowcode-types'; import { isCustomView } from './is-custom-view'; - +import { isObject } from '../is-object'; export function isSetterConfig(obj: any): obj is IPublicTypeSetterConfig { - return obj && typeof obj === 'object' && 'componentName' in obj && !isCustomView(obj); + if (!isObject(obj)) { + return false; + } + return 'componentName' in obj && !isCustomView(obj); } diff --git a/packages/utils/src/check-types/is-setting-field.ts b/packages/utils/src/check-types/is-setting-field.ts index 67a183a959..0d6e21d848 100644 --- a/packages/utils/src/check-types/is-setting-field.ts +++ b/packages/utils/src/check-types/is-setting-field.ts @@ -1,5 +1,10 @@ -import { IPublicModelSettingField } from "@alilc/lowcode-types"; +import { IPublicModelSettingField } from '@alilc/lowcode-types'; +import { isObject } from '../is-object'; export function isSettingField(obj: any): obj is IPublicModelSettingField { - return obj && obj.isSettingField; + if (!isObject(obj)) { + return false; + } + + return 'isSettingField' in obj && obj.isSettingField; } diff --git a/packages/utils/src/clone-enumerable-property.ts b/packages/utils/src/clone-enumerable-property.ts index 414f8dccdd..eb09e177fc 100644 --- a/packages/utils/src/clone-enumerable-property.ts +++ b/packages/utils/src/clone-enumerable-property.ts @@ -11,8 +11,8 @@ const excludePropertyNames = [ 'arguments', ]; -export function cloneEnumerableProperty(target: any, origin: any) { - const compExtraPropertyNames = Object.keys(origin).filter(d => !excludePropertyNames.includes(d)); +export function cloneEnumerableProperty(target: any, origin: any, excludes = excludePropertyNames) { + const compExtraPropertyNames = Object.keys(origin).filter(d => !excludes.includes(d)); compExtraPropertyNames.forEach((d: string) => { (target as any)[d] = origin[d]; diff --git a/packages/utils/src/is-object.ts b/packages/utils/src/is-object.ts index 50b580e5a1..c8d764458b 100644 --- a/packages/utils/src/is-object.ts +++ b/packages/utils/src/is-object.ts @@ -1,4 +1,4 @@ -export function isObject(value: any): value is Record<string, unknown> { +export function isObject(value: any): value is Record<string, any> { return value !== null && typeof value === 'object'; } diff --git a/packages/utils/src/is-react.ts b/packages/utils/src/is-react.ts index b19f043f14..1d6c939ea1 100644 --- a/packages/utils/src/is-react.ts +++ b/packages/utils/src/is-react.ts @@ -2,27 +2,49 @@ import { ComponentClass, Component, FunctionComponent, ComponentType, createElem import { cloneEnumerableProperty } from './clone-enumerable-property'; const hasSymbol = typeof Symbol === 'function' && Symbol.for; -const REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; -const REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; +export const REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; +export const REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3; export function isReactClass(obj: any): obj is ComponentClass<any> { - return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component); + if (!obj) { + return false; + } + if (obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component)) { + return true; + } + return false; } export function acceptsRef(obj: any): boolean { - return obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj); + if (!obj) { + return false; + } + if (obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj)) { + return true; + } + + return false; } export function isForwardRefType(obj: any): boolean { - return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE; + if (!obj || !obj?.$$typeof) { + return false; + } + return obj?.$$typeof === REACT_FORWARD_REF_TYPE; } -function isMemoType(obj: any): boolean { - return obj?.$$typeof && obj.$$typeof === REACT_MEMO_TYPE; +export function isMemoType(obj: any): boolean { + if (!obj || !obj?.$$typeof) { + return false; + } + return obj.$$typeof === REACT_MEMO_TYPE; } export function isForwardOrMemoForward(obj: any): boolean { - return obj?.$$typeof && ( + if (!obj || !obj?.$$typeof) { + return false; + } + return ( // React.forwardRef(..) isForwardRefType(obj) || // React.memo(React.forwardRef(..)) diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 4c8f375ecd..3eb43eedbe 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -88,7 +88,7 @@ const shouldOutput = ( const output = (logLevel: string, bizName: string) => { return (...args: any[]) => { - return outputFunction[logLevel].apply(console, getLogArgs(args, bizName, logLevel)); + return outputFunction[logLevel]?.apply(console, getLogArgs(args, bizName, logLevel)); }; }; @@ -142,7 +142,6 @@ const defaultOptions: Options = { bizName: '*', }; - class Logger { bizName: string; targetBizName: string; @@ -192,7 +191,6 @@ class Logger { } } - export { Logger }; export function getLogger(config: { level: Level; bizName: string }): Logger { diff --git a/packages/utils/src/misc.ts b/packages/utils/src/misc.ts index 89f121065b..28833ef321 100644 --- a/packages/utils/src/misc.ts +++ b/packages/utils/src/misc.ts @@ -2,6 +2,9 @@ import { isI18NObject } from './is-object'; import { get } from 'lodash'; import { IPublicEnumTransformStage, IPublicModelComponentMeta } from '@alilc/lowcode-types'; +import { Logger } from './logger'; + +const logger = new Logger({ level: 'warn', bizName: 'utils' }); interface Variable { type: 'variable'; @@ -10,7 +13,10 @@ interface Variable { } export function isVariable(obj: any): obj is Variable { - return obj && obj.type === 'variable'; + if (!obj || typeof obj !== 'object') { + return false; + } + return obj.type === 'variable'; } export function isUseI18NSetter(prototype: any, propName: string) { @@ -103,12 +109,15 @@ export function invariant(check: any, message: string, thing?: any) { export function deprecate(fail: any, message: string, alterative?: string) { if (fail) { - console.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.` : '')); + logger.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.` : '')); } } export function isRegExp(obj: any): obj is RegExp { - return obj && obj.test && obj.exec && obj.compile; + if (!obj || typeof obj !== 'object') { + return false; + } + return 'test' in obj && 'exec' in obj && 'compile' in obj; } /** diff --git a/packages/utils/src/navtive-selection.ts b/packages/utils/src/navtive-selection.ts index 76f51f48aa..b8e5257734 100644 --- a/packages/utils/src/navtive-selection.ts +++ b/packages/utils/src/navtive-selection.ts @@ -1,4 +1,5 @@ -let nativeSelectionEnabled = true; +export let nativeSelectionEnabled = true; + const preventSelection = (e: Event) => { if (nativeSelectionEnabled) { return null; diff --git a/packages/utils/src/script.ts b/packages/utils/src/script.ts index 25159b198c..c4c476fac4 100644 --- a/packages/utils/src/script.ts +++ b/packages/utils/src/script.ts @@ -1,4 +1,7 @@ import { createDefer } from './create-defer'; +import { Logger } from './logger'; + +const logger = new Logger({ level: 'warn', bizName: 'utils' }); export function evaluate(script: string, scriptType?: string) { const scriptEl = document.createElement('script'); @@ -53,7 +56,7 @@ export function newFunction(args: string, code: string) { // eslint-disable-next-line no-new-func return new Function(args, code); } catch (e) { - console.warn('Caught error, Cant init func'); + logger.warn('Caught error, Cant init func'); return null; } } diff --git a/packages/utils/src/svg-icon.tsx b/packages/utils/src/svg-icon.tsx index f75724b064..2513f7bcab 100644 --- a/packages/utils/src/svg-icon.tsx +++ b/packages/utils/src/svg-icon.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import React, { ReactNode } from 'react'; const SizePresets: any = { xsmall: 8, diff --git a/packages/utils/test/src/__snapshots__/is-react.test.tsx.snap b/packages/utils/test/src/__snapshots__/is-react.test.tsx.snap new file mode 100644 index 0000000000..14ef394533 --- /dev/null +++ b/packages/utils/test/src/__snapshots__/is-react.test.tsx.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`wrapReactClass should render the FunctionComponent with props 1`] = ` +<FunctionComponent + prop1="value1" + prop2="value2" +> + Child Text +</FunctionComponent> +`; diff --git a/packages/utils/test/src/build-components/buildComponents.test.ts b/packages/utils/test/src/build-components/buildComponents.test.ts deleted file mode 100644 index e854890da4..0000000000 --- a/packages/utils/test/src/build-components/buildComponents.test.ts +++ /dev/null @@ -1,342 +0,0 @@ - -import { buildComponents } from "../../../src/build-components"; - -function Button() {}; - -function WrapButton() {}; - -function ButtonGroup() {}; - -function WrapButtonGroup() {}; - -ButtonGroup.Button = Button; - -Button.displayName = "Button"; -ButtonGroup.displayName = "ButtonGroup"; -ButtonGroup.prototype.isReactComponent = true; -Button.prototype.isReactComponent = true; - -jest.mock('../../../src/is-react', () => { - const original = jest.requireActual('../../../src/is-react'); - return { - ...original, - wrapReactClass(view) { - return view; - } - } -}) - -describe('build-component', () => { - it('basic button', () => { - expect( - buildComponents( - { - '@alilc/button': { - Button, - } - }, - { - Button: { - componentName: 'Button', - package: '@alilc/button', - destructuring: true, - exportName: 'Button', - subName: 'Button', - } - }, - () => {}, - )) - .toEqual({ - Button, - }); - }); - - it('component is a __esModule', () => { - expect( - buildComponents( - { - '@alilc/button': { - __esModule: true, - default: Button, - } - }, - { - Button: { - componentName: 'Button', - package: '@alilc/button', - } - }, - () => {}, - )) - .toEqual({ - Button, - }); - }) - - it('basic warp button', () => { - expect( - buildComponents( - { - '@alilc/button': { - WrapButton, - } - }, - { - WrapButton: { - componentName: 'WrapButton', - package: '@alilc/button', - destructuring: true, - exportName: 'WrapButton', - subName: 'WrapButton', - } - }, - () => {}, - )) - .toEqual({ - WrapButton, - }); - }); - - it('destructuring is false button', () => { - expect( - buildComponents( - { - '@alilc/button': Button - }, - { - Button: { - componentName: 'Button', - package: '@alilc/button', - destructuring: false, - } - }, - () => {}, - )) - .toEqual({ - Button, - }); - }); - - it('Button and ButtonGroup', () => { - expect( - buildComponents( - { - '@alilc/button': { - Button, - ButtonGroup, - } - }, - { - Button: { - componentName: 'Button', - package: '@alilc/button', - destructuring: true, - exportName: 'Button', - subName: 'Button', - }, - ButtonGroup: { - componentName: 'ButtonGroup', - package: '@alilc/button', - destructuring: true, - exportName: 'ButtonGroup', - subName: 'ButtonGroup', - } - }, - () => {}, - )) - .toEqual({ - Button, - ButtonGroup, - }); - }); - - it('ButtonGroup and ButtonGroup.Button', () => { - expect( - buildComponents( - { - '@alilc/button': { - ButtonGroup, - } - }, - { - Button: { - componentName: 'Button', - package: '@alilc/button', - destructuring: true, - exportName: 'ButtonGroup', - subName: 'ButtonGroup.Button', - }, - ButtonGroup: { - componentName: 'ButtonGroup', - package: '@alilc/button', - destructuring: true, - exportName: 'ButtonGroup', - subName: 'ButtonGroup', - } - }, - () => {}, - )) - .toEqual({ - Button, - ButtonGroup, - }); - }); - - it('ButtonGroup.default and ButtonGroup.Button', () => { - expect( - buildComponents( - { - '@alilc/button': ButtonGroup, - }, - { - Button: { - componentName: 'Button', - package: '@alilc/button', - destructuring: true, - exportName: 'Button', - subName: 'Button', - }, - ButtonGroup: { - componentName: 'ButtonGroup', - package: '@alilc/button', - destructuring: true, - exportName: 'default', - subName: 'default', - } - }, - () => {}, - )) - .toEqual({ - Button, - ButtonGroup, - }); - }); - - it('no npm component', () => { - expect( - buildComponents( - { - '@alilc/button': Button, - }, - { - Button: null, - }, - () => {}, - )) - .toEqual({}); - }); - - it('no npm component and global button', () => { - window.Button = Button; - expect( - buildComponents( - {}, - { - Button: null, - }, - () => {}, - )) - .toEqual({ - Button, - }); - window.Button = null; - }); - - it('componentsMap value is component funtion', () => { - expect( - buildComponents( - {}, - { - Button, - }, - () => {}, - )) - .toEqual({ - Button, - }); - }); - - - it('componentsMap value is component', () => { - expect( - buildComponents( - {}, - { - Button: WrapButton, - }, - () => {}, - )) - .toEqual({ - Button: WrapButton, - }); - }); - - it('componentsMap value is mix component', () => { - expect( - buildComponents( - {}, - { - Button: { - WrapButton, - Button, - ButtonGroup, - }, - }, - () => {}, - )) - .toEqual({ - Button: { - WrapButton, - Button, - ButtonGroup, - }, - }); - }); - - it('componentsMap value is Lowcode Component', () => { - expect( - buildComponents( - {}, - { - Button: { - componentName: 'Component', - schema: {}, - }, - }, - (component) => { - return component as any; - }, - )) - .toEqual({ - Button: { - componentsMap: [], - componentsTree: [ - { - componentName: 'Component', - schema: {}, - } - ], - version: "", - }, - }); - }) -}); - -describe('build div component', () => { - it('build div component', () => { - const components = buildComponents( - { - '@alilc/div': 'div' - }, - { - div: { - componentName: 'div', - package: '@alilc/div' - } - }, - () => {}, - ); - - expect(components['div']).not.toBeNull(); - }) -}) \ No newline at end of file diff --git a/packages/utils/test/src/build-components/buildComponents.test.tsx b/packages/utils/test/src/build-components/buildComponents.test.tsx new file mode 100644 index 0000000000..a50a68b396 --- /dev/null +++ b/packages/utils/test/src/build-components/buildComponents.test.tsx @@ -0,0 +1,616 @@ +import React from 'react'; +import { + accessLibrary, + generateHtmlComp, + getSubComponent, + buildComponents, + getProjectUtils, +} from "../../../src/build-components"; + +function Button() {}; + +function WrapButton() {}; + +function ButtonGroup() {}; + +function WrapButtonGroup() {}; + +ButtonGroup.Button = Button; + +Button.displayName = "Button"; +ButtonGroup.displayName = "ButtonGroup"; +ButtonGroup.prototype.isReactComponent = true; +Button.prototype.isReactComponent = true; + +jest.mock('../../../src/is-react', () => { + const original = jest.requireActual('../../../src/is-react'); + return { + ...original, + wrapReactClass(view) { + return view; + } + } +}); + +describe('accessLibrary', () => { + it('should return a library object when given a library object', () => { + const libraryObject = { key: 'value' }; + const result = accessLibrary(libraryObject); + expect(result).toEqual(libraryObject); + }); + + it('should generate an HTML component when given a string library name', () => { + const libraryName = 'div'; + const result = accessLibrary(libraryName); + + // You can write more specific assertions to validate the generated component + expect(result).toBeDefined(); + }); + + // Add more test cases to cover other scenarios +}); + +describe('generateHtmlComp', () => { + it('should generate an HTML component for valid HTML tags', () => { + const htmlTags = ['a', 'img', 'div', 'span', 'svg']; + htmlTags.forEach((tag) => { + const result = generateHtmlComp(tag); + + // You can write more specific assertions to validate the generated component + expect(result).toBeDefined(); + }); + }); + + it('should return undefined for an invalid HTML tag', () => { + const invalidTag = 'invalidtag'; + const result = generateHtmlComp(invalidTag); + expect(result).toBeUndefined(); + }); + + // Add more test cases to cover other scenarios +}); + +describe('getSubComponent', () => { + it('should return the root library if paths are empty', () => { + const library = { component: 'RootComponent' }; + const paths = []; + const result = getSubComponent(library, paths); + expect(result).toEqual(library); + }); + + it('should return the specified sub-component', () => { + const library = { + components: { + Button: 'ButtonComponent', + Text: 'TextComponent', + }, + }; + const paths = ['components', 'Button']; + const result = getSubComponent(library, paths); + expect(result).toEqual('ButtonComponent'); + }); + + it('should handle missing keys in the path', () => { + const library = { + components: { + Button: 'ButtonComponent', + }, + }; + const paths = ['components', 'Text']; + const result = getSubComponent(library, paths); + expect(result).toEqual({ + Button: 'ButtonComponent', + }); + }); + + it('should handle exceptions and return null', () => { + const library = 'ButtonComponent'; + const paths = ['components', 'Button']; + // Simulate an exception by providing a non-object in place of 'ButtonComponent' + const result = getSubComponent(library, paths); + expect(result).toBeNull(); + }); + + it('should handle the "default" key as the first path element', () => { + const library = { + default: 'DefaultComponent', + }; + const paths = ['default']; + const result = getSubComponent(library, paths); + expect(result).toEqual('DefaultComponent'); + }); +}); + +describe('getProjectUtils', () => { + it('should return an empty object when given empty metadata and library map', () => { + const libraryMap = {}; + const utilsMetadata = []; + const result = getProjectUtils(libraryMap, utilsMetadata); + expect(result).toEqual({}); + }); + + it('should return project utilities based on metadata and library map', () => { + const libraryMap = { + 'package1': 'library1', + 'package2': 'library2', + }; + + const utilsMetadata = [ + { + name: 'util1', + npm: { + package: 'package1', + }, + }, + { + name: 'util2', + npm: { + package: 'package2', + }, + }, + ]; + + global['library1'] = { name: 'library1' }; + global['library2'] = { name: 'library2' }; + + const result = getProjectUtils(libraryMap, utilsMetadata); + + // Define the expected output based on the mocked accessLibrary + const expectedOutput = { + 'util1': { name: 'library1' }, + 'util2': { name: 'library2' }, + }; + + expect(result).toEqual(expectedOutput); + + global['library1'] = null; + global['library1'] = null; + }); + + it('should handle metadata with destructuring', () => { + const libraryMap = { + 'package1': { destructuring: true, util1: 'library1', util2: 'library2' }, + }; + + const utilsMetadata = [ + { + name: 'util1', + npm: { + package: 'package1', + destructuring: true, + }, + }, + ]; + + const result = getProjectUtils(libraryMap, utilsMetadata); + + // Define the expected output based on the mocked accessLibrary + const expectedOutput = { + 'util1': 'library1', + 'util2': 'library2', + }; + + expect(result).toEqual(expectedOutput); + }); +}); + +describe('buildComponents', () => { + it('should create components from component map with React components', () => { + const libraryMap = {}; + const componentsMap = { + Button: () => <button>Button</button>, + Text: () => <p>Text</p>, + }; + + const createComponent = (schema) => { + // Mock createComponent function + return schema.componentsTree.map((component) => component.component); + }; + + const result = buildComponents(libraryMap, componentsMap, createComponent); + + expect(result.Button).toBeDefined(); + expect(result.Text).toBeDefined(); + }); + + it('should create components from component map with component schemas', () => { + const libraryMap = {}; + const componentsMap = { + Button: { + componentsTree: [ + { + componentName: 'Component' + } + ] + }, + Text: { + componentsTree: [ + { + componentName: 'Component' + } + ] + }, + }; + + const createComponent = (schema) => { + // Mock createComponent function + return schema.componentsTree.map((component) => component.component); + }; + + const result = buildComponents(libraryMap, componentsMap, createComponent); + + expect(result.Button).toBeDefined(); + expect(result.Text).toBeDefined(); + }); + + it('should create components from component map with React components and schemas', () => { + const libraryMap = {}; + const componentsMap = { + Button: () => <button>Button</button>, + Text: { + type: 'ComponentSchema', + // Add component schema properties here + }, + }; + + const createComponent = (schema) => { + // Mock createComponent function + return schema.componentsTree.map((component) => component.component); + }; + + const result = buildComponents(libraryMap, componentsMap, createComponent); + + expect(result.Button).toBeDefined(); + expect(result.Text).toBeDefined(); + }); + + it('should create components from component map with library mappings', () => { + const libraryMap = { + 'libraryName1': 'library1', + 'libraryName2': 'library2', + }; + const componentsMap = { + Button: { + package: 'libraryName1', + version: '1.0', + exportName: 'ButtonComponent', + }, + Text: { + package: 'libraryName2', + version: '2.0', + exportName: 'TextComponent', + }, + }; + + const createComponent = (schema) => { + // Mock createComponent function + return schema.componentsTree.map((component) => component.component); + }; + + global['library1'] = () => <button>ButtonComponent</button>; + global['library2'] = () => () => <p>TextComponent</p>; + + const result = buildComponents(libraryMap, componentsMap, createComponent); + + expect(result.Button).toBeDefined(); + expect(result.Text).toBeDefined(); + + global['library1'] = null; + global['library2'] = null; + }); +}); + +describe('build-component', () => { + it('basic button', () => { + expect( + buildComponents( + { + '@alilc/button': { + Button, + } + }, + { + Button: { + componentName: 'Button', + package: '@alilc/button', + destructuring: true, + exportName: 'Button', + subName: 'Button', + } + }, + () => {}, + )) + .toEqual({ + Button, + }); + }); + + it('component is a __esModule', () => { + expect( + buildComponents( + { + '@alilc/button': { + __esModule: true, + default: Button, + } + }, + { + Button: { + componentName: 'Button', + package: '@alilc/button', + } + }, + () => {}, + )) + .toEqual({ + Button, + }); + }) + + it('basic warp button', () => { + expect( + buildComponents( + { + '@alilc/button': { + WrapButton, + } + }, + { + WrapButton: { + componentName: 'WrapButton', + package: '@alilc/button', + destructuring: true, + exportName: 'WrapButton', + subName: 'WrapButton', + } + }, + () => {}, + )) + .toEqual({ + WrapButton, + }); + }); + + it('destructuring is false button', () => { + expect( + buildComponents( + { + '@alilc/button': Button + }, + { + Button: { + componentName: 'Button', + package: '@alilc/button', + destructuring: false, + } + }, + () => {}, + )) + .toEqual({ + Button, + }); + }); + + it('Button and ButtonGroup', () => { + expect( + buildComponents( + { + '@alilc/button': { + Button, + ButtonGroup, + } + }, + { + Button: { + componentName: 'Button', + package: '@alilc/button', + destructuring: true, + exportName: 'Button', + subName: 'Button', + }, + ButtonGroup: { + componentName: 'ButtonGroup', + package: '@alilc/button', + destructuring: true, + exportName: 'ButtonGroup', + subName: 'ButtonGroup', + } + }, + () => {}, + )) + .toEqual({ + Button, + ButtonGroup, + }); + }); + + it('ButtonGroup and ButtonGroup.Button', () => { + expect( + buildComponents( + { + '@alilc/button': { + ButtonGroup, + } + }, + { + Button: { + componentName: 'Button', + package: '@alilc/button', + destructuring: true, + exportName: 'ButtonGroup', + subName: 'ButtonGroup.Button', + }, + ButtonGroup: { + componentName: 'ButtonGroup', + package: '@alilc/button', + destructuring: true, + exportName: 'ButtonGroup', + subName: 'ButtonGroup', + } + }, + () => {}, + )) + .toEqual({ + Button, + ButtonGroup, + }); + }); + + it('ButtonGroup.default and ButtonGroup.Button', () => { + expect( + buildComponents( + { + '@alilc/button': ButtonGroup, + }, + { + Button: { + componentName: 'Button', + package: '@alilc/button', + destructuring: true, + exportName: 'Button', + subName: 'Button', + }, + ButtonGroup: { + componentName: 'ButtonGroup', + package: '@alilc/button', + destructuring: true, + exportName: 'default', + subName: 'default', + } + }, + () => {}, + )) + .toEqual({ + Button, + ButtonGroup, + }); + }); + + it('no npm component', () => { + expect( + buildComponents( + { + '@alilc/button': Button, + }, + { + Button: null, + }, + () => {}, + )) + .toEqual({}); + }); + + it('no npm component and global button', () => { + window.Button = Button; + expect( + buildComponents( + {}, + { + Button: null, + }, + () => {}, + )) + .toEqual({ + Button, + }); + window.Button = null; + }); + + it('componentsMap value is component funtion', () => { + expect( + buildComponents( + {}, + { + Button, + }, + () => {}, + )) + .toEqual({ + Button, + }); + }); + + + it('componentsMap value is component', () => { + expect( + buildComponents( + {}, + { + Button: WrapButton, + }, + () => {}, + )) + .toEqual({ + Button: WrapButton, + }); + }); + + it('componentsMap value is mix component', () => { + expect( + buildComponents( + {}, + { + Button: { + WrapButton, + Button, + ButtonGroup, + }, + }, + () => {}, + )) + .toEqual({ + Button: { + WrapButton, + Button, + ButtonGroup, + }, + }); + }); + + it('componentsMap value is Lowcode Component', () => { + expect( + buildComponents( + {}, + { + Button: { + componentName: 'Component', + schema: {}, + }, + }, + (component) => { + return component as any; + }, + )) + .toEqual({ + Button: { + componentsMap: [], + componentsTree: [ + { + componentName: 'Component', + schema: {}, + } + ], + version: "", + }, + }); + }) +}); + +describe('build div component', () => { + it('build div component', () => { + const components = buildComponents( + { + '@alilc/div': 'div' + }, + { + div: { + componentName: 'div', + package: '@alilc/div' + } + }, + () => {}, + ); + + expect(components['div']).not.toBeNull(); + }) +}) \ No newline at end of file diff --git a/packages/utils/test/src/check-types/is-action-content-object.test.ts b/packages/utils/test/src/check-types/is-action-content-object.test.ts new file mode 100644 index 0000000000..08b95788d1 --- /dev/null +++ b/packages/utils/test/src/check-types/is-action-content-object.test.ts @@ -0,0 +1,20 @@ +import { isActionContentObject } from '../../../src/check-types/is-action-content-object'; + +describe('isActionContentObject', () => { + test('should return true for an object', () => { + const obj = { prop: 'value' }; + expect(isActionContentObject(obj)).toBe(true); + }); + + test('should return false for a non-object', () => { + expect(isActionContentObject('not an object')).toBe(false); + expect(isActionContentObject(123)).toBe(false); + expect(isActionContentObject(null)).toBe(false); + expect(isActionContentObject(undefined)).toBe(false); + }); + + test('should return false for an empty object', () => { + const obj = {}; + expect(isActionContentObject(obj)).toBe(true); + }); +}); diff --git a/packages/utils/test/src/check-types/is-custom-view.test.tsx b/packages/utils/test/src/check-types/is-custom-view.test.tsx new file mode 100644 index 0000000000..62c08780e6 --- /dev/null +++ b/packages/utils/test/src/check-types/is-custom-view.test.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { isCustomView } from '../../../src/check-types/is-custom-view'; +import { IPublicTypeCustomView } from '@alilc/lowcode-types'; + +describe('isCustomView', () => { + test('should return true when obj is a valid React element', () => { + const obj: IPublicTypeCustomView = <div>Hello, World!</div>; + expect(isCustomView(obj)).toBe(true); + }); + + test('should return true when obj is a valid React component', () => { + const MyComponent: React.FC = () => <div>Hello, World!</div>; + const obj: IPublicTypeCustomView = MyComponent; + expect(isCustomView(obj)).toBe(true); + }); + + test('should return false when obj is null or undefined', () => { + expect(isCustomView(null)).toBe(false); + expect(isCustomView(undefined)).toBe(false); + }); + + test('should return false when obj is not a valid React element or component', () => { + const obj: IPublicTypeCustomView = 'not a valid object'; + expect(isCustomView(obj)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-dom-text.test.ts b/packages/utils/test/src/check-types/is-dom-text.test.ts new file mode 100644 index 0000000000..50dce0fb7a --- /dev/null +++ b/packages/utils/test/src/check-types/is-dom-text.test.ts @@ -0,0 +1,13 @@ +import { isDOMText } from '../../../src/check-types/is-dom-text'; + +describe('isDOMText', () => { + it('should return true when the input is a string', () => { + const result = isDOMText('Hello World'); + expect(result).toBe(true); + }); + + it('should return false when the input is not a string', () => { + const result = isDOMText(123); + expect(result).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-drag-any-object.test.ts b/packages/utils/test/src/check-types/is-drag-any-object.test.ts new file mode 100644 index 0000000000..6a835f2be3 --- /dev/null +++ b/packages/utils/test/src/check-types/is-drag-any-object.test.ts @@ -0,0 +1,32 @@ +import { isDragAnyObject } from '../../../src/check-types/is-drag-any-object'; +import { IPublicEnumDragObjectType } from '@alilc/lowcode-types'; + +describe('isDragAnyObject', () => { + it('should return false if obj is null', () => { + const result = isDragAnyObject(null); + expect(result).toBe(false); + }); + + it('should return false if obj is number', () => { + const result = isDragAnyObject(2); + expect(result).toBe(false); + }); + + it('should return false if obj.type is NodeData', () => { + const obj = { type: IPublicEnumDragObjectType.NodeData }; + const result = isDragAnyObject(obj); + expect(result).toBe(false); + }); + + it('should return false if obj.type is Node', () => { + const obj = { type: IPublicEnumDragObjectType.Node }; + const result = isDragAnyObject(obj); + expect(result).toBe(false); + }); + + it('should return true if obj.type is anything else', () => { + const obj = { type: 'SomeOtherType' }; + const result = isDragAnyObject(obj); + expect(result).toBe(true); + }); +}); diff --git a/packages/utils/test/src/check-types/is-drag-node-data-object.test.ts b/packages/utils/test/src/check-types/is-drag-node-data-object.test.ts new file mode 100644 index 0000000000..92867843a2 --- /dev/null +++ b/packages/utils/test/src/check-types/is-drag-node-data-object.test.ts @@ -0,0 +1,29 @@ +import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types'; +import { isDragNodeDataObject } from '../../../src/check-types/is-drag-node-data-object'; + +describe('isDragNodeDataObject', () => { + test('should return true for valid IPublicTypeDragNodeDataObject', () => { + const obj: IPublicTypeDragNodeDataObject = { + type: IPublicEnumDragObjectType.NodeData, + // 其他属性... + }; + + expect(isDragNodeDataObject(obj)).toBe(true); + }); + + test('should return false for invalid IPublicTypeDragNodeDataObject', () => { + const obj: any = { + type: 'InvalidType', + // 其他属性... + }; + + expect(isDragNodeDataObject(obj)).toBe(false); + }); + + test('should return false for null or undefined', () => { + expect(isDragNodeDataObject(null)).toBe(false); + expect(isDragNodeDataObject(undefined)).toBe(false); + }); + + // 可以添加更多测试用例... +}); diff --git a/packages/utils/test/src/check-types/is-drag-node-object.test.ts b/packages/utils/test/src/check-types/is-drag-node-object.test.ts new file mode 100644 index 0000000000..3561c87885 --- /dev/null +++ b/packages/utils/test/src/check-types/is-drag-node-object.test.ts @@ -0,0 +1,36 @@ +import { IPublicEnumDragObjectType } from '@alilc/lowcode-types'; +import { isDragNodeObject } from '../../../src/check-types/is-drag-node-object'; + +describe('isDragNodeObject', () => { + it('should return true if the object is of IPublicTypeDragNodeObject type and has type IPublicEnumDragObjectType.Node', () => { + const obj = { + type: IPublicEnumDragObjectType.Node, + //... other properties + }; + + expect(isDragNodeObject(obj)).toBe(true); + }); + + it('should return false if the object is not of IPublicTypeDragNodeObject type', () => { + const obj = { + type: IPublicEnumDragObjectType.OtherType, + //... other properties + }; + + expect(isDragNodeObject(obj)).toBe(false); + }); + + it('should return false if the object is of IPublicTypeDragNodeObject type but type is not IPublicEnumDragObjectType.Node', () => { + const obj = { + type: IPublicEnumDragObjectType.OtherType, + //... other properties + }; + + expect(isDragNodeObject(obj)).toBe(false); + }); + + it('should return false if the object is null or undefined', () => { + expect(isDragNodeObject(null)).toBe(false); + expect(isDragNodeObject(undefined)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-dynamic-setter.test.ts b/packages/utils/test/src/check-types/is-dynamic-setter.test.ts new file mode 100644 index 0000000000..72f55367d0 --- /dev/null +++ b/packages/utils/test/src/check-types/is-dynamic-setter.test.ts @@ -0,0 +1,28 @@ +import { Component } from 'react'; +import { isDynamicSetter } from '../../../src/check-types/is-dynamic-setter'; + +describe('isDynamicSetter', () => { + it('returns true if input is a dynamic setter function', () => { + const dynamicSetter = (value: any) => { + // some implementation + }; + + expect(isDynamicSetter(dynamicSetter)).toBeTruthy(); + }); + + it('returns false if input is not a dynamic setter function', () => { + expect(isDynamicSetter('not a function')).toBeFalsy(); + expect(isDynamicSetter(null)).toBeFalsy(); + expect(isDynamicSetter(undefined)).toBeFalsy(); + expect(isDynamicSetter(2)).toBeFalsy(); + expect(isDynamicSetter(0)).toBeFalsy(); + }); + + it('returns false if input is a React class', () => { + class ReactClass extends Component { + // some implementation + } + + expect(isDynamicSetter(ReactClass)).toBeFalsy(); + }); +}); diff --git a/packages/utils/test/src/check-types/is-i18n-data.test.ts b/packages/utils/test/src/check-types/is-i18n-data.test.ts new file mode 100644 index 0000000000..2e903a2ed2 --- /dev/null +++ b/packages/utils/test/src/check-types/is-i18n-data.test.ts @@ -0,0 +1,27 @@ +import { isI18nData } from '../../../src/check-types/is-i18n-data'; +import { IPublicTypeI18nData } from "@alilc/lowcode-types"; + +describe('isI18nData', () => { + it('should return true for valid i18n data', () => { + const i18nData: IPublicTypeI18nData = { + type: 'i18n', + // add any other required properties here + }; + + expect(isI18nData(i18nData)).toBe(true); + }); + + it('should return false for invalid i18n data', () => { + const invalidData = { + type: 'some-other-type', + // add any other properties here + }; + + expect(isI18nData(invalidData)).toBe(false); + }); + + it('should return false for undefined or null', () => { + expect(isI18nData(undefined)).toBe(false); + expect(isI18nData(null)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-isfunction.test.ts b/packages/utils/test/src/check-types/is-isfunction.test.ts new file mode 100644 index 0000000000..5154282285 --- /dev/null +++ b/packages/utils/test/src/check-types/is-isfunction.test.ts @@ -0,0 +1,61 @@ +import { isInnerJsFunction, isJSFunction } from '../../../src/check-types/is-isfunction'; + +describe('isInnerJsFunction', () => { + test('should return true for valid input', () => { + const data = { + type: 'JSExpression', + source: '', + value: '', + extType: 'function' + }; + + expect(isInnerJsFunction(data)).toBe(true); + }); + + test('should return false for invalid input', () => { + const data = { + type: 'JSExpression', + source: '', + value: '', + extType: 'object' + }; + + expect(isInnerJsFunction(data)).toBe(false); + expect(isInnerJsFunction(null)).toBe(false); + expect(isInnerJsFunction(undefined)).toBe(false); + expect(isInnerJsFunction(1)).toBe(false); + expect(isInnerJsFunction(0)).toBe(false); + expect(isInnerJsFunction('string')).toBe(false); + expect(isInnerJsFunction('')).toBe(false); + }); +}); + +describe('isJSFunction', () => { + test('should return true for valid input', () => { + const data = { + type: 'JSFunction', + }; + + expect(isJSFunction(data)).toBe(true); + }); + + test('should return true for inner js function', () => { + const data = { + type: 'JSExpression', + source: '', + value: '', + extType: 'function' + }; + + expect(isJSFunction(data)).toBe(true); + }); + + test('should return false for invalid input', () => { + expect(isJSFunction(null)).toBe(false); + expect(isJSFunction(undefined)).toBe(false); + expect(isJSFunction('string')).toBe(false); + expect(isJSFunction('')).toBe(false); + expect(isJSFunction(0)).toBe(false); + expect(isJSFunction(2)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-jsblock.test.ts b/packages/utils/test/src/check-types/is-jsblock.test.ts new file mode 100644 index 0000000000..e44e9eb705 --- /dev/null +++ b/packages/utils/test/src/check-types/is-jsblock.test.ts @@ -0,0 +1,22 @@ +import { isJSBlock } from '../../../src/check-types/is-jsblock'; + +describe('isJSBlock', () => { + it('should return false if data is null or undefined', () => { + expect(isJSBlock(null)).toBe(false); + expect(isJSBlock(undefined)).toBe(false); + }); + + it('should return false if data is not an object', () => { + expect(isJSBlock('JSBlock')).toBe(false); + expect(isJSBlock(123)).toBe(false); + expect(isJSBlock(true)).toBe(false); + }); + + it('should return false if data.type is not "JSBlock"', () => { + expect(isJSBlock({ type: 'InvalidType' })).toBe(false); + }); + + it('should return true if data is an object and data.type is "JSBlock"', () => { + expect(isJSBlock({ type: 'JSBlock' })).toBe(true); + }); +}); diff --git a/packages/utils/test/src/check-types/is-jsexpression.test.ts b/packages/utils/test/src/check-types/is-jsexpression.test.ts new file mode 100644 index 0000000000..dd8509a3b3 --- /dev/null +++ b/packages/utils/test/src/check-types/is-jsexpression.test.ts @@ -0,0 +1,39 @@ +import { isJSExpression } from '../../../src/check-types/is-jsexpression'; + +describe('isJSExpression', () => { + it('should return true if the input is a valid JSExpression object', () => { + const validJSExpression = { + type: 'JSExpression', + extType: 'variable', + }; + + const result = isJSExpression(validJSExpression); + + expect(result).toBe(true); + }); + + it('should return false if the input is not a valid JSExpression object', () => { + const invalidJSExpression = { + type: 'JSExpression', + extType: 'function', + }; + + const result = isJSExpression(invalidJSExpression); + + expect(result).toBe(false); + }); + + it('should return false if the input is null', () => { + const result = isJSExpression(null); + + expect(result).toBe(false); + }); + + it('should return false if the input is undefined', () => { + const result = isJSExpression(undefined); + + expect(result).toBe(false); + }); + + // 添加其他需要的测试 +}); diff --git a/packages/utils/test/src/check-types/is-jsslot.test.ts b/packages/utils/test/src/check-types/is-jsslot.test.ts new file mode 100644 index 0000000000..5c130cddfd --- /dev/null +++ b/packages/utils/test/src/check-types/is-jsslot.test.ts @@ -0,0 +1,37 @@ +import { isJSSlot } from '../../../src/check-types/is-jsslot'; +import { IPublicTypeJSSlot } from '@alilc/lowcode-types'; + +describe('isJSSlot', () => { + it('should return true when input is of type IPublicTypeJSSlot', () => { + const input: IPublicTypeJSSlot = { + type: 'JSSlot', + // other properties of IPublicTypeJSSlot + }; + + const result = isJSSlot(input); + + expect(result).toBe(true); + }); + + it('should return false when input is not of type IPublicTypeJSSlot', () => { + const input = { + type: 'OtherType', + // other properties + }; + + const result = isJSSlot(input); + + expect(result).toBe(false); + }); + + it('should return false when input is null or undefined', () => { + const input1 = null; + const input2 = undefined; + + const result1 = isJSSlot(input1); + const result2 = isJSSlot(input2); + + expect(result1).toBe(false); + expect(result2).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-location-children-detail.test.ts b/packages/utils/test/src/check-types/is-location-children-detail.test.ts new file mode 100644 index 0000000000..f209e8e63f --- /dev/null +++ b/packages/utils/test/src/check-types/is-location-children-detail.test.ts @@ -0,0 +1,27 @@ +import { isLocationChildrenDetail } from '../../../src/check-types/is-location-children-detail'; +import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types'; + +describe('isLocationChildrenDetail', () => { + it('should return true when obj is IPublicTypeLocationChildrenDetail', () => { + const obj: IPublicTypeLocationChildrenDetail = { + type: IPublicTypeLocationDetailType.Children, + // 添加其他必要的属性 + }; + + expect(isLocationChildrenDetail(obj)).toBe(true); + }); + + it('should return false when obj is not IPublicTypeLocationChildrenDetail', () => { + const obj = { + type: 'other', + // 添加其他必要的属性 + }; + + expect(isLocationChildrenDetail(obj)).toBe(false); + expect(isLocationChildrenDetail(null)).toBe(false); + expect(isLocationChildrenDetail(undefined)).toBe(false); + expect(isLocationChildrenDetail('string')).toBe(false); + expect(isLocationChildrenDetail(0)).toBe(false); + expect(isLocationChildrenDetail(2)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-location-data.test.ts b/packages/utils/test/src/check-types/is-location-data.test.ts new file mode 100644 index 0000000000..ba2e2c8be0 --- /dev/null +++ b/packages/utils/test/src/check-types/is-location-data.test.ts @@ -0,0 +1,44 @@ +import { isLocationData } from '../../../src/check-types/is-location-data'; +import { IPublicTypeLocationData } from '@alilc/lowcode-types'; + +describe('isLocationData', () => { + it('should return true when obj is valid location data', () => { + const obj: IPublicTypeLocationData = { + target: 'some target', + detail: 'some detail', + }; + + const result = isLocationData(obj); + + expect(result).toBe(true); + }); + + it('should return false when obj is missing target or detail', () => { + const obj1 = { + target: 'some target', + // missing detail + }; + + const obj2 = { + // missing target + detail: 'some detail', + }; + + const result1 = isLocationData(obj1); + const result2 = isLocationData(obj2); + + expect(result1).toBe(false); + expect(result2).toBe(false); + }); + + it('should return false when obj is null or undefined', () => { + const obj1 = null; + const obj2 = undefined; + + const result1 = isLocationData(obj1); + const result2 = isLocationData(obj2); + + expect(result1).toBe(false); + expect(result2).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-lowcode-component-type.test.ts b/packages/utils/test/src/check-types/is-lowcode-component-type.test.ts new file mode 100644 index 0000000000..35b76f00b5 --- /dev/null +++ b/packages/utils/test/src/check-types/is-lowcode-component-type.test.ts @@ -0,0 +1,21 @@ +import { isLowCodeComponentType } from '../../../src/check-types/is-lowcode-component-type'; +import { IPublicTypeLowCodeComponent, IPublicTypeProCodeComponent } from '@alilc/lowcode-types'; + +describe('isLowCodeComponentType', () => { + test('should return true for a low code component type', () => { + const desc: IPublicTypeLowCodeComponent = { + // create a valid low code component description + }; + + expect(isLowCodeComponentType(desc)).toBe(true); + }); + + test('should return false for a pro code component type', () => { + const desc: IPublicTypeProCodeComponent = { + // create a valid pro code component description + package: 'pro-code' + }; + + expect(isLowCodeComponentType(desc)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-lowcode-project-schema.test.ts b/packages/utils/test/src/check-types/is-lowcode-project-schema.test.ts new file mode 100644 index 0000000000..bb750ed88b --- /dev/null +++ b/packages/utils/test/src/check-types/is-lowcode-project-schema.test.ts @@ -0,0 +1,42 @@ +import { isLowcodeProjectSchema } from "../../../src/check-types/is-lowcode-project-schema"; + +describe("isLowcodeProjectSchema", () => { + it("should return false when data is null", () => { + const result = isLowcodeProjectSchema(null); + expect(result).toBe(false); + }); + + it("should return false when data is undefined", () => { + const result = isLowcodeProjectSchema(undefined); + expect(result).toBe(false); + }); + + it("should return false when data is not an object", () => { + const result = isLowcodeProjectSchema("not an object"); + expect(result).toBe(false); + }); + + it("should return false when componentsTree is missing", () => { + const data = { someKey: "someValue" }; + const result = isLowcodeProjectSchema(data); + expect(result).toBe(false); + }); + + it("should return false when componentsTree is an empty array", () => { + const data = { componentsTree: [] }; + const result = isLowcodeProjectSchema(data); + expect(result).toBe(false); + }); + + it("should return false when the first element of componentsTree is not a component schema", () => { + const data = { componentsTree: [{}] }; + const result = isLowcodeProjectSchema(data); + expect(result).toBe(false); + }); + + it("should return true when all conditions are met", () => { + const data = { componentsTree: [{ prop: "value", componentName: 'Component' }] }; + const result = isLowcodeProjectSchema(data); + expect(result).toBe(true); + }); +}); diff --git a/packages/utils/test/src/check-types/is-node-schema.test.ts b/packages/utils/test/src/check-types/is-node-schema.test.ts new file mode 100644 index 0000000000..b5a4e39acb --- /dev/null +++ b/packages/utils/test/src/check-types/is-node-schema.test.ts @@ -0,0 +1,43 @@ +import { isNodeSchema } from '../../../src/check-types/is-node-schema'; + +describe('isNodeSchema', () => { + // 测试正常情况 + it('should return true for valid IPublicTypeNodeSchema', () => { + const validData = { + componentName: 'Component', + isNode: false, + }; + expect(isNodeSchema(validData)).toBe(true); + }); + + // 测试 null 或 undefined + it('should return false for null or undefined', () => { + expect(isNodeSchema(null)).toBe(false); + expect(isNodeSchema(undefined)).toBe(false); + }); + + // 测试没有componentName属性的情况 + it('should return false if componentName is missing', () => { + const invalidData = { + isNode: false, + }; + expect(isNodeSchema(invalidData)).toBe(false); + }); + + // 测试isNode为true的情况 + it('should return false if isNode is true', () => { + const invalidData = { + componentName: 'Component', + isNode: true, + }; + expect(isNodeSchema(invalidData)).toBe(false); + }); + + // 测试其他数据类型的情况 + it('should return false for other data types', () => { + expect(isNodeSchema('string')).toBe(false); + expect(isNodeSchema(123)).toBe(false); + expect(isNodeSchema([])).toBe(false); + expect(isNodeSchema({})).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-node.test.ts b/packages/utils/test/src/check-types/is-node.test.ts new file mode 100644 index 0000000000..d6d8dfc03d --- /dev/null +++ b/packages/utils/test/src/check-types/is-node.test.ts @@ -0,0 +1,19 @@ +import { isNode } from '../../../src/check-types/is-node'; + +describe('isNode', () => { + it('should return true for a valid node', () => { + const node = { isNode: true }; + expect(isNode(node)).toBeTruthy(); + }); + + it('should return false for an invalid node', () => { + const node = { isNode: false }; + expect(isNode(node)).toBeFalsy(); + }); + + it('should return false for an undefined node', () => { + expect(isNode(undefined)).toBeFalsy(); + }); + + // Add more test cases if needed +}); diff --git a/packages/utils/test/src/check-types/is-procode-component-type.test.ts b/packages/utils/test/src/check-types/is-procode-component-type.test.ts new file mode 100644 index 0000000000..58f435b98a --- /dev/null +++ b/packages/utils/test/src/check-types/is-procode-component-type.test.ts @@ -0,0 +1,13 @@ +import { isProCodeComponentType } from '../../../src/check-types/is-procode-component-type'; + +describe('isProCodeComponentType', () => { + it('should return true if the given desc object contains "package" property', () => { + const desc = { package: 'packageName' }; + expect(isProCodeComponentType(desc)).toBe(true); + }); + + it('should return false if the given desc object does not contain "package" property', () => { + const desc = { name: 'componentName' }; + expect(isProCodeComponentType(desc)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-project-schema.test.ts b/packages/utils/test/src/check-types/is-project-schema.test.ts new file mode 100644 index 0000000000..0ec3f47408 --- /dev/null +++ b/packages/utils/test/src/check-types/is-project-schema.test.ts @@ -0,0 +1,28 @@ +import { IPublicTypeProjectSchema } from "@alilc/lowcode-types"; +import { isProjectSchema } from "../../../src/check-types/is-project-schema"; + +describe("isProjectSchema", () => { + it("should return true if data has componentsTree property", () => { + const data: IPublicTypeProjectSchema = { + // ... + componentsTree: { + // ... + }, + }; + expect(isProjectSchema(data)).toBe(true); + }); + + it("should return false if data does not have componentsTree property", () => { + const data = { + // ... + }; + expect(isProjectSchema(data)).toBe(false); + }); + + it("should return false if data is null or undefined", () => { + expect(isProjectSchema(null)).toBe(false); + expect(isProjectSchema(undefined)).toBe(false); + }); + + // 更多的测试用例... +}); diff --git a/packages/utils/test/src/check-types/is-setter-config.test.ts b/packages/utils/test/src/check-types/is-setter-config.test.ts new file mode 100644 index 0000000000..eee234658d --- /dev/null +++ b/packages/utils/test/src/check-types/is-setter-config.test.ts @@ -0,0 +1,26 @@ +import { isSetterConfig } from '../../../src/check-types/is-setter-config'; + +describe('isSetterConfig', () => { + test('should return true for valid setter config', () => { + const config = { + componentName: 'MyComponent', + // Add other required properties here + }; + + expect(isSetterConfig(config)).toBe(true); + }); + + test('should return false for invalid setter config', () => { + const config = { + // Missing componentName property + }; + + expect(isSetterConfig(config)).toBe(false); + expect(isSetterConfig(null)).toBe(false); + expect(isSetterConfig(undefined)).toBe(false); + expect(isSetterConfig(0)).toBe(false); + expect(isSetterConfig(2)).toBe(false); + }); + + // Add more test cases for different scenarios you want to cover +}); diff --git a/packages/utils/test/src/check-types/is-setting-field.test.ts b/packages/utils/test/src/check-types/is-setting-field.test.ts new file mode 100644 index 0000000000..5f9bbd6239 --- /dev/null +++ b/packages/utils/test/src/check-types/is-setting-field.test.ts @@ -0,0 +1,18 @@ +import { isSettingField } from "../../../src/check-types/is-setting-field"; + +describe("isSettingField", () => { + it("should return true for an object that has isSettingField property", () => { + const obj = { isSettingField: true }; + expect(isSettingField(obj)).toBe(true); + }); + + it("should return false for an object that does not have isSettingField property", () => { + const obj = { foo: "bar" }; + expect(isSettingField(obj)).toBe(false); + }); + + it("should return false for a falsy value", () => { + const obj = null; + expect(isSettingField(obj)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/check-types/is-title-config.test.ts b/packages/utils/test/src/check-types/is-title-config.test.ts new file mode 100644 index 0000000000..4aa6d219cb --- /dev/null +++ b/packages/utils/test/src/check-types/is-title-config.test.ts @@ -0,0 +1,18 @@ +import { isTitleConfig } from '../../../src/check-types/is-title-config'; + +describe('isTitleConfig', () => { + it('should return true for valid config object', () => { + const config = { title: 'My Title' }; + expect(isTitleConfig(config)).toBe(true); + }); + + it('should return false for invalid config object', () => { + const config = { title: 'My Title', type: 'i18n' , i18nData: {} }; + expect(isTitleConfig(config)).toBe(false); + }); + + it('should return false for non-object input', () => { + const config = 'invalid'; + expect(isTitleConfig(config)).toBe(false); + }); +}); diff --git a/packages/utils/test/src/clone-deep.test.ts b/packages/utils/test/src/clone-deep.test.ts new file mode 100644 index 0000000000..58fabc6f68 --- /dev/null +++ b/packages/utils/test/src/clone-deep.test.ts @@ -0,0 +1,30 @@ +import { cloneDeep } from '../../src/clone-deep'; + +describe('cloneDeep', () => { + it('should clone null', () => { + const src = null; + expect(cloneDeep(src)).toBeNull(); + }); + + it('should clone undefined', () => { + const src = undefined; + expect(cloneDeep(src)).toBeUndefined(); + }); + + it('should clone an array', () => { + const src = [1, 2, 3, 4]; + expect(cloneDeep(src)).toEqual(src); + }); + + it('should clone an object', () => { + const src = { name: 'John', age: 25 }; + expect(cloneDeep(src)).toEqual(src); + }); + + it('should deep clone nested objects', () => { + const src = { person: { name: 'John', age: 25 } }; + const cloned = cloneDeep(src); + expect(cloned).toEqual(src); + expect(cloned.person).not.toBe(src.person); + }); +}); \ No newline at end of file diff --git a/packages/utils/test/src/clone-enumerable-property.test.ts b/packages/utils/test/src/clone-enumerable-property.test.ts new file mode 100644 index 0000000000..2eff09e44c --- /dev/null +++ b/packages/utils/test/src/clone-enumerable-property.test.ts @@ -0,0 +1,30 @@ +import { cloneEnumerableProperty } from '../../src/clone-enumerable-property'; + +describe('cloneEnumerableProperty', () => { + test('should clone enumerable properties from origin to target', () => { + // Arrange + const target = {}; + const origin = { prop1: 1, prop2: 'hello', prop3: true }; + + // Act + const result = cloneEnumerableProperty(target, origin); + + // Assert + expect(result).toBe(target); + expect(result).toEqual(origin); + }); + + test('should exclude properties specified in excludePropertyNames', () => { + // Arrange + const target = {}; + const origin = { prop1: 1, prop2: 'hello', prop3: true }; + const excludePropertyNames = ['prop2']; + + // Act + const result = cloneEnumerableProperty(target, origin, excludePropertyNames); + + // Assert + expect(result).toBe(target); + expect(result).toEqual({ prop1: 1, prop3: true }); + }); +}); \ No newline at end of file diff --git a/packages/utils/test/src/create-content.test.tsx b/packages/utils/test/src/create-content.test.tsx new file mode 100644 index 0000000000..c41fb0f0da --- /dev/null +++ b/packages/utils/test/src/create-content.test.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { createContent } from '../../src/create-content'; + +const MyComponent = () => { + return <div>MyComponent</div> +} +describe('createContent', () => { + test('should return the same content if it is a valid React element', () => { + const content = <div>Hello</div>; + const result = createContent(content); + + expect(result).toEqual(content); + }); + + test('should clone the element with props if props are provided', () => { + const content = <div></div>; + const props = { className: 'my-class' }; + const result = createContent(content, props); + + expect(result.props).toEqual(props); + }); + + test('should create an element with props if the content is a React component', () => { + const content = MyComponent; + const props = { className: 'my-class' }; + const result = createContent(content, props); + + expect(result.type).toEqual(content); + expect(result.props).toEqual(props); + }); + + test('should return the content if it is not a React element or a React component', () => { + const content = 'Hello'; + const result = createContent(content); + + expect(result).toEqual(content); + }); +}); diff --git a/packages/utils/test/src/create-defer.test.ts b/packages/utils/test/src/create-defer.test.ts new file mode 100644 index 0000000000..c6ab9207a9 --- /dev/null +++ b/packages/utils/test/src/create-defer.test.ts @@ -0,0 +1,16 @@ +import { createDefer } from '../../src/create-defer'; + +describe('createDefer', () => { + it('should resolve with given value', async () => { + const defer = createDefer<number>(); + defer.resolve(42); + const result = await defer.promise(); + expect(result).toBe(42); + }); + + it('should reject with given reason', async () => { + const defer = createDefer<number>(); + defer.reject('error'); + await expect(defer.promise()).rejects.toEqual('error'); + }); +}); diff --git a/packages/utils/test/src/is-object.test.ts b/packages/utils/test/src/is-object.test.ts new file mode 100644 index 0000000000..7ae984b8f8 --- /dev/null +++ b/packages/utils/test/src/is-object.test.ts @@ -0,0 +1,45 @@ +import { isObject, isI18NObject } from '../../src/is-object'; + +describe('isObject', () => { + it('should return true for an object', () => { + const obj = { key: 'value' }; + const result = isObject(obj); + expect(result).toBe(true); + }); + + it('should return false for null', () => { + const result = isObject(null); + expect(result).toBe(false); + }); + + it('should return false for a non-object value', () => { + const value = 42; // Not an object + const result = isObject(value); + expect(result).toBe(false); + }); +}); + +describe('isI18NObject', () => { + it('should return true for an I18N object', () => { + const i18nObject = { type: 'i18n', data: 'some data' }; + const result = isI18NObject(i18nObject); + expect(result).toBe(true); + }); + + it('should return false for a non-I18N object', () => { + const nonI18nObject = { type: 'other', data: 'some data' }; + const result = isI18NObject(nonI18nObject); + expect(result).toBe(false); + }); + + it('should return false for null', () => { + const result = isI18NObject(null); + expect(result).toBe(false); + }); + + it('should return false for a non-object value', () => { + const value = 42; // Not an object + const result = isI18NObject(value); + expect(result).toBe(false); + }); +}); diff --git a/packages/utils/test/src/is-react.test.ts b/packages/utils/test/src/is-react.test.ts deleted file mode 100644 index 74c88c9330..0000000000 --- a/packages/utils/test/src/is-react.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import React from "react"; -import { isReactComponent, wrapReactClass } from "../../src/is-react"; - -class reactDemo extends React.Component { - -} - -const reactMemo = React.memo(reactDemo); - -const reactForwardRef = React.forwardRef((props, ref): any => { - return ''; -}); - -describe('is-react-ut', () => { - it('isReactComponent', () => { - expect(isReactComponent(null)).toBeFalsy(); - expect(isReactComponent(() => {})).toBeTruthy(); - expect(isReactComponent({ - $$typeof: Symbol.for('react.memo') - })).toBeTruthy(); - expect(isReactComponent({ - $$typeof: Symbol.for('react.forward_ref') - })).toBeTruthy(); - expect(isReactComponent(reactDemo)).toBeTruthy(); - expect(isReactComponent(reactMemo)).toBeTruthy(); - expect(isReactComponent(reactForwardRef)).toBeTruthy(); - - }); - - it('wrapReactClass', () => { - const wrap = wrapReactClass(() => {}); - expect(isReactComponent(wrap)).toBeTruthy(); - - const fun = () => {}; - fun.displayName = 'mock'; - expect(wrapReactClass(fun).displayName).toBe('mock'); - }) -}) \ No newline at end of file diff --git a/packages/utils/test/src/is-react.test.tsx b/packages/utils/test/src/is-react.test.tsx new file mode 100644 index 0000000000..9ed2bd6c38 --- /dev/null +++ b/packages/utils/test/src/is-react.test.tsx @@ -0,0 +1,316 @@ +import React, { Component, createElement } from "react"; +import { + isReactComponent, + wrapReactClass, + isForwardOrMemoForward, + isMemoType, + isForwardRefType, + acceptsRef, + isReactClass, + REACT_MEMO_TYPE, + REACT_FORWARD_REF_TYPE, + } from "../../src/is-react"; + +class reactDemo extends React.Component { + +} + +const reactMemo = React.memo(reactDemo); + +const reactForwardRef = React.forwardRef((props, ref): any => { + return ''; +}); + +describe('is-react-ut', () => { + it('isReactComponent', () => { + expect(isReactComponent(null)).toBeFalsy(); + expect(isReactComponent(() => {})).toBeTruthy(); + expect(isReactComponent({ + $$typeof: Symbol.for('react.memo') + })).toBeTruthy(); + expect(isReactComponent({ + $$typeof: Symbol.for('react.forward_ref') + })).toBeTruthy(); + expect(isReactComponent(reactDemo)).toBeTruthy(); + expect(isReactComponent(reactMemo)).toBeTruthy(); + expect(isReactComponent(reactForwardRef)).toBeTruthy(); + + }); + + it('wrapReactClass', () => { + const wrap = wrapReactClass(() => {}); + expect(isReactComponent(wrap)).toBeTruthy(); + + const fun = () => {}; + fun.displayName = 'mock'; + expect(wrapReactClass(fun).displayName).toBe('mock'); + }) +}) + +describe('wrapReactClass', () => { + it('should wrap a FunctionComponent', () => { + // Create a mock FunctionComponent + const MockComponent: React.FunctionComponent = (props) => { + return <div>{props.children}</div>; + }; + + // Wrap the FunctionComponent using wrapReactClass + const WrappedComponent = wrapReactClass(MockComponent); + const instance = new WrappedComponent(); + + // Check if the WrappedComponent extends Component + expect(instance instanceof React.Component).toBe(true); + }); + + it('should render the FunctionComponent with props', () => { + // Create a mock FunctionComponent + const MockComponent: React.FunctionComponent = (props) => { + return <div>{props.children}</div>; + }; + + MockComponent.displayName = 'FunctionComponent'; + + // Wrap the FunctionComponent using wrapReactClass + const WrappedComponent = wrapReactClass(MockComponent); + + // Create some test props + const testProps = { prop1: 'value1', prop2: 'value2' }; + + // Render the WrappedComponent with test props + const rendered = createElement(WrappedComponent, testProps, 'Child Text'); + + // Check if the WrappedComponent renders the FunctionComponent with props + expect(rendered).toMatchSnapshot(); + }); +}); + +describe('isReactComponent', () => { + it('should identify a class component as a React component', () => { + class ClassComponent extends React.Component { + render() { + return <div>Class Component</div>; + } + } + + expect(isReactComponent(ClassComponent)).toBe(true); + }); + + it('should identify a functional component as a React component', () => { + const FunctionalComponent = () => { + return <div>Functional Component</div>; + }; + + expect(isReactComponent(FunctionalComponent)).toBe(true); + }); + + it('should identify a forward ref component as a React component', () => { + const ForwardRefComponent = React.forwardRef((props, ref) => { + return <div ref={ref}>Forward Ref Component</div>; + }); + + expect(isReactComponent(ForwardRefComponent)).toBe(true); + }); + + it('should identify a memo component as a React component', () => { + const MemoComponent = React.memo(() => { + return <div>Memo Component</div>; + }); + + expect(isReactComponent(MemoComponent)).toBe(true); + }); + + it('should return false for non-React components', () => { + const plainObject = { prop: 'value' }; + const notAComponent = 'Not a component'; + + expect(isReactComponent(plainObject)).toBe(false); + expect(isReactComponent(notAComponent)).toBe(false); + }); + + it('should return false for null or undefined', () => { + const nullValue = null; + const undefinedValue = undefined; + + expect(isReactComponent(nullValue)).toBe(false); + expect(isReactComponent(undefinedValue)).toBe(false); + }); +}); + +describe('isForwardOrMemoForward', () => { + it('should return true for a forwardRef component', () => { + const forwardRefComponent = React.forwardRef(() => { + return <div>ForwardRef Component</div>; + }); + + expect(isForwardOrMemoForward(forwardRefComponent)).toBe(true); + }); + + it('should return true for a memoized forwardRef component', () => { + const forwardRefComponent = React.forwardRef(() => { + return <div>ForwardRef Component</div>; + }); + + const memoizedComponent = React.memo(forwardRefComponent); + + expect(isForwardOrMemoForward(memoizedComponent)).toBe(true); + }); + + it('should return false for a memoized component that is not a forwardRef', () => { + const memoizedComponent = React.memo(() => { + return <div>Memoized Component</div>; + }); + + expect(isForwardOrMemoForward(memoizedComponent)).toBe(false); + }); + + it('should return false for a plain object', () => { + const plainObject = { prop: 'value' }; + + expect(isForwardOrMemoForward(plainObject)).toBe(false); + }); + + it('should return false for null or undefined', () => { + const nullValue = null; + const undefinedValue = undefined; + + expect(isForwardOrMemoForward(nullValue)).toBe(false); + expect(isForwardOrMemoForward(undefinedValue)).toBe(false); + }); +}); + +describe('isMemoType', () => { + it('should return true for an object with $$typeof matching REACT_MEMO_TYPE', () => { + const memoTypeObject = { $$typeof: REACT_MEMO_TYPE }; + + expect(isMemoType(memoTypeObject)).toBe(true); + }); + + it('should return false for an object with $$typeof not matching REACT_MEMO_TYPE', () => { + const otherTypeObject = { $$typeof: Symbol.for('other.type') }; + + expect(isMemoType(otherTypeObject)).toBe(false); + }); + + it('should return false for an object with no $$typeof property', () => { + const noTypeObject = { key: 'value' }; + + expect(isMemoType(noTypeObject)).toBe(false); + }); + + it('should return false for null or undefined', () => { + const nullValue = null; + const undefinedValue = undefined; + + expect(isMemoType(nullValue)).toBe(false); + expect(isMemoType(undefinedValue)).toBe(false); + }); +}); + +describe('isForwardRefType', () => { + it('should return true for an object with $$typeof matching REACT_FORWARD_REF_TYPE', () => { + const forwardRefTypeObject = { $$typeof: REACT_FORWARD_REF_TYPE }; + + expect(isForwardRefType(forwardRefTypeObject)).toBe(true); + }); + + it('should return false for an object with $$typeof not matching REACT_FORWARD_REF_TYPE', () => { + const otherTypeObject = { $$typeof: Symbol.for('other.type') }; + + expect(isForwardRefType(otherTypeObject)).toBe(false); + }); + + it('should return false for an object with no $$typeof property', () => { + const noTypeObject = { key: 'value' }; + + expect(isForwardRefType(noTypeObject)).toBe(false); + }); + + it('should return false for null or undefined', () => { + const nullValue = null; + const undefinedValue = undefined; + + expect(isForwardRefType(nullValue)).toBe(false); + expect(isForwardRefType(undefinedValue)).toBe(false); + }); +}); + +describe('acceptsRef', () => { + it('should return true for an object with isReactComponent in its prototype', () => { + const objWithIsReactComponent = { + prototype: { + isReactComponent: true, + }, + }; + + expect(acceptsRef(objWithIsReactComponent)).toBe(true); + }); + + it('should return true for an object that is forwardRef or memoized forwardRef', () => { + const forwardRefObject = React.forwardRef(() => { + return null; + }); + + const memoizedForwardRefObject = React.memo(forwardRefObject); + + expect(acceptsRef(forwardRefObject)).toBe(true); + expect(acceptsRef(memoizedForwardRefObject)).toBe(true); + }); + + it('should return false for an object without isReactComponent in its prototype', () => { + const objWithoutIsReactComponent = { + prototype: { + someOtherProperty: true, + }, + }; + + expect(acceptsRef(objWithoutIsReactComponent)).toBe(false); + }); + + it('should return false for null or undefined', () => { + const nullValue = null; + const undefinedValue = undefined; + + expect(acceptsRef(nullValue)).toBe(false); + expect(acceptsRef(undefinedValue)).toBe(false); + }); +}); + +describe('isReactClass', () => { + it('should return true for an object with isReactComponent in its prototype', () => { + class ReactClassComponent extends Component { + render() { + return null; + } + } + + expect(isReactClass(ReactClassComponent)).toBe(true); + }); + + it('should return true for an object with Component in its prototype chain', () => { + class CustomComponent extends Component { + render() { + return null; + } + } + + expect(isReactClass(CustomComponent)).toBe(true); + }); + + it('should return false for an object without isReactComponent in its prototype', () => { + class NonReactComponent { + render() { + return null; + } + } + + expect(isReactClass(NonReactComponent)).toBe(false); + }); + + it('should return false for null or undefined', () => { + const nullValue = null; + const undefinedValue = undefined; + + expect(isReactClass(nullValue)).toBe(false); + expect(isReactClass(undefinedValue)).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/utils/test/src/is-shaken.test.ts b/packages/utils/test/src/is-shaken.test.ts new file mode 100644 index 0000000000..35a27af5f6 --- /dev/null +++ b/packages/utils/test/src/is-shaken.test.ts @@ -0,0 +1,45 @@ +import { isShaken } from '../../src/is-shaken'; + +describe('isShaken', () => { + it('should return true if e1 has shaken property', () => { + const e1: any = { shaken: true }; + const e2: MouseEvent | DragEvent = { target: null } as MouseEvent | DragEvent; + + expect(isShaken(e1, e2)).toBe(true); + }); + + it('should return true if e1.target and e2.target are different', () => { + const e1: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent; + const e2: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent; + + expect(isShaken(e1, e2)).toBe(true); + }); + + it('should return false if e1 and e2 targets are the same and distance is less than SHAKE_DISTANCE', () => { + const target = {}; + const e1: MouseEvent | DragEvent = { target: target } as MouseEvent | DragEvent; + const e2: MouseEvent | DragEvent = { target: target } as MouseEvent | DragEvent; + + // Assuming SHAKE_DISTANCE is 100 + e1.clientY = 50; + e2.clientY = 50; + + e1.clientX = 60; + e2.clientX = 60; + + expect(isShaken(e1, e2)).toBe(false); + }); + + it('should return true if e1 and e2 targets are the same and distance is greater than SHAKE_DISTANCE', () => { + const e1: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent; + const e2: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent; + + // Assuming SHAKE_DISTANCE is 100 + e1.clientY = 50; + e1.clientX = 50; + e2.clientY = 200; + e2.clientX = 200; + + expect(isShaken(e1, e2)).toBe(true); + }); +}); diff --git a/packages/utils/test/src/misc.test.ts b/packages/utils/test/src/misc.test.ts index 8873dc4c80..2514661508 100644 --- a/packages/utils/test/src/misc.test.ts +++ b/packages/utils/test/src/misc.test.ts @@ -1,4 +1,321 @@ -import { shouldUseVariableSetter } from '../../src/misc'; +import { + isVariable, + isUseI18NSetter, + convertToI18NObject, + isString, + waitForThing, + arrShallowEquals, + isFromVC, + executePendingFn, + compatStage, + invariant, + isRegExp, + shouldUseVariableSetter, +} from '../../src/misc'; +import { IPublicModelComponentMeta } from '@alilc/lowcode-types'; + +describe('isVariable', () => { + it('should return true for a variable object', () => { + const variable = { type: 'variable', variable: 'foo', value: 'bar' }; + const result = isVariable(variable); + expect(result).toBe(true); + }); + + it('should return false for non-variable objects', () => { + const obj = { type: 'object' }; + const result = isVariable(obj); + expect(result).toBe(false); + }); +}); + +describe('isUseI18NSetter', () => { + it('should return true for a property with I18nSetter', () => { + const prototype = { options: { configure: [{ name: 'propName', setter: { type: { displayName: 'I18nSetter' } } }] } }; + const propName = 'propName'; + const result = isUseI18NSetter(prototype, propName); + expect(result).toBe(true); + }); + + it('should return false for a property without I18nSetter', () => { + const prototype = { options: { configure: [{ name: 'propName', setter: { type: { displayName: 'OtherSetter' } } }] } }; + const propName = 'propName'; + const result = isUseI18NSetter(prototype, propName); + expect(result).toBe(false); + }); +}); + +describe('convertToI18NObject', () => { + it('should return the input if it is already an I18N object', () => { + const i18nObject = { type: 'i18n', use: 'en', en: 'Hello' }; + const result = convertToI18NObject(i18nObject); + expect(result).toEqual(i18nObject); + }); + + it('should convert a string to an I18N object', () => { + const inputString = 'Hello'; + const result = convertToI18NObject(inputString); + const expectedOutput = { type: 'i18n', use: 'zh-CN', 'zh-CN': inputString }; + expect(result).toEqual(expectedOutput); + }); +}); + +describe('isString', () => { + it('should return true for a string', () => { + const stringValue = 'Hello, world!'; + const result = isString(stringValue); + expect(result).toBe(true); + }); + + it('should return true for an empty string', () => { + const emptyString = ''; + const result = isString(emptyString); + expect(result).toBe(true); + }); + + it('should return false for a number', () => { + const numberValue = 42; // Not a string + const result = isString(numberValue); + expect(result).toBe(false); + }); + + it('should return false for an object', () => { + const objectValue = { key: 'value' }; // Not a string + const result = isString(objectValue); + expect(result).toBe(false); + }); + + it('should return false for null', () => { + const result = isString(null); + expect(result).toBe(false); + }); + + it('should return false for undefined', () => { + const undefinedValue = undefined; + const result = isString(undefinedValue); + expect(result).toBe(false); + }); + + it('should return false for a boolean', () => { + const booleanValue = true; // Not a string + const result = isString(booleanValue); + expect(result).toBe(false); + }); +}); + +describe('waitForThing', () => { + it('should resolve immediately if the thing is available', async () => { + const obj = { prop: 'value' }; + const path = 'prop'; + const result = await waitForThing(obj, path); + expect(result).toBe('value'); + }); + + it('should resolve after a delay if the thing becomes available', async () => { + const obj = { prop: undefined }; + const path = 'prop'; + const delay = 100; // Adjust the delay as needed + setTimeout(() => { + obj.prop = 'value'; + }, delay); + + const result = await waitForThing(obj, path); + expect(result).toBe('value'); + }); +}); + +describe('arrShallowEquals', () => { + it('should return true for two empty arrays', () => { + const arr1 = []; + const arr2 = []; + const result = arrShallowEquals(arr1, arr2); + expect(result).toBe(true); + }); + + it('should return true for two arrays with the same elements in the same order', () => { + const arr1 = [1, 2, 3]; + const arr2 = [1, 2, 3]; + const result = arrShallowEquals(arr1, arr2); + expect(result).toBe(true); + }); + + it('should return true for two arrays with the same elements in a different order', () => { + const arr1 = [1, 2, 3]; + const arr2 = [3, 2, 1]; + const result = arrShallowEquals(arr1, arr2); + expect(result).toBe(true); + }); + + it('should return false for two arrays with different lengths', () => { + const arr1 = [1, 2, 3]; + const arr2 = [1, 2]; + const result = arrShallowEquals(arr1, arr2); + expect(result).toBe(false); + }); + + it('should return false for one array and a non-array', () => { + const arr1 = [1, 2, 3]; + const nonArray = 'not an array'; + const result = arrShallowEquals(arr1, nonArray); + expect(result).toBe(false); + }); + + it('should return false for two arrays with different elements', () => { + const arr1 = [1, 2, 3]; + const arr2 = [3, 4, 5]; + const result = arrShallowEquals(arr1, arr2); + expect(result).toBe(false); + }); + + it('should return true for arrays with duplicate elements', () => { + const arr1 = [1, 2, 2, 3]; + const arr2 = [2, 3, 3, 1]; + const result = arrShallowEquals(arr1, arr2); + expect(result).toBe(true); + }); +}); + +describe('isFromVC', () => { + it('should return true when advanced configuration is present', () => { + // Create a mock meta object with advanced configuration + const meta: IPublicModelComponentMeta = { + getMetadata: () => ({ configure: { advanced: true } }), + }; + + const result = isFromVC(meta); + + expect(result).toBe(true); + }); + + it('should return false when advanced configuration is not present', () => { + // Create a mock meta object without advanced configuration + const meta: IPublicModelComponentMeta = { + getMetadata: () => ({ configure: { advanced: false } }), + }; + + const result = isFromVC(meta); + + expect(result).toBe(false); + }); + + it('should return false when meta is undefined', () => { + const meta: IPublicModelComponentMeta | undefined = undefined; + + const result = isFromVC(meta); + + expect(result).toBe(false); + }); + + it('should return false when meta does not have configure information', () => { + // Create a mock meta object without configure information + const meta: IPublicModelComponentMeta = { + getMetadata: () => ({}), + }; + + const result = isFromVC(meta); + + expect(result).toBe(false); + }); + + it('should return false when configure.advanced is not present', () => { + // Create a mock meta object with incomplete configure information + const meta: IPublicModelComponentMeta = { + getMetadata: () => ({ configure: {} }), + }; + + const result = isFromVC(meta); + + expect(result).toBe(false); + }); +}); + +describe('executePendingFn', () => { + it('should execute the provided function after the specified timeout', async () => { + // Mock the function to execute + const fn = jest.fn(); + + // Call executePendingFn with the mocked function and a short timeout + executePendingFn(fn, 100); + + // Ensure the function has not been called immediately + expect(fn).not.toHaveBeenCalled(); + + // Wait for the specified timeout + await new Promise(resolve => setTimeout(resolve, 100)); + + // Ensure the function has been called after the timeout + expect(fn).toHaveBeenCalled(); + }); + + it('should execute the provided function with a default timeout if not specified', async () => { + // Mock the function to execute + const fn = jest.fn(); + + // Call executePendingFn with the mocked function without specifying a timeout + executePendingFn(fn); + + // Ensure the function has not been called immediately + expect(fn).not.toHaveBeenCalled(); + + // Wait for the default timeout (2000 milliseconds) + await new Promise(resolve => setTimeout(resolve, 2000)); + + // Ensure the function has been called after the default timeout + expect(fn).toHaveBeenCalled(); + }); +}); + +describe('compatStage', () => { + it('should convert a number to an enum stage', () => { + const result = compatStage(3); + expect(result).toBe('save'); + }); + + it('should warn about the deprecated usage', () => { + const warnSpy = jest.spyOn(console, 'warn'); + const result = compatStage(2); + expect(result).toBe('serilize'); + expect(warnSpy).toHaveBeenCalledWith( + 'stage 直接指定为数字的使用方式已经过时,将在下一版本移除,请直接使用 IPublicEnumTransformStage.Render|Serilize|Save|Clone|Init|Upgrade' + ); + warnSpy.mockRestore(); + }); + + it('should return the enum stage if it is already an enum', () => { + const result = compatStage('render'); + expect(result).toBe('render'); + }); +}); + +describe('invariant', () => { + it('should not throw an error if the check is true', () => { + expect(() => invariant(true, 'Test invariant', 'thing')).not.toThrow(); + }); + + it('should throw an error if the check is false', () => { + expect(() => invariant(false, 'Test invariant', 'thing')).toThrowError( + "Invariant failed: Test invariant in 'thing'" + ); + }); +}); + +describe('isRegExp', () => { + it('should return true for a valid RegExp', () => { + const regex = /test/; + const result = isRegExp(regex); + expect(result).toBe(true); + }); + + it('should return false for a non-RegExp object', () => { + const nonRegExp = { test: /test/ }; + const result = isRegExp(nonRegExp); + expect(result).toBe(false); + }); + + it('should return false for null', () => { + const result = isRegExp(null); + expect(result).toBe(false); + }); +}); it('shouldUseVariableSetter', () => { expect(shouldUseVariableSetter(false, true)).toBeFalsy(); diff --git a/packages/utils/test/src/navtive-selection.test.ts b/packages/utils/test/src/navtive-selection.test.ts new file mode 100644 index 0000000000..f45d0e1b2a --- /dev/null +++ b/packages/utils/test/src/navtive-selection.test.ts @@ -0,0 +1,18 @@ +import { setNativeSelection, nativeSelectionEnabled } from '../../src/navtive-selection'; + +describe('setNativeSelection', () => { + beforeEach(() => { + // 在每个测试运行之前重置nativeSelectionEnabled的值 + setNativeSelection(true); + }); + + test('should enable native selection', () => { + setNativeSelection(true); + expect(nativeSelectionEnabled).toBe(true); + }); + + test('should disable native selection', () => { + setNativeSelection(false); + expect(nativeSelectionEnabled).toBe(false); + }); +}); diff --git a/packages/utils/test/src/schema.test.ts b/packages/utils/test/src/schema.test.ts index 138dd7a82e..8d03f58118 100644 --- a/packages/utils/test/src/schema.test.ts +++ b/packages/utils/test/src/schema.test.ts @@ -1,4 +1,132 @@ -import { compatibleLegaoSchema } from '../../src/schema'; +import { + compatibleLegaoSchema, + getNodeSchemaById, + applyActivities, +} from '../../src/schema'; +import { ActivityType } from '@alilc/lowcode-types'; + +describe('compatibleLegaoSchema', () => { + it('should handle null input', () => { + const result = compatibleLegaoSchema(null); + expect(result).toBeNull(); + }); + + it('should convert Legao schema to JSExpression', () => { + // Create your test input + const legaoSchema = { + type: 'LegaoType', + source: 'LegaoSource', + compiled: 'LegaoCompiled', + }; + const result = compatibleLegaoSchema(legaoSchema); + + // Define the expected output + const expectedOutput = { + type: 'JSExpression', + value: 'LegaoCompiled', + extType: 'function', + }; + + // Assert that the result matches the expected output + expect(result).toEqual(expectedOutput); + }); + + // Add more test cases for other scenarios +}); + +describe('getNodeSchemaById', () => { + it('should find a node in the schema', () => { + // Create your test schema and node ID + const testSchema = { + id: 'root', + children: [ + { + id: 'child1', + children: [ + { + id: 'child1.1', + }, + ], + }, + ], + }; + const nodeId = 'child1.1'; + + const result = getNodeSchemaById(testSchema, nodeId); + + // Define the expected output + const expectedOutput = { + id: 'child1.1', + }; + + // Assert that the result matches the expected output + expect(result).toEqual(expectedOutput); + }); + + // Add more test cases for other scenarios +}); + +describe('applyActivities', () => { + it('should apply ADD activity', () => { + // Create your test schema and activities + const testSchema = { + id: 'root', + children: [ + { + id: 'child1', + children: [ + { + id: 'child1.1', + }, + ], + }, + ], + }; + const activities = [ + { + type: ActivityType.ADDED, + payload: { + location: { + parent: { + nodeId: 'child1', + index: 0, + }, + }, + schema: { + id: 'newChild', + }, + }, + }, + ]; + + const result = applyActivities(testSchema, activities); + + // Define the expected output + const expectedOutput = { + id: 'root', + children: [ + { + id: 'child1', + children: [ + { + id: 'newChild', + }, + { + id: 'child1.1', + }, + ], + }, + ], + }; + + // Assert that the result matches the expected output + expect(result).toEqual(expectedOutput); + }); + + // Add more test cases for other activity types and scenarios +}); + + describe('Schema Ut', () => { it('props', () => { const schema = { diff --git a/packages/utils/test/src/script.test.ts b/packages/utils/test/src/script.test.ts new file mode 100644 index 0000000000..d3d4ffd59a --- /dev/null +++ b/packages/utils/test/src/script.test.ts @@ -0,0 +1,47 @@ +import { + evaluate, + evaluateExpression, + newFunction, +} from '../../src/script'; + +describe('evaluate', () => { + test('should evaluate the given script', () => { + const script = 'console.log("Hello, world!");'; + global.console = { log: jest.fn() }; + + evaluate(script); + + expect(global.console.log).toHaveBeenCalledWith('Hello, world!'); + }); +}); + +describe('evaluateExpression', () => { + test('should evaluate the given expression', () => { + const expr = 'return 1 + 2'; + + const result = evaluateExpression(expr); + + expect(result).toBe(3); + }); +}); + +describe('newFunction', () => { + test('should create a new function with the given arguments and code', () => { + const args = 'a, b'; + const code = 'return a + b'; + + const result = newFunction(args, code); + + expect(result).toBeInstanceOf(Function); + expect(result(1, 2)).toBe(3); + }); + + test('should return null if an error occurs', () => { + const args = 'a, b'; + const code = 'return a +;'; // Invalid code + + const result = newFunction(args, code); + + expect(result).toBeNull(); + }); +}); diff --git a/packages/utils/test/src/svg-icon.test.tsx b/packages/utils/test/src/svg-icon.test.tsx new file mode 100644 index 0000000000..bbb6e18b7c --- /dev/null +++ b/packages/utils/test/src/svg-icon.test.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { SVGIcon, IconProps } from '../../src/svg-icon'; + +describe('SVGIcon', () => { + it('should render SVG element with correct size', () => { + const iconProps: IconProps = { + size: 'small', + viewBox: '0 0 24 24', + }; + + const { container } = render(<SVGIcon {...iconProps} />); + + const svgElement = container.querySelector('svg'); + + expect(svgElement).toHaveAttribute('width', '12'); + expect(svgElement).toHaveAttribute('height', '12'); + }); + + it('should render SVG element with custom size', () => { + const iconProps: IconProps = { + size: 24, + viewBox: '0 0 24 24', + }; + + const { container } = render(<SVGIcon {...iconProps} />); + + const svgElement = container.querySelector('svg'); + + expect(svgElement).toHaveAttribute('width', '24'); + expect(svgElement).toHaveAttribute('height', '24'); + }); + + // Add more tests for other scenarios if needed +}); diff --git a/packages/utils/test/src/transaction-manager.test.ts b/packages/utils/test/src/transaction-manager.test.ts new file mode 100644 index 0000000000..42c7fa8bf0 --- /dev/null +++ b/packages/utils/test/src/transaction-manager.test.ts @@ -0,0 +1,58 @@ +import { transactionManager } from '../../src/transaction-manager'; +import { IPublicEnumTransitionType } from '@alilc/lowcode-types'; + +const type = IPublicEnumTransitionType.REPAINT; + +describe('TransactionManager', () => { + let fn1: jest.Mock; + let fn2: jest.Mock; + + beforeEach(() => { + fn1 = jest.fn(); + fn2 = jest.fn(); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('executeTransaction should emit startTransaction and endTransaction events', () => { + const startTransactionSpy = jest.spyOn(transactionManager.emitter, 'emit'); + const endTransactionSpy = jest.spyOn(transactionManager.emitter, 'emit'); + + transactionManager.executeTransaction(() => { + // Perform some action within the transaction + }); + + expect(startTransactionSpy).toHaveBeenCalledWith(`[${type}]startTransaction`); + expect(endTransactionSpy).toHaveBeenCalledWith(`[${type}]endTransaction`); + }); + + test('onStartTransaction should register the provided function for startTransaction event', () => { + const offSpy = jest.spyOn(transactionManager.emitter, 'off'); + + const offFunction = transactionManager.onStartTransaction(fn1); + + expect(transactionManager.emitter.listenerCount(`[${type}]startTransaction`)).toBe(1); + expect(offSpy).not.toHaveBeenCalled(); + + offFunction(); + + expect(transactionManager.emitter.listenerCount(`[${type}]startTransaction`)).toBe(0); + expect(offSpy).toHaveBeenCalledWith(`[${type}]startTransaction`, fn1); + }); + + test('onEndTransaction should register the provided function for endTransaction event', () => { + const offSpy = jest.spyOn(transactionManager.emitter, 'off'); + + const offFunction = transactionManager.onEndTransaction(fn2); + + expect(transactionManager.emitter.listenerCount(`[${type}]endTransaction`)).toBe(1); + expect(offSpy).not.toHaveBeenCalled(); + + offFunction(); + + expect(transactionManager.emitter.listenerCount(`[${type}]endTransaction`)).toBe(0); + expect(offSpy).toHaveBeenCalledWith(`[${type}]endTransaction`, fn2); + }); +}); diff --git a/packages/utils/test/src/unique-id.test.ts b/packages/utils/test/src/unique-id.test.ts new file mode 100644 index 0000000000..2b4b6e9e04 --- /dev/null +++ b/packages/utils/test/src/unique-id.test.ts @@ -0,0 +1,11 @@ +import { uniqueId } from '../../src/unique-id'; + +test('uniqueId should return a unique id with prefix', () => { + const id = uniqueId('test'); + expect(id.startsWith('test')).toBeTruthy(); +}); + +test('uniqueId should return a unique id without prefix', () => { + const id = uniqueId(); + expect(id).not.toBeFalsy(); +}); From 151748dbab0989555c1161721044ad4a2d29a2ff Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 13 Nov 2023 13:36:07 +0800 Subject: [PATCH 172/361] docs: add before start doc --- docs/docs/guide/quickStart/demo.md | 2 +- docs/docs/guide/quickStart/intro.md | 17 ++++++++++++++++- docs/docs/guide/quickStart/start.md | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/docs/guide/quickStart/demo.md b/docs/docs/guide/quickStart/demo.md index a05a42486d..ee76d5aa1b 100644 --- a/docs/docs/guide/quickStart/demo.md +++ b/docs/docs/guide/quickStart/demo.md @@ -1,6 +1,6 @@ --- title: 试用低代码引擎 Demo -sidebar_position: 1 +sidebar_position: 2 --- ## 访问地址 diff --git a/docs/docs/guide/quickStart/intro.md b/docs/docs/guide/quickStart/intro.md index 661f5912f7..b65baac269 100644 --- a/docs/docs/guide/quickStart/intro.md +++ b/docs/docs/guide/quickStart/intro.md @@ -1,6 +1,6 @@ --- title: 简介 -sidebar_position: 0 +sidebar_position: 1 --- # 阿里低代码引擎简介 @@ -46,3 +46,18 @@ sidebar_position: 0 **低代码设计器研发框架** 低代码引擎的核心是设计器,通过扩展、周边生态等可以产出各式各样的设计器。它不是一套可以适合所有人的低代码平台,而是帮助低代码平台的开发者,快速生产低代码平台的工具。 + +## 寻找适合您的低代码解决方案 + +帮助用户根据个人或企业需求选择合适的低代码产品。 + +| 特性/产品 | 低代码引擎 | Lab平台 | UIPaaS | +|-----------------|-----------------------------------------|-----------------------------------------|--------------------------------------------| +| **适用用户** | 前端开发者 | 需要快速搭建应用/页面的用户 | 企业用户,需要大规模部署低代码解决方案的组织 | +| **产品特点** | 设计器研发框架,适合定制开发 | 低代码平台, 可视化操作界面,易于上手 | 低代码平台孵化器,企业级功能 | +| **使用场景** | 定制和开发低代码平台的设计器部分 | 通过可视化, 快速开发应用或页面 | 帮助具有一定规模软件研发团队的的企业低成本定制低代码平台 | +| **产品关系** | 开源产品 | 基于UIPaaS技术实现, 展示了UIPaaS的部分能力 | 提供完整的低代码平台解决方案,商业产品 | +| **收费情况** | 免费 | 可免费使用(有额度限制),不提供私有化部署售卖 | 仅提供私有化部署售卖 | +| **官方网站** | [低代码引擎官网](https://lowcode-engine.cn/) | [Lab平台官网](https://lab.lowcode-engine.cn/) | [UIPaaS官网](https://uipaas.net/) | + +*注:请根据您的具体需求和条件选择合适的产品。如需更详细的信息,请访问各产品的官方网站。* diff --git a/docs/docs/guide/quickStart/start.md b/docs/docs/guide/quickStart/start.md index b2b728b9fe..356f501769 100644 --- a/docs/docs/guide/quickStart/start.md +++ b/docs/docs/guide/quickStart/start.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 title: 快速开始 --- From ef6a203a45ae7d8d0d4708bac28d36d10d7d4b07 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 13 Nov 2023 14:09:58 +0800 Subject: [PATCH 173/361] chore(docs): publish docs 1.1.16 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 27d1a17d04..c206cdf16a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.15", + "version": "1.1.16", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 9108e8cfabdb442064f43be0533538ebbaff7f4a Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 13 Nov 2023 18:46:17 +0800 Subject: [PATCH 174/361] feat(types): add IPublicTypeInstanceOf to prop-types --- packages/types/src/shell/type/prop-types.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/types/src/shell/type/prop-types.ts b/packages/types/src/shell/type/prop-types.ts index a3344b0591..22d84c86fc 100644 --- a/packages/types/src/shell/type/prop-types.ts +++ b/packages/types/src/shell/type/prop-types.ts @@ -3,7 +3,7 @@ import { IPublicTypePropConfig } from './'; export type IPublicTypePropType = IPublicTypeBasicType | IPublicTypeRequiredType | IPublicTypeComplexType; export type IPublicTypeBasicType = 'array' | 'bool' | 'func' | 'number' | 'object' | 'string' | 'node' | 'element' | 'any'; -export type IPublicTypeComplexType = IPublicTypeOneOf | IPublicTypeOneOfType | IPublicTypeArrayOf | IPublicTypeObjectOf | IPublicTypeShape | IPublicTypeExact; +export type IPublicTypeComplexType = IPublicTypeOneOf | IPublicTypeOneOfType | IPublicTypeArrayOf | IPublicTypeObjectOf | IPublicTypeShape | IPublicTypeExact | IPublicTypeInstanceOf; export interface IPublicTypeRequiredType { type: IPublicTypeBasicType; @@ -40,3 +40,9 @@ export interface IPublicTypeExact { value: IPublicTypePropConfig[]; isRequired?: boolean; } + +export interface IPublicTypeInstanceOf { + type: 'instanceOf'; + value: IPublicTypePropConfig; + isRequired?: boolean; +} From 1020f98756c6a4886f8dd755c5fca3ff6f374876 Mon Sep 17 00:00:00 2001 From: beautiful-boyyy <66351806+beautiful-boyyy@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:48:36 +0800 Subject: [PATCH 175/361] chore: remove useless code (#2643) --- .../editor-skeleton/src/components/widget-views/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/editor-skeleton/src/components/widget-views/index.tsx b/packages/editor-skeleton/src/components/widget-views/index.tsx index 513fc1bdd6..ba49b3d1ab 100644 --- a/packages/editor-skeleton/src/components/widget-views/index.tsx +++ b/packages/editor-skeleton/src/components/widget-views/index.tsx @@ -232,12 +232,8 @@ export class PanelView extends Component<{ this.lastVisible = currentVisible; if (this.lastVisible) { panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel); - // FIXME! remove this line - panel.skeleton.postEvent('leftPanel.show' as any, panel.name, panel); } else { panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel); - // FIXME! remove this line - panel.skeleton.postEvent('leftPanel.hide' as any, panel.name, panel); } } } From b697ea9ad4399a90cf2560b45beb4ae669700fbc Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 14 Nov 2023 09:55:58 +0800 Subject: [PATCH 176/361] feat(render-core): update logger to console --- .../designer/src/builtin-simulator/index.ts | 1 + .../builtin-simulator/utils/parse-metadata.ts | 6 ++- packages/renderer-core/babel.config.js | 1 + packages/renderer-core/src/hoc/leaf.tsx | 3 +- packages/renderer-core/src/renderer/addon.tsx | 3 +- packages/renderer-core/src/renderer/base.tsx | 14 +++---- packages/renderer-core/src/renderer/temp.tsx | 3 +- packages/renderer-core/src/utils/common.ts | 6 +-- .../renderer-core/src/utils/data-helper.ts | 10 ++--- .../renderer-core/tests/utils/common.test.ts | 40 ++++++++++++++++++- .../tests/utils/data-helper.test.ts | 10 ----- 11 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 packages/renderer-core/babel.config.js diff --git a/packages/designer/src/builtin-simulator/index.ts b/packages/designer/src/builtin-simulator/index.ts index 6bcee7eb76..6977fd66c6 100644 --- a/packages/designer/src/builtin-simulator/index.ts +++ b/packages/designer/src/builtin-simulator/index.ts @@ -2,3 +2,4 @@ export * from './host'; export * from './host-view'; export * from './renderer'; export * from './live-editing/live-editing'; +export { LowcodeTypes } from './utils/parse-metadata'; diff --git a/packages/designer/src/builtin-simulator/utils/parse-metadata.ts b/packages/designer/src/builtin-simulator/utils/parse-metadata.ts index b84e4e6985..5c81340a14 100644 --- a/packages/designer/src/builtin-simulator/utils/parse-metadata.ts +++ b/packages/designer/src/builtin-simulator/utils/parse-metadata.ts @@ -46,13 +46,15 @@ function define(propType: any = PropTypes.any, lowcodeType: string | object = {} return lowcodeCheckType; } -const LowcodeTypes: any = { +export const LowcodeTypes: any = { ...PropTypes, define, }; (window as any).PropTypes = LowcodeTypes; -(window as any).React.PropTypes = LowcodeTypes; +if ((window as any).React) { + (window as any).React.PropTypes = LowcodeTypes; +} // override primitive type checkers primitiveTypes.forEach((type) => { diff --git a/packages/renderer-core/babel.config.js b/packages/renderer-core/babel.config.js new file mode 100644 index 0000000000..c5986f2bc0 --- /dev/null +++ b/packages/renderer-core/babel.config.js @@ -0,0 +1 @@ +module.exports = require('../../babel.config'); \ No newline at end of file diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index 1ff91cb147..2bb3c0b368 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -4,6 +4,7 @@ import { isReactComponent, cloneEnumerableProperty } from '@alilc/lowcode-utils' import { debounce } from '../utils/common'; import adapter from '../adapter'; import * as types from '../types/index'; +import logger from '../utils/logger'; export interface IComponentHocInfo { schema: any; @@ -183,7 +184,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { } if (!isReactComponent(Comp)) { - console.error(`${schema.componentName} component may be has errors: `, Comp); + logger.error(`${schema.componentName} component may be has errors: `, Comp); } initRerenderEvent({ diff --git a/packages/renderer-core/src/renderer/addon.tsx b/packages/renderer-core/src/renderer/addon.tsx index 9cb114bee4..211ec182f2 100644 --- a/packages/renderer-core/src/renderer/addon.tsx +++ b/packages/renderer-core/src/renderer/addon.tsx @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import baseRendererFactory from './base'; import { isEmpty } from '../utils'; import { IRendererAppHelper, IBaseRendererProps, IBaseRenderComponent } from '../types'; +import logger from '../utils/logger'; export default function addonRendererFactory(): IBaseRenderComponent { const BaseRenderer = baseRendererFactory(); @@ -32,7 +33,7 @@ export default function addonRendererFactory(): IBaseRenderComponent { const schema = props.__schema || {}; this.state = this.__parseData(schema.state || {}); if (isEmpty(props.config) || !props.config?.addonKey) { - console.warn('lce addon has wrong config'); + logger.warn('lce addon has wrong config'); this.setState({ __hasError: true, }); diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 1980734e43..6c2a04aa78 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -56,14 +56,14 @@ export function executeLifeCycleMethod(context: any, schema: IPublicTypeNodeSche } if (typeof fn !== 'function') { - console.error(`生命周期${method}类型不符`, fn); + logger.error(`生命周期${method}类型不符`, fn); return; } try { return fn.apply(context, args); } catch (e) { - console.error(`[${schema.componentName}]生命周期${method}出错`, e); + logger.error(`[${schema.componentName}]生命周期${method}出错`, e); } } @@ -208,7 +208,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { async componentDidCatch(...args: any[]) { this.__executeLifeCycleMethod('componentDidCatch', args); - console.warn(args); + logger.warn(args); } reloadDataSource = () => new Promise((resolve, reject) => { @@ -278,7 +278,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { value = this.__parseExpression(value, this); } if (typeof value !== 'function') { - console.error(`custom method ${key} can not be parsed to a valid function`, value); + logger.error(`custom method ${key} can not be parsed to a valid function`, value); return; } this[key] = value.bind(this); @@ -369,7 +369,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.setLocale = (loc: string) => { const setLocaleFn = this.appHelper?.utils?.i18n?.setLocale; if (!setLocaleFn || typeof setLocaleFn !== 'function') { - console.warn('initI18nAPIs Failed, i18n only works when appHelper.utils.i18n.setLocale() exists'); + logger.warn('initI18nAPIs Failed, i18n only works when appHelper.utils.i18n.setLocale() exists'); return undefined; } return setLocaleFn(loc); @@ -527,7 +527,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { : {}; if (!Comp) { - console.error(`${schema.componentName} component is not found in components list! component list is:`, components || this.props.__container?.components); + logger.error(`${schema.componentName} component is not found in components list! component list is:`, components || this.props.__container?.components); return engine.createElement( engine.getNotFoundComponent(), { @@ -749,7 +749,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { __createLoopVirtualDom = (schema: IPublicTypeNodeSchema, scope: any, parentInfo: INodeInfo, idx: number | string) => { if (isFileSchema(schema)) { - console.warn('file type not support Loop'); + logger.warn('file type not support Loop'); return null; } if (!Array.isArray(schema.loop)) { diff --git a/packages/renderer-core/src/renderer/temp.tsx b/packages/renderer-core/src/renderer/temp.tsx index 83adef7e30..1432da5fd2 100644 --- a/packages/renderer-core/src/renderer/temp.tsx +++ b/packages/renderer-core/src/renderer/temp.tsx @@ -1,4 +1,5 @@ import { IBaseRenderComponent } from '../types'; +import logger from '../utils/logger'; import baseRendererFactory from './base'; export default function tempRendererFactory(): IBaseRenderComponent { @@ -41,7 +42,7 @@ export default function tempRendererFactory(): IBaseRenderComponent { } async componentDidCatch(e: any) { - console.warn(e); + logger.warn(e); this.__debug(`componentDidCatch - ${this.props.__schema.fileName}`); } diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 29381b5473..495744acd9 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -183,13 +183,13 @@ export function transformArrayToMap(arr: any[], key: string, overwrite = true) { return res; } -export function checkPropTypes(value: any, name: string, rule: any, componentName: string) { +export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean { let ruleFunction = rule; if (typeof rule === 'string') { ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2); } if (!ruleFunction || typeof ruleFunction !== 'function') { - console.warn('checkPropTypes should have a function type rule argument'); + logger.warn('checkPropTypes should have a function type rule argument'); return true; } const err = ruleFunction( @@ -203,7 +203,7 @@ export function checkPropTypes(value: any, name: string, rule: any, componentNam ReactPropTypesSecret, ); if (err) { - console.warn(err); + logger.warn(err); } return !err; } diff --git a/packages/renderer-core/src/utils/data-helper.ts b/packages/renderer-core/src/utils/data-helper.ts index d884c13c97..41bcb9bfa0 100644 --- a/packages/renderer-core/src/utils/data-helper.ts +++ b/packages/renderer-core/src/utils/data-helper.ts @@ -186,7 +186,7 @@ export class DataHelper { } const { headers, ...otherProps } = otherOptionsObj || {}; if (!req) { - console.warn(`getDataSource API named ${id} not exist`); + logger.warn(`getDataSource API named ${id} not exist`); return; } @@ -215,7 +215,7 @@ export class DataHelper { try { callbackFn && callbackFn(res && res[id]); } catch (e) { - console.error('load请求回调函数报错', e); + logger.error('load请求回调函数报错', e); } return res && res[id]; }) @@ -223,7 +223,7 @@ export class DataHelper { try { callbackFn && callbackFn(null, err); } catch (e) { - console.error('load请求回调函数报错', e); + logger.error('load请求回调函数报错', e); } return err; }); @@ -300,9 +300,9 @@ export class DataHelper { return dataHandlerFun.call(this.host, data, error); } catch (e) { if (id) { - console.error(`[${id}]单个请求数据处理函数运行出错`, e); + logger.error(`[${id}]单个请求数据处理函数运行出错`, e); } else { - console.error('请求数据处理函数运行出错', e); + logger.error('请求数据处理函数运行出错', e); } } } diff --git a/packages/renderer-core/tests/utils/common.test.ts b/packages/renderer-core/tests/utils/common.test.ts index 995e55642e..2ee3ed4dcc 100644 --- a/packages/renderer-core/tests/utils/common.test.ts +++ b/packages/renderer-core/tests/utils/common.test.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +import factoryWithTypeCheckers from 'prop-types/factoryWithTypeCheckers'; import { isSchema, isFileSchema, @@ -18,9 +18,14 @@ import { parseThisRequiredExpression, parseI18n, parseData, + checkPropTypes, } from '../../src/utils/common'; import logger from '../../src/utils/logger'; +var ReactIs = require('react-is'); + +const PropTypes = factoryWithTypeCheckers(ReactIs.isElement, true); + describe('test isSchema', () => { it('should be false when empty value is passed', () => { expect(isSchema(null)).toBeFalsy(); @@ -461,4 +466,37 @@ describe('test parseData ', () => { expect(result.__privateKey).toBeUndefined(); }); +}); + +describe('checkPropTypes', () => { + it('should validate correctly with valid prop type', () => { + expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true); + expect(checkPropTypes('123', 'age', PropTypes.string, 'TestComponent')).toBe(true); + }); + + it('should log a warning and return false with invalid prop type', () => { + expect(checkPropTypes(123, 'age', PropTypes.string, 'TestComponent')).toBe(false); + expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false); + }); + + it('should handle custom rule functions correctly', () => { + const customRule = (props, propName) => { + if (props[propName] !== 123) { + return new Error('Invalid value'); + } + }; + const result = checkPropTypes(123, 'customProp', customRule, 'TestComponent'); + expect(result).toBe(true); + }); + + + it('should interpret and validate a rule given as a string', () => { + const result = checkPropTypes(123, 'age', 'PropTypes.number', 'TestComponent'); + expect(result).toBe(true); + }); + + it('should log a warning for invalid rule type', () => { + const result = checkPropTypes(123, 'age', 123, 'TestComponent'); + expect(result).toBe(true); + }); }); \ No newline at end of file diff --git a/packages/renderer-core/tests/utils/data-helper.test.ts b/packages/renderer-core/tests/utils/data-helper.test.ts index cd4508ea87..f4b388ce92 100644 --- a/packages/renderer-core/tests/utils/data-helper.test.ts +++ b/packages/renderer-core/tests/utils/data-helper.test.ts @@ -346,11 +346,6 @@ describe('test DataHelper ', () => { result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); expect(result).toStrictEqual({ data: 'mockDataValue' }); - // test exception - const mockError = jest.fn(); - const orginalConsole = global.console; - global.console = { error: mockError }; - // exception with id mockDataHandler = { type: 'JSFunction', @@ -358,7 +353,6 @@ describe('test DataHelper ', () => { }; result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); expect(result).toBeUndefined(); - expect(mockError).toBeCalledWith('[fullConfigGet]单个请求数据处理函数运行出错', expect.anything()); // exception without id mockDataHandler = { @@ -367,12 +361,8 @@ describe('test DataHelper ', () => { }; result = dataHelper.handleData(null, mockDataHandler, { data: 'mockDataValue' }, null); expect(result).toBeUndefined(); - expect(mockError).toBeCalledWith('请求数据处理函数运行出错', expect.anything()); - - global.console = orginalConsole; }); - it('updateConfig should work', () => { const mockHost = { stateA: 'aValue'}; const mockDataSourceConfig = { From 944012ab3ff56bb9ec5781b1c9ecb0d14a165581 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 14 Nov 2023 11:46:13 +0800 Subject: [PATCH 177/361] test(designer): add test ut to sequencify --- packages/designer/jest.config.js | 1 + packages/designer/src/plugin/sequencify.ts | 58 ++++++-- .../designer/tests/plugin/sequencify.test.ts | 128 ++++++++++++++++++ 3 files changed, 177 insertions(+), 10 deletions(-) create mode 100644 packages/designer/tests/plugin/sequencify.test.ts diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 1ecebd9388..f0ad2e861e 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -20,6 +20,7 @@ const jestConfig = { // testMatch: ['**/node.test.ts'], // testMatch: ['**/builtin-hotkey.test.ts'], // testMatch: ['**/selection.test.ts'], + // testMatch: ['**/plugin/sequencify.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/designer/src/plugin/sequencify.ts b/packages/designer/src/plugin/sequencify.ts index a312df2075..9084b0a0e6 100644 --- a/packages/designer/src/plugin/sequencify.ts +++ b/packages/designer/src/plugin/sequencify.ts @@ -1,19 +1,50 @@ -function sequence(tasks, names, results, missing, recursive, nest) { +interface ITaks { + [key: string]: { + name: string; + dep: string[]; + }; +} + +export function sequence({ + tasks, + names, + results, + missing, + recursive, + nest, + parentName, +}: { + tasks: ITaks; + names: string[]; + results: string[]; + missing: string[]; + recursive: string[][]; + nest: string[]; + parentName: string; +}) { names.forEach((name) => { if (results.indexOf(name) !== -1) { return; // de-dup results } const node = tasks[name]; if (!node) { - missing.push(name); + missing.push([parentName, name].filter((d => !!d)).join('.')); } else if (nest.indexOf(name) > -1) { nest.push(name); recursive.push(nest.slice(0)); - nest.pop(name); + nest.pop(); } else if (node.dep.length) { nest.push(name); - sequence(tasks, node.dep, results, missing, recursive, nest); // recurse - nest.pop(name); + sequence({ + tasks, + parentName: name, + names: node.dep, + results, + missing, + recursive, + nest, + }); // recurse + nest.pop(); } results.push(name); }); @@ -21,12 +52,19 @@ function sequence(tasks, names, results, missing, recursive, nest) { // tasks: object with keys as task names // names: array of task names -export default function (tasks, names) { - let results = []; // the final sequence - const missing = []; // missing tasks - const recursive = []; // recursive task dependencies +export default function (tasks: ITaks, names: string[]) { + let results: string[] = []; // the final sequence + const missing: string[] = []; // missing tasks + const recursive: string[][] = []; // recursive task dependencies - sequence(tasks, names, results, missing, recursive, []); + sequence({ + tasks, + names, + results, + missing, + recursive, + nest: [], + }); if (missing.length || recursive.length) { results = []; // results are incomplete at best, completely wrong at worst, remove them to avoid confusion diff --git a/packages/designer/tests/plugin/sequencify.test.ts b/packages/designer/tests/plugin/sequencify.test.ts new file mode 100644 index 0000000000..89140e2794 --- /dev/null +++ b/packages/designer/tests/plugin/sequencify.test.ts @@ -0,0 +1,128 @@ +import sequencify, { sequence } from '../../src/plugin/sequencify'; + +describe('sequence', () => { + it('handles tasks with no dependencies', () => { + const tasks = { + task1: { name: 'Task 1', dep: [] }, + task2: { name: 'Task 2', dep: [] } + }; + const results = []; + const missing = []; + const recursive = []; + sequence({ tasks, names: ['task1', 'task2'], results, missing, recursive, nest: [] }); + + expect(results).toEqual(['task1', 'task2']); + expect(missing).toEqual([]); + expect(recursive).toEqual([]); + }); + + it('correctly orders tasks based on dependencies', () => { + const tasks = { + task1: { name: 'Task 1', dep: [] }, + task2: { name: 'Task 2', dep: ['task1'] } + }; + const results = []; + const missing = []; + const recursive = []; + sequence({ tasks, names: ['task2', 'task1'], results, missing, recursive, nest: [] }); + + expect(results).toEqual(['task1', 'task2']); + expect(missing).toEqual([]); + expect(recursive).toEqual([]); + }); + + it('identifies missing tasks', () => { + const tasks = { + task1: { name: 'Task 1', dep: [] } + }; + const results = []; + const missing = []; + const recursive = []; + const nest = [] + sequence({ tasks, names: ['task2'], results, missing, recursive, nest }); + + expect(results).toEqual(['task2']); + expect(missing).toEqual(['task2']); + expect(recursive).toEqual([]); + expect(nest).toEqual([]); + }); + + it('detects recursive dependencies', () => { + const tasks = { + task1: { name: 'Task 1', dep: ['task2'] }, + task2: { name: 'Task 2', dep: ['task1'] } + }; + const results = []; + const missing = []; + const recursive = []; + const nest = [] + sequence({ tasks, names: ['task1', 'task2'], results, missing, recursive, nest }); + + expect(results).toEqual(['task1', 'task2', 'task1']); + expect(missing).toEqual([]); + expect(recursive).toEqual([['task1', 'task2', 'task1']]); + expect(nest).toEqual([]); + }); +}); + +describe('sequence', () => { + + it('should return tasks in sequence without dependencies', () => { + const tasks = { + task1: { name: 'Task 1', dep: [] }, + task2: { name: 'Task 2', dep: [] }, + task3: { name: 'Task 3', dep: [] } + }; + const names = ['task1', 'task2', 'task3']; + const expected = { + sequence: ['task1', 'task2', 'task3'], + missingTasks: [], + recursiveDependencies: [] + }; + expect(sequencify(tasks, names)).toEqual(expected); + }); + + it('should handle tasks with dependencies', () => { + const tasks = { + task1: { name: 'Task 1', dep: [] }, + task2: { name: 'Task 2', dep: ['task1'] }, + task3: { name: 'Task 3', dep: ['task2'] } + }; + const names = ['task3', 'task2', 'task1']; + const expected = { + sequence: ['task1', 'task2', 'task3'], + missingTasks: [], + recursiveDependencies: [] + }; + expect(sequencify(tasks, names)).toEqual(expected); + }); + + it('should identify missing tasks', () => { + const tasks = { + task1: { name: 'Task 1', dep: [] }, + task2: { name: 'Task 2', dep: ['task3'] } // task3 is missing + }; + const names = ['task1', 'task2']; + const expected = { + sequence: [], + missingTasks: ['task2.task3'], + recursiveDependencies: [] + }; + expect(sequencify(tasks, names)).toEqual(expected); + }); + + it('should detect recursive dependencies', () => { + const tasks = { + task1: { name: 'Task 1', dep: ['task2'] }, + task2: { name: 'Task 2', dep: ['task1'] } // Recursive dependency + }; + const names = ['task1', 'task2']; + const expected = { + sequence: [], + missingTasks: [], + recursiveDependencies: [['task1', 'task2', 'task1']] + }; + expect(sequencify(tasks, names)).toEqual(expected); + }); + +}); \ No newline at end of file From 736cb0e96552c557aa3f2c6d290cc3c915fb8adb Mon Sep 17 00:00:00 2001 From: beautiful-boyyy <beautiful_boyyy@outlook.com> Date: Wed, 15 Nov 2023 12:09:55 +0800 Subject: [PATCH 178/361] docs: update prepare.md --- docs/docs/participate/prepare.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md index c0e1d5880e..acb0947f22 100644 --- a/docs/docs/participate/prepare.md +++ b/docs/docs/participate/prepare.md @@ -33,27 +33,27 @@ npm install && npm start "proxy": [ [ "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/engine-core.js", - "http://localhost:5555/js/engine-core.js" + "http://localhost:5555/js/AliLowCodeEngine.js" ], [ "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/engine-core.css", - "http://localhost:5555/css/engine-core.css" + "http://localhost:5555/css/AliLowCodeEngine.css" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/react-simulator-renderer.js", - "http://localhost:5555/js/react-simulator-renderer.js" + "http://localhost:5555/js/ReactSimulatorRenderer.js" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/react-simulator-renderer.css", - "http://localhost:5555/css/react-simulator-renderer.css" + "http://localhost:5555/css/ReactSimulatorRenderer.css" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/rax-simulator-renderer.js", - "http://localhost:5555/js/rax-simulator-renderer.js" + "http://localhost:5555/js/RaxSimulatorRenderer.js" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/rax-simulator-renderer.css", - "http://localhost:5555/css/rax-simulator-renderer.css" + "http://localhost:5555/css/RaxSimulatorRenderer.css" ], ] } From 6cba4bcc206c148ec87aa2aed5ffd382ae3fe438 Mon Sep 17 00:00:00 2001 From: beautiful-boyyy <beautiful_boyyy@outlook.com> Date: Wed, 15 Nov 2023 12:09:55 +0800 Subject: [PATCH 179/361] docs: update prepare.md --- docs/docs/participate/prepare.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md index c0e1d5880e..acb0947f22 100644 --- a/docs/docs/participate/prepare.md +++ b/docs/docs/participate/prepare.md @@ -33,27 +33,27 @@ npm install && npm start "proxy": [ [ "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/engine-core.js", - "http://localhost:5555/js/engine-core.js" + "http://localhost:5555/js/AliLowCodeEngine.js" ], [ "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/engine-core.css", - "http://localhost:5555/css/engine-core.css" + "http://localhost:5555/css/AliLowCodeEngine.css" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/react-simulator-renderer.js", - "http://localhost:5555/js/react-simulator-renderer.js" + "http://localhost:5555/js/ReactSimulatorRenderer.js" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/react-simulator-renderer.css", - "http://localhost:5555/css/react-simulator-renderer.css" + "http://localhost:5555/css/ReactSimulatorRenderer.css" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/rax-simulator-renderer.js", - "http://localhost:5555/js/rax-simulator-renderer.js" + "http://localhost:5555/js/RaxSimulatorRenderer.js" ], [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/rax-simulator-renderer.css", - "http://localhost:5555/css/rax-simulator-renderer.css" + "http://localhost:5555/css/RaxSimulatorRenderer.css" ], ] } From e7884fdb5a9b448aa92ca3e897def4c05bc8caa6 Mon Sep 17 00:00:00 2001 From: Super-Rz <41566502+Super-Rz@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:23:07 +0800 Subject: [PATCH 180/361] fix: createIcon props (#2629) * fix: createIcon props * fix: createIcon props --- .../src/builtin-simulator/bem-tools/border-selecting.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx index 0e9d734b60..4f452727d2 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx @@ -143,7 +143,7 @@ function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActio }); }} > - {icon && createIcon(icon)} + {icon && createIcon(icon, { key, node: node.internalToShellNode() })} <Tip>{title}</Tip> </div> ); From 058e184b21b15bcf512d796aea825b69756db537 Mon Sep 17 00:00:00 2001 From: beautiful-boyyy <beautiful_boyyy@outlook.com> Date: Wed, 15 Nov 2023 15:18:18 +0800 Subject: [PATCH 181/361] fix: fixed string trim issue --- packages/renderer-core/src/renderer/base.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 6c2a04aa78..ac4b1de125 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -901,9 +901,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); return checkProps(res); } - if (typeof props === 'string') { - return checkProps(props.trim()); - } return checkProps(props); }; From 8898f1c4a7bb9766a0ce78632501b98942070ab4 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 15 Nov 2023 15:23:03 +0800 Subject: [PATCH 182/361] fix: fix engine-core classes is undefined --- packages/engine/src/engine-core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 204b9b30ab..2b59ba1b6d 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -54,7 +54,7 @@ import { } from '@alilc/lowcode-shell'; import { isPlainObject } from '@alilc/lowcode-utils'; import './modules/live-editing'; -import classes from './modules/classes'; +import * as classes from './modules/classes'; import symbols from './modules/symbols'; import { componentMetaParser } from './inner-plugins/component-meta-parser'; import { setterRegistry } from './inner-plugins/setter-registry'; From 0f8bc8228236439775a0429c488308ba32ab7a4d 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?= <liujup@foxmail.com> Date: Mon, 20 Nov 2023 16:04:26 +0800 Subject: [PATCH 183/361] Update index.md --- docs/docs/article/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index e62f8f9d87..2de0b059ee 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -6,6 +6,7 @@ - [2022/12/21 低代码多分支协同开发的建设与实践](https://mp.weixin.qq.com/s/DmwxL67htHfTUP1U966N-Q) - [2022/11/24 低代码引擎半岁啦,来跟大家唠唠嗑...](https://segmentfault.com/a/1190000042884409) - [2022/10/27 低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ) +- [基于 LowCodeEngine 的调试能力建设与实践](https://mp.weixin.qq.com/s/H8KvEOylmzLPgIuuBO0S9w) - [2022/06/23 低代码渲染那些事](https://mp.weixin.qq.com/s/yqYey76qLGYPfDtpGkVFfA) - [2022/06/16 关于 LowCode&ProCode 混合研发的思考](https://mp.weixin.qq.com/s/TY3VXjkSmsQoT47xma3wig) - [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) From 8208dd3a324081eeed3718d0924a397142c0c950 Mon Sep 17 00:00:00 2001 From: AprChell <smile_zchi@163.com> Date: Mon, 20 Nov 2023 16:24:27 +0800 Subject: [PATCH 184/361] fix(exportschema): exportSchema(IPublicEnumTransformStage.Save) type conver (#2661) * fix(exportschema): exportSchema(IPublicEnumTransformStage.Save) type conver * test(prop): nullProp equals null, not --- .../designer/src/document/node/props/prop.ts | 4 ---- .../tests/document/node/props/prop.test.ts | 2 +- packages/designer/tests/fixtures/schema/form.ts | 16 ++++++++-------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 01b2dc26b9..e2d9f12e8e 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -290,10 +290,6 @@ export class Prop implements IProp, IPropParent { } if (type === 'literal' || type === 'expression') { - // TODO 后端改造之后删除此逻辑 - if (this._value === null && stage === IPublicEnumTransformStage.Save) { - return ''; - } return this._value; } diff --git a/packages/designer/tests/document/node/props/prop.test.ts b/packages/designer/tests/document/node/props/prop.test.ts index 58c24a4ea4..4424eb6010 100644 --- a/packages/designer/tests/document/node/props/prop.test.ts +++ b/packages/designer/tests/document/node/props/prop.test.ts @@ -136,7 +136,7 @@ describe('Prop 类测试', () => { expect(boolProp.export(IPublicEnumTransformStage.Save)).toBe(true); expect(strProp.export(IPublicEnumTransformStage.Save)).toBe('haha'); expect(numProp.export(IPublicEnumTransformStage.Save)).toBe(1); - expect(nullProp.export(IPublicEnumTransformStage.Save)).toBe(''); + expect(nullProp.export(IPublicEnumTransformStage.Save)).toBe(null); expect(nullProp.export(IPublicEnumTransformStage.Serilize)).toBe(null); expect(expProp.export(IPublicEnumTransformStage.Save)).toEqual({ type: 'JSExpression', diff --git a/packages/designer/tests/fixtures/schema/form.ts b/packages/designer/tests/fixtures/schema/form.ts index 8da6faf9e1..e8479629f8 100644 --- a/packages/designer/tests/fixtures/schema/form.ts +++ b/packages/designer/tests/fixtures/schema/form.ts @@ -267,7 +267,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, @@ -337,7 +337,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, @@ -407,7 +407,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, @@ -489,7 +489,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, @@ -578,7 +578,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, searchDelay: 300, @@ -697,7 +697,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, @@ -789,7 +789,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, @@ -871,7 +871,7 @@ export default { labelTipsText: { type: 'i18n', use: 'zh-CN', - 'en-US': null, + 'en-US': '', 'zh-CN': '', }, }, From 3c4bd1d2d0321453b3a1fa5253b0340c3dde8afc Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 20 Nov 2023 16:45:11 +0800 Subject: [PATCH 185/361] chore(docs): publish docs 1.1.17 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index c206cdf16a..81703741ac 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.16", + "version": "1.1.17", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 396e99aa11d442f1ace9ff138b2d4698ef57d9f5 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?= <liujup@foxmail.com> Date: Mon, 20 Nov 2023 17:00:36 +0800 Subject: [PATCH 186/361] docs: update index.md --- docs/docs/article/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index 2de0b059ee..c223137b25 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -6,7 +6,7 @@ - [2022/12/21 低代码多分支协同开发的建设与实践](https://mp.weixin.qq.com/s/DmwxL67htHfTUP1U966N-Q) - [2022/11/24 低代码引擎半岁啦,来跟大家唠唠嗑...](https://segmentfault.com/a/1190000042884409) - [2022/10/27 低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ) -- [基于 LowCodeEngine 的调试能力建设与实践](https://mp.weixin.qq.com/s/H8KvEOylmzLPgIuuBO0S9w) +- [2022/08/23 基于 LowCodeEngine 的调试能力建设与实践](https://mp.weixin.qq.com/s/H8KvEOylmzLPgIuuBO0S9w) - [2022/06/23 低代码渲染那些事](https://mp.weixin.qq.com/s/yqYey76qLGYPfDtpGkVFfA) - [2022/06/16 关于 LowCode&ProCode 混合研发的思考](https://mp.weixin.qq.com/s/TY3VXjkSmsQoT47xma3wig) - [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) From bf50071cc8ca2c06b70f03c16347fc85533bd8e0 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?= <liujup@foxmail.com> Date: Mon, 20 Nov 2023 17:03:11 +0800 Subject: [PATCH 187/361] docs: update index.md --- docs/docs/video/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/video/index.md b/docs/docs/video/index.md index 9f348e4e65..2f8a5f49ce 100644 --- a/docs/docs/video/index.md +++ b/docs/docs/video/index.md @@ -1,4 +1,5 @@ # 官方视频 +- [2023/11/17 云栖大会|阿里开源低代码引擎及商业解决方案](https://www.bilibili.com/video/BV1Qw411H7DH) - [2023/08/03 初识低代码引擎](https://www.bilibili.com/video/BV1gu411p7TC) # 社区视频 From d47df9dc441cfc5f0a3490e2243e90473e3469e1 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 20 Nov 2023 17:33:53 +0800 Subject: [PATCH 188/361] style: add --workspace-left-area-width --- docs/docs/guide/expand/editor/theme.md | 1 + packages/editor-skeleton/src/layouts/workbench.less | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index b62fb4f28c..94e434580d 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -72,6 +72,7 @@ sidebar_position: 9 - `--workspace-sub-top-area-height`: 应用级二级 topArea 高度 - `--workspace-sub-top-area-margin`: 应用级二级 topArea margin - `--workspace-sub-top-area-padding`: 应用级二级 topArea padding +- `--workspace-left-area-width`: 应用级 leftArea width ### 生态使用主题色变量 diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 6d0604a1f1..eb86bfe04c 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -13,6 +13,7 @@ --popup-border-radius: @popup-border-radius; --left-area-width: 48px; + --workspace-left-area-width: 48px; --right-area-width: 300px; --top-area-height: 48px; --toolbar-height: 36px; @@ -273,7 +274,7 @@ body { } .lc-left-area, .lc-workspace-left-area { height: 100%; - width: var(--left-area-width); + width: var(--workspace-left-area-width, --left-area-width); display: none; flex-shrink: 0; flex-direction: column; From 322313ceada4bf3d2011a0032f0be598c73ebeab Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 20 Nov 2023 18:14:15 +0800 Subject: [PATCH 189/361] docs: update faq list --- docs/docs/faq/index.md | 43 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/docs/docs/faq/index.md b/docs/docs/faq/index.md index ed31bad28e..5e5eee8ac4 100644 --- a/docs/docs/faq/index.md +++ b/docs/docs/faq/index.md @@ -1,7 +1,46 @@ --- title: FAQ 概述 -sidebar_position: 1 +sidebar_position: -1 tags: [FAQ] --- -不定期将社区常见问题及答案维护到此处 \ No newline at end of file +不定期将社区常见问题及答案维护到此处 + +## Demo 使用 +- [渲染唯一标识(key)](/site/docs/faq/faq002) +- [点击事件如何添加参数](/site/docs/faq/faq003) +- [如何通过 API 手动调用数据源请求](/site/docs/faq/faq006) + +## 设计器定制 +- [如何通过 this.utils 使用第三方工具扩展](/site/docs/faq/faq005) +- [设置面板中的高级 tab 如何配置](/site/docs/faq/faq007) +- [插件面板如何调整位置](/site/docs/faq/faq010) + +## 源码和依赖 +- [某某 npm 包对应的源码在哪里?](/site/docs/faq/faq008) + +## 错误和报错 +- [物料出现 Component Not Found 相关报错](/site/docs/faq/faq009) +- [VERSION_PLACEHOLDER is not defined](/site/docs/faq/faq014) +- [Cannot read property 'Icon' of Undefined](/site/docs/faq/faq016) +- [windows 下运行低代码引擎源码出现报错](/site/docs/faq/faq019) +- [Can't import the named export from non ECMAScript module](/site/docs/faq/faq020) +- [Slot组件渲染报错问题](/site/docs/faq/faq023) + +## 物料相关问题 +- [如何获取物料当前处于编辑态还是渲染态](/site/docs/faq/faq011) +- [Procode 物料如何调用数据源方法](/site/docs/faq/faq012) +- [已有组件如何快速接入引擎](/site/docs/faq/faq015) +- [Modal 类组件 hidden 属性被强制设置 true](/site/docs/faq/faq013) +- [最小渲染单元配置](/site/docs/faq/faq004) +- [节点无法拖拽到 Page 下](/site/docs/faq/faq022) + +## 其他说明 +- [vue 画布支持说明](/site/docs/faq/faq017) +- [是否可以生成 Vue 页面代码?](/site/docs/faq/faq018) + +## 参与贡献 +- [提交 PR 时,明明签署过 CLA,仍被提示需要签署](/site/docs/faq/faq021) + +## 相关依赖文档 +- [build-scripts 的使用文档](/site/docs/faq/faq001) From e35c672a50dc877f5768c1092e330bfb0424cfe2 Mon Sep 17 00:00:00 2001 From: "chenkeyao.chenkeya" <chenkeyao.chenkeya@alibaba-inc.com> Date: Mon, 20 Nov 2023 21:02:05 +0800 Subject: [PATCH 190/361] feat: add new video --- docs/docs/video/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/video/index.md b/docs/docs/video/index.md index 2f8a5f49ce..8ae21620bc 100644 --- a/docs/docs/video/index.md +++ b/docs/docs/video/index.md @@ -1,5 +1,5 @@ # 官方视频 -- [2023/11/17 云栖大会|阿里开源低代码引擎及商业解决方案](https://www.bilibili.com/video/BV1Qw411H7DH) +- [2023/11/20 云栖大会|阿里开源低代码引擎及商业解决方案](https://www.bilibili.com/video/BV1Ku4y1w7Zr) - [2023/08/03 初识低代码引擎](https://www.bilibili.com/video/BV1gu411p7TC) # 社区视频 From 7c72261fef0324cb57fd3e42331ede0f5b680573 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 21 Nov 2023 10:28:27 +0800 Subject: [PATCH 191/361] chore(docs): publish docs 1.2.0 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 81703741ac..cb3cb946dc 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.1.17", + "version": "1.2.0", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 394b56d0cef70101709802fb6ab1fda8f0ec2e3a Mon Sep 17 00:00:00 2001 From: 1ncounter <1ncounter.100@gmail.com> Date: Wed, 22 Nov 2023 19:50:22 +0800 Subject: [PATCH 192/361] fix: recover component lifecycle and avoid execute from scope __proto__ --- packages/renderer-core/src/renderer/base.tsx | 5 +++++ .../renderer-core/src/renderer/component.tsx | 21 ------------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index ac4b1de125..dddc55e838 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -50,6 +50,11 @@ export function executeLifeCycleMethod(context: any, schema: IPublicTypeNodeSche return; } + // avoid execute lifeCycle method from __proto__'s method (it is React class Component Class lifeCycle) + if (!Object.prototype.hasOwnProperty.call(context, method) && method !== 'constructor') { + return; + } + // TODO: cache if (isJSExpression(fn) || isJSFunction(fn)) { fn = thisRequiredInJSE ? parseThisRequiredExpression(fn, context) : parseExpression(fn, context); diff --git a/packages/renderer-core/src/renderer/component.tsx b/packages/renderer-core/src/renderer/component.tsx index f9f6e8f96e..3dfc1df33f 100644 --- a/packages/renderer-core/src/renderer/component.tsx +++ b/packages/renderer-core/src/renderer/component.tsx @@ -46,26 +46,5 @@ export default function componentRendererFactory(): IBaseRenderComponent { return this.__renderComp(Component, this.__renderContextProvider({ compContext: this })); } - - getComponentName() { - return this.props?.componentName; - } - - /** 需要重载下面几个方法,如果在低代码组件中绑定了对应的生命周期时会出现死循环 */ - componentDidMount() { - this.__debug(`componentDidMount - ${this.getComponentName()}`); - } - getSnapshotBeforeUpdate() { - this.__debug(`getSnapshotBeforeUpdate - ${this.getComponentName()}`); - } - componentDidUpdate() { - this.__debug(`componentDidUpdate - ${this.getComponentName()}`); - } - componentWillUnmount() { - this.__debug(`componentWillUnmount - ${this.getComponentName()}`); - } - componentDidCatch() { - this.__debug(`componentDidCatch - ${this.getComponentName()}`); - } }; } From 27e914cecee34a886680db3f2bc0c69f2b62c726 Mon Sep 17 00:00:00 2001 From: andylili21 <101868030+andylili21@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:05:07 +0800 Subject: [PATCH 193/361] fix: Improve code and simplify logic (#2651) * fix: Improve code and simplify logic --- packages/designer/src/document/node/node.ts | 14 ++--- .../designer/tests/document/node/node.test.ts | 61 +++++++++++++++++-- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 9effc341dd..145a5a85ec 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -440,23 +440,23 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> } private initialChildren(children: IPublicTypeNodeData | IPublicTypeNodeData[] | undefined): IPublicTypeNodeData[] { - // FIXME! this is dirty code + const { initialChildren } = this.componentMeta.advanced; + if (children == null) { - const { initialChildren } = this.componentMeta.advanced; if (initialChildren) { if (typeof initialChildren === 'function') { return initialChildren(this.internalToShellNode()!) || []; } return initialChildren; } + return []; } + if (Array.isArray(children)) { return children; - } else if (children) { - return [children]; - } else { - return []; } + + return [children]; } isContainer(): boolean { @@ -1094,7 +1094,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> } /** - * 是否可执行某action + * 是否可执行某 action */ canPerformAction(actionName: string): boolean { const availableActions = diff --git a/packages/designer/tests/document/node/node.test.ts b/packages/designer/tests/document/node/node.test.ts index c4717b3a02..2695d6c838 100644 --- a/packages/designer/tests/document/node/node.test.ts +++ b/packages/designer/tests/document/node/node.test.ts @@ -54,7 +54,60 @@ describe('Node 方法测试', () => { project = null; }); - it('condition group', () => {}); + // Case 1: When children is null + test('initialChildren returns result of initialChildren function when children is null ', () => { + const node = new Node(doc, { componentName: 'Button', props: { a: 1 } }); + const result = node.initialChildren(null); + // 预期结果是一个空数组 + expect(result).toEqual([]); + }); + + // Case 2: When children is undefined + test('initialChildren returns result of initialChildren function when children is null ', () => { + const node = new Node(doc, { componentName: 'Button', props: { a: 1 } }); + const result = node.initialChildren(undefined); + // 预期结果是一个空数组 + expect(result).toEqual([]); + }); + + // Case 3: When children is array + test('initialChildren returns result of initialChildren function when children is null ', () => { + const node = new Node(doc, { componentName: 'Button', props: { a: 1 } }); + const childrenArray = [{ id: 1, name: 'Child 1' }, { id: 2, name: 'Child 2' }]; + const result = node.initialChildren(childrenArray); + // 预期结果是一个数组 + expect(result).toEqual(childrenArray); + }); + + // Case 4: When children is not null and not an array + test('initialChildren returns result of initialChildren function when children is null ', () => { + const node = new Node(doc, { componentName: 'Button', props: { a: 1 } }); + const childObject = { id: 1, name: 'Child 1' }; + const result = node.initialChildren(childObject); + // 预期结果是一个数组 + expect(result).toEqual([childObject]); + }); + + // Case 5: When children 0 + test('initialChildren returns result of initialChildren function when children is null ', () => { + const node = new Node(doc, { componentName: 'Button', props: { a: 1 } }); + const childObject = 0; + const result = node.initialChildren(childObject); + // 预期结果是一个数组 + expect(result).toEqual([0]); + }); + + // Case 6: When children false + test('initialChildren returns result of initialChildren function when children is null ', () => { + const node = new Node(doc, { componentName: 'Button', props: { a: 1 } }); + const childObject = false; + const result = node.initialChildren(childObject); + // 预期结果是一个数组 + expect(result).toEqual([false]); + }); + + + it('condition group', () => { }); it('getExtraProp / setExtraProp', () => { const firstBtn = doc.getNode('node_k1ow3cbn')!; @@ -367,7 +420,7 @@ describe('Node 方法测试', () => { expect(mockFn).not.toHaveBeenCalled(); }); - it('addSlot / unlinkSlot / removeSlot', () => {}); + it('addSlot / unlinkSlot / removeSlot', () => { }); it('setProps', () => { const firstBtn = doc.getNode('node_k1ow3cbn')!; @@ -407,7 +460,7 @@ describe('Node 方法测试', () => { designer.createComponentMeta(btnMetadata); const btn = doc.getNode('node_k1ow3cbn'); // 从 componentMeta 中获取到 title 值 - expect(btn.title).toEqual({ type: 'i18n', 'zh-CN': '按钮', 'en-US': 'Button' } ); + expect(btn.title).toEqual({ type: 'i18n', 'zh-CN': '按钮', 'en-US': 'Button' }); // 从 extraProp 中获取值 btn.setExtraProp('title', 'hello button'); expect(btn.title).toBe('hello button'); @@ -546,7 +599,7 @@ describe('Node 方法测试', () => { expect(comparePosition(firstBtn, firstCard)).toBe(PositionNO.BeforeOrAfter); }); - it('getZLevelTop', () => {}); + it('getZLevelTop', () => { }); it('propsData', () => { expect(new Node(doc, { componentName: 'Leaf' }).propsData).toBeNull(); expect(new Node(doc, { componentName: 'Fragment' }).propsData).toBeNull(); From ad044f49ed9064fe1afa5195f68759a76bda5f5e Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 23 Nov 2023 11:01:50 +0800 Subject: [PATCH 194/361] feat(utils): add workspace utils --- packages/designer/src/plugin/plugin-types.ts | 1 + packages/engine/src/engine-core.ts | 1 + .../types/src/shell/model/plugin-context.ts | 2 + packages/utils/src/index.ts | 1 + packages/utils/src/workspace.tsx | 54 +++++++++++++++++++ .../workspace/src/context/base-context.ts | 1 + 6 files changed, 60 insertions(+) create mode 100644 packages/utils/src/workspace.tsx diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index ac08d7d0ca..6091170f02 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -60,6 +60,7 @@ export interface ILowCodePluginContextPrivate { set workspace(workspace: IPublicApiWorkspace); set editorWindow(window: IPublicModelWindow); set registerLevel(level: IPublicEnumPluginRegisterLevel); + set isPluginRegisteredInWorkspace(flag: boolean); } export interface ILowCodePluginContextApiAssembler { assembleApis( diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 2b59ba1b6d..3ac4c32a75 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -139,6 +139,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` }); context.workspace = workspace; context.registerLevel = IPublicEnumPluginRegisterLevel.Default; + context.isPluginRegisteredInWorkspace = false; }, }; diff --git a/packages/types/src/shell/model/plugin-context.ts b/packages/types/src/shell/model/plugin-context.ts index 1f3d3b5e85..35e7e38af3 100644 --- a/packages/types/src/shell/model/plugin-context.ts +++ b/packages/types/src/shell/model/plugin-context.ts @@ -108,6 +108,8 @@ export interface IPublicModelPluginContext { */ get registerLevel(): IPublicEnumPluginRegisterLevel; + get isPluginRegisteredInWorkspace(): boolean; + get editorWindow(): IPublicModelWindow; } diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index e3f70ff80a..3e37f46ba6 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -30,3 +30,4 @@ export * from './is-plugin-event-name'; export * as css from './css-helper'; export { transactionManager } from './transaction-manager'; export * from './check-types'; +export * from './workspace'; diff --git a/packages/utils/src/workspace.tsx b/packages/utils/src/workspace.tsx new file mode 100644 index 0000000000..446530ce8e --- /dev/null +++ b/packages/utils/src/workspace.tsx @@ -0,0 +1,54 @@ +import React, { useEffect, useState, useCallback } from 'react'; +import { IPublicModelPluginContext, IPublicEnumPluginRegisterLevel, IPublicModelWindow, IPublicModelEditorView } from '@alilc/lowcode-types'; + +/** + * 高阶组件(HOC):为组件提供 view 插件上下文。 + * + * @param {React.ComponentType} Component - 需要被封装的组件。 + * @param {string|string[]} viewName - 视图名称或视图名称数组,用于过滤特定的视图插件上下文。 + * @returns {React.ComponentType} 返回封装后的组件。 + * + * @example + * // 用法示例(函数组件): + * const EnhancedComponent = ProvideViewPluginContext(MyComponent, "viewName"); + */ +export const ProvideViewPluginContext = (Component: any, viewName?: string | string[]) => { + // 创建一个新的函数组件,以便在其中使用 Hooks + return function WithPluginContext(props: { + [key: string]: any; + + pluginContext?: IPublicModelPluginContext; + }) { + const getPluginContextFun = useCallback((editorWindow?: IPublicModelWindow | null) => { + if (!editorWindow?.currentEditorView) { + return null; + } + if (viewName) { + const items = editorWindow?.editorViews.filter(d => (d as any).viewName === viewName || (Array.isArray(viewName) && viewName.includes((d as any).viewName))); + return items[0]; + } else { + return editorWindow.currentEditorView; + } + }, []); + + const { workspace } = props.pluginContext || {}; + const [pluginContext, setPluginContext] = useState<IPublicModelEditorView | null>(getPluginContextFun(workspace?.window)); + + useEffect(() => { + if (workspace?.window) { + const ctx = getPluginContextFun(workspace.window); + ctx && setPluginContext(ctx); + } + return workspace?.onChangeActiveEditorView(() => { + const ctx = getPluginContextFun(workspace.window); + ctx && setPluginContext(ctx); + }); + }, [workspace, getPluginContextFun]); + + if (props.pluginContext?.registerLevel !== IPublicEnumPluginRegisterLevel.Workspace || !props.pluginContext) { + return <Component {...props} />; + } + + return <Component {...props} pluginContext={pluginContext} />; + }; +}; diff --git a/packages/workspace/src/context/base-context.ts b/packages/workspace/src/context/base-context.ts index b359a6139f..78f32079ff 100644 --- a/packages/workspace/src/context/base-context.ts +++ b/packages/workspace/src/context/base-context.ts @@ -170,6 +170,7 @@ export class BasicContext implements IBasicContext { context.editorWindow = new Window(editorWindow); } context.registerLevel = registerLevel; + context.isPluginRegisteredInWorkspace = registerLevel === IPublicEnumPluginRegisterLevel.Workspace; }, }; From 029fd1ce67739e85dd669c61ebfedf52199c2d11 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 23 Nov 2023 11:23:34 +0800 Subject: [PATCH 195/361] feat(outline-pane): suport registry in workspace level --- .../src/controllers/tree-master.ts | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/plugin-outline-pane/src/controllers/tree-master.ts b/packages/plugin-outline-pane/src/controllers/tree-master.ts index 40162d808f..ede5f0f5f3 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-master.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-master.ts @@ -41,22 +41,19 @@ export class TreeMaster { this.initEvent(); if (pluginContext.registerLevel === IPublicEnumPluginRegisterLevel.Workspace) { this.setPluginContext(workspace.window?.currentEditorView); - workspace.onWindowRendererReady(() => { - this.setPluginContext(workspace.window?.currentEditorView); - let dispose: IPublicTypeDisposable | undefined; - const windowViewTypeChangeEvent = () => { - dispose = workspace.window?.onChangeViewType(() => { - this.setPluginContext(workspace.window?.currentEditorView); - }); - }; - - windowViewTypeChangeEvent(); - - workspace.onChangeActiveWindow(() => { - windowViewTypeChangeEvent(); + let dispose: IPublicTypeDisposable | undefined; + const windowViewTypeChangeEvent = () => { + dispose = workspace.window?.onChangeViewType(() => { this.setPluginContext(workspace.window?.currentEditorView); - dispose && dispose(); }); + }; + + windowViewTypeChangeEvent(); + + workspace.onChangeActiveWindow(() => { + windowViewTypeChangeEvent(); + this.setPluginContext(workspace.window?.currentEditorView); + dispose && dispose(); }); } } From a3fef9c13d39ac1b35b200cf0f711cf7c7c233d8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 23 Nov 2023 15:32:54 +0800 Subject: [PATCH 196/361] feat(skeleton): add registerConfigTransducer API --- docs/docs/api/skeleton.md | 62 +++++++++++++++++++ packages/editor-skeleton/src/skeleton.ts | 31 +++++++++- packages/shell/src/api/skeleton.ts | 6 +- packages/types/src/shell/api/skeleton.ts | 19 +++++- .../types/src/shell/type/config-transducer.ts | 9 +++ packages/types/src/shell/type/index.ts | 1 + 6 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 packages/types/src/shell/type/config-transducer.ts diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index c378792de0..90cf1a2c17 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -295,6 +295,68 @@ showArea(areaName: string): void; */ hideArea(areaName: string): void; ``` + +### registerConfigTransducer +注册一个面板的配置转换器(transducer)。 + +```typescript +/** + * 注册一个面板的配置转换器(transducer)。 + * Registers a configuration transducer for a panel. + * @param {IPublicTypeConfigTransducer} transducer + * - 要注册的转换器函数。该函数接受一个配置对象(类型为 IPublicTypeSkeletonConfig)作为输入,并返回修改后的配置对象。 + * - The transducer function to be registered. This function takes a configuration object + * + * @param {number} level + * - 转换器的优先级。优先级较高的转换器会先执行。 + * - The priority level of the transducer. Transducers with higher priority levels are executed first. + * + * @param {string} [id] + * - (可选)转换器的唯一标识符。用于在需要时引用或操作特定的转换器。 + * - (Optional) A unique identifier for the transducer. Used for referencing or manipulating a specific transducer when needed. + */ +registerConfigTransducer(transducer: IPublicTypeConfigTransducer, level: number, id?: string): void; +``` + +使用示例 + +```typescript +import { IPublicModelPluginContext, IPublicTypeSkeletonConfig } from '@alilc/lowcode-types'; + +function updatePanelWidth(config: IPublicTypeSkeletonConfig) { + if (config.type === 'PanelDock') { + return { + ...config, + panelProps: { + ...(config.panelProps || {}), + width: 240, + }, + } + } + + return config; +} + +const controlPanelWidthPlugin = (ctx: IPublicModelPluginContext) => { + const { skeleton } = ctx; + (skeleton as any).registerConfigTransducer?.(updatePanelWidth, 1, 'update-panel-width'); + + return { + init() {}, + }; +}; + +controlPanelWidthPlugin.pluginName = 'controlPanelWidthPlugin'; +controlPanelWidthPlugin.meta = { + dependencies: [], + engines: { + lowcodeEngine: '^1.2.3', // 插件需要配合 ^1.0.0 的引擎才可运行 + }, +}; + +export default controlPanelWidthPlugin; +``` + ## 事件 ### onShowPanel diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 89bffc4cfe..13967e94d6 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -28,6 +28,7 @@ import { IPublicTypeWidgetConfigArea, IPublicTypeSkeletonConfig, IPublicApiSkeleton, + IPublicTypeConfigTransducer, } from '@alilc/lowcode-types'; const logger = new Logger({ level: 'warn', bizName: 'skeleton' }); @@ -111,6 +112,8 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton, export class Skeleton implements ISkeleton { private panels = new Map<string, Panel>(); + private configTransducers: IPublicTypeConfigTransducer[] = []; + private containers = new Map<string, WidgetContainer<any>>(); readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>; @@ -448,11 +451,35 @@ export class Skeleton implements ISkeleton { return restConfig; } + registerConfigTransducer( + transducer: IPublicTypeConfigTransducer, + level = 100, + id?: string, + ) { + transducer.level = level; + transducer.id = id; + const i = this.configTransducers.findIndex((item) => item.level != null && item.level > level); + if (i < 0) { + this.configTransducers.push(transducer); + } else { + this.configTransducers.splice(i, 0, transducer); + } + } + + getRegisteredConfigTransducers(): IPublicTypeConfigTransducer[] { + return this.configTransducers; + } + add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined { - const parsedConfig = { + const registeredTransducers = this.getRegisteredConfigTransducers(); + + const parsedConfig = registeredTransducers.reduce((prevConfig, current) => { + return current(prevConfig); + }, { ...this.parseConfig(config), ...extraConfig, - }; + }); + let { area } = parsedConfig; if (!area) { if (parsedConfig.type === 'Panel') { diff --git a/packages/shell/src/api/skeleton.ts b/packages/shell/src/api/skeleton.ts index 0d17075257..07a1727dd3 100644 --- a/packages/shell/src/api/skeleton.ts +++ b/packages/shell/src/api/skeleton.ts @@ -4,7 +4,7 @@ import { SkeletonEvents, } from '@alilc/lowcode-editor-skeleton'; import { skeletonSymbol } from '../symbols'; -import { IPublicApiSkeleton, IPublicModelSkeletonItem, IPublicTypeDisposable, IPublicTypeSkeletonConfig, IPublicTypeWidgetConfigArea } from '@alilc/lowcode-types'; +import { IPublicApiSkeleton, IPublicModelSkeletonItem, IPublicTypeConfigTransducer, IPublicTypeDisposable, IPublicTypeSkeletonConfig, IPublicTypeWidgetConfigArea } from '@alilc/lowcode-types'; import { getLogger } from '@alilc/lowcode-utils'; import { SkeletonItem } from '../model/skeleton-item'; @@ -208,6 +208,10 @@ export class Skeleton implements IPublicApiSkeleton { }); return () => editor.eventBus.off(SkeletonEvents.WIDGET_HIDE, listener); } + + registerConfigTransducer(fn: IPublicTypeConfigTransducer, level: number, id?: string) { + this[skeletonSymbol].registerConfigTransducer(fn, level, id); + } } function normalizeArea(area: IPublicTypeWidgetConfigArea | undefined): 'leftArea' | 'rightArea' | 'topArea' | 'toolbar' | 'mainArea' | 'bottomArea' | 'leftFixedArea' | 'leftFloatArea' | 'stages' | 'subTopArea' { diff --git a/packages/types/src/shell/api/skeleton.ts b/packages/types/src/shell/api/skeleton.ts index 2ad561518b..9a36aa4690 100644 --- a/packages/types/src/shell/api/skeleton.ts +++ b/packages/types/src/shell/api/skeleton.ts @@ -1,5 +1,5 @@ import { IPublicModelSkeletonItem } from '../model'; -import { IPublicTypeDisposable, IPublicTypeSkeletonConfig } from '../type'; +import { IPublicTypeConfigTransducer, IPublicTypeDisposable, IPublicTypeSkeletonConfig } from '../type'; export interface IPublicApiSkeleton { @@ -114,4 +114,21 @@ export interface IPublicApiSkeleton { * @returns */ onHideWidget(listener: (...args: any[]) => void): IPublicTypeDisposable; + + /** + * 注册一个面板的配置转换器(transducer)。 + * Registers a configuration transducer for a panel. + * @param {IPublicTypeConfigTransducer} transducer + * - 要注册的转换器函数。该函数接受一个配置对象(类型为 IPublicTypeSkeletonConfig)作为输入,并返回修改后的配置对象。 + * - The transducer function to be registered. This function takes a configuration object (of type IPublicTypeSkeletonConfig) as input and returns a modified configuration object. + * + * @param {number} level + * - 转换器的优先级。优先级较高的转换器会先执行。 + * - The priority level of the transducer. Transducers with higher priority levels are executed first. + * + * @param {string} [id] + * - (可选)转换器的唯一标识符。用于在需要时引用或操作特定的转换器。 + * - (Optional) A unique identifier for the transducer. Used for referencing or manipulating a specific transducer when needed. + */ + registerConfigTransducer(transducer: IPublicTypeConfigTransducer, level: number, id?: string): void; } diff --git a/packages/types/src/shell/type/config-transducer.ts b/packages/types/src/shell/type/config-transducer.ts new file mode 100644 index 0000000000..64c33a5c4e --- /dev/null +++ b/packages/types/src/shell/type/config-transducer.ts @@ -0,0 +1,9 @@ +import { IPublicTypeSkeletonConfig } from '.'; + +export interface IPublicTypeConfigTransducer { + (prev: IPublicTypeSkeletonConfig): IPublicTypeSkeletonConfig; + + level?: number; + + id?: string; +} diff --git a/packages/types/src/shell/type/index.ts b/packages/types/src/shell/type/index.ts index 7232ffbbdc..b2fd3313f9 100644 --- a/packages/types/src/shell/type/index.ts +++ b/packages/types/src/shell/type/index.ts @@ -91,3 +91,4 @@ export * from './hotkey-callback-config'; export * from './hotkey-callbacks'; export * from './scrollable'; export * from './simulator-renderer'; +export * from './config-transducer'; \ No newline at end of file From 7e80d1f863f934720915df35db3b27415a11ebb7 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 23 Nov 2023 16:33:45 +0800 Subject: [PATCH 197/361] chore(docs): publish docs 1.2.1 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index cb3cb946dc..14d0c99e55 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.0", + "version": "1.2.1", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From dc1e0f5a49a81b3fb8c47b4a1495d06e16798fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Thu, 23 Nov 2023 18:58:24 +0800 Subject: [PATCH 198/361] Fix/component lifecycle not execute (#2690) * fix: recover component lifecycle and avoid execute from scope __proto__ From 6c7a52652131b0a18a03bf6f90b8730544b8be34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Thu, 23 Nov 2023 19:28:41 +0800 Subject: [PATCH 199/361] Fix/component lifecycle not execute (#2692) * fix: recover component lifecycle and avoid execute from scope __proto__ From c643c0fc4f4c9eb90b8d273447fef04d28cfe13d Mon Sep 17 00:00:00 2001 From: 1ncounter <1ncounter.100@gmail.com> Date: Thu, 23 Nov 2023 19:35:37 +0800 Subject: [PATCH 200/361] fix(renderer-core): remove compatibility with uipaas --- packages/renderer-core/src/renderer/base.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index dddc55e838..ac4b1de125 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -50,11 +50,6 @@ export function executeLifeCycleMethod(context: any, schema: IPublicTypeNodeSche return; } - // avoid execute lifeCycle method from __proto__'s method (it is React class Component Class lifeCycle) - if (!Object.prototype.hasOwnProperty.call(context, method) && method !== 'constructor') { - return; - } - // TODO: cache if (isJSExpression(fn) || isJSFunction(fn)) { fn = thisRequiredInJSE ? parseThisRequiredExpression(fn, context) : parseExpression(fn, context); From 1c2f195e8bce05284419eb7bbbba33bb97acf30e 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?= <liujup@foxmail.com> Date: Mon, 27 Nov 2023 16:22:29 +0800 Subject: [PATCH 201/361] docs: update skeleton.md --- docs/docs/api/skeleton.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 90cf1a2c17..5bfa239724 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -69,6 +69,7 @@ skeleton.add({ props: { align: "left", icon: "wenjian", + title: '标题', // 图标下方展示的标题 description: "JS 面板", }, panelProps: { From 20bf62aed3c67753c265c38dffaa5e5a31c2b4ee Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 27 Nov 2023 17:50:48 +0800 Subject: [PATCH 202/361] chore(docs): publish docs 1.2.2 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 14d0c99e55..e9d5b87b43 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.1", + "version": "1.2.2", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From d41f2c13d24a0270616ae4d2d2484e347ca02573 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?= <liujup@foxmail.com> Date: Mon, 27 Nov 2023 21:40:25 +0800 Subject: [PATCH 203/361] docs: update material.md --- docs/docs/api/material.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 8b1214476b..51ed4e3054 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -116,6 +116,21 @@ material.setAssets(assets1); material.loadIncrementalAssets(assets2); ``` +更新特定物料的描述文件 + +```typescript +import { material } from '@alilc/lowcode-engine'; +material.loadIncrementalAssets({ + version: '', + components: [ + { + "componentName": 'Button', + "props": [{ name: 'new', title: 'new', propType: 'string' }] + } + ], +}) +``` + ### 设计器辅助层 #### addBuiltinComponentAction 在设计器辅助层增加一个扩展 action From f75b9ae61cdc46618038b3fe43e6744aa8d56f5c Mon Sep 17 00:00:00 2001 From: owenchen1004 <yoga981004@gmail.com> Date: Tue, 28 Nov 2023 10:50:38 +0800 Subject: [PATCH 204/361] fix: executeLifeCycleMethod return bug in renderer --- packages/renderer-core/src/renderer/base.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 1980734e43..640763538a 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -182,7 +182,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { __afterInit(_props: IBaseRendererProps) { } static getDerivedStateFromProps(props: IBaseRendererProps, state: any) { - return executeLifeCycleMethod(this, props?.__schema, 'getDerivedStateFromProps', [props, state], props.thisRequiredInJSE); + return executeLifeCycleMethod(this, props?.__schema, 'getDerivedStateFromProps', [props, state], props.thisRequiredInJSE) || null; } async getSnapshotBeforeUpdate(...args: any[]) { From b786c8fcaad1376d1d4d1316f75e283418f93913 Mon Sep 17 00:00:00 2001 From: owenchen1004 <yoga981004@gmail.com> Date: Tue, 28 Nov 2023 11:04:37 +0800 Subject: [PATCH 205/361] fix: coding style update --- packages/renderer-core/src/renderer/base.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 640763538a..ebaa8eadc8 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -182,7 +182,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { __afterInit(_props: IBaseRendererProps) { } static getDerivedStateFromProps(props: IBaseRendererProps, state: any) { - return executeLifeCycleMethod(this, props?.__schema, 'getDerivedStateFromProps', [props, state], props.thisRequiredInJSE) || null; + const result = executeLifeCycleMethod(this, props?.__schema, 'getDerivedStateFromProps', [props, state], props.thisRequiredInJSE); + return result === undefined ? null : result; } async getSnapshotBeforeUpdate(...args: any[]) { From d199b44eca0b1fe47d1744421a275188f69533e1 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 28 Nov 2023 16:11:04 +0800 Subject: [PATCH 206/361] style: add --color-toolbar-background --- docs/docs/guide/expand/editor/theme.md | 73 +++++++++++++++---- .../src/layouts/workbench.less | 2 +- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index 94e434580d..16bcf04b09 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -3,23 +3,46 @@ title: 主题色扩展 sidebar_position: 9 --- -## 主题色扩展简述 +## 简介 -通过主题色扩展,可以定制多种设计器主题。 +主题色扩展允许用户定制多样的设计器主题,增加界面的个性化和品牌识别度。 -## 主题色扩展说明 +## 设计器主题色定制 + +在 CSS 的根级别定义主题色变量可以确保这些变量在整个应用中都可用。例如: + +```css +:root { + --color-brand: rgba(0, 108, 255, 1); /* 主品牌色 */ + --color-brand-light: rgba(25, 122, 255, 1); /* 浅色品牌色 */ + --color-brand-dark: rgba(0, 96, 229, 1); /* 深色品牌色 */ +} + +``` + +将样式文件引入到你的设计器中,定义的 CSS 变量就可以改变设计器的主题色了。 ### 主题色变量 -- `--color-brand`: 品牌色 -- `--color-brand-light`: 品牌色(light) -- `--color-brand-dark`: 品牌色(dark) -- `--color-icon-normal`: 正常 icon 颜色 -- `--color-icon-hover`: icon hover 态颜色 -- `--color-icon-active`: icon active 态颜色 -- `--color-icon-reverse`: icon 反色 -- `--color-icon-disabled`: icon 禁用态颜色 -- `--color-icon-pane`: icon 面板颜色 +以下是低代码引擎设计器支持的主题色变量列表,以及它们的用途说明: + +#### 品牌相关颜色 + +- `--color-brand`: 主品牌色 +- `--color-brand-light`: 浅色品牌色 +- `--color-brand-dark`: 深色品牌色 + +#### Icon 相关颜色 + +- `--color-icon-normal`: 默认状态 +- `--color-icon-hover`: 鼠标悬停状态 +- `--color-icon-active`: 激活状态 +- `--color-icon-reverse`: 反色状态 +- `--color-icon-disabled`: 禁用状态 +- `--color-icon-pane`: 面板颜色 + +#### 线条和文本颜色 + - `--color-line-normal`: 线条颜色 - `--color-line-darken`: 线条颜色(darken) - `--color-title`: 标题颜色 @@ -29,6 +52,9 @@ sidebar_position: 9 - `--color-text-reverse`: 反色情况下,文字颜色 - `--color-text-regular`: 文字颜色(regular) - `--color-text-disabled`: 禁用态文字颜色 + +#### 字段和边框颜色 + - `--color-field-label`: field 标签颜色 - `--color-field-text`: field 文本颜色 - `--color-field-placeholder`: field placeholder 颜色 @@ -36,6 +62,9 @@ sidebar_position: 9 - `--color-field-border-hover`: hover 态下,field 边框颜色 - `--color-field-border-active`: active 态下,field 边框颜色 - `--color-field-background`: field 背景色 + +#### 状态颜色 + - `--color-success`: success 颜色 - `--colo-success-dark`: success 颜色(dark) - `--color-success-light`: success 颜色(light) @@ -50,7 +79,9 @@ sidebar_position: 9 - `--color-error-light`: error 颜色(light) - `--color-purple`: purple 颜色 - `--color-brown`: brown 颜色 -- `--color-pane-background`: 面板背景色 + +#### 区块背景色 + - `--color-block-background-normal`: 区块背景色 - `--color-block-background-light`: 区块背景色(light), 作用于画布组件 hover 时遮罩背景色。 - `--color-block-background-shallow`: 区块背景色 shallow @@ -61,20 +92,30 @@ sidebar_position: 9 - `--color-block-background-error`: 区块背景色(error) - `--color-block-background-success`: 区块背景色(success) - `--color-block-background-deep-dark`: 区块背景色(deep-dark),作用于多个组件同时拖拽的背景色。 + +#### 其他区域背景色 + - `--color-layer-mask-background`: 拖拽元素时,元素原来位置的遮罩背景色 - `--color-layer-tooltip-background`: tooltip 背景色 +- `--color-pane-background`: 面板背景色 - `--color-background`: 设计器主要背景色 - `--color-top-area-background`: topArea 背景色,优先级大于 `--color-pane-background` - `--color-left-area-background`: leftArea 背景色,优先级大于 `--color-pane-background` +- `--color-toolbar-background`: toolbar 背景色,优先级大于 `--color-pane-background` - `--color-workspace-left-area-background`: 应用级 leftArea 背景色,优先级大于 `--color-pane-background` - `--color-workspace-top-area-background`: 应用级 topArea 背景色,优先级大于 `--color-pane-background` - `--color-workspace-sub-top-area-background`: 应用级二级 topArea 背景色,优先级大于 `--color-pane-background` + +#### 其他变量 + - `--workspace-sub-top-area-height`: 应用级二级 topArea 高度 - `--workspace-sub-top-area-margin`: 应用级二级 topArea margin - `--workspace-sub-top-area-padding`: 应用级二级 topArea padding - `--workspace-left-area-width`: 应用级 leftArea width -### 生态使用主题色变量 + + +### 低代码引擎生态主题色定制 插件、物料、设置器等生态为了支持主题色需要对样式进行改造,需要对生态中的样式升级为 css 变量。例如: @@ -87,6 +128,8 @@ background: var(--color-brand, #006cff); ``` +这里 `var(--color-brand, #默认色)` 表示使用 `--color-brand` 变量,如果该变量未定义,则使用默认颜色(#默认色)。 + ### fusion 物料进行主题色扩展 -如果使用了 fusion 组件,可以通过 https://fusion.alibaba-inc.com/ 平台进行主题色定制。 \ No newline at end of file +如果使用了 fusion 组件时,可以通过 [fusion 平台](https://fusion.design/) 进行主题色定制。在平台上,您可以选择不同的主题颜色,并直接应用于您的 fusion 组件,这样可以无缝地集成到您的应用设计中。 \ No newline at end of file diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index eb86bfe04c..1f0eae8ec8 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -366,7 +366,7 @@ body { .lc-toolbar { display: flex; height: var(--toolbar-height); - background-color: var(--color-pane-background); + background-color: var(--color-toolbar-background, var(--color-pane-background)); padding: 8px 16px; .lc-toolbar-center { display: flex; From d703e64ac958de5e91d34f4741b49b94a6b467ea Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Wed, 29 Nov 2023 11:10:29 +0800 Subject: [PATCH 207/361] chore(docs): publish docs 1.2.3 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index e9d5b87b43..00887a7588 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.2", + "version": "1.2.3", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 19bf6ad28456feab9b58de3a00023898c72d8fde Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 29 Nov 2023 11:29:33 +0800 Subject: [PATCH 208/361] style: add --color-toolbar-background --- packages/editor-skeleton/src/layouts/workbench.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 1f0eae8ec8..2cddb25372 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -452,7 +452,7 @@ body { .lc-toolbar { display: flex; height: var(--toolbar-height); - background-color: var(--color-pane-background); + background-color: var(--color-toolbar-background, var(--color-pane-background)); padding: 8px 16px; .lc-toolbar-center { display: flex; From 1a328bd1f63a27074ba4b07c9b866ef85038e6e2 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 30 Nov 2023 17:36:55 +0800 Subject: [PATCH 209/361] style: fix --workspace-left-area-width style bug --- docs/docs/guide/expand/editor/theme.md | 1 + packages/editor-skeleton/src/layouts/workbench.less | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index 16bcf04b09..35a77f2ac6 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -112,6 +112,7 @@ sidebar_position: 9 - `--workspace-sub-top-area-margin`: 应用级二级 topArea margin - `--workspace-sub-top-area-padding`: 应用级二级 topArea padding - `--workspace-left-area-width`: 应用级 leftArea width +- `--left-area-width`: leftArea width diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 2cddb25372..565b6f07d7 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -443,6 +443,10 @@ body { min-height: 0; position: relative; + > .lc-left-float-pane { + left: calc(var(--workspace-left-area-width, var(--left-area-width)) + 1px); + } + .lc-workspace-workbench-center { flex: 1; display: flex; From 8f5ba69813bf4cf1a3b084c2a1eb24f2dbc8be35 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 1 Dec 2023 14:23:29 +0800 Subject: [PATCH 210/361] docs: add meet docs --- docs/docs/participate/meet.md | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 docs/docs/participate/meet.md diff --git a/docs/docs/participate/meet.md b/docs/docs/participate/meet.md new file mode 100644 index 0000000000..23226bf1cd --- /dev/null +++ b/docs/docs/participate/meet.md @@ -0,0 +1,55 @@ +--- +title: 开源社区例会 +sidebar_position: 0 +--- + +## **简介** + +低代码引擎开源社区致力于共同推动低代码技术的发展和创新。本社区汇集了低代码技术领域的开发者、技术专家和行业观察者,通过定期的例会来交流思想、分享经验、讨论新技术,并探索低代码技术的未来发展方向。 + +## 参与要求 + +为了确保例会的质量和效果,我们建议以下人员参加: + +- **已参与低代码引擎贡献的成员**:那些对低代码引擎有实际贡献的社区成员。 +- **参考贡献指南**:可查阅[贡献指南](https://lowcode-engine.cn/site/docs/participate/)获取更多信息。 +- **提供过优秀建议的成员**:那些在过去为低代码引擎提供过有价值建议的成员。 + +## **时间周期** + +- **周期性**:月例会 + +### **特别说明** + +- 例会周期可根据成员反馈进行调整。如果讨论的议题较多,可增加例会频率;若议题较少,单次例会可能取消。若多次取消,可能会暂停例会。 + +## **例会流程** + +### **准备阶段** + +- **定期确定议题**:会前一周确定下一次会议的议题。 +- **分发会议通知**:提前发送会议时间、议程和参与方式。 + +### **会议阶段** + +- **开场和介绍**:简短开场和自我介绍,特别是新成员加入时。 +- **议题讨论**:按照议程进行议题讨论,每个议题分配一定时间,并留足够时间供讨论和提问。 +- **记录要点和决定**:记录讨论要点、决策和任何行动事项。 + +### **后续阶段** + +- **分享会议纪要**:会后将会议纪要和行动计划分发给所有成员。 +- **执行和跟进**:根据会议中的讨论和决策执行相关任务,并在下次会议中进行跟进汇报。 + +## **开源例会议题** + +开源例会议题包括但不限于: + +- **共建低代码行业发展**:探讨通过开源社区合作加速低代码行业发展。 +- **改进建议和反馈收集**:讨论社区成员对低代码引擎的使用体验和改进建议。 +- **前端技术与低代码的结合**:针对前端开发者,讨论将前端技术与低代码引擎结合的方式。 +- **低代码业务场景和经验分享**:邀请社区成员分享低代码引擎的实际应用经验。 +- **低代码技术原理介绍**:深入理解低代码引擎的技术原理和实现方式。 +- **低代码引擎的最新进展**:分享低代码引擎的最新进展,包括新版本发布和新功能实现等。 +- **低代码技术的未来展望**:讨论低代码技术的未来发展方向。 +- **最新低代码平台功能和趋势分析**:分享和讨论当前低代码平台的新功能、趋势和发展方向。 \ No newline at end of file From ebdcc4146135ae3d41c8cf79024e9247238a8c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Fri, 1 Dec 2023 15:27:30 +0800 Subject: [PATCH 211/361] fix: scope props merge defaultProps (#2716) --- packages/renderer-core/src/renderer/base.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index f6930e86d5..9d9e88ab59 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -429,7 +429,14 @@ export default function baseRendererFactory(): IBaseRenderComponent { __createDom = () => { const { __schema, __ctx, __components = {} } = this.props; - const scope: any = {}; + // merge defaultProps + const scopeProps = { + ...__schema.defaultProps, + ...this.props, + }; + const scope: any = { + props: scopeProps, + }; scope.__proto__ = __ctx || this; const _children = getSchemaChildren(__schema); From 4d03610fd3b6d056fa7ce35f127cf7a90f99dd6c Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 30 Nov 2023 20:38:12 +0800 Subject: [PATCH 212/361] feat: update types define --- packages/types/src/shell/type/plugin-config.ts | 4 ++-- packages/types/src/shell/type/resource-type-config.ts | 3 ++- packages/types/src/shell/type/resource-type.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/types/src/shell/type/plugin-config.ts b/packages/types/src/shell/type/plugin-config.ts index e9e65192e0..2d841dd804 100644 --- a/packages/types/src/shell/type/plugin-config.ts +++ b/packages/types/src/shell/type/plugin-config.ts @@ -1,5 +1,5 @@ export interface IPublicTypePluginConfig { - init(): Promise<void>; - destroy?(): Promise<void>; + init(): Promise<void> | void; + destroy?(): Promise<void> | void; exports?(): any; } diff --git a/packages/types/src/shell/type/resource-type-config.ts b/packages/types/src/shell/type/resource-type-config.ts index 474987b529..01b49aa2bd 100644 --- a/packages/types/src/shell/type/resource-type-config.ts +++ b/packages/types/src/shell/type/resource-type-config.ts @@ -1,3 +1,4 @@ +import React from 'react'; import { IPublicTypeEditorView } from './editor-view'; export interface IPublicResourceTypeConfig { @@ -6,7 +7,7 @@ export interface IPublicResourceTypeConfig { description?: string; /** 资源 icon 标识 */ - icon?: React.ReactElement; + icon?: React.ReactElement | React.FunctionComponent | React.ComponentClass; /** * 默认视图类型 diff --git a/packages/types/src/shell/type/resource-type.ts b/packages/types/src/shell/type/resource-type.ts index 7cfb125aaf..7d64a4463d 100644 --- a/packages/types/src/shell/type/resource-type.ts +++ b/packages/types/src/shell/type/resource-type.ts @@ -4,7 +4,7 @@ import { IPublicResourceTypeConfig } from './resource-type-config'; export interface IPublicTypeResourceType { resourceName: string; - resourceType: 'editor' | 'webview'; + resourceType: 'editor' | 'webview' | string; (ctx: IPublicModelPluginContext, options: Object): IPublicResourceTypeConfig; } \ No newline at end of file From 70845a1eca349c5786101119537ff9664fbe9056 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 5 Dec 2023 09:32:21 +0800 Subject: [PATCH 213/361] chore(docs): publish docs 1.2.4 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 00887a7588..d5d42cf96d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.3", + "version": "1.2.4", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 0a50cf5a0d351fd3f140f4893140193f6aa5231c Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 5 Dec 2023 13:05:08 +0800 Subject: [PATCH 214/361] docs: update participate docs --- docs/docs/participate/config.md | 88 -------------------- docs/docs/participate/doc.md | 25 ------ docs/docs/participate/index.md | 133 ++++++++++++++++++++++++++----- docs/docs/participate/prepare.md | 64 --------------- 4 files changed, 114 insertions(+), 196 deletions(-) delete mode 100644 docs/docs/participate/config.md delete mode 100644 docs/docs/participate/doc.md delete mode 100644 docs/docs/participate/prepare.md diff --git a/docs/docs/participate/config.md b/docs/docs/participate/config.md deleted file mode 100644 index 1d70a7a89e..0000000000 --- a/docs/docs/participate/config.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: 工程化配置 -sidebar_position: 3 ---- -目前引擎体系共包含 2 个 js 文件 (配套 2 个 css),即: - - -```html -<!-- 低代码引擎的页面框架样式 --> -<link rel="stylesheet" href="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/css/engine-core.css" /> -<!-- 低代码引擎官方扩展的样式 --> -<link rel="stylesheet" href="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/css/engine-ext.css" /> - -<!-- 低代码引擎的主包 --> -<script crossorigin="anonymous" src="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js"></script> -<!-- 低代码引擎官方扩展的主包 --> -<script crossorigin="anonymous" src="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/js/engine-ext.js"></script> -``` - -> 注,这里的版本号是示例,请尽量选用最新版 - -工程化配置我们进行了统一,具体如下: -```shell -{ - "entry": { - ... - }, - "library": "...", - "libraryTarget": "umd", - "externals": { - "react": "var window.React", - "react-dom": "var window.ReactDOM", - "prop-types": "var window.PropTypes", - "@alilc/lowcode-engine": "var window.AliLowCodeEngine", - "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", - "moment": "var moment", - "lodash": "var _", - "@alifd/next": "var Next" - }, - "polyfill": false, - "outputDir": "dist", - "vendor": false, - "ignoreHtmlTemplate": true, - "sourceMap": true, - "plugins": [ - "build-plugin-react-app", - ["build-plugin-fusion", { - }], - ["build-plugin-moment-locales", { - "locales": ["zh-CN"] - }], - "./build.plugin.js" - ] -} - -``` -总结一下,有 2 点: - -1. **都不包含 polyfill,**需要应用级别单独引入 polyfill,推荐动态 polyfill -2. **都不包含 lodash / moment / next** - - -#### 前置依赖资源: -```html -<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.20.25/next.min.css"> - -<script src="//polyfill.alicdn.com/s/polyfill.min.js?features=default,es2017,es6,fetch,RegeneratorRuntime"></script> -<script src="//alifd.alicdn.com/npm/@alifd/next/1.20.25/next.min.js"></script> -<script src="//g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"></script> -<script src="//g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"></script> -``` - - -#### 所有资源: -```html -<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.20.25/next.min.css"> -<link rel="stylesheet" href="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/css/engine-core.css"/> -<link rel="stylesheet" href="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.5/dist/css/engine-ext.css"/> - -<script src="//polyfill.alicdn.com/s/polyfill.min.js?features=default,es2017,es6,fetch,RegeneratorRuntime"></script> -<script src="//alifd.alicdn.com/npm/@alifd/next/1.20.25/next.min.js"></script> -<script src="//g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"></script> -<script src="//g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"></script> -<!-- engine-core 引擎的 core,负责引擎的基础模块 --> -<script crossorigin="anonymous" src="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js"></script> -<!-- engine-ext 引擎的扩展包,负责收拢内置 setters / plugins,方便迭代 --> -<script crossorigin="anonymous" src="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.5/dist/js/engine-ext.js"></script> -``` diff --git a/docs/docs/participate/doc.md b/docs/docs/participate/doc.md deleted file mode 100644 index 1e19918db5..0000000000 --- a/docs/docs/participate/doc.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 参与文档贡献 -sidebar_position: 3 ---- - -## 基本原则 - -### 维护方式 - -- 官方文档通过 github 管理文档源,官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 -- 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。 -- 欢迎 PR,文档 PR 也会作为贡献者贡献,会用于贡献度统计。 -- **文档同步到官方网站由官方人员进行操作**,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 -- 为了提供更好的阅读和使用体验,文档中的图片文件会定期转换成可信的 CDN 地址。 - -### PR 提交注意事项 - -- 指向 develop 分支。 -- 涉及到图片的,需附在文档同级的 img 目录下,通过相对地址引用。 - -### 文档格式 - -本项目文档参考[文档编写指南](https://github.com/sparanoid/chinese-copywriting-guidelines)。 - -使用 vscode 进行编辑的朋友可以安装 vscode 插件 [huacnlee.autocorrect](https://github.com/huacnlee/autocorrect) 辅助文档 lint。 diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md index ea87651ffd..4540fa640d 100644 --- a/docs/docs/participate/index.md +++ b/docs/docs/participate/index.md @@ -1,31 +1,126 @@ --- -title: 贡献者指南 +title: 参与贡献 sidebar_position: 0 --- -### 首个 Pull Request -在写第一个 Pull Request?你可以从这一系列视频中学习怎么做: -[How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) -为了使你能够快速上手和熟悉贡献流程,我们这里有个列表 [good first issues](https://github.com/alibaba/lowcode-engine/issues?q=is:open+is:issue+label:%22good+first+issue%22),里面有相对没那么笼统的漏洞,从这开始是个不错的选择。 +### 环境准备 + +开发 LowcodeEngine 需要 Node.js 16+。 + +推荐使用 nvm 管理 Node.js,避免权限问题的同时,还能够随时切换当前使用的 Node.js 的版本。 + +### 贡献低代码引擎 + +#### clone 项目 + +``` +git clone git@github.com:alibaba/lowcode-engine.git +cd lowcode-engine +``` + +#### 安装依赖并构建 + +``` +npm install && npm run setup +``` + +#### 调试环境配置 + +本质上是将 demo 页面引入的几个 js/css 代理到 engine 项目,可以使用趁手的代理工具,这里推荐 [XSwitch](https://chrome.google.com/webstore/detail/xswitch/idkjhjggpffolpidfkikidcokdkdaogg?hl=en-US)。 + +本地开发代理规则如下: +```json +{ + "proxy": [ + [ + "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/engine-core.js", + "http://localhost:5555/js/AliLowCodeEngine.js" + ], + [ + "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/engine-core.css", + "http://localhost:5555/css/AliLowCodeEngine.css" + ], + [ + "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/react-simulator-renderer.js", + "http://localhost:5555/js/ReactSimulatorRenderer.js" + ], + [ + "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/react-simulator-renderer.css", + "http://localhost:5555/css/ReactSimulatorRenderer.css" + ], + [ + "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/rax-simulator-renderer.js", + "http://localhost:5555/js/RaxSimulatorRenderer.js" + ], + [ + "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/rax-simulator-renderer.css", + "http://localhost:5555/css/RaxSimulatorRenderer.css" + ], + ] +} +``` + +#### 开发 + +``` +npm start +``` + +选择一个环境进行调试,例如[低代码引擎在线 DEMO](https://lowcode-engine.cn/demo/demo-general/index.html) + +开启代理之后,就可以进行开发调试了。 -如果你想解决一个 issue,请确定检查了该 issue 下的评论以防有人正在处理它。如果目前没人在处理该 issue,那么请留下评论去表明你想处理该 issue 以便其他人不会意外重复你的工作。 -如果有人留言表明要处理该 issue 但是超过两周没有跟进,你可以接手工作,不过也应该留言说明。 +### 贡献低代码引擎文档 -### 提交 Pull Request -核心团队时刻关注 pull requests,我们会先评审你的 pull request,之后可能会合并,可能会要求再次更改,也可能会关闭该 pull request 并对此作出解释。我们会尽力全程更新和反馈。 +#### 开发文档 -**提交 pull request 前**,请确保完成以下步骤: +在 lowcode-engine 目录下执行下面命令 +``` +cd docs -1. Fork [此仓库](https://github.com/alibaba/lowcode-engine),从 main 创建分支。 -2. 在仓库根目录下执行 yarn。 -3. 如果你修复了 bug 或者添加了代码,而这些内容需要测试,请添加测试! -4. 确保通过测试套件(yarn test)。 -5. 请签订贡献者许可证协议(Contributor License Agreement)。 - > 如已签署 CLA 仍被提示需要签署,[解决办法](/site/docs/faq/faq021) +npm start +``` -### 核心贡献者交流 -如果你想长期参与到项目维护中,我们提供了一个核心贡献者交流群。 +#### 维护方式 +- 官方文档通过 github 管理文档源,官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 +- 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。 +- 欢迎 PR,文档 PR 也会作为贡献者贡献,会用于贡献度统计。 +- **文档同步到官方网站由官方人员进行操作**,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 +- 为了提供更好的阅读和使用体验,文档中的图片文件会定期转换成可信的 CDN 地址。 + +#### 文档格式 + +本项目文档参考[文档编写指南](https://github.com/sparanoid/chinese-copywriting-guidelines)。 + +使用 vscode 进行编辑的朋友可以安装 vscode 插件 [huacnlee.autocorrect](https://github.com/huacnlee/autocorrect) 辅助文档 lint。 + + +### 贡献低代码引擎生态 + +相关源码详见[NPM 包对应源码位置汇总](/site/docs/guide/appendix/npms) + +开发调试方式详见[低代码生态脚手架 & 调试机制](/site/docs/guide/expand/editor/cli) + +### 发布 + +PR 被合并之后,我们会尽快发布相关的正式版本或者 beta 版本。 + +### 加入 Contributor 群 +提交过 Bugfix 或 Feature 类 PR 的同学,如果有兴趣一起参与维护 LowcodeEngine,我们提供了一个核心贡献者交流群。 1. 可以通过[填写问卷](https://survey.taobao.com/apps/zhiliao/4YEtu9gHF)的方式,参与到其中。 -2. 填写问卷后加微信号 `wxidvlalalalal` 说明一下。 +2. 填写问卷后加微信号 `wxidvlalalalal` (注明 github id)我们会拉你到群里。 + +如果你不知道可以贡献什么,可以到源码里搜 TODO 或 FIXME 找找。 + +为了使你能够快速上手和熟悉贡献流程,我们这里有个列表 [good first issues](https://github.com/alibaba/lowcode-engine/issues?q=is:open+is:issue+label:%22good+first+issue%22),里面有相对没那么笼统的漏洞,从这开始是个不错的选择。 + +### PR 提交注意事项 + +- lowcode-engine 仓库建议从 develop 创建分支,PR 指向 develop 分支。 +- 其他仓库从 main 分支创建分支,PR 指向 main 分支 +- 如果你修复了 bug 或者添加了代码,而这些内容需要测试,请添加测试! +- 确保通过测试套件(yarn test)。 +- 请签订贡献者许可证协议(Contributor License Agreement)。 + > 如已签署 CLA 仍被提示需要签署,[解决办法](/site/docs/faq/faq021) \ No newline at end of file diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md deleted file mode 100644 index acb0947f22..0000000000 --- a/docs/docs/participate/prepare.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 调试环境配置 -sidebar_position: 1 ---- -低代码引擎的核心仓库是不包含任何物料、插件、setter 的,它本身用于生成低代码引擎的主包。 - -如果您需要对低代码的主包进行开发和调试,需要用到本文里介绍的知识。 - -如果您需要对低代码编辑器进行定制,您可能只需要 clone [lowcode-demo 项目](https://github.com/alibaba/lowcode-demo)并进行修改,参考“[配置低代码扩展点](/site/docs/guide/expand/editor/summary)”章节。 - -> 前置条件: -> node 推荐使用 16.18.0(14.x 也可以) - -### 1. 拉取代码,启动项目 -```bash -git clone git@github.com:alibaba/lowcode-engine.git -cd lowcode-engine -npm install && npm run setup -npm start - - -git clone git@github.com:alibaba/lowcode-demo.git -cd lowcode-demo -npm install && npm start -``` - -### 2. 配置资源代理 -本质上是将 demo 页面引入的几个 js/css 代理到 engine 项目,可以使用趁手的代理工具,这里推荐 [XSwitch](https://chrome.google.com/webstore/detail/xswitch/idkjhjggpffolpidfkikidcokdkdaogg?hl=en-US)。 - -本地开发代理规则如下: -```json -{ - "proxy": [ - [ - "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/engine-core.js", - "http://localhost:5555/js/AliLowCodeEngine.js" - ], - [ - "https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/engine-core.css", - "http://localhost:5555/css/AliLowCodeEngine.css" - ], - [ - "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/react-simulator-renderer.js", - "http://localhost:5555/js/ReactSimulatorRenderer.js" - ], - [ - "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/react-simulator-renderer.css", - "http://localhost:5555/css/ReactSimulatorRenderer.css" - ], - [ - "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/rax-simulator-renderer.js", - "http://localhost:5555/js/RaxSimulatorRenderer.js" - ], - [ - "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/rax-simulator-renderer.css", - "http://localhost:5555/css/RaxSimulatorRenderer.css" - ], - ] -} -``` - -### 3. 本地调试物料/插件/设置器 - -详见[低代码生态脚手架 & 调试机制](/site/docs/guide/expand/editor/cli) From 28fdf9a37d04fc4c5d942aca4f87511bb0f901fe Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Tue, 5 Dec 2023 13:29:16 +0800 Subject: [PATCH 215/361] chore(docs): publish docs 1.2.5 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index d5d42cf96d..75704e688c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.4", + "version": "1.2.5", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From a87dcaada18eb28d0b67fa99e4ab82ca1d552d7d Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 5 Dec 2023 15:25:28 +0800 Subject: [PATCH 216/361] chore: create publish docs.yml --- .github/workflows/publish docs.yml | 51 ++++++++++++++++++++++++++++++ docs/package.json | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish docs.yml diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml new file mode 100644 index 0000000000..dcbeec3844 --- /dev/null +++ b/.github/workflows/publish docs.yml @@ -0,0 +1,51 @@ +name: Update and Publish Docs + +on: + push: + branches: + - develop + paths: + - 'docs/**' + +jobs: + publish-docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + registry-url: 'https://registry.npmjs.org' + - run: cd docs && npm install + - run: | + cd docs + npm version patch + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add package.json + git commit -m "Update package version" + git push + - run: cd docs && npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Get version + id: get_version + run: echo "::set-output name=version::$(node -p "require('./docs/package.json').version")" + + comment-pr: + needs: publish-docs + runs-on: ubuntu-latest + steps: + - name: Comment on PR + if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true + uses: actions/github-script@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: '🚀 New version has been released: ' + '${{ needs.publish-docs.outputs.version }}' + }) \ No newline at end of file diff --git a/docs/package.json b/docs/package.json index 75704e688c..8af810d33e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.5", + "version": "1.2.6", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 77aea1bfbafe4315e8488417d862d820e81dd573 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Tue, 5 Dec 2023 07:29:34 +0000 Subject: [PATCH 217/361] Update package version --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 8af810d33e..634f73bee1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.6", + "version": "1.2.7", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 398f06974571a05af5b03b3d7c651c3f604f5967 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 5 Dec 2023 14:42:28 +0800 Subject: [PATCH 218/361] style: add css themes vars --- docs/docs/guide/expand/editor/theme.md | 11 ++++++++++- .../designer/src/builtin-simulator/host.less | 8 ++++---- packages/editor-skeleton/src/layouts/theme.less | 2 +- .../editor-skeleton/src/layouts/workbench.less | 16 ++++++++-------- .../types/src/shell/type/widget-base-config.ts | 5 +++++ 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index 35a77f2ac6..36500cb458 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -50,7 +50,6 @@ sidebar_position: 9 - `--color-text-dark`: 文字颜色(dark) - `--color-text-light`: 文字颜色(light) - `--color-text-reverse`: 反色情况下,文字颜色 -- `--color-text-regular`: 文字颜色(regular) - `--color-text-disabled`: 禁用态文字颜色 #### 字段和边框颜色 @@ -109,10 +108,20 @@ sidebar_position: 9 #### 其他变量 - `--workspace-sub-top-area-height`: 应用级二级 topArea 高度 +- `--top-area-height`: 顶部区域的高度 - `--workspace-sub-top-area-margin`: 应用级二级 topArea margin - `--workspace-sub-top-area-padding`: 应用级二级 topArea padding - `--workspace-left-area-width`: 应用级 leftArea width - `--left-area-width`: leftArea width +- `--simulator-top-distance`: simulator 距离容器顶部的距离 +- `--simulator-bottom-distance`: simulator 距离容器底部的距离 +- `--simulator-left-distance`: simulator 距离容器左边的距离 +- `--simulator-right-distance`: simulator 距离容器右边的距离 +- `--toolbar-padding`: toolbar 的 padding +- `--toolbar-height`: toolbar 的高度 +- `--pane-title-height`: 面板标题高度 +- `--pane-title-font-size`: 面板标题字体大小 +- `--pane-title-padding`: 面板标题边距 diff --git a/packages/designer/src/builtin-simulator/host.less b/packages/designer/src/builtin-simulator/host.less index 7130c42972..9a00963f24 100644 --- a/packages/designer/src/builtin-simulator/host.less +++ b/packages/designer/src/builtin-simulator/host.less @@ -73,10 +73,10 @@ } &-device-default { - top: 16px; - right: 16px; - bottom: 16px; - left: 16px; + top: var(--simulator-top-distance, 16px); + right: var(--simulator-right-distance, 16px); + bottom: var(--simulator-bottom-distance, 16px); + left: var(--simulator-left-distance, 16px); width: auto; box-shadow: 0 1px 4px 0 var(--color-block-background-shallow, rgba(31, 50, 88, 0.125)); } diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index 716ab3a99e..78c6fa5fd6 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -27,7 +27,6 @@ --color-text-dark: darken(@dark-alpha-3, 10%); --color-text-light: lighten(@dark-alpha-3, 10%); --color-text-reverse: @white-alpha-2; - --color-text-regular: @normal-alpha-2; --color-text-disabled: @gray-light; --color-field-label: @dark-alpha-4; @@ -87,4 +86,5 @@ --color-function-error-light: lighten(@brand-danger, 10%); --color-function-purple: rgb(144, 94, 190); --color-function-brown: #7b605b; + --color-text-regular: @normal-alpha-2; } diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 565b6f07d7..596ea69f60 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -66,16 +66,16 @@ body { } } > .lc-panel-title { - height: 48px; - font-size: 16px; - padding: 0 15px; + height: var(--pane-title-height, 48px); + font-size: var(--pane-title-font-size, 16px); + padding: var(--pane-title-padding, 0 15px); color: var(--color-title, #0f1726); font-weight: bold; } .lc-panel-body { position: absolute; - top: 48px; + top: var(--pane-title-height, 48px); bottom: 0; left: 0; right: 0; @@ -234,7 +234,7 @@ body { .lc-pane-icon-close { position: absolute; right: 16px; - top: 14px; + top: calc(var(--pane-title-height, 48px) / 2 - 10px); height: auto; z-index: 2; .next-icon { @@ -247,7 +247,7 @@ body { .lc-pane-icon-float { position: absolute; right: 38px; - top: 14px; + top: calc(var(--pane-title-height, 48px) / 2 - 10px); height: auto; z-index: 2; svg { @@ -367,7 +367,7 @@ body { display: flex; height: var(--toolbar-height); background-color: var(--color-toolbar-background, var(--color-pane-background)); - padding: 8px 16px; + padding: var(--toolbar-padding, 8px 16px); .lc-toolbar-center { display: flex; justify-content: center; @@ -457,7 +457,7 @@ body { display: flex; height: var(--toolbar-height); background-color: var(--color-toolbar-background, var(--color-pane-background)); - padding: 8px 16px; + padding: var(--toolbar-padding, 8px 16px); .lc-toolbar-center { display: flex; justify-content: center; diff --git a/packages/types/src/shell/type/widget-base-config.ts b/packages/types/src/shell/type/widget-base-config.ts index edddf2d68f..b23ba0f137 100644 --- a/packages/types/src/shell/type/widget-base-config.ts +++ b/packages/types/src/shell/type/widget-base-config.ts @@ -15,6 +15,11 @@ export interface IPublicTypeWidgetBaseConfig { props?: Record<string, any>; content?: any; contentProps?: Record<string, any>; + + /** + * 优先级,值越小,优先级越高,优先级高的会排在前面 + */ + index?: number; } export interface IPublicTypePanelDockConfig extends IPublicTypeWidgetBaseConfig { From 3786b3a7ff09c4223f0b84fc15da58356c123694 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Tue, 5 Dec 2023 07:38:51 +0000 Subject: [PATCH 219/361] Update package version --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 634f73bee1..f175552e54 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.7", + "version": "1.2.8", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 1f214918bb5ce4d03132b78081eb63c815b0c347 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 7 Dec 2023 11:03:07 +0800 Subject: [PATCH 220/361] style: add css themes vars --- docs/docs/guide/expand/editor/theme.md | 8 +++++++- .../designer/src/builtin-simulator/bem-tools/borders.less | 2 +- packages/editor-skeleton/src/layouts/theme.less | 8 ++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index 36500cb458..ef0e04d28d 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -35,6 +35,7 @@ sidebar_position: 9 #### Icon 相关颜色 - `--color-icon-normal`: 默认状态 +- `--color-icon-light`: icon light 状态 - `--color-icon-hover`: 鼠标悬停状态 - `--color-icon-active`: 激活状态 - `--color-icon-reverse`: 反色状态 @@ -82,16 +83,21 @@ sidebar_position: 9 #### 区块背景色 - `--color-block-background-normal`: 区块背景色 -- `--color-block-background-light`: 区块背景色(light), 作用于画布组件 hover 时遮罩背景色。 +- `--color-block-background-light`: 区块背景色(light)。 - `--color-block-background-shallow`: 区块背景色 shallow - `--color-block-background-dark`: 区块背景色(dark) - `--color-block-background-disabled`: 区块背景色(disabled) - `--color-block-background-active`: 区块背景色(active) +- `--color-block-background-active-light`: 区块背景色(active light) - `--color-block-background-warning`: 区块背景色(warning) - `--color-block-background-error`: 区块背景色(error) - `--color-block-background-success`: 区块背景色(success) - `--color-block-background-deep-dark`: 区块背景色(deep-dark),作用于多个组件同时拖拽的背景色。 +#### 引擎相关颜色 + +- `--color-canvas-detecting-background`: 画布组件 hover 时遮罩背景色。 + #### 其他区域背景色 - `--color-layer-mask-background`: 拖拽元素时,元素原来位置的遮罩背景色 diff --git a/packages/designer/src/builtin-simulator/bem-tools/borders.less b/packages/designer/src/builtin-simulator/bem-tools/borders.less index 43fba6a2b8..cb83d36f38 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/borders.less +++ b/packages/designer/src/builtin-simulator/bem-tools/borders.less @@ -100,7 +100,7 @@ &&-detecting { z-index: 1; border-style: dashed; - background: var(--color-block-background-light, rgba(0,121,242,.04)); + background: var(--color-canvas-detecting-background, rgba(0,121,242,.04)); } &&-selecting { diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index 78c6fa5fd6..01542c7584 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -14,6 +14,7 @@ --color-icon-normal: @normal-alpha-4; --color-icon-hover: @normal-alpha-3; + --color-icon-light: @normal-alpha-5; --color-icon-active: @brand-color-1; --color-icon-reverse: @white-alpha-1; --color-icon-disabled: @normal-alpha-6; @@ -55,10 +56,11 @@ --color-pane-background: @white-alpha-1; --color-block-background-normal: @white-alpha-1; --color-block-background-light: @normal-alpha-9; - --color-block-background-shallow: @normal-alpha-8; --color-block-background-dark: @normal-alpha-7; + --color-block-background-shallow: @normal-alpha-8; --color-block-background-disabled: @normal-alpha-6; - --color-block-background-active: @brand-color-1-7; + --color-block-background-active: @brand-color-1; + --color-block-background-active-light: @brand-color-1-7; --color-block-background-warning: @brand-warning-alpha-7; --color-block-background-error: @brand-danger-alpha-7; --color-block-background-success: @brand-success-alpha-7; @@ -67,6 +69,8 @@ --color-layer-tooltip-background: rgba(44,47,51,0.8); --color-background: #edeff3; + --color-canvas-detecting-background: rgba(0,121,242,.04); + --pane-title-bg-color: rgba(31,56,88,.04); } From 6932c3bdc7def44a7db971672469c18e5fbc2e63 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 7 Dec 2023 05:49:17 +0000 Subject: [PATCH 221/361] Update package version --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index f175552e54..a1b6d646f5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.8", + "version": "1.2.9", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 014834a31f1ebbcfb21c8993534046d753540b99 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 13 Dec 2023 12:16:28 +0800 Subject: [PATCH 222/361] style(outline): update outline-filter-icon style --- packages/plugin-outline-pane/src/views/style.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index 15f115ea6b..8521883b49 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -28,7 +28,7 @@ } .lc-outline-filter-icon { - background: var(--color-block-background-shallow, #ebecf0); + background: var(--color-block-background-light, #ebecf0); border: 1px solid var(--color-field-border, #c4c6cf); display: flex; align-items: center; From a0975428c4c7301b9d678cf0c19e6e49c241ee79 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 13 Dec 2023 14:21:59 +0800 Subject: [PATCH 223/361] docs: add faq024 --- docs/docs/faq/faq024.md | 133 ++++++++++++++++++++++++++++++++++++++++ docs/docs/faq/index.md | 1 + 2 files changed, 134 insertions(+) create mode 100644 docs/docs/faq/faq024.md diff --git a/docs/docs/faq/faq024.md b/docs/docs/faq/faq024.md new file mode 100644 index 0000000000..ab1b68f5d7 --- /dev/null +++ b/docs/docs/faq/faq024.md @@ -0,0 +1,133 @@ +--- +title: workspace 模式常见问题 +sidebar_position: 23 +tags: [FAQ] +--- + +#### 如何判断是否开启了IDE模式? + +- **通过官方API判断**:您可以通过访问 [workspace.isActive](/site/docs/api/workspace#isactive) 来判断当前是否处于IDE模式。这是阿里低代码引擎提供的一个官方API,专门用于确认是否处于集成开发环境。 + + + +#### 如何使用插件的ctx来做判断在哪个模式下? + +- **插件是否为应用级别**:可以通过 **ctx.isPluginRegisteredInWorkspace** 方法来判断一个插件是否是应用级别的插件。这有助于理解插件在阿里低代码引擎中的作用域和潜在的使用场景。 +- **插件的注册级别**:您可以使用 **ctx.registerLevel** 属性来判断插件处于哪个级别。插件级别的值包括: + - **Default**:默认级别。非 IDE 模式下的值 + - **Workspace**:应用级别。 + - **Resource**:资源级别。 + - **EditorView**:编辑视图级别。 这些级别代表了插件可能的作用域和使用场景,有助于在开发和管理低代码应用时对插件进行更精确的控制和配置。 + + + +#### 如何在IDE模式下设置资源列表? + +- **设置资源列表API**:在IDE模式下,可以通过访问 [workspace.setResourceList](/site/docs/api/workspace#setresourcelist) 来设置或更新IDE中的资源列表。这确保您在编辑器窗口中打开的资源是最新且可访问的。 + + + +#### 如何打开视图窗口? + +- **使用推荐的方法**:使用 `openEditorWindow(resource: Resource, sleep?: boolean): Promise<void>;` 来打开视图窗口。这里的 **resource** 参数指的是您要打开的特定资源,可通过 [workspace.resourceList](/site/docs/api/workspace#resourcelist) 获取。 +- **不推荐使用的过时方法**:有一个过时的方法 `openEditorWindow(resourceName: string, id: string, extra: Object, viewName?: string, sleep?: boolean): Promise<void>;` 也用于打开视图窗口。虽然仍然可用,但官方不推荐使用此方法,并计划在后续版本中废弃,因为它在维护和可扩展性方面存在限制。 + + + +#### 如何在全局插件中获取视图的上下文? + +- 在阿里低代码引擎的全局插件中获取视图的上下文,可以通过使用 **ProvideViewPluginContext** 函数实现。这个函数来自 **@alilc/lowcode-utils** 库,它使得您的 React 组件能够接收 **pluginContext** 作为 props,进而访问和操作当前视图的状态和属性。 + +**步骤** + +**引入依赖**:首先,确保您的插件文件中已经引入了 **ProvideViewPluginContext** 以及其他必要的依赖。 + +``` +import { ProvideViewPluginContext } from '@alilc/lowcode-utils'; +``` + +**定义 React 组件**:创建一个 React 组件,它将使用来自 **ProvideViewPluginContext** 的 **pluginContext**。 + +```typescript +const MyComponent = (props) => { + const { pluginContext } = props; + // 组件逻辑 + return <div>/* 组件内容 */</div>; +}; +``` + +**定义全局插件**:定义一个函数,这个函数会在插件被注册时调用。这个函数通常接受一个上下文对象 **ctx**,它提供了对引擎功能的访问。 + +```javascript +const globalPlugin = (ctx) => { + const { skeleton } = ctx; + + skeleton.add({ + type: 'PanelDock', + name: 'datapool', + content: ProvideViewPluginContext((props) => { + // 组件内容 + return ( + <MyComponent {...props} /> + ) + }), + // 其他配置 + contentProps: { + // 需要提供 pluginContext 作为参数 + pluginContext: ctx, + } + }); +}; +``` + +通过这些步骤,您的全局插件中的 React 组件就能够获取并使用视图的上下文了。这为您在插件中实现更复杂的功能和交互提供了基础。 + + + +**注意事项** + +- **组件重渲染**:正常情况下,**pluginsContext** 是视图的上下文。当视图切换时,组件会重新渲染。如果需要在组件中处理视图切换导致的重新渲染,可以利用 React 的 **key** 属性。 + +**示例代码** + +```typescript +ProvideViewPluginContext(props => { + return ( + <DataPoolPane + {...props} + key={props.pluginContext?.editorWindow?.id} + ); +}); +``` + +通过这种方式,当视图切换时,组件会根据视图的不同进行重新渲染,确保组件状态与当前视图的上下文保持一致。这对于在低代码平台上开发复杂插件和交互功能是非常有用的。 + + + +#### 如何判断插件是否在 Workspace 模式下注册? + +**使用** **ctx.isPluginRegisteredInWorkspace()** **方法**: + +通过 **ctx.isPluginRegisteredInWorkspace()** 方法,可以判断一个插件是否在 Workspace 级别注册。以下是一个示例代码片段: + +```javascript +if (ctx.isPluginRegisteredInWorkspace('pluginName')) { + console.log('插件已在 Workspace 模式下注册。'); +} else { + console.log('插件未在 Workspace 模式下注册。'); +} +``` + +注意:此方法目前在 beta 版本中,可能会有 TypeScript 提示显示已移除。 + +**检查** **ctx.registerLevel** **的值**: + +可以通过比较 **ctx.registerLevel** 的值来判断插件的注册级别。示例代码如下: + +```javascript +if (ctx.registerLevel !== IPublicEnumPluginRegisterLevel.Workspace) { + console.log('插件未在 Workspace 模式下注册。'); +} else { + console.log('插件已在 Workspace 模式下注册。'); +} +``` diff --git a/docs/docs/faq/index.md b/docs/docs/faq/index.md index 5e5eee8ac4..ef8d7b3b15 100644 --- a/docs/docs/faq/index.md +++ b/docs/docs/faq/index.md @@ -15,6 +15,7 @@ tags: [FAQ] - [如何通过 this.utils 使用第三方工具扩展](/site/docs/faq/faq005) - [设置面板中的高级 tab 如何配置](/site/docs/faq/faq007) - [插件面板如何调整位置](/site/docs/faq/faq010) +- [workspace 模式常见问题](/site/docs/faq/faq024) ## 源码和依赖 - [某某 npm 包对应的源码在哪里?](/site/docs/faq/faq008) From 07ee7e0355bdb251053afdb860bae3c87012b1b9 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Wed, 13 Dec 2023 06:37:30 +0000 Subject: [PATCH 224/361] Update package version --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index a1b6d646f5..eaf87ac219 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.9", + "version": "1.2.10", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 271aef4fb964f2fab74f1a70b020ab679564a10f Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 13 Dec 2023 16:12:15 +0800 Subject: [PATCH 225/361] chore: add publish engine actions --- .github/workflows/publish docs.yml | 2 +- .github/workflows/publish engine beta.yml | 30 +++++++++++++++++++ .github/workflows/publish engine.yml | 26 ++++++++++++++++ package.json | 4 +-- .../src/layouts/workbench.less | 1 + 5 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/publish engine beta.yml create mode 100644 .github/workflows/publish engine.yml diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index dcbeec3844..ed16bb869a 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -5,7 +5,7 @@ on: branches: - develop paths: - - 'docs/**' + - 'docs/docs/**' jobs: publish-docs: diff --git a/.github/workflows/publish engine beta.yml b/.github/workflows/publish engine beta.yml new file mode 100644 index 0000000000..ab498c8df6 --- /dev/null +++ b/.github/workflows/publish engine beta.yml @@ -0,0 +1,30 @@ +name: Update and Publish Docs + +on: + push: + branches: + - 'release/[0-9]+.[0-9]+.[0-9]+-beta' + paths: + - 'packages/**' + +jobs: + publish-engine: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + registry-url: 'https://registry.npmjs.org' + - run: npm install && npm run setup + - run: | + npm run build + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + - run: npm run pub:prerelease + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Get version + id: get_version + run: echo "::set-output name=version::$(node -p "require('./docs/package.json').version")" diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml new file mode 100644 index 0000000000..3710cf816c --- /dev/null +++ b/.github/workflows/publish engine.yml @@ -0,0 +1,26 @@ +name: Update and Publish Docs + +on: + workflow_dispatch: + +jobs: + publish-engine: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + registry-url: 'https://registry.npmjs.org' + - run: npm install && npm run setup + - run: | + npm run build + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + - run: npm run pub + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Get version + id: get_version + run: echo "::set-output name=version::$(node -p "require('./docs/package.json').version")" diff --git a/package.json b/package.json index aded2a3015..caabbeeb13 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,11 @@ "lint:fix": "f2elint fix -i ./packages/*/src", "lint:modules": "f2elint scan -q -i ./modules/*/src", "lint:modules:fix": "f2elint fix -i ./modules/*/src", - "pub": "npm run watchdog:build && lerna publish patch --force-publish --exact --no-changelog", + "pub": "npm run watchdog:build && lerna publish patch --yes --force-publish --exact --no-changelog", "pub:premajor": "npm run watchdog:build && lerna publish premajor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:preminor": "npm run watchdog:build && lerna publish preminor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prepatch": "npm run watchdog:build && lerna publish prepatch --force-publish --exact --dist-tag beta --preid beta --no-changelog", - "pub:prerelease": "npm run watchdog:build && lerna publish prerelease --force-publish --exact --dist-tag beta --preid beta --no-changelog", + "pub:prerelease": "npm run watchdog:build && lerna publish prerelease --yes --force-publish --exact --dist-tag beta --preid beta --no-changelog", "setup": "node ./scripts/setup.js", "setup:test": "./scripts/setup-for-test.sh", "setup:skip-build": "./scripts/setup-skip-build.sh", diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 596ea69f60..97a017523d 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -105,6 +105,7 @@ body { right: 0; bottom: 0; z-index: -1; + overflow: hidden; &.active { z-index: 999; From a25aad4975231706a9e47ba3e62e17034ce18846 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 13 Dec 2023 16:43:51 +0800 Subject: [PATCH 226/361] fix(outline): fix view change bugs in workspace mode --- .github/workflows/publish engine beta.yml | 4 ++-- .github/workflows/publish engine.yml | 4 ++-- packages/plugin-outline-pane/src/controllers/tree-master.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish engine beta.yml b/.github/workflows/publish engine beta.yml index ab498c8df6..32c5b4c15b 100644 --- a/.github/workflows/publish engine beta.yml +++ b/.github/workflows/publish engine beta.yml @@ -1,4 +1,4 @@ -name: Update and Publish Docs +name: Publish Engine Beta on: push: @@ -27,4 +27,4 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version - run: echo "::set-output name=version::$(node -p "require('./docs/package.json').version")" + run: echo "::set-output name=version::$(node -p "require('./package.json').version")" diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml index 3710cf816c..f9206d4cb9 100644 --- a/.github/workflows/publish engine.yml +++ b/.github/workflows/publish engine.yml @@ -1,4 +1,4 @@ -name: Update and Publish Docs +name: Publish Engine on: workflow_dispatch: @@ -23,4 +23,4 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version - run: echo "::set-output name=version::$(node -p "require('./docs/package.json').version")" + run: echo "::set-output name=version::$(node -p "require('./package.json').version")" diff --git a/packages/plugin-outline-pane/src/controllers/tree-master.ts b/packages/plugin-outline-pane/src/controllers/tree-master.ts index ede5f0f5f3..f86ce3deca 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-master.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-master.ts @@ -51,9 +51,9 @@ export class TreeMaster { windowViewTypeChangeEvent(); workspace.onChangeActiveWindow(() => { - windowViewTypeChangeEvent(); this.setPluginContext(workspace.window?.currentEditorView); dispose && dispose(); + windowViewTypeChangeEvent(); }); } } From 2ec9bf7cdf203c3d4cdda8dc4048c44851019028 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?= <liujup@foxmail.com> Date: Wed, 13 Dec 2023 17:05:03 +0800 Subject: [PATCH 227/361] chore: create publish engine.yml --- .github/workflows/publish engine.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/publish engine.yml diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml new file mode 100644 index 0000000000..7c245a3d82 --- /dev/null +++ b/.github/workflows/publish engine.yml @@ -0,0 +1,26 @@ +name: Publish Engine + +on: + workflow_dispatch: + +jobs: + publish-engine: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '16' + registry-url: 'https://registry.npmjs.org' + - run: npm install && npm run setup + - run: | + npm run build + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + - run: npm run pub + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Get version + id: get_version + run: echo "::set-output name=version::$(node -p "require('./package.json').version")" From 3c3a305c7aa00544d1f28084367eb43f3e42b5a1 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 13 Dec 2023 17:22:40 +0800 Subject: [PATCH 228/361] chore: update publish engine.yml --- .github/workflows/publish engine.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml index 7c245a3d82..6825c66fca 100644 --- a/.github/workflows/publish engine.yml +++ b/.github/workflows/publish engine.yml @@ -6,6 +6,9 @@ on: jobs: publish-engine: runs-on: ubuntu-latest + if: >- + contains(github.ref, 'refs/heads/release/') && + (github.actor == 'JackLian' || github.actor == 'liujuping') steps: - uses: actions/checkout@v2 - name: Setup Node.js From 2e604c99109b82d2dc1f447ab1de37f623e3188d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Thu, 23 Nov 2023 18:58:24 +0800 Subject: [PATCH 229/361] Fix/component lifecycle not execute (#2690) * fix: recover component lifecycle and avoid execute from scope __proto__ From c3d0ffb62cd03d81f4fc46d01b1714eb1dd79a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Thu, 23 Nov 2023 19:28:41 +0800 Subject: [PATCH 230/361] Fix/component lifecycle not execute (#2692) * fix: recover component lifecycle and avoid execute from scope __proto__ From f418e5b2c18ddb5299a575f0888ad67de642bcf2 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Wed, 13 Dec 2023 09:34:24 +0000 Subject: [PATCH 231/361] chore(release): publish 1.2.3 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 34be89faa8..98ef80f138 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.2.2", + "version": "1.2.3", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 69a402ed22..e961451d88 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.2.2", + "version": "1.2.3", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.2.2", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-editor-core": "1.2.3", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index de9d30bc8b..345783c806 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.2.2", + "version": "1.2.3", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index fe2d0d43ff..fa5c1e13e6 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.2.2", + "version": "1.2.3", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-editor-core": "1.2.2", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-editor-core": "1.2.3", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 3ea47f79da..c9eef3534c 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.2.2", + "version": "1.2.3", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-editor-core": "1.2.2", - "@alilc/lowcode-editor-skeleton": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-editor-core": "1.2.3", + "@alilc/lowcode-editor-skeleton": "1.2.3", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.2.2", - "@alilc/lowcode-plugin-outline-pane": "1.2.2", - "@alilc/lowcode-shell": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", - "@alilc/lowcode-workspace": "1.2.2", + "@alilc/lowcode-plugin-designer": "1.2.3", + "@alilc/lowcode-plugin-outline-pane": "1.2.3", + "@alilc/lowcode-shell": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-workspace": "1.2.3", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index d737a7c868..71a21484c4 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.2.2", + "version": "1.2.3", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index fe653568bb..500c0c9611 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.2.2", + "version": "1.2.3", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-editor-core": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-editor-core": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 2540ca5ad4..5a2ef38a45 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.2.2", + "version": "1.2.3", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 60ea0c6981..837aebc85e 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.2.2", + "version": "1.2.3", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-renderer-core": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 520ff32c89..dc9b7b1478 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.2.2", + "version": "1.2.3", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-rax-renderer": "1.2.2", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-rax-renderer": "1.2.3", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index a35039fc3c..1dceb9c2e7 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.2.2", + "version": "1.2.3", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.2.2" + "@alilc/lowcode-renderer-core": "1.2.3" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 413b1825f8..8935c92eef 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.2.2", + "version": "1.2.3", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-react-renderer": "1.2.2", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-react-renderer": "1.2.3", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 3b96ef40b3..4774ae3689 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.2.2", + "version": "1.2.3", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 7e20192352..2ebf14bbc2 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.2.2", + "version": "1.2.3", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-editor-core": "1.2.2", - "@alilc/lowcode-editor-skeleton": "1.2.2", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", - "@alilc/lowcode-workspace": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-editor-core": "1.2.3", + "@alilc/lowcode-editor-skeleton": "1.2.3", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-workspace": "1.2.3", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index c4fa290036..c0b8e203fe 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.2.2", + "version": "1.2.3", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index af76e9e2f6..00efffb8d3 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.2.2", + "version": "1.2.3", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.2", + "@alilc/lowcode-types": "1.2.3", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 4724323797..8c09a93b6c 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.2.2", + "version": "1.2.3", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.2", - "@alilc/lowcode-editor-core": "1.2.2", - "@alilc/lowcode-editor-skeleton": "1.2.2", - "@alilc/lowcode-types": "1.2.2", - "@alilc/lowcode-utils": "1.2.2", + "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-editor-core": "1.2.3", + "@alilc/lowcode-editor-skeleton": "1.2.3", + "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-utils": "1.2.3", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From f2d8fca18840cfaaa531219b0cb430294d99f01a 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?= <liujup@foxmail.com> Date: Thu, 14 Dec 2023 09:55:14 +0800 Subject: [PATCH 232/361] docs: update workspace.md --- docs/docs/api/workspace.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 9911dc93ad..6d0714ae09 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -87,7 +87,7 @@ registerResourceType(resourceTypeModel: IPublicTypeResourceType): void; setResourceList(resourceList: IPublicResourceList) {} ``` -相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts) +相关类型:[IPublicResourceData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-list.ts) ### openEditorWindow From c0ddba5543d7fee9735445774806396fec82fdfc Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 14 Dec 2023 02:15:38 +0000 Subject: [PATCH 233/361] Update package version --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index eaf87ac219..3c43bff657 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.10", + "version": "1.2.11", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 27bf7babe53ac07bf165832cd4eb55f4aafcf37c Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 10:16:30 +0800 Subject: [PATCH 234/361] chore: use tnpm as oss-syncing source --- scripts/sync-oss.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/sync-oss.js b/scripts/sync-oss.js index ba4a77be37..2108e676d2 100644 --- a/scripts/sync-oss.js +++ b/scripts/sync-oss.js @@ -19,7 +19,7 @@ const onResponse = function (res) { chunks.push(chunk); }); - res.on('end', (chunk) => { + res.on('end', () => { const body = Buffer.concat(chunks); console.table(JSON.stringify(JSON.parse(body.toString()), null, 2)); }); @@ -39,9 +39,9 @@ const postData = JSON.stringify({ }, ], // 可以发布指定源的 npm 包,默认公网 npm - useTnpm: false, + useTnpm: true, }); req.write(postData); -req.end(); \ No newline at end of file +req.end(); From 9d526ebcd8a43635a27a300f00d8223f74ecc353 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 10:22:26 +0800 Subject: [PATCH 235/361] chore(workflows/publish-docs): update commit message --- .github/workflows/publish docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index ed16bb869a..4bddec3ba3 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -24,7 +24,7 @@ jobs: git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add package.json - git commit -m "Update package version" + git commit -m "chore(docs): publish documentation" git push - run: cd docs && npm publish env: @@ -48,4 +48,4 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: '🚀 New version has been released: ' + '${{ needs.publish-docs.outputs.version }}' - }) \ No newline at end of file + }) From bb50a20ef11367fbfe52efc800194697c0c3056e Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 10:44:34 +0800 Subject: [PATCH 236/361] chore(docs): use tnpm as oss-syncing source --- docs/scripts/sync-oss.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/scripts/sync-oss.js b/docs/scripts/sync-oss.js index 9518a8ea7f..2d052dfa12 100644 --- a/docs/scripts/sync-oss.js +++ b/docs/scripts/sync-oss.js @@ -19,7 +19,7 @@ const onResponse = function (res) { chunks.push(chunk); }); - res.on('end', (chunk) => { + res.on('end', () => { const body = Buffer.concat(chunks); console.table(JSON.stringify(JSON.parse(body.toString()), null, 2)); }); @@ -39,9 +39,9 @@ const postData = JSON.stringify({ }, ], // 可以发布指定源的 npm 包,默认公网 npm - useTnpm: false, + useTnpm: true, }); req.write(postData); -req.end(); \ No newline at end of file +req.end(); From a567f12473791f05a4282bc04299d936d4fd8a30 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 11:08:47 +0800 Subject: [PATCH 237/361] docs: add new link to video page --- docs/docs/video/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/video/index.md b/docs/docs/video/index.md index 8ae21620bc..d7d438e4f7 100644 --- a/docs/docs/video/index.md +++ b/docs/docs/video/index.md @@ -3,6 +3,7 @@ - [2023/08/03 初识低代码引擎](https://www.bilibili.com/video/BV1gu411p7TC) # 社区视频 +- [低代码从入门到实战:低代码引擎实践](https://www.bilibili.com/video/BV1aP4y1Q7Xa/?vd_source=cb026325b1d587f9669d09fb586bc020) - [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) - [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) - [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) From ef573d3ad9e3c3c8304957c4198f4217a394400a Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 14 Dec 2023 03:09:41 +0000 Subject: [PATCH 238/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 3c43bff657..75d7f1f28f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.11", + "version": "1.2.12", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From ec843543f04a9e10c221b1d99368d3b45986747a Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 14 Dec 2023 11:31:05 +0800 Subject: [PATCH 239/361] chore: update docs publish action --- .github/workflows/publish docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index 4bddec3ba3..7218976e42 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -26,7 +26,7 @@ jobs: git add package.json git commit -m "chore(docs): publish documentation" git push - - run: cd docs && npm publish + - run: cd docs && npm build && npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version From 08401c76f93ccb9200c43d3fec2455ea6dd89cf6 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 13:57:29 +0800 Subject: [PATCH 240/361] chore(workflows/publish-docs): add workflow_dispatch trigger --- .github/workflows/publish docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index 7218976e42..3b42398310 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -6,6 +6,7 @@ on: - develop paths: - 'docs/docs/**' + workflow_dispatch: jobs: publish-docs: From 613142b2d836f73e98ad22f443f96e99e706ef4f Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:00:52 +0800 Subject: [PATCH 241/361] chore(workflows/publish-docs): add workflow_dispatch trigger --- .github/workflows/publish docs.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index ed16bb869a..3b42398310 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -6,6 +6,7 @@ on: - develop paths: - 'docs/docs/**' + workflow_dispatch: jobs: publish-docs: @@ -24,9 +25,9 @@ jobs: git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add package.json - git commit -m "Update package version" + git commit -m "chore(docs): publish documentation" git push - - run: cd docs && npm publish + - run: cd docs && npm build && npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version @@ -48,4 +49,4 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: '🚀 New version has been released: ' + '${{ needs.publish-docs.outputs.version }}' - }) \ No newline at end of file + }) From cdcc8c8a90e9e7075d9ca8ade90fe84adccde7e3 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 14 Dec 2023 06:04:49 +0000 Subject: [PATCH 242/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 75d7f1f28f..0d4964cd9a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.12", + "version": "1.2.13", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From b56a2a92742e170b95766e2907a3bde099d8a833 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:13:58 +0800 Subject: [PATCH 243/361] chore(workflows/publish-docs): update config --- .github/workflows/publish docs.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index 3b42398310..e85d08f2a9 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -16,7 +16,8 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v2 with: - node-version: '14' + ref: 'develop' + node-version: '16' registry-url: 'https://registry.npmjs.org' - run: cd docs && npm install - run: | @@ -27,7 +28,7 @@ jobs: git add package.json git commit -m "chore(docs): publish documentation" git push - - run: cd docs && npm build && npm publish + - run: cd docs && npm run build && npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version From 729b123e462b17123b691ba1925dab2b8af07ee6 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 14 Dec 2023 06:16:05 +0000 Subject: [PATCH 244/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 0d4964cd9a..c1d9fe53fb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.13", + "version": "1.2.14", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 729083aa01844d2b40ca39a45e69cfd82028279e Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:18:57 +0800 Subject: [PATCH 245/361] chore(workflows/publish-docs): update config --- .github/workflows/publish docs.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index 3b42398310..e85d08f2a9 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -16,7 +16,8 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v2 with: - node-version: '14' + ref: 'develop' + node-version: '16' registry-url: 'https://registry.npmjs.org' - run: cd docs && npm install - run: | @@ -27,7 +28,7 @@ jobs: git add package.json git commit -m "chore(docs): publish documentation" git push - - run: cd docs && npm build && npm publish + - run: cd docs && npm run build && npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version From 5d08b6858d73f24cae33b07c22474c83f3868d27 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:45:01 +0800 Subject: [PATCH 246/361] chore(workflows/publish-docs): update config --- .github/workflows/publish docs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index e85d08f2a9..7553fa50f8 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -7,6 +7,14 @@ on: paths: - 'docs/docs/**' workflow_dispatch: + inputs: + branch: + description: 'doc is designed be published from develop' + required: true + default: 'develop' + type: choice + options: + - 'develop' jobs: publish-docs: From 53078ba5f0c973ccf137def297cdd3dc0ba23a0c Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:46:17 +0800 Subject: [PATCH 247/361] chore(workflows/publish-docs): update config --- .github/workflows/publish docs.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index e85d08f2a9..7553fa50f8 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -7,6 +7,14 @@ on: paths: - 'docs/docs/**' workflow_dispatch: + inputs: + branch: + description: 'doc is designed be published from develop' + required: true + default: 'develop' + type: choice + options: + - 'develop' jobs: publish-docs: From 9394aecc7c612ab6818d3d5751d69d2a19eb2b16 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:49:25 +0800 Subject: [PATCH 248/361] chore(workflows/publish-docs): update config --- .github/workflows/publish docs.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index 7553fa50f8..e85d08f2a9 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -7,14 +7,6 @@ on: paths: - 'docs/docs/**' workflow_dispatch: - inputs: - branch: - description: 'doc is designed be published from develop' - required: true - default: 'develop' - type: choice - options: - - 'develop' jobs: publish-docs: From 39d030bfc3a1546b6ca13208734be28c30561e2d Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 14:49:25 +0800 Subject: [PATCH 249/361] chore(workflows/publish-docs): update config --- .github/workflows/publish docs.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index 7553fa50f8..e85d08f2a9 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -7,14 +7,6 @@ on: paths: - 'docs/docs/**' workflow_dispatch: - inputs: - branch: - description: 'doc is designed be published from develop' - required: true - default: 'develop' - type: choice - options: - - 'develop' jobs: publish-docs: From 230e63ce5527078b2d223f873cd0c2f3796cf871 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Thu, 14 Dec 2023 17:27:07 +0800 Subject: [PATCH 250/361] docs: add new link to video page --- docs/docs/video/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/docs/video/index.md b/docs/docs/video/index.md index d7d438e4f7..38a0e8a5ce 100644 --- a/docs/docs/video/index.md +++ b/docs/docs/video/index.md @@ -3,7 +3,8 @@ - [2023/08/03 初识低代码引擎](https://www.bilibili.com/video/BV1gu411p7TC) # 社区视频 -- [低代码从入门到实战:低代码引擎实践](https://www.bilibili.com/video/BV1aP4y1Q7Xa/?vd_source=cb026325b1d587f9669d09fb586bc020) +- [低代码从入门到实战:低代码引擎实践](https://www.bilibili.com/video/BV1aP4y1Q7Xa/) +- [低代码技术在研发团队的应用模式](https://www.bilibili.com/video/BV1L14y1Y72J/) - [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) - [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) - [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) From c6e00252568f7429385d31996ee2f9062ca2575e Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 14 Dec 2023 09:28:13 +0000 Subject: [PATCH 251/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index c1d9fe53fb..3b9e4902a2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.14", + "version": "1.2.15", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 711a5f66b912da315fcdd2a16c65ba188b9623f6 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Sat, 16 Dec 2023 18:30:03 +0800 Subject: [PATCH 252/361] style: remove .lc-workbench-center z-index --- packages/editor-skeleton/src/layouts/workbench.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 97a017523d..9c7a9815dd 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -363,7 +363,7 @@ body { flex: 1; display: flex; flex-direction: column; - z-index: 10; + .lc-toolbar { display: flex; height: var(--toolbar-height); From 16713f4b848f3648fa93c82d70007fbec4e8a816 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Sun, 17 Dec 2023 16:37:17 +0800 Subject: [PATCH 253/361] feat(skeleton): Add TS defs for modules & optimize Tabs display with array contents --- .../src/components/widget-views/index.tsx | 23 ++++++++--- .../src/layouts/left-fixed-pane.tsx | 7 ++-- .../src/layouts/left-float-pane.tsx | 5 +-- packages/editor-skeleton/src/skeleton.ts | 38 +++++++++---------- packages/editor-skeleton/src/types.ts | 33 +++------------- packages/editor-skeleton/src/widget/panel.ts | 15 +++----- .../src/shell/type/widget-base-config.ts | 27 ++++++++++++- 7 files changed, 78 insertions(+), 70 deletions(-) diff --git a/packages/editor-skeleton/src/components/widget-views/index.tsx b/packages/editor-skeleton/src/components/widget-views/index.tsx index ba49b3d1ab..2b2f6931cb 100644 --- a/packages/editor-skeleton/src/components/widget-views/index.tsx +++ b/packages/editor-skeleton/src/components/widget-views/index.tsx @@ -266,15 +266,28 @@ export class PanelView extends Component<{ } @observer -export class TabsPanelView extends Component<{ container: WidgetContainer<Panel> }> { +export class TabsPanelView extends Component<{ + container: WidgetContainer<Panel>; + // shouldHideSingleTab: 一个布尔值,用于控制当 Tabs 组件只有一个标签时是否隐藏该标签。 + shouldHideSingleTab?: boolean; +}> { render() { const { container } = this.props; const titles: ReactElement[] = []; const contents: ReactElement[] = []; - container.items.forEach((item: any) => { - titles.push(<PanelTitle key={item.id} panel={item} className="lc-tab-title" />); - contents.push(<PanelView key={item.id} panel={item} hideOperationRow hideDragLine />); - }); + // 如果只有一个标签且 shouldHideSingleTab 为 true,则不显示 Tabs + if (this.props.shouldHideSingleTab && container.items.length === 1) { + contents.push(<PanelView key={container.items[0].id} panel={container.items[0]} hideOperationRow hideDragLine />); + } else { + container.items.forEach((item: any) => { + titles.push(<PanelTitle key={item.id} panel={item} className="lc-tab-title" />); + contents.push(<PanelView key={item.id} panel={item} hideOperationRow hideDragLine />); + }); + } + + if (!titles.length) { + return contents; + } return ( <div className="lc-tabs"> diff --git a/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx b/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx index cda600f74a..a56b449079 100644 --- a/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx @@ -2,17 +2,16 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; -import { PanelConfig } from '../types'; import { Panel } from '../widget/panel'; +import { IPublicTypePanelConfig } from '@alilc/lowcode-types'; @observer -export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> { +export default class LeftFixedPane extends Component<{ area: Area<IPublicTypePanelConfig, Panel> }> { componentDidUpdate() { // FIXME: dirty fix, need deep think this.props.area.skeleton.editor.get('designer')?.touchOffsetObserver(); } - render() { const { area } = this.props; const width = area.current?.config.props?.width; @@ -36,7 +35,7 @@ export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, P } @observer -class Contents extends Component<{ area: Area<PanelConfig, Panel> }> { +class Contents extends Component<{ area: Area<IPublicTypePanelConfig, Panel> }> { render() { const { area } = this.props; return <Fragment>{area.container.items.map((panel) => panel.content)}</Fragment>; diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx index 15f4926199..296f083211 100644 --- a/packages/editor-skeleton/src/layouts/left-float-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -3,11 +3,10 @@ import classNames from 'classnames'; import { observer, Focusable } from '@alilc/lowcode-editor-core'; import { Area } from '../area'; import { Panel } from '../widget/panel'; -import { PanelConfig } from '../types'; -import { IPublicApiProject } from '@alilc/lowcode-types'; +import { IPublicApiProject, IPublicTypePanelConfig } from '@alilc/lowcode-types'; @observer -export default class LeftFloatPane extends Component<{ area: Area<PanelConfig, Panel> }> { +export default class LeftFloatPane extends Component<{ area: Area<IPublicTypePanelConfig, Panel> }> { private dispose?: () => void; private focusing?: Focusable; diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 13967e94d6..7ff462391d 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -1,7 +1,6 @@ import { action, makeObservable, obx, engineConfig, IEditor, FocusTracker } from '@alilc/lowcode-editor-core'; import { DockConfig, - PanelConfig, WidgetConfig, PanelDockConfig, DialogDockConfig, @@ -29,6 +28,7 @@ import { IPublicTypeSkeletonConfig, IPublicApiSkeleton, IPublicTypeConfigTransducer, + IPublicTypePanelConfig, } from '@alilc/lowcode-types'; const logger = new Logger({ level: 'warn', bizName: 'skeleton' }); @@ -70,15 +70,15 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton, readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - readonly leftFixedArea: Area<PanelConfig, Panel>; + readonly leftFixedArea: Area<IPublicTypePanelConfig, Panel>; - readonly leftFloatArea: Area<PanelConfig, Panel>; + readonly leftFloatArea: Area<IPublicTypePanelConfig, Panel>; - readonly rightArea: Area<PanelConfig, Panel>; + readonly rightArea: Area<IPublicTypePanelConfig, Panel>; - readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>; + readonly mainArea: Area<WidgetConfig | IPublicTypePanelConfig, Widget | Panel>; - readonly bottomArea: Area<PanelConfig, Panel>; + readonly bottomArea: Area<IPublicTypePanelConfig, Panel>; readonly stages: Area<StageConfig, Stage>; @@ -104,7 +104,7 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton, defaultSetCurrent?: boolean, ): WidgetContainer; - createPanel(config: PanelConfig): Panel; + createPanel(config: IPublicTypePanelConfig): Panel; add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined; } @@ -124,15 +124,15 @@ export class Skeleton implements ISkeleton { readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - readonly leftFixedArea: Area<PanelConfig, Panel>; + readonly leftFixedArea: Area<IPublicTypePanelConfig, Panel>; - readonly leftFloatArea: Area<PanelConfig, Panel>; + readonly leftFloatArea: Area<IPublicTypePanelConfig, Panel>; - readonly rightArea: Area<PanelConfig, Panel>; + readonly rightArea: Area<IPublicTypePanelConfig, Panel>; - @obx readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>; + @obx readonly mainArea: Area<WidgetConfig | IPublicTypePanelConfig, Widget | Panel>; - readonly bottomArea: Area<PanelConfig, Panel>; + readonly bottomArea: Area<IPublicTypePanelConfig, Panel>; readonly stages: Area<StageConfig, Stage>; @@ -388,9 +388,9 @@ export class Skeleton implements ISkeleton { return this.widgets.find(widget => widget.name === name); } - createPanel(config: PanelConfig) { + createPanel(config: IPublicTypePanelConfig) { const parsedConfig = this.parseConfig(config); - const panel = new Panel(this, parsedConfig as PanelConfig); + const panel = new Panel(this, parsedConfig as IPublicTypePanelConfig); this.panels.set(panel.name, panel); logger.debug(`Panel created with name: ${panel.name} \nconfig:`, config, '\n current panels: ', this.panels); return panel; @@ -496,7 +496,7 @@ export class Skeleton implements ISkeleton { return this.leftArea.add(parsedConfig as PanelDockConfig); case 'rightArea': case 'right': - return this.rightArea.add(parsedConfig as PanelConfig); + return this.rightArea.add(parsedConfig as IPublicTypePanelConfig); case 'topArea': case 'top': return this.topArea.add(parsedConfig as PanelDockConfig); @@ -508,14 +508,14 @@ export class Skeleton implements ISkeleton { case 'main': case 'center': case 'centerArea': - return this.mainArea.add(parsedConfig as PanelConfig); + return this.mainArea.add(parsedConfig as IPublicTypePanelConfig); case 'bottomArea': case 'bottom': - return this.bottomArea.add(parsedConfig as PanelConfig); + return this.bottomArea.add(parsedConfig as IPublicTypePanelConfig); case 'leftFixedArea': - return this.leftFixedArea.add(parsedConfig as PanelConfig); + return this.leftFixedArea.add(parsedConfig as IPublicTypePanelConfig); case 'leftFloatArea': - return this.leftFloatArea.add(parsedConfig as PanelConfig); + return this.leftFloatArea.add(parsedConfig as IPublicTypePanelConfig); case 'stages': return this.stages.add(parsedConfig as StageConfig); default: diff --git a/packages/editor-skeleton/src/types.ts b/packages/editor-skeleton/src/types.ts index b73dc4adce..8c5f1484a0 100644 --- a/packages/editor-skeleton/src/types.ts +++ b/packages/editor-skeleton/src/types.ts @@ -1,11 +1,11 @@ import { ReactElement, ComponentType } from 'react'; import { IPublicTypeTitleContent, - IPublicTypeI18nData, IPublicTypeWidgetConfigArea, IPublicTypeWidgetBaseConfig, - IPublicTypePanelDockPanelProps, IPublicTypePanelDockProps, + IPublicTypePanelConfigProps, + IPublicTypePanelConfig, } from '@alilc/lowcode-types'; import { IWidget } from './widget/widget'; @@ -66,40 +66,17 @@ export function isDialogDockConfig(obj: any): obj is DialogDockConfig { return obj && obj.type === 'DialogDock'; } -// 窗格扩展 -export interface PanelConfig extends IPublicTypeWidgetBaseConfig { - type: 'Panel'; - content?: string | ReactElement | ComponentType<any> | PanelConfig[]; // as children - props?: PanelProps; -} - -export function isPanelConfig(obj: any): obj is PanelConfig { +export function isPanelConfig(obj: any): obj is IPublicTypePanelConfig { return obj && obj.type === 'Panel'; } -export type HelpTipConfig = string | { url?: string; content?: string | ReactElement }; - -export interface PanelProps extends IPublicTypePanelDockPanelProps { - title?: IPublicTypeTitleContent; - icon?: any; // 冗余字段 - description?: string | IPublicTypeI18nData; - help?: HelpTipConfig; // 显示问号帮助 - hiddenWhenInit?: boolean; // when this is true, by default will be hidden - condition?: (widget: IWidget) => any; - onInit?: (widget: IWidget) => any; - onDestroy?: () => any; - shortcut?: string; // 只有在特定位置,可触发 toggle show - enableDrag?: boolean; // 是否开启通过 drag 调整 宽度 - keepVisibleWhileDragging?: boolean; // 是否在该 panel 范围内拖拽时保持 visible 状态 -} - export interface PanelDockConfig extends IDockBaseConfig { type: 'PanelDock'; panelName?: string; - panelProps?: PanelProps & { + panelProps?: IPublicTypePanelConfigProps & { area?: IPublicTypeWidgetConfigArea; }; - content?: string | ReactElement | ComponentType<any> | PanelConfig[]; // content for pane + content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[]; // content for pane } export function isPanelDockConfig(obj: any): obj is PanelDockConfig { diff --git a/packages/editor-skeleton/src/widget/panel.ts b/packages/editor-skeleton/src/widget/panel.ts index b35af6a212..3a1ce3b00b 100644 --- a/packages/editor-skeleton/src/widget/panel.ts +++ b/packages/editor-skeleton/src/widget/panel.ts @@ -1,10 +1,9 @@ import { createElement, ReactNode } from 'react'; import { obx, computed, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { uniqueId, createContent } from '@alilc/lowcode-utils'; -import { IPublicTypeTitleContent } from '@alilc/lowcode-types'; +import { IPublicTypeHelpTipConfig, IPublicTypePanelConfig, IPublicTypeTitleContent } from '@alilc/lowcode-types'; import { WidgetContainer } from './widget-container'; import { getEvent } from '@alilc/lowcode-shell'; -import { PanelConfig, HelpTipConfig } from '../types'; import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views'; import { ISkeleton } from '../skeleton'; import { composeTitle } from './utils'; @@ -45,6 +44,7 @@ export class Panel implements IWidget { if (this.container) { return createElement(TabsPanelView, { container: this.container, + shouldHideSingleTab: true, }); } @@ -72,15 +72,15 @@ export class Panel implements IWidget { readonly title: IPublicTypeTitleContent; - readonly help?: HelpTipConfig; + readonly help?: IPublicTypeHelpTipConfig; private plain = false; - private container?: WidgetContainer<Panel, PanelConfig>; + private container?: WidgetContainer<Panel, IPublicTypePanelConfig>; @obx.ref public parent?: WidgetContainer; - constructor(readonly skeleton: ISkeleton, readonly config: PanelConfig) { + constructor(readonly skeleton: ISkeleton, readonly config: IPublicTypePanelConfig) { makeObservable(this); const { name, content, props = {} } = config; const { hideTitleBar, title, icon, description, help } = props; @@ -90,9 +90,6 @@ export class Panel implements IWidget { this.plain = hideTitleBar || !title; this.help = help; if (Array.isArray(content)) { - if (content.length === 1) { - // todo: not show tabs - } this.container = this.skeleton.createContainer( name, (item) => { @@ -127,7 +124,7 @@ export class Panel implements IWidget { this.parent = parent; } - add(item: Panel | PanelConfig) { + add(item: Panel | IPublicTypePanelConfig) { return this.container?.add(item); } diff --git a/packages/types/src/shell/type/widget-base-config.ts b/packages/types/src/shell/type/widget-base-config.ts index b23ba0f137..2764ce1927 100644 --- a/packages/types/src/shell/type/widget-base-config.ts +++ b/packages/types/src/shell/type/widget-base-config.ts @@ -1,4 +1,27 @@ -import { IPublicTypeIconType, IPublicTypeTitleContent, IPublicTypeWidgetConfigArea, TipContent } from './'; +import { ReactElement, ComponentType } from 'react'; +import { IPublicTypeI18nData, IPublicTypeIconType, IPublicTypeTitleContent, IPublicTypeWidgetConfigArea, TipContent } from './'; + +export type IPublicTypeHelpTipConfig = string | { url?: string; content?: string | ReactElement }; + +export interface IPublicTypePanelConfigProps extends IPublicTypePanelDockPanelProps { + title?: IPublicTypeTitleContent; + icon?: any; // 冗余字段 + description?: string | IPublicTypeI18nData; + help?: IPublicTypeHelpTipConfig; // 显示问号帮助 + hiddenWhenInit?: boolean; // when this is true, by default will be hidden + condition?: (widget: any) => any; + onInit?: (widget: any) => any; + onDestroy?: () => any; + shortcut?: string; // 只有在特定位置,可触发 toggle show + enableDrag?: boolean; // 是否开启通过 drag 调整 宽度 + keepVisibleWhileDragging?: boolean; // 是否在该 panel 范围内拖拽时保持 visible 状态 +} + +export interface IPublicTypePanelConfig extends IPublicTypeWidgetBaseConfig { + type: 'Panel'; + content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[]; // as children + props?: IPublicTypePanelConfigProps; +} export interface IPublicTypeWidgetBaseConfig { [extra: string]: any; @@ -13,7 +36,7 @@ export interface IPublicTypeWidgetBaseConfig { */ area?: IPublicTypeWidgetConfigArea; props?: Record<string, any>; - content?: any; + content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[]; contentProps?: Record<string, any>; /** From 594abc4e6c967dc75a6e4aedfd132a778b8312a9 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 18 Dec 2023 14:27:31 +0800 Subject: [PATCH 254/361] style(designer): update bem-tools index --- .../designer/src/builtin-simulator/bem-tools/bem-tools.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/builtin-simulator/bem-tools/bem-tools.less b/packages/designer/src/builtin-simulator/bem-tools/bem-tools.less index 83a411e566..8c66e85139 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/bem-tools.less +++ b/packages/designer/src/builtin-simulator/bem-tools/bem-tools.less @@ -6,5 +6,5 @@ bottom: 0; right: 0; overflow: visible; - z-index: 800; + z-index: 1; } From 2bf3aa70a70ebde17139330423d0f02d2a1a8945 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 18 Dec 2023 19:16:42 +0800 Subject: [PATCH 255/361] docs: add skeleton.getAreaItems docs --- docs/docs/api/skeleton.md | 17 +++++++++++++++++ packages/types/src/shell/api/skeleton.ts | 8 +++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 5bfa239724..ea5672172c 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -297,7 +297,24 @@ showArea(areaName: string): void; hideArea(areaName: string): void; ``` +### getAreaItems + +获取某个区域下的所有面板实例 + +```typescript +/** + * 获取某个区域下的所有面板实例 + * @param areaName IPublicTypeWidgetConfigArea + */ +getAreaItems(areaName: IPublicTypeWidgetConfigArea): IPublicModelSkeletonItem[] | undefined; +``` + +相关类型:[IPublicModelSkeletonItem](https://github.com/alibaba/lowcode-engine/blob/main/packages/shell/src/model/skeleton-item.ts) + + + ### registerConfigTransducer + 注册一个面板的配置转换器(transducer)。 ```typescript diff --git a/packages/types/src/shell/api/skeleton.ts b/packages/types/src/shell/api/skeleton.ts index 9a36aa4690..83a3f97788 100644 --- a/packages/types/src/shell/api/skeleton.ts +++ b/packages/types/src/shell/api/skeleton.ts @@ -1,5 +1,5 @@ import { IPublicModelSkeletonItem } from '../model'; -import { IPublicTypeConfigTransducer, IPublicTypeDisposable, IPublicTypeSkeletonConfig } from '../type'; +import { IPublicTypeConfigTransducer, IPublicTypeDisposable, IPublicTypeSkeletonConfig, IPublicTypeWidgetConfigArea } from '../type'; export interface IPublicApiSkeleton { @@ -20,6 +20,12 @@ export interface IPublicApiSkeleton { */ remove(config: IPublicTypeSkeletonConfig): number | undefined; + /** + * 获取某个区域下的所有面板实例 + * @param areaName IPublicTypeWidgetConfigArea + */ + getAreaItems(areaName: IPublicTypeWidgetConfigArea): IPublicModelSkeletonItem[] | undefined; + /** * 获取面板实例 * @param name 面板名称 From 4a502f823c149fb10aaa178ec9a2de82476bef71 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Tue, 19 Dec 2023 01:32:47 +0000 Subject: [PATCH 256/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 3b9e4902a2..457af1fe31 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.15", + "version": "1.2.16", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From e79f68611a4779e30a9bd455dd1d8e20275823f6 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 19 Dec 2023 17:40:20 +0800 Subject: [PATCH 257/361] feat(skeleton): add onDisableWidget & onEnableWidget APIs --- docs/docs/api/skeleton.md | 35 +++++++++++++++++++++--- packages/shell/src/api/skeleton.ts | 34 ++++++++++++++--------- packages/types/src/shell/api/skeleton.ts | 20 +++++++++++--- 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index ea5672172c..0713546e19 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -387,7 +387,7 @@ export default controlPanelWidthPlugin; * @param listener * @returns */ -onShowPanel(listener: (...args: any[]) => void): IPublicTypeDisposable; +onShowPanel(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) @@ -403,11 +403,38 @@ onShowPanel(listener: (...args: any[]) => void): IPublicTypeDisposable; * @param listener * @returns */ -onHidePanel(listener: (...args: any[]) => void): IPublicTypeDisposable; +onHidePanel(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) +### onDisableWidget + +监听 Widget 实例 Disable 事件 + +```typescript +/** + * 监听 Widget 实例 Disable 事件 + * @param listener + */ +onDisableWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; +``` + +相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + +### onEnableWidget + +监听 Widget 实例 Enable 事件 + +```typescript +/** + * 监听 Widget 实例 Enable 事件 + * @param listener + */ +onEnableWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; +``` + +相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onShowWidget @@ -420,7 +447,7 @@ onHidePanel(listener: (...args: any[]) => void): IPublicTypeDisposable; * @param listener * @returns */ -onShowWidget(listener: (...args: any[]) => void): IPublicTypeDisposable; +onShowWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) @@ -436,7 +463,7 @@ onShowWidget(listener: (...args: any[]) => void): IPublicTypeDisposable; * @param listener * @returns */ -onHideWidget(listener: (...args: any[]) => void): IPublicTypeDisposable; +onHideWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) diff --git a/packages/shell/src/api/skeleton.ts b/packages/shell/src/api/skeleton.ts index 07a1727dd3..c61edf95d0 100644 --- a/packages/shell/src/api/skeleton.ts +++ b/packages/shell/src/api/skeleton.ts @@ -154,16 +154,30 @@ export class Skeleton implements IPublicApiSkeleton { * @param listener * @returns */ - onShowPanel(listener: (...args: any[]) => void): IPublicTypeDisposable { + onShowPanel(listener: (paneName: string, panel: IPublicModelSkeletonItem) => void): IPublicTypeDisposable { const { editor } = this[skeletonSymbol]; editor.eventBus.on(SkeletonEvents.PANEL_SHOW, (name: any, panel: any) => { - // 不泄漏 skeleton - const { skeleton, ...restPanel } = panel; - listener(name, restPanel); + listener(name, new SkeletonItem(panel)); }); return () => editor.eventBus.off(SkeletonEvents.PANEL_SHOW, listener); } + onDisableWidget(listener: (...args: any[]) => void): IPublicTypeDisposable { + const { editor } = this[skeletonSymbol]; + editor.eventBus.on(SkeletonEvents.WIDGET_DISABLE, (name: any, panel: any) => { + listener(name, new SkeletonItem(panel)); + }); + return () => editor.eventBus.off(SkeletonEvents.WIDGET_DISABLE, listener); + } + + onEnableWidget(listener: (...args: any[]) => void): IPublicTypeDisposable { + const { editor } = this[skeletonSymbol]; + editor.eventBus.on(SkeletonEvents.WIDGET_ENABLE, (name: any, panel: any) => { + listener(name, new SkeletonItem(panel)); + }); + return () => editor.eventBus.off(SkeletonEvents.WIDGET_ENABLE, listener); + } + /** * 监听 panel 隐藏事件 * @param listener @@ -172,9 +186,7 @@ export class Skeleton implements IPublicApiSkeleton { onHidePanel(listener: (...args: any[]) => void): IPublicTypeDisposable { const { editor } = this[skeletonSymbol]; editor.eventBus.on(SkeletonEvents.PANEL_HIDE, (name: any, panel: any) => { - // 不泄漏 skeleton - const { skeleton, ...restPanel } = panel; - listener(name, restPanel); + listener(name, new SkeletonItem(panel)); }); return () => editor.eventBus.off(SkeletonEvents.PANEL_HIDE, listener); } @@ -187,9 +199,7 @@ export class Skeleton implements IPublicApiSkeleton { onShowWidget(listener: (...args: any[]) => void): IPublicTypeDisposable { const { editor } = this[skeletonSymbol]; editor.eventBus.on(SkeletonEvents.WIDGET_SHOW, (name: any, panel: any) => { - // 不泄漏 skeleton - const { skeleton, ...rest } = panel; - listener(name, rest); + listener(name, new SkeletonItem(panel)); }); return () => editor.eventBus.off(SkeletonEvents.WIDGET_SHOW, listener); } @@ -202,9 +212,7 @@ export class Skeleton implements IPublicApiSkeleton { onHideWidget(listener: (...args: any[]) => void): IPublicTypeDisposable { const { editor } = this[skeletonSymbol]; editor.eventBus.on(SkeletonEvents.WIDGET_HIDE, (name: any, panel: any) => { - // 不泄漏 skeleton - const { skeleton, ...rest } = panel; - listener(name, rest); + listener(name, new SkeletonItem(panel)); }); return () => editor.eventBus.off(SkeletonEvents.WIDGET_HIDE, listener); } diff --git a/packages/types/src/shell/api/skeleton.ts b/packages/types/src/shell/api/skeleton.ts index 83a3f97788..1bf788e121 100644 --- a/packages/types/src/shell/api/skeleton.ts +++ b/packages/types/src/shell/api/skeleton.ts @@ -95,7 +95,7 @@ export interface IPublicApiSkeleton { * @param listener * @returns */ - onShowPanel(listener: (...args: any[]) => void): IPublicTypeDisposable; + onShowPanel(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; /** * 监听 Panel 实例隐藏事件 @@ -103,7 +103,19 @@ export interface IPublicApiSkeleton { * @param listener * @returns */ - onHidePanel(listener: (...args: any[]) => void): IPublicTypeDisposable; + onHidePanel(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; + + /** + * 监听 Widget 实例 Disable 事件 + * @param listener + */ + onDisableWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; + + /** + * 监听 Widget 实例 Enable 事件 + * @param listener + */ + onEnableWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; /** * 监听 Widget 显示事件 @@ -111,7 +123,7 @@ export interface IPublicApiSkeleton { * @param listener * @returns */ - onShowWidget(listener: (...args: any[]) => void): IPublicTypeDisposable; + onShowWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; /** * 监听 Widget 隐藏事件 @@ -119,7 +131,7 @@ export interface IPublicApiSkeleton { * @param listener * @returns */ - onHideWidget(listener: (...args: any[]) => void): IPublicTypeDisposable; + onHideWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; /** * 注册一个面板的配置转换器(transducer)。 From 733229985b1835ef273770e1b4da363d948121da Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Tue, 19 Dec 2023 09:57:55 +0000 Subject: [PATCH 258/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 457af1fe31..ab6edf5cb5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.16", + "version": "1.2.17", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 73dacadaee254dd0d6a5229f3ad869168360d47f Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 25 Dec 2023 19:44:40 +0800 Subject: [PATCH 259/361] style(skeleton): update setting pane styles --- .../src/components/settings/settings-primary-pane.tsx | 6 ++++-- packages/utils/src/create-icon.tsx | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index a68647ed0d..747a2ea1df 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -65,8 +65,10 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon', })} - <Title title={settings.componentMeta!.title} /> - <span> x {settings.nodes.length}</span> + <div style={{ marginLeft: '5px' }}> + <Title title={settings.componentMeta!.title} /> + <span> x {settings.nodes.length}</span> + </div> </div> ); } diff --git a/packages/utils/src/create-icon.tsx b/packages/utils/src/create-icon.tsx index 0a5d6c1ff7..621b5c7ab4 100644 --- a/packages/utils/src/create-icon.tsx +++ b/packages/utils/src/create-icon.tsx @@ -30,7 +30,10 @@ export function createIcon( return cloneElement(icon, { ...props }); } if (isReactComponent(icon)) { - return createElement(icon, { ...props }); + return createElement(icon, { + class: props?.className, + ...props, + }); } return <Icon {...icon} {...props} />; From f483970aef86c0e9591ec4f9bdf6fa9be75f5f46 Mon Sep 17 00:00:00 2001 From: eightHundreds <mingoing@outlook.com> Date: Tue, 12 Dec 2023 16:12:45 +0800 Subject: [PATCH 260/361] fix: trigger node.add event on mergeChildren --- packages/designer/src/document/node/node-children.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index bf982cbfa7..65210fe62c 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -462,6 +462,9 @@ export class NodeChildren implements INodeChildren { const node: INode = this.owner.document?.createNode(child); this.children.push(node); node.internalSetParent(this.owner); + /* istanbul ignore next */ + const editor = node.document?.designer.editor; + editor?.eventBus.emit('node.add', { node }); }); changed = true; } From f7ba053476302b5b87d01a856e1ab98076591a3a Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 26 Dec 2023 14:52:24 +0800 Subject: [PATCH 261/361] fix(outline-pane): hover invalid --- packages/plugin-outline-pane/src/views/tree.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-outline-pane/src/views/tree.tsx b/packages/plugin-outline-pane/src/views/tree.tsx index 675f70c2b3..8428ec944c 100644 --- a/packages/plugin-outline-pane/src/views/tree.tsx +++ b/packages/plugin-outline-pane/src/views/tree.tsx @@ -40,7 +40,7 @@ export default class TreeView extends PureComponent<{ return; } const node = this.getTreeNodeFromEvent(e)?.node; - detecting?.capture(node as any); + node?.id && detecting?.capture(node.id); } private onClick = (e: ReactMouseEvent) => { From 89e912ba1a3a4e33c0de72773f5fda36a09c4702 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 28 Dec 2023 05:57:44 +0000 Subject: [PATCH 262/361] chore(release): publish 1.2.4 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 98ef80f138..323f3fb412 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.2.3", + "version": "1.2.4", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index e961451d88..a681a03bc8 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.2.3", + "version": "1.2.4", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.2.3", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-editor-core": "1.2.4", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 345783c806..ba638df961 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.2.3", + "version": "1.2.4", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index fa5c1e13e6..e8b42920f7 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.2.3", + "version": "1.2.4", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-editor-core": "1.2.3", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-editor-core": "1.2.4", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index c9eef3534c..092b7c39b3 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.2.3", + "version": "1.2.4", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-editor-core": "1.2.3", - "@alilc/lowcode-editor-skeleton": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-editor-core": "1.2.4", + "@alilc/lowcode-editor-skeleton": "1.2.4", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.2.3", - "@alilc/lowcode-plugin-outline-pane": "1.2.3", - "@alilc/lowcode-shell": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", - "@alilc/lowcode-workspace": "1.2.3", + "@alilc/lowcode-plugin-designer": "1.2.4", + "@alilc/lowcode-plugin-outline-pane": "1.2.4", + "@alilc/lowcode-shell": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-workspace": "1.2.4", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 71a21484c4..bdc73a24a8 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.2.3", + "version": "1.2.4", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 500c0c9611..8a3c532e6a 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.2.3", + "version": "1.2.4", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-editor-core": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-editor-core": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 5a2ef38a45..c2b6424d68 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.2.3", + "version": "1.2.4", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 837aebc85e..fa66dbb084 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.2.3", + "version": "1.2.4", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-renderer-core": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index dc9b7b1478..511cfa46dc 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.2.3", + "version": "1.2.4", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-rax-renderer": "1.2.3", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-rax-renderer": "1.2.4", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 1dceb9c2e7..53764e8d93 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.2.3", + "version": "1.2.4", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.2.3" + "@alilc/lowcode-renderer-core": "1.2.4" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 8935c92eef..6c07ea42a0 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.2.3", + "version": "1.2.4", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-react-renderer": "1.2.3", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-react-renderer": "1.2.4", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 4774ae3689..bc55f80975 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.2.3", + "version": "1.2.4", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 2ebf14bbc2..efb5fc1e28 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.2.3", + "version": "1.2.4", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-editor-core": "1.2.3", - "@alilc/lowcode-editor-skeleton": "1.2.3", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", - "@alilc/lowcode-workspace": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-editor-core": "1.2.4", + "@alilc/lowcode-editor-skeleton": "1.2.4", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-workspace": "1.2.4", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index c0b8e203fe..82624356ea 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.2.3", + "version": "1.2.4", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 00efffb8d3..ac0f36502f 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.2.3", + "version": "1.2.4", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.3", + "@alilc/lowcode-types": "1.2.4", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 8c09a93b6c..d3868c3307 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.2.3", + "version": "1.2.4", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.3", - "@alilc/lowcode-editor-core": "1.2.3", - "@alilc/lowcode-editor-skeleton": "1.2.3", - "@alilc/lowcode-types": "1.2.3", - "@alilc/lowcode-utils": "1.2.3", + "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-editor-core": "1.2.4", + "@alilc/lowcode-editor-skeleton": "1.2.4", + "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-utils": "1.2.4", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From b2abb67440e8ed36aef465d2b072292acb27c4c3 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 28 Dec 2023 06:22:34 +0000 Subject: [PATCH 263/361] chore(release): publish 1.2.5 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 17 files changed, 65 insertions(+), 65 deletions(-) diff --git a/lerna.json b/lerna.json index 323f3fb412..1170309170 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.2.4", + "version": "1.2.5", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index a681a03bc8..0e6e67e882 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.2.4", + "version": "1.2.5", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.2.4", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-editor-core": "1.2.5", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index ba638df961..0875584501 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.2.4", + "version": "1.2.5", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index e8b42920f7..648ed5be1f 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.2.4", + "version": "1.2.5", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-editor-core": "1.2.4", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-editor-core": "1.2.5", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 092b7c39b3..4caf32c009 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.2.4", + "version": "1.2.5", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-editor-core": "1.2.4", - "@alilc/lowcode-editor-skeleton": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-editor-core": "1.2.5", + "@alilc/lowcode-editor-skeleton": "1.2.5", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.2.4", - "@alilc/lowcode-plugin-outline-pane": "1.2.4", - "@alilc/lowcode-shell": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", - "@alilc/lowcode-workspace": "1.2.4", + "@alilc/lowcode-plugin-designer": "1.2.5", + "@alilc/lowcode-plugin-outline-pane": "1.2.5", + "@alilc/lowcode-shell": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-workspace": "1.2.5", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index bdc73a24a8..f131dc14c3 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.2.4", + "version": "1.2.5", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 8a3c532e6a..d764f7d9ed 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.2.4", + "version": "1.2.5", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-editor-core": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-editor-core": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index c2b6424d68..f864356fc8 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.2.4", + "version": "1.2.5", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index fa66dbb084..8173d6e4e1 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.2.4", + "version": "1.2.5", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-renderer-core": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 511cfa46dc..f264380ec1 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.2.4", + "version": "1.2.5", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-rax-renderer": "1.2.4", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-rax-renderer": "1.2.5", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 53764e8d93..2970e93410 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.2.4", + "version": "1.2.5", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.2.4" + "@alilc/lowcode-renderer-core": "1.2.5" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 6c07ea42a0..030a197082 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.2.4", + "version": "1.2.5", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-react-renderer": "1.2.4", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-react-renderer": "1.2.5", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index bc55f80975..fab0d3f133 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.2.4", + "version": "1.2.5", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index efb5fc1e28..86c4c7d11e 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.2.4", + "version": "1.2.5", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-editor-core": "1.2.4", - "@alilc/lowcode-editor-skeleton": "1.2.4", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", - "@alilc/lowcode-workspace": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-editor-core": "1.2.5", + "@alilc/lowcode-editor-skeleton": "1.2.5", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-workspace": "1.2.5", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 82624356ea..52a5e03ae0 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.2.4", + "version": "1.2.5", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index ac0f36502f..976b76341b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.2.4", + "version": "1.2.5", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.4", + "@alilc/lowcode-types": "1.2.5", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index d3868c3307..cbc31f3797 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.2.4", + "version": "1.2.5", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.4", - "@alilc/lowcode-editor-core": "1.2.4", - "@alilc/lowcode-editor-skeleton": "1.2.4", - "@alilc/lowcode-types": "1.2.4", - "@alilc/lowcode-utils": "1.2.4", + "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-editor-core": "1.2.5", + "@alilc/lowcode-editor-skeleton": "1.2.5", + "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-utils": "1.2.5", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 7b85a35b2419f5b2390be0243056ac815e140c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=81=AA=E5=B0=8F=E9=99=88?= <xiaohuoni@users.noreply.github.com> Date: Tue, 2 Jan 2024 18:15:30 +0800 Subject: [PATCH 264/361] feat: zip publisher support browser (#2744) --- modules/code-generator/README.md | 14 ++++- modules/code-generator/package.json | 2 + .../code-generator/src/publisher/zip/index.ts | 18 ++++--- .../code-generator/src/publisher/zip/utils.ts | 3 +- .../tests/public/publisher/zip/zip.test.ts | 51 +++++++++++++++++-- 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/modules/code-generator/README.md b/modules/code-generator/README.md index 03ce94b54e..1d67b3aa16 100644 --- a/modules/code-generator/README.md +++ b/modules/code-generator/README.md @@ -94,16 +94,26 @@ await CodeGenerator.init(); 4. 出码 ```js -const result = await CodeGenerator.generateCode({ +const project = await CodeGenerator.generateCode({ solution: 'icejs', // 出码方案 (目前内置有 icejs 和 rax ) schema, // 编排搭建出来的 schema }); -console.log(result); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果) +console.log(project); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果) ``` 注:一般来说在浏览器中出码适合做即时预览功能。 +5. 下载 zip 包 + +```js +// 写入到 zip 包 +await CodeGenerator.publishers.zip().publish({ + project, // 上一步生成的 project + projectSlug: 'your-project-slug', // 项目标识 -- 对应下载 your-project-slug.zip 文件 +}); +``` + ### 5)自定义出码 前端框架灵活多变,默认内置的出码方案很难满足所有人的需求,好在此代码生成器支持非常灵活的插件机制 -- 欢迎参考 ./src/plugins/xxx 来编写您自己的出码插件,然后参考 ./src/solutions/xxx 将各种插件组合成一套适合您的业务场景的出码方案。 diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 6ff1ecb63f..5c0d91cc08 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -80,6 +80,7 @@ "change-case": "^3.1.0", "commander": "^6.1.0", "debug": "^4.3.2", + "file-saver": "^2.0.5", "fp-ts": "^2.11.9", "fs-extra": "9.x", "glob": "^7.2.0", @@ -109,6 +110,7 @@ "devDependencies": { "@iceworks/spec": "^1.4.2", "@types/babel__traverse": "^7.11.0", + "@types/file-saver": "^2.0.7", "@types/jest": "^27.0.2", "@types/lodash": "^4.14.162", "@types/node": "^14.14.20", diff --git a/modules/code-generator/src/publisher/zip/index.ts b/modules/code-generator/src/publisher/zip/index.ts index cc2f082b27..0ac0b6f67f 100644 --- a/modules/code-generator/src/publisher/zip/index.ts +++ b/modules/code-generator/src/publisher/zip/index.ts @@ -2,9 +2,9 @@ import { ResultDir } from '@alilc/lowcode-types'; import { PublisherFactory, IPublisher, IPublisherFactoryParams, PublisherError } from '../../types'; import { getErrorMessage } from '../../utils/errors'; import { isNodeProcess, writeZipToDisk, generateProjectZip } from './utils'; +import { saveAs } from 'file-saver'; -// export type ZipBuffer = Buffer | Blob; -export type ZipBuffer = Buffer; +export type ZipBuffer = Buffer | Blob; declare type ZipPublisherResponse = string | ZipBuffer; @@ -44,10 +44,16 @@ export const createZipPublisher: PublisherFactory<ZipFactoryParams, ZipPublisher try { const zipContent = await generateProjectZip(projectToPublish); - // If not output path is provided, zip is not written to disk - const projectOutputPath = options.outputPath || outputPath; - if (projectOutputPath && isNodeProcess()) { - await writeZipToDisk(projectOutputPath, zipContent, zipName); + if (isNodeProcess()) { + // If not output path is provided on the node side, zip is not written to disk + const projectOutputPath = options.outputPath || outputPath; + if (projectOutputPath) { + await writeZipToDisk(projectOutputPath, zipContent, zipName); + } + } else { + // the browser end does not require a path + // auto download zip files + saveAs(zipContent as Blob, `${zipName}.zip`); } return { success: true, payload: zipContent }; diff --git a/modules/code-generator/src/publisher/zip/utils.ts b/modules/code-generator/src/publisher/zip/utils.ts index 10e1ad4a68..08d3a12f44 100644 --- a/modules/code-generator/src/publisher/zip/utils.ts +++ b/modules/code-generator/src/publisher/zip/utils.ts @@ -40,8 +40,7 @@ export const writeZipToDisk = ( export const generateProjectZip = async (project: ResultDir): Promise<ZipBuffer> => { let zip = new JSZip(); zip = writeFolderToZip(project, zip, true); - // const zipType = isNodeProcess() ? 'nodebuffer' : 'blob'; - const zipType = 'nodebuffer'; // 目前先只支持 node 调用 + const zipType = isNodeProcess() ? 'nodebuffer' : 'blob'; return zip.generateAsync({ type: zipType }); }; diff --git a/modules/code-generator/tests/public/publisher/zip/zip.test.ts b/modules/code-generator/tests/public/publisher/zip/zip.test.ts index ed37980d03..d51957004a 100644 --- a/modules/code-generator/tests/public/publisher/zip/zip.test.ts +++ b/modules/code-generator/tests/public/publisher/zip/zip.test.ts @@ -1,6 +1,14 @@ import CodeGen from '../../../../src'; +import fileSaver from 'file-saver'; +import * as utils from '../../../../src/publisher/zip/utils'; + +jest.mock('file-saver'); describe('public/publisher/zip/zip', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + it('should works', async () => { const zip = CodeGen.publishers.zip({ outputPath: 'demo-output', @@ -19,15 +27,15 @@ describe('public/publisher/zip/zip', () => { ], }; - expect(zip.getOutputPath()).toMatchInlineSnapshot(`"demo-output"`); + expect(zip.getOutputPath()).toMatchInlineSnapshot('"demo-output"'); - expect(zip.getProject()).toMatchInlineSnapshot(`undefined`); + expect(zip.getProject()).toMatchInlineSnapshot('undefined'); zip.setProject(demoProject); expect(zip.getProject()).toBeTruthy(); - expect(zip.getOutputPath()).toMatchInlineSnapshot(`"demo-output"`); + expect(zip.getOutputPath()).toMatchInlineSnapshot('"demo-output"'); expect(zip.setOutputPath('output')).toBe(undefined); - expect(zip.getOutputPath()).toMatchInlineSnapshot(`"output"`); + expect(zip.getOutputPath()).toMatchInlineSnapshot('"output"'); const publishRes = await zip.publish({ project: demoProject, @@ -41,4 +49,39 @@ describe('public/publisher/zip/zip', () => { const zip = CodeGen.publishers.zip({}); expect(zip.publish()).rejects.toBeTruthy(); }); + + it('should publish the project as a zip file in the browser', async () => { + const zipContent = 'zip content'; + const zipName = 'example-project'; + jest.spyOn(utils, 'isNodeProcess').mockReturnValue(false); + // new Zip 里面也有平台判断,所以这里 mock + jest.spyOn(utils, 'generateProjectZip').mockResolvedValue(zipContent as any); + const spy = jest.spyOn(fileSaver, 'saveAs'); + + const zip = CodeGen.publishers.zip({ + projectSlug: zipName, + }); + + const demoProject = { + name: 'demo', + dirs: [], + files: [ + { + name: 'package', + ext: 'json', + content: '{ "name": "demo", "version": "1.0.0" }', + }, + ], + }; + + zip.setProject(demoProject); + const publishRes = await zip.publish({ + project: demoProject, + }); + + expect(publishRes.success).toBeTruthy(); + expect(spy).toBeCalledWith(zipContent, `${zipName}.zip`); + spy.mockReset(); + spy.mockRestore(); + }); }); From 173978ffd4f8b13f6babcc5c14b2c450bca73eb7 Mon Sep 17 00:00:00 2001 From: wangwei <1021281778@qq.com> Date: Wed, 3 Jan 2024 15:17:40 +0800 Subject: [PATCH 265/361] chore(release): code-gen 1.1.7 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 5c0d91cc08..cd114fa067 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-code-generator", - "version": "1.1.6", + "version": "1.1.7", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From e1f3a11c4197317fd9a520ca014b78905096b46f Mon Sep 17 00:00:00 2001 From: LiuTeiTei <ltt_catchyou@163.com> Date: Thu, 4 Jan 2024 18:20:22 +0800 Subject: [PATCH 266/361] fix: trigger onFilterResultChanged when filtered --- .../src/views/filter-tree.ts | 5 +++++ .../src/views/tree-node.tsx | 16 +++++++++++--- .../src/views/tree-title.tsx | 22 +++++++++++++------ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/packages/plugin-outline-pane/src/views/filter-tree.ts b/packages/plugin-outline-pane/src/views/filter-tree.ts index 2a07e15c6b..793aa03cc5 100644 --- a/packages/plugin-outline-pane/src/views/filter-tree.ts +++ b/packages/plugin-outline-pane/src/views/filter-tree.ts @@ -77,6 +77,11 @@ export const matchTreeNode = ( return matchTreeNode(childNode, keywords, filterOps); }).find(Boolean); + // 如果命中了子节点,需要将该节点展开 + if (matchChild && treeNode.expandable) { + treeNode.setExpanded(true); + } + treeNode.setFilterReult({ filterWorking: true, matchChild, diff --git a/packages/plugin-outline-pane/src/views/tree-node.tsx b/packages/plugin-outline-pane/src/views/tree-node.tsx index be6e6ae2c8..11bd95d12f 100644 --- a/packages/plugin-outline-pane/src/views/tree-node.tsx +++ b/packages/plugin-outline-pane/src/views/tree-node.tsx @@ -34,7 +34,7 @@ class ModalTreeNodeView extends PureComponent<{ } componentDidMount(): void { - const rootTreeNode = this.rootTreeNode; + const { rootTreeNode } = this; rootTreeNode.onExpandableChanged(() => { this.setState({ treeChildren: rootTreeNode.children, @@ -53,7 +53,7 @@ class ModalTreeNodeView extends PureComponent<{ } render() { - const rootTreeNode = this.rootTreeNode; + const { rootTreeNode } = this; const { expanded } = rootTreeNode; const hasVisibleModalNode = !!this.modalNodesManager?.getVisibleModalNode(); @@ -98,6 +98,9 @@ export default class TreeNodeView extends PureComponent<{ conditionFlow: boolean; expandable: boolean; treeChildren: TreeNode[] | null; + filterWorking: boolean; + matchChild: boolean; + matchSelf: boolean; } = { expanded: false, selected: false, @@ -110,6 +113,9 @@ export default class TreeNodeView extends PureComponent<{ conditionFlow: false, expandable: false, treeChildren: [], + filterWorking: false, + matchChild: false, + matchSelf: false, }; eventOffCallbacks: Array<IPublicTypeDisposable | undefined> = []; @@ -154,6 +160,10 @@ export default class TreeNodeView extends PureComponent<{ treeChildren: treeNode.children, }); }); + treeNode.onFilterResultChanged(() => { + const { filterWorking: newFilterWorking, matchChild: newMatchChild, matchSelf: newMatchSelf } = treeNode.filterReult; + this.setState({ filterWorking: newFilterWorking, matchChild: newMatchChild, matchSelf: newMatchSelf }); + }); this.eventOffCallbacks.push( doc?.onDropLocationChanged(() => { this.setState({ @@ -216,7 +226,7 @@ export default class TreeNodeView extends PureComponent<{ let shouldShowModalTreeNode: boolean = this.shouldShowModalTreeNode(); // filter 处理 - const { filterWorking, matchChild, matchSelf } = treeNode.filterReult; + const { filterWorking, matchChild, matchSelf } = this.state; if (!isRootNode && filterWorking && !matchChild && !matchSelf) { // 条件过滤生效时,如果未命中本节点或子节点,则不展示该节点 // 根节点始终展示 diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index c8c0e75b09..f822bd644b 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -29,9 +29,15 @@ export default class TreeTitle extends PureComponent<{ title: string; condition?: boolean; visible?: boolean; + filterWorking: boolean; + keywords: string; + matchSelf: boolean; } = { editing: false, title: '', + filterWorking: false, + keywords: '', + matchSelf: false, }; private lastInput?: HTMLInputElement; @@ -100,6 +106,10 @@ export default class TreeTitle extends PureComponent<{ visible: !hidden, }); }); + treeNode.onFilterResultChanged(() => { + const { filterWorking: newFilterWorking, keywords: newKeywords, matchSelf: newMatchSelf } = treeNode.filterReult; + this.setState({ filterWorking: newFilterWorking, keywords: newKeywords, matchSelf: newMatchSelf }); + }); } deleteClick = () => { const { treeNode } = this.props; @@ -109,7 +119,7 @@ export default class TreeTitle extends PureComponent<{ render() { const { treeNode, isModal } = this.props; const { pluginContext } = treeNode; - const { editing } = this.state; + const { editing, filterWorking, matchSelf, keywords } = this.state; const isCNode = !treeNode.isRoot(); const { node } = treeNode; const { componentMeta } = node; @@ -125,11 +135,9 @@ export default class TreeTitle extends PureComponent<{ marginLeft: -indent, }; } - const { filterWorking, matchSelf, keywords } = treeNode.filterReult; const Extra = pluginContext.extraTitle; const { intlNode, common, config } = pluginContext; - const Tip = common.editorCabin.Tip; - const Title = common.editorCabin.Title; + const { Tip, Title } = common.editorCabin; const couldHide = availableActions.includes('hide'); const couldLock = availableActions.includes('lock'); const couldUnlock = availableActions.includes('unlock'); @@ -253,7 +261,7 @@ class RenameBtn extends PureComponent<{ }> { render() { const { intl, common } = this.props.treeNode.pluginContext; - const Tip = common.editorCabin.Tip; + const { Tip } = common.editorCabin; return ( <div className="tree-node-rename-btn" @@ -274,7 +282,7 @@ class LockBtn extends PureComponent<{ render() { const { treeNode, locked } = this.props; const { intl, common } = this.props.treeNode.pluginContext; - const Tip = common.editorCabin.Tip; + const { Tip } = common.editorCabin; return ( <div className="tree-node-lock-btn" @@ -300,7 +308,7 @@ class HideBtn extends PureComponent<{ render() { const { treeNode, hidden } = this.props; const { intl, common } = treeNode.pluginContext; - const Tip = common.editorCabin.Tip; + const { Tip } = common.editorCabin; return ( <div className="tree-node-hide-btn" From c24c3d8ae59e4ee9cf17c5816f088463aedb5a44 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 5 Jan 2024 10:33:10 +0800 Subject: [PATCH 267/361] feat: add hideComponentAction config --- docs/docs/api/configOptions.md | 6 ++++++ .../builtin-simulator/bem-tools/border-selecting.tsx | 10 +++++++--- packages/editor-core/src/config.ts | 5 +++++ packages/types/src/shell/type/engine-options.ts | 6 ++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index aaea28261d..5f6ade710f 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -216,6 +216,12 @@ config.set('enableCondition', false) 是否在只有一个 item 的时候隐藏设置 tabs +#### hideComponentAction + +`@type {boolean}` `@default {false}` + +隐藏设计器辅助层 + #### thisRequiredInJSE `@type {boolean}` `@default {true}` diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx index 4f452727d2..143c67e020 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx @@ -9,7 +9,7 @@ import { ComponentType, } from 'react'; import classNames from 'classnames'; -import { observer, computed, Tip } from '@alilc/lowcode-editor-core'; +import { observer, computed, Tip, engineConfig } from '@alilc/lowcode-editor-core'; import { createIcon, isReactComponent, isActionContentObject } from '@alilc/lowcode-utils'; import { IPublicTypeActionContentObject } from '@alilc/lowcode-types'; import { BuiltinSimulatorHost } from '../host'; @@ -47,14 +47,18 @@ export class BorderSelectingInstance extends Component<{ }); const { hideSelectTools } = observed.node.componentMeta.advanced; + const hideComponentAction = engineConfig.get('hideComponentAction'); if (hideSelectTools) { return null; } return ( - <div className={className} style={style}> - {!dragging && <Toolbar observed={observed} />} + <div + className={className} + style={style} + > + {(!dragging && !hideComponentAction) ? <Toolbar observed={observed} /> : null} </div> ); } diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 85e6097801..1c73347b74 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -159,6 +159,11 @@ const VALID_ENGINE_OPTIONS = { type: 'function', description: '应用级设计模式下,窗口为空时展示的占位组件', }, + hideComponentAction: { + type: 'boolean', + description: '是否隐藏设计器辅助层', + default: false, + }, }; const getStrictModeValue = (engineOptions: IPublicTypeEngineOptions, defaultValue: boolean): boolean => { diff --git a/packages/types/src/shell/type/engine-options.ts b/packages/types/src/shell/type/engine-options.ts index f177166530..b570d1990a 100644 --- a/packages/types/src/shell/type/engine-options.ts +++ b/packages/types/src/shell/type/engine-options.ts @@ -177,6 +177,12 @@ export interface IPublicTypeEngineOptions { * 应用级设计模式下,自动打开第一个窗口 */ enableAutoOpenFirstWindow?: boolean; + + /** + * @default false + * 隐藏设计器辅助层 + */ + hideComponentAction?: boolean; } /** From d81eb8d75da665ab9603339bfe78759fe6e2f602 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 5 Jan 2024 10:37:15 +0800 Subject: [PATCH 268/361] style(outline): update selected item style --- packages/plugin-outline-pane/src/views/style.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index 8521883b49..8a38ba749b 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -356,7 +356,7 @@ // 选中节点处理 &.selected { & > .tree-node-title { - background: var(--color-block-background-shallow); + background: var(--color-block-background-light); } & > .tree-node-branches::before { From be0456fb398c731c4492fbca83aebc8ed9e9f3f3 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 5 Jan 2024 11:32:28 +0800 Subject: [PATCH 269/361] feat: add commonUI API --- docs/docs/api/commonUI.md | 118 ++++++++++++++++++ packages/designer/src/component-meta.ts | 8 +- .../designer/src/plugin/plugin-context.ts | 3 + packages/designer/src/plugin/plugin-types.ts | 2 + .../editor-core/src/widgets/title/index.tsx | 10 +- packages/engine/src/engine-core.ts | 5 + packages/shell/src/api/commonUI.ts | 43 +++++++ packages/shell/src/api/index.ts | 3 +- packages/shell/src/index.ts | 2 + packages/types/src/shell/api/commonUI.ts | 48 +++++++ packages/types/src/shell/api/index.ts | 1 + .../types/src/shell/model/plugin-context.ts | 7 ++ packages/types/src/shell/type/tip-config.ts | 12 ++ packages/types/src/shell/type/title-config.ts | 27 +++- .../workspace/src/context/base-context.ts | 4 + 15 files changed, 281 insertions(+), 12 deletions(-) create mode 100644 docs/docs/api/commonUI.md create mode 100644 packages/shell/src/api/commonUI.ts create mode 100644 packages/types/src/shell/api/commonUI.ts diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md new file mode 100644 index 0000000000..9d1f706520 --- /dev/null +++ b/docs/docs/api/commonUI.md @@ -0,0 +1,118 @@ +--- +title: commonUI - UI 组件库 +sidebar_position: 11 +--- + +## 简介 +CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开发的插件,可以保证在不同项目和主题切换中能够保持一致性和兼容性。 + +## 组件列表 + +### Tip + +提示组件 + +| 参数 | 说明 | 类型 | 默认值 | +|-----------|--------------|---------------------------------------|--------| +| className | className | string (optional) | | +| children | tip 的内容 | IPublicTypeI18nData \| ReactNode | | +| direction | tip 的方向 | 'top' \| 'bottom' \| 'left' \| 'right' | | + + +### Title + +标题组件 + +| 参数 | 说明 | 类型 | 默认值 | +|-----------|------------|-----------------------------|--------| +| title | 标题内容 | IPublicTypeTitleContent | | +| className | className | string (optional) | | +| onClick | 点击事件 | () => void (optional) | | + +### Balloon +详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon) + +### Breadcrumb +详细文档: [Breadcrumb Documentation](https://fusion.design/pc/component/breadcrumb) + +### Button +详细文档: [Button Documentation](https://fusion.design/pc/component/button) + +### Card +详细文档: [Card Documentation](https://fusion.design/pc/component/card) + +### Checkbox +详细文档: [Checkbox Documentation](https://fusion.design/pc/component/checkbox) + +### DatePicker +详细文档: [DatePicker Documentation](https://fusion.design/pc/component/datepicker) + +### Dialog +详细文档: [Dialog Documentation](https://fusion.design/pc/component/dialog) + +### Dropdown +详细文档: [Dropdown Documentation](https://fusion.design/pc/component/dropdown) + +### Form +详细文档: [Form Documentation](https://fusion.design/pc/component/form) + +### Icon +详细文档: [Icon Documentation](https://fusion.design/pc/component/icon) + +引擎默认主题支持的 icon 列表:https://fusion.design/64063/component/icon?themeid=20133 + + +### Input +详细文档: [Input Documentation](https://fusion.design/pc/component/input) + +### Loading +详细文档: [Loading Documentation](https://fusion.design/pc/component/loading) + +### Message +详细文档: [Message Documentation](https://fusion.design/pc/component/message) + +### Overlay +详细文档: [Overlay Documentation](https://fusion.design/pc/component/overlay) + +### Pagination +详细文档: [Pagination Documentation](https://fusion.design/pc/component/pagination) + +### Radio +详细文档: [Radio Documentation](https://fusion.design/pc/component/radio) + +### Search +详细文档: [Search Documentation](https://fusion.design/pc/component/search) + +### Select +详细文档: [Select Documentation](https://fusion.design/pc/component/select) + +### SplitButton +详细文档: [SplitButton Documentation](https://fusion.design/pc/component/splitbutton) + +### Step +详细文档: [Step Documentation](https://fusion.design/pc/component/step) + +### Switch +详细文档: [Switch Documentation](https://fusion.design/pc/component/switch) + +### Tab +详细文档: [Tab Documentation](https://fusion.design/pc/component/tab) + +### Table +详细文档: [Table Documentation](https://fusion.design/pc/component/table) + +### Tree +详细文档: [Tree Documentation](https://fusion.design/pc/component/tree) + +### TreeSelect +详细文档: [TreeSelect Documentation](https://fusion.design/pc/component/treeselect) + +### Upload +详细文档: [Upload Documentation](https://fusion.design/pc/component/upload) + +### Divider +详细文档: [Divider Documentation](https://fusion.design/pc/component/divider) + +## 说明 + +如果需要其他组件,可以提issue给我们 \ No newline at end of file diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index 00c4956217..1ee1154f18 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -48,13 +48,17 @@ export function buildFilter(rule?: string | string[] | RegExp | IPublicTypeNesti return rule; } if (isRegExp(rule)) { - return (testNode: Node | IPublicTypeNodeSchema) => rule.test(testNode.componentName); + return (testNode: Node | IPublicTypeNodeSchema) => { + return rule.test(testNode.componentName); + }; } const list = ensureAList(rule); if (!list) { return null; } - return (testNode: Node | IPublicTypeNodeSchema) => list.includes(testNode.componentName); + return (testNode: Node | IPublicTypeNodeSchema) => { + return list.includes(testNode.componentName); + }; } export interface IComponentMeta extends IPublicModelComponentMeta<INode> { diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index 94e296fd1c..7f26a2b4f3 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -19,6 +19,7 @@ import { IPublicApiWorkspace, IPublicEnumPluginRegisterLevel, IPublicModelWindow, + IPublicApiCommonUI, } from '@alilc/lowcode-types'; import { IPluginContextOptions, @@ -45,6 +46,8 @@ export default class PluginContext implements workspace: IPublicApiWorkspace; registerLevel: IPublicEnumPluginRegisterLevel; editorWindow: IPublicModelWindow; + commonUI: IPublicApiCommonUI; + isPluginRegisteredInWorkspace: false; constructor( options: IPluginContextOptions, diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index 6091170f02..d648067a36 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -18,6 +18,7 @@ import { IPublicTypePluginRegisterOptions, IPublicModelWindow, IPublicEnumPluginRegisterLevel, + IPublicApiCommonUI, } from '@alilc/lowcode-types'; import PluginContext from './plugin-context'; @@ -61,6 +62,7 @@ export interface ILowCodePluginContextPrivate { set editorWindow(window: IPublicModelWindow); set registerLevel(level: IPublicEnumPluginRegisterLevel); set isPluginRegisteredInWorkspace(flag: boolean); + set commonUI(commonUI: IPublicApiCommonUI); } export interface ILowCodePluginContextApiAssembler { assembleApis( diff --git a/packages/editor-core/src/widgets/title/index.tsx b/packages/editor-core/src/widgets/title/index.tsx index 88a15ab29b..7df2676f92 100644 --- a/packages/editor-core/src/widgets/title/index.tsx +++ b/packages/editor-core/src/widgets/title/index.tsx @@ -1,7 +1,7 @@ import { Component, isValidElement, ReactNode } from 'react'; import classNames from 'classnames'; import { createIcon, isI18nData, isTitleConfig } from '@alilc/lowcode-utils'; -import { IPublicTypeTitleContent, IPublicTypeI18nData, IPublicTypeTitleConfig } from '@alilc/lowcode-types'; +import { IPublicTypeI18nData, IPublicTypeTitleConfig, IPublicTypeTitleProps } from '@alilc/lowcode-types'; import { intl } from '../../intl'; import { Tip } from '../tip'; import './title.less'; @@ -36,13 +36,7 @@ import './title.less'; return fragments; } -export class Title extends Component<{ - title: IPublicTypeTitleContent; - className?: string; - onClick?: () => void; - match?: boolean; - keywords?: string; -}> { +export class Title extends Component<IPublicTypeTitleProps> { constructor(props: any) { super(props); this.handleClick = this.handleClick.bind(this); diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 3ac4c32a75..9f29046fbe 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -51,6 +51,7 @@ import { Canvas, Workspace, Config, + CommonUI, } from '@alilc/lowcode-shell'; import { isPlainObject } from '@alilc/lowcode-utils'; import './modules/live-editing'; @@ -111,10 +112,12 @@ const innerSetters = new InnerSetters(); const setters = new Setters(innerSetters); const material = new Material(editor); +const commonUI = new CommonUI(); editor.set('project', project); editor.set('setters' as any, setters); editor.set('material', material); editor.set('innerHotkey', innerHotkey); +editor.set('commonUI' as any, commonUI); const config = new Config(engineConfig); const event = new Event(commonEvent, { prefix: 'common' }); const logger = new Logger({ level: 'warn', bizName: 'common' }); @@ -138,6 +141,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { context.plugins = plugins; context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` }); context.workspace = workspace; + context.commonUI = commonUI; context.registerLevel = IPublicEnumPluginRegisterLevel.Default; context.isPluginRegisteredInWorkspace = false; }, @@ -161,6 +165,7 @@ export { common, workspace, canvas, + commonUI, }; // declare this is open-source version export const isOpenSource = true; diff --git a/packages/shell/src/api/commonUI.ts b/packages/shell/src/api/commonUI.ts new file mode 100644 index 0000000000..718b409707 --- /dev/null +++ b/packages/shell/src/api/commonUI.ts @@ -0,0 +1,43 @@ +import { IPublicApiCommonUI } from '@alilc/lowcode-types'; +import { + Tip as InnerTip, + Title as InnerTitle, + } from '@alilc/lowcode-editor-core'; +import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; + +export class CommonUI implements IPublicApiCommonUI { + Balloon = Balloon; + Breadcrumb = Breadcrumb; + Button = Button; + Card = Card; + Checkbox = Checkbox; + DatePicker = DatePicker; + Dialog = Dialog; + Dropdown = Dropdown; + Form = Form; + Icon = Icon; + Input = Input; + Loading = Loading; + Message = Message; + Overlay = Overlay; + Pagination = Pagination; + Radio = Radio; + Search = Search; + Select = Select; + SplitButton = SplitButton; + Step = Step; + Switch = Switch; + Tab = Tab; + Table = Table; + Tree = Tree; + TreeSelect = TreeSelect; + Upload = Upload; + Divider = Divider; + + get Tip() { + return InnerTip; + } + get Title() { + return InnerTitle; + } +} diff --git a/packages/shell/src/api/index.ts b/packages/shell/src/api/index.ts index 4114926e19..3726020de0 100644 --- a/packages/shell/src/api/index.ts +++ b/packages/shell/src/api/index.ts @@ -10,4 +10,5 @@ export * from './simulator-host'; export * from './skeleton'; export * from './canvas'; export * from './workspace'; -export * from './config'; \ No newline at end of file +export * from './config'; +export * from './commonUI'; \ No newline at end of file diff --git a/packages/shell/src/index.ts b/packages/shell/src/index.ts index 6f79c78bcd..ce09ccaaa7 100644 --- a/packages/shell/src/index.ts +++ b/packages/shell/src/index.ts @@ -28,6 +28,7 @@ import { Workspace, SimulatorHost, Config, + CommonUI, } from './api'; export * from './symbols'; @@ -68,4 +69,5 @@ export { Config, SettingField, SkeletonItem, + CommonUI, }; diff --git a/packages/types/src/shell/api/commonUI.ts b/packages/types/src/shell/api/commonUI.ts new file mode 100644 index 0000000000..3d7bb57bf3 --- /dev/null +++ b/packages/types/src/shell/api/commonUI.ts @@ -0,0 +1,48 @@ +import { IPublicTypeTitleContent } from '../type'; +import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; + +export interface IPublicApiCommonUI { + Balloon: typeof Balloon; + Breadcrumb: typeof Breadcrumb; + Button: typeof Button; + Card: typeof Card; + Checkbox: typeof Checkbox; + DatePicker: typeof DatePicker; + Dialog: typeof Dialog; + Dropdown: typeof Dropdown; + Form: typeof Form; + Icon: typeof Icon; + Input: typeof Input; + Loading: typeof Loading; + Message: typeof Message; + Overlay: typeof Overlay; + Pagination: typeof Pagination; + Radio: typeof Radio; + Search: typeof Search; + Select: typeof Select; + SplitButton: typeof SplitButton; + Step: typeof Step; + Switch: typeof Switch; + Tab: typeof Tab; + Table: typeof Table; + Tree: typeof Tree; + TreeSelect: typeof TreeSelect; + Upload: typeof Upload; + Divider: typeof Divider; + + /** + * Title 组件 + * @experimental unstable API, pay extra caution when trying to use this + */ + get Tip(): React.ComponentClass<{}>; + + /** + * Tip 组件 + * @experimental unstable API, pay extra caution when trying to use this + */ + get Title(): React.ComponentClass<{ + title: IPublicTypeTitleContent | undefined; + match?: boolean; + keywords?: string | null; + }>; +} \ No newline at end of file diff --git a/packages/types/src/shell/api/index.ts b/packages/types/src/shell/api/index.ts index 3d7d765598..79f1b0dc7c 100644 --- a/packages/types/src/shell/api/index.ts +++ b/packages/types/src/shell/api/index.ts @@ -10,3 +10,4 @@ export * from './plugins'; export * from './logger'; export * from './canvas'; export * from './workspace'; +export * from './commonUI'; diff --git a/packages/types/src/shell/model/plugin-context.ts b/packages/types/src/shell/model/plugin-context.ts index 35e7e38af3..45568424de 100644 --- a/packages/types/src/shell/model/plugin-context.ts +++ b/packages/types/src/shell/model/plugin-context.ts @@ -11,6 +11,7 @@ import { IPluginPreferenceMananger, IPublicApiPlugins, IPublicApiWorkspace, + IPublicApiCommonUI, } from '../api'; import { IPublicEnumPluginRegisterLevel } from '../enum'; import { IPublicModelEngineConfig, IPublicModelWindow } from './'; @@ -102,6 +103,12 @@ export interface IPublicModelPluginContext { */ get workspace(): IPublicApiWorkspace; + /** + * commonUI API + * @tutorial https://lowcode-engine.cn/site/docs/api/commonUI + */ + get commonUI(): IPublicApiCommonUI; + /** * 插件注册层级 * @since v1.1.7 diff --git a/packages/types/src/shell/type/tip-config.ts b/packages/types/src/shell/type/tip-config.ts index fa82ab96f1..f8b271c909 100644 --- a/packages/types/src/shell/type/tip-config.ts +++ b/packages/types/src/shell/type/tip-config.ts @@ -2,8 +2,20 @@ import { IPublicTypeI18nData } from '..'; import { ReactNode } from 'react'; export interface IPublicTypeTipConfig { + + /** + * className + */ className?: string; + + /** + * tip 的内容 + */ children?: IPublicTypeI18nData | ReactNode; theme?: string; + + /** + * tip 的方向 + */ direction?: 'top' | 'bottom' | 'left' | 'right'; } diff --git a/packages/types/src/shell/type/title-config.ts b/packages/types/src/shell/type/title-config.ts index 571502bc5e..f8de287599 100644 --- a/packages/types/src/shell/type/title-config.ts +++ b/packages/types/src/shell/type/title-config.ts @@ -1,26 +1,51 @@ import { ReactNode } from 'react'; -import { IPublicTypeI18nData, IPublicTypeIconType, TipContent } from './'; +import { IPublicTypeI18nData, IPublicTypeIconType, IPublicTypeTitleContent, TipContent } from './'; + +export interface IPublicTypeTitleProps { + + /** + * 标题内容 + */ + title: IPublicTypeTitleContent; + + /** + * className + */ + className?: string; + + /** + * 点击事件 + */ + onClick?: () => void; + match?: boolean; + keywords?: string; +} /** * 描述 props 的 setter title */ export interface IPublicTypeTitleConfig { + /** * 文字描述 */ label?: IPublicTypeI18nData | ReactNode; + /** * hover 后的展现内容 */ tip?: TipContent; + /** * 文档链接,暂未实现 */ docUrl?: string; + /** * 图标 */ icon?: IPublicTypeIconType; + /** * CSS 类 */ diff --git a/packages/workspace/src/context/base-context.ts b/packages/workspace/src/context/base-context.ts index 78f32079ff..e090d1e374 100644 --- a/packages/workspace/src/context/base-context.ts +++ b/packages/workspace/src/context/base-context.ts @@ -32,6 +32,7 @@ import { Workspace, Window, Canvas, + CommonUI, } from '@alilc/lowcode-shell'; import { IPluginPreferenceMananger, @@ -127,11 +128,13 @@ export class BasicContext implements IBasicContext { const logger = getLogger({ level: 'warn', bizName: 'common' }); const skeleton = new Skeleton(innerSkeleton, 'any', true); const canvas = new Canvas(editor, true); + const commonUI = new CommonUI(); editor.set('setters', setters); editor.set('project', project); editor.set('material', material); editor.set('hotkey', hotkey); editor.set('innerHotkey', innerHotkey); + editor.set('commonUI' as any, commonUI); this.innerSetters = innerSetters; this.innerSkeleton = innerSkeleton; this.skeleton = skeleton; @@ -166,6 +169,7 @@ export class BasicContext implements IBasicContext { context.plugins = plugins; context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` }); context.canvas = canvas; + context.commonUI = commonUI; if (editorWindow) { context.editorWindow = new Window(editorWindow); } From e8aebb9aa35605c33aa69debe13a94e337507441 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 5 Jan 2024 03:44:36 +0000 Subject: [PATCH 270/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index ab6edf5cb5..4d6ef0a770 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.17", + "version": "1.2.18", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From ba53d6c69072b5d6225bd93b94eb596cd4e85d1e Mon Sep 17 00:00:00 2001 From: Arun <arun@arun.blog> Date: Thu, 4 Jan 2024 19:46:30 -0800 Subject: [PATCH 271/361] ci: Use GITHUB_OUTPUT envvar instead of set-output command --- .github/workflows/publish docs.yml | 2 +- .github/workflows/publish engine beta.yml | 2 +- .github/workflows/publish engine.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish docs.yml b/.github/workflows/publish docs.yml index e85d08f2a9..139b70239f 100644 --- a/.github/workflows/publish docs.yml +++ b/.github/workflows/publish docs.yml @@ -33,7 +33,7 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version - run: echo "::set-output name=version::$(node -p "require('./docs/package.json').version")" + run: echo "version=$(node -p "require('./docs/package.json').version")" >> $GITHUB_OUTPUT comment-pr: needs: publish-docs diff --git a/.github/workflows/publish engine beta.yml b/.github/workflows/publish engine beta.yml index 32c5b4c15b..ed4c374756 100644 --- a/.github/workflows/publish engine beta.yml +++ b/.github/workflows/publish engine beta.yml @@ -27,4 +27,4 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version - run: echo "::set-output name=version::$(node -p "require('./package.json').version")" + run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml index 6825c66fca..ad4c3963b2 100644 --- a/.github/workflows/publish engine.yml +++ b/.github/workflows/publish engine.yml @@ -26,4 +26,4 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version - run: echo "::set-output name=version::$(node -p "require('./package.json').version")" + run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT From 31a031ce4e4cc22c377aa9d1ce961c5df4cad58b Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 5 Jan 2024 15:53:58 +0800 Subject: [PATCH 272/361] feat: removed Rax packages, discontinuing support for Rax --- docs/docs/guide/appendix/npms.md | 2 - docs/docs/guide/appendix/repos.md | 16 +- docs/docs/guide/design/renderer.md | 1 - docs/docs/guide/expand/runtime/renderer.md | 1 - docs/docs/participate/index.md | 10 +- docs/docs/specs/lowcode-spec.md | 1 - package.json | 2 +- .../designer/src/builtin-simulator/host.ts | 37 +- .../src/designer/setting/setting-top-entry.ts | 15 +- packages/editor-core/src/config.ts | 2 +- packages/engine/README-zh_CN.md | 2 +- packages/engine/README.md | 2 +- packages/ignitor/build.json | 3 +- packages/rax-renderer/README.md | 49 -- packages/rax-renderer/build.json | 11 - packages/rax-renderer/demo/index.jsx | 35 - packages/rax-renderer/demo/miniapp/app.js | 1 - packages/rax-renderer/demo/miniapp/app.json | 6 - .../demo/miniapp/pages/index.acss | 0 .../demo/miniapp/pages/index.axml | 1 - .../rax-renderer/demo/miniapp/pages/index.js | 4 - .../demo/miniapp/pages/index.json | 6 - .../demo/wechat-miniprogram/app.js | 1 - .../demo/wechat-miniprogram/app.json | 6 - .../demo/wechat-miniprogram/pages/index.js | 4 - .../demo/wechat-miniprogram/pages/index.json | 6 - .../demo/wechat-miniprogram/pages/index.wxml | 1 - .../demo/wechat-miniprogram/pages/index.wxss | 0 packages/rax-renderer/package.json | 54 -- packages/rax-renderer/src/hoc/compFactory.tsx | 82 --- packages/rax-renderer/src/index.ts | 52 -- packages/rax-renderer/src/renderer/block.tsx | 25 - .../rax-renderer/src/renderer/component.tsx | 37 - packages/rax-renderer/src/renderer/page.tsx | 38 - packages/rax-renderer/tsconfig.json | 26 - packages/rax-simulator-renderer/.babelrc | 9 - .../rax-simulator-renderer/babel.config.js | 1 - packages/rax-simulator-renderer/build.json | 3 - .../rax-simulator-renderer/build.plugin.js | 5 - .../rax-simulator-renderer/build.umd.json | 38 - packages/rax-simulator-renderer/package.json | 55 -- .../UnusualComponent/index.less | 0 .../UnusualComponent/index.tsx | 34 - .../src/builtin-components/leaf.tsx | 251 ------- .../src/builtin-components/renderUtils.ts | 83 --- .../src/builtin-components/slot.tsx | 54 -- packages/rax-simulator-renderer/src/host.ts | 4 - .../rax-simulator-renderer/src/image.d.ts | 2 - packages/rax-simulator-renderer/src/index.ts | 7 - .../src/rax-use-router.js | 288 -------- .../src/renderer-view.tsx | 275 ------- .../rax-simulator-renderer/src/renderer.less | 125 ---- .../rax-simulator-renderer/src/renderer.ts | 690 ------------------ .../src/utils/create-defer.ts | 17 - .../src/utils/find-dom-nodes.ts | 18 - .../src/utils/get-client-rects.ts | 13 - .../src/utils/get-closest-node-instance.ts | 0 .../src/utils/get-device-view.ts | 23 - .../src/utils/is-dom-node.ts | 4 - .../src/utils/loader.ts | 114 --- .../src/utils/script.ts | 54 -- .../rax-simulator-renderer/src/utils/style.ts | 75 -- .../rax-simulator-renderer/src/utils/url.ts | 74 -- packages/renderer-core/src/adapter/index.ts | 15 +- .../tests/adapter/adapter.test.ts | 7 +- .../types/src/shell/type/engine-options.ts | 2 +- scripts/build.sh | 6 - scripts/sync.sh | 2 - 68 files changed, 36 insertions(+), 2851 deletions(-) delete mode 100644 packages/rax-renderer/README.md delete mode 100644 packages/rax-renderer/build.json delete mode 100644 packages/rax-renderer/demo/index.jsx delete mode 100644 packages/rax-renderer/demo/miniapp/app.js delete mode 100644 packages/rax-renderer/demo/miniapp/app.json delete mode 100644 packages/rax-renderer/demo/miniapp/pages/index.acss delete mode 100644 packages/rax-renderer/demo/miniapp/pages/index.axml delete mode 100644 packages/rax-renderer/demo/miniapp/pages/index.js delete mode 100644 packages/rax-renderer/demo/miniapp/pages/index.json delete mode 100644 packages/rax-renderer/demo/wechat-miniprogram/app.js delete mode 100644 packages/rax-renderer/demo/wechat-miniprogram/app.json delete mode 100644 packages/rax-renderer/demo/wechat-miniprogram/pages/index.js delete mode 100644 packages/rax-renderer/demo/wechat-miniprogram/pages/index.json delete mode 100644 packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxml delete mode 100644 packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxss delete mode 100644 packages/rax-renderer/package.json delete mode 100644 packages/rax-renderer/src/hoc/compFactory.tsx delete mode 100644 packages/rax-renderer/src/index.ts delete mode 100644 packages/rax-renderer/src/renderer/block.tsx delete mode 100644 packages/rax-renderer/src/renderer/component.tsx delete mode 100644 packages/rax-renderer/src/renderer/page.tsx delete mode 100644 packages/rax-renderer/tsconfig.json delete mode 100644 packages/rax-simulator-renderer/.babelrc delete mode 100644 packages/rax-simulator-renderer/babel.config.js delete mode 100644 packages/rax-simulator-renderer/build.json delete mode 100644 packages/rax-simulator-renderer/build.plugin.js delete mode 100644 packages/rax-simulator-renderer/build.umd.json delete mode 100644 packages/rax-simulator-renderer/package.json delete mode 100644 packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.less delete mode 100644 packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.tsx delete mode 100644 packages/rax-simulator-renderer/src/builtin-components/leaf.tsx delete mode 100644 packages/rax-simulator-renderer/src/builtin-components/renderUtils.ts delete mode 100644 packages/rax-simulator-renderer/src/builtin-components/slot.tsx delete mode 100644 packages/rax-simulator-renderer/src/host.ts delete mode 100644 packages/rax-simulator-renderer/src/image.d.ts delete mode 100644 packages/rax-simulator-renderer/src/index.ts delete mode 100644 packages/rax-simulator-renderer/src/rax-use-router.js delete mode 100644 packages/rax-simulator-renderer/src/renderer-view.tsx delete mode 100644 packages/rax-simulator-renderer/src/renderer.less delete mode 100644 packages/rax-simulator-renderer/src/renderer.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/create-defer.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/find-dom-nodes.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/get-client-rects.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/get-closest-node-instance.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/get-device-view.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/is-dom-node.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/loader.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/script.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/style.ts delete mode 100644 packages/rax-simulator-renderer/src/utils/url.ts diff --git a/docs/docs/guide/appendix/npms.md b/docs/docs/guide/appendix/npms.md index 93980f32ce..b0292c2739 100644 --- a/docs/docs/guide/appendix/npms.md +++ b/docs/docs/guide/appendix/npms.md @@ -12,8 +12,6 @@ sidebar_position: 3 | @alilc/lowcode-engine | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/engine | | @alilc/lowcode-plugin-designer | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/plugin-designer | | @alilc/lowcode-plugin-outline-pane | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/plugin-outline-pane | -| @alilc/lowcode-rax-renderer | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/rax-renderer | -| @alilc/lowcode-rax-simulator-renderer | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/rax-simulator-renderer | | @alilc/lowcode-react-renderer | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/react-renderer | | @alilc/lowcode-react-simulator-renderer | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/react-simulator-renderer | | @alilc/lowcode-renderer-core | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | packages/renderer-core | diff --git a/docs/docs/guide/appendix/repos.md b/docs/docs/guide/appendix/repos.md index 4fbfdc12cb..87852258d2 100644 --- a/docs/docs/guide/appendix/repos.md +++ b/docs/docs/guide/appendix/repos.md @@ -15,15 +15,13 @@ sidebar_position: 2 5. ignitor 6. plugin-designer 7. plugin-outline-pane -8. rax-renderer -9. rax-simulator-renderer -10. react-renderer -11. react-simulator-renderer -12. renderer-core -13. types -14. utils -15. material-parser -16. code-generator +8. react-renderer +9. react-simulator-renderer +10. renderer-core +11. types +12. utils +13. material-parser +14. code-generator ## 2. 引擎官方扩展包 包含了常用的设置器(setter)、跟 setter 绑定的插件等 diff --git a/docs/docs/guide/design/renderer.md b/docs/docs/guide/design/renderer.md index 4c3021b54e..4a8c43f329 100644 --- a/docs/docs/guide/design/renderer.md +++ b/docs/docs/guide/design/renderer.md @@ -11,7 +11,6 @@ sidebar_position: 4 ## npm 包与仓库信息 - React 框架渲染 npm 包:@alilc/lowcode-react-renderer -- Rax 框架渲染 npm 包:@alilc/lowcode-rax-renderer - 仓库:[https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) 下的 - packages/renderer-core - packages/react-renderer diff --git a/docs/docs/guide/expand/runtime/renderer.md b/docs/docs/guide/expand/runtime/renderer.md index 71eb755980..4e6d914bbf 100644 --- a/docs/docs/guide/expand/runtime/renderer.md +++ b/docs/docs/guide/expand/runtime/renderer.md @@ -40,7 +40,6 @@ ReactDOM.render(( ), document.getElementById('root')); ``` -- rax-renderer:npm 包替换为 @alilc/lowcode-rax-renderer #### ### 项目使用示例 > [设计器 demo](https://lowcode-engine.cn/demo/demo-general/index.html) diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md index 4540fa640d..e09f2ddad2 100644 --- a/docs/docs/participate/index.md +++ b/docs/docs/participate/index.md @@ -47,15 +47,7 @@ npm install && npm run setup [ "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/react-simulator-renderer.css", "http://localhost:5555/css/ReactSimulatorRenderer.css" - ], - [ - "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/rax-simulator-renderer.js", - "http://localhost:5555/js/RaxSimulatorRenderer.js" - ], - [ - "https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/rax-simulator-renderer.css", - "http://localhost:5555/css/RaxSimulatorRenderer.css" - ], + ] ] } ``` diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index 59ff85586c..c277214106 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -499,7 +499,6 @@ try { - 说明:组件即将从 DOM 中移除 - componentDidCatch(error, info) - 说明:组件捕获到异常 -- Rax:目前没有使用生命周期,使用 hooks 替代生命周期; 该对象由一系列 key-value 组成,key 为生命周期方法名,value 为 JSFunction 的描述,详见下方示例: diff --git a/package.json b/package.json index caabbeeb13..047b287b98 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "yarn": "^1.22.17", "rimraf": "^3.0.2", "@types/react-router": "5.1.18", - "@alilc/build-plugin-lce": "^0.0.3", + "@alilc/build-plugin-lce": "^0.0.4", "babel-jest": "^26.5.2", "@alilc/lowcode-test-mate": "^1.0.1" }, diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index eb855e4498..6efe6a68b5 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -39,6 +39,7 @@ import { isDragAnyObject, isDragNodeObject, isLocationData, + Logger, } from '@alilc/lowcode-utils'; import { isShaken, @@ -72,6 +73,8 @@ import { IScroller } from '../designer/scroller'; import { isElementNode, isDOMNodeVisible } from '../utils/misc'; import { debounce } from 'lodash'; +const logger = new Logger({ level: 'warn', bizName: 'designer' }); + export type LibraryItem = IPublicTypePackage & { package: string; library: string; @@ -122,21 +125,6 @@ const defaultSimulatorUrl = (() => { return urls; })(); -const defaultRaxSimulatorUrl = (() => { - const publicPath = getPublicPath(); - let urls; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [_, prefix = '', dev] = /^(.+?)(\/js)?\/?$/.exec(publicPath) || []; - if (dev) { - urls = [`${prefix}/css/rax-simulator-renderer.css`, `${prefix}/js/rax-simulator-renderer.js`]; - } else if (process.env.NODE_ENV === 'production') { - urls = [`${prefix}/rax-simulator-renderer.css`, `${prefix}/rax-simulator-renderer.js`]; - } else { - urls = [`${prefix}/rax-simulator-renderer.css`, `${prefix}/rax-simulator-renderer.js`]; - } - return urls; -})(); - const defaultEnvironment = [ // https://g.alicdn.com/mylib/??react/16.11.0/umd/react.production.min.js,react-dom/16.8.6/umd/react-dom.production.min.js,prop-types/15.7.2/prop-types.min.js assetItem( @@ -151,17 +139,6 @@ const defaultEnvironment = [ ), ]; -const defaultRaxEnvironment = [ - assetItem( - AssetType.JSText, - 'window.Rax=parent.Rax;window.React=parent.React;window.ReactDOM=parent.ReactDOM;window.VisualEngineUtils=parent.VisualEngineUtils;window.VisualEngine=parent.VisualEngine', - ), - assetItem( - AssetType.JSText, - 'window.PropTypes=parent.PropTypes;React.PropTypes=parent.PropTypes; window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;', - ), -]; - export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProps> { readonly isSimulator = true; @@ -467,11 +444,15 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp const libraryAsset: AssetList = this.buildLibrary(); + if (this.renderEnv === 'rax') { + logger.error('After LowcodeEngine v1.3.0, Rax is no longer supported.'); + } + const vendors = [ // required & use once assetBundle( this.get('environment') || - (this.renderEnv === 'rax' ? defaultRaxEnvironment : defaultEnvironment), + defaultEnvironment, AssetLevel.Environment, ), // required & use once @@ -484,7 +465,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp // required & use once assetBundle( this.get('simulatorUrl') || - (this.renderEnv === 'rax' ? defaultRaxSimulatorUrl : defaultSimulatorUrl), + defaultSimulatorUrl, AssetLevel.Runtime, ), ]; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index f89ff8a62b..85be74b7f6 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,4 +1,4 @@ -import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry } from '@alilc/lowcode-types'; +import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types'; import { isCustomView } from '@alilc/lowcode-utils'; import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { ISettingEntry } from './setting-entry-type'; @@ -6,7 +6,6 @@ import { ISettingField, SettingField } from './setting-field'; import { INode } from '../../document'; import type { IComponentMeta } from '../../component-meta'; import { IDesigner } from '../designer'; -import { Setters } from '@alilc/lowcode-shell'; function generateSessionId(nodes: INode[]) { return nodes @@ -19,18 +18,18 @@ export interface ISettingTopEntry extends ISettingEntry, IPublicModelSettingTopE INode, ISettingField > { - purge(): void; - - items: Array<ISettingField | IPublicTypeCustomView>; - readonly top: ISettingTopEntry; readonly parent: ISettingTopEntry; readonly path: never[]; + items: Array<ISettingField | IPublicTypeCustomView>; + componentMeta: IComponentMeta | null; + purge(): void; + getExtraPropValue(propName: string): void; setExtraPropValue(propName: string, value: any): void; @@ -92,7 +91,7 @@ export class SettingTopEntry implements ISettingTopEntry { readonly designer: IDesigner | undefined; - readonly setters: Setters; + readonly setters: IPublicApiSetters; disposeFunctions: any[] = []; @@ -103,7 +102,7 @@ export class SettingTopEntry implements ISettingTopEntry { this.id = generateSessionId(nodes); this.first = nodes[0]; this.designer = this.first.document?.designer; - this.setters = editor.get('setters') as Setters; + this.setters = editor.get('setters') as IPublicApiSetters; // setups this.setupComponentMeta(); diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 1c73347b74..a5da74742d 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -44,7 +44,7 @@ const VALID_ENGINE_OPTIONS = { }, renderEnv: { type: 'string', - enum: ['react', 'rax', 'any string value'], + enum: ['react', 'any string value'], default: 'react', description: '渲染器类型', }, diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index c99e98cf6c..5442aa58bd 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -126,7 +126,7 @@ https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.18/dist ``` #### 方式 5:使用自有 cdn -将源码中 packages/engine/dist 和 packages/(react|rax)-simulator-renderer/dist 下的文件传至你的 cdn 提供商 +将源码中 packages/engine/dist 和 packages/react-simulator-renderer/dist 下的文件传至你的 cdn 提供商 ## 🔗 相关链接 diff --git a/packages/engine/README.md b/packages/engine/README.md index 52bce86163..ae4e7fd43b 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -126,7 +126,7 @@ https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.18/dist ``` #### Method 5: Use your own cdn -Pass the files under packages/engine/dist and packages/(react|rax)-simulator-renderer/dist in the source code to your cdn provider +Pass the files under packages/engine/dist and packages/react-simulator-renderer/dist in the source code to your cdn provider ## 🔗 Related Links diff --git a/packages/ignitor/build.json b/packages/ignitor/build.json index 218373247c..f1956cf527 100644 --- a/packages/ignitor/build.json +++ b/packages/ignitor/build.json @@ -1,8 +1,7 @@ { "entry": { "AliLowCodeEngine": "../engine/src/index.ts", - "ReactSimulatorRenderer": "../react-simulator-renderer/src/index.ts", - "RaxSimulatorRenderer": "../rax-simulator-renderer/src/index.ts" + "ReactSimulatorRenderer": "../react-simulator-renderer/src/index.ts" }, "vendor": false, "devServer": { diff --git a/packages/rax-renderer/README.md b/packages/rax-renderer/README.md deleted file mode 100644 index 7b430de630..0000000000 --- a/packages/rax-renderer/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Rax Renderer - -Rax 渲染模块。 - -## 安装 - -``` -$ npm install @alilc/lowcode-rax-renderer --save -``` - -## 使用 - -```js -import { createElement, render } from 'rax'; -import DriverUniversal from 'driver-universal'; -import RaxRenderer from '@ali/lowcode-rax-renderer'; - -const components = { - View, - Text -}; - -const schema = { - componentName: 'Page', - fileName: 'home', - children: [ - { - componentName: 'View', - children: [ - { - componentName: 'Text', - props: { - type: 'primary' - }, - children: ['Welcome to Your Rax App'] - } - ] - } - ] -}; - -render( - <RaxRenderer - schema={schema} - components={components} - />, - document.getElementById('root'), { driver: DriverUniversal } -); -``` diff --git a/packages/rax-renderer/build.json b/packages/rax-renderer/build.json deleted file mode 100644 index 3edf143801..0000000000 --- a/packages/rax-renderer/build.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "plugins": [ - [ - "build-plugin-rax-component", - { - "type": "rax", - "targets": ["web"] - } - ] - ] -} diff --git a/packages/rax-renderer/demo/index.jsx b/packages/rax-renderer/demo/index.jsx deleted file mode 100644 index cfcae2a201..0000000000 --- a/packages/rax-renderer/demo/index.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import { createElement, render } from 'rax'; -import DriverUniversal from 'driver-universal'; -import View from 'rax-view'; -import Text from 'rax-text'; -import { Engine } from '../src/index'; - -const components = { - View, - Text, -}; - -const schema = { - componentName: 'Page', - fileName: 'home', - props: {}, - children: [ - { - componentName: 'View', - props: {}, - children: [ - { - componentName: 'Text', - props: { - type: 'primary', - }, - children: ['Welcome to Your Rax App!'], - }, - ], - }, - ], -}; - -render(<Engine schema={schema} components={components} />, document.getElementById('root'), { - driver: DriverUniversal, -}); diff --git a/packages/rax-renderer/demo/miniapp/app.js b/packages/rax-renderer/demo/miniapp/app.js deleted file mode 100644 index 3482935519..0000000000 --- a/packages/rax-renderer/demo/miniapp/app.js +++ /dev/null @@ -1 +0,0 @@ -App({}); diff --git a/packages/rax-renderer/demo/miniapp/app.json b/packages/rax-renderer/demo/miniapp/app.json deleted file mode 100644 index 94127c774c..0000000000 --- a/packages/rax-renderer/demo/miniapp/app.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pages": ["pages/index"], - "window": { - "defaultTitle": "demo" - } -} diff --git a/packages/rax-renderer/demo/miniapp/pages/index.acss b/packages/rax-renderer/demo/miniapp/pages/index.acss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/rax-renderer/demo/miniapp/pages/index.axml b/packages/rax-renderer/demo/miniapp/pages/index.axml deleted file mode 100644 index 41b536b4ce..0000000000 --- a/packages/rax-renderer/demo/miniapp/pages/index.axml +++ /dev/null @@ -1 +0,0 @@ -<my-component></my-component> diff --git a/packages/rax-renderer/demo/miniapp/pages/index.js b/packages/rax-renderer/demo/miniapp/pages/index.js deleted file mode 100644 index 687d87e197..0000000000 --- a/packages/rax-renderer/demo/miniapp/pages/index.js +++ /dev/null @@ -1,4 +0,0 @@ -Page({ - onLoad() {}, - onShow() {}, -}); diff --git a/packages/rax-renderer/demo/miniapp/pages/index.json b/packages/rax-renderer/demo/miniapp/pages/index.json deleted file mode 100644 index 89b15c54ca..0000000000 --- a/packages/rax-renderer/demo/miniapp/pages/index.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "defaultTitle": "Miniapp Rax Text demo", - "usingComponents": { - "my-component": "../components/Target/index" - } -} diff --git a/packages/rax-renderer/demo/wechat-miniprogram/app.js b/packages/rax-renderer/demo/wechat-miniprogram/app.js deleted file mode 100644 index 3482935519..0000000000 --- a/packages/rax-renderer/demo/wechat-miniprogram/app.js +++ /dev/null @@ -1 +0,0 @@ -App({}); diff --git a/packages/rax-renderer/demo/wechat-miniprogram/app.json b/packages/rax-renderer/demo/wechat-miniprogram/app.json deleted file mode 100644 index be00ced601..0000000000 --- a/packages/rax-renderer/demo/wechat-miniprogram/app.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pages": ["pages/index"], - "window": { - "title": "demo" - } -} diff --git a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.js b/packages/rax-renderer/demo/wechat-miniprogram/pages/index.js deleted file mode 100644 index 687d87e197..0000000000 --- a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.js +++ /dev/null @@ -1,4 +0,0 @@ -Page({ - onLoad() {}, - onShow() {}, -}); diff --git a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.json b/packages/rax-renderer/demo/wechat-miniprogram/pages/index.json deleted file mode 100644 index 9448c84eaf..0000000000 --- a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "title": "Wechat MiniProgram Rax Text demo", - "usingComponents": { - "my-component": "../components/Target/index" - } -} diff --git a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxml b/packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxml deleted file mode 100644 index 41b536b4ce..0000000000 --- a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxml +++ /dev/null @@ -1 +0,0 @@ -<my-component></my-component> diff --git a/packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxss b/packages/rax-renderer/demo/wechat-miniprogram/pages/index.wxss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json deleted file mode 100644 index 8173d6e4e1..0000000000 --- a/packages/rax-renderer/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@alilc/lowcode-rax-renderer", - "version": "1.2.5", - "description": "Rax renderer for Ali lowCode engine", - "main": "lib/index.js", - "module": "es/index.js", - "miniappConfig": { - "main": "lib/miniapp/index", - "main:wechat": "lib/wechat-miniprogram/index" - }, - "files": [ - "dist", - "es", - "lib" - ], - "keywords": [ - "low-code", - "lowcode", - "Rax" - ], - "engines": { - "npm": ">=3.0.0" - }, - "peerDependencies": { - "prop-types": "^15.7.2", - "rax": "^1.1.0" - }, - "scripts": { - "start": "build-scripts start", - "build": "build-scripts build" - }, - "dependencies": { - "@alilc/lowcode-renderer-core": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", - "rax-find-dom-node": "^1.0.1" - }, - "devDependencies": { - "@alib/build-scripts": "^0.1.0", - "build-plugin-rax-component": "^0.2.11", - "driver-universal": "^3.1.3" - }, - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org/" - }, - "repository": { - "type": "http", - "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/rax-renderer" - }, - "license": "MIT", - "homepage": "https://github.com/alibaba/lowcode-engine/#readme", - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", - "bugs": "https://github.com/alibaba/lowcode-engine/issues" -} diff --git a/packages/rax-renderer/src/hoc/compFactory.tsx b/packages/rax-renderer/src/hoc/compFactory.tsx deleted file mode 100644 index 1c821ab6d9..0000000000 --- a/packages/rax-renderer/src/hoc/compFactory.tsx +++ /dev/null @@ -1,82 +0,0 @@ -// @ts-nocheck - -import { Component, forwardRef } from 'rax'; -import PropTypes from 'prop-types'; -import { AppHelper } from '@alilc/lowcode-utils'; -import { utils, contextFactory } from '@alilc/lowcode-renderer-core'; -import componentRendererFactory from '../renderer/component'; -import blockRendererFactory from '../renderer/block'; - -const { forEach, isFileSchema } = utils; - -export default function compFactory(schema, components = {}, componentsMap = {}, config = {}) { - // 自定义组件需要有自己独立的appHelper - const appHelper = new AppHelper(config); - const CompRenderer = componentRendererFactory(); - const BlockRenderer = blockRendererFactory(); - const AppContext = contextFactory(); - - class LNCompView extends Component { - static displayName = 'LceCompFactory'; - - static version = config.version || '0.0.0'; - - static contextType = AppContext; - - static propTypes = { - forwardedRef: PropTypes.func, - }; - - render() { - if (!schema || schema.componentName !== 'Component' || !isFileSchema(schema)) { - console.warn('自定义组件模型结构异常!'); - return null; - } - const { forwardedRef, ...otherProps } = this.props; - // 低代码组件透传应用上下文 - const ctx = ['utils', 'constants', 'history', 'location', 'match']; - ctx.forEach(key => { - if (!appHelper[key] && this.context?.appHelper && this.context?.appHelper[key]) { - appHelper.set(key, this.context.appHelper[key]); - } - }); - // 支持通过context透传国际化配置 - const localeProps = {}; - const { locale, messages } = this.context; - if (locale && messages && messages[schema.fileName]) { - localeProps.locale = locale; - localeProps.messages = messages[schema.fileName]; - } - const props = { - ...schema.defaultProps, - ...localeProps, - ...otherProps, - __schema: schema, - ref: forwardedRef, - }; - - return ( - <AppContext.Consumer> - {context => { - this.context = context; - return ( - <CompRenderer - {...props} - __appHelper={appHelper} - __components={{ ...components, Component: CompRenderer, Block: BlockRenderer }} - __componentsMap={componentsMap} - /> - ); - }} - </AppContext.Consumer> - ); - } - } - - const ResComp = forwardRef((props, ref) => <LNCompView {...props} forwardedRef={ref} />); - forEach(schema.static, (val, key) => { - ResComp[key] = val; - }); - ResComp.version = config.version || '0.0.0'; - return ResComp; -} diff --git a/packages/rax-renderer/src/index.ts b/packages/rax-renderer/src/index.ts deleted file mode 100644 index 1947aa5aec..0000000000 --- a/packages/rax-renderer/src/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Component, PureComponent, createElement, createContext, forwardRef } from 'rax'; -import findDOMNode from 'rax-find-dom-node'; -import { - adapter, - addonRendererFactory, - tempRendererFactory, - rendererFactory, -} from '@alilc/lowcode-renderer-core'; -import pageRendererFactory from './renderer/page'; -import componentRendererFactory from './renderer/component'; -import blockRendererFactory from './renderer/block'; -import CompFactory from './hoc/compFactory'; - -adapter.setRuntime({ - Component, - PureComponent, - createContext, - createElement, - forwardRef, - findDOMNode, -}); - -adapter.setRenderers({ - PageRenderer: pageRendererFactory(), - ComponentRenderer: componentRendererFactory(), - BlockRenderer: blockRendererFactory(), - AddonRenderer: addonRendererFactory(), - TempRenderer: tempRendererFactory(), -}); - -function factory() { - const Renderer = rendererFactory(); - return class extends Renderer { - constructor(props: any, context: any) { - super(props, context); - } - - isValidComponent(obj: any) { - return obj?.prototype?.setState || obj?.prototype instanceof Component; - } - }; -} - -const RaxRenderer: any = factory(); -const Engine: any = RaxRenderer; - -export { - Engine, - CompFactory, -}; - -export default RaxRenderer; diff --git a/packages/rax-renderer/src/renderer/block.tsx b/packages/rax-renderer/src/renderer/block.tsx deleted file mode 100644 index 8fa4a27316..0000000000 --- a/packages/rax-renderer/src/renderer/block.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { blockRendererFactory, types } from '@alilc/lowcode-renderer-core'; - -const raxBlockRendererFactory: () => any = () => { - const OriginBlock = blockRendererFactory(); - return class BlockRenderer extends OriginBlock { - render() { - // @ts-ignore - const that: types.IRenderer = this; - const { __schema, __components } = that.props; - if (that.__checkSchema(__schema)) { - return '区块 schema 结构异常!'; - } - that.__debug(`render - ${__schema.fileName}`); - - const children = ((context) => { - that.context = context; - that.__generateCtx({}); - that.__render(); - return that.__renderComp((__components as any)?.Block, { blockContext: that }); - }); - return that.__renderContextConsumer(children); - } - }; -}; -export default raxBlockRendererFactory; diff --git a/packages/rax-renderer/src/renderer/component.tsx b/packages/rax-renderer/src/renderer/component.tsx deleted file mode 100644 index 9943b3c2f1..0000000000 --- a/packages/rax-renderer/src/renderer/component.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { componentRendererFactory, types } from '@alilc/lowcode-renderer-core'; - -const raxComponentRendererFactory: () => any = () => { - const OriginComponent = componentRendererFactory(); - return class ComponentRenderer extends OriginComponent { - render() { - // @ts-ignore - const that: types.IRenderer = this; - const { __schema, __components } = that.props; - if (that.__checkSchema(__schema)) { - return '自定义组件 schema 结构异常!'; - } - that.__debug(`render - ${__schema.fileName}`); - - const { noContainer } = that.__parseData(__schema.props); - - const children = ((context) => { - that.context = context; - that.__generateCtx({ component: that }); - that.__render(); - // 传 null,使用内置的 div 来渲染,解决在页面中渲染 vc-component 报错的问题 - return that.__renderComp(null, { - compContext: that, - blockContext: that, - }); - }); - const content = that.__renderContextConsumer(children); - - if (noContainer) { - return content; - } - - return that.__renderContent(content); - } - }; -}; -export default raxComponentRendererFactory; diff --git a/packages/rax-renderer/src/renderer/page.tsx b/packages/rax-renderer/src/renderer/page.tsx deleted file mode 100644 index f6ebd3f7cf..0000000000 --- a/packages/rax-renderer/src/renderer/page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { pageRendererFactory, types } from '@alilc/lowcode-renderer-core'; - -const raxPageRendererFactory: () => any = () => { - const OriginPage = pageRendererFactory(); - return class PageRenderer extends OriginPage { - async componentDidUpdate() { - // @ts-ignore - super.componentDidUpdate(...arguments); - } - - render() { - // @ts-ignore - const that: types.IRenderer = this; - const { __schema, __components } = that.props; - if (that.__checkSchema(__schema)) { - return '页面 schema 结构异常!'; - } - that.__debug(`render - ${__schema?.fileName}`); - - const { Page } = __components as any; - if (Page) { - const children = ((context) => { - that.context = context; - that.__render(); - return that.__renderComp(Page, { pageContext: that }); - }); - return that.__renderContextConsumer(children); - } - - return that.__renderContent(that.__renderContextConsumer((context) => { - that.context = context; - return that.__renderContextProvider({ pageContext: that }); - })); - } - }; -}; - -export default raxPageRendererFactory; \ No newline at end of file diff --git a/packages/rax-renderer/tsconfig.json b/packages/rax-renderer/tsconfig.json deleted file mode 100644 index 7e264d1f05..0000000000 --- a/packages/rax-renderer/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2015", "dom"], - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "strict": false, - "strictPropertyInitialization": false, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "jsx": "react", - "jsxFactory": "createElement", - "importHelpers": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "sourceMap": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "outDir": "lib" - }, - "exclude": ["test", "lib", "es", "node_modules"], - "include": [ - "src" - ] -} diff --git a/packages/rax-simulator-renderer/.babelrc b/packages/rax-simulator-renderer/.babelrc deleted file mode 100644 index e0e2e5f343..0000000000 --- a/packages/rax-simulator-renderer/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "plugins": [ - ["@babel/plugin-transform-react-jsx", { - "pragma": "createElement", // default pragma is React.createElement - "pragmaFrag": "createFragment", // default is React.Fragment - "throwIfNamespace": false // defaults to true - }] - ] -} diff --git a/packages/rax-simulator-renderer/babel.config.js b/packages/rax-simulator-renderer/babel.config.js deleted file mode 100644 index c5986f2bc0..0000000000 --- a/packages/rax-simulator-renderer/babel.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../babel.config'); \ No newline at end of file diff --git a/packages/rax-simulator-renderer/build.json b/packages/rax-simulator-renderer/build.json deleted file mode 100644 index e7ae1dcf7a..0000000000 --- a/packages/rax-simulator-renderer/build.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "plugins": ["@alilc/build-plugin-lce", "./build.plugin.js"] -} diff --git a/packages/rax-simulator-renderer/build.plugin.js b/packages/rax-simulator-renderer/build.plugin.js deleted file mode 100644 index d613f1f56a..0000000000 --- a/packages/rax-simulator-renderer/build.plugin.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = ({ onGetWebpackConfig }) => { - onGetWebpackConfig((config) => { - config.performance.hints(false); - }); -}; diff --git a/packages/rax-simulator-renderer/build.umd.json b/packages/rax-simulator-renderer/build.umd.json deleted file mode 100644 index 833c92b246..0000000000 --- a/packages/rax-simulator-renderer/build.umd.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "entry": { - "rax-simulator-renderer": "src/index" - }, - "sourceMap": true, - "library": "___RaxSimulatorRenderer___", - "libraryTarget": "umd", - "externals": { - "react": "var window.React", - "react-dom": "var window.ReactDOM", - "prop-types": "var window.PropTypes", - "@alifd/next": "var Next", - "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", - "rax": "var window.Rax", - "moment": "var moment", - "lodash": "var _" - }, - "polyfill": false, - "outputDir": "dist", - "vendor": false, - "ignoreHtmlTemplate": true, - "plugins": [ - "build-plugin-react-app", - [ - "build-plugin-fusion", - { - "externalNext": "umd" - } - ], - [ - "build-plugin-moment-locales", - { - "locales": ["zh-cn"] - } - ], - "./build.plugin.js" - ] -} diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json deleted file mode 100644 index f264380ec1..0000000000 --- a/packages/rax-simulator-renderer/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.2.5", - "description": "rax simulator renderer for alibaba lowcode designer", - "main": "lib/index.js", - "module": "es/index.js", - "license": "MIT", - "files": [ - "dist" - ], - "scripts": { - "build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build", - "build:umd": "build-scripts build --config build.umd.json" - }, - "dependencies": { - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-rax-renderer": "1.2.5", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", - "classnames": "^2.2.6", - "driver-universal": "^3.1.3", - "history": "^5.0.0", - "lodash": "^4.17.19", - "mobx": "^6.3.0", - "mobx-react": "^7.2.0", - "path-to-regexp": "3.2.0", - "rax-find-dom-node": "^1.0.0", - "react": "^16", - "react-dom": "^16.7.0" - }, - "devDependencies": { - "@alib/build-scripts": "^0.1.18", - "@babel/plugin-transform-react-jsx": "^7.10.4", - "@types/classnames": "^2.2.7", - "@types/node": "^13.7.1", - "@types/rax": "^1.0.0", - "@types/react": "^16", - "@types/react-dom": "^16", - "build-plugin-rax-component": "^0.2.11" - }, - "peerDependencies": { - "rax": "^1.1.0" - }, - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org/" - }, - "repository": { - "type": "http", - "url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/rax-simulator-renderer" - }, - "homepage": "https://github.com/alibaba/lowcode-engine/#readme", - "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6", - "bugs": "https://github.com/alibaba/lowcode-engine/issues" -} diff --git a/packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.less b/packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.less deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.tsx b/packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.tsx deleted file mode 100644 index 6608942c4b..0000000000 --- a/packages/rax-simulator-renderer/src/builtin-components/UnusualComponent/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Component } from 'rax'; -import lg from '@ali/vu-logger'; - -import './index.less'; - -export class UnknownComponent extends Component { - props: { - _componentName: string; - }; - - render() { - lg.log('ERROR_NO_COMPONENT_VIEW'); - lg.error('Error component information:', this.props); - return <div className="engine-unknow-component">组件 {this.props._componentName} 无视图,请打开控制台排查</div>; - } -} - -export class FaultComponent extends Component { - props: { - _componentName: string; - }; - - render() { - return <div className="engine-fault-component">组件 {this.props._componentName} 渲染错误,请打开控制台排查</div>; - } -} - -export class HiddenComponent extends Component { - render() { - return <div className="engine-hidden-component">在本页面不显示</div>; - } -} - -export default { FaultComponent, HiddenComponent, UnknownComponent }; diff --git a/packages/rax-simulator-renderer/src/builtin-components/leaf.tsx b/packages/rax-simulator-renderer/src/builtin-components/leaf.tsx deleted file mode 100644 index 5276b0018d..0000000000 --- a/packages/rax-simulator-renderer/src/builtin-components/leaf.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import { Component } from 'rax'; - -class Leaf extends Component { - static displayName = 'Leaf'; - - static componentMetadata = { - componentName: 'Leaf', - configure: { - props: [{ - name: 'children', - setter: 'StringSetter', - }], - // events/className/style/general/directives - supports: false, - }, - }; - - render() { - const { children } = this.props; - return children; - } -} - -export default Leaf; - -// import { Component, createElement } from 'rax'; -// import findDOMNode from 'rax-find-dom-node'; -// import { each, get, omit } from 'lodash'; -// import { getView, setNativeNode, createNodeStyleSheet } from '../renderUtils'; - -// import { FaultComponent, HiddenComponent, UnknownComponent } from '../UnusualComponent'; - -// export interface ILeaf { -// leaf: any; -// } -// export default class Leaf extends Component<ILeaf, {}> { -// static displayName = 'Leaf'; - -// state = { -// hasError: false, -// }; - -// willDetach: any[]; - -// styleSheet: any; - -// context: any; -// refs: any; - -// componentWillMount() { -// const { leaf } = this.props; -// this.willDetach = [ -// leaf.onPropsChange(() => { -// // 强制刷新 -// this.setState(this.state); -// }), -// leaf.onChildrenChange(() => { -// // 强制刷新 -// this.setState(this.state); -// }), -// leaf.onStatusChange((status: { dropping: boolean }, field: string) => { -// // console.log({...status}, field) -// if (status.dropping !== false) { -// // 当 dropping 为 Insertion 对象时,强制渲染会出错,原因待查 -// return; -// } -// if (field === 'dragging' || field === 'dropping' || field === 'pseudo' || field === 'visibility') { -// // 强制刷新 -// this.setState(this.state); -// } -// }), -// ]; - -// /** -// * while props replaced -// * bind the new event on it -// */ -// leaf.onPropsReplace(() => { -// this.willDetach[0](); -// this.willDetach[0] = leaf.onPropsChange(() => { -// // 强制刷新 -// this.setState(this.state); -// }); -// }); -// } - -// componentDidMount() { -// this.modifyDOM(); -// } - -// shouldComponentUpdate() { -// // forceUpdate 的替代方案 -// return true; -// // const pageCanRefresh = this.leaf.getPage().canRefresh(); -// // if (pageCanRefresh) { -// // return pageCanRefresh; -// // } -// // const getExtProps = obj => { -// // const { leaf, ...props } = obj; -// // return props; -// // }; -// // return !shallowEqual(getExtProps(this.props), getExtProps(nextProps)); -// } - -// componentDidUpdate() { -// this.modifyDOM(); -// } - -// componentWillUnmount() { -// if (this.willDetach) { -// this.willDetach.forEach((off) => off()); -// } -// setNativeNode(this.props.leaf, null); -// } - -// componentDidCatch() { -// this.setState({ hasError: true }, () => { -// console.log('error'); -// }); -// } - -// modifyDOM() { -// const shell = findDOMNode(this); -// const { leaf } = this.props; -// // 与 React 不同,rax 的 findDOMNode 找不到节点时, -// // shell 会是 <!-- empty -->,而不是 null, -// // 所以这里进行是否为注释的判断 -// if (shell && shell.nodeType !== window.Node.COMMENT_NODE) { -// setNativeNode(leaf, shell); -// if (leaf.getStatus('dragging')) { -// get(shell, 'classList').add('engine-dragging'); -// } else { -// get(shell, 'classList').remove('engine-dragging'); -// } -// each(get(shell, 'classList'), (cls) => { -// if (cls.substring(0, 8) === '-pseudo-') { -// get(shell, 'classList').remove(cls); -// } -// }); -// const pseudo = leaf.getStatus('pseudo'); -// if (pseudo) { -// get(shell, 'classList').add(`-pseudo-${pseudo}`); -// } -// } else { -// setNativeNode(leaf, null); -// } -// } - -// render() { -// const props = omit(this.props, ['leaf']); -// const { leaf } = this.props; -// const componentName = leaf.getComponentName(); - -// const View = getView(componentName); - -// const newProps = { -// _componentName: componentName, -// }; - -// if (!View) { -// return createElement(UnknownComponent, { -// // _componentName: componentName, -// ...newProps, -// }); -// } - -// let staticProps = { -// ...leaf.getStaticProps(false), -// ...props, -// _componentName: componentName, -// _leaf: leaf, -// componentId: leaf.getId(), -// }; - -// if (!leaf.isVisibleInPane()) { -// return null; -// } - -// if (!leaf.isVisible()) { -// return createElement(HiddenComponent, { -// ...staticProps, -// }); -// } - -// if (this.state.hasError) { -// return createElement(FaultComponent, { -// // _componentName: componentName, -// ...newProps, -// }); -// } - -// if (this.styleSheet) { -// this.styleSheet.parentNode.removeChild(this.styleSheet); -// } - -// this.styleSheet = createNodeStyleSheet(staticProps); - -// if (leaf.ableToModifyChildren()) { -// const children = leaf -// .getChildren() -// .filter((child: any) => child.getComponentName() !== 'Slot') -// .map((child: any) => -// createElement(Leaf, { -// key: child.getId(), -// leaf: child, -// }), -// ); -// // const insertion = leaf.getStatus('dropping'); -// // InsertionGhost 都是React节点,用Rax渲染会报错,后面这些节点需要通过Rax组件来实现 -// // if (children.length < 1 && insertion && insertion.getIndex() !== null) { - -// // //children = []; -// // children = [<InsertionGhost key="insertion" />]; -// // } else if (insertion && insertion.isNearEdge()) { -// // if (insertion.isNearAfter()) { -// // children.push(<InsertionGhost key="insertion" />); -// // } else { -// // children.unshift(<InsertionGhost key="insertion" />); -// // } -// // } -// staticProps = { -// ...staticProps, -// ...this.processSlots(this.props.leaf.getChildren()), -// }; - -// return createElement( -// View, -// { -// ...staticProps, -// }, -// children, -// ); -// } - -// return createElement(View, { -// ...staticProps, -// }); -// } - -// processSlots(children: Rax.RaxNodeArray) { -// const slots: any = {}; -// children && -// children.length && -// children.forEach((child: any) => { -// if (child.getComponentName() === 'Slot') { -// slots[child.getPropValue('slotName')] = <Leaf key={child.getId()} leaf={child} />; -// } -// }); -// return slots; -// } -// } diff --git a/packages/rax-simulator-renderer/src/builtin-components/renderUtils.ts b/packages/rax-simulator-renderer/src/builtin-components/renderUtils.ts deleted file mode 100644 index 10f8438fb2..0000000000 --- a/packages/rax-simulator-renderer/src/builtin-components/renderUtils.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { isObject } from 'lodash'; -import { css } from '@alilc/lowcode-utils'; - -const { toCss } = css; -const engine = (window as any).VisualEngine; -const { Trunk, Viewport } = engine; - -export const NativeNodeCache: any = {}; - -function ucfirst(s: string) { - return s.charAt(0).toUpperCase() + s.substring(1); -} - -export function shallowEqual(obj: { [key: string]: string }, tObj: { [key: string]: string }) { - for (const i in obj) { - if (Object.prototype.hasOwnProperty.call(obj, i) && obj[i] !== tObj[i]) { - return false; - } - } - return true; -} - -export function createNodeStyleSheet(props: any) { - if (props && props.fieldId) { - let styleProp = props.__style__; - - if (isObject(styleProp)) { - styleProp = toCss(styleProp); - } - - if (typeof styleProp === 'string') { - const s = document.createElement('style'); - const cssId = `_style_pesudo_${ props.fieldId}`; - const cssClass = `_css_pesudo_${ props.fieldId}`; - - props.className = cssClass; - s.setAttribute('type', 'text/css'); - s.setAttribute('id', cssId); - document.getElementsByTagName('head')[0].appendChild(s); - - s.appendChild( - document.createTextNode( - styleProp - .replace(/(\d+)rpx/g, (a, b) => { - return `${b / 2}px`; - }) - .replace(/:root/g, `.${ cssClass}`), - ), - ); - return s; - } - } -} - -export function setNativeNode(leaf: any, node: Rax.RaxNode) { - const id = leaf.getId(); - if (NativeNodeCache[id] === node) { - return; - } - NativeNodeCache[id] = node; - leaf.mountChange(); -} - -export function getView(componentName: string) { - // let view = new Trunk().getPrototypeView(componentName); - let view = Trunk.getPrototypeView(componentName); - if (!view) { - return null; - } - const viewport = Viewport.getViewport(); - if (viewport) { - const [mode, device] = viewport.split('-', 2).map(ucfirst); - if (view.hasOwnProperty(device)) { - view = view[device]; - } - - if (view.hasOwnProperty(mode)) { - view = view[mode]; - } - } - - return view; -} diff --git a/packages/rax-simulator-renderer/src/builtin-components/slot.tsx b/packages/rax-simulator-renderer/src/builtin-components/slot.tsx deleted file mode 100644 index 3a77491bc0..0000000000 --- a/packages/rax-simulator-renderer/src/builtin-components/slot.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { Component } from 'rax'; - -class Slot extends Component { - static displayName = 'Slot'; - - static componentMetadata = { - componentName: 'Slot', - configure: { - props: [{ - name: '___title', - title: { - type: 'i18n', - 'en-US': 'Slot Title', - 'zh-CN': '插槽标题', - }, - setter: 'StringSetter', - defaultValue: '插槽容器', - }, { - name: '___params', - title: { - type: 'i18n', - 'en-US': 'Slot Params', - 'zh-CN': '插槽入参', - }, - setter: { - componentName: 'ArraySetter', - props: { - itemSetter: { - componentName: 'StringSetter', - props: { - placeholder: { - type: 'i18n', - 'zh-CN': '参数名称', - 'en-US': 'Argument Name', - }, - }, - }, - }, - }, - }], - // events/className/style/general/directives - supports: false, - }, - }; - - render() { - const { children } = this.props; - return ( - <div className="lc-container">{children}</div> - ); - } -} - -export default Slot; diff --git a/packages/rax-simulator-renderer/src/host.ts b/packages/rax-simulator-renderer/src/host.ts deleted file mode 100644 index c5cf2e3e1c..0000000000 --- a/packages/rax-simulator-renderer/src/host.ts +++ /dev/null @@ -1,4 +0,0 @@ -// NOTE: 仅做类型标注,切勿做其它用途 -import { BuiltinSimulatorHost } from '@alilc/lowcode-designer'; - -export const host: BuiltinSimulatorHost = (window as any).LCSimulatorHost; diff --git a/packages/rax-simulator-renderer/src/image.d.ts b/packages/rax-simulator-renderer/src/image.d.ts deleted file mode 100644 index 7ed4ad925c..0000000000 --- a/packages/rax-simulator-renderer/src/image.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare module 'rax-find-dom-node'; -declare module '@alilc/lowcode-rax-renderer/lib/index'; diff --git a/packages/rax-simulator-renderer/src/index.ts b/packages/rax-simulator-renderer/src/index.ts deleted file mode 100644 index 3a88726657..0000000000 --- a/packages/rax-simulator-renderer/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import renderer from './renderer'; - -if (typeof window !== 'undefined') { - (window as any).SimulatorRenderer = renderer; -} - -export default renderer; diff --git a/packages/rax-simulator-renderer/src/rax-use-router.js b/packages/rax-simulator-renderer/src/rax-use-router.js deleted file mode 100644 index 9a399a9478..0000000000 --- a/packages/rax-simulator-renderer/src/rax-use-router.js +++ /dev/null @@ -1,288 +0,0 @@ -// Inspired by react-router and universal-router -import { useState, useEffect, useLayoutEffect, createElement } from 'rax'; -import pathToRegexp from 'path-to-regexp'; - -const cache = {}; -function decodeParam(val) { - try { - return decodeURIComponent(val); - } catch (err) { - return val; - } -} - -function matchPath(route, pathname, parentParams) { - let { path, routes, exact: end = true, strict = false, sensitive = false } = route; - // If not has path or has routes that should do not exact match - if (path == null || routes) { - end = false; - } - - // Default path is empty - path = path || ''; - - const regexpCacheKey = `${path}|${end}|${strict}|${sensitive}`; - const keysCacheKey = `${regexpCacheKey }|`; - - let regexp = cache[regexpCacheKey]; - const keys = cache[keysCacheKey] || []; - - if (!regexp) { - regexp = pathToRegexp(path, keys, { - end, - strict, - sensitive, - }); - cache[regexpCacheKey] = regexp; - cache[keysCacheKey] = keys; - } - - const result = regexp.exec(pathname); - if (!result) { - return null; - } - - const url = result[0]; - const params = { ...parentParams, history: router.history, location: router.history.location }; - - for (let i = 1; i < result.length; i++) { - const key = keys[i - 1]; - const prop = key.name; - const value = result[i]; - if (value !== undefined || !Object.prototype.hasOwnProperty.call(params, prop)) { - if (key.repeat) { - params[prop] = value ? value.split(key.delimiter).map(decodeParam) : []; - } else { - params[prop] = value ? decodeParam(value) : value; - } - } - } - - return { - path: !end && url.charAt(url.length - 1) === '/' ? url.slice(1) : url, - params, - }; -} - -function matchRoute(route, baseUrl, pathname, parentParams) { - let matched; - let childMatches; - let childIndex = 0; - - return { - next() { - if (!matched) { - matched = matchPath(route, pathname, parentParams); - - if (matched) { - return { - done: false, - $: { - route, - baseUrl, - path: matched.path, - params: matched.params, - }, - }; - } - } - - if (matched && route.routes) { - while (childIndex < route.routes.length) { - if (!childMatches) { - const childRoute = route.routes[childIndex]; - childRoute.parent = route; - - childMatches = matchRoute( - childRoute, - baseUrl + matched.path, - pathname.slice(matched.path.length), - matched.params, - ); - } - - const childMatch = childMatches.next(); - if (!childMatch.done) { - return { - done: false, - $: childMatch.$, - }; - } - - childMatches = null; - childIndex++; - } - } - - return { done: true }; - }, - }; -} - -let _initialized = false; -let _routerConfig = null; -const router = { - history: null, - handles: [], - errorHandler() { }, - addHandle(handle) { - return router.handles.push(handle); - }, - removeHandle(handleId) { - router.handles[handleId - 1] = null; - }, - triggerHandles(component) { - router.handles.forEach((handle) => { - handle && handle(component); - }); - }, - match(fullpath) { - if (fullpath == null) return; - - router.fullpath = fullpath; - - const parent = router.root; - const matched = matchRoute( - parent, - parent.path, - fullpath, - ); - - function next(parent) { - const current = matched.next(); - - if (current.done) { - const error = new Error(`No match for ${fullpath}`); - return router.errorHandler(error, router.history.location); - } - - let { component } = current.$.route; - if (typeof component === 'function') { - component = component(current.$.params, router.history.location); - } - if (component instanceof Promise) { - // Lazy loading component by import('./Foo') - return component.then((component) => { - // Check current fullpath avoid router has changed before lazy loading complete - if (fullpath === router.fullpath) { - router.triggerHandles(component); - } - }); - } else if (component != null) { - router.triggerHandles(component); - return component; - } else { - return next(parent); - } - } - - return next(parent); - }, -}; - -function matchLocation({ pathname }) { - router.match(pathname); -} - - -function getInitialComponent(routerConfig) { - let InitialComponent = []; - - if (_routerConfig === null) { - if (process.env.NODE_ENV !== 'production') { - if (!routerConfig) { - throw new Error('Error: useRouter should have routerConfig, see: https://www.npmjs.com/package/rax-use-router.'); - } - if (!routerConfig.history || !routerConfig.routes) { - throw new Error('Error: routerConfig should contain history and routes, see: https://www.npmjs.com/package/rax-use-router.'); - } - } - _routerConfig = routerConfig; - } - if (_routerConfig.InitialComponent) { - InitialComponent = _routerConfig.InitialComponent; - } - router.history = _routerConfig.history; - - return InitialComponent; -} - -let unlisten = null; -let handleId = null; -let pathes = ''; -export function useRouter(routerConfig) { - const [component, setComponent] = useState(getInitialComponent(routerConfig)); - - let newPathes = ''; - if (routerConfig) { - _routerConfig = routerConfig; - const { routes } = _routerConfig; - router.root = Array.isArray(routes) ? { routes } : routes; - if (Array.isArray(routes)) { - newPathes = routes.map(it => it.path).join(','); - } else { - newPathes = routes.path; - } - } - if (_initialized && _routerConfig.history) { - if (newPathes !== pathes) { - matchLocation(_routerConfig.history.location); - pathes = newPathes; - } - } - - useLayoutEffect(() => { - if (unlisten) { - unlisten(); - unlisten = null; - } - - if (handleId) { - router.removeHandle(handleId); - handleId = null; - } - - const { history } = _routerConfig; - const { routes } = _routerConfig; - - router.root = Array.isArray(routes) ? { routes } : routes; - - handleId = router.addHandle((component) => { - setComponent(component); - }); - - // Init path match - if (_initialized || !_routerConfig.InitialComponent) { - matchLocation(history.location); - pathes = newPathes; - } - - unlisten = history.listen(({ location }) => { - matchLocation(location); - pathes = newPathes; - }); - - _initialized = true; - - return () => { - pathes = ''; - router.removeHandle(handleId); - handleId = null; - unlisten(); - unlisten = null; - }; - }, []); - - return { component }; -} - -export function withRouter(Component) { - function Wrapper(props) { - const { history } = router; - return createElement(Component, { ...props, history, location: history.location }); - } - - Wrapper.displayName = `withRouter(${ Component.displayName || Component.name })`; - Wrapper.WrappedComponent = Component; - return Wrapper; -} diff --git a/packages/rax-simulator-renderer/src/renderer-view.tsx b/packages/rax-simulator-renderer/src/renderer-view.tsx deleted file mode 100644 index bc39cddea0..0000000000 --- a/packages/rax-simulator-renderer/src/renderer-view.tsx +++ /dev/null @@ -1,275 +0,0 @@ -import RaxRenderer from '@alilc/lowcode-rax-renderer'; -import { History } from 'history'; -import { Component, createElement, Fragment } from 'rax'; -import { useRouter } from './rax-use-router'; -import { DocumentInstance, SimulatorRendererContainer } from './renderer'; -import './renderer.less'; -import { uniqueId } from '@alilc/lowcode-utils'; -import { GlobalEvent } from '@alilc/lowcode-types'; -import { host } from './host'; - -// patch cloneElement avoid lost keyProps -const originCloneElement = (window as any).Rax.cloneElement; -(window as any).Rax.cloneElement = (child: any, { _leaf, ...props }: any = {}, ...rest: any[]) => { - if (child.ref && props.ref) { - const dRef = props.ref; - const cRef = child.ref; - props.ref = (x: any) => { - if (cRef) { - if (typeof cRef === 'function') { - cRef(x); - } else { - try { - cRef.current = x; - } catch (e) { - console.error(e); - } - } - } - if (dRef) { - if (typeof dRef === 'function') { - dRef(x); - } else { - try { - dRef.current = x; - } catch (e) { - console.error(e); - } - } - } - }; - } - return originCloneElement(child, props, ...rest); -}; - -export default class SimulatorRendererView extends Component<{ rendererContainer: SimulatorRendererContainer }> { - private unlisten: any; - - componentDidMount() { - const { rendererContainer } = this.props; - this.unlisten = rendererContainer.onLayoutChange(() => { - this.forceUpdate(); - }); - } - - componentWillUnmount() { - if (this.unlisten) { - this.unlisten(); - } - } - - render() { - const { rendererContainer } = this.props; - return ( - <Layout rendererContainer={rendererContainer}> - <Routes rendererContainer={rendererContainer} history={rendererContainer.history} /> - </Layout> - ); - } -} - -export const Routes = (props: { - rendererContainer: SimulatorRendererContainer; - history: History; -}) => { - const { rendererContainer, history } = props; - const { documentInstances } = rendererContainer; - - const routes = { - history, - routes: documentInstances.map(instance => { - return { - path: instance.path, - component: (props: any) => <Renderer key={instance.id} rendererContainer={rendererContainer} documentInstance={instance} {...props} />, - }; - }), - }; - const { component } = useRouter(routes); - return component; -}; - -function ucfirst(s: string) { - return s.charAt(0).toUpperCase() + s.substring(1); -} -function getDeviceView(view: any, device: string, mode: string) { - if (!view || typeof view === 'string') { - return view; - } - - // compatible vision Mobile | Preview - device = ucfirst(device); - if (device === 'Mobile' && view.hasOwnProperty(device)) { - view = view[device]; - } - mode = ucfirst(mode); - if (mode === 'Preview' && view.hasOwnProperty(mode)) { - view = view[mode]; - } - return view; -} - -class Layout extends Component<{ rendererContainer: SimulatorRendererContainer }> { - constructor(props: any) { - super(props); - this.props.rendererContainer.onReRender(() => { - this.forceUpdate(); - }); - } - - render() { - const { rendererContainer, children } = this.props; - const { layout } = rendererContainer; - - if (layout) { - const { Component, props, componentName } = layout; - if (Component) { - return <Component props={props}>{children}</Component>; - } - if (componentName && rendererContainer.getComponent(componentName)) { - return createElement( - rendererContainer.getComponent(componentName), - { - ...props, - rendererContainer, - }, - [children], - ); - } - } - - return <Fragment>{children}</Fragment>; - } -} - -class Renderer extends Component<{ - rendererContainer: SimulatorRendererContainer; - documentInstance: DocumentInstance; -}> { - private unlisten: any; - private key: string; - private startTime: number | null = null; - - componentWillMount() { - this.key = uniqueId('renderer'); - } - - componentDidMount() { - const { documentInstance } = this.props; - this.unlisten = documentInstance.onReRender((params) => { - if (params && params.shouldRemount) { - this.key = uniqueId('renderer'); - } - this.forceUpdate(); - }); - } - - componentWillUnmount() { - if (this.unlisten) { - this.unlisten(); - } - } - shouldComponentUpdate() { - return false; - } - - componentDidUpdate() { - if (this.startTime) { - const time = Date.now() - this.startTime; - const nodeCount = host.designer.currentDocument?.getNodeCount?.(); - host.designer.editor?.eventBus.emit(GlobalEvent.Node.Rerender, { - componentName: 'Renderer', - type: 'All', - time, - nodeCount, - }); - } - } - - schemaChangedSymbol = false; - - getSchemaChangedSymbol = () => { - return this.schemaChangedSymbol; - }; - - setSchemaChangedSymbol = (symbol: boolean) => { - this.schemaChangedSymbol = symbol; - }; - - render() { - const { documentInstance } = this.props; - const { container, document } = documentInstance; - const { designMode, device } = container; - const { rendererContainer: renderer } = this.props; - this.startTime = Date.now(); - this.schemaChangedSymbol = false; - - return ( - <RaxRenderer - schema={documentInstance.schema} - components={renderer.components} - appHelper={renderer.context} - context={renderer.context} - device={device} - designMode={renderer.designMode} - key={this.key} - __host={host} - __container={container} - suspended={documentInstance.suspended} - self={documentInstance.scope} - onCompGetRef={(schema: any, ref: any) => { - documentInstance.mountInstance(schema.id, ref); - }} - thisRequiredInJSE={host.thisRequiredInJSE} - documentId={document.id} - getNode={(id: string) => documentInstance.getNode(id) as any} - rendererName="PageRenderer" - customCreateElement={(Component: any, props: any, children: any) => { - const { __id, ...viewProps } = props; - viewProps.componentId = __id; - const leaf = documentInstance.getNode(__id); - viewProps._leaf = leaf; - viewProps._componentName = leaf?.componentName; - // 如果是容器 && 无children && 高宽为空 增加一个占位容器,方便拖动 - if ( - !viewProps.dataSource && - leaf?.isContainer() && - (children == null || (Array.isArray(children) && !children.length)) && - (!viewProps.style || Object.keys(viewProps.style).length === 0) - ) { - children = ( - <div className="lc-container-placeholder" style={viewProps.placeholderStyle}> - {viewProps.placeholder || '拖拽组件或模板到这里'} - </div> - ); - } - - // if (viewProps._componentName === 'Menu') { - // Object.assign(viewProps, { - // _componentName: 'Menu', - // className: '_css_pesudo_menu_kbrzyh0f', - // context: { VE: (window as any).VisualLowCodeRenderer }, - // direction: undefined, - // events: { ignored: true }, - // fieldId: 'menu_kbrzyh0f', - // footer: '', - // header: '', - // mode: 'inline', - // onItemClick: { ignored: true }, - // onSelect: { ignored: true }, - // popupAlign: 'follow', - // selectMode: false, - // triggerType: 'click', - // }); - // console.info('menuprops', viewProps); - // } - - return createElement( - getDeviceView(Component, device, designMode), - viewProps, - leaf?.isContainer() ? (children == null ? [] : Array.isArray(children) ? children : [children]) : children, - ); - }} - /> - ); - } -} diff --git a/packages/rax-simulator-renderer/src/renderer.less b/packages/rax-simulator-renderer/src/renderer.less deleted file mode 100644 index b71dde9896..0000000000 --- a/packages/rax-simulator-renderer/src/renderer.less +++ /dev/null @@ -1,125 +0,0 @@ -body, html { - display: block; - background: white; - padding: 0; - margin: 0; -} - -html.engine-cursor-move, html.engine-cursor-move * { - cursor: grabbing !important; -} - -html.engine-cursor-copy, html.engine-cursor-copy * { - cursor: copy !important; -} - -html.engine-cursor-ew-resize, html.engine-cursor-ew-resize * { - cursor: ew-resize !important; -} - -::-webkit-scrollbar { - display: none; -} - -.lc-container { - &:empty { - background: #f2f3f5; - color: #a7b1bd; - outline: 1px dashed rgba(31, 56, 88, 0.2); - outline-offset: -1px !important; - height: 66px; - max-height: 100%; - min-width: 140px; - text-align: center; - overflow: hidden; - display: flex; - align-items: center; - &:before { - content: '\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC'; - font-size: 14px; - z-index: 1; - width: 100%; - white-space: nowrap; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - } -} - -.engine-empty { - background: #f2f3f5; - color: #a7b1bd; - outline: 1px dashed rgba(31, 56, 88, 0.2); - outline-offset: -1px !important; - height: 66px; - max-height: 100%; - min-width: 140px; - text-align: center; - overflow: hidden; - display: flex; - align-items: center; -} - -.engine-empty:before { - content: '\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC'; - font-size: 14px; - z-index: 1; - width: 100%; - white-space: nowrap; - height: 100%; - display: flex; - align-items: center; - justify-content: center; -} - -.lc-container-placeholder { - min-height: 60px; - height: 100%; - width: 100%; - background-color: rgb(240, 240, 240); - border: 1px dotted; - color: rgb(167, 177, 189); - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; -} - -body.engine-document { - &:after, &:before { - content: ""; - display: table; - } - &:after { - clear: both; - } - - /* - .next-input-group, - .next-checkbox-group,.next-date-picker,.next-input,.next-month-picker, - .next-number-picker,.next-radio-group,.next-range,.next-range-picker, - .next-rating,.next-select,.next-switch,.next-time-picker,.next-upload, - .next-year-picker, - .next-breadcrumb-item,.next-calendar-header,.next-calendar-table { - pointer-events: none !important; - } */ -} - -.engine-live-editing { - cursor: text; - outline: none; - box-shadow: 0 0 0 2px rgb(102, 188, 92); - user-select: text; -} - -/* stylelint-disable-next-line selector-max-id */ -#app { - height: 100vh; -} - - -.luna-page { - height: 100%; -} diff --git a/packages/rax-simulator-renderer/src/renderer.ts b/packages/rax-simulator-renderer/src/renderer.ts deleted file mode 100644 index 64ec2d2c69..0000000000 --- a/packages/rax-simulator-renderer/src/renderer.ts +++ /dev/null @@ -1,690 +0,0 @@ -import { BuiltinSimulatorRenderer, Component, IBaseNode, IDocumentModel } from '@alilc/lowcode-designer'; -import { IPublicTypeComponentSchema, IPublicTypeNodeSchema, IPublicTypeNpmInfo, IPublicEnumTransformStage, IPublicTypeNodeInstance, IPublicTypeProjectSchema } from '@alilc/lowcode-types'; -import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isLowcodeProjectSchema, isComponentSchema, isPlainObject, isReactComponent, setNativeSelection } from '@alilc/lowcode-utils'; -import LowCodeRenderer from '@alilc/lowcode-rax-renderer'; -import { computed, observable as obx, makeObservable, configure } from 'mobx'; -import DriverUniversal from 'driver-universal'; -import { createMemoryHistory, MemoryHistory } from 'history'; -// @ts-ignore -import Rax, { ComponentType, createElement, render as raxRender, shared } from 'rax'; -import Leaf from './builtin-components/leaf'; -import Slot from './builtin-components/slot'; -import { host } from './host'; -import SimulatorRendererView from './renderer-view'; -import { raxFindDOMNodes } from './utils/find-dom-nodes'; -import { getClientRects } from './utils/get-client-rects'; -import loader from './utils/loader'; -import { parseQuery, withQueryParams } from './utils/url'; -import { IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; - -configure({ enforceActions: 'never' }); -const { Instance } = shared; - -export interface LibraryMap { - [key: string]: string; -} - -const SYMBOL_VNID = Symbol('_LCNodeId'); -const SYMBOL_VDID = Symbol('_LCDocId'); - -const INTERNAL = '_internal'; - -function accessLibrary(library: string | object) { - if (typeof library !== 'string') { - return library; - } - - return (window as any)[library]; -} - -// Slot/Leaf and Fragment|FunctionComponent polyfill(ref) - -const builtinComponents = { - Slot, - Leaf, -}; - -function buildComponents( - libraryMap: LibraryMap, - componentsMap: { [componentName: string]: IPublicTypeNpmInfo | ComponentType<any> | IPublicTypeComponentSchema }, - createComponent: (schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>) => Component | null, -) { - const components: any = { - ...builtinComponents, - }; - Object.keys(componentsMap).forEach((componentName) => { - let component = componentsMap[componentName]; - if (component && (isLowcodeProjectSchema(component) || isComponentSchema(component))) { - if (isComponentSchema(component)) { - components[componentName] = createComponent({ - version: '', - componentsMap: [], - componentsTree: [component], - }); - } else { - components[componentName] = createComponent(component); - } - } else if (isReactComponent(component)) { - components[componentName] = component; - } else { - component = findComponent(libraryMap, componentName, component as IPublicTypeNpmInfo); - if (component) { - components[componentName] = component; - } - } - }); - return components; -} - -let REACT_KEY = ''; -function cacheReactKey(el: Element): Element { - if (REACT_KEY !== '') { - return el; - } - // react17 采用 __reactFiber 开头 - REACT_KEY = Object.keys(el).find( - (key) => key.startsWith('__reactInternalInstance$') || key.startsWith('__reactFiber$'), - ) || ''; - if (!REACT_KEY && (el as HTMLElement).parentElement) { - return cacheReactKey((el as HTMLElement).parentElement!); - } - return el; -} - -function checkInstanceMounted(instance: any): boolean { - if (isElement(instance)) { - return instance.parentElement != null; - } - return true; -} - -function isValidDesignModeRaxComponentInstance( - raxComponentInst: any, -): raxComponentInst is { - props: { - _leaf: Exclude<IPublicTypeNodeInstance<any>['node'], null | undefined>; - }; -} { - const leaf = raxComponentInst?.props?._leaf; - return leaf && typeof leaf === 'object' && leaf.isNode; -} - -export class DocumentInstance { - private instancesMap = new Map<string, any[]>(); - - private emitter: IEventBus = createModuleEventBus('DocumentInstance'); - - get schema(): any { - return this.document.export(IPublicEnumTransformStage.Render); - } - - constructor(readonly container: SimulatorRendererContainer, readonly document: IDocumentModel) { - makeObservable(this); - } - - @computed get suspended(): any { - return false; - } - - @computed get scope(): any { - return null; - } - - get path(): string { - return `/${ this.document.fileName}`; - } - - get id() { - return this.document.id; - } - - private unmountIntance(id: string, instance: any) { - const instances = this.instancesMap.get(id); - if (instances) { - const i = instances.indexOf(instance); - if (i > -1) { - instances.splice(i, 1); - host.setInstance(this.document.id, id, instances); - } - } - } - - refresh() { - this.emitter.emit('rerender', { shouldRemount: true }); - } - - onReRender(fn: () => void) { - this.emitter.on('rerender', fn); - return () => { - this.emitter.removeListener('renderer', fn); - }; - } - - mountInstance(id: string, instance: any) { - const docId = this.document.id; - const { instancesMap } = this; - if (instance == null) { - let instances = this.instancesMap.get(id); - if (instances) { - instances = instances.filter(checkInstanceMounted); - if (instances.length > 0) { - instancesMap.set(id, instances); - host.setInstance(this.document.id, id, instances); - } else { - instancesMap.delete(id); - host.setInstance(this.document.id, id, null); - } - } - return; - } - const unmountIntance = this.unmountIntance.bind(this); - const origId = (instance as any)[SYMBOL_VNID]; - if (origId && origId !== id) { - // 另外一个节点的 instance 在此被复用了,需要从原来地方卸载 - unmountIntance(origId, instance); - } - if (isElement(instance)) { - cacheReactKey(instance); - } else if (origId !== id) { - // 涵盖 origId == null || origId !== id 的情况 - let origUnmount: any = instance.componentWillUnmount; - if (origUnmount && origUnmount.origUnmount) { - origUnmount = origUnmount.origUnmount; - } - // hack! delete instance from map - const newUnmount = function (this: any) { - unmountIntance(id, instance); - origUnmount && origUnmount.call(this); - }; - (newUnmount as any).origUnmount = origUnmount; - instance.componentWillUnmount = newUnmount; - } - - (instance as any)[SYMBOL_VNID] = id; - (instance as any)[SYMBOL_VDID] = docId; - let instances = this.instancesMap.get(id); - if (instances) { - const l = instances.length; - instances = instances.filter(checkInstanceMounted); - let updated = instances.length !== l; - if (!instances.includes(instance)) { - instances.push(instance); - updated = true; - } - if (!updated) { - return; - } - } else { - instances = [instance]; - } - instancesMap.set(id, instances); - host.setInstance(this.document.id, id, instances); - } - - mountContext(docId: string, id: string, ctx: object) { - // this.ctxMap.set(id, ctx); - } - - getComponentInstances(id: string): any[] | null { - return this.instancesMap.get(id) || null; - } - - getNode(id: string): IBaseNode<IPublicTypeNodeSchema> | null { - return this.document.getNode(id); - } -} - -export class SimulatorRendererContainer implements BuiltinSimulatorRenderer { - readonly isSimulatorRenderer = true; - private dispose?: () => void; - readonly history: MemoryHistory; - - private emitter: IEventBus = createModuleEventBus('SimulatorRendererContainer'); - - @obx.ref private _documentInstances: DocumentInstance[] = []; - get documentInstances() { - return this._documentInstances; - } - - get currentDocumentInstance() { - return this._documentInstances.find((item) => item.id === host.project.currentDocument?.id); - } - - constructor() { - this.dispose = host.connect(this, () => { - // sync layout config - this._layout = host.project.get('config').layout; - // todo: split with others, not all should recompute - if (this._libraryMap !== host.libraryMap || this._componentsMap !== host.designer.componentsMap) { - this._libraryMap = host.libraryMap || {}; - this._componentsMap = host.designer.componentsMap; - this.buildComponents(); - } - - // sync designMode - this._designMode = host.designMode; - - this._locale = host.locale; - - // sync requestHandlersMap - this._requestHandlersMap = host.requestHandlersMap; - - // sync device - this._device = host.device; - - this.emitter.emit('layoutChange'); - }); - const documentInstanceMap = new Map<string, DocumentInstance>(); - let initialEntry = '/'; - let firstRun = true; - host.autorun(() => { - this._documentInstances = host.project.documents.map((doc) => { - let inst = documentInstanceMap.get(doc.id); - if (!inst) { - inst = new DocumentInstance(this, doc); - documentInstanceMap.set(doc.id, inst); - } - return inst; - }); - - const path = host.project.currentDocument ? documentInstanceMap.get(host.project.currentDocument.id)!.path : '/'; - if (firstRun) { - initialEntry = path; - firstRun = false; - } else { - if (this.history.location.pathname !== path) { - this.history.replace(path); - } - this.emitter.emit('layoutChange'); - } - }); - const history = createMemoryHistory({ - initialEntries: [initialEntry], - }); - this.history = history; - history.listen(({ location }) => { - host.project.open(location.pathname.slice(1)); - }); - host.componentsConsumer.consume(async (componentsAsset) => { - if (componentsAsset) { - await this.load(componentsAsset); - this.buildComponents(); - } - }); - this._appContext = { - utils: { - router: { - push(path: string, params?: object) { - history.push(withQueryParams(path, params)); - }, - replace(path: string, params?: object) { - history.replace(withQueryParams(path, params)); - }, - back() { - history.back(); - }, - }, - legaoBuiltins: { - getUrlParams() { - const { search } = history.location; - return parseQuery(search); - }, - }, - }, - constants: {}, - requestHandlersMap: this._requestHandlersMap, - }; - host.injectionConsumer.consume((data) => { - // sync utils, i18n, contants,... config - }); - } - - @obx private _layout: any = null; - @computed get layout(): any { - // TODO: parse layout Component - return this._layout; - } - set layout(value: any) { - this._layout = value; - } - - private _libraryMap: { [key: string]: string } = {}; - private buildComponents() { - // TODO: remove this.createComponent - this._components = buildComponents(this._libraryMap, this._componentsMap, this.createComponent.bind(this)); - } - @obx.ref private _components: Record<string, React.FC | React.ComponentClass> | null = {}; - @computed get components(): Record<string, React.FC | React.ComponentClass> { - // 根据 device 选择不同组件,进行响应式 - // 更好的做法是,根据 device 选择加载不同的组件资源,甚至是 simulatorUrl - return this._components || {}; - } - // context from: utils、constants、history、location、match - @obx.ref private _appContext = {}; - @computed get context(): any { - return this._appContext; - } - @obx.ref private _designMode: string = 'design'; - @computed get designMode(): any { - return this._designMode; - } - @obx.ref private _device: string = 'default'; - @computed get device() { - return this._device; - } - @obx.ref private _locale: string | undefined = undefined; - @computed get locale() { - return this._locale; - } - @obx.ref private _requestHandlersMap = null; - @computed get requestHandlersMap(): any { - return this._requestHandlersMap; - } - @obx.ref private _componentsMap = {}; - @computed get componentsMap(): any { - return this._componentsMap; - } - - /** - * 加载资源 - */ - load(asset: Asset): Promise<any> { - return loader.load(asset); - } - - async loadAsyncLibrary(asyncLibraryMap: Record<string, any>) { - } - - getComponent(componentName: string) { - const paths = componentName.split('.'); - const subs: string[] = []; - - while (true) { - const component = this._components?.[componentName]; - if (component) { - return getSubComponent(component, subs); - } - - const sub = paths.pop(); - if (!sub) { - return null; - } - subs.unshift(sub); - componentName = paths.join('.'); - } - } - - getNodeInstance(dom: HTMLElement): IPublicTypeNodeInstance<any> | null { - const INTERNAL = '_internal'; - let instance: any = dom; - if (!isElement(instance)) { - return { - docId: instance.props._leaf.document.id, - nodeId: instance.props._leaf.getId(), - instance, - node: instance.props._leaf, - }; - } - instance = Instance.get(dom); - - let loopNum = 0; // 防止由于某种意外而导致死循环 - while (instance && instance[INTERNAL] && loopNum < 1000) { - if (isValidDesignModeRaxComponentInstance(instance)) { - // if (instance && SYMBOL_VNID in instance) { - // const docId = (instance.props as any).schema.docId; - return { - docId: instance.props._leaf.document?.id || '', - nodeId: instance.props._leaf.getId(), - instance, - node: instance.props._leaf, - }; - } - - instance = getRaxVDomParentInstance(instance); - loopNum += 1; - } - - return null; - } - - getClosestNodeInstance(from: any, nodeId?: string): IPublicTypeNodeInstance<any> | null { - const el: any = from; - if (el) { - // if (isElement(el)) { - // el = cacheReactKey(el); - // } else { - // return getNodeInstance(el, specId); - // } - return this.getNodeInstance(el); - } - return null; - } - - findDOMNodes(instance: any, selector?: string): Array<Element | Text> | null { - let el = instance; - if (selector) { - el = document.querySelector(selector); - } - try { - return raxFindDOMNodes(el); - } catch (e) { - // ignore - } - if (el && el.type && el.props && el.props.componentId) { - el = document.querySelector(`${el.type}[componentid=${el.props.componentId}]`); - } else { - console.error(instance); - throw new Error('This instance may not a valid element'); - } - return raxFindDOMNodes(el); - } - - getClientRects(element: Element | Text) { - return getClientRects(element); - } - - setNativeSelection(enableFlag: boolean) { - setNativeSelection(enableFlag); - } - setDraggingState(state: boolean) { - cursor.setDragging(state); - } - setCopyState(state: boolean) { - cursor.setCopy(state); - } - clearState() { - cursor.release(); - } - - onLayoutChange(cb: () => void) { - this.emitter.on('layoutChange', cb); - return () => { - this.emitter.removeListener('layoutChange', cb); - }; - } - - onReRender(fn: () => void) { - this.emitter.on('rerender', fn); - return () => { - this.emitter.removeListener('renderer', fn); - }; - } - - rerender() { - this.currentDocumentInstance?.refresh(); - } - - stopAutoRepaintNode() { - } - - enableAutoRepaintNode() { - } - - createComponent(schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema>): Component | null { - const _schema: IPublicTypeProjectSchema<IPublicTypeComponentSchema> = { - ...schema, - componentsTree: schema.componentsTree.map(compatibleLegaoSchema), - }; - - const componentsTreeSchema = _schema.componentsTree[0]; - - if (componentsTreeSchema.componentName === 'Component' && componentsTreeSchema.css) { - const doc = window.document; - const s = doc.createElement('style'); - s.setAttribute('type', 'text/css'); - s.setAttribute('id', `Component-${componentsTreeSchema.id || ''}`); - s.appendChild(doc.createTextNode(componentsTreeSchema.css || '')); - doc.getElementsByTagName('head')[0].appendChild(s); - } - - const renderer = this; - const { componentsMap: components } = renderer; - - class LowCodeComp extends Rax.Component { - render() { - const extraProps = getLowCodeComponentProps(this.props); - // @ts-ignore - return createElement(LowCodeRenderer, { - ...extraProps, - schema: componentsTreeSchema, - components, - designMode: '', - locale: renderer.locale, - messages: _schema.i18n || {}, - device: renderer.device, - appHelper: renderer.context, - rendererName: 'LowCodeRenderer', - thisRequiredInJSE: host.thisRequiredInJSE, - customCreateElement: (Comp: any, props: any, children: any) => { - const componentMeta = host.currentDocument?.getComponentMeta(Comp.displayName); - if (componentMeta?.isModal) { - return null; - } - - const { __id, __designMode, ...viewProps } = props; - // mock _leaf,减少性能开销 - const _leaf = { - isEmpty: () => false, - isMock: true, - }; - viewProps._leaf = _leaf; - return createElement(Comp, viewProps, children); - }, - }); - } - } - - return LowCodeComp; - } - - private _running = false; - run() { - if (this._running) { - return; - } - this._running = true; - const containerId = 'app'; - let container = document.getElementById(containerId); - if (!container) { - container = document.createElement('div'); - document.body.appendChild(container); - container.id = containerId; - } - - // ==== compatiable vision - document.documentElement.classList.add('engine-page'); - document.body.classList.add('engine-document'); // important! Stylesheet.invoke depends - - raxRender(createElement(SimulatorRendererView, { - rendererContainer: this, - }), container, { - driver: DriverUniversal, - }); - host.project.setRendererReady(this); - } -} - -function getSubComponent(library: any, paths: string[]) { - const l = paths.length; - if (l < 1 || !library) { - return library; - } - let i = 0; - let component: any; - while (i < l) { - const key = paths[i]!; - let ex: any; - try { - component = library[key]; - } catch (e) { - ex = e; - component = null; - } - if (i === 0 && component == null && key === 'default') { - if (ex) { - return l === 1 ? library : null; - } - component = library; - } else if (component == null) { - return null; - } - library = component; - i++; - } - return component; -} - -function findComponent(libraryMap: LibraryMap, componentName: string, npm?: IPublicTypeNpmInfo) { - if (!npm) { - return accessLibrary(componentName); - } - // libraryName the key access to global - // export { exportName } from xxx exportName === global.libraryName.exportName - // export exportName from xxx exportName === global.libraryName.default || global.libraryName - // export { exportName as componentName } from package - // if exportName == null exportName === componentName; - // const componentName = exportName.subName, if exportName empty subName donot use - const exportName = npm.exportName || npm.componentName || componentName; - const libraryName = libraryMap[npm.package] || exportName; - const library = accessLibrary(libraryName); - const paths = npm.exportName && npm.subName ? npm.subName.split('.') : []; - if (npm.destructuring) { - paths.unshift(exportName); - } else if (isESModule(library)) { - paths.unshift('default'); - } - return getSubComponent(library, paths); -} - -function getLowCodeComponentProps(props: any) { - if (!props || !isPlainObject(props)) { - return props; - } - const newProps: any = {}; - Object.keys(props).forEach(k => { - if (['children', 'componentId', '__designMode', '_componentName', '_leaf'].includes(k)) { - return; - } - newProps[k] = props[k]; - }); - return newProps; -} - -/** - * 获取 Rax 里面 VDOM 的上一级的实例 - * 注意:Rax 的 development 的包是带有 __parentInstance, - * 但是 production 的包 __parentInstance 会被压缩掉, - * 所以这里遍历下其中的所有值,尝试找到有 _internal 的那个(别的值不会带有这个属性的) - */ -function getRaxVDomParentInstance(instance: { _internal: any }) { - const internalInstance = instance._internal; - return internalInstance.__parentInstance || - Object.values(internalInstance).find(v => ( - v !== null && - v !== instance && - typeof v === 'object' && - typeof (v as {_internal: unknown})._internal === 'object' - )); -} - -export default new SimulatorRendererContainer(); diff --git a/packages/rax-simulator-renderer/src/utils/create-defer.ts b/packages/rax-simulator-renderer/src/utils/create-defer.ts deleted file mode 100644 index e7997365a0..0000000000 --- a/packages/rax-simulator-renderer/src/utils/create-defer.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface Defer<T = any> { - resolve(value?: T | PromiseLike<T>): void; - reject(reason?: any): void; - promise(): Promise<T>; -} - -export function createDefer<T = any>(): Defer<T> { - const r: any = {}; - const promise = new Promise<T>((resolve, reject) => { - r.resolve = resolve; - r.reject = reject; - }); - - r.promise = () => promise; - - return r; -} diff --git a/packages/rax-simulator-renderer/src/utils/find-dom-nodes.ts b/packages/rax-simulator-renderer/src/utils/find-dom-nodes.ts deleted file mode 100644 index 106af2efac..0000000000 --- a/packages/rax-simulator-renderer/src/utils/find-dom-nodes.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { isElement } from '@alilc/lowcode-utils'; -import findDOMNode from 'rax-find-dom-node'; -// import { isDOMNode } from './is-dom-node'; - -export function raxFindDOMNodes(instance: any): Array<Element | Text> | null { - if (!instance) { - return null; - } - if (isElement(instance)) { - return [instance]; - } - // eslint-disable-next-line react/no-find-dom-node - const result = findDOMNode(instance); - if (Array.isArray(result)) { - return result; - } - return [result]; -} diff --git a/packages/rax-simulator-renderer/src/utils/get-client-rects.ts b/packages/rax-simulator-renderer/src/utils/get-client-rects.ts deleted file mode 100644 index dd13aba81e..0000000000 --- a/packages/rax-simulator-renderer/src/utils/get-client-rects.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { isElement } from '@alilc/lowcode-utils'; - -// a range for test TextNode clientRect -const cycleRange = document.createRange(); - -export function getClientRects(node: Element | Text) { - if (isElement(node)) { - return [node.getBoundingClientRect()]; - } - - cycleRange.selectNode(node); - return Array.from(cycleRange.getClientRects()); -} diff --git a/packages/rax-simulator-renderer/src/utils/get-closest-node-instance.ts b/packages/rax-simulator-renderer/src/utils/get-closest-node-instance.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/rax-simulator-renderer/src/utils/get-device-view.ts b/packages/rax-simulator-renderer/src/utils/get-device-view.ts deleted file mode 100644 index 9005562599..0000000000 --- a/packages/rax-simulator-renderer/src/utils/get-device-view.ts +++ /dev/null @@ -1,23 +0,0 @@ -function ucfirst(s: string) { - return s.charAt(0).toUpperCase() + s.substring(1); -} -function getDeviceView(view: any, device: string, mode: string) { - if (!view || typeof view === 'string') { - return view; - } - - // compatible vision Mobile | Preview - device = ucfirst(device); - if (device === 'Mobile' && view.hasOwnProperty(device)) { - view = view[device]; - } - mode = ucfirst(mode); - if (mode === 'Preview' && view.hasOwnProperty(mode)) { - view = view[mode]; - } - return view; -} - -export default { - getDeviceView, -}; diff --git a/packages/rax-simulator-renderer/src/utils/is-dom-node.ts b/packages/rax-simulator-renderer/src/utils/is-dom-node.ts deleted file mode 100644 index bfbeb79c1f..0000000000 --- a/packages/rax-simulator-renderer/src/utils/is-dom-node.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function isDOMNode(node: any): node is Element | Text { - if (!node) return false; - return node.nodeType && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE); -} diff --git a/packages/rax-simulator-renderer/src/utils/loader.ts b/packages/rax-simulator-renderer/src/utils/loader.ts deleted file mode 100644 index 436e51c441..0000000000 --- a/packages/rax-simulator-renderer/src/utils/loader.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { load, evaluate } from './script'; -import StylePoint from './style'; -import { - Asset, - AssetLevel, - AssetLevels, - AssetType, - AssetList, - isAssetBundle, - isAssetItem, - assetItem, - AssetItem, - isCSSUrl, -} from '@alilc/lowcode-utils'; - -function parseAssetList(scripts: any, styles: any, assets: AssetList, level?: AssetLevel) { - for (const asset of assets) { - parseAsset(scripts, styles, asset, level); - } -} - -function parseAsset(scripts: any, styles: any, asset: Asset | undefined | null, level?: AssetLevel) { - if (!asset) { - return; - } - if (Array.isArray(asset)) { - return parseAssetList(scripts, styles, asset, level); - } - - if (isAssetBundle(asset)) { - if (asset.assets) { - if (Array.isArray(asset.assets)) { - parseAssetList(scripts, styles, asset.assets, asset.level || level); - } else { - parseAsset(scripts, styles, asset.assets, asset.level || level); - } - return; - } - return; - } - - if (!isAssetItem(asset)) { - asset = assetItem(isCSSUrl(asset) ? AssetType.CSSUrl : AssetType.JSUrl, asset, level)!; - } - - let lv = asset.level || level; - - if (!lv || AssetLevel[lv] == null) { - lv = AssetLevel.App; - } - - asset.level = lv; - if (asset.type === AssetType.CSSUrl || asset.type == AssetType.CSSText) { - styles[lv].push(asset); - } else { - scripts[lv].push(asset); - } -} - -export class AssetLoader { - async load(asset: Asset) { - const styles: any = {}; - const scripts: any = {}; - AssetLevels.forEach(lv => { - styles[lv] = []; - scripts[lv] = []; - }); - parseAsset(scripts, styles, asset); - const styleQueue: AssetItem[] = styles[AssetLevel.Environment].concat( - styles[AssetLevel.Library], - styles[AssetLevel.Theme], - styles[AssetLevel.Runtime], - styles[AssetLevel.App], - ); - const scriptQueue: AssetItem[] = scripts[AssetLevel.Environment].concat( - scripts[AssetLevel.Library], - scripts[AssetLevel.Theme], - scripts[AssetLevel.Runtime], - scripts[AssetLevel.App], - ); - await Promise.all( - styleQueue.map(({ content, level, type, id }) => this.loadStyle(content, level!, type === AssetType.CSSUrl, id)), - ); - await Promise.all(scriptQueue.map(({ content, type }) => this.loadScript(content, type === AssetType.JSUrl))); - } - - private stylePoints = new Map<string, StylePoint>(); - - private loadStyle(content: string | undefined | null, level: AssetLevel, isUrl?: boolean, id?: string) { - if (!content) { - return; - } - let point: StylePoint | undefined; - if (id) { - point = this.stylePoints.get(id); - if (!point) { - point = new StylePoint(level, id); - this.stylePoints.set(id, point); - } - } else { - point = new StylePoint(level); - } - return isUrl ? point.applyUrl(content) : point.applyText(content); - } - - private loadScript(content: string | undefined | null, isUrl?: boolean) { - if (!content) { - return; - } - return isUrl ? load(content) : evaluate(content); - } -} - -export default new AssetLoader(); diff --git a/packages/rax-simulator-renderer/src/utils/script.ts b/packages/rax-simulator-renderer/src/utils/script.ts deleted file mode 100644 index 81841ff6d2..0000000000 --- a/packages/rax-simulator-renderer/src/utils/script.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { createDefer } from './create-defer'; - -export function evaluate(script: string) { - const scriptEl = document.createElement('script'); - scriptEl.text = script; - document.head.appendChild(scriptEl); - document.head.removeChild(scriptEl); -} - -export function load(url: string) { - const node: any = document.createElement('script'); - - // node.setAttribute('crossorigin', 'anonymous'); - - node.onload = onload; - node.onerror = onload; - - const i = createDefer(); - - function onload(e: any) { - node.onload = null; - node.onerror = null; - if (e.type === 'load') { - i.resolve(); - } else { - i.reject(); - } - // document.head.removeChild(node); - // node = null; - } - - // node.async = true; - node.src = url; - - document.head.appendChild(node); - - return i.promise(); -} - -export function evaluateExpression(expr: string) { - // eslint-disable-next-line no-new-func - const fn = new Function(expr); - return fn(); -} - -export function newFunction(args: string, code: string) { - try { - // eslint-disable-next-line no-new-func - return new Function(args, code); - } catch (e) { - console.warn('Caught error, Cant init func'); - return null; - } -} diff --git a/packages/rax-simulator-renderer/src/utils/style.ts b/packages/rax-simulator-renderer/src/utils/style.ts deleted file mode 100644 index 91dbbc6345..0000000000 --- a/packages/rax-simulator-renderer/src/utils/style.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { createDefer } from './create-defer'; - -export default class StylePoint { - private lastContent: string | undefined; - - private lastUrl: string | undefined; - - private placeholder: Element | Text; - - constructor(readonly level: number, readonly id?: string) { - let placeholder: any; - if (id) { - placeholder = document.head.querySelector(`style[data-id="${id}"]`); - } - if (!placeholder) { - placeholder = document.createTextNode(''); - const meta = document.head.querySelector(`meta[level="${level}"]`); - if (meta) { - document.head.insertBefore(placeholder, meta); - } else { - document.head.appendChild(placeholder); - } - } - this.placeholder = placeholder; - } - - applyText(content: string) { - if (this.lastContent === content) { - return; - } - this.lastContent = content; - this.lastUrl = undefined; - const element = document.createElement('style'); - element.setAttribute('type', 'text/css'); - if (this.id) { - element.setAttribute('data-id', this.id); - } - element.appendChild(document.createTextNode(content)); - document.head.insertBefore(element, this.placeholder.parentNode === document.head ? this.placeholder.nextSibling : null); - document.head.removeChild(this.placeholder); - this.placeholder = element; - } - - applyUrl(url: string) { - if (this.lastUrl === url) { - return; - } - this.lastContent = undefined; - this.lastUrl = url; - const element = document.createElement('link'); - element.onload = onload; - element.onerror = onload; - - const i = createDefer(); - function onload(e: any) { - element.onload = null; - element.onerror = null; - if (e.type === 'load') { - i.resolve(); - } else { - i.reject(); - } - } - - element.href = url; - element.rel = 'stylesheet'; - if (this.id) { - element.setAttribute('data-id', this.id); - } - document.head.insertBefore(element, this.placeholder.parentNode === document.head ? this.placeholder.nextSibling : null); - document.head.removeChild(this.placeholder); - this.placeholder = element; - return i.promise(); - } -} diff --git a/packages/rax-simulator-renderer/src/utils/url.ts b/packages/rax-simulator-renderer/src/utils/url.ts deleted file mode 100644 index d720323b3a..0000000000 --- a/packages/rax-simulator-renderer/src/utils/url.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Parse queryString - * @param {String} str '?q=query&b=test' - * @return {Object} - */ -export function parseQuery(str: string): object { - const ret: any = {}; - - if (typeof str !== 'string') { - return ret; - } - - const s = str.trim().replace(/^(\?|#|&)/, ''); - - if (!s) { - return ret; - } - - s.split('&').forEach((param) => { - const parts = param.replace(/\+/g, ' ').split('='); - let key = parts.shift()!; - let val: any = parts.length > 0 ? parts.join('=') : undefined; - - key = decodeURIComponent(key); - - val = val === undefined ? null : decodeURIComponent(val); - - if (ret[key] === undefined) { - ret[key] = val; - } else if (Array.isArray(ret[key])) { - ret[key].push(val); - } else { - ret[key] = [ret[key], val]; - } - }); - - return ret; -} - -/** - * Stringify object to query parammeters - * @param {Object} obj - * @return {String} - */ -export function stringifyQuery(obj: any): string { - const param: string[] = []; - Object.keys(obj).forEach((key) => { - let value = obj[key]; - if (value && typeof value === 'object') { - value = JSON.stringify(value); - } - param.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`); - }); - return param.join('&'); -} - -export function uriEncode(uri: string) { - return encodeURIComponent(uri); -} - -export function uriDecode(uri: string) { - return decodeURIComponent(uri); -} - -export function withQueryParams(url: string, params?: object) { - const queryStr = params ? stringifyQuery(params) : ''; - if (queryStr === '') { - return url; - } - const urlSplit = url.split('#'); - const hash = urlSplit[1] ? `#${urlSplit[1]}` : ''; - const urlWithoutHash = urlSplit[0]; - return `${urlWithoutHash}${~urlWithoutHash.indexOf('?') ? '&' : '?'}${queryStr}${hash}`; -} diff --git a/packages/renderer-core/src/adapter/index.ts b/packages/renderer-core/src/adapter/index.ts index 12896b1372..7a56bc039e 100644 --- a/packages/renderer-core/src/adapter/index.ts +++ b/packages/renderer-core/src/adapter/index.ts @@ -2,7 +2,6 @@ import { IRuntime, IRendererModules, IGeneralConstructor } from '../types'; export enum Env { React = 'react', - Rax = 'rax', } class Adapter { @@ -22,22 +21,22 @@ class Adapter { initRuntime() { const Component: IGeneralConstructor = class <T = any, S = any> { - setState() {} - forceUpdate() {} - render() {} state: Readonly<S>; props: Readonly<T> & Readonly<{ children?: any | undefined }>; refs: Record<string, unknown>; context: Record<string, unknown>; - }; - const PureComponent = class <T = any, S = any> { setState() {} forceUpdate() {} render() {} + }; + const PureComponent = class <T = any, S = any> { state: Readonly<S>; props: Readonly<T> & Readonly<{ children?: any | undefined }>; refs: Record<string, unknown>; context: Record<string, unknown>; + setState() {} + forceUpdate() {} + render() {} }; const createElement = () => {}; const createContext = () => {}; @@ -85,10 +84,6 @@ class Adapter { return this.env === Env.React; } - isRax() { - return this.env === Env.Rax; - } - setRenderers(renderers: IRendererModules) { this.renderers = renderers; } diff --git a/packages/renderer-core/tests/adapter/adapter.test.ts b/packages/renderer-core/tests/adapter/adapter.test.ts index a838602fbe..57d92d1d42 100644 --- a/packages/renderer-core/tests/adapter/adapter.test.ts +++ b/packages/renderer-core/tests/adapter/adapter.test.ts @@ -79,15 +79,10 @@ describe('test src/adapter ', () => { }); - it('setEnv/.env/isReact/isRax works', () => { + it('setEnv/.env/isReact works', () => { adapter.setEnv(Env.React); expect(adapter.env).toBe(Env.React); expect(adapter.isReact()).toBeTruthy(); - expect(adapter.isRax()).toBeFalsy(); - adapter.setEnv(Env.Rax); - expect(adapter.env).toBe(Env.Rax); - expect(adapter.isRax()).toBeTruthy(); - expect(adapter.isReact()).toBeFalsy(); }); it('setRenderers/getRenderers works', () => { diff --git a/packages/types/src/shell/type/engine-options.ts b/packages/types/src/shell/type/engine-options.ts index b570d1990a..72078c8107 100644 --- a/packages/types/src/shell/type/engine-options.ts +++ b/packages/types/src/shell/type/engine-options.ts @@ -41,7 +41,7 @@ export interface IPublicTypeEngineOptions { /** * 渲染器类型,默认值:'react' */ - renderEnv?: 'react' | 'rax' | string; + renderEnv?: 'react' | string; /** * 设备类型映射器,处理设计器与渲染器中 device 的映射 diff --git a/scripts/build.sh b/scripts/build.sh index 92b0a99c23..0d96598e62 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -9,8 +9,6 @@ lerna run build \ --scope @alilc/lowcode-designer \ --scope @alilc/lowcode-plugin-designer \ --scope @alilc/lowcode-plugin-outline-pane \ - --scope @alilc/lowcode-rax-renderer \ - --scope @alilc/lowcode-rax-simulator-renderer \ --scope @alilc/lowcode-react-renderer \ --scope @alilc/lowcode-react-simulator-renderer \ --scope @alilc/lowcode-renderer-core \ @@ -20,13 +18,9 @@ lerna run build \ lerna run build:umd \ --scope @alilc/lowcode-engine \ - --scope @alilc/lowcode-rax-simulator-renderer \ --scope @alilc/lowcode-react-simulator-renderer \ --scope @alilc/lowcode-react-renderer \ --stream cp ./packages/react-simulator-renderer/dist/js/* ./packages/engine/dist/js/ cp ./packages/react-simulator-renderer/dist/css/* ./packages/engine/dist/css/ - -cp ./packages/rax-simulator-renderer/dist/js/* ./packages/engine/dist/js/ -cp ./packages/rax-simulator-renderer/dist/css/* ./packages/engine/dist/css/ \ No newline at end of file diff --git a/scripts/sync.sh b/scripts/sync.sh index 98895c7234..e9840eeca6 100755 --- a/scripts/sync.sh +++ b/scripts/sync.sh @@ -10,8 +10,6 @@ tnpm sync @alilc/lowcode-designer tnpm sync @alilc/lowcode-plugin-designer tnpm sync @alilc/lowcode-plugin-outline-pane tnpm sync @alilc/lowcode-renderer-core -tnpm sync @alilc/lowcode-rax-renderer -tnpm sync @alilc/lowcode-rax-simulator-renderer tnpm sync @alilc/lowcode-react-renderer tnpm sync @alilc/lowcode-react-simulator-renderer tnpm sync @alilc/lowcode-engine From d47c2d2f91a57aa4f19fa5bbc8b1dfb3ded88da9 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 5 Jan 2024 08:09:04 +0000 Subject: [PATCH 273/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 4d6ef0a770..6659eaf853 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.18", + "version": "1.2.19", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 1b00c61a32027084e531a0ffacb2a9a2020fbcbf Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 8 Jan 2024 14:46:27 +0800 Subject: [PATCH 274/361] feat(engine): add context menu --- .gitignore | 2 + docs/docs/api/commonUI.md | 20 ++ docs/docs/api/configOptions.md | 6 + docs/docs/guide/expand/editor/theme.md | 1 + .../designer/src/context-menu-actions.scss | 10 + packages/designer/src/context-menu-actions.ts | 145 +++++++++++++++ packages/designer/src/designer/designer.ts | 11 +- packages/designer/src/index.ts | 1 + packages/editor-core/src/config.ts | 5 + packages/engine/src/engine-core.ts | 3 + .../src/inner-plugins/default-context-menu.ts | 172 ++++++++++++++++++ packages/engine/src/locale/en-US.json | 9 + packages/engine/src/locale/index.ts | 14 ++ packages/engine/src/locale/zh-CN.json | 9 + packages/shell/src/api/commonUI.ts | 4 + packages/shell/src/api/material.ts | 14 ++ .../shell/src/components/context-menu.tsx | 46 +++++ packages/types/src/shell/api/commonUI.ts | 8 +- packages/types/src/shell/api/material.ts | 20 +- packages/types/src/shell/enum/context-menu.ts | 7 + packages/types/src/shell/enum/index.ts | 3 +- packages/types/src/shell/type/context-menu.ts | 57 ++++++ .../types/src/shell/type/engine-options.ts | 6 + packages/types/src/shell/type/index.ts | 3 +- packages/utils/src/context-menu.scss | 33 ++++ packages/utils/src/context-menu.tsx | 138 ++++++++++++++ packages/utils/src/index.ts | 1 + 27 files changed, 743 insertions(+), 5 deletions(-) create mode 100644 packages/designer/src/context-menu-actions.scss create mode 100644 packages/designer/src/context-menu-actions.ts create mode 100644 packages/engine/src/inner-plugins/default-context-menu.ts create mode 100644 packages/engine/src/locale/en-US.json create mode 100644 packages/engine/src/locale/index.ts create mode 100644 packages/engine/src/locale/zh-CN.json create mode 100644 packages/shell/src/components/context-menu.tsx create mode 100644 packages/types/src/shell/enum/context-menu.ts create mode 100644 packages/types/src/shell/type/context-menu.ts create mode 100644 packages/utils/src/context-menu.scss create mode 100644 packages/utils/src/context-menu.tsx diff --git a/.gitignore b/.gitignore index 05159f0473..6a19ae3e0c 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,5 @@ typings/ # codealike codealike.json .node + +.must.config.js \ No newline at end of file diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index 9d1f706520..ef7af7f415 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -29,6 +29,26 @@ CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开 | className | className | string (optional) | | | onClick | 点击事件 | () => void (optional) | | +### ContextMenu + +| 参数 | 说明 | 类型 | 默认值 | +|--------|----------------------------------------------------|------------------------------------|--------| +| menus | 定义上下文菜单的动作数组 | IPublicTypeContextMenuAction[] | | +| children | 组件的子元素 | React.ReactElement[] | | + +**IPublicTypeContextMenuAction Interface** + +| 参数 | 说明 | 类型 | 默认值 | +|------------|--------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------------| +| name | 动作的唯一标识符<br>Unique identifier for the action | string | | +| title | 显示的标题,可以是字符串或国际化数据<br>Display title, can be a string or internationalized data | string \| IPublicTypeI18nData (optional) | | +| type | 菜单项类型<br>Menu item type | IPublicEnumContextMenuType (optional) | IPublicEnumPContextMenuType.MENU_ITEM | +| action | 点击时执行的动作,可选<br>Action to execute on click, optional | (nodes: IPublicModelNode[]) => void (optional) | | +| items | 子菜单项或生成子节点的函数,可选,仅支持两级<br>Sub-menu items or function to generate child node, optional | Omit<IPublicTypeContextMenuAction, 'items'>[] \| ((nodes: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]) (optional) | | +| condition | 显示条件函数<br>Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | | +| disabled | 禁用条件函数,可选<br>Function to determine disabled condition, optional | (nodes: IPublicModelNode[]) => boolean (optional) | | + + ### Balloon 详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon) diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index 5f6ade710f..67d2fae2c1 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -185,6 +185,12 @@ config.set('enableCondition', false) `@type {boolean}` `@default {false}` +#### enableContextMenu - 开启右键菜单 + +`@type {boolean}` `@default {false}` + +是否开启右键菜单 + #### disableDetecting `@type {boolean}` `@default {false}` diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index ef0e04d28d..1c442c5132 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -128,6 +128,7 @@ sidebar_position: 9 - `--pane-title-height`: 面板标题高度 - `--pane-title-font-size`: 面板标题字体大小 - `--pane-title-padding`: 面板标题边距 +- `--context-menu-item-height`: 右键菜单项高度 diff --git a/packages/designer/src/context-menu-actions.scss b/packages/designer/src/context-menu-actions.scss new file mode 100644 index 0000000000..863c929447 --- /dev/null +++ b/packages/designer/src/context-menu-actions.scss @@ -0,0 +1,10 @@ +.engine-context-menu { + &.next-menu.next-ver .next-menu-item { + padding-right: 30px; + + .next-menu-item-inner { + height: var(--context-menu-item-height, 30px); + line-height: var(--context-menu-item-height, 30px); + } + } +} \ No newline at end of file diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts new file mode 100644 index 0000000000..053e4f0313 --- /dev/null +++ b/packages/designer/src/context-menu-actions.ts @@ -0,0 +1,145 @@ +import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial } from '@alilc/lowcode-types'; +import { IDesigner, INode } from './designer'; +import { parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; +import { Menu } from '@alifd/next'; +import { engineConfig } from '@alilc/lowcode-editor-core'; +import './context-menu-actions.scss'; + +export interface IContextMenuActions { + actions: IPublicTypeContextMenuAction[]; + + adjustMenuLayoutFn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]; + + addMenuAction: IPublicApiMaterial['addContextMenuOption']; + + removeMenuAction: IPublicApiMaterial['removeContextMenuOption']; + + adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout']; +} + +export class ContextMenuActions implements IContextMenuActions { + actions: IPublicTypeContextMenuAction[] = []; + + designer: IDesigner; + + dispose: Function[]; + + enableContextMenu: boolean; + + constructor(designer: IDesigner) { + this.designer = designer; + this.dispose = []; + + engineConfig.onGot('enableContextMenu', (enable) => { + if (this.enableContextMenu === enable) { + return; + } + this.enableContextMenu = enable; + this.dispose.forEach(d => d()); + if (enable) { + this.initEvent(); + } + }); + } + + handleContextMenu = ( + nodes: INode[], + event: MouseEvent, + ) => { + const designer = this.designer; + event.stopPropagation(); + event.preventDefault(); + + const actions = designer.contextMenuActions.actions; + + const { bounds } = designer.project.simulator?.viewport || { bounds: { left: 0, top: 0 } }; + const { left: simulatorLeft, top: simulatorTop } = bounds; + + let destroyFn: Function | undefined; + + const destroy = () => { + destroyFn?.(); + }; + + const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, { + nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!), + destroy, + }); + + if (!menus.length) { + return; + } + + const layoutMenu = designer.contextMenuActions.adjustMenuLayoutFn(menus); + + const menuNode = parseContextMenuAsReactNode(layoutMenu, { + destroy, + nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!), + designer, + }); + + const target = event.target; + + const { top, left } = target?.getBoundingClientRect(); + + const menuInstance = Menu.create({ + target: event.target, + offset: [event.clientX - left + simulatorLeft, event.clientY - top + simulatorTop], + children: menuNode, + className: 'engine-context-menu', + }); + + destroyFn = (menuInstance as any).destroy; + }; + + initEvent() { + const designer = this.designer; + this.dispose.push( + designer.editor.eventBus.on('designer.builtinSimulator.contextmenu', ({ + node, + originalEvent, + }: { + node: INode; + originalEvent: MouseEvent; + }) => { + // 如果右键的节点不在 当前选中的节点中,选中该节点 + if (!designer.currentSelection.has(node.id)) { + designer.currentSelection.select(node.id); + } + const nodes = designer.currentSelection.getNodes(); + this.handleContextMenu(nodes, originalEvent); + }), + (() => { + const handleContextMenu = (e: MouseEvent) => { + this.handleContextMenu([], e); + }; + + document.addEventListener('contextmenu', handleContextMenu); + + return () => { + document.removeEventListener('contextmenu', handleContextMenu); + }; + })(), + ); + } + + adjustMenuLayoutFn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[] = (actions) => actions; + + addMenuAction(action: IPublicTypeContextMenuAction) { + this.actions.push({ + type: IPublicEnumContextMenuType.MENU_ITEM, + ...action, + }); + } + + removeMenuAction(name: string) { + const i = this.actions.findIndex((action) => action.name === name); + if (i > -1) { + this.actions.splice(i, 1); + } + } + + adjustMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) { + this.adjustMenuLayoutFn = fn; + } +} \ No newline at end of file diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index d7e17e84ca..1dd4bc04e6 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -20,7 +20,7 @@ import { } from '@alilc/lowcode-types'; import { mergeAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { IProject, Project } from '../project'; -import { Node, DocumentModel, insertChildren, INode } from '../document'; +import { Node, DocumentModel, insertChildren, INode, ISelection } from '../document'; import { ComponentMeta, IComponentMeta } from '../component-meta'; import { INodeSelector, Component } from '../simulator'; import { Scroller } from './scroller'; @@ -32,6 +32,7 @@ import { OffsetObserver, createOffsetObserver } from './offset-observer'; import { ISettingTopEntry, SettingTopEntry } from './setting'; import { BemToolsManager } from '../builtin-simulator/bem-tools/manager'; import { ComponentActions } from '../component-actions'; +import { ContextMenuActions, IContextMenuActions } from '../context-menu-actions'; const logger = new Logger({ level: 'warn', bizName: 'designer' }); @@ -72,12 +73,16 @@ export interface IDesigner { get componentActions(): ComponentActions; + get contextMenuActions(): ContextMenuActions; + get editor(): IPublicModelEditor; get detecting(): Detecting; get simulatorComponent(): ComponentType<any> | undefined; + get currentSelection(): ISelection; + createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller; refreshComponentMetasMap(): void; @@ -122,6 +127,8 @@ export class Designer implements IDesigner { readonly componentActions = new ComponentActions(); + readonly contextMenuActions: IContextMenuActions; + readonly activeTracker = new ActiveTracker(); readonly detecting = new Detecting(); @@ -198,6 +205,8 @@ export class Designer implements IDesigner { this.postEvent('dragstart', e); }); + this.contextMenuActions = new ContextMenuActions(this); + this.dragon.onDrag((e) => { if (this.props?.onDrag) { this.props.onDrag(e); diff --git a/packages/designer/src/index.ts b/packages/designer/src/index.ts index 489d81482f..11e6453b8a 100644 --- a/packages/designer/src/index.ts +++ b/packages/designer/src/index.ts @@ -6,3 +6,4 @@ export * from './project'; export * from './builtin-simulator'; export * from './plugin'; export * from './types'; +export * from './context-menu-actions'; diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index a5da74742d..c4ff407b9a 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -159,6 +159,11 @@ const VALID_ENGINE_OPTIONS = { type: 'function', description: '应用级设计模式下,窗口为空时展示的占位组件', }, + enableContextMenu: { + type: 'boolean', + description: '是否开启右键菜单', + default: false, + }, hideComponentAction: { type: 'boolean', description: '是否隐藏设计器辅助层', diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 9f29046fbe..29b4a7f038 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -62,6 +62,7 @@ import { setterRegistry } from './inner-plugins/setter-registry'; import { defaultPanelRegistry } from './inner-plugins/default-panel-registry'; import { shellModelFactory } from './modules/shell-model-factory'; import { builtinHotkey } from './inner-plugins/builtin-hotkey'; +import { defaultContextMenu } from './inner-plugins/default-context-menu'; import { OutlinePlugin } from '@alilc/lowcode-plugin-outline-pane'; export * from './modules/skeleton-types'; @@ -78,6 +79,7 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins await plugins.register(defaultPanelRegistryPlugin); await plugins.register(builtinHotkey); await plugins.register(registerDefaults, {}, { autoInit: true }); + await plugins.register(defaultContextMenu); return () => { plugins.delete(OutlinePlugin.pluginName); @@ -86,6 +88,7 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins plugins.delete(defaultPanelRegistryPlugin.pluginName); plugins.delete(builtinHotkey.pluginName); plugins.delete(registerDefaults.pluginName); + plugins.delete(defaultContextMenu.pluginName); }; } diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts new file mode 100644 index 0000000000..86feb17d97 --- /dev/null +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -0,0 +1,172 @@ +import { + IPublicEnumContextMenuType, + IPublicEnumTransformStage, + IPublicModelNode, + IPublicModelPluginContext, + IPublicTypeNodeSchema, +} from '@alilc/lowcode-types'; +import { isProjectSchema } from '@alilc/lowcode-utils'; +import { Notification } from '@alifd/next'; +import { intl } from '../locale'; + +function getNodesSchema(nodes: IPublicModelNode[]) { + const componentsTree = nodes.map((node) => node?.exportSchema(IPublicEnumTransformStage.Clone)); + const data = { type: 'nodeSchema', componentsMap: {}, componentsTree }; + return data; +} + +async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> { + return new Promise((resolve, reject) => { + // 使用 Clipboard API 读取剪贴板内容 + navigator.clipboard.readText().then( + (text) => { + try { + const data = JSON.parse(text); + if (isProjectSchema(data)) { + resolve(data.componentsTree); + } else { + Notification.open({ + content: intl('NotValidNodeData'), + type: 'error', + }); + reject( + new Error(intl('NotValidNodeData')), + ); + } + } catch (error) { + Notification.open({ + content: intl('NotValidNodeData'), + type: 'error', + }); + reject(error); + } + }, + (err) => { + reject(err); + }, + ); + }); +} + +export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { + const { material, canvas } = ctx; + const { clipboard } = canvas; + + return { + init() { + material.addContextMenuOption({ + name: 'selectComponent', + title: intl('SelectComponents'), + condition: (nodes) => { + return nodes.length === 1; + }, + items: [ + { + name: 'nodeTree', + type: IPublicEnumContextMenuType.NODE_TREE, + }, + ], + }); + + material.addContextMenuOption({ + name: 'copyAndPaste', + title: intl('Copy'), + condition: (nodes) => { + return nodes.length === 1; + }, + action(nodes) { + const node = nodes[0]; + const { document: doc, parent, index } = node; + if (parent) { + const newNode = doc?.insertNode(parent, node, (index ?? 0) + 1, true); + newNode?.select(); + } + }, + }); + + material.addContextMenuOption({ + name: 'copy', + title: intl('Copy.1'), + action(nodes) { + if (!nodes || nodes.length < 1) { + return; + } + + const data = getNodesSchema(nodes); + clipboard.setData(data); + }, + }); + + material.addContextMenuOption({ + name: 'zhantieToBottom', + title: intl('PasteToTheBottom'), + condition: (nodes) => { + return nodes.length === 1; + }, + async action(nodes) { + if (!nodes || nodes.length < 1) { + return; + } + + const node = nodes[0]; + const { document: doc, parent, index } = node; + + try { + const nodeSchema = await getClipboardText(); + if (parent) { + nodeSchema.forEach((schema, schemaIndex) => { + doc?.insertNode(parent, schema, (index ?? 0) + 1 + schemaIndex, true); + }); + } + } catch (error) { + console.error(error); + } + }, + }); + + material.addContextMenuOption({ + name: 'zhantieToInner', + title: intl('PasteToTheInside'), + condition: (nodes) => { + return nodes.length === 1; + }, + disabled: (nodes) => { + // 获取粘贴数据 + const node = nodes[0]; + return !node.isContainerNode; + }, + async action(nodes) { + const node = nodes[0]; + const { document: doc, parent } = node; + + try { + const nodeSchema = await getClipboardText(); + if (parent) { + const index = node.children?.size || 0; + + if (parent) { + nodeSchema.forEach((schema, schemaIndex) => { + doc?.insertNode(node, schema, (index ?? 0) + 1 + schemaIndex, true); + }); + } + } + } catch (error) { + console.error(error); + } + }, + }); + + material.addContextMenuOption({ + name: 'delete', + title: intl('Delete'), + action(nodes) { + nodes.forEach((node) => { + node.remove(); + }); + }, + }); + }, + }; +}; + +defaultContextMenu.pluginName = '___default_context_menu___'; diff --git a/packages/engine/src/locale/en-US.json b/packages/engine/src/locale/en-US.json new file mode 100644 index 0000000000..1cdb06f28b --- /dev/null +++ b/packages/engine/src/locale/en-US.json @@ -0,0 +1,9 @@ +{ + "NotValidNodeData": "Not valid node data", + "SelectComponents": "Select components", + "Copy": "Copy", + "Copy.1": "Copy", + "PasteToTheBottom": "Paste to the bottom", + "PasteToTheInside": "Paste to the inside", + "Delete": "Delete" +} diff --git a/packages/engine/src/locale/index.ts b/packages/engine/src/locale/index.ts new file mode 100644 index 0000000000..510fcf056a --- /dev/null +++ b/packages/engine/src/locale/index.ts @@ -0,0 +1,14 @@ +import { createIntl } from '@alilc/lowcode-editor-core'; +import enUS from './en-US.json'; +import zhCN from './zh-CN.json'; + +const { intl } = createIntl?.({ + 'en-US': enUS, + 'zh-CN': zhCN, +}) || { + intl: (id) => { + return zhCN[id]; + }, +}; + +export { intl, enUS, zhCN }; diff --git a/packages/engine/src/locale/zh-CN.json b/packages/engine/src/locale/zh-CN.json new file mode 100644 index 0000000000..ba0f87f8e6 --- /dev/null +++ b/packages/engine/src/locale/zh-CN.json @@ -0,0 +1,9 @@ +{ + "NotValidNodeData": "不是有效的节点数据", + "SelectComponents": "选择组件", + "Copy": "复制", + "Copy.1": "拷贝", + "PasteToTheBottom": "粘贴至下方", + "PasteToTheInside": "粘贴至内部", + "Delete": "删除" +} diff --git a/packages/shell/src/api/commonUI.ts b/packages/shell/src/api/commonUI.ts index 718b409707..9f40afa119 100644 --- a/packages/shell/src/api/commonUI.ts +++ b/packages/shell/src/api/commonUI.ts @@ -4,6 +4,7 @@ import { Title as InnerTitle, } from '@alilc/lowcode-editor-core'; import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; +import { ContextMenu } from '../components/context-menu'; export class CommonUI implements IPublicApiCommonUI { Balloon = Balloon; @@ -40,4 +41,7 @@ export class CommonUI implements IPublicApiCommonUI { get Title() { return InnerTitle; } + get ContextMenu() { + return ContextMenu; + } } diff --git a/packages/shell/src/api/material.ts b/packages/shell/src/api/material.ts index 39b21848e0..f0c37d8a4d 100644 --- a/packages/shell/src/api/material.ts +++ b/packages/shell/src/api/material.ts @@ -13,6 +13,8 @@ import { IPublicTypeNpmInfo, IPublicModelEditor, IPublicTypeDisposable, + IPublicTypeContextMenuAction, + IPublicTypeContextMenuItem, } from '@alilc/lowcode-types'; import { Workspace as InnerWorkspace } from '@alilc/lowcode-workspace'; import { editorSymbol, designerSymbol } from '../symbols'; @@ -190,4 +192,16 @@ export class Material implements IPublicApiMaterial { dispose.forEach(d => d && d()); }; } + + addContextMenuOption(option: IPublicTypeContextMenuAction) { + this[designerSymbol].contextMenuActions.addMenuAction(option); + } + + removeContextMenuOption(name: string) { + this[designerSymbol].contextMenuActions.removeMenuAction(name); + } + + adjustContextMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) { + this[designerSymbol].contextMenuActions.adjustMenuLayout(fn); + } } diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx new file mode 100644 index 0000000000..0085e1c777 --- /dev/null +++ b/packages/shell/src/components/context-menu.tsx @@ -0,0 +1,46 @@ +import { Menu } from '@alifd/next'; +import { parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; +import { engineConfig } from '@alilc/lowcode-editor-core'; +import { IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; +import React from 'react'; + +export function ContextMenu({ children, menus }: { + menus: IPublicTypeContextMenuAction[]; + children: React.ReactElement[]; +}): React.ReactElement<any, string | React.JSXElementConstructor<any>>[] { + if (!engineConfig.get('enableContextMenu')) { + return children; + } + + const handleContextMenu = (event: React.MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + + const target = event.target; + const { top, left } = target?.getBoundingClientRect(); + let destroyFn: Function | undefined; + const destroy = () => { + destroyFn?.(); + }; + const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, { + destroy, + })); + + const menuInstance = Menu.create({ + target: event.target, + offset: [event.clientX - left, event.clientY - top], + children, + }); + + destroyFn = (menuInstance as any).destroy; + }; + + // 克隆 children 并添加 onContextMenu 事件处理器 + const childrenWithContextMenu = React.Children.map(children, (child) => + React.cloneElement( + child, + { onContextMenu: handleContextMenu }, + )); + + return childrenWithContextMenu; +} \ No newline at end of file diff --git a/packages/types/src/shell/api/commonUI.ts b/packages/types/src/shell/api/commonUI.ts index 3d7bb57bf3..dcc6fab0c3 100644 --- a/packages/types/src/shell/api/commonUI.ts +++ b/packages/types/src/shell/api/commonUI.ts @@ -1,4 +1,5 @@ -import { IPublicTypeTitleContent } from '../type'; +import { ReactElement } from 'react'; +import { IPublicTypeContextMenuAction, IPublicTypeTitleContent } from '../type'; import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; export interface IPublicApiCommonUI { @@ -45,4 +46,9 @@ export interface IPublicApiCommonUI { match?: boolean; keywords?: string | null; }>; + + get ContextMenu(): (props: { + menus: IPublicTypeContextMenuAction[]; + children: React.ReactElement[]; + }) => ReactElement[]; } \ No newline at end of file diff --git a/packages/types/src/shell/api/material.ts b/packages/types/src/shell/api/material.ts index d64455eddd..6354c7fa0f 100644 --- a/packages/types/src/shell/api/material.ts +++ b/packages/types/src/shell/api/material.ts @@ -1,4 +1,4 @@ -import { IPublicTypeAssetsJson, IPublicTypeMetadataTransducer, IPublicTypeComponentAction, IPublicTypeNpmInfo, IPublicTypeDisposable } from '../type'; +import { IPublicTypeAssetsJson, IPublicTypeMetadataTransducer, IPublicTypeComponentAction, IPublicTypeNpmInfo, IPublicTypeDisposable, IPublicTypeContextMenuAction, IPublicTypeContextMenuItem } from '../type'; import { IPublicModelComponentMeta } from '../model'; import { ComponentType } from 'react'; @@ -128,4 +128,22 @@ export interface IPublicApiMaterial { * @since v1.1.7 */ refreshComponentMetasMap(): void; + + /** + * 添加右键菜单项 + * @param action + */ + addContextMenuOption(action: IPublicTypeContextMenuAction): void; + + /** + * 删除特定右键菜单项 + * @param name + */ + removeContextMenuOption(name: string): void; + + /** + * 调整右键菜单项布局 + * @param actions + */ + adjustContextMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]): void; } diff --git a/packages/types/src/shell/enum/context-menu.ts b/packages/types/src/shell/enum/context-menu.ts new file mode 100644 index 0000000000..fd209b1974 --- /dev/null +++ b/packages/types/src/shell/enum/context-menu.ts @@ -0,0 +1,7 @@ +export enum IPublicEnumContextMenuType { + SEPARATOR = 'separator', + // 'menuItem' + MENU_ITEM = 'menuItem', + // 'nodeTree' + NODE_TREE = 'nodeTree', +} \ No newline at end of file diff --git a/packages/types/src/shell/enum/index.ts b/packages/types/src/shell/enum/index.ts index f3d5580119..13282d0f2b 100644 --- a/packages/types/src/shell/enum/index.ts +++ b/packages/types/src/shell/enum/index.ts @@ -3,4 +3,5 @@ export * from './transition-type'; export * from './transform-stage'; export * from './drag-object-type'; export * from './prop-value-changed-type'; -export * from './plugin-register-level'; \ No newline at end of file +export * from './plugin-register-level'; +export * from './context-menu'; \ No newline at end of file diff --git a/packages/types/src/shell/type/context-menu.ts b/packages/types/src/shell/type/context-menu.ts new file mode 100644 index 0000000000..595893d32c --- /dev/null +++ b/packages/types/src/shell/type/context-menu.ts @@ -0,0 +1,57 @@ +import { IPublicEnumContextMenuType } from '../enum'; +import { IPublicModelNode } from '../model'; +import { IPublicTypeI18nData } from './i8n-data'; + +export interface IPublicTypeContextMenuItem extends Omit<IPublicTypeContextMenuAction, 'condition' | 'disabled' | 'items'> { + disabled?: boolean; + + items?: Omit<IPublicTypeContextMenuItem, 'items'>[]; +} + +export interface IPublicTypeContextMenuAction { + + /** + * 动作的唯一标识符 + * Unique identifier for the action + */ + name: string; + + /** + * 显示的标题,可以是字符串或国际化数据 + * Display title, can be a string or internationalized data + */ + title?: string | IPublicTypeI18nData; + + /** + * 菜单项类型 + * Menu item type + * @see IPublicEnumContextMenuType + * @default IPublicEnumPContextMenuType.MENU_ITEM + */ + type?: IPublicEnumContextMenuType; + + /** + * 点击时执行的动作,可选 + * Action to execute on click, optional + */ + action?: (nodes: IPublicModelNode[]) => void; + + /** + * 子菜单项或生成子节点的函数,可选,仅支持两级 + * Sub-menu items or function to generate child node, optional + */ + items?: Omit<IPublicTypeContextMenuAction, 'items'>[] | ((nodes: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]); + + /** + * 显示条件函数 + * Function to determine display condition + */ + condition?: (nodes: IPublicModelNode[]) => boolean; + + /** + * 禁用条件函数,可选 + * Function to determine disabled condition, optional + */ + disabled?: (nodes: IPublicModelNode[]) => boolean; +} + diff --git a/packages/types/src/shell/type/engine-options.ts b/packages/types/src/shell/type/engine-options.ts index 72078c8107..8221c4089c 100644 --- a/packages/types/src/shell/type/engine-options.ts +++ b/packages/types/src/shell/type/engine-options.ts @@ -178,6 +178,12 @@ export interface IPublicTypeEngineOptions { */ enableAutoOpenFirstWindow?: boolean; + /** + * @default false + * 开启右键菜单能力 + */ + enableContextMenu?: boolean; + /** * @default false * 隐藏设计器辅助层 diff --git a/packages/types/src/shell/type/index.ts b/packages/types/src/shell/type/index.ts index b2fd3313f9..b1c7779d05 100644 --- a/packages/types/src/shell/type/index.ts +++ b/packages/types/src/shell/type/index.ts @@ -91,4 +91,5 @@ export * from './hotkey-callback-config'; export * from './hotkey-callbacks'; export * from './scrollable'; export * from './simulator-renderer'; -export * from './config-transducer'; \ No newline at end of file +export * from './config-transducer'; +export * from './context-menu'; \ No newline at end of file diff --git a/packages/utils/src/context-menu.scss b/packages/utils/src/context-menu.scss new file mode 100644 index 0000000000..744eede873 --- /dev/null +++ b/packages/utils/src/context-menu.scss @@ -0,0 +1,33 @@ +.context-menu-tree-wrap { + position: relative; + padding: 4px 10px 4px 24px; +} + +.context-menu-tree-children { + margin-left: 8px; + line-height: 24px; +} + +.context-menu-tree-bg { + position: absolute; + left: 0; + right: 0; + cursor: pointer; +} + +.context-menu-tree-bg-inner { + position: absolute; + height: 24px; + top: -24px; + width: 100%; + + &:hover { + background-color: var(--color-block-background-light); + } +} + +.context-menu-tree-selected-icon { + position: absolute; + left: 10px; + color: var(--color-icon-active); +} \ No newline at end of file diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx new file mode 100644 index 0000000000..3c7bb5d134 --- /dev/null +++ b/packages/utils/src/context-menu.tsx @@ -0,0 +1,138 @@ +import { Menu, Icon } from '@alifd/next'; +import { IDesigner } from '@alilc/lowcode-designer'; +import { IPublicEnumContextMenuType, IPublicModelNode, IPublicTypeContextMenuAction, IPublicTypeContextMenuItem } from '@alilc/lowcode-types'; +import { Logger } from '@alilc/lowcode-utils'; +import React from 'react'; +import './context-menu.scss'; + +const logger = new Logger({ level: 'warn', bizName: 'designer' }); +const { Item, Divider, PopupItem } = Menu; + +const MAX_LEVEL = 2; + +const Tree = (props: { + node?: IPublicModelNode; + children?: React.ReactNode; + options: { + nodes?: IPublicModelNode[] | null; + destroy?: Function; + designer?: IDesigner; + }; +}) => { + const { node } = props; + + if (!node) { + return null; + } + + if (!node.parent) { + return ( + <div className="context-menu-tree-wrap"> + <div className="context-menu-tree-children"> + {props.children} + </div> + </div> + ); + } + + const commonUI = props.options.designer?.editor?.get('commonUI'); + + const Title = commonUI?.Title; + + return ( + <Tree {...props} node={node.parent} > + {props.options.nodes?.[0].id === node.id ? (<Icon className="context-menu-tree-selected-icon" size="small" type="success" />) : null} + <Title title={node.title} /> + <div + className="context-menu-tree-children" + > + <div + className="context-menu-tree-bg" + onClick={() => { + props.options.destroy?.(); + node.select(); + }} + > + <div className="context-menu-tree-bg-inner" /> + </div> + { props.children } + </div> + </Tree> + ); +}; + +export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], options: { + nodes?: IPublicModelNode[] | null; + destroy?: Function; + designer?: IDesigner; +} = {}): React.ReactNode[] { + const children: React.ReactNode[] = []; + menus.forEach((menu, index) => { + if (menu.type === IPublicEnumContextMenuType.SEPARATOR) { + children.push(<Divider key={menu.name || index} />); + return; + } + + if (menu.type === IPublicEnumContextMenuType.MENU_ITEM) { + if (menu.items && menu.items.length) { + children.push(( + <PopupItem key={menu.name} label={menu.title}> + <Menu className="next-context engine-context-menu"> + { parseContextMenuAsReactNode(menu.items, options) } + </Menu> + </PopupItem> + )); + } else { + children.push((<Item disabled={menu.disabled} onClick={menu.action} key={menu.name}>{menu.title}</Item>)); + } + } + + if (menu.type === IPublicEnumContextMenuType.NODE_TREE) { + children.push(( + <Tree node={options.nodes?.[0]} options={options} /> + )); + } + }); + + return children; +} + +export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction | Omit<IPublicTypeContextMenuAction, 'items'>)[], options: { + nodes?: IPublicModelNode[] | null; + destroy?: Function; +}, level = 1): IPublicTypeContextMenuItem[] { + const { nodes, destroy } = options; + if (level > MAX_LEVEL) { + logger.warn('context menu level is too deep, please check your context menu config'); + return []; + } + + return menus.filter(menu => !menu.condition || (menu.condition && menu.condition(nodes || []))).map((menu) => { + const { + name, + title, + type = IPublicEnumContextMenuType.MENU_ITEM, + } = menu; + + const result: IPublicTypeContextMenuItem = { + name, + title, + type, + action: () => { + destroy?.(); + menu.action?.(nodes || []); + }, + disabled: menu.disabled && menu.disabled(nodes || []) || false, + }; + + if ('items' in menu && menu.items) { + result.items = parseContextMenuProperties( + typeof menu.items === 'function' ? menu.items(nodes || []) : menu.items, + options, + level + 1, + ); + } + + return result; + }); +} \ No newline at end of file diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 3e37f46ba6..b99ab02073 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -31,3 +31,4 @@ export * as css from './css-helper'; export { transactionManager } from './transaction-manager'; export * from './check-types'; export * from './workspace'; +export * from './context-menu'; From 3f369e446d2c16f6c2aa88ee1c9d5f336ad37b71 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Mon, 8 Jan 2024 06:56:19 +0000 Subject: [PATCH 275/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 6659eaf853..3ef05af3cb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.19", + "version": "1.2.20", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 6288ab9d60fe4e91475b685c7926c1adb971a935 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 8 Jan 2024 15:06:00 +0800 Subject: [PATCH 276/361] fix(docs): fix invalid doc content --- docs/docs/api/commonUI.md | 70 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index ef7af7f415..82b57c3893 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -40,99 +40,99 @@ CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开 | 参数 | 说明 | 类型 | 默认值 | |------------|--------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------------| -| name | 动作的唯一标识符<br>Unique identifier for the action | string | | -| title | 显示的标题,可以是字符串或国际化数据<br>Display title, can be a string or internationalized data | string \| IPublicTypeI18nData (optional) | | -| type | 菜单项类型<br>Menu item type | IPublicEnumContextMenuType (optional) | IPublicEnumPContextMenuType.MENU_ITEM | -| action | 点击时执行的动作,可选<br>Action to execute on click, optional | (nodes: IPublicModelNode[]) => void (optional) | | -| items | 子菜单项或生成子节点的函数,可选,仅支持两级<br>Sub-menu items or function to generate child node, optional | Omit<IPublicTypeContextMenuAction, 'items'>[] \| ((nodes: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]) (optional) | | -| condition | 显示条件函数<br>Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | | -| disabled | 禁用条件函数,可选<br>Function to determine disabled condition, optional | (nodes: IPublicModelNode[]) => boolean (optional) | | +| name | 动作的唯一标识符<br/>Unique identifier for the action | string | | +| title | 显示的标题,可以是字符串或国际化数据<br/>Display title, can be a string or internationalized data | string \| IPublicTypeI18nData (optional) | | +| type | 菜单项类型<br/>Menu item type | IPublicEnumContextMenuType (optional) | IPublicEnumPContextMenuType.MENU_ITEM | +| action | 点击时执行的动作,可选<br/>Action to execute on click, optional | (nodes: IPublicModelNode[]) => void (optional) | | +| items | 子菜单项或生成子节点的函数,可选,仅支持两级<br/>Sub-menu items or function to generate child node, optional | Omit<IPublicTypeContextMenuAction, 'items'>[] \| ((nodes: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]) (optional) | | +| condition | 显示条件函数<br/>Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | | +| disabled | 禁用条件函数,可选<br/>Function to determine disabled condition, optional | (nodes: IPublicModelNode[]) => boolean (optional) | | ### Balloon -详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon) +详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon) ### Breadcrumb -详细文档: [Breadcrumb Documentation](https://fusion.design/pc/component/breadcrumb) +详细文档: [Breadcrumb Documentation](https://fusion.design/pc/component/breadcrumb) ### Button -详细文档: [Button Documentation](https://fusion.design/pc/component/button) +详细文档: [Button Documentation](https://fusion.design/pc/component/button) ### Card -详细文档: [Card Documentation](https://fusion.design/pc/component/card) +详细文档:[Card Documentation](https://fusion.design/pc/component/card) ### Checkbox -详细文档: [Checkbox Documentation](https://fusion.design/pc/component/checkbox) +详细文档:[Checkbox Documentation](https://fusion.design/pc/component/checkbox) ### DatePicker -详细文档: [DatePicker Documentation](https://fusion.design/pc/component/datepicker) +详细文档:[DatePicker Documentation](https://fusion.design/pc/component/datepicker) ### Dialog -详细文档: [Dialog Documentation](https://fusion.design/pc/component/dialog) +详细文档:[Dialog Documentation](https://fusion.design/pc/component/dialog) ### Dropdown -详细文档: [Dropdown Documentation](https://fusion.design/pc/component/dropdown) +详细文档:[Dropdown Documentation](https://fusion.design/pc/component/dropdown) ### Form -详细文档: [Form Documentation](https://fusion.design/pc/component/form) +详细文档:[Form Documentation](https://fusion.design/pc/component/form) ### Icon -详细文档: [Icon Documentation](https://fusion.design/pc/component/icon) +详细文档:[Icon Documentation](https://fusion.design/pc/component/icon) 引擎默认主题支持的 icon 列表:https://fusion.design/64063/component/icon?themeid=20133 ### Input -详细文档: [Input Documentation](https://fusion.design/pc/component/input) +详细文档:[Input Documentation](https://fusion.design/pc/component/input) ### Loading -详细文档: [Loading Documentation](https://fusion.design/pc/component/loading) +详细文档:[Loading Documentation](https://fusion.design/pc/component/loading) ### Message -详细文档: [Message Documentation](https://fusion.design/pc/component/message) +详细文档:[Message Documentation](https://fusion.design/pc/component/message) ### Overlay -详细文档: [Overlay Documentation](https://fusion.design/pc/component/overlay) +详细文档:[Overlay Documentation](https://fusion.design/pc/component/overlay) ### Pagination -详细文档: [Pagination Documentation](https://fusion.design/pc/component/pagination) +详细文档:[Pagination Documentation](https://fusion.design/pc/component/pagination) ### Radio -详细文档: [Radio Documentation](https://fusion.design/pc/component/radio) +详细文档:[Radio Documentation](https://fusion.design/pc/component/radio) ### Search -详细文档: [Search Documentation](https://fusion.design/pc/component/search) +详细文档:[Search Documentation](https://fusion.design/pc/component/search) ### Select -详细文档: [Select Documentation](https://fusion.design/pc/component/select) +详细文档:[Select Documentation](https://fusion.design/pc/component/select) ### SplitButton -详细文档: [SplitButton Documentation](https://fusion.design/pc/component/splitbutton) +详细文档:[SplitButton Documentation](https://fusion.design/pc/component/splitbutton) ### Step -详细文档: [Step Documentation](https://fusion.design/pc/component/step) +详细文档:[Step Documentation](https://fusion.design/pc/component/step) ### Switch -详细文档: [Switch Documentation](https://fusion.design/pc/component/switch) +详细文档:[Switch Documentation](https://fusion.design/pc/component/switch) ### Tab -详细文档: [Tab Documentation](https://fusion.design/pc/component/tab) +详细文档:[Tab Documentation](https://fusion.design/pc/component/tab) ### Table -详细文档: [Table Documentation](https://fusion.design/pc/component/table) +详细文档:[Table Documentation](https://fusion.design/pc/component/table) ### Tree -详细文档: [Tree Documentation](https://fusion.design/pc/component/tree) +详细文档:[Tree Documentation](https://fusion.design/pc/component/tree) ### TreeSelect -详细文档: [TreeSelect Documentation](https://fusion.design/pc/component/treeselect) +详细文档:[TreeSelect Documentation](https://fusion.design/pc/component/treeselect) ### Upload -详细文档: [Upload Documentation](https://fusion.design/pc/component/upload) +详细文档:[Upload Documentation](https://fusion.design/pc/component/upload) ### Divider -详细文档: [Divider Documentation](https://fusion.design/pc/component/divider) +详细文档:[Divider Documentation](https://fusion.design/pc/component/divider) ## 说明 -如果需要其他组件,可以提issue给我们 \ No newline at end of file +如果需要其他组件,可以提 issue 给我们。 From 6ce381f60aa1deb714d3fbe52f6240f8d352f759 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Mon, 8 Jan 2024 07:06:58 +0000 Subject: [PATCH 277/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 3ef05af3cb..1f49ab6247 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.20", + "version": "1.2.21", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 6ded1a6384174b10b0069d9129bbc14d1a9daeb6 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 8 Jan 2024 18:48:06 +0800 Subject: [PATCH 278/361] chore: update CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c2e49b783f..1000fca053 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,4 +5,4 @@ * @liujuping @JackLian /modules/material-parser @akirakai -/modules/code-generator @leoyuan +/modules/code-generator @qingniaotonghua From 8f0291fc3e58eaec2d786ff8e1854657208d5bde Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 8 Jan 2024 18:46:30 +0800 Subject: [PATCH 279/361] fix(context-menu): fix context menu bugs --- packages/designer/src/context-menu-actions.ts | 4 +++- .../engine/src/inner-plugins/default-context-menu.ts | 6 ++++++ packages/utils/src/context-menu.scss | 2 +- packages/utils/src/context-menu.tsx | 10 +--------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index 053e4f0313..55a83ef2ff 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -17,6 +17,8 @@ export interface IContextMenuActions { adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout']; } +let destroyFn: Function | undefined; + export class ContextMenuActions implements IContextMenuActions { actions: IPublicTypeContextMenuAction[] = []; @@ -55,7 +57,7 @@ export class ContextMenuActions implements IContextMenuActions { const { bounds } = designer.project.simulator?.viewport || { bounds: { left: 0, top: 0 } }; const { left: simulatorLeft, top: simulatorTop } = bounds; - let destroyFn: Function | undefined; + destroyFn?.(); const destroy = () => { destroyFn?.(); diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index 86feb17d97..50a86fcec8 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -87,6 +87,9 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copy', title: intl('Copy.1'), + condition(nodes) { + return nodes.length > 0; + }, action(nodes) { if (!nodes || nodes.length < 1) { return; @@ -159,6 +162,9 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'delete', title: intl('Delete'), + condition(nodes) { + return nodes.length > 0; + }, action(nodes) { nodes.forEach((node) => { node.remove(); diff --git a/packages/utils/src/context-menu.scss b/packages/utils/src/context-menu.scss index 744eede873..0bcf39d153 100644 --- a/packages/utils/src/context-menu.scss +++ b/packages/utils/src/context-menu.scss @@ -1,6 +1,6 @@ .context-menu-tree-wrap { position: relative; - padding: 4px 10px 4px 24px; + padding: 4px 10px 4px 32px; } .context-menu-tree-children { diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx index 3c7bb5d134..f65bc312f6 100644 --- a/packages/utils/src/context-menu.tsx +++ b/packages/utils/src/context-menu.tsx @@ -22,16 +22,8 @@ const Tree = (props: { const { node } = props; if (!node) { - return null; - } - - if (!node.parent) { return ( - <div className="context-menu-tree-wrap"> - <div className="context-menu-tree-children"> - {props.children} - </div> - </div> + <div className="context-menu-tree-wrap">{ props.children }</div> ); } From c381b85f0a48b215414e72c76864aa8b435fd443 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 9 Jan 2024 16:37:42 +0800 Subject: [PATCH 280/361] fix(context-menu): fix context menu bugs --- docs/docs/api/commonUI.md | 2 +- packages/designer/src/context-menu-actions.ts | 121 +++++++++++++++--- .../src/inner-plugins/default-context-menu.ts | 4 +- packages/engine/src/locale/en-US.json | 2 +- packages/engine/src/locale/zh-CN.json | 4 +- .../shell/src/components/context-menu.tsx | 16 ++- packages/types/src/shell/api/commonUI.ts | 4 +- packages/types/src/shell/type/context-menu.ts | 4 +- packages/utils/src/context-menu.tsx | 73 +++++++---- 9 files changed, 171 insertions(+), 59 deletions(-) diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index 82b57c3893..f3afe1fc25 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -42,7 +42,7 @@ CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开 |------------|--------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------------| | name | 动作的唯一标识符<br/>Unique identifier for the action | string | | | title | 显示的标题,可以是字符串或国际化数据<br/>Display title, can be a string or internationalized data | string \| IPublicTypeI18nData (optional) | | -| type | 菜单项类型<br/>Menu item type | IPublicEnumContextMenuType (optional) | IPublicEnumPContextMenuType.MENU_ITEM | +| type | 菜单项类型<br/>Menu item type | IPublicEnumContextMenuType (optional) | IPublicEnumContextMenuType.MENU_ITEM | | action | 点击时执行的动作,可选<br/>Action to execute on click, optional | (nodes: IPublicModelNode[]) => void (optional) | | | items | 子菜单项或生成子节点的函数,可选,仅支持两级<br/>Sub-menu items or function to generate child node, optional | Omit<IPublicTypeContextMenuAction, 'items'>[] \| ((nodes: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]) (optional) | | | condition | 显示条件函数<br/>Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | | diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index 55a83ef2ff..8c210d89e0 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -1,6 +1,6 @@ import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial } from '@alilc/lowcode-types'; import { IDesigner, INode } from './designer'; -import { parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; +import { parseContextMenuAsReactNode, parseContextMenuProperties, uniqueId } from '@alilc/lowcode-utils'; import { Menu } from '@alifd/next'; import { engineConfig } from '@alilc/lowcode-editor-core'; import './context-menu-actions.scss'; @@ -17,7 +17,100 @@ export interface IContextMenuActions { adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout']; } -let destroyFn: Function | undefined; +let adjustMenuLayoutFn: Function = (actions: IPublicTypeContextMenuAction[]) => actions; + +export class GlobalContextMenuActions { + enableContextMenu: boolean; + + dispose: Function[]; + + contextMenuActionsMap: Map<string, ContextMenuActions> = new Map(); + + constructor() { + this.dispose = []; + + engineConfig.onGot('enableContextMenu', (enable) => { + if (this.enableContextMenu === enable) { + return; + } + this.enableContextMenu = enable; + this.dispose.forEach(d => d()); + if (enable) { + this.initEvent(); + } + }); + } + + handleContextMenu = ( + event: MouseEvent, + ) => { + event.stopPropagation(); + event.preventDefault(); + + const actions: IPublicTypeContextMenuAction[] = []; + this.contextMenuActionsMap.forEach((contextMenu) => { + actions.push(...contextMenu.actions); + }); + + let destroyFn: Function | undefined; + + const destroy = () => { + destroyFn?.(); + }; + + const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, { + nodes: [], + destroy, + event, + }); + + if (!menus.length) { + return; + } + + const layoutMenu = adjustMenuLayoutFn(menus); + + const menuNode = parseContextMenuAsReactNode(layoutMenu, { + destroy, + nodes: [], + }); + + const target = event.target; + + const { top, left } = target?.getBoundingClientRect(); + + const menuInstance = Menu.create({ + target: event.target, + offset: [event.clientX - left, event.clientY - top], + children: menuNode, + className: 'engine-context-menu', + }); + + destroyFn = (menuInstance as any).destroy; + }; + + initEvent() { + this.dispose.push( + (() => { + const handleContextMenu = (e: MouseEvent) => { + this.handleContextMenu(e); + }; + + document.addEventListener('contextmenu', handleContextMenu); + + return () => { + document.removeEventListener('contextmenu', handleContextMenu); + }; + })(), + ); + } + + registerContextMenuActions(contextMenu: ContextMenuActions) { + this.contextMenuActionsMap.set(contextMenu.id, contextMenu); + } +} + +const globalContextMenuActions = new GlobalContextMenuActions(); export class ContextMenuActions implements IContextMenuActions { actions: IPublicTypeContextMenuAction[] = []; @@ -28,6 +121,8 @@ export class ContextMenuActions implements IContextMenuActions { enableContextMenu: boolean; + id: string = uniqueId('contextMenu');; + constructor(designer: IDesigner) { this.designer = designer; this.dispose = []; @@ -42,6 +137,8 @@ export class ContextMenuActions implements IContextMenuActions { this.initEvent(); } }); + + globalContextMenuActions.registerContextMenuActions(this); } handleContextMenu = ( @@ -57,7 +154,7 @@ export class ContextMenuActions implements IContextMenuActions { const { bounds } = designer.project.simulator?.viewport || { bounds: { left: 0, top: 0 } }; const { left: simulatorLeft, top: simulatorTop } = bounds; - destroyFn?.(); + let destroyFn: Function | undefined; const destroy = () => { destroyFn?.(); @@ -66,13 +163,14 @@ export class ContextMenuActions implements IContextMenuActions { const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, { nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!), destroy, + event, }); if (!menus.length) { return; } - const layoutMenu = designer.contextMenuActions.adjustMenuLayoutFn(menus); + const layoutMenu = adjustMenuLayoutFn(menus); const menuNode = parseContextMenuAsReactNode(layoutMenu, { destroy, @@ -111,22 +209,9 @@ export class ContextMenuActions implements IContextMenuActions { const nodes = designer.currentSelection.getNodes(); this.handleContextMenu(nodes, originalEvent); }), - (() => { - const handleContextMenu = (e: MouseEvent) => { - this.handleContextMenu([], e); - }; - - document.addEventListener('contextmenu', handleContextMenu); - - return () => { - document.removeEventListener('contextmenu', handleContextMenu); - }; - })(), ); } - adjustMenuLayoutFn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[] = (actions) => actions; - addMenuAction(action: IPublicTypeContextMenuAction) { this.actions.push({ type: IPublicEnumContextMenuType.MENU_ITEM, @@ -142,6 +227,6 @@ export class ContextMenuActions implements IContextMenuActions { } adjustMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) { - this.adjustMenuLayoutFn = fn; + adjustMenuLayoutFn = fn; } } \ No newline at end of file diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index 50a86fcec8..fc1da96b4a 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -70,7 +70,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copyAndPaste', - title: intl('Copy'), + title: intl('CopyAndPaste'), condition: (nodes) => { return nodes.length === 1; }, @@ -86,7 +86,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copy', - title: intl('Copy.1'), + title: intl('Copy'), condition(nodes) { return nodes.length > 0; }, diff --git a/packages/engine/src/locale/en-US.json b/packages/engine/src/locale/en-US.json index 1cdb06f28b..e931607073 100644 --- a/packages/engine/src/locale/en-US.json +++ b/packages/engine/src/locale/en-US.json @@ -1,8 +1,8 @@ { "NotValidNodeData": "Not valid node data", "SelectComponents": "Select components", + "CopyAndPaste": "Copy and Paste", "Copy": "Copy", - "Copy.1": "Copy", "PasteToTheBottom": "Paste to the bottom", "PasteToTheInside": "Paste to the inside", "Delete": "Delete" diff --git a/packages/engine/src/locale/zh-CN.json b/packages/engine/src/locale/zh-CN.json index ba0f87f8e6..9b68b71490 100644 --- a/packages/engine/src/locale/zh-CN.json +++ b/packages/engine/src/locale/zh-CN.json @@ -1,8 +1,8 @@ { "NotValidNodeData": "不是有效的节点数据", "SelectComponents": "选择组件", - "Copy": "复制", - "Copy.1": "拷贝", + "CopyAndPaste": "复制", + "Copy": "拷贝", "PasteToTheBottom": "粘贴至下方", "PasteToTheInside": "粘贴至内部", "Delete": "删除" diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx index 0085e1c777..f12f6ca93d 100644 --- a/packages/shell/src/components/context-menu.tsx +++ b/packages/shell/src/components/context-menu.tsx @@ -6,10 +6,12 @@ import React from 'react'; export function ContextMenu({ children, menus }: { menus: IPublicTypeContextMenuAction[]; - children: React.ReactElement[]; -}): React.ReactElement<any, string | React.JSXElementConstructor<any>>[] { + children: React.ReactElement[] | React.ReactElement; +}): React.ReactElement<any, string | React.JSXElementConstructor<any>> { if (!engineConfig.get('enableContextMenu')) { - return children; + return ( + <>{ children }</> + ); } const handleContextMenu = (event: React.MouseEvent) => { @@ -26,6 +28,10 @@ export function ContextMenu({ children, menus }: { destroy, })); + if (!children?.length) { + return; + } + const menuInstance = Menu.create({ target: event.target, offset: [event.clientX - left, event.clientY - top], @@ -42,5 +48,7 @@ export function ContextMenu({ children, menus }: { { onContextMenu: handleContextMenu }, )); - return childrenWithContextMenu; + return ( + <>{childrenWithContextMenu}</> + ); } \ No newline at end of file diff --git a/packages/types/src/shell/api/commonUI.ts b/packages/types/src/shell/api/commonUI.ts index dcc6fab0c3..71e2bbe83f 100644 --- a/packages/types/src/shell/api/commonUI.ts +++ b/packages/types/src/shell/api/commonUI.ts @@ -49,6 +49,6 @@ export interface IPublicApiCommonUI { get ContextMenu(): (props: { menus: IPublicTypeContextMenuAction[]; - children: React.ReactElement[]; - }) => ReactElement[]; + children: React.ReactElement[] | React.ReactElement; + }) => ReactElement; } \ No newline at end of file diff --git a/packages/types/src/shell/type/context-menu.ts b/packages/types/src/shell/type/context-menu.ts index 595893d32c..1eeb93d696 100644 --- a/packages/types/src/shell/type/context-menu.ts +++ b/packages/types/src/shell/type/context-menu.ts @@ -26,7 +26,7 @@ export interface IPublicTypeContextMenuAction { * 菜单项类型 * Menu item type * @see IPublicEnumContextMenuType - * @default IPublicEnumPContextMenuType.MENU_ITEM + * @default IPublicEnumContextMenuType.MENU_ITEM */ type?: IPublicEnumContextMenuType; @@ -34,7 +34,7 @@ export interface IPublicTypeContextMenuAction { * 点击时执行的动作,可选 * Action to execute on click, optional */ - action?: (nodes: IPublicModelNode[]) => void; + action?: (nodes: IPublicModelNode[], event?: MouseEvent) => void; /** * 子菜单项或生成子节点的函数,可选,仅支持两级 diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx index f65bc312f6..f28619df61 100644 --- a/packages/utils/src/context-menu.tsx +++ b/packages/utils/src/context-menu.tsx @@ -89,42 +89,61 @@ export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], return children; } +let destroyFn: Function | undefined; export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction | Omit<IPublicTypeContextMenuAction, 'items'>)[], options: { nodes?: IPublicModelNode[] | null; destroy?: Function; + event?: MouseEvent; }, level = 1): IPublicTypeContextMenuItem[] { + destroyFn?.(); + destroyFn = options.destroy; + const { nodes, destroy } = options; if (level > MAX_LEVEL) { logger.warn('context menu level is too deep, please check your context menu config'); return []; } - return menus.filter(menu => !menu.condition || (menu.condition && menu.condition(nodes || []))).map((menu) => { - const { - name, - title, - type = IPublicEnumContextMenuType.MENU_ITEM, - } = menu; - - const result: IPublicTypeContextMenuItem = { - name, - title, - type, - action: () => { - destroy?.(); - menu.action?.(nodes || []); - }, - disabled: menu.disabled && menu.disabled(nodes || []) || false, - }; - - if ('items' in menu && menu.items) { - result.items = parseContextMenuProperties( - typeof menu.items === 'function' ? menu.items(nodes || []) : menu.items, - options, - level + 1, - ); - } + return menus + .filter(menu => !menu.condition || (menu.condition && menu.condition(nodes || []))) + .map((menu) => { + const { + name, + title, + type = IPublicEnumContextMenuType.MENU_ITEM, + } = menu; + + const result: IPublicTypeContextMenuItem = { + name, + title, + type, + action: () => { + destroy?.(); + menu.action?.(nodes || [], options.event); + }, + disabled: menu.disabled && menu.disabled(nodes || []) || false, + }; + + if ('items' in menu && menu.items) { + result.items = parseContextMenuProperties( + typeof menu.items === 'function' ? menu.items(nodes || []) : menu.items, + options, + level + 1, + ); + } - return result; - }); + return result; + }) + .reduce((menus: IPublicTypeContextMenuItem[], currentMenu: IPublicTypeContextMenuItem) => { + if (!currentMenu.name) { + return menus.concat([currentMenu]); + } + + const index = menus.find(item => item.name === currentMenu.name); + if (!index) { + return menus.concat([currentMenu]); + } else { + return menus; + } + }, []); } \ No newline at end of file From 14728476b65d5bdeaa7624df1b4a74850516d049 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Tue, 9 Jan 2024 08:43:50 +0000 Subject: [PATCH 281/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 1f49ab6247..e0fea44a14 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.21", + "version": "1.2.22", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 3627ae326a5b46e669d921e5b98e237a44e9bdea Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 10 Jan 2024 15:13:44 +0800 Subject: [PATCH 282/361] feat: optimize context menu details --- docs/docs/api/material.md | 37 ++++++++ packages/designer/src/context-menu-actions.ts | 16 +--- .../src/inner-plugins/default-context-menu.ts | 90 +++++++++++++++---- packages/engine/src/locale/index.ts | 4 +- .../shell/src/components/context-menu.tsx | 13 +-- packages/utils/src/context-menu.tsx | 55 +++++++++++- 6 files changed, 174 insertions(+), 41 deletions(-) diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 51ed4e3054..c83935b971 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -237,6 +237,43 @@ material.modifyBuiltinComponentAction('remove', (action) => { }); ``` +### 右键菜单项 +#### addContextMenuOption + +添加右键菜单项 + +```typescript +/** + * 添加右键菜单项 + * @param action + */ +addContextMenuOption(action: IPublicTypeContextMenuAction): void; +``` + +#### removeContextMenuOption + +删除特定右键菜单项 + +```typescript +/** + * 删除特定右键菜单项 + * @param name + */ +removeContextMenuOption(name: string): void; +``` + +#### adjustContextMenuLayout + +调整右键菜单项布局,每次调用都会覆盖之前注册的调整函数,只有最后注册的函数会被应用。 + +```typescript +/** + * 调整右键菜单项布局 + * @param actions + */ +adjustContextMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]): void; +``` + ### 物料元数据 #### getComponentMeta 获取指定名称的物料元数据 diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index 8c210d89e0..5b44055b42 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -1,6 +1,6 @@ import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial } from '@alilc/lowcode-types'; import { IDesigner, INode } from './designer'; -import { parseContextMenuAsReactNode, parseContextMenuProperties, uniqueId } from '@alilc/lowcode-utils'; +import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties, uniqueId } from '@alilc/lowcode-utils'; import { Menu } from '@alifd/next'; import { engineConfig } from '@alilc/lowcode-editor-core'; import './context-menu-actions.scss'; @@ -178,18 +178,10 @@ export class ContextMenuActions implements IContextMenuActions { designer, }); - const target = event.target; - - const { top, left } = target?.getBoundingClientRect(); - - const menuInstance = Menu.create({ - target: event.target, - offset: [event.clientX - left + simulatorLeft, event.clientY - top + simulatorTop], - children: menuNode, - className: 'engine-context-menu', + destroyFn = createContextMenu(menuNode, { + event, + offset: [simulatorLeft, simulatorTop], }); - - destroyFn = (menuInstance as any).destroy; }; initEvent() { diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index fc1da96b4a..9d1336b34e 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -1,13 +1,16 @@ import { IPublicEnumContextMenuType, + IPublicEnumDragObjectType, IPublicEnumTransformStage, IPublicModelNode, IPublicModelPluginContext, + IPublicTypeDragNodeDataObject, + IPublicTypeI18nData, IPublicTypeNodeSchema, } from '@alilc/lowcode-types'; -import { isProjectSchema } from '@alilc/lowcode-utils'; +import { isI18nData, isProjectSchema } from '@alilc/lowcode-utils'; import { Notification } from '@alifd/next'; -import { intl } from '../locale'; +import { intl, getLocale } from '../locale'; function getNodesSchema(nodes: IPublicModelNode[]) { const componentsTree = nodes.map((node) => node?.exportSchema(IPublicEnumTransformStage.Clone)); @@ -15,6 +18,15 @@ function getNodesSchema(nodes: IPublicModelNode[]) { return data; } +function getIntlStr(data: string | IPublicTypeI18nData) { + if (!isI18nData(data)) { + return data; + } + + const locale = getLocale(); + return data[locale] || data['zh-CN'] || data['zh_CN'] || data['en-US'] || data['en_US'] || ''; +} + async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> { return new Promise((resolve, reject) => { // 使用 Clipboard API 读取剪贴板内容 @@ -71,12 +83,18 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copyAndPaste', title: intl('CopyAndPaste'), + disabled: (nodes) => { + return nodes?.filter((node) => !node?.canPerformAction('copy')).length > 0; + }, condition: (nodes) => { return nodes.length === 1; }, action(nodes) { const node = nodes[0]; const { document: doc, parent, index } = node; + const data = getNodesSchema(nodes); + clipboard.setData(data); + if (parent) { const newNode = doc?.insertNode(parent, node, (index ?? 0) + 1, true); newNode?.select(); @@ -87,6 +105,9 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copy', title: intl('Copy'), + disabled: (nodes) => { + return nodes?.filter((node) => !node?.canPerformAction('copy')).length > 0; + }, condition(nodes) { return nodes.length > 0; }, @@ -101,7 +122,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { }); material.addContextMenuOption({ - name: 'zhantieToBottom', + name: 'pasteToBottom', title: intl('PasteToTheBottom'), condition: (nodes) => { return nodes.length === 1; @@ -116,10 +137,30 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { try { const nodeSchema = await getClipboardText(); + if (nodeSchema.length === 0) { + return; + } if (parent) { - nodeSchema.forEach((schema, schemaIndex) => { - doc?.insertNode(parent, schema, (index ?? 0) + 1 + schemaIndex, true); + let canAddNodes = nodeSchema.filter((nodeSchema: IPublicTypeNodeSchema) => { + const dragNodeObject: IPublicTypeDragNodeDataObject = { + type: IPublicEnumDragObjectType.NodeData, + data: nodeSchema, + }; + return doc?.checkNesting(parent, dragNodeObject); + }); + if (canAddNodes.length === 0) { + Notification.open({ + content: `${nodeSchema.map(d => getIntlStr(d.title || d.componentName)).join(',')}等组件无法放置到${getIntlStr(parent.title || parent.componentName as any)}内`, + type: 'error', + }); + return; + } + const nodes: IPublicModelNode[] = []; + canAddNodes.forEach((schema, schemaIndex) => { + const node = doc?.insertNode(parent, schema, (index ?? 0) + 1 + schemaIndex, true); + node && nodes.push(node); }); + doc?.selection.selectAll(nodes.map((node) => node?.id)); } } catch (error) { console.error(error); @@ -128,7 +169,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { }); material.addContextMenuOption({ - name: 'zhantieToInner', + name: 'pasteToInner', title: intl('PasteToTheInside'), condition: (nodes) => { return nodes.length === 1; @@ -140,19 +181,35 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { }, async action(nodes) { const node = nodes[0]; - const { document: doc, parent } = node; + const { document: doc } = node; try { const nodeSchema = await getClipboardText(); - if (parent) { - const index = node.children?.size || 0; - - if (parent) { - nodeSchema.forEach((schema, schemaIndex) => { - doc?.insertNode(node, schema, (index ?? 0) + 1 + schemaIndex, true); - }); - } + const index = node.children?.size || 0; + if (nodeSchema.length === 0) { + return; } + let canAddNodes = nodeSchema.filter((nodeSchema: IPublicTypeNodeSchema) => { + const dragNodeObject: IPublicTypeDragNodeDataObject = { + type: IPublicEnumDragObjectType.NodeData, + data: nodeSchema, + }; + return doc?.checkNesting(node, dragNodeObject); + }); + if (canAddNodes.length === 0) { + Notification.open({ + content: `${nodeSchema.map(d => getIntlStr(d.title || d.componentName)).join(',')}等组件无法放置到${getIntlStr(node.title || node.componentName as any)}内`, + type: 'error', + }); + return; + } + + const nodes: IPublicModelNode[] = []; + nodeSchema.forEach((schema, schemaIndex) => { + const newNode = doc?.insertNode(node, schema, (index ?? 0) + 1 + schemaIndex, true); + newNode && nodes.push(newNode); + }); + doc?.selection.selectAll(nodes.map((node) => node?.id)); } catch (error) { console.error(error); } @@ -162,6 +219,9 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'delete', title: intl('Delete'), + disabled(nodes) { + return nodes?.filter((node) => !node?.canPerformAction('remove')).length > 0; + }, condition(nodes) { return nodes.length > 0; }, diff --git a/packages/engine/src/locale/index.ts b/packages/engine/src/locale/index.ts index 510fcf056a..ca89840b05 100644 --- a/packages/engine/src/locale/index.ts +++ b/packages/engine/src/locale/index.ts @@ -2,7 +2,7 @@ import { createIntl } from '@alilc/lowcode-editor-core'; import enUS from './en-US.json'; import zhCN from './zh-CN.json'; -const { intl } = createIntl?.({ +const { intl, getLocale } = createIntl?.({ 'en-US': enUS, 'zh-CN': zhCN, }) || { @@ -11,4 +11,4 @@ const { intl } = createIntl?.({ }, }; -export { intl, enUS, zhCN }; +export { intl, enUS, zhCN, getLocale }; diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx index f12f6ca93d..acefbebd28 100644 --- a/packages/shell/src/components/context-menu.tsx +++ b/packages/shell/src/components/context-menu.tsx @@ -1,5 +1,4 @@ -import { Menu } from '@alifd/next'; -import { parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; +import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; import { engineConfig } from '@alilc/lowcode-editor-core'; import { IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; import React from 'react'; @@ -18,8 +17,6 @@ export function ContextMenu({ children, menus }: { event.preventDefault(); event.stopPropagation(); - const target = event.target; - const { top, left } = target?.getBoundingClientRect(); let destroyFn: Function | undefined; const destroy = () => { destroyFn?.(); @@ -32,13 +29,9 @@ export function ContextMenu({ children, menus }: { return; } - const menuInstance = Menu.create({ - target: event.target, - offset: [event.clientX - left, event.clientY - top], - children, + destroyFn = createContextMenu(children, { + event, }); - - destroyFn = (menuInstance as any).destroy; }; // 克隆 children 并添加 onContextMenu 事件处理器 diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx index f28619df61..1816f5b526 100644 --- a/packages/utils/src/context-menu.tsx +++ b/packages/utils/src/context-menu.tsx @@ -53,6 +53,8 @@ const Tree = (props: { ); }; +let destroyFn: Function | undefined; + export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], options: { nodes?: IPublicModelNode[] | null; destroy?: Function; @@ -89,14 +91,12 @@ export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], return children; } -let destroyFn: Function | undefined; export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction | Omit<IPublicTypeContextMenuAction, 'items'>)[], options: { nodes?: IPublicModelNode[] | null; destroy?: Function; event?: MouseEvent; }, level = 1): IPublicTypeContextMenuItem[] { destroyFn?.(); - destroyFn = options.destroy; const { nodes, destroy } = options; if (level > MAX_LEVEL) { @@ -146,4 +146,55 @@ export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction return menus; } }, []); +} + +let cachedMenuItemHeight: string | undefined; + +function getMenuItemHeight() { + if (cachedMenuItemHeight) { + return cachedMenuItemHeight; + } + const root = document.documentElement; + const styles = getComputedStyle(root); + // Access the value of the CSS variable + const menuItemHeight = styles.getPropertyValue('--context-menu-item-height').trim(); + cachedMenuItemHeight = menuItemHeight; + + return menuItemHeight; +} + +export function createContextMenu(children: React.ReactNode[], { + event, + offset = [0, 0], +}: { + event: MouseEvent | React.MouseEvent; + offset?: [number, number]; +}) { + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + const dividerCount = React.Children.count(children.filter(child => React.isValidElement(child) && child.type === Divider)); + const popupItemCount = React.Children.count(children.filter(child => React.isValidElement(child) && (child.type === PopupItem || child.type === Item))); + const menuHeight = popupItemCount * parseInt(getMenuItemHeight(), 10) + dividerCount * 8 + 16; + const menuWidthLimit = 200; + const target = event.target; + const { top, left } = (target as any)?.getBoundingClientRect(); + let x = event.clientX - left + offset[0]; + let y = event.clientY - top + offset[1]; + if (x + menuWidthLimit + left > viewportWidth) { + x = x - menuWidthLimit; + } + if (y + menuHeight + top > viewportHeight) { + y = y - menuHeight; + } + + const menuInstance = Menu.create({ + target, + offset: [x, y, 0, 0], + children, + className: 'engine-context-menu', + }); + + destroyFn = (menuInstance as any).destroy; + + return destroyFn; } \ No newline at end of file From a00c5c9b607f1e1597c1ed3b985b6f4249b11a68 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Wed, 10 Jan 2024 07:21:10 +0000 Subject: [PATCH 283/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index e0fea44a14..d1c3cd9f90 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.22", + "version": "1.2.23", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From a7d3996fa2eaccd883eb554677d6c15af6134978 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 11 Jan 2024 10:37:12 +0800 Subject: [PATCH 284/361] feat(common): add common.utils.intl API --- docs/docs/api/common.md | 16 ++++++++++++++++ packages/editor-core/src/intl/index.ts | 12 ++---------- packages/shell/src/api/common.tsx | 5 +++++ packages/types/src/shell/api/common.ts | 7 ++++++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index 966e2277f2..6613547ea9 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -145,6 +145,22 @@ const { intl, getLocale, setLocale } = common.utils.createIntl({ ``` +#### intl + +i18n 转换方法 + +```typescript +/** + * i18n 转换方法 + */ +intl(data: IPublicTypeI18nData | string, params?: object): string; +``` + +##### 示例 +``` +const title = common.utils.intl(node.title) +``` + ### skeletonCabin #### Workbench 编辑器框架 View diff --git a/packages/editor-core/src/intl/index.ts b/packages/editor-core/src/intl/index.ts index 6d9d840c3c..99e99a4fb9 100644 --- a/packages/editor-core/src/intl/index.ts +++ b/packages/editor-core/src/intl/index.ts @@ -3,6 +3,7 @@ import { IntlMessageFormat } from 'intl-messageformat'; import { globalLocale } from './global-locale'; import { isI18nData } from '@alilc/lowcode-utils'; import { observer } from '../utils'; +import { IPublicTypeI18nData } from '@alilc/lowcode-types'; function generateTryLocales(locale: string) { const tries = [locale, locale.replace('-', '_')]; @@ -26,18 +27,9 @@ function injectVars(msg: string, params: any, locale: string): string { } const formater = new IntlMessageFormat(msg, locale); return formater.format(params as any) as string; - /* - - return template.replace(/({\w+})/g, (_, $1) => { - const key = (/\d+/.exec($1) || [])[0] as any; - if (key && params[key] != null) { - return params[key]; - } - return $1; - }); */ } -export function intl(data: any, params?: object): ReactNode { +export function intl(data: IPublicTypeI18nData | string, params?: object): ReactNode { if (!isI18nData(data)) { return data; } diff --git a/packages/shell/src/api/common.tsx b/packages/shell/src/api/common.tsx index a2e4d8c4fa..8ce07153ad 100644 --- a/packages/shell/src/api/common.tsx +++ b/packages/shell/src/api/common.tsx @@ -26,6 +26,7 @@ import { IPublicApiCommonEditorCabin, IPublicModelDragon, IPublicModelSettingField, + IPublicTypeI18nData, } from '@alilc/lowcode-types'; import { SettingField as InnerSettingField, @@ -261,6 +262,10 @@ class Utils implements IPublicApiCommonUtils { } { return innerCreateIntl(instance); } + + intl(data: IPublicTypeI18nData | string, params?: object): any { + return innerIntl(data, params); + } } class EditorCabin implements IPublicApiCommonEditorCabin { diff --git a/packages/types/src/shell/api/common.ts b/packages/types/src/shell/api/common.ts index 60fac1606d..05ef0da17f 100644 --- a/packages/types/src/shell/api/common.ts +++ b/packages/types/src/shell/api/common.ts @@ -1,6 +1,6 @@ import { Component, ReactNode } from 'react'; -import { IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type'; +import { IPublicTypeI18nData, IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type'; import { IPublicEnumTransitionType } from '../enum'; export interface IPublicApiCommonUtils { @@ -69,6 +69,11 @@ export interface IPublicApiCommonUtils { getLocale(): string; setLocale(locale: string): void; }; + + /** + * i18n 转换方法 + */ + intl(data: IPublicTypeI18nData | string, params?: object): string; } export interface IPublicApiCommonSkeletonCabin { From 3e7d199a7c3f1df2d813cafcb8109f24125ab4c7 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 11 Jan 2024 02:50:04 +0000 Subject: [PATCH 285/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index d1c3cd9f90..80396a0146 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.23", + "version": "1.2.24", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From bb5d7ddf827be5e72707cd1e5ccdf09f6ae16cc1 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 11 Jan 2024 10:59:44 +0800 Subject: [PATCH 286/361] feat(context-menu): update context-menu docs, details, styles --- docs/docs/api/commonUI.md | 62 +++++++++++++ docs/docs/api/material.md | 46 +++++++++ packages/designer/src/context-menu-actions.ts | 11 ++- packages/engine/src/engine-core.ts | 4 +- .../src/inner-plugins/default-context-menu.ts | 21 ++--- .../src/api/{commonUI.ts => commonUI.tsx} | 24 ++++- .../shell/src/components/context-menu.tsx | 28 +++++- packages/utils/src/context-menu.scss | 36 ++++--- packages/utils/src/context-menu.tsx | 93 ++++++++++++------- .../workspace/src/context/base-context.ts | 4 +- 10 files changed, 254 insertions(+), 75 deletions(-) rename packages/shell/src/api/{commonUI.ts => commonUI.tsx} (56%) diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index f3afe1fc25..350d60dd7a 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -48,8 +48,70 @@ CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开 | condition | 显示条件函数<br/>Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | | | disabled | 禁用条件函数,可选<br/>Function to determine disabled condition, optional | (nodes: IPublicModelNode[]) => boolean (optional) | | +**ContextMenu 示例** + +```typescript +const App = () => { + const menuItems: IPublicTypeContextMenuAction[] = [ + { + name: 'a', + title: '选项 1', + action: () => console.log('选项 1 被点击'), + }, + { + name: 'b', + title: '选项 2', + action: () => console.log('选项 2 被点击'), + }, + ]; + + const ContextMenu = ctx.commonUI.ContextMenu; + + return ( + <div> + <ContextMenu menus={menuItems}> + <div>右键点击这里</div> + </ContextMenu> + </div> + ); +}; + +export default App; +``` + +**ContextMenu.create 示例** + +```typescript +const App = () => { + const menuItems: IPublicTypeContextMenuAction[] = [ + { + name: 'a', + title: '选项 1', + action: () => console.log('选项 1 被点击'), + }, + { + name: 'b', + title: '选项 2', + action: () => console.log('选项 2 被点击'), + }, + ]; + + const ContextMenu = ctx.commonUI.ContextMenu; + + return ( + <div> + <div onClick={(e) => { + ContextMenu.create(menuItems, e); + }}>点击这里</div> + </div> + ); +}; + +export default App; +``` ### Balloon + 详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon) ### Breadcrumb diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index c83935b971..d237180ca9 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -250,6 +250,33 @@ material.modifyBuiltinComponentAction('remove', (action) => { addContextMenuOption(action: IPublicTypeContextMenuAction): void; ``` +示例 + +```typescript +import { IPublicEnumContextMenuType } from '@alilc/lowcode-types'; + +material.addContextMenuOption({ + name: 'parentItem', + title: 'Parent Item', + condition: (nodes) => true, + items: [ + { + name: 'childItem1', + title: 'Child Item 1', + action: (nodes) => console.log('Child Item 1 clicked', nodes), + condition: (nodes) => true + }, + // 分割线 + { + type: IPublicEnumContextMenuType.SEPARATOR + name: 'separator.1' + } + // 更多子菜单项... + ] +}); + +``` + #### removeContextMenuOption 删除特定右键菜单项 @@ -274,7 +301,26 @@ removeContextMenuOption(name: string): void; adjustContextMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]): void; ``` +**示例** + +通过 adjustContextMenuLayout 补充分割线 + +```typescript +material.adjustContextMenuLayout((actions: IPublicTypeContextMenuAction) => { + const names = ['a', 'b']; + const newActions = []; + actions.forEach(d => { + newActions.push(d); + if (names.include(d.name)) { + newActions.push({ type: 'separator' }) + } + }); + return newActions +}) +``` + ### 物料元数据 + #### getComponentMeta 获取指定名称的物料元数据 diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index 5b44055b42..c3bad37da5 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -1,4 +1,4 @@ -import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial } from '@alilc/lowcode-types'; +import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial, IPublicModelPluginContext } from '@alilc/lowcode-types'; import { IDesigner, INode } from './designer'; import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties, uniqueId } from '@alilc/lowcode-utils'; import { Menu } from '@alifd/next'; @@ -48,6 +48,7 @@ export class GlobalContextMenuActions { event.preventDefault(); const actions: IPublicTypeContextMenuAction[] = []; + let contextMenu: ContextMenuActions = this.contextMenuActionsMap.values().next().value; this.contextMenuActionsMap.forEach((contextMenu) => { actions.push(...contextMenu.actions); }); @@ -57,11 +58,13 @@ export class GlobalContextMenuActions { const destroy = () => { destroyFn?.(); }; + const pluginContext: IPublicModelPluginContext = contextMenu.designer.editor.get('pluginContext') as IPublicModelPluginContext; const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, { nodes: [], destroy, event, + pluginContext, }); if (!menus.length) { @@ -73,6 +76,7 @@ export class GlobalContextMenuActions { const menuNode = parseContextMenuAsReactNode(layoutMenu, { destroy, nodes: [], + pluginContext, }); const target = event.target; @@ -160,10 +164,13 @@ export class ContextMenuActions implements IContextMenuActions { destroyFn?.(); }; + const pluginContext: IPublicModelPluginContext = this.designer.editor.get('pluginContext') as IPublicModelPluginContext; + const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, { nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!), destroy, event, + pluginContext, }); if (!menus.length) { @@ -175,7 +182,7 @@ export class ContextMenuActions implements IContextMenuActions { const menuNode = parseContextMenuAsReactNode(layoutMenu, { destroy, nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!), - designer, + pluginContext, }); destroyFn = createContextMenu(menuNode, { diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 29b4a7f038..3ccfdf51d1 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -115,12 +115,11 @@ const innerSetters = new InnerSetters(); const setters = new Setters(innerSetters); const material = new Material(editor); -const commonUI = new CommonUI(); +const commonUI = new CommonUI(editor); editor.set('project', project); editor.set('setters' as any, setters); editor.set('material', material); editor.set('innerHotkey', innerHotkey); -editor.set('commonUI' as any, commonUI); const config = new Config(engineConfig); const event = new Event(commonEvent, { prefix: 'common' }); const logger = new Logger({ level: 'warn', bizName: 'common' }); @@ -147,6 +146,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { context.commonUI = commonUI; context.registerLevel = IPublicEnumPluginRegisterLevel.Default; context.isPluginRegisteredInWorkspace = false; + editor.set('pluginContext', context); }, }; diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index 9d1336b34e..db3d54a0c8 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -5,12 +5,11 @@ import { IPublicModelNode, IPublicModelPluginContext, IPublicTypeDragNodeDataObject, - IPublicTypeI18nData, IPublicTypeNodeSchema, } from '@alilc/lowcode-types'; -import { isI18nData, isProjectSchema } from '@alilc/lowcode-utils'; +import { isProjectSchema } from '@alilc/lowcode-utils'; import { Notification } from '@alifd/next'; -import { intl, getLocale } from '../locale'; +import { intl } from '../locale'; function getNodesSchema(nodes: IPublicModelNode[]) { const componentsTree = nodes.map((node) => node?.exportSchema(IPublicEnumTransformStage.Clone)); @@ -18,15 +17,6 @@ function getNodesSchema(nodes: IPublicModelNode[]) { return data; } -function getIntlStr(data: string | IPublicTypeI18nData) { - if (!isI18nData(data)) { - return data; - } - - const locale = getLocale(); - return data[locale] || data['zh-CN'] || data['zh_CN'] || data['en-US'] || data['en_US'] || ''; -} - async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> { return new Promise((resolve, reject) => { // 使用 Clipboard API 读取剪贴板内容 @@ -61,8 +51,9 @@ async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> { } export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { - const { material, canvas } = ctx; + const { material, canvas, common } = ctx; const { clipboard } = canvas; + const { intl: utilsIntl } = common.utils; return { init() { @@ -150,7 +141,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { }); if (canAddNodes.length === 0) { Notification.open({ - content: `${nodeSchema.map(d => getIntlStr(d.title || d.componentName)).join(',')}等组件无法放置到${getIntlStr(parent.title || parent.componentName as any)}内`, + content: `${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(parent.title || parent.componentName as any)}内`, type: 'error', }); return; @@ -198,7 +189,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { }); if (canAddNodes.length === 0) { Notification.open({ - content: `${nodeSchema.map(d => getIntlStr(d.title || d.componentName)).join(',')}等组件无法放置到${getIntlStr(node.title || node.componentName as any)}内`, + content: `${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(node.title || node.componentName as any)}内`, type: 'error', }); return; diff --git a/packages/shell/src/api/commonUI.ts b/packages/shell/src/api/commonUI.tsx similarity index 56% rename from packages/shell/src/api/commonUI.ts rename to packages/shell/src/api/commonUI.tsx index 9f40afa119..cb4b7ae38e 100644 --- a/packages/shell/src/api/commonUI.ts +++ b/packages/shell/src/api/commonUI.tsx @@ -1,12 +1,16 @@ -import { IPublicApiCommonUI } from '@alilc/lowcode-types'; +import { IPublicApiCommonUI, IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; import { + IEditor, Tip as InnerTip, Title as InnerTitle, } from '@alilc/lowcode-editor-core'; import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; import { ContextMenu } from '../components/context-menu'; +import { editorSymbol } from '../symbols'; export class CommonUI implements IPublicApiCommonUI { + [editorSymbol]: IEditor; + Balloon = Balloon; Breadcrumb = Breadcrumb; Button = Button; @@ -35,13 +39,29 @@ export class CommonUI implements IPublicApiCommonUI { Upload = Upload; Divider = Divider; + constructor(editor: IEditor) { + this[editorSymbol] = editor; + } + get Tip() { return InnerTip; } get Title() { return InnerTitle; } + get ContextMenu() { - return ContextMenu; + const editor = this[editorSymbol]; + const innerContextMenu = (props: any) => { + const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext; + return <ContextMenu {...props} pluginContext={pluginContext} />; + }; + + innerContextMenu.create = (menus: IPublicTypeContextMenuAction[], event: MouseEvent) => { + const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext; + return ContextMenu.create(pluginContext, menus, event); + }; + + return innerContextMenu; } } diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx index acefbebd28..d2e10abbfe 100644 --- a/packages/shell/src/components/context-menu.tsx +++ b/packages/shell/src/components/context-menu.tsx @@ -1,11 +1,12 @@ import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; import { engineConfig } from '@alilc/lowcode-editor-core'; -import { IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; +import { IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; import React from 'react'; -export function ContextMenu({ children, menus }: { +export function ContextMenu({ children, menus, pluginContext }: { menus: IPublicTypeContextMenuAction[]; children: React.ReactElement[] | React.ReactElement; + pluginContext: IPublicModelPluginContext; }): React.ReactElement<any, string | React.JSXElementConstructor<any>> { if (!engineConfig.get('enableContextMenu')) { return ( @@ -23,7 +24,10 @@ export function ContextMenu({ children, menus }: { }; const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, { destroy, - })); + pluginContext, + }), { + pluginContext, + }); if (!children?.length) { return; @@ -44,4 +48,20 @@ export function ContextMenu({ children, menus }: { return ( <>{childrenWithContextMenu}</> ); -} \ No newline at end of file +} + +ContextMenu.create = (pluginContext: IPublicModelPluginContext, menus: IPublicTypeContextMenuAction[], event: MouseEvent) => { + const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, { + pluginContext, + }), { + pluginContext, + }); + + if (!children?.length) { + return; + } + + return createContextMenu(children, { + event, + }); +}; \ No newline at end of file diff --git a/packages/utils/src/context-menu.scss b/packages/utils/src/context-menu.scss index 0bcf39d153..366d03e45a 100644 --- a/packages/utils/src/context-menu.scss +++ b/packages/utils/src/context-menu.scss @@ -1,32 +1,42 @@ -.context-menu-tree-wrap { +.engine-context-menu-tree-wrap { position: relative; padding: 4px 10px 4px 32px; } -.context-menu-tree-children { +.engine-context-menu-tree-children { margin-left: 8px; line-height: 24px; } -.context-menu-tree-bg { - position: absolute; - left: 0; - right: 0; - cursor: pointer; +.engine-context-menu-item { + .engine-context-menu-text { + color: var(--color-text); + } + + &:hover { + .engine-context-menu-text { + color: var(--color-title); + } + } + + &.disbale { + .engine-context-menu-text { + color: var(--color-text-disabled); + } + } } -.context-menu-tree-bg-inner { - position: absolute; - height: 24px; - top: -24px; - width: 100%; +.engine-context-menu-title { + color: var(--color-text); + cursor: pointer; &:hover { background-color: var(--color-block-background-light); + color: var(--color-title); } } -.context-menu-tree-selected-icon { +.engine-context-menu-tree-selecte-icon { position: absolute; left: 10px; color: var(--color-icon-active); diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx index 1816f5b526..0f157e4383 100644 --- a/packages/utils/src/context-menu.tsx +++ b/packages/utils/src/context-menu.tsx @@ -1,7 +1,7 @@ import { Menu, Icon } from '@alifd/next'; -import { IDesigner } from '@alilc/lowcode-designer'; -import { IPublicEnumContextMenuType, IPublicModelNode, IPublicTypeContextMenuAction, IPublicTypeContextMenuItem } from '@alilc/lowcode-types'; +import { IPublicEnumContextMenuType, IPublicModelNode, IPublicModelPluginContext, IPublicTypeContextMenuAction, IPublicTypeContextMenuItem } from '@alilc/lowcode-types'; import { Logger } from '@alilc/lowcode-utils'; +import classNames from 'classnames'; import React from 'react'; import './context-menu.scss'; @@ -10,43 +10,51 @@ const { Item, Divider, PopupItem } = Menu; const MAX_LEVEL = 2; +interface IOptions { + nodes?: IPublicModelNode[] | null; + destroy?: Function; + pluginContext: IPublicModelPluginContext; +} + const Tree = (props: { - node?: IPublicModelNode; + node?: IPublicModelNode | null; children?: React.ReactNode; - options: { - nodes?: IPublicModelNode[] | null; - destroy?: Function; - designer?: IDesigner; - }; + options: IOptions; }) => { const { node } = props; if (!node) { return ( - <div className="context-menu-tree-wrap">{ props.children }</div> + <div className="engine-context-menu-tree-wrap">{ props.children }</div> ); } - const commonUI = props.options.designer?.editor?.get('commonUI'); - - const Title = commonUI?.Title; + const { common } = props.options.pluginContext || {}; + const { intl } = common?.utils || {}; + const indent = node.zLevel * 8 + 32; + const style = { + paddingLeft: indent, + marginLeft: -indent, + marginRight: -10, + paddingRight: 10, + }; return ( <Tree {...props} node={node.parent} > - {props.options.nodes?.[0].id === node.id ? (<Icon className="context-menu-tree-selected-icon" size="small" type="success" />) : null} - <Title title={node.title} /> <div - className="context-menu-tree-children" + className="engine-context-menu-title" + onClick={() => { + props.options.destroy?.(); + node.select(); + }} + style={style} + > + {props.options.nodes?.[0].id === node.id ? (<Icon className="engine-context-menu-tree-selecte-icon" size="small" type="success" />) : null} + {intl(node.title)} + </div> + <div + className="engine-context-menu-tree-children" > - <div - className="context-menu-tree-bg" - onClick={() => { - props.options.destroy?.(); - node.select(); - }} - > - <div className="context-menu-tree-bg-inner" /> - </div> { props.children } </div> </Tree> @@ -55,11 +63,10 @@ const Tree = (props: { let destroyFn: Function | undefined; -export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], options: { - nodes?: IPublicModelNode[] | null; - destroy?: Function; - designer?: IDesigner; -} = {}): React.ReactNode[] { +export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], options: IOptions): React.ReactNode[] { + const { common } = options.pluginContext || {}; + const { intl = (title: any) => title } = common?.utils || {}; + const children: React.ReactNode[] = []; menus.forEach((menu, index) => { if (menu.type === IPublicEnumContextMenuType.SEPARATOR) { @@ -70,14 +77,33 @@ export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], if (menu.type === IPublicEnumContextMenuType.MENU_ITEM) { if (menu.items && menu.items.length) { children.push(( - <PopupItem key={menu.name} label={menu.title}> + <PopupItem + className={classNames('engine-context-menu-item', { + disbale: menu.disabled, + })} + key={menu.name} + label={<div className="engine-context-menu-text">{intl(menu.title)}</div>} + > <Menu className="next-context engine-context-menu"> { parseContextMenuAsReactNode(menu.items, options) } </Menu> </PopupItem> )); } else { - children.push((<Item disabled={menu.disabled} onClick={menu.action} key={menu.name}>{menu.title}</Item>)); + children.push(( + <Item + className={classNames('engine-context-menu-item', { + disbale: menu.disabled, + })} + disabled={menu.disabled} + onClick={menu.action} + key={menu.name} + > + <div className="engine-context-menu-text"> + {intl(menu.title)} + </div> + </Item> + )); } } @@ -91,9 +117,7 @@ export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], return children; } -export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction | Omit<IPublicTypeContextMenuAction, 'items'>)[], options: { - nodes?: IPublicModelNode[] | null; - destroy?: Function; +export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction | Omit<IPublicTypeContextMenuAction, 'items'>)[], options: IOptions & { event?: MouseEvent; }, level = 1): IPublicTypeContextMenuItem[] { destroyFn?.(); @@ -156,7 +180,6 @@ function getMenuItemHeight() { } const root = document.documentElement; const styles = getComputedStyle(root); - // Access the value of the CSS variable const menuItemHeight = styles.getPropertyValue('--context-menu-item-height').trim(); cachedMenuItemHeight = menuItemHeight; diff --git a/packages/workspace/src/context/base-context.ts b/packages/workspace/src/context/base-context.ts index e090d1e374..2f6154788f 100644 --- a/packages/workspace/src/context/base-context.ts +++ b/packages/workspace/src/context/base-context.ts @@ -128,13 +128,12 @@ export class BasicContext implements IBasicContext { const logger = getLogger({ level: 'warn', bizName: 'common' }); const skeleton = new Skeleton(innerSkeleton, 'any', true); const canvas = new Canvas(editor, true); - const commonUI = new CommonUI(); + const commonUI = new CommonUI(editor); editor.set('setters', setters); editor.set('project', project); editor.set('material', material); editor.set('hotkey', hotkey); editor.set('innerHotkey', innerHotkey); - editor.set('commonUI' as any, commonUI); this.innerSetters = innerSetters; this.innerSkeleton = innerSkeleton; this.skeleton = skeleton; @@ -175,6 +174,7 @@ export class BasicContext implements IBasicContext { } context.registerLevel = registerLevel; context.isPluginRegisteredInWorkspace = registerLevel === IPublicEnumPluginRegisterLevel.Workspace; + editor.set('pluginContext', context); }, }; From 18642ee92312fd335cb8d793bfc0136ccad7ad58 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 11 Jan 2024 03:17:25 +0000 Subject: [PATCH 287/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 80396a0146..1626d99578 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.24", + "version": "1.2.25", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From ce72fc1b16912312ab9fb2a38bba811dbea7ef13 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 11 Jan 2024 18:03:22 +0800 Subject: [PATCH 288/361] feat(common-ui): add HelpTip --- docs/docs/api/commonUI.md | 10 +++++ .../editor-core/src/widgets/tip/help-tips.tsx | 40 +++++++++++++++++++ packages/editor-core/src/widgets/tip/index.ts | 1 + .../src/components/widget-views/index.tsx | 24 +---------- packages/shell/src/api/commonUI.tsx | 6 +++ packages/types/src/shell/api/commonUI.ts | 36 +++++++++++++---- 6 files changed, 87 insertions(+), 30 deletions(-) create mode 100644 packages/editor-core/src/widgets/tip/help-tips.tsx diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index 350d60dd7a..c0bbda588e 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -19,6 +19,16 @@ CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开 | direction | tip 的方向 | 'top' \| 'bottom' \| 'left' \| 'right' | | +### HelpTip + +带 help icon 的提示组件 + +| 参数 | 说明 | 类型 | 默认值 | +|-----------|--------|-----------------------------------|--------| +| help | 描述 | IPublicTypeHelpTipConfig | | +| direction | 方向 | IPublicTypeTipConfig['direction'] | 'top' | +| size | 方向 | IconProps['size'] | 'small'| + ### Title 标题组件 diff --git a/packages/editor-core/src/widgets/tip/help-tips.tsx b/packages/editor-core/src/widgets/tip/help-tips.tsx new file mode 100644 index 0000000000..ab5f65050e --- /dev/null +++ b/packages/editor-core/src/widgets/tip/help-tips.tsx @@ -0,0 +1,40 @@ +import { IPublicTypeHelpTipConfig, IPublicTypeTipConfig } from '@alilc/lowcode-types'; +import { Tip } from './tip'; +import { Icon } from '@alifd/next'; +import { IconProps } from '@alifd/next/types/icon'; + +export function HelpTip({ + help, + direction = 'top', + size = 'small', +}: { + help: IPublicTypeHelpTipConfig; + direction?: IPublicTypeTipConfig['direction']; + size?: IconProps['size']; +}) { + if (typeof help === 'string') { + return ( + <div> + <Icon type="help" size={size} className="lc-help-tip" /> + <Tip direction={direction}>{help}</Tip> + </div> + ); + } + + if (typeof help === 'object' && help.url) { + return ( + <div> + <a href={help.url} target="_blank" rel="noopener noreferrer"> + <Icon type="help" size={size} className="lc-help-tip" /> + </a> + <Tip direction={direction}>{help.content}</Tip> + </div> + ); + } + return ( + <div> + <Icon type="help" size="small" className="lc-help-tip" /> + <Tip direction={direction}>{help.content}</Tip> + </div> + ); +} \ No newline at end of file diff --git a/packages/editor-core/src/widgets/tip/index.ts b/packages/editor-core/src/widgets/tip/index.ts index dba4412c7f..d2b3768003 100644 --- a/packages/editor-core/src/widgets/tip/index.ts +++ b/packages/editor-core/src/widgets/tip/index.ts @@ -2,3 +2,4 @@ import './style.less'; export * from './tip'; export * from './tip-container'; +export * from './help-tips'; diff --git a/packages/editor-skeleton/src/components/widget-views/index.tsx b/packages/editor-skeleton/src/components/widget-views/index.tsx index 2b2f6931cb..7cdff4c014 100644 --- a/packages/editor-skeleton/src/components/widget-views/index.tsx +++ b/packages/editor-skeleton/src/components/widget-views/index.tsx @@ -1,7 +1,6 @@ import { Component, ReactElement } from 'react'; -import { Icon } from '@alifd/next'; import classNames from 'classnames'; -import { Title, observer, Tip } from '@alilc/lowcode-editor-core'; +import { Title, observer, HelpTip } from '@alilc/lowcode-editor-core'; import { DockProps } from '../../types'; import { PanelDock } from '../../widget/panel-dock'; import { composeTitle } from '../../widget/utils'; @@ -26,25 +25,6 @@ export function DockView({ title, icon, description, size, className, onClick }: ); } -function HelpTip({ tip }: any) { - if (tip && tip.url) { - return ( - <div> - <a href={tip.url} target="_blank" rel="noopener noreferrer"> - <Icon type="help" size="small" className="lc-help-tip" /> - </a> - <Tip>{tip.content}</Tip> - </div> - ); - } - return ( - <div> - <Icon type="help" size="small" className="lc-help-tip" /> - <Tip>{tip.content}</Tip> - </div> - ); -} - @observer export class PanelDockView extends Component<DockProps & { dock: PanelDock }> { private lastActived = false; @@ -328,7 +308,7 @@ class PanelTitle extends Component<{ panel: Panel; className?: string }> { data-name={panel.name} > <Title title={panel.title || panel.name} /> - {panel.help ? <HelpTip tip={panel.help} /> : null} + {panel.help ? <HelpTip help={panel.help} /> : null} </div> ); } diff --git a/packages/shell/src/api/commonUI.tsx b/packages/shell/src/api/commonUI.tsx index cb4b7ae38e..0a9021fe6a 100644 --- a/packages/shell/src/api/commonUI.tsx +++ b/packages/shell/src/api/commonUI.tsx @@ -1,5 +1,6 @@ import { IPublicApiCommonUI, IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; import { + HelpTip, IEditor, Tip as InnerTip, Title as InnerTitle, @@ -46,6 +47,11 @@ export class CommonUI implements IPublicApiCommonUI { get Tip() { return InnerTip; } + + get HelpTip() { + return HelpTip; + } + get Title() { return InnerTitle; } diff --git a/packages/types/src/shell/api/commonUI.ts b/packages/types/src/shell/api/commonUI.ts index 71e2bbe83f..5ac025fcde 100644 --- a/packages/types/src/shell/api/commonUI.ts +++ b/packages/types/src/shell/api/commonUI.ts @@ -1,6 +1,7 @@ -import { ReactElement } from 'react'; -import { IPublicTypeContextMenuAction, IPublicTypeTitleContent } from '../type'; +import React, { ReactElement } from 'react'; +import { IPublicTypeContextMenuAction, IPublicTypeHelpTipConfig, IPublicTypeTipConfig, IPublicTypeTitleContent } from '../type'; import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; +import { IconProps } from '@alifd/next/types/icon'; export interface IPublicApiCommonUI { Balloon: typeof Balloon; @@ -33,13 +34,30 @@ export interface IPublicApiCommonUI { /** * Title 组件 - * @experimental unstable API, pay extra caution when trying to use this */ - get Tip(): React.ComponentClass<{}>; + get Tip(): React.ComponentClass<IPublicTypeTipConfig>; + + /** + * HelpTip 组件 + */ + get HelpTip(): React.VFC<{ + help: IPublicTypeHelpTipConfig; + + /** + * 方向 + * @default 'top' + */ + direction: IPublicTypeTipConfig['direction']; + + /** + * 大小 + * @default 'small' + */ + size: IconProps['size']; + }>; /** * Tip 组件 - * @experimental unstable API, pay extra caution when trying to use this */ get Title(): React.ComponentClass<{ title: IPublicTypeTitleContent | undefined; @@ -47,8 +65,10 @@ export interface IPublicApiCommonUI { keywords?: string | null; }>; - get ContextMenu(): (props: { + get ContextMenu(): ((props: { menus: IPublicTypeContextMenuAction[]; children: React.ReactElement[] | React.ReactElement; - }) => ReactElement; -} \ No newline at end of file + }) => ReactElement) & { + create(menus: IPublicTypeContextMenuAction[], event: MouseEvent | React.MouseEvent): void; + }; +} From 6f9359e042191d488a7bf9687a1e5a45d46dfcfa Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 11 Jan 2024 10:13:55 +0000 Subject: [PATCH 289/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 1626d99578..6a029b851b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.25", + "version": "1.2.26", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 844ca783d720e5d8829a8e8e54314c97997ec275 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 11 Jan 2024 18:49:21 +0800 Subject: [PATCH 290/361] feat(context-menu): add context-menu css theme, help config, ts define --- docs/docs/guide/expand/editor/theme.md | 5 +++ .../designer/src/builtin-simulator/host.ts | 8 ++++- packages/designer/src/context-menu-actions.ts | 2 ++ .../src/inner-plugins/default-context-menu.ts | 36 +++++++++++-------- .../shell/src/components/context-menu.tsx | 8 ++--- packages/types/src/shell/type/context-menu.ts | 14 +++++--- packages/utils/src/context-menu.scss | 21 +++++++---- packages/utils/src/context-menu.tsx | 33 ++++++++++------- 8 files changed, 81 insertions(+), 46 deletions(-) diff --git a/docs/docs/guide/expand/editor/theme.md b/docs/docs/guide/expand/editor/theme.md index 1c442c5132..897b6b360b 100644 --- a/docs/docs/guide/expand/editor/theme.md +++ b/docs/docs/guide/expand/editor/theme.md @@ -53,6 +53,11 @@ sidebar_position: 9 - `--color-text-reverse`: 反色情况下,文字颜色 - `--color-text-disabled`: 禁用态文字颜色 +#### 菜单颜色 +- `--color-context-menu-text`: 菜单项颜色 +- `--color-context-menu-text-hover`: 菜单项 hover 颜色 +- `--color-context-menu-text-disabled`: 菜单项 disabled 颜色 + #### 字段和边框颜色 - `--color-field-label`: field 标签颜色 diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 6efe6a68b5..57f8569326 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -832,16 +832,22 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp doc.addEventListener('contextmenu', (e: MouseEvent) => { const targetElement = e.target as HTMLElement; const nodeInst = this.getNodeInstanceFromElement(targetElement); + const editor = this.designer?.editor; if (!nodeInst) { + editor?.eventBus.emit('designer.builtinSimulator.contextmenu', { + originalEvent: e, + }); return; } const node = nodeInst.node || this.project.currentDocument?.focusNode; if (!node) { + editor?.eventBus.emit('designer.builtinSimulator.contextmenu', { + originalEvent: e, + }); return; } // dirty code should refector - const editor = this.designer?.editor; const npm = node?.componentMeta?.npm; const selected = [npm?.package, npm?.componentName].filter((item) => !!item).join('-') || diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index c3bad37da5..c88e03ac65 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -201,6 +201,8 @@ export class ContextMenuActions implements IContextMenuActions { node: INode; originalEvent: MouseEvent; }) => { + originalEvent.stopPropagation(); + originalEvent.preventDefault(); // 如果右键的节点不在 当前选中的节点中,选中该节点 if (!designer.currentSelection.has(node.id)) { designer.currentSelection.select(node.id); diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index db3d54a0c8..c8997aa7ed 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -60,7 +60,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'selectComponent', title: intl('SelectComponents'), - condition: (nodes) => { + condition: (nodes = []) => { return nodes.length === 1; }, items: [ @@ -74,14 +74,17 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copyAndPaste', title: intl('CopyAndPaste'), - disabled: (nodes) => { + disabled: (nodes = []) => { return nodes?.filter((node) => !node?.canPerformAction('copy')).length > 0; }, condition: (nodes) => { - return nodes.length === 1; + return nodes?.length === 1; }, action(nodes) { - const node = nodes[0]; + const node = nodes?.[0]; + if (!node) { + return; + } const { document: doc, parent, index } = node; const data = getNodesSchema(nodes); clipboard.setData(data); @@ -96,11 +99,11 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'copy', title: intl('Copy'), - disabled: (nodes) => { + disabled: (nodes = []) => { return nodes?.filter((node) => !node?.canPerformAction('copy')).length > 0; }, - condition(nodes) { - return nodes.length > 0; + condition(nodes = []) { + return nodes?.length > 0; }, action(nodes) { if (!nodes || nodes.length < 1) { @@ -116,7 +119,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { name: 'pasteToBottom', title: intl('PasteToTheBottom'), condition: (nodes) => { - return nodes.length === 1; + return nodes?.length === 1; }, async action(nodes) { if (!nodes || nodes.length < 1) { @@ -163,15 +166,18 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { name: 'pasteToInner', title: intl('PasteToTheInside'), condition: (nodes) => { - return nodes.length === 1; + return nodes?.length === 1; }, - disabled: (nodes) => { + disabled: (nodes = []) => { // 获取粘贴数据 - const node = nodes[0]; + const node = nodes?.[0]; return !node.isContainerNode; }, async action(nodes) { - const node = nodes[0]; + const node = nodes?.[0]; + if (!node) { + return; + } const { document: doc } = node; try { @@ -210,14 +216,14 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { material.addContextMenuOption({ name: 'delete', title: intl('Delete'), - disabled(nodes) { + disabled(nodes = []) { return nodes?.filter((node) => !node?.canPerformAction('remove')).length > 0; }, - condition(nodes) { + condition(nodes = []) { return nodes.length > 0; }, action(nodes) { - nodes.forEach((node) => { + nodes?.forEach((node) => { node.remove(); }); }, diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx index d2e10abbfe..c752e79903 100644 --- a/packages/shell/src/components/context-menu.tsx +++ b/packages/shell/src/components/context-menu.tsx @@ -25,17 +25,13 @@ export function ContextMenu({ children, menus, pluginContext }: { const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, { destroy, pluginContext, - }), { - pluginContext, - }); + }), { pluginContext }); if (!children?.length) { return; } - destroyFn = createContextMenu(children, { - event, - }); + destroyFn = createContextMenu(children, { event }); }; // 克隆 children 并添加 onContextMenu 事件处理器 diff --git a/packages/types/src/shell/type/context-menu.ts b/packages/types/src/shell/type/context-menu.ts index 1eeb93d696..dd6d583c25 100644 --- a/packages/types/src/shell/type/context-menu.ts +++ b/packages/types/src/shell/type/context-menu.ts @@ -1,6 +1,7 @@ import { IPublicEnumContextMenuType } from '../enum'; import { IPublicModelNode } from '../model'; import { IPublicTypeI18nData } from './i8n-data'; +import { IPublicTypeHelpTipConfig } from './widget-base-config'; export interface IPublicTypeContextMenuItem extends Omit<IPublicTypeContextMenuAction, 'condition' | 'disabled' | 'items'> { disabled?: boolean; @@ -34,24 +35,29 @@ export interface IPublicTypeContextMenuAction { * 点击时执行的动作,可选 * Action to execute on click, optional */ - action?: (nodes: IPublicModelNode[], event?: MouseEvent) => void; + action?: (nodes?: IPublicModelNode[], event?: MouseEvent) => void; /** * 子菜单项或生成子节点的函数,可选,仅支持两级 * Sub-menu items or function to generate child node, optional */ - items?: Omit<IPublicTypeContextMenuAction, 'items'>[] | ((nodes: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]); + items?: Omit<IPublicTypeContextMenuAction, 'items'>[] | ((nodes?: IPublicModelNode[]) => Omit<IPublicTypeContextMenuAction, 'items'>[]); /** * 显示条件函数 * Function to determine display condition */ - condition?: (nodes: IPublicModelNode[]) => boolean; + condition?: (nodes?: IPublicModelNode[]) => boolean; /** * 禁用条件函数,可选 * Function to determine disabled condition, optional */ - disabled?: (nodes: IPublicModelNode[]) => boolean; + disabled?: (nodes?: IPublicModelNode[]) => boolean; + + /** + * 帮助提示,可选 + */ + help?: IPublicTypeHelpTipConfig; } diff --git a/packages/utils/src/context-menu.scss b/packages/utils/src/context-menu.scss index 366d03e45a..0b75ca3ec1 100644 --- a/packages/utils/src/context-menu.scss +++ b/packages/utils/src/context-menu.scss @@ -10,24 +10,31 @@ .engine-context-menu-item { .engine-context-menu-text { - color: var(--color-text); + color: var(--color-context-menu-text, var(--color-text)); + display: flex; + align-items: center; + + .lc-help-tip { + margin-left: 4px; + opacity: 0.8; + } } - &:hover { - .engine-context-menu-text { - color: var(--color-title); + &.disabled { + &:hover .engine-context-menu-text, .engine-context-menu-text { + color: var(--color-context-menu-text-disabled, var(--color-text-disabled)); } } - &.disbale { + &:hover { .engine-context-menu-text { - color: var(--color-text-disabled); + color: var(--color-context-menu-text-hover, var(--color-title)); } } } .engine-context-menu-title { - color: var(--color-text); + color: var(--color-context-menu-text, var(--color-text)); cursor: pointer; &:hover { diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx index 0f157e4383..d783a96434 100644 --- a/packages/utils/src/context-menu.tsx +++ b/packages/utils/src/context-menu.tsx @@ -64,8 +64,9 @@ const Tree = (props: { let destroyFn: Function | undefined; export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], options: IOptions): React.ReactNode[] { - const { common } = options.pluginContext || {}; + const { common, commonUI } = options.pluginContext || {}; const { intl = (title: any) => title } = common?.utils || {}; + const { HelpTip } = commonUI || {}; const children: React.ReactNode[] = []; menus.forEach((menu, index) => { @@ -79,7 +80,7 @@ export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], children.push(( <PopupItem className={classNames('engine-context-menu-item', { - disbale: menu.disabled, + disabled: menu.disabled, })} key={menu.name} label={<div className="engine-context-menu-text">{intl(menu.title)}</div>} @@ -93,14 +94,17 @@ export function parseContextMenuAsReactNode(menus: IPublicTypeContextMenuItem[], children.push(( <Item className={classNames('engine-context-menu-item', { - disbale: menu.disabled, + disabled: menu.disabled, })} disabled={menu.disabled} - onClick={menu.action} + onClick={() => { + menu.action?.(); + }} key={menu.name} > <div className="engine-context-menu-text"> - {intl(menu.title)} + { menu.title ? intl(menu.title) : null } + { menu.help ? <HelpTip size="xs" help={menu.help} direction="right" /> : null } </div> </Item> )); @@ -135,12 +139,14 @@ export function parseContextMenuProperties(menus: (IPublicTypeContextMenuAction name, title, type = IPublicEnumContextMenuType.MENU_ITEM, + help, } = menu; const result: IPublicTypeContextMenuItem = { name, title, type, + help, action: () => { destroy?.(); menu.action?.(nodes || [], options.event); @@ -193,26 +199,27 @@ export function createContextMenu(children: React.ReactNode[], { event: MouseEvent | React.MouseEvent; offset?: [number, number]; }) { + event.preventDefault(); + event.stopPropagation(); + const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const dividerCount = React.Children.count(children.filter(child => React.isValidElement(child) && child.type === Divider)); const popupItemCount = React.Children.count(children.filter(child => React.isValidElement(child) && (child.type === PopupItem || child.type === Item))); const menuHeight = popupItemCount * parseInt(getMenuItemHeight(), 10) + dividerCount * 8 + 16; const menuWidthLimit = 200; - const target = event.target; - const { top, left } = (target as any)?.getBoundingClientRect(); - let x = event.clientX - left + offset[0]; - let y = event.clientY - top + offset[1]; - if (x + menuWidthLimit + left > viewportWidth) { + let x = event.clientX + offset[0]; + let y = event.clientY + offset[1]; + if (x + menuWidthLimit > viewportWidth) { x = x - menuWidthLimit; } - if (y + menuHeight + top > viewportHeight) { + if (y + menuHeight > viewportHeight) { y = y - menuHeight; } const menuInstance = Menu.create({ - target, - offset: [x, y, 0, 0], + target: document.body, + offset: [x, y], children, className: 'engine-context-menu', }); From 8931d8393d74133fe0f3201d1826fffc7d2849d1 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 12 Jan 2024 01:17:52 +0000 Subject: [PATCH 291/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 6a029b851b..643bdace2b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.26", + "version": "1.2.27", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 34a5a11b49cac4eddd0a4871cf0bb7e16543a493 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 12 Jan 2024 15:51:18 +0800 Subject: [PATCH 292/361] fix: fix clipboard.setData fial in workspace mode --- packages/designer/src/designer/clipboard.ts | 4 ++++ packages/designer/src/designer/designer-view.tsx | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/designer/clipboard.ts b/packages/designer/src/designer/clipboard.ts index 941f914428..26f57f8112 100644 --- a/packages/designer/src/designer/clipboard.ts +++ b/packages/designer/src/designer/clipboard.ts @@ -36,6 +36,10 @@ class Clipboard implements IClipboard { private waitFn?: (data: any, e: ClipboardEvent) => void; + constructor() { + this.injectCopyPaster(document); + } + isCopyPasteEvent(e: Event) { this.isCopyPaster(e.target); } diff --git a/packages/designer/src/designer/designer-view.tsx b/packages/designer/src/designer/designer-view.tsx index 0db2a3fa3e..aaf0c9583e 100644 --- a/packages/designer/src/designer/designer-view.tsx +++ b/packages/designer/src/designer/designer-view.tsx @@ -4,7 +4,6 @@ import BuiltinDragGhostComponent from './drag-ghost'; import { Designer, DesignerProps } from './designer'; import { ProjectView } from '../project'; import './designer.less'; -import { clipboard } from './clipboard'; type IProps = DesignerProps & { designer?: Designer; @@ -44,7 +43,6 @@ export class DesignerView extends Component<IProps> { if (onMount) { onMount(this.designer); } - clipboard.injectCopyPaster(document); this.designer.postEvent('mount', this.designer); } From 1132a30483e31d82e33d8aa036f6733bfad67483 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 12 Jan 2024 15:52:36 +0800 Subject: [PATCH 293/361] feat: update context-menu message --- .../src/inner-plugins/default-context-menu.ts | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/packages/engine/src/inner-plugins/default-context-menu.ts b/packages/engine/src/inner-plugins/default-context-menu.ts index c8997aa7ed..81978d9209 100644 --- a/packages/engine/src/inner-plugins/default-context-menu.ts +++ b/packages/engine/src/inner-plugins/default-context-menu.ts @@ -8,7 +8,7 @@ import { IPublicTypeNodeSchema, } from '@alilc/lowcode-types'; import { isProjectSchema } from '@alilc/lowcode-utils'; -import { Notification } from '@alifd/next'; +import { Message } from '@alifd/next'; import { intl } from '../locale'; function getNodesSchema(nodes: IPublicModelNode[]) { @@ -27,19 +27,13 @@ async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> { if (isProjectSchema(data)) { resolve(data.componentsTree); } else { - Notification.open({ - content: intl('NotValidNodeData'), - type: 'error', - }); + Message.error(intl('NotValidNodeData')); reject( new Error(intl('NotValidNodeData')), ); } } catch (error) { - Notification.open({ - content: intl('NotValidNodeData'), - type: 'error', - }); + Message.error(intl('NotValidNodeData')); reject(error); } }, @@ -143,10 +137,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { return doc?.checkNesting(parent, dragNodeObject); }); if (canAddNodes.length === 0) { - Notification.open({ - content: `${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(parent.title || parent.componentName as any)}内`, - type: 'error', - }); + Message.error(`${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(parent.title || parent.componentName as any)}内`); return; } const nodes: IPublicModelNode[] = []; @@ -194,10 +185,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => { return doc?.checkNesting(node, dragNodeObject); }); if (canAddNodes.length === 0) { - Notification.open({ - content: `${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(node.title || node.componentName as any)}内`, - type: 'error', - }); + Message.error(`${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(node.title || node.componentName as any)}内`); return; } From adb9f6b090a71052ece0b10d3b6e48125c8799e8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Mon, 15 Jan 2024 10:02:26 +0800 Subject: [PATCH 294/361] fix(canvas): clipboard init error --- packages/designer/src/designer/clipboard.ts | 8 +++++++- packages/types/src/shell/api/material.ts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/designer/clipboard.ts b/packages/designer/src/designer/clipboard.ts index 26f57f8112..34ce2b5b53 100644 --- a/packages/designer/src/designer/clipboard.ts +++ b/packages/designer/src/designer/clipboard.ts @@ -73,7 +73,13 @@ class Clipboard implements IClipboard { } const copyPaster = document.createElement<'textarea'>('textarea'); copyPaster.style.cssText = 'position: absolute;left: -9999px;top:-100px'; - document.body.appendChild(copyPaster); + if (document.body) { + document.body.appendChild(copyPaster); + } else { + document.addEventListener('DOMContentLoaded', () => { + document.body.appendChild(copyPaster); + }); + } const dispose = this.initCopyPaster(copyPaster); return () => { dispose(); diff --git a/packages/types/src/shell/api/material.ts b/packages/types/src/shell/api/material.ts index 6354c7fa0f..89b2b39ad1 100644 --- a/packages/types/src/shell/api/material.ts +++ b/packages/types/src/shell/api/material.ts @@ -15,7 +15,7 @@ export interface IPublicApiMaterial { * set data for Assets * @returns void */ - setAssets(assets: IPublicTypeAssetsJson): void; + setAssets(assets: IPublicTypeAssetsJson): Promise<void>; /** * 获取「资产包」结构 From d1a8bacd75df198ca0f97ebaf985bd3438049114 Mon Sep 17 00:00:00 2001 From: eightHundreds <mingoing@outlook.com> Date: Mon, 15 Jan 2024 12:10:52 +0800 Subject: [PATCH 295/361] fix(designer): node.ts cannot generate declaration file --- packages/designer/src/document/node/node.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 4071fb9138..c8363d0586 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -392,7 +392,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> this.isInited = true; this.emitter = createModuleEventBus('Node'); - const editor = this.document.designer.editor; + const { editor } = this.document.designer; this.onVisibleChange((visible: boolean) => { editor?.eventBus.emit(EDITOR_EVENT.NODE_VISIBLE_CHANGE, this, visible); }); @@ -1219,11 +1219,18 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> /** * 获取磁贴相关信息 */ - getRGL() { + getRGL(): { + isContainerNode: boolean; + isEmptyNode: boolean; + isRGLContainerNode: boolean; + isRGLNode: boolean; + isRGL: boolean; + rglNode: Node | null; + } { const isContainerNode = this.isContainer(); const isEmptyNode = this.isEmpty(); const isRGLContainerNode = this.isRGLContainer; - const isRGLNode = this.getParent()?.isRGLContainer; + const isRGLNode = (this.getParent()?.isRGLContainer) as boolean; const isRGL = isRGLContainerNode || (isRGLNode && (!isContainerNode || !isEmptyNode)); let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null; return { isContainerNode, isEmptyNode, isRGLContainerNode, isRGLNode, isRGL, rglNode }; From e77063636cd053a2ca7730298520bef56e246651 Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 15 Jan 2024 14:02:38 +0800 Subject: [PATCH 296/361] chore: add pub:minor and pub:major commands --- .github/workflows/publish engine.yml | 6 +++++- package.json | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml index 6825c66fca..ab63eec52e 100644 --- a/.github/workflows/publish engine.yml +++ b/.github/workflows/publish engine.yml @@ -2,6 +2,10 @@ name: Publish Engine on: workflow_dispatch: + inputs: + publishCommand: + description: 'publish command' + required: true jobs: publish-engine: @@ -21,7 +25,7 @@ jobs: npm run build git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - - run: npm run pub + - run: npm run ${{ github.event.inputs.publishCommand }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version diff --git a/package.json b/package.json index caabbeeb13..6562cec3b5 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "lint:modules": "f2elint scan -q -i ./modules/*/src", "lint:modules:fix": "f2elint fix -i ./modules/*/src", "pub": "npm run watchdog:build && lerna publish patch --yes --force-publish --exact --no-changelog", + "pub:minor": "npm run watchdog:build && lerna publish minor --yes --force-publish --exact --no-changelog", + "pub:major": "npm run watchdog:build && lerna publish major --yes --force-publish --exact --no-changelog", "pub:premajor": "npm run watchdog:build && lerna publish premajor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:preminor": "npm run watchdog:build && lerna publish preminor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prepatch": "npm run watchdog:build && lerna publish prepatch --force-publish --exact --dist-tag beta --preid beta --no-changelog", From d957be8072a7d9004c5b5875a39861386ac8e52b Mon Sep 17 00:00:00 2001 From: JackLian <jack.lianjie@gmail.com> Date: Mon, 15 Jan 2024 14:02:38 +0800 Subject: [PATCH 297/361] chore: add pub:minor and pub:major commands --- .github/workflows/publish engine.yml | 6 +++++- package.json | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish engine.yml b/.github/workflows/publish engine.yml index ad4c3963b2..dcbf0547e7 100644 --- a/.github/workflows/publish engine.yml +++ b/.github/workflows/publish engine.yml @@ -2,6 +2,10 @@ name: Publish Engine on: workflow_dispatch: + inputs: + publishCommand: + description: 'publish command' + required: true jobs: publish-engine: @@ -21,7 +25,7 @@ jobs: npm run build git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - - run: npm run pub + - run: npm run ${{ github.event.inputs.publishCommand }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version diff --git a/package.json b/package.json index 047b287b98..8b566e0f0c 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "lint:modules": "f2elint scan -q -i ./modules/*/src", "lint:modules:fix": "f2elint fix -i ./modules/*/src", "pub": "npm run watchdog:build && lerna publish patch --yes --force-publish --exact --no-changelog", + "pub:minor": "npm run watchdog:build && lerna publish minor --yes --force-publish --exact --no-changelog", + "pub:major": "npm run watchdog:build && lerna publish major --yes --force-publish --exact --no-changelog", "pub:premajor": "npm run watchdog:build && lerna publish premajor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:preminor": "npm run watchdog:build && lerna publish preminor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prepatch": "npm run watchdog:build && lerna publish prepatch --force-publish --exact --dist-tag beta --preid beta --no-changelog", From 1943172d65ece0608e7fef760bd35a4c93c9b2a2 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Mon, 15 Jan 2024 06:12:28 +0000 Subject: [PATCH 298/361] chore(release): publish 1.3.0 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 15 files changed, 57 insertions(+), 57 deletions(-) diff --git a/lerna.json b/lerna.json index 1170309170..33d4899d0c 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.2.5", + "version": "1.3.0", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 0e6e67e882..5ecf6c1390 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.2.5", + "version": "1.3.0", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.2.5", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-editor-core": "1.3.0", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 0875584501..888642adf5 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.2.5", + "version": "1.3.0", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 648ed5be1f..58c5f2e18a 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.2.5", + "version": "1.3.0", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-editor-core": "1.2.5", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-editor-core": "1.3.0", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 4caf32c009..7eef6514b3 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.2.5", + "version": "1.3.0", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-editor-core": "1.2.5", - "@alilc/lowcode-editor-skeleton": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-editor-core": "1.3.0", + "@alilc/lowcode-editor-skeleton": "1.3.0", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.2.5", - "@alilc/lowcode-plugin-outline-pane": "1.2.5", - "@alilc/lowcode-shell": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", - "@alilc/lowcode-workspace": "1.2.5", + "@alilc/lowcode-plugin-designer": "1.3.0", + "@alilc/lowcode-plugin-outline-pane": "1.3.0", + "@alilc/lowcode-shell": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-workspace": "1.3.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index f131dc14c3..cb87c297f8 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.2.5", + "version": "1.3.0", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index d764f7d9ed..a2c0fcf191 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.2.5", + "version": "1.3.0", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-editor-core": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-editor-core": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index f864356fc8..073830381f 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.2.5", + "version": "1.3.0", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 2970e93410..b1b22f8f4e 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.2.5", + "version": "1.3.0", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.2.5" + "@alilc/lowcode-renderer-core": "1.3.0" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 030a197082..49778b5df9 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.2.5", + "version": "1.3.0", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-react-renderer": "1.2.5", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-react-renderer": "1.3.0", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index fab0d3f133..bf2afdea1f 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.2.5", + "version": "1.3.0", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 86c4c7d11e..fba14598eb 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.2.5", + "version": "1.3.0", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-editor-core": "1.2.5", - "@alilc/lowcode-editor-skeleton": "1.2.5", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", - "@alilc/lowcode-workspace": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-editor-core": "1.3.0", + "@alilc/lowcode-editor-skeleton": "1.3.0", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-workspace": "1.3.0", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 52a5e03ae0..8d056e4eed 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.2.5", + "version": "1.3.0", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 976b76341b..2172041323 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.2.5", + "version": "1.3.0", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.2.5", + "@alilc/lowcode-types": "1.3.0", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index cbc31f3797..3c58c040e6 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.2.5", + "version": "1.3.0", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.2.5", - "@alilc/lowcode-editor-core": "1.2.5", - "@alilc/lowcode-editor-skeleton": "1.2.5", - "@alilc/lowcode-types": "1.2.5", - "@alilc/lowcode-utils": "1.2.5", + "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-editor-core": "1.3.0", + "@alilc/lowcode-editor-skeleton": "1.3.0", + "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-utils": "1.3.0", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From d8406c5bab142641f7ffc559794e2d5159b0c1f7 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 16 Jan 2024 10:32:47 +0800 Subject: [PATCH 299/361] docs: update resource docs --- docs/docs/api/model/resource.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/docs/api/model/resource.md b/docs/docs/api/model/resource.md index 3977234545..a5fdeaf782 100644 --- a/docs/docs/api/model/resource.md +++ b/docs/docs/api/model/resource.md @@ -15,6 +15,12 @@ sidebar_position: 13 `@type {string}` +### id + +资源 id + +`@type {string}` + ### name 资源名字 @@ -44,3 +50,9 @@ sidebar_position: 13 资源配置信息 `@type {Object}` + +### config + +资源配置信息 + +`@type {Object}` \ No newline at end of file From 7f2b2870aa8d4402069258932a00f8566b7f290a Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Tue, 16 Jan 2024 02:35:43 +0000 Subject: [PATCH 300/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 643bdace2b..3b7f1e95c2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.27", + "version": "1.2.28", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 4dd6f7a352f7ba1cea0774114142abe663b6cc31 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 16 Jan 2024 10:34:26 +0800 Subject: [PATCH 301/361] feat: update comtext menu component --- .../shell/src/components/context-menu.tsx | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx index c752e79903..ccd910efc4 100644 --- a/packages/shell/src/components/context-menu.tsx +++ b/packages/shell/src/components/context-menu.tsx @@ -1,20 +1,14 @@ import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils'; import { engineConfig } from '@alilc/lowcode-editor-core'; import { IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types'; -import React from 'react'; +import React, { useCallback } from 'react'; export function ContextMenu({ children, menus, pluginContext }: { menus: IPublicTypeContextMenuAction[]; children: React.ReactElement[] | React.ReactElement; pluginContext: IPublicModelPluginContext; }): React.ReactElement<any, string | React.JSXElementConstructor<any>> { - if (!engineConfig.get('enableContextMenu')) { - return ( - <>{ children }</> - ); - } - - const handleContextMenu = (event: React.MouseEvent) => { + const handleContextMenu = useCallback((event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); @@ -32,7 +26,19 @@ export function ContextMenu({ children, menus, pluginContext }: { } destroyFn = createContextMenu(children, { event }); - }; + }, [menus]); + + if (!engineConfig.get('enableContextMenu')) { + return ( + <>{ children }</> + ); + } + + if (!menus || !menus.length) { + return ( + <>{ children }</> + ); + } // 克隆 children 并添加 onContextMenu 事件处理器 const childrenWithContextMenu = React.Children.map(children, (child) => From 84b4c76db250fb8b644998fcd22e4df88f10b2a6 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 16 Jan 2024 17:16:05 +0800 Subject: [PATCH 302/361] chore: update build-plugin-lce version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8b566e0f0c..213bbc1c45 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "yarn": "^1.22.17", "rimraf": "^3.0.2", "@types/react-router": "5.1.18", - "@alilc/build-plugin-lce": "^0.0.4", + "@alilc/build-plugin-lce": "^0.0.5", "babel-jest": "^26.5.2", "@alilc/lowcode-test-mate": "^1.0.1" }, From a8b9b2b5e13c10dea802bfe1d85f78217e7186a8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 16 Jan 2024 18:00:18 +0800 Subject: [PATCH 303/361] chore: add "set -e" in build.sh --- .github/workflows/pre build.yml | 34 +++++++++++++++++++++++++++++ packages/shell/src/api/commonUI.tsx | 2 +- scripts/build.sh | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pre build.yml diff --git a/.github/workflows/pre build.yml b/.github/workflows/pre build.yml new file mode 100644 index 0000000000..e6f7d6479d --- /dev/null +++ b/.github/workflows/pre build.yml @@ -0,0 +1,34 @@ +name: Pre Build + +on: + push: + paths: + - 'packages/**' + - '!packages/**.md' + pull_request: + paths: + - 'packages/**' + - '!packages/**.md' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install dependencies and setup + run: npm install && npm run setup + + - name: Build + run: npm run build + + - name: Check build status + run: | + if [ $? -eq 0 ]; then + echo "Build succeeded!" + else + echo "Build failed!" + exit 1 + fi diff --git a/packages/shell/src/api/commonUI.tsx b/packages/shell/src/api/commonUI.tsx index 0a9021fe6a..f25cd232c4 100644 --- a/packages/shell/src/api/commonUI.tsx +++ b/packages/shell/src/api/commonUI.tsx @@ -23,7 +23,7 @@ export class CommonUI implements IPublicApiCommonUI { Form = Form; Icon = Icon; Input = Input; - Loading = Loading; + Loading = Loading as any; Message = Message; Overlay = Overlay; Pagination = Pagination; diff --git a/scripts/build.sh b/scripts/build.sh index 0d96598e62..828bb16d99 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +set -e + lerna run build \ --scope @alilc/lowcode-types \ --scope @alilc/lowcode-utils \ From 8f8908c83242b6c418cb7486195b3b13d1516782 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 17 Jan 2024 11:08:28 +0800 Subject: [PATCH 304/361] fix(context-menu): fix context menu component instance changed --- packages/shell/src/api/commonUI.tsx | 35 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/shell/src/api/commonUI.tsx b/packages/shell/src/api/commonUI.tsx index f25cd232c4..69dd104b2a 100644 --- a/packages/shell/src/api/commonUI.tsx +++ b/packages/shell/src/api/commonUI.tsx @@ -8,6 +8,7 @@ import { import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next'; import { ContextMenu } from '../components/context-menu'; import { editorSymbol } from '../symbols'; +import { ReactElement } from 'react'; export class CommonUI implements IPublicApiCommonUI { [editorSymbol]: IEditor; @@ -40,8 +41,27 @@ export class CommonUI implements IPublicApiCommonUI { Upload = Upload; Divider = Divider; + ContextMenu: ((props: { + menus: IPublicTypeContextMenuAction[]; + children: React.ReactElement[] | React.ReactElement; + }) => ReactElement) & { + create(menus: IPublicTypeContextMenuAction[], event: MouseEvent | React.MouseEvent): void; + }; + constructor(editor: IEditor) { this[editorSymbol] = editor; + + const innerContextMenu = (props: any) => { + const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext; + return <ContextMenu {...props} pluginContext={pluginContext} />; + }; + + innerContextMenu.create = (menus: IPublicTypeContextMenuAction[], event: MouseEvent) => { + const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext; + return ContextMenu.create(pluginContext, menus, event); + }; + + this.ContextMenu = innerContextMenu; } get Tip() { @@ -55,19 +75,4 @@ export class CommonUI implements IPublicApiCommonUI { get Title() { return InnerTitle; } - - get ContextMenu() { - const editor = this[editorSymbol]; - const innerContextMenu = (props: any) => { - const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext; - return <ContextMenu {...props} pluginContext={pluginContext} />; - }; - - innerContextMenu.create = (menus: IPublicTypeContextMenuAction[], event: MouseEvent) => { - const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext; - return ContextMenu.create(pluginContext, menus, event); - }; - - return innerContextMenu; - } } From 4025a7d2e00f06501121485dcbce7ecdefb7b9ce Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Wed, 17 Jan 2024 06:01:02 +0000 Subject: [PATCH 305/361] chore(release): publish 1.3.1 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 18 +++++++++--------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 +++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 ++++++------ 15 files changed, 57 insertions(+), 57 deletions(-) diff --git a/lerna.json b/lerna.json index 33d4899d0c..7de339c6cd 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.3.0", + "version": "1.3.1", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 5ecf6c1390..ec7c153c80 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.3.0", + "version": "1.3.1", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.3.0", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-editor-core": "1.3.1", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 888642adf5..f807ef5155 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.3.0", + "version": "1.3.1", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 58c5f2e18a..7c14943552 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.3.0", + "version": "1.3.1", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.3.0", - "@alilc/lowcode-editor-core": "1.3.0", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-editor-core": "1.3.1", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 7eef6514b3..4b622eaa4b 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.3.0", + "version": "1.3.1", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,15 +19,15 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.3.0", - "@alilc/lowcode-editor-core": "1.3.0", - "@alilc/lowcode-editor-skeleton": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-editor-core": "1.3.1", + "@alilc/lowcode-editor-skeleton": "1.3.1", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.3.0", - "@alilc/lowcode-plugin-outline-pane": "1.3.0", - "@alilc/lowcode-shell": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", - "@alilc/lowcode-workspace": "1.3.0", + "@alilc/lowcode-plugin-designer": "1.3.1", + "@alilc/lowcode-plugin-outline-pane": "1.3.1", + "@alilc/lowcode-shell": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-workspace": "1.3.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index cb87c297f8..a32e30783f 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.3.0", + "version": "1.3.1", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index a2c0fcf191..9fb9a75655 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.3.0", + "version": "1.3.1", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.3.0", - "@alilc/lowcode-editor-core": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-editor-core": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 073830381f..1539ac6ae3 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.3.0", + "version": "1.3.1", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index b1b22f8f4e..b041823e85 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.3.0", + "version": "1.3.1", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.3.0" + "@alilc/lowcode-renderer-core": "1.3.1" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 49778b5df9..1361535099 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.3.0", + "version": "1.3.1", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.3.0", - "@alilc/lowcode-react-renderer": "1.3.0", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-react-renderer": "1.3.1", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index bf2afdea1f..dd48d361f1 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.3.0", + "version": "1.3.1", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index fba14598eb..87f71a5ee6 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.3.0", + "version": "1.3.1", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.3.0", - "@alilc/lowcode-editor-core": "1.3.0", - "@alilc/lowcode-editor-skeleton": "1.3.0", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", - "@alilc/lowcode-workspace": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-editor-core": "1.3.1", + "@alilc/lowcode-editor-skeleton": "1.3.1", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-workspace": "1.3.1", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 8d056e4eed..31dadb5ea0 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.3.0", + "version": "1.3.1", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 2172041323..12e3ebc1b3 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.3.0", + "version": "1.3.1", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.3.0", + "@alilc/lowcode-types": "1.3.1", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16" diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 3c58c040e6..7af4a7159c 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.3.0", + "version": "1.3.1", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.3.0", - "@alilc/lowcode-editor-core": "1.3.0", - "@alilc/lowcode-editor-skeleton": "1.3.0", - "@alilc/lowcode-types": "1.3.0", - "@alilc/lowcode-utils": "1.3.0", + "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-editor-core": "1.3.1", + "@alilc/lowcode-editor-skeleton": "1.3.1", + "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-utils": "1.3.1", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 9b19d8f8895415335ffb862051f0ac6e5873ecfe Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 18 Jan 2024 08:00:41 +0800 Subject: [PATCH 306/361] =?UTF-8?q?docs:=20remove=20title=20level=20from?= =?UTF-8?q?=20=E7=A4=BA=E4=BE=8B=20sections=20in=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs/api/common.md | 7 ++++--- docs/docs/api/config.md | 12 ++++++------ docs/docs/api/material.md | 22 +++++++++++----------- docs/docs/api/project.md | 2 +- docs/docs/api/simulatorHost.md | 2 +- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index 6613547ea9..1a70436adf 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -82,7 +82,7 @@ executeTransaction(fn: () => void, type: IPublicEnumTransitionType): void; ``` **@since v1.0.16** -##### 示例 +**示例** ```typescript import { common } from '@alilc/lowcode-engine'; import { IPublicEnumTransitionType } from '@alilc/lowcode-types'; @@ -132,7 +132,8 @@ createIntl(instance: string | object): { **@since v1.0.17** -##### 示例 +**示例** + ```typescript import { common } from '@alilc/lowcode-engine'; import enUS from './en-US.json'; @@ -156,7 +157,7 @@ i18n 转换方法 intl(data: IPublicTypeI18nData | string, params?: object): string; ``` -##### 示例 +**示例** ``` const title = common.utils.intl(node.title) ``` diff --git a/docs/docs/api/config.md b/docs/docs/api/config.md index 9294b9d289..fb631a945f 100644 --- a/docs/docs/api/config.md +++ b/docs/docs/api/config.md @@ -24,7 +24,7 @@ sidebar_position: 8 */ get(key: string, defaultValue?: any): any; ``` -#### 示例 +**示例** ```typescript import { config } from '@alilc/lowcode-engine'; @@ -43,7 +43,7 @@ config.get('keyB', { a: 1 }); */ set(key: string, value: any): void; ``` -#### 示例 +**示例** ```typescript import { config } from '@alilc/lowcode-engine'; @@ -63,7 +63,7 @@ config.set('keyC', 1); has(key: string): boolean; ``` -#### 示例 +**示例** ```typescript import { config } from '@alilc/lowcode-engine'; @@ -81,7 +81,7 @@ config.has('keyD'); */ setConfig(config: { [key: string]: any }): void; ``` -#### 示例 +**示例** ```typescript import { config } from '@alilc/lowcode-engine'; @@ -134,7 +134,7 @@ config.getPreference().set(`${panelName}-pinned-status-isFloat`, false, 'skeleto */ onceGot(key: string): Promise<any>; ``` -#### 示例 +**示例** ```typescript import { config } from '@alilc/lowcode-engine'; @@ -160,7 +160,7 @@ const value = await config.onceGot('keyA'); */ onGot(key: string, fn: (data: any) => void): () => void; ``` -#### 示例 +**示例** ```typescript import { config } from '@alilc/lowcode-engine'; diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index d237180ca9..b6ef070b2c 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -39,7 +39,7 @@ setAssets(assets: IPublicTypeAssetsJson): void; 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) -##### 示例 +**示例** 直接在项目中引用 npm 包 ```javascript import { material } from '@alilc/lowcode-engine'; @@ -85,7 +85,7 @@ getAssets(): IPublicTypeAssetsJson; 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine'; @@ -106,7 +106,7 @@ loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): Promise<void>; ``` 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine'; import assets1 from '@alilc/mc-assets-<siteId>/assets.json'; @@ -146,7 +146,7 @@ addBuiltinComponentAction(action: IPublicTypeComponentAction): void; 相关类型:[IPublicTypeComponentAction](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/component-action.ts) -##### 示例 +**示例** 新增设计扩展位,并绑定事件 ```typescript import { material } from '@alilc/lowcode-engine'; @@ -186,7 +186,7 @@ removeBuiltinComponentAction(name: string): void; - lock:锁定,不可编辑 - unlock:解锁,可编辑 -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine'; @@ -222,7 +222,7 @@ modifyBuiltinComponentAction( -##### 示例 +**示例** 给原始的 remove 扩展时间添加执行前后的日志 ```typescript import { material } from '@alilc/lowcode-engine'; @@ -335,7 +335,7 @@ getComponentMeta(componentName: string): IPublicModelComponentMeta | null; ``` 相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts) -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine'; @@ -356,7 +356,7 @@ material.getComponentMeta('Input'); ``` 相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts) -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine'; @@ -393,7 +393,7 @@ registerMetadataTransducer( ): void; ``` -##### 示例 +**示例** 给每一个组件的配置添加高级配置面板,其中有一个是否渲染配置项 ```typescript import { material } from '@alilc/lowcode-engine' @@ -475,7 +475,7 @@ material.registerMetadataTransducer((transducer) => { getRegisteredMetadataTransducers(): IPublicTypeMetadataTransducer[]; ``` -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine' @@ -496,7 +496,7 @@ onChangeAssets(fn: () => void): IPublicTypeDisposable; 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) -##### 示例 +**示例** ```typescript import { material } from '@alilc/lowcode-engine'; diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index 7998228e2b..49d3193858 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -201,7 +201,7 @@ addPropsTransducer( - [IPublicTypePropsTransducer](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-transducer.ts) - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) -#### 示例 +**示例** 在保存的时候删除每一个组件的 props.hidden ```typescript import { project } from '@alilc/lowcode-engine'; diff --git a/docs/docs/api/simulatorHost.md b/docs/docs/api/simulatorHost.md index ee8f038fc3..c7f739f6b4 100644 --- a/docs/docs/api/simulatorHost.md +++ b/docs/docs/api/simulatorHost.md @@ -20,7 +20,7 @@ sidebar_position: 3 */ set(key: string, value: any): void; ``` -#### 示例 +**示例** 设置若干用于画布渲染的变量,比如画布大小、locale 等。 以设置画布大小为例: From de738b5d7cfd2eaa4afcbc9583675c8c1095b054 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 18 Jan 2024 01:06:41 +0000 Subject: [PATCH 307/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 3b7f1e95c2..69dddfce2c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.28", + "version": "1.2.29", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From e6ba79b4d7eab23962c5aae29fca633a9862d173 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 24 Jan 2024 17:02:28 +0800 Subject: [PATCH 308/361] feat(utils): checkPropTypes suport IPublicTypePropType as rule for check --- packages/renderer-core/src/utils/common.ts | 48 ++++- .../renderer-core/tests/utils/common.test.ts | 184 +++++++++++++++++- 2 files changed, 229 insertions(+), 3 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 495744acd9..894d2d8ca8 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -1,7 +1,7 @@ /* eslint-disable no-console */ /* eslint-disable no-new-func */ import logger from './logger'; -import { IPublicTypeRootSchema, IPublicTypeNodeSchema, IPublicTypeJSSlot } from '@alilc/lowcode-types'; +import { IPublicTypeRootSchema, IPublicTypeNodeSchema, IPublicTypeJSSlot, IPublicTypePropType, IPublicTypeRequiredType, IPublicTypeBasicType } from '@alilc/lowcode-types'; import { isI18nData, isJSExpression } from '@alilc/lowcode-utils'; import { isEmpty } from 'lodash'; import IntlMessageFormat from 'intl-messageformat'; @@ -183,8 +183,54 @@ export function transformArrayToMap(arr: any[], key: string, overwrite = true) { return res; } +export function isBasicType(propType: IPublicTypePropType): propType is IPublicTypeBasicType { + if (!propType) { + return false; + } + return typeof propType === 'string'; +} + +export function isRequiredType(propType: IPublicTypePropType): propType is IPublicTypeRequiredType { + if (!propType) { + return false; + } + return typeof propType === 'object' && propType.type && ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'any'].includes(propType.type); +} + +export function transformPropTypesRuleToString(rule: IPublicTypePropType): string { + if (!rule) { + return 'PropTypes.any'; + } + + if (typeof rule === 'string') { + return `PropTypes.${rule}`; + } + + if (isRequiredType(rule)) { + const { type, isRequired } = rule; + return `PropTypes.${type}${isRequired ? '.isRequired' : ''}`; + } + + const { type, value } = rule; + switch (type) { + case 'oneOf': + return `PropTypes.oneOf([${value.map((item: any) => `"${item}"`).join(',')}])`; + case 'oneOfType': + return `PropTypes.oneOfType([${value.map((item: any) => transformPropTypesRuleToString(item)).join(', ')}])`; + case 'arrayOf': + case 'objectOf': + return `PropTypes.${type}(${transformPropTypesRuleToString(value)})`; + case 'shape': + case 'exact': + return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`; + } +} + export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean { let ruleFunction = rule; + if (typeof rule === 'object') { + ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2); + } if (typeof rule === 'string') { ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2); } diff --git a/packages/renderer-core/tests/utils/common.test.ts b/packages/renderer-core/tests/utils/common.test.ts index 2ee3ed4dcc..45a8e33d7e 100644 --- a/packages/renderer-core/tests/utils/common.test.ts +++ b/packages/renderer-core/tests/utils/common.test.ts @@ -19,6 +19,9 @@ import { parseI18n, parseData, checkPropTypes, + transformPropTypesRuleToString, + isRequiredType, + isBasicType, } from '../../src/utils/common'; import logger from '../../src/utils/logger'; @@ -283,7 +286,7 @@ describe('test capitalizeFirstLetter ', () => { describe('test forEach ', () => { it('should work', () => { const mockFn = jest.fn(); - + forEach(null, mockFn); expect(mockFn).toBeCalledTimes(0); @@ -298,7 +301,7 @@ describe('test forEach ', () => { forEach({ a: 1, b: 2, c: 3 }, mockFn); expect(mockFn).toBeCalledTimes(3); - + const mockFn2 = jest.fn(); forEach({ a: 1 }, mockFn2, { b: 'bbb' }); expect(mockFn2).toHaveBeenCalledWith(1, 'a'); @@ -468,6 +471,28 @@ describe('test parseData ', () => { }); }); +describe('test isBasicType ', () => { + it('should work', () => { + expect(isBasicType(null)).toBeFalsy(); + expect(isBasicType(undefined)).toBeFalsy(); + expect(isBasicType({})).toBeFalsy(); + expect(isBasicType({ type: 'any other type' })).toBeFalsy(); + expect(isBasicType('string')).toBeTruthy(); + }); +}); + +describe('test isRequiredType', () => { + it('should work', () => { + expect(isRequiredType(null)).toBeFalsy(); + expect(isRequiredType(undefined)).toBeFalsy(); + expect(isRequiredType({})).toBeFalsy(); + expect(isRequiredType({ type: 'any other type' })).toBeFalsy(); + expect(isRequiredType('string')).toBeFalsy(); + expect(isRequiredType({ type: 'string' })).toBeTruthy(); + expect(isRequiredType({ type: 'string', isRequired: true })).toBeTruthy(); + }); +}) + describe('checkPropTypes', () => { it('should validate correctly with valid prop type', () => { expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true); @@ -499,4 +524,159 @@ describe('checkPropTypes', () => { const result = checkPropTypes(123, 'age', 123, 'TestComponent'); expect(result).toBe(true); }); + + // oneOf + it('should validate correctly with valid oneOf prop type', () => { + const rule = { + type: 'oneOf', + value: ['News', 'Photos'], + } + expect(transformPropTypesRuleToString(rule)).toBe(`PropTypes.oneOf(["News","Photos"])`); + expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(false); + }); + + // oneOfType + it('should validate correctly with valid oneOfType prop type', () => { + const rule = { + type: 'oneOfType', + value: ['string', 'number', { + type: 'array', + isRequired: true, + }], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array.isRequired])'); + expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes(123, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false); + }); + + // arrayOf + it('should validate correctly with valid arrayOf prop type', () => { + const rule = { + type: 'arrayOf', + value: { + type: 'string', + isRequired: true, + }, + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.arrayOf(PropTypes.string.isRequired)'); + expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes(['News', 123], 'type', rule, 'TestComponent')).toBe(false); + }); + + // objectOf + it('should validate correctly with valid objectOf prop type', () => { + const rule = { + type: 'objectOf', + value: { + type: 'string', + isRequired: true, + }, + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.objectOf(PropTypes.string.isRequired)'); + expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(false); + }); + + // shape + it('should validate correctly with valid shape prop type', () => { + const rule = { + type: 'shape', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: true, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false); + + // isRequired + const rule2 = { + type: 'shape', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: false, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true); + expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false); + }); + + // exact + it('should validate correctly with valid exact prop type', () => { + const rule = { + type: 'exact', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: true, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false); + + // isRequired + const rule2 = { + type: 'exact', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: false, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true); + expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false); + }); }); \ No newline at end of file From cd67a8cea37af8b801b765b2a4b648fcf6d957c2 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 24 Jan 2024 14:58:56 +0800 Subject: [PATCH 309/361] test(designer): add parse-metadata test --- packages/designer/jest.config.js | 1 + .../builtin-simulator/utils/parse-metadata.ts | 12 +- .../utils/parse-metadata.test.ts | 166 +++++++++++++++++- 3 files changed, 176 insertions(+), 3 deletions(-) diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index f0ad2e861e..3684a48acb 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -21,6 +21,7 @@ const jestConfig = { // testMatch: ['**/builtin-hotkey.test.ts'], // testMatch: ['**/selection.test.ts'], // testMatch: ['**/plugin/sequencify.test.ts'], + // testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/designer/src/builtin-simulator/utils/parse-metadata.ts b/packages/designer/src/builtin-simulator/utils/parse-metadata.ts index 5c81340a14..6969a47db5 100644 --- a/packages/designer/src/builtin-simulator/utils/parse-metadata.ts +++ b/packages/designer/src/builtin-simulator/utils/parse-metadata.ts @@ -16,8 +16,16 @@ export const primitiveTypes = [ 'any', ]; +interface LowcodeCheckType { + // isRequired, props, propName, componentName, location, propFullName, secret + (props: any, propName: string, componentName: string, ...rest: any[]): Error | null; + // (...reset: any[]): Error | null; + isRequired?: LowcodeCheckType; + type?: string | object; +} + // eslint-disable-next-line @typescript-eslint/ban-types -function makeRequired(propType: any, lowcodeType: string | object) { +function makeRequired(propType: any, lowcodeType: string | object): LowcodeCheckType { function lowcodeCheckTypeIsRequired(...rest: any[]) { return propType.isRequired(...rest); } @@ -34,7 +42,7 @@ function makeRequired(propType: any, lowcodeType: string | object) { } // eslint-disable-next-line @typescript-eslint/ban-types -function define(propType: any = PropTypes.any, lowcodeType: string | object = {}) { +function define(propType: any = PropTypes.any, lowcodeType: string | object = {}): LowcodeCheckType { if (!propType._inner && propType.name !== 'lowcodeCheckType') { propType.lowcodeType = lowcodeType; } diff --git a/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts b/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts index 1843a24429..64e19376e2 100644 --- a/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts +++ b/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts @@ -1,5 +1,7 @@ import '../../fixtures/window'; -import { parseMetadata } from '../../../src/builtin-simulator/utils/parse-metadata'; +import PropTypes from 'prop-types'; +import { LowcodeTypes, parseMetadata, parseProps } from '../../../src/builtin-simulator/utils/parse-metadata'; +import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret'; describe('parseMetadata', () => { it('parseMetadata', async () => { @@ -11,3 +13,165 @@ describe('parseMetadata', () => { expect(result).toBeDefined(); }); }); + +describe('LowcodeTypes basic type validators', () => { + it('should validate string types', () => { + const stringValidator = LowcodeTypes.string; + // 对 stringValidator 进行测试 + const props = { testProp: 'This is a string' }; + const propName = 'testProp'; + const componentName = 'TestComponent'; + + const result = stringValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeNull(); // No error for valid string + }); + + it('should fail with a non-string type', () => { + const stringValidator = LowcodeTypes.string; + const props = { testProp: 42 }; + const propName = 'testProp'; + const componentName = 'TestComponent'; + + const result = stringValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeInstanceOf(Error); // Error for non-string type + expect(result.message).toContain('Invalid prop `testProp` of type `number` supplied to `TestComponent`, expected `string`.'); + }); + + it('should pass with a valid number', () => { + const numberValidator = LowcodeTypes.number; + const props = { testProp: 42 }; + const propName = 'testProp'; + const componentName = 'TestComponent'; + + const result = numberValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeNull(); // No error for valid number + }); + + it('should fail with a non-number type', () => { + const numberValidator = LowcodeTypes.number; + const props = { testProp: 'Not a number' }; + const propName = 'testProp'; + const componentName = 'TestComponent'; + + const result = numberValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeInstanceOf(Error); // Error for non-number type + expect(result.message).toContain('Invalid prop `testProp` of type `string` supplied to `TestComponent`, expected `number`.'); + }); +}); + +describe('Custom type constructors', () => { + it('should create a custom type validator using define', () => { + const customType = LowcodeTypes.define(PropTypes.string, 'customType'); + const props = { testProp: 'This is a string' }; + const propName = 'testProp'; + const componentName = 'TestComponent'; + + // 测试有效值 + const validResult = customType(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(validResult).toBeNull(); // No error for valid string + + // 测试无效值 + const invalidProps = { testProp: 42 }; + const invalidResult = customType(invalidProps, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(invalidResult).toBeInstanceOf(Error); // Error for non-string type + + // 验证 lowcodeType 属性 + expect(customType.lowcodeType).toEqual('customType'); + + // 验证 isRequired 属性 + const requiredResult = customType.isRequired(invalidProps, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(requiredResult).toBeInstanceOf(Error); // Error for non-string type + }); +}); + + +describe('Advanced type constructors', () => { + describe('oneOf Type Validator', () => { + const oneOfValidator = LowcodeTypes.oneOf(['red', 'green', 'blue']); + const propName = 'color'; + const componentName = 'ColorPicker'; + + it('should pass with a valid value', () => { + const props = { color: 'red' }; + const result = oneOfValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeNull(); // No error for valid value + }); + + it('should fail with an invalid value', () => { + const props = { color: 'yellow' }; + const result = oneOfValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeInstanceOf(Error); // Error for invalid value + expect(result.message).toContain(`Invalid prop \`${propName}\` of value \`yellow\` supplied to \`${componentName}\`, expected one of ["red","green","blue"].`); + }); + + it('should fail with a non-existing value', () => { + const props = { color: 'others' }; + const result = oneOfValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret); + expect(result).toBeInstanceOf(Error); // Error for non-existing value + expect(result.message).toContain(`Invalid prop \`${propName}\` of value \`others\` supplied to \`${componentName}\`, expected one of ["red","green","blue"].`); + }); + }); +}); + + +describe('parseProps function', () => { + it('should correctly parse propTypes and defaultProps', () => { + const component = { + propTypes: { + name: LowcodeTypes.string, + age: LowcodeTypes.number, + }, + defaultProps: { + name: 'John Doe', + age: 30, + }, + }; + const parsedProps = parseProps(component); + + // 测试结果长度 + expect(parsedProps.length).toBe(2); + + // 测试 name 属性 + const nameProp: any = parsedProps.find(prop => prop.name === 'name'); + expect(nameProp).toBeDefined(); + expect(nameProp.propType).toEqual('string'); + expect(nameProp.defaultValue).toEqual('John Doe'); + + // 测试 age 属性 + const ageProp: any = parsedProps.find(prop => prop.name === 'age'); + expect(ageProp).toBeDefined(); + expect(ageProp.propType).toEqual('number'); + expect(ageProp.defaultValue).toEqual(30); + }); +}); + +describe('parseProps function', () => { + it('should correctly parse propTypes and defaultProps', () => { + const component = { + propTypes: { + name: LowcodeTypes.string, + age: LowcodeTypes.number, + }, + defaultProps: { + name: 'John Doe', + age: 30, + }, + }; + const parsedProps = parseProps(component); + + // 测试结果长度 + expect(parsedProps.length).toBe(2); + + // 测试 name 属性 + const nameProp: any = parsedProps.find(prop => prop.name === 'name'); + expect(nameProp).toBeDefined(); + expect(nameProp.propType).toEqual('string'); + expect(nameProp.defaultValue).toEqual('John Doe'); + + // 测试 age 属性 + const ageProp: any = parsedProps.find(prop => prop.name === 'age'); + expect(ageProp).toBeDefined(); + expect(ageProp.propType).toEqual('number'); + expect(ageProp.defaultValue).toEqual(30); + }); +}); From 0e65f021169aa9ddc9016cfa2929bcfd15fd605e Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 25 Jan 2024 10:38:52 +0800 Subject: [PATCH 310/361] feat(utils): move checkPropTypes to utils module --- packages/renderer-core/src/renderer/base.tsx | 3 +- packages/renderer-core/src/utils/common.ts | 76 ------ .../renderer-core/tests/utils/common.test.ts | 219 ------------------ packages/utils/package.json | 1 + packages/utils/src/check-prop-types.ts | 68 ++++++ packages/utils/src/check-types/index.ts | 4 +- .../src/check-types/is-basic-prop-type.ts | 8 + .../src/check-types/is-required-prop-type.ts | 8 + packages/utils/src/context-menu.tsx | 2 +- packages/utils/src/index.ts | 1 + .../utils/test/src/check-prop-types.test.ts | 190 +++++++++++++++ .../check-types/is-basic-prop-type.test.ts | 11 + .../check-types/is-required-prop-type.test.ts | 13 ++ 13 files changed, 305 insertions(+), 299 deletions(-) create mode 100644 packages/utils/src/check-prop-types.ts create mode 100644 packages/utils/src/check-types/is-basic-prop-type.ts create mode 100644 packages/utils/src/check-types/is-required-prop-type.ts create mode 100644 packages/utils/test/src/check-prop-types.test.ts create mode 100644 packages/utils/test/src/check-types/is-basic-prop-type.test.ts create mode 100644 packages/utils/test/src/check-types/is-required-prop-type.test.ts diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 9d9e88ab59..d240095604 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -4,7 +4,7 @@ import classnames from 'classnames'; import { create as createDataSourceEngine } from '@alilc/lowcode-datasource-engine/interpret'; import { IPublicTypeNodeSchema, IPublicTypeNodeData, IPublicTypeJSONValue, IPublicTypeCompositeValue } from '@alilc/lowcode-types'; -import { isI18nData, isJSExpression, isJSFunction } from '@alilc/lowcode-utils'; +import { checkPropTypes, isI18nData, isJSExpression, isJSFunction } from '@alilc/lowcode-utils'; import adapter from '../adapter'; import divFactory from '../components/Div'; import visualDomFactory from '../components/VisualDom'; @@ -21,7 +21,6 @@ import { isFileSchema, transformArrayToMap, transformStringToFunction, - checkPropTypes, getI18n, getFileCssName, capitalizeFirstLetter, diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 894d2d8ca8..80150f379f 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -6,16 +6,11 @@ import { isI18nData, isJSExpression } from '@alilc/lowcode-utils'; import { isEmpty } from 'lodash'; import IntlMessageFormat from 'intl-messageformat'; import pkg from '../../package.json'; -import * as ReactIs from 'react-is'; -import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret'; -import { default as factoryWithTypeCheckers } from 'prop-types/factoryWithTypeCheckers'; (window as any).sdkVersion = pkg.version; export { pick, isEqualWith as deepEqual, cloneDeep as clone, isEmpty, throttle, debounce } from 'lodash'; -const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true); - const EXPRESSION_TYPE = { JSEXPRESSION: 'JSExpression', JSFUNCTION: 'JSFunction', @@ -183,77 +178,6 @@ export function transformArrayToMap(arr: any[], key: string, overwrite = true) { return res; } -export function isBasicType(propType: IPublicTypePropType): propType is IPublicTypeBasicType { - if (!propType) { - return false; - } - return typeof propType === 'string'; -} - -export function isRequiredType(propType: IPublicTypePropType): propType is IPublicTypeRequiredType { - if (!propType) { - return false; - } - return typeof propType === 'object' && propType.type && ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'any'].includes(propType.type); -} - -export function transformPropTypesRuleToString(rule: IPublicTypePropType): string { - if (!rule) { - return 'PropTypes.any'; - } - - if (typeof rule === 'string') { - return `PropTypes.${rule}`; - } - - if (isRequiredType(rule)) { - const { type, isRequired } = rule; - return `PropTypes.${type}${isRequired ? '.isRequired' : ''}`; - } - - const { type, value } = rule; - switch (type) { - case 'oneOf': - return `PropTypes.oneOf([${value.map((item: any) => `"${item}"`).join(',')}])`; - case 'oneOfType': - return `PropTypes.oneOfType([${value.map((item: any) => transformPropTypesRuleToString(item)).join(', ')}])`; - case 'arrayOf': - case 'objectOf': - return `PropTypes.${type}(${transformPropTypesRuleToString(value)})`; - case 'shape': - case 'exact': - return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`; - } -} - -export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean { - let ruleFunction = rule; - if (typeof rule === 'object') { - ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2); - } - if (typeof rule === 'string') { - ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2); - } - if (!ruleFunction || typeof ruleFunction !== 'function') { - logger.warn('checkPropTypes should have a function type rule argument'); - return true; - } - const err = ruleFunction( - { - [name]: value, - }, - name, - componentName, - 'prop', - null, - ReactPropTypesSecret, - ); - if (err) { - logger.warn(err); - } - return !err; -} - /** * transform string to a function * @param str function in string form diff --git a/packages/renderer-core/tests/utils/common.test.ts b/packages/renderer-core/tests/utils/common.test.ts index 45a8e33d7e..13b6908d50 100644 --- a/packages/renderer-core/tests/utils/common.test.ts +++ b/packages/renderer-core/tests/utils/common.test.ts @@ -1,4 +1,3 @@ -import factoryWithTypeCheckers from 'prop-types/factoryWithTypeCheckers'; import { isSchema, isFileSchema, @@ -18,17 +17,9 @@ import { parseThisRequiredExpression, parseI18n, parseData, - checkPropTypes, - transformPropTypesRuleToString, - isRequiredType, - isBasicType, } from '../../src/utils/common'; import logger from '../../src/utils/logger'; -var ReactIs = require('react-is'); - -const PropTypes = factoryWithTypeCheckers(ReactIs.isElement, true); - describe('test isSchema', () => { it('should be false when empty value is passed', () => { expect(isSchema(null)).toBeFalsy(); @@ -470,213 +461,3 @@ describe('test parseData ', () => { }); }); - -describe('test isBasicType ', () => { - it('should work', () => { - expect(isBasicType(null)).toBeFalsy(); - expect(isBasicType(undefined)).toBeFalsy(); - expect(isBasicType({})).toBeFalsy(); - expect(isBasicType({ type: 'any other type' })).toBeFalsy(); - expect(isBasicType('string')).toBeTruthy(); - }); -}); - -describe('test isRequiredType', () => { - it('should work', () => { - expect(isRequiredType(null)).toBeFalsy(); - expect(isRequiredType(undefined)).toBeFalsy(); - expect(isRequiredType({})).toBeFalsy(); - expect(isRequiredType({ type: 'any other type' })).toBeFalsy(); - expect(isRequiredType('string')).toBeFalsy(); - expect(isRequiredType({ type: 'string' })).toBeTruthy(); - expect(isRequiredType({ type: 'string', isRequired: true })).toBeTruthy(); - }); -}) - -describe('checkPropTypes', () => { - it('should validate correctly with valid prop type', () => { - expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true); - expect(checkPropTypes('123', 'age', PropTypes.string, 'TestComponent')).toBe(true); - }); - - it('should log a warning and return false with invalid prop type', () => { - expect(checkPropTypes(123, 'age', PropTypes.string, 'TestComponent')).toBe(false); - expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false); - }); - - it('should handle custom rule functions correctly', () => { - const customRule = (props, propName) => { - if (props[propName] !== 123) { - return new Error('Invalid value'); - } - }; - const result = checkPropTypes(123, 'customProp', customRule, 'TestComponent'); - expect(result).toBe(true); - }); - - - it('should interpret and validate a rule given as a string', () => { - const result = checkPropTypes(123, 'age', 'PropTypes.number', 'TestComponent'); - expect(result).toBe(true); - }); - - it('should log a warning for invalid rule type', () => { - const result = checkPropTypes(123, 'age', 123, 'TestComponent'); - expect(result).toBe(true); - }); - - // oneOf - it('should validate correctly with valid oneOf prop type', () => { - const rule = { - type: 'oneOf', - value: ['News', 'Photos'], - } - expect(transformPropTypesRuleToString(rule)).toBe(`PropTypes.oneOf(["News","Photos"])`); - expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(false); - }); - - // oneOfType - it('should validate correctly with valid oneOfType prop type', () => { - const rule = { - type: 'oneOfType', - value: ['string', 'number', { - type: 'array', - isRequired: true, - }], - }; - expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array.isRequired])'); - expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes(123, 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false); - }); - - // arrayOf - it('should validate correctly with valid arrayOf prop type', () => { - const rule = { - type: 'arrayOf', - value: { - type: 'string', - isRequired: true, - }, - }; - expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.arrayOf(PropTypes.string.isRequired)'); - expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes(['News', 123], 'type', rule, 'TestComponent')).toBe(false); - }); - - // objectOf - it('should validate correctly with valid objectOf prop type', () => { - const rule = { - type: 'objectOf', - value: { - type: 'string', - isRequired: true, - }, - }; - expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.objectOf(PropTypes.string.isRequired)'); - expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(false); - }); - - // shape - it('should validate correctly with valid shape prop type', () => { - const rule = { - type: 'shape', - value: [ - { - name: 'a', - propType: { - type: 'string', - isRequired: true, - }, - }, - { - name: 'b', - propType: { - type: 'number', - isRequired: true, - }, - }, - ], - }; - expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})'); - expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false); - - // isRequired - const rule2 = { - type: 'shape', - value: [ - { - name: 'a', - propType: { - type: 'string', - isRequired: true, - }, - }, - { - name: 'b', - propType: { - type: 'number', - isRequired: false, - }, - }, - ], - }; - expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number})'); - expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true); - expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false); - }); - - // exact - it('should validate correctly with valid exact prop type', () => { - const rule = { - type: 'exact', - value: [ - { - name: 'a', - propType: { - type: 'string', - isRequired: true, - }, - }, - { - name: 'b', - propType: { - type: 'number', - isRequired: true, - }, - }, - ], - }; - expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})'); - expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true); - expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false); - - // isRequired - const rule2 = { - type: 'exact', - value: [ - { - name: 'a', - propType: { - type: 'string', - isRequired: true, - }, - }, - { - name: 'b', - propType: { - type: 'number', - isRequired: false, - }, - }, - ], - }; - expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number})'); - expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true); - expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false); - }); -}); \ No newline at end of file diff --git a/packages/utils/package.json b/packages/utils/package.json index 12e3ebc1b3..cc363a7292 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -17,6 +17,7 @@ "@alilc/lowcode-types": "1.3.1", "lodash": "^4.17.21", "mobx": "^6.3.0", + "prop-types": "^15.8.1", "react": "^16" }, "devDependencies": { diff --git a/packages/utils/src/check-prop-types.ts b/packages/utils/src/check-prop-types.ts new file mode 100644 index 0000000000..89555c70b4 --- /dev/null +++ b/packages/utils/src/check-prop-types.ts @@ -0,0 +1,68 @@ +import * as ReactIs from 'react-is'; +import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret'; +import { default as factoryWithTypeCheckers } from 'prop-types/factoryWithTypeCheckers'; +import { IPublicTypePropType } from '@alilc/lowcode-types'; +import { isRequiredPropType } from './check-types/is-required-prop-type'; +import { Logger } from './logger'; + +const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true); +const logger = new Logger({ level: 'warn', bizName: 'utils' }); + +export function transformPropTypesRuleToString(rule: IPublicTypePropType): string { + if (!rule) { + return 'PropTypes.any'; + } + + if (typeof rule === 'string') { + return `PropTypes.${rule}`; + } + + if (isRequiredPropType(rule)) { + const { type, isRequired } = rule; + return `PropTypes.${type}${isRequired ? '.isRequired' : ''}`; + } + + const { type, value } = rule; + switch (type) { + case 'oneOf': + return `PropTypes.oneOf([${value.map((item: any) => `"${item}"`).join(',')}])`; + case 'oneOfType': + return `PropTypes.oneOfType([${value.map((item: any) => transformPropTypesRuleToString(item)).join(', ')}])`; + case 'arrayOf': + case 'objectOf': + return `PropTypes.${type}(${transformPropTypesRuleToString(value)})`; + case 'shape': + case 'exact': + return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`; + } +} + +export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean { + let ruleFunction = rule; + if (typeof rule === 'object') { + // eslint-disable-next-line no-new-func + ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2); + } + if (typeof rule === 'string') { + // eslint-disable-next-line no-new-func + ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2); + } + if (!ruleFunction || typeof ruleFunction !== 'function') { + logger.warn('checkPropTypes should have a function type rule argument'); + return true; + } + const err = ruleFunction( + { + [name]: value, + }, + name, + componentName, + 'prop', + null, + ReactPropTypesSecret, + ); + if (err) { + logger.warn(err); + } + return !err; +} diff --git a/packages/utils/src/check-types/index.ts b/packages/utils/src/check-types/index.ts index 3155926ef2..507259b2c5 100644 --- a/packages/utils/src/check-types/index.ts +++ b/packages/utils/src/check-types/index.ts @@ -23,4 +23,6 @@ export * from './is-location-data'; export * from './is-setting-field'; export * from './is-lowcode-component-type'; export * from './is-lowcode-project-schema'; -export * from './is-component-schema'; \ No newline at end of file +export * from './is-component-schema'; +export * from './is-basic-prop-type'; +export * from './is-required-prop-type'; \ No newline at end of file diff --git a/packages/utils/src/check-types/is-basic-prop-type.ts b/packages/utils/src/check-types/is-basic-prop-type.ts new file mode 100644 index 0000000000..fd3b1b1dcb --- /dev/null +++ b/packages/utils/src/check-types/is-basic-prop-type.ts @@ -0,0 +1,8 @@ +import { IPublicTypeBasicType, IPublicTypePropType } from '@alilc/lowcode-types'; + +export function isBasicPropType(propType: IPublicTypePropType): propType is IPublicTypeBasicType { + if (!propType) { + return false; + } + return typeof propType === 'string'; +} \ No newline at end of file diff --git a/packages/utils/src/check-types/is-required-prop-type.ts b/packages/utils/src/check-types/is-required-prop-type.ts new file mode 100644 index 0000000000..106da78a00 --- /dev/null +++ b/packages/utils/src/check-types/is-required-prop-type.ts @@ -0,0 +1,8 @@ +import { IPublicTypePropType, IPublicTypeRequiredType } from '@alilc/lowcode-types'; + +export function isRequiredPropType(propType: IPublicTypePropType): propType is IPublicTypeRequiredType { + if (!propType) { + return false; + } + return typeof propType === 'object' && propType.type && ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'any'].includes(propType.type); +} \ No newline at end of file diff --git a/packages/utils/src/context-menu.tsx b/packages/utils/src/context-menu.tsx index d783a96434..185abbb343 100644 --- a/packages/utils/src/context-menu.tsx +++ b/packages/utils/src/context-menu.tsx @@ -5,7 +5,7 @@ import classNames from 'classnames'; import React from 'react'; import './context-menu.scss'; -const logger = new Logger({ level: 'warn', bizName: 'designer' }); +const logger = new Logger({ level: 'warn', bizName: 'utils' }); const { Item, Divider, PopupItem } = Menu; const MAX_LEVEL = 2; diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index b99ab02073..22bad0e36e 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -32,3 +32,4 @@ export { transactionManager } from './transaction-manager'; export * from './check-types'; export * from './workspace'; export * from './context-menu'; +export { checkPropTypes } from './check-prop-types'; \ No newline at end of file diff --git a/packages/utils/test/src/check-prop-types.test.ts b/packages/utils/test/src/check-prop-types.test.ts new file mode 100644 index 0000000000..c1902bec38 --- /dev/null +++ b/packages/utils/test/src/check-prop-types.test.ts @@ -0,0 +1,190 @@ +import { checkPropTypes, transformPropTypesRuleToString } from '../../src/check-prop-types'; +import PropTypes from 'prop-types'; + +describe('checkPropTypes', () => { + it('should validate correctly with valid prop type', () => { + expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true); + expect(checkPropTypes('123', 'age', PropTypes.string, 'TestComponent')).toBe(true); + }); + + it('should log a warning and return false with invalid prop type', () => { + expect(checkPropTypes(123, 'age', PropTypes.string, 'TestComponent')).toBe(false); + expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false); + }); + + it('should handle custom rule functions correctly', () => { + const customRule = (props, propName) => { + if (props[propName] !== 123) { + return new Error('Invalid value'); + } + }; + const result = checkPropTypes(123, 'customProp', customRule, 'TestComponent'); + expect(result).toBe(true); + }); + + + it('should interpret and validate a rule given as a string', () => { + const result = checkPropTypes(123, 'age', 'PropTypes.number', 'TestComponent'); + expect(result).toBe(true); + }); + + it('should log a warning for invalid rule type', () => { + const result = checkPropTypes(123, 'age', 123, 'TestComponent'); + expect(result).toBe(true); + }); + + // oneOf + it('should validate correctly with valid oneOf prop type', () => { + const rule = { + type: 'oneOf', + value: ['News', 'Photos'], + } + expect(transformPropTypesRuleToString(rule)).toBe(`PropTypes.oneOf(["News","Photos"])`); + expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(false); + }); + + // oneOfType + it('should validate correctly with valid oneOfType prop type', () => { + const rule = { + type: 'oneOfType', + value: ['string', 'number', { + type: 'array', + isRequired: true, + }], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array.isRequired])'); + expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes(123, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false); + }); + + // arrayOf + it('should validate correctly with valid arrayOf prop type', () => { + const rule = { + type: 'arrayOf', + value: { + type: 'string', + isRequired: true, + }, + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.arrayOf(PropTypes.string.isRequired)'); + expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes(['News', 123], 'type', rule, 'TestComponent')).toBe(false); + }); + + // objectOf + it('should validate correctly with valid objectOf prop type', () => { + const rule = { + type: 'objectOf', + value: { + type: 'string', + isRequired: true, + }, + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.objectOf(PropTypes.string.isRequired)'); + expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(false); + }); + + // shape + it('should validate correctly with valid shape prop type', () => { + const rule = { + type: 'shape', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: true, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false); + + // isRequired + const rule2 = { + type: 'shape', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: false, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true); + expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false); + }); + + // exact + it('should validate correctly with valid exact prop type', () => { + const rule = { + type: 'exact', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: true, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false); + + // isRequired + const rule2 = { + type: 'exact', + value: [ + { + name: 'a', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'b', + propType: { + type: 'number', + isRequired: false, + }, + }, + ], + }; + expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number})'); + expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true); + expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/utils/test/src/check-types/is-basic-prop-type.test.ts b/packages/utils/test/src/check-types/is-basic-prop-type.test.ts new file mode 100644 index 0000000000..81a1bf0d34 --- /dev/null +++ b/packages/utils/test/src/check-types/is-basic-prop-type.test.ts @@ -0,0 +1,11 @@ +import { isBasicPropType } from '../../../src'; + +describe('test isBasicPropType ', () => { + it('should work', () => { + expect(isBasicPropType(null)).toBeFalsy(); + expect(isBasicPropType(undefined)).toBeFalsy(); + expect(isBasicPropType({})).toBeFalsy(); + expect(isBasicPropType({ type: 'any other type' })).toBeFalsy(); + expect(isBasicPropType('string')).toBeTruthy(); + }); +}); \ No newline at end of file diff --git a/packages/utils/test/src/check-types/is-required-prop-type.test.ts b/packages/utils/test/src/check-types/is-required-prop-type.test.ts new file mode 100644 index 0000000000..25515f9aab --- /dev/null +++ b/packages/utils/test/src/check-types/is-required-prop-type.test.ts @@ -0,0 +1,13 @@ +import { isRequiredPropType } from '../../../src'; + +describe('test isRequiredType', () => { + it('should work', () => { + expect(isRequiredPropType(null)).toBeFalsy(); + expect(isRequiredPropType(undefined)).toBeFalsy(); + expect(isRequiredPropType({})).toBeFalsy(); + expect(isRequiredPropType({ type: 'any other type' })).toBeFalsy(); + expect(isRequiredPropType('string')).toBeFalsy(); + expect(isRequiredPropType({ type: 'string' })).toBeTruthy(); + expect(isRequiredPropType({ type: 'string', isRequired: true })).toBeTruthy(); + }); +}) From dca3448cbf52d6f96d7219858f6b2aed6609cf02 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 25 Jan 2024 15:45:26 +0800 Subject: [PATCH 311/361] chore(editor-core): init test --- .github/workflows/test packages.yml | 18 +++++++++++++++++- packages/editor-core/build.test.json | 9 +++++++++ packages/editor-core/jest.config.js | 26 ++++++++++++++++++++++++++ packages/editor-core/package.json | 4 +++- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 packages/editor-core/build.test.json create mode 100644 packages/editor-core/jest.config.js diff --git a/.github/workflows/test packages.yml b/.github/workflows/test packages.yml index 4ee9b4156c..abb2973708 100644 --- a/.github/workflows/test packages.yml +++ b/.github/workflows/test packages.yml @@ -105,4 +105,20 @@ jobs: run: npm i && npm run setup:skip-build - name: test - run: cd packages/utils && npm test \ No newline at end of file + run: cd packages/utils && npm test + + test-editor-core: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: install + run: npm i && npm run setup:skip-build + + - name: test + run: cd packages/editor-core && npm test \ No newline at end of file diff --git a/packages/editor-core/build.test.json b/packages/editor-core/build.test.json new file mode 100644 index 0000000000..10d18109b8 --- /dev/null +++ b/packages/editor-core/build.test.json @@ -0,0 +1,9 @@ +{ + "plugins": [ + "@alilc/build-plugin-lce", + "@alilc/lowcode-test-mate/plugin/index.ts" + ], + "babelPlugins": [ + ["@babel/plugin-proposal-private-property-in-object", { "loose": true }] + ] +} diff --git a/packages/editor-core/jest.config.js b/packages/editor-core/jest.config.js new file mode 100644 index 0000000000..e8441e3dbb --- /dev/null +++ b/packages/editor-core/jest.config.js @@ -0,0 +1,26 @@ +const fs = require('fs'); +const { join } = require('path'); +const esModules = [].join('|'); +const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.')); + +const jestConfig = { + transformIgnorePatterns: [ + `/node_modules/(?!${esModules})/`, + ], + moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], + collectCoverage: false, + collectCoverageFrom: [ + 'src/**/*.ts', + '!src/**/*.d.ts', + '!src/icons/**', + '!src/locale/**', + '!**/node_modules/**', + '!**/vendor/**', + ], +}; + +// 只对本仓库内的 pkg 做 mapping +jestConfig.moduleNameMapper = {}; +jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '<rootDir>/../$1/src'; + +module.exports = jestConfig; \ No newline at end of file diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index f807ef5155..98644ad3d6 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -10,7 +10,9 @@ "es" ], "scripts": { - "build": "build-scripts build" + "build": "build-scripts build", + "test": "build-scripts test --config build.test.json", + "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { "@alifd/next": "^1.19.16", From 947c6218225e8b88df604cb3fa964e1298b18b84 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 25 Jan 2024 15:47:48 +0800 Subject: [PATCH 312/361] test(utils): add more test case for checkPropTypes --- packages/utils/src/check-prop-types.ts | 10 ++- .../utils/test/src/check-prop-types.test.ts | 65 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/packages/utils/src/check-prop-types.ts b/packages/utils/src/check-prop-types.ts index 89555c70b4..dc9ce31ed5 100644 --- a/packages/utils/src/check-prop-types.ts +++ b/packages/utils/src/check-prop-types.ts @@ -8,13 +8,13 @@ import { Logger } from './logger'; const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true); const logger = new Logger({ level: 'warn', bizName: 'utils' }); -export function transformPropTypesRuleToString(rule: IPublicTypePropType): string { +export function transformPropTypesRuleToString(rule: IPublicTypePropType | string): string { if (!rule) { return 'PropTypes.any'; } if (typeof rule === 'string') { - return `PropTypes.${rule}`; + return rule.startsWith('PropTypes.') ? rule : `PropTypes.${rule}`; } if (isRequiredPropType(rule)) { @@ -34,7 +34,11 @@ export function transformPropTypesRuleToString(rule: IPublicTypePropType): strin case 'shape': case 'exact': return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`; + default: + logger.error(`Unknown prop type: ${type}`); } + + return 'PropTypes.any'; } export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean { @@ -45,7 +49,7 @@ export function checkPropTypes(value: any, name: string, rule: any, componentNam } if (typeof rule === 'string') { // eslint-disable-next-line no-new-func - ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2); + ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2); } if (!ruleFunction || typeof ruleFunction !== 'function') { logger.warn('checkPropTypes should have a function type rule argument'); diff --git a/packages/utils/test/src/check-prop-types.test.ts b/packages/utils/test/src/check-prop-types.test.ts index c1902bec38..74146f2d94 100644 --- a/packages/utils/test/src/check-prop-types.test.ts +++ b/packages/utils/test/src/check-prop-types.test.ts @@ -12,6 +12,26 @@ describe('checkPropTypes', () => { expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false); }); + it('should validate correctly with valid object prop type', () => { + expect(checkPropTypes({ a: 123 }, 'age', PropTypes.object, 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: '123' }, 'age', PropTypes.object, 'TestComponent')).toBe(true); + }); + + it('should validate correctly with valid object string prop type', () => { + expect(checkPropTypes({ a: 123 }, 'age', 'object', 'TestComponent')).toBe(true); + expect(checkPropTypes({ a: '123' }, 'age', 'object', 'TestComponent')).toBe(true); + }); + + it('should validate correctly with valid isRequired prop type', () => { + const rule = { + type: 'string', + isRequired: true, + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.string.isRequired'); + expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes(undefined, 'type', rule, 'TestComponent')).toBe(false); + }); + it('should handle custom rule functions correctly', () => { const customRule = (props, propName) => { if (props[propName] !== 123) { @@ -28,6 +48,11 @@ describe('checkPropTypes', () => { expect(result).toBe(true); }); + it('should interpret and validate a rule given as a string', () => { + expect(checkPropTypes(123, 'age', 'number', 'TestComponent')).toBe(true); + expect(checkPropTypes('123', 'age', 'string', 'TestComponent')).toBe(true); + }); + it('should log a warning for invalid rule type', () => { const result = checkPropTypes(123, 'age', 123, 'TestComponent'); expect(result).toBe(true); @@ -60,6 +85,46 @@ describe('checkPropTypes', () => { expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false); }); + it('should validate correctly with valid oneOfType prop type', () => { + const rule = { + type: 'oneOfType', + value: [ + 'bool', + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSExpression'], + } + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + ], + }; + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.bool, PropTypes.shape({type: PropTypes.oneOf(["JSExpression"]),value: PropTypes.string})])'); + expect(checkPropTypes(true, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ type: 'JSExpression', value: '1 + 1 === 2' }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ type: 'JSExpression' }, 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes({ type: 'JSExpression', value: 123 }, 'type', rule, 'TestComponent')).toBe(false); + }); + + it('should log a warning for invalid type', () => { + const rule = { + type: 'inval', + value: ['News', 'Photos'], + } + expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.any'); + expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true); + expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(true); + }); + // arrayOf it('should validate correctly with valid arrayOf prop type', () => { const rule = { From b3880e9a96c70d750f8f8487913bf6329cdcfb92 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 25 Jan 2024 15:55:32 +0800 Subject: [PATCH 313/361] feat(command): add command apis --- packages/designer/src/plugin/plugin-types.ts | 2 + packages/editor-core/src/command.ts | 91 +++ packages/editor-core/src/index.ts | 1 + packages/editor-core/test/command.test.ts | 326 +++++++++++ packages/engine/src/engine-core.ts | 29 + .../src/inner-plugins/default-command.ts | 524 ++++++++++++++++++ .../inner-plugins/default-command.test.ts | 110 ++++ packages/renderer-core/src/utils/common.ts | 2 +- packages/shell/src/api/command.ts | 46 ++ packages/shell/src/api/index.ts | 3 +- packages/shell/src/index.ts | 2 + packages/shell/src/symbols.ts | 3 +- packages/types/src/shell/api/command.ts | 34 ++ packages/types/src/shell/api/index.ts | 1 + .../types/src/shell/model/plugin-context.ts | 3 + packages/types/src/shell/type/command.ts | 71 +++ packages/types/src/shell/type/index.ts | 3 +- packages/types/src/shell/type/plugin-meta.ts | 8 + .../workspace/src/context/base-context.ts | 7 + 19 files changed, 1262 insertions(+), 4 deletions(-) create mode 100644 packages/editor-core/src/command.ts create mode 100644 packages/editor-core/test/command.test.ts create mode 100644 packages/engine/src/inner-plugins/default-command.ts create mode 100644 packages/engine/tests/inner-plugins/default-command.test.ts create mode 100644 packages/shell/src/api/command.ts create mode 100644 packages/types/src/shell/api/command.ts create mode 100644 packages/types/src/shell/type/command.ts diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index d648067a36..cfc38866f5 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -19,6 +19,7 @@ import { IPublicModelWindow, IPublicEnumPluginRegisterLevel, IPublicApiCommonUI, + IPublicApiCommand, } from '@alilc/lowcode-types'; import PluginContext from './plugin-context'; @@ -63,6 +64,7 @@ export interface ILowCodePluginContextPrivate { set registerLevel(level: IPublicEnumPluginRegisterLevel); set isPluginRegisteredInWorkspace(flag: boolean); set commonUI(commonUI: IPublicApiCommonUI); + set command(command: IPublicApiCommand); } export interface ILowCodePluginContextApiAssembler { assembleApis( diff --git a/packages/editor-core/src/command.ts b/packages/editor-core/src/command.ts new file mode 100644 index 0000000000..7facc33d94 --- /dev/null +++ b/packages/editor-core/src/command.ts @@ -0,0 +1,91 @@ +import { IPublicApiCommand, IPublicEnumTransitionType, IPublicModelPluginContext, IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '@alilc/lowcode-types'; +import { checkPropTypes } from '@alilc/lowcode-utils'; +export interface ICommand extends Omit<IPublicApiCommand, 'registerCommand' | 'batchExecuteCommand'> { + registerCommand(command: IPublicTypeCommand, options?: { + commandScope?: string; + }): void; + + batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[], pluginContext?: IPublicModelPluginContext): void; +} + +export interface ICommandOptions { + commandScope?: string; +} + +export class Command implements ICommand { + private commands: Map<string, IPublicTypeCommand> = new Map(); + private commandErrors: Function[] = []; + + registerCommand(command: IPublicTypeCommand, options?: ICommandOptions): void { + if (!options?.commandScope) { + throw new Error('plugin meta.commandScope is required.'); + } + const name = `${options.commandScope}:${command.name}`; + if (this.commands.has(name)) { + throw new Error(`Command '${command.name}' is already registered.`); + } + this.commands.set(name, { + ...command, + name, + }); + } + + unregisterCommand(name: string): void { + if (!this.commands.has(name)) { + throw new Error(`Command '${name}' is not registered.`); + } + this.commands.delete(name); + } + + executeCommand(name: string, args: IPublicTypeCommandHandlerArgs): void { + const command = this.commands.get(name); + if (!command) { + throw new Error(`Command '${name}' is not registered.`); + } + command.parameters?.forEach(d => { + if (!checkPropTypes(args[d.name], d.name, d.propType, 'command')) { + throw new Error(`Command '${name}' arguments ${d.name} is invalid.`); + } + }); + try { + command.handler(args); + } catch (error) { + if (this.commandErrors && this.commandErrors.length) { + this.commandErrors.forEach(callback => callback(name, error)); + } else { + throw error; + } + } + } + + batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[], pluginContext: IPublicModelPluginContext): void { + if (!commands || !commands.length) { + return; + } + pluginContext.common.utils.executeTransaction(() => { + commands.forEach(command => this.executeCommand(command.name, command.args)); + }, IPublicEnumTransitionType.REPAINT); + } + + listCommands(): IPublicTypeListCommand[] { + return Array.from(this.commands.values()).map(d => { + const result: IPublicTypeListCommand = { + name: d.name, + }; + + if (d.description) { + result.description = d.description; + } + + if (d.parameters) { + result.parameters = d.parameters; + } + + return result; + }); + } + + onCommandError(callback: (name: string, error: Error) => void): void { + this.commandErrors.push(callback); + } +} diff --git a/packages/editor-core/src/index.ts b/packages/editor-core/src/index.ts index 9b0542bdaf..c4a54bccde 100644 --- a/packages/editor-core/src/index.ts +++ b/packages/editor-core/src/index.ts @@ -6,3 +6,4 @@ export * from './hotkey'; export * from './widgets'; export * from './config'; export * from './event-bus'; +export * from './command'; diff --git a/packages/editor-core/test/command.test.ts b/packages/editor-core/test/command.test.ts new file mode 100644 index 0000000000..bb2e15943d --- /dev/null +++ b/packages/editor-core/test/command.test.ts @@ -0,0 +1,326 @@ +import { Command } from '../src/command'; + +describe('Command', () => { + let commandInstance; + let mockHandler; + + beforeEach(() => { + commandInstance = new Command(); + mockHandler = jest.fn(); + }); + + describe('registerCommand', () => { + it('should register a command successfully', () => { + const command = { + name: 'testCommand', + handler: mockHandler, + }; + commandInstance.registerCommand(command, { commandScope: 'testScope' }); + + const registeredCommand = commandInstance.listCommands().find(c => c.name === 'testScope:testCommand'); + expect(registeredCommand).toBeDefined(); + expect(registeredCommand.name).toBe('testScope:testCommand'); + }); + + it('should throw an error if commandScope is not provided', () => { + const command = { + name: 'testCommand', + handler: mockHandler, + }; + + expect(() => { + commandInstance.registerCommand(command); + }).toThrow('plugin meta.commandScope is required.'); + }); + + it('should throw an error if command is already registered', () => { + const command = { + name: 'testCommand', + handler: mockHandler, + }; + commandInstance.registerCommand(command, { commandScope: 'testScope' }); + + expect(() => { + commandInstance.registerCommand(command, { commandScope: 'testScope' }); + }).toThrow(`Command 'testCommand' is already registered.`); + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); + +describe('unregisterCommand', () => { + let commandInstance; + let mockHandler; + + beforeEach(() => { + commandInstance = new Command(); + mockHandler = jest.fn(); + // 先注册一个命令以便之后注销 + const command = { + name: 'testCommand', + handler: mockHandler, + }; + commandInstance.registerCommand(command, { commandScope: 'testScope' }); + }); + + it('should unregister a command successfully', () => { + const commandName = 'testScope:testCommand'; + expect(commandInstance.listCommands().find(c => c.name === commandName)).toBeDefined(); + + commandInstance.unregisterCommand(commandName); + + expect(commandInstance.listCommands().find(c => c.name === commandName)).toBeUndefined(); + }); + + it('should throw an error if the command is not registered', () => { + const nonExistingCommandName = 'testScope:nonExistingCommand'; + expect(() => { + commandInstance.unregisterCommand(nonExistingCommandName); + }).toThrow(`Command '${nonExistingCommandName}' is not registered.`); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); + +describe('executeCommand', () => { + let commandInstance; + let mockHandler; + + beforeEach(() => { + commandInstance = new Command(); + mockHandler = jest.fn(); + // 注册一个带参数校验的命令 + const command = { + name: 'testCommand', + handler: mockHandler, + parameters: [ + { name: 'param1', propType: 'string' }, + { name: 'param2', propType: 'number' } + ], + }; + commandInstance.registerCommand(command, { commandScope: 'testScope' }); + }); + + it('should execute a command successfully', () => { + const commandName = 'testScope:testCommand'; + const args = { param1: 'test', param2: 42 }; + + commandInstance.executeCommand(commandName, args); + + expect(mockHandler).toHaveBeenCalledWith(args); + }); + + it('should throw an error if the command is not registered', () => { + const nonExistingCommandName = 'testScope:nonExistingCommand'; + expect(() => { + commandInstance.executeCommand(nonExistingCommandName, {}); + }).toThrow(`Command '${nonExistingCommandName}' is not registered.`); + }); + + it('should throw an error if arguments are invalid', () => { + const commandName = 'testScope:testCommand'; + const invalidArgs = { param1: 'test', param2: 'not-a-number' }; // param2 should be a number + + expect(() => { + commandInstance.executeCommand(commandName, invalidArgs); + }).toThrow(`Command '${commandName}' arguments param2 is invalid.`); + }); + + it('should handle errors thrown by the command handler', () => { + const commandName = 'testScope:testCommand'; + const args = { param1: 'test', param2: 42 }; + const errorMessage = 'Command handler error'; + mockHandler.mockImplementation(() => { + throw new Error(errorMessage); + }); + + expect(() => { + commandInstance.executeCommand(commandName, args); + }).toThrow(errorMessage); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); + +describe('batchExecuteCommand', () => { + let commandInstance; + let mockHandler; + let mockExecuteTransaction; + let mockPluginContext; + + beforeEach(() => { + commandInstance = new Command(); + mockHandler = jest.fn(); + mockExecuteTransaction = jest.fn(callback => callback()); + mockPluginContext = { + common: { + utils: { + executeTransaction: mockExecuteTransaction + } + } + }; + + // 注册几个命令 + const command1 = { + name: 'testCommand1', + handler: mockHandler, + }; + const command2 = { + name: 'testCommand2', + handler: mockHandler, + }; + commandInstance.registerCommand(command1, { commandScope: 'testScope' }); + commandInstance.registerCommand(command2, { commandScope: 'testScope' }); + }); + + it('should execute a batch of commands', () => { + const commands = [ + { name: 'testScope:testCommand1', args: { param: 'value1' } }, + { name: 'testScope:testCommand2', args: { param: 'value2' } }, + ]; + + commandInstance.batchExecuteCommand(commands, mockPluginContext); + + expect(mockExecuteTransaction).toHaveBeenCalledTimes(1); + expect(mockHandler).toHaveBeenCalledWith({ param: 'value1' }); + expect(mockHandler).toHaveBeenCalledWith({ param: 'value2' }); + }); + + it('should not execute anything if commands array is empty', () => { + commandInstance.batchExecuteCommand([], mockPluginContext); + + expect(mockExecuteTransaction).not.toHaveBeenCalled(); + expect(mockHandler).not.toHaveBeenCalled(); + }); + + it('should handle errors thrown during command execution', () => { + const errorMessage = 'Command handler error'; + mockHandler.mockImplementation(() => { + throw new Error(errorMessage); + }); + + const commands = [ + { name: 'testScope:testCommand1', args: { param: 'value1' } }, + { name: 'testScope:testCommand2', args: { param: 'value2' } }, + ]; + + expect(() => { + commandInstance.batchExecuteCommand(commands, mockPluginContext); + }).toThrow(errorMessage); + + expect(mockExecuteTransaction).toHaveBeenCalledTimes(1); // Still called once + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); + +describe('listCommands', () => { + let commandInstance; + let mockHandler; + + beforeEach(() => { + commandInstance = new Command(); + mockHandler = jest.fn(); + }); + + it('should list all registered commands', () => { + // 注册几个命令 + const command1 = { + name: 'testCommand1', + handler: mockHandler, + description: 'Test Command 1', + parameters: [{ name: 'param1', propType: 'string' }] + }; + const command2 = { + name: 'testCommand2', + handler: mockHandler, + description: 'Test Command 2', + parameters: [{ name: 'param2', propType: 'number' }] + }; + commandInstance.registerCommand(command1, { commandScope: 'testScope' }); + commandInstance.registerCommand(command2, { commandScope: 'testScope' }); + + const listedCommands = commandInstance.listCommands(); + + expect(listedCommands.length).toBe(2); + expect(listedCommands).toEqual(expect.arrayContaining([ + expect.objectContaining({ + name: 'testScope:testCommand1', + description: 'Test Command 1', + parameters: [{ name: 'param1', propType: 'string' }] + }), + expect.objectContaining({ + name: 'testScope:testCommand2', + description: 'Test Command 2', + parameters: [{ name: 'param2', propType: 'number' }] + }) + ])); + }); + + it('should return an empty array if no commands are registered', () => { + const listedCommands = commandInstance.listCommands(); + expect(listedCommands).toEqual([]); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); + +describe('onCommandError', () => { + let commandInstance; + let mockHandler; + let mockErrorHandler1; + let mockErrorHandler2; + + beforeEach(() => { + commandInstance = new Command(); + mockHandler = jest.fn(); + mockErrorHandler1 = jest.fn(); + mockErrorHandler2 = jest.fn(); + + // 注册一个命令,该命令会抛出错误 + const command = { + name: 'testCommand', + handler: () => { + throw new Error('Command execution failed'); + }, + }; + commandInstance.registerCommand(command, { commandScope: 'testScope' }); + }); + + it('should call all registered error handlers when a command throws an error', () => { + const commandName = 'testScope:testCommand'; + commandInstance.onCommandError(mockErrorHandler1); + commandInstance.onCommandError(mockErrorHandler2); + + expect(() => { + commandInstance.executeCommand(commandName, {}); + }).not.toThrow(); + + // 确保所有错误处理函数都被调用,并且传递了正确的参数 + expect(mockErrorHandler1).toHaveBeenCalledWith(commandName, expect.any(Error)); + expect(mockErrorHandler2).toHaveBeenCalledWith(commandName, expect.any(Error)); + }); + + it('should throw the error if no error handlers are registered', () => { + const commandName = 'testScope:testCommand'; + + expect(() => { + commandInstance.executeCommand(commandName, {}); + }).toThrow('Command execution failed'); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 3ccfdf51d1..778438a3d4 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -10,6 +10,7 @@ import { Setters as InnerSetters, Hotkey as InnerHotkey, IEditor, + Command as InnerCommand, } from '@alilc/lowcode-editor-core'; import { IPublicTypeEngineOptions, @@ -19,6 +20,7 @@ import { IPublicApiPlugins, IPublicApiWorkspace, IPublicEnumPluginRegisterLevel, + IPublicModelPluginContext, } from '@alilc/lowcode-types'; import { Designer, @@ -52,6 +54,7 @@ import { Workspace, Config, CommonUI, + Command, } from '@alilc/lowcode-shell'; import { isPlainObject } from '@alilc/lowcode-utils'; import './modules/live-editing'; @@ -63,6 +66,7 @@ import { defaultPanelRegistry } from './inner-plugins/default-panel-registry'; import { shellModelFactory } from './modules/shell-model-factory'; import { builtinHotkey } from './inner-plugins/builtin-hotkey'; import { defaultContextMenu } from './inner-plugins/default-context-menu'; +import { defaultCommand } from './inner-plugins/default-command'; import { OutlinePlugin } from '@alilc/lowcode-plugin-outline-pane'; export * from './modules/skeleton-types'; @@ -80,6 +84,7 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins await plugins.register(builtinHotkey); await plugins.register(registerDefaults, {}, { autoInit: true }); await plugins.register(defaultContextMenu); + await plugins.register(defaultCommand, {}); return () => { plugins.delete(OutlinePlugin.pluginName); @@ -89,6 +94,7 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins plugins.delete(builtinHotkey.pluginName); plugins.delete(registerDefaults.pluginName); plugins.delete(defaultContextMenu.pluginName); + plugins.delete(defaultCommand.pluginName); }; } @@ -99,6 +105,8 @@ globalContext.register(editor, Editor); globalContext.register(editor, 'editor'); globalContext.register(innerWorkspace, 'workspace'); +const engineContext: Partial<ILowCodePluginContextPrivate> = {}; + const innerSkeleton = new InnerSkeleton(editor); editor.set('skeleton' as any, innerSkeleton); @@ -113,6 +121,8 @@ const project = new Project(innerProject); const skeleton = new Skeleton(innerSkeleton, 'any', false); const innerSetters = new InnerSetters(); const setters = new Setters(innerSetters); +const innerCommand = new InnerCommand(); +const command = new Command(innerCommand, engineContext as IPublicModelPluginContext); const material = new Material(editor); const commonUI = new CommonUI(editor); @@ -136,6 +146,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { context.setters = setters; context.material = material; const eventPrefix = meta?.eventPrefix || 'common'; + const commandScope = meta?.commandScope; context.event = new Event(commonEvent, { prefix: eventPrefix }); context.config = config; context.common = common; @@ -144,6 +155,9 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` }); context.workspace = workspace; context.commonUI = commonUI; + context.command = new Command(innerCommand, context as IPublicModelPluginContext, { + commandScope, + }); context.registerLevel = IPublicEnumPluginRegisterLevel.Default; context.isPluginRegisteredInWorkspace = false; editor.set('pluginContext', context); @@ -155,6 +169,20 @@ plugins = new Plugins(innerPlugins).toProxy(); editor.set('innerPlugins' as any, innerPlugins); editor.set('plugins' as any, plugins); +engineContext.skeleton = skeleton; +engineContext.plugins = plugins; +engineContext.project = project; +engineContext.setters = setters; +engineContext.material = material; +engineContext.event = event; +engineContext.logger = logger; +engineContext.hotkey = hotkey; +engineContext.common = common; +engineContext.workspace = workspace; +engineContext.canvas = canvas; +engineContext.commonUI = commonUI; +engineContext.command = command; + export { skeleton, plugins, @@ -169,6 +197,7 @@ export { workspace, canvas, commonUI, + command, }; // declare this is open-source version export const isOpenSource = true; diff --git a/packages/engine/src/inner-plugins/default-command.ts b/packages/engine/src/inner-plugins/default-command.ts new file mode 100644 index 0000000000..b2b899acb0 --- /dev/null +++ b/packages/engine/src/inner-plugins/default-command.ts @@ -0,0 +1,524 @@ +import { + IPublicModelPluginContext, + IPublicTypeNodeSchema, + IPublicTypePropType, +} from '@alilc/lowcode-types'; +import { isNodeSchema } from '@alilc/lowcode-utils'; + +const sampleNodeSchema: IPublicTypePropType = { + type: 'shape', + value: [ + { + name: 'id', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'componentName', + propType: { + type: 'string', + isRequired: true, + }, + }, + { + name: 'props', + propType: 'object', + }, + { + name: 'condition', + propType: 'any', + }, + { + name: 'loop', + propType: 'any', + }, + { + name: 'loopArgs', + propType: 'any', + }, + { + name: 'children', + propType: 'any', + }, + ], +}; + +export const nodeSchemaPropType: IPublicTypePropType = { + type: 'shape', + value: [ + sampleNodeSchema.value[0], + sampleNodeSchema.value[1], + { + name: 'props', + propType: { + type: 'objectOf', + value: { + type: 'oneOfType', + // 不会强制校验,更多作为提示 + value: [ + 'any', + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSExpression'], + }, + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSFunction'], + }, + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSSlot'], + }, + }, + { + name: 'value', + propType: { + type: 'oneOfType', + value: [ + sampleNodeSchema, + { + type: 'arrayOf', + value: sampleNodeSchema, + }, + ], + }, + }, + ], + }, + ], + }, + }, + }, + { + name: 'condition', + propType: { + type: 'oneOfType', + value: [ + 'bool', + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSExpression'], + }, + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + ], + }, + }, + { + name: 'loop', + propType: { + type: 'oneOfType', + value: [ + 'array', + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSExpression'], + }, + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + ], + }, + }, + { + name: 'loopArgs', + propType: { + type: 'oneOfType', + value: [ + { + type: 'arrayOf', + value: { + type: 'oneOfType', + value: [ + 'any', + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSExpression'], + }, + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + ], + }, + }, + { + type: 'shape', + value: [ + { + name: 'type', + propType: { + type: 'oneOf', + value: ['JSExpression'], + }, + }, + { + name: 'value', + propType: 'string', + }, + ], + }, + ], + }, + }, + { + name: 'children', + propType: { + type: 'arrayOf', + value: sampleNodeSchema, + }, + }, + ], +}; + +export const historyCommand = (ctx: IPublicModelPluginContext) => { + const { command, project } = ctx; + return { + init() { + command.registerCommand({ + name: 'undo', + description: 'Undo the last operation.', + handler: () => { + const state = project.currentDocument?.history.getState() || 0; + const enable = !!(state & 1); + if (!enable) { + throw new Error('Can not undo.'); + } + project.currentDocument?.history.back(); + }, + }); + + command.registerCommand({ + name: 'redo', + description: 'Redo the last operation.', + handler: () => { + const state = project.currentDocument?.history.getState() || 0; + const enable = !!(state & 2); + if (!enable) { + throw new Error('Can not redo.'); + } + project.currentDocument?.history.forward(); + }, + }); + }, + }; +}; + +historyCommand.pluginName = '___history_command___'; +historyCommand.meta = { + commandScope: 'history', +}; + +export const nodeCommand = (ctx: IPublicModelPluginContext) => { + const { command, project } = ctx; + return { + init() { + command.registerCommand({ + name: 'add', + description: 'Add a node to the canvas.', + handler: (param: { + parentNodeId: string; + nodeSchema: IPublicTypeNodeSchema; + }) => { + const { + parentNodeId, + nodeSchema, + } = param; + const { project } = ctx; + const parentNode = project.currentDocument?.getNodeById(parentNodeId); + if (!parentNode) { + throw new Error(`Can not find node '${parentNodeId}'.`); + } + + if (!parentNode.isContainerNode) { + throw new Error(`Node '${parentNodeId}' is not a container node.`); + } + + if (!isNodeSchema(nodeSchema)) { + throw new Error('Invalid node.'); + } + + project.currentDocument?.insertNode(parentNode, nodeSchema); + }, + parameters: [ + { + name: 'parentNodeId', + propType: 'string', + description: 'The id of the parent node.', + }, + { + name: 'nodeSchema', + propType: nodeSchemaPropType, + description: 'The node to be added.', + }, + ], + }); + + command.registerCommand({ + name: 'move', + description: 'Move a node to another node.', + handler(param: { + nodeId: string; + targetNodeId: string; + index: number; + }) { + const { + nodeId, + targetNodeId, + index = 0, + } = param; + + const node = project.currentDocument?.getNodeById(nodeId); + const targetNode = project.currentDocument?.getNodeById(targetNodeId); + if (!node) { + throw new Error(`Can not find node '${nodeId}'.`); + } + + if (!targetNode) { + throw new Error(`Can not find node '${targetNodeId}'.`); + } + + if (!targetNode.isContainerNode) { + throw new Error(`Node '${targetNodeId}' is not a container node.`); + } + + if (index < 0 || index > (targetNode.children?.size || 0)) { + throw new Error(`Invalid index '${index}'.`); + } + + project.currentDocument?.removeNode(node); + project.currentDocument?.insertNode(targetNode, node, index); + }, + parameters: [ + { + name: 'nodeId', + propType: 'string', + description: 'The id of the node to be moved.', + }, + { + name: 'targetNodeId', + propType: 'string', + description: 'The id of the target node.', + }, + { + name: 'index', + propType: 'number', + description: 'The index of the node to be moved.', + }, + ], + }); + + command.registerCommand({ + name: 'remove', + description: 'Remove a node from the canvas.', + handler(param: { + nodeId: string; + }) { + const { + nodeId, + } = param; + + const node = project.currentDocument?.getNodeById(nodeId); + if (!node) { + throw new Error(`Can not find node '${nodeId}'.`); + } + + project.currentDocument?.removeNode(node); + }, + parameters: [ + { + name: 'nodeId', + propType: 'string', + description: 'The id of the node to be removed.', + }, + ], + }); + + command.registerCommand({ + name: 'replace', + description: 'Replace a node with another node.', + handler(param: { + nodeId: string; + nodeSchema: IPublicTypeNodeSchema; + }) { + const { + nodeId, + nodeSchema, + } = param; + + const node = project.currentDocument?.getNodeById(nodeId); + if (!node) { + throw new Error(`Can not find node '${nodeId}'.`); + } + + if (!isNodeSchema(nodeSchema)) { + throw new Error('Invalid node.'); + } + + node.importSchema(nodeSchema); + }, + parameters: [ + { + name: 'nodeId', + propType: 'string', + description: 'The id of the node to be replaced.', + }, + { + name: 'nodeSchema', + propType: nodeSchemaPropType, + description: 'The node to replace.', + }, + ], + }); + + command.registerCommand({ + name: 'updateProps', + description: 'Update the properties of a node.', + handler(param: { + nodeId: string; + props: Record<string, any>; + }) { + const { + nodeId, + props, + } = param; + + const node = project.currentDocument?.getNodeById(nodeId); + if (!node) { + throw new Error(`Can not find node '${nodeId}'.`); + } + + Object.keys(props).forEach(key => { + node.setPropValue(key, props[key]); + }); + }, + parameters: [ + { + name: 'nodeId', + propType: 'string', + description: 'The id of the node to be updated.', + }, + { + name: 'props', + propType: 'object', + description: 'The properties to be updated.', + }, + ], + }); + + command.registerCommand({ + name: 'removeProps', + description: 'Remove the properties of a node.', + handler(param: { + nodeId: string; + propNames: string[]; + }) { + const { + nodeId, + propNames, + } = param; + + const node = project.currentDocument?.getNodeById(nodeId); + if (!node) { + throw new Error(`Can not find node '${nodeId}'.`); + } + + propNames.forEach(key => { + node.props?.getProp(key)?.remove(); + }); + }, + parameters: [ + { + name: 'nodeId', + propType: 'string', + description: 'The id of the node to be updated.', + }, + { + name: 'propNames', + propType: 'array', + description: 'The properties to be removed.', + }, + ], + }); + }, + }; +}; + +nodeCommand.pluginName = '___node_command___'; +nodeCommand.meta = { + commandScope: 'node', +}; + +export const defaultCommand = (ctx: IPublicModelPluginContext) => { + const { plugins } = ctx; + plugins.register(nodeCommand); + plugins.register(historyCommand); + + return { + init() { + }, + }; +}; + +defaultCommand.pluginName = '___default_command___'; +defaultCommand.meta = { + commandScope: 'common', +}; diff --git a/packages/engine/tests/inner-plugins/default-command.test.ts b/packages/engine/tests/inner-plugins/default-command.test.ts new file mode 100644 index 0000000000..0e28c642b8 --- /dev/null +++ b/packages/engine/tests/inner-plugins/default-command.test.ts @@ -0,0 +1,110 @@ +import { checkPropTypes } from '@alilc/lowcode-utils/src/check-prop-types'; +import { nodeSchemaPropType } from '../../src/inner-plugins/default-command'; + +describe('nodeSchemaPropType', () => { + const componentName = 'NodeComponent'; + const getPropType = (name: string) => nodeSchemaPropType.value.find(d => d.name === name)?.propType; + + it('should validate the id as a string', () => { + const validId = 'node1'; + const invalidId = 123; // Not a string + expect(checkPropTypes(validId, 'id', getPropType('id'), componentName)).toBe(true); + expect(checkPropTypes(invalidId, 'id', getPropType('id'), componentName)).toBe(false); + // isRequired + expect(checkPropTypes(undefined, 'id', getPropType('id'), componentName)).toBe(false); + }); + + it('should validate the componentName as a string', () => { + const validComponentName = 'Button'; + const invalidComponentName = false; // Not a string + expect(checkPropTypes(validComponentName, 'componentName', getPropType('componentName'), componentName)).toBe(true); + expect(checkPropTypes(invalidComponentName, 'componentName', getPropType('componentName'), componentName)).toBe(false); + // isRequired + expect(checkPropTypes(undefined, 'componentName', getPropType('componentName'), componentName)).toBe(false); + }); + + it('should validate the props as an object', () => { + const validProps = { key: 'value' }; + const invalidProps = 'Not an object'; // Not an object + expect(checkPropTypes(validProps, 'props', getPropType('props'), componentName)).toBe(true); + expect(checkPropTypes(invalidProps, 'props', getPropType('props'), componentName)).toBe(false); + }); + + it('should validate the props as a JSExpression', () => { + const validProps = { type: 'JSExpression', value: 'props' }; + expect(checkPropTypes(validProps, 'props', getPropType('props'), componentName)).toBe(true); + }); + + it('should validate the props as a JSFunction', () => { + const validProps = { type: 'JSFunction', value: 'props' }; + expect(checkPropTypes(validProps, 'props', getPropType('props'), componentName)).toBe(true); + }); + + it('should validate the props as a JSSlot', () => { + const validProps = { type: 'JSSlot', value: 'props' }; + expect(checkPropTypes(validProps, 'props', getPropType('props'), componentName)).toBe(true); + }); + + it('should validate the condition as a bool', () => { + const validCondition = true; + const invalidCondition = 'Not a bool'; // Not a boolean + expect(checkPropTypes(validCondition, 'condition', getPropType('condition'), componentName)).toBe(true); + expect(checkPropTypes(invalidCondition, 'condition', getPropType('condition'), componentName)).toBe(false); + }); + + it('should validate the condition as a JSExpression', () => { + const validCondition = { type: 'JSExpression', value: '1 + 1 === 2' }; + const invalidCondition = { type: 'JSExpression', value: 123 }; // Not a string + expect(checkPropTypes(validCondition, 'condition', getPropType('condition'), componentName)).toBe(true); + expect(checkPropTypes(invalidCondition, 'condition', getPropType('condition'), componentName)).toBe(false); + }); + + it('should validate the loop as an array', () => { + const validLoop = ['item1', 'item2']; + const invalidLoop = 'Not an array'; // Not an array + expect(checkPropTypes(validLoop, 'loop', getPropType('loop'), componentName)).toBe(true); + expect(checkPropTypes(invalidLoop, 'loop', getPropType('loop'), componentName)).toBe(false); + }); + + it('should validate the loop as a JSExpression', () => { + const validLoop = { type: 'JSExpression', value: 'items' }; + const invalidLoop = { type: 'JSExpression', value: 123 }; // Not a string + expect(checkPropTypes(validLoop, 'loop', getPropType('loop'), componentName)).toBe(true); + expect(checkPropTypes(invalidLoop, 'loop', getPropType('loop'), componentName)).toBe(false); + }) + + it('should validate the loopArgs as an array', () => { + const validLoopArgs = ['item']; + const invalidLoopArgs = 'Not an array'; // Not an array + expect(checkPropTypes(validLoopArgs, 'loopArgs', getPropType('loopArgs'), componentName)).toBe(true); + expect(checkPropTypes(invalidLoopArgs, 'loopArgs', getPropType('loopArgs'), componentName)).toBe(false); + }); + + it('should validate the loopArgs as a JSExpression', () => { + const validLoopArgs = { type: 'JSExpression', value: 'item' }; + const invalidLoopArgs = { type: 'JSExpression', value: 123 }; // Not a string + const validLoopArgs2 = [{ type: 'JSExpression', value: 'item' }, { type: 'JSExpression', value: 'index' }]; + expect(checkPropTypes(validLoopArgs, 'loopArgs', getPropType('loopArgs'), componentName)).toBe(true); + expect(checkPropTypes(invalidLoopArgs, 'loopArgs', getPropType('loopArgs'), componentName)).toBe(false); + expect(checkPropTypes(validLoopArgs2, 'loopArgs', getPropType('loopArgs'), componentName)).toBe(true); + }); + + it('should validate the children as an array', () => { + const validChildren = [{ + id: 'child1', + componentName: 'Button', + }, { + id: 'child2', + componentName: 'Button', + }]; + const invalidChildren = 'Not an array'; // Not an array + const invalidChildren2 = [{}]; // Not an valid array + expect(checkPropTypes(invalidChildren, 'children', getPropType('children'), componentName)).toBe(false); + expect(checkPropTypes(validChildren, 'children', getPropType('children'), componentName)).toBe(true); + expect(checkPropTypes(invalidChildren2, 'children', getPropType('children'), componentName)).toBe(false); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); +}); diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 80150f379f..0462d358a7 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -1,7 +1,7 @@ /* eslint-disable no-console */ /* eslint-disable no-new-func */ import logger from './logger'; -import { IPublicTypeRootSchema, IPublicTypeNodeSchema, IPublicTypeJSSlot, IPublicTypePropType, IPublicTypeRequiredType, IPublicTypeBasicType } from '@alilc/lowcode-types'; +import { IPublicTypeRootSchema, IPublicTypeNodeSchema, IPublicTypeJSSlot } from '@alilc/lowcode-types'; import { isI18nData, isJSExpression } from '@alilc/lowcode-utils'; import { isEmpty } from 'lodash'; import IntlMessageFormat from 'intl-messageformat'; diff --git a/packages/shell/src/api/command.ts b/packages/shell/src/api/command.ts new file mode 100644 index 0000000000..ebab4a9ff5 --- /dev/null +++ b/packages/shell/src/api/command.ts @@ -0,0 +1,46 @@ +import { IPublicApiCommand, IPublicModelPluginContext, IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '@alilc/lowcode-types'; +import { commandSymbol, pluginContextSymbol } from '../symbols'; +import { ICommand, ICommandOptions } from '@alilc/lowcode-editor-core'; + +const optionsSymbol = Symbol('options'); +const commandScopeSet = new Set<string>(); + +export class Command implements IPublicApiCommand { + [commandSymbol]: ICommand; + [optionsSymbol]?: ICommandOptions; + [pluginContextSymbol]?: IPublicModelPluginContext; + + constructor(innerCommand: ICommand, pluginContext?: IPublicModelPluginContext, options?: ICommandOptions) { + this[commandSymbol] = innerCommand; + this[optionsSymbol] = options; + this[pluginContextSymbol] = pluginContext; + const commandScope = options?.commandScope; + if (commandScope && commandScopeSet.has(commandScope)) { + throw new Error(`Command scope "${commandScope}" has been registered.`); + } + } + + registerCommand(command: IPublicTypeCommand): void { + this[commandSymbol].registerCommand(command, this[optionsSymbol]); + } + + batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[]): void { + this[commandSymbol].batchExecuteCommand(commands, this[pluginContextSymbol]); + } + + executeCommand(name: string, args: IPublicTypeCommandHandlerArgs): void { + this[commandSymbol].executeCommand(name, args); + } + + listCommands(): IPublicTypeListCommand[] { + return this[commandSymbol].listCommands(); + } + + unregisterCommand(name: string): void { + this[commandSymbol].unregisterCommand(name); + } + + onCommandError(callback: (name: string, error: Error) => void): void { + this[commandSymbol].onCommandError(callback); + } +} diff --git a/packages/shell/src/api/index.ts b/packages/shell/src/api/index.ts index 3726020de0..79340f6777 100644 --- a/packages/shell/src/api/index.ts +++ b/packages/shell/src/api/index.ts @@ -11,4 +11,5 @@ export * from './skeleton'; export * from './canvas'; export * from './workspace'; export * from './config'; -export * from './commonUI'; \ No newline at end of file +export * from './commonUI'; +export * from './command'; \ No newline at end of file diff --git a/packages/shell/src/index.ts b/packages/shell/src/index.ts index ce09ccaaa7..fb1e7228f3 100644 --- a/packages/shell/src/index.ts +++ b/packages/shell/src/index.ts @@ -29,6 +29,7 @@ import { SimulatorHost, Config, CommonUI, + Command, } from './api'; export * from './symbols'; @@ -70,4 +71,5 @@ export { SettingField, SkeletonItem, CommonUI, + Command, }; diff --git a/packages/shell/src/symbols.ts b/packages/shell/src/symbols.ts index 8e2962a24f..e0f846ad36 100644 --- a/packages/shell/src/symbols.ts +++ b/packages/shell/src/symbols.ts @@ -39,4 +39,5 @@ export const configSymbol = Symbol('configSymbol'); export const conditionGroupSymbol = Symbol('conditionGroup'); export const editorViewSymbol = Symbol('editorView'); export const pluginContextSymbol = Symbol('pluginContext'); -export const skeletonItemSymbol = Symbol('skeletonItem'); \ No newline at end of file +export const skeletonItemSymbol = Symbol('skeletonItem'); +export const commandSymbol = Symbol('command'); \ No newline at end of file diff --git a/packages/types/src/shell/api/command.ts b/packages/types/src/shell/api/command.ts new file mode 100644 index 0000000000..5cbfaa2e10 --- /dev/null +++ b/packages/types/src/shell/api/command.ts @@ -0,0 +1,34 @@ +import { IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '../type'; + +export interface IPublicApiCommand { + + /** + * 注册一个新命令及其处理函数 + */ + registerCommand(command: IPublicTypeCommand): void; + + /** + * 注销一个已存在的命令 + */ + unregisterCommand(name: string): void; + + /** + * 通过名称和给定参数执行一个命令,会校验参数是否符合命令定义 + */ + executeCommand(name: string, args: IPublicTypeCommandHandlerArgs): void; + + /** + * 批量执行命令,执行完所有命令后再进行一次重绘,历史记录中只会记录一次 + */ + batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[]): void; + + /** + * 列出所有已注册的命令 + */ + listCommands(): IPublicTypeListCommand[]; + + /** + * 注册错误处理回调函数 + */ + onCommandError(callback: (name: string, error: Error) => void): void; +} \ No newline at end of file diff --git a/packages/types/src/shell/api/index.ts b/packages/types/src/shell/api/index.ts index 79f1b0dc7c..8f14d8dadd 100644 --- a/packages/types/src/shell/api/index.ts +++ b/packages/types/src/shell/api/index.ts @@ -11,3 +11,4 @@ export * from './logger'; export * from './canvas'; export * from './workspace'; export * from './commonUI'; +export * from './command'; \ No newline at end of file diff --git a/packages/types/src/shell/model/plugin-context.ts b/packages/types/src/shell/model/plugin-context.ts index 45568424de..d4d715e96b 100644 --- a/packages/types/src/shell/model/plugin-context.ts +++ b/packages/types/src/shell/model/plugin-context.ts @@ -12,6 +12,7 @@ import { IPublicApiPlugins, IPublicApiWorkspace, IPublicApiCommonUI, + IPublicApiCommand, } from '../api'; import { IPublicEnumPluginRegisterLevel } from '../enum'; import { IPublicModelEngineConfig, IPublicModelWindow } from './'; @@ -109,6 +110,8 @@ export interface IPublicModelPluginContext { */ get commonUI(): IPublicApiCommonUI; + get command(): IPublicApiCommand; + /** * 插件注册层级 * @since v1.1.7 diff --git a/packages/types/src/shell/type/command.ts b/packages/types/src/shell/type/command.ts new file mode 100644 index 0000000000..dd0420def1 --- /dev/null +++ b/packages/types/src/shell/type/command.ts @@ -0,0 +1,71 @@ +// 定义命令处理函数的参数类型 +export interface IPublicTypeCommandHandlerArgs { + [key: string]: any; +} + +// 定义复杂参数类型的接口 +export interface IPublicTypeCommandPropType { + + /** + * 参数基础类型 + */ + type: string; + + /** + * 参数是否必需(可选) + */ + isRequired?: boolean; +} + +// 定义命令参数的接口 +export interface IPublicTypeCommandParameter { + + /** + * 参数名称 + */ + name: string; + + /** + * 参数类型或详细类型描述 + */ + propType: string | IPublicTypeCommandPropType; + + /** + * 参数描述 + */ + description: string; + + /** + * 参数默认值(可选) + */ + defaultValue?: any; +} + +// 定义单个命令的接口 +export interface IPublicTypeCommand { + + /** + * 命令名称 + * 命名规则:commandName + * 使用规则:commandScope:commandName (commandScope 在插件 meta 中定义,用于区分不同插件的命令) + */ + name: string; + + /** + * 命令参数 + */ + parameters?: IPublicTypeCommandParameter[]; + + /** + * 命令描述 + */ + description?: string; + + /** + * 命令处理函数 + */ + handler: (args: any) => void; +} + +export interface IPublicTypeListCommand extends Pick<IPublicTypeCommand, 'name' | 'description' | 'parameters'> { +} \ No newline at end of file diff --git a/packages/types/src/shell/type/index.ts b/packages/types/src/shell/type/index.ts index b1c7779d05..76dd389255 100644 --- a/packages/types/src/shell/type/index.ts +++ b/packages/types/src/shell/type/index.ts @@ -92,4 +92,5 @@ export * from './hotkey-callbacks'; export * from './scrollable'; export * from './simulator-renderer'; export * from './config-transducer'; -export * from './context-menu'; \ No newline at end of file +export * from './context-menu'; +export * from './command'; \ No newline at end of file diff --git a/packages/types/src/shell/type/plugin-meta.ts b/packages/types/src/shell/type/plugin-meta.ts index 421e59ad0a..bf7f6212e8 100644 --- a/packages/types/src/shell/type/plugin-meta.ts +++ b/packages/types/src/shell/type/plugin-meta.ts @@ -1,14 +1,17 @@ import { IPublicTypePluginDeclaration } from './'; export interface IPublicTypePluginMeta { + /** * define dependencies which the plugin depends on */ dependencies?: string[]; + /** * specify which engine version is compatible with the plugin */ engines?: { + /** e.g. '^1.0.0' */ lowcodeEngine?: string; }; @@ -26,4 +29,9 @@ export interface IPublicTypePluginMeta { * event.emit('someEventName') is actually sending event with name 'myEvent:someEventName' */ eventPrefix?: string; + + /** + * 如果要使用 command 注册命令,需要在插件 meta 中定义 commandScope + */ + commandScope?: string; } diff --git a/packages/workspace/src/context/base-context.ts b/packages/workspace/src/context/base-context.ts index 2f6154788f..db33597aea 100644 --- a/packages/workspace/src/context/base-context.ts +++ b/packages/workspace/src/context/base-context.ts @@ -5,6 +5,7 @@ import { commonEvent, IEngineConfig, IHotKey, + Command as InnerCommand, } from '@alilc/lowcode-editor-core'; import { Designer, @@ -33,6 +34,7 @@ import { Window, Canvas, CommonUI, + Command, } from '@alilc/lowcode-shell'; import { IPluginPreferenceMananger, @@ -129,6 +131,7 @@ export class BasicContext implements IBasicContext { const skeleton = new Skeleton(innerSkeleton, 'any', true); const canvas = new Canvas(editor, true); const commonUI = new CommonUI(editor); + const innerCommand = new InnerCommand(); editor.set('setters', setters); editor.set('project', project); editor.set('material', material); @@ -162,6 +165,7 @@ export class BasicContext implements IBasicContext { context.setters = setters; context.material = material; const eventPrefix = meta?.eventPrefix || 'common'; + const commandScope = meta?.commandScope; context.event = new Event(commonEvent, { prefix: eventPrefix }); context.config = config; context.common = common; @@ -172,6 +176,9 @@ export class BasicContext implements IBasicContext { if (editorWindow) { context.editorWindow = new Window(editorWindow); } + context.command = new Command(innerCommand, context as IPublicModelPluginContext, { + commandScope, + }); context.registerLevel = registerLevel; context.isPluginRegisteredInWorkspace = registerLevel === IPublicEnumPluginRegisterLevel.Workspace; editor.set('pluginContext', context); From b29c53901e4a1c1f437d9fe71aadaa16d02686f4 Mon Sep 17 00:00:00 2001 From: ZeralZhang <zeralzhang@gmail.com> Date: Fri, 26 Jan 2024 09:38:37 +0800 Subject: [PATCH 314/361] fix(react-simulator-renderer): detached node has children detached node has children will return false, causing memory leaks. --- packages/react-simulator-renderer/src/renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index efebeda040..20f6e18c0b 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -614,7 +614,7 @@ function getNodeInstance(fiberNode: any, specId?: string): IPublicTypeNodeInstan function checkInstanceMounted(instance: any): boolean { if (isElement(instance)) { - return instance.parentElement != null; + return instance.parentElement != null && window.document.contains(instance); } return true; } From b97570f10c1035991d17aba49031edd0ef710024 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 26 Jan 2024 15:20:13 +0800 Subject: [PATCH 315/361] docs(demo): add dialog use desc --- docs/docs/demoUsage/makeStuff/dialog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/demoUsage/makeStuff/dialog.md b/docs/docs/demoUsage/makeStuff/dialog.md index 56303067cb..da78cc8e8c 100644 --- a/docs/docs/demoUsage/makeStuff/dialog.md +++ b/docs/docs/demoUsage/makeStuff/dialog.md @@ -2,6 +2,8 @@ title: 3. 如何通过按钮展示/隐藏弹窗 sidebar_position: 1 --- +> 说明:这个方式依赖低代码弹窗组件是否对外保留了相关的 API,不同的物料支持的方式不一样,这里只针对综合场景的弹窗物料。 + ## 1.拖拽一个按钮 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01kLaWA31D6WwTui9VW_!!6000000000167-2-tps-3584-1812.png) From 739572172a9901c7223f7bc1617495b8e8752900 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 26 Jan 2024 08:40:59 +0000 Subject: [PATCH 316/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 69dddfce2c..ce6a969c1f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.29", + "version": "1.2.30", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 6e89d4d605760d376fedf350b99f24bc11770ec5 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 26 Jan 2024 15:14:16 +0800 Subject: [PATCH 317/361] feat(setter): add field ts --- packages/editor-core/src/di/setter.ts | 6 +++--- .../src/components/settings/settings-pane.tsx | 4 ++-- packages/editor-skeleton/src/transducers/parse-props.ts | 3 ++- packages/types/src/shell/type/field-extra-props.ts | 2 +- packages/types/src/shell/type/registered-setter.ts | 7 +++++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/editor-core/src/di/setter.ts b/packages/editor-core/src/di/setter.ts index 437d9a89e2..5af2c0230f 100644 --- a/packages/editor-core/src/di/setter.ts +++ b/packages/editor-core/src/di/setter.ts @@ -1,5 +1,5 @@ import { ReactNode } from 'react'; -import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeRegisteredSetter } from '@alilc/lowcode-types'; +import { IPublicApiSetters, IPublicModelSettingField, IPublicTypeCustomView, IPublicTypeRegisteredSetter } from '@alilc/lowcode-types'; import { createContent, isCustomView } from '@alilc/lowcode-utils'; const settersMap = new Map<string, IPublicTypeRegisteredSetter & { @@ -28,7 +28,7 @@ export function registerSetter( if (!setter.initialValue) { const initial = getInitialFromSetter(setter.component); if (initial) { - setter.initialValue = (field: any) => { + setter.initialValue = (field: IPublicModelSettingField) => { return initial.call(field, field.getValue()); }; } @@ -81,7 +81,7 @@ export class Setters implements ISetters { if (!setter.initialValue) { const initial = getInitialFromSetter(setter.component); if (initial) { - setter.initialValue = (field: any) => { + setter.initialValue = (field: IPublicModelSettingField) => { return initial.call(field, field.getValue()); }; } diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index 1d651bb5a3..1561bf8bbe 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -225,7 +225,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView const value = this.value; - let _onChange = extraProps?.onChange; + let onChangeAPI = extraProps?.onChange; let stageName = this.stageName; return createField( @@ -261,7 +261,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView value, }); field.setValue(value, true); - if (_onChange) _onChange(value, field); + if (onChangeAPI) onChangeAPI(value, field.internalToShellField()); }, onInitial: () => { if (initialValue == null) { diff --git a/packages/editor-skeleton/src/transducers/parse-props.ts b/packages/editor-skeleton/src/transducers/parse-props.ts index d22f07f437..573d24ac62 100644 --- a/packages/editor-skeleton/src/transducers/parse-props.ts +++ b/packages/editor-skeleton/src/transducers/parse-props.ts @@ -9,6 +9,7 @@ import { IPublicTypeTransformedComponentMetadata, IPublicTypeOneOfType, ConfigureSupportEvent, + IPublicModelSettingField, } from '@alilc/lowcode-types'; function propConfigToFieldConfig(propConfig: IPublicTypePropConfig): IPublicTypeFieldConfig { @@ -102,7 +103,7 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType }, }, isRequired, - initialValue: (field: any) => { + initialValue: (field: IPublicModelSettingField) => { const data: any = {}; items.forEach((item: any) => { let initial = item.defaultValue; diff --git a/packages/types/src/shell/type/field-extra-props.ts b/packages/types/src/shell/type/field-extra-props.ts index 3e2df280b7..7aae7e0fe8 100644 --- a/packages/types/src/shell/type/field-extra-props.ts +++ b/packages/types/src/shell/type/field-extra-props.ts @@ -77,5 +77,5 @@ export interface IPublicTypeFieldExtraProps { /** * onChange 事件 */ - onChange?: (value: any, field: any) => void; + onChange?: (value: any, field: IPublicModelSettingField) => void; } diff --git a/packages/types/src/shell/type/registered-setter.ts b/packages/types/src/shell/type/registered-setter.ts index 85cad5a803..55a90465a8 100644 --- a/packages/types/src/shell/type/registered-setter.ts +++ b/packages/types/src/shell/type/registered-setter.ts @@ -1,17 +1,20 @@ +import { IPublicModelSettingField } from '../model'; import { IPublicTypeCustomView, IPublicTypeTitleContent } from './'; export interface IPublicTypeRegisteredSetter { component: IPublicTypeCustomView; defaultProps?: object; title?: IPublicTypeTitleContent; + /** * for MixedSetter to check this setter if available */ - condition?: (field: any) => boolean; + condition?: (field: IPublicModelSettingField) => boolean; + /** * for MixedSetter to manual change to this setter */ - initialValue?: any | ((field: any) => any); + initialValue?: any | ((field: IPublicModelSettingField) => any); recommend?: boolean; // 标识是否为动态 setter,默认为 true isDynamic?: boolean; From e3a19896d78cf79736e0fabba9dd37c4c3f22997 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 26 Jan 2024 16:58:20 +0800 Subject: [PATCH 318/361] fix(prop): emit event when unset prop --- .../designer/src/document/node/props/prop.ts | 43 ++++--- .../tests/document/node/props/prop.test.ts | 106 +++++++++++++++++- 2 files changed, 132 insertions(+), 17 deletions(-) diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index e2d9f12e8e..fd9401314a 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -353,7 +353,6 @@ export class Prop implements IProp, IPropParent { @action setValue(val: IPublicTypeCompositeValue) { if (val === this._value) return; - const editor = this.owner.document?.designer.editor; const oldValue = this._value; this._value = val; this._code = null; @@ -386,22 +385,31 @@ export class Prop implements IProp, IPropParent { this.setupItems(); if (oldValue !== this._value) { - const propsInfo = { - key: this.key, - prop: this, - oldValue, - newValue: this._value, - }; - - editor?.eventBus.emit(GlobalEvent.Node.Prop.InnerChange, { - node: this.owner as any, - ...propsInfo, - }); - - this.owner?.emitPropChange?.(propsInfo); + this.emitChange({ oldValue }); } } + emitChange = ({ + oldValue, + }: { + oldValue: IPublicTypeCompositeValue | UNSET; + }) => { + const editor = this.owner.document?.designer.editor; + const propsInfo = { + key: this.key, + prop: this, + oldValue, + newValue: this.type === 'unset' ? undefined : this._value, + }; + + editor?.eventBus.emit(GlobalEvent.Node.Prop.InnerChange, { + node: this.owner as any, + ...propsInfo, + }); + + this.owner?.emitPropChange?.(propsInfo); + }; + getValue(): IPublicTypeCompositeValue { return this.export(IPublicEnumTransformStage.Serilize); } @@ -462,7 +470,12 @@ export class Prop implements IProp, IPropParent { */ @action unset() { - this._type = 'unset'; + if (this._type !== 'unset') { + this._type = 'unset'; + this.emitChange({ + oldValue: this._value, + }); + } } /** diff --git a/packages/designer/tests/document/node/props/prop.test.ts b/packages/designer/tests/document/node/props/prop.test.ts index 4424eb6010..8630376b68 100644 --- a/packages/designer/tests/document/node/props/prop.test.ts +++ b/packages/designer/tests/document/node/props/prop.test.ts @@ -3,7 +3,7 @@ import { Editor, engineConfig } from '@alilc/lowcode-editor-core'; import { Designer } from '../../../../src/designer/designer'; import { DocumentModel } from '../../../../src/document/document-model'; import { Prop, isProp, isValidArrayIndex } from '../../../../src/document/node/props/prop'; -import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; +import { GlobalEvent, IPublicEnumTransformStage } from '@alilc/lowcode-types'; import { shellModelFactory } from '../../../../../engine/src/modules/shell-model-factory'; const slotNodeImportMockFn = jest.fn(); @@ -24,9 +24,16 @@ const mockOwner = { remove: slotNodeRemoveMockFn, }; }, - designer: {}, + designer: { + editor: { + eventBus: { + emit: jest.fn(), + }, + }, + }, }, isInited: true, + emitPropChange: jest.fn(), }; const mockPropsInst = { @@ -564,3 +571,98 @@ describe('其他导出函数', () => { expect(isValidArrayIndex('2', 1)).toBeFalsy(); }); }); + +describe('setValue with event', () => { + let propInstance; + let mockEmitChange; + let mockEventBusEmit; + let mockEmitPropChange; + + beforeEach(() => { + // Initialize the instance of your class + propInstance = new Prop(mockPropsInst, true, 'stringProp');; + + // Mock necessary methods and properties + mockEmitChange = jest.spyOn(propInstance, 'emitChange'); + propInstance.owner = { + document: { + designer: { + editor: { + eventBus: { + emit: jest.fn(), + }, + }, + }, + }, + emitPropChange: jest.fn(), + }; + mockEventBusEmit = jest.spyOn(propInstance.owner.document.designer.editor.eventBus, 'emit'); + mockEmitPropChange = jest.spyOn(propInstance.owner, 'emitPropChange'); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('should correctly handle string values and emit changes', () => { + const oldValue = propInstance._value; + const newValue = 'new string value'; + + propInstance.setValue(newValue); + + const expectedPartialPropsInfo = expect.objectContaining({ + key: propInstance.key, + newValue, // You can specifically test only certain keys + oldValue, + }); + + expect(propInstance.getValue()).toBe(newValue); + expect(propInstance.type).toBe('literal'); + expect(mockEmitChange).toHaveBeenCalledWith({ oldValue }); + expect(mockEventBusEmit).toHaveBeenCalledWith(GlobalEvent.Node.Prop.InnerChange, expectedPartialPropsInfo); + expect(mockEmitPropChange).toHaveBeenCalledWith(expectedPartialPropsInfo); + }); + + it('should handle object values and set type to map', () => { + const oldValue = propInstance._value; + const newValue = 234; + + const expectedPartialPropsInfo = expect.objectContaining({ + key: propInstance.key, + newValue, // You can specifically test only certain keys + oldValue, + }); + + propInstance.setValue(newValue); + + expect(propInstance.getValue()).toEqual(newValue); + expect(propInstance.type).toBe('literal'); + expect(mockEmitChange).toHaveBeenCalledWith({ oldValue }); + expect(mockEventBusEmit).toHaveBeenCalledWith(GlobalEvent.Node.Prop.InnerChange, expectedPartialPropsInfo); + expect(mockEmitPropChange).toHaveBeenCalledWith(expectedPartialPropsInfo); + }); + + it('should has event when unset call', () => { + const oldValue = propInstance._value; + + propInstance.unset(); + + const expectedPartialPropsInfo = expect.objectContaining({ + key: propInstance.key, + newValue: undefined, // You can specifically test only certain keys + oldValue, + }); + + expect(propInstance.getValue()).toEqual(undefined); + expect(propInstance.type).toBe('unset'); + expect(mockEmitChange).toHaveBeenCalledWith({ + oldValue, + newValue: undefined, + }); + expect(mockEventBusEmit).toHaveBeenCalledWith(GlobalEvent.Node.Prop.InnerChange, expectedPartialPropsInfo); + expect(mockEmitPropChange).toHaveBeenCalledWith(expectedPartialPropsInfo); + + propInstance.unset(); + expect(mockEmitChange).toHaveBeenCalledTimes(1); + }); +}); From ed7befbff01d174a0335f0a1832fd9e313e308ea Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 30 Jan 2024 10:22:43 +0800 Subject: [PATCH 319/361] feat(context-menu): prevent event bubbling when "menus" is empty --- packages/shell/src/components/context-menu.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/shell/src/components/context-menu.tsx b/packages/shell/src/components/context-menu.tsx index ccd910efc4..8c7ab446ba 100644 --- a/packages/shell/src/components/context-menu.tsx +++ b/packages/shell/src/components/context-menu.tsx @@ -34,7 +34,7 @@ export function ContextMenu({ children, menus, pluginContext }: { ); } - if (!menus || !menus.length) { + if (!menus) { return ( <>{ children }</> ); @@ -53,6 +53,9 @@ export function ContextMenu({ children, menus, pluginContext }: { } ContextMenu.create = (pluginContext: IPublicModelPluginContext, menus: IPublicTypeContextMenuAction[], event: MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, { pluginContext, }), { From 80bb7102b65ccfc24399e372cff5f3fbaf8258a4 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 30 Jan 2024 14:19:30 +0800 Subject: [PATCH 320/361] feat(command): update default commands --- .../src/inner-plugins/default-command.ts | 44 ++++++++++++++----- packages/types/src/shell/api/command.ts | 4 +- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/packages/engine/src/inner-plugins/default-command.ts b/packages/engine/src/inner-plugins/default-command.ts index b2b899acb0..68d65c5001 100644 --- a/packages/engine/src/inner-plugins/default-command.ts +++ b/packages/engine/src/inner-plugins/default-command.ts @@ -10,10 +10,7 @@ const sampleNodeSchema: IPublicTypePropType = { value: [ { name: 'id', - propType: { - type: 'string', - isRequired: true, - }, + propType: 'string', }, { name: 'componentName', @@ -277,10 +274,12 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { handler: (param: { parentNodeId: string; nodeSchema: IPublicTypeNodeSchema; + index: number; }) => { const { parentNodeId, nodeSchema, + index, } = param; const { project } = ctx; const parentNode = project.currentDocument?.getNodeById(parentNodeId); @@ -296,7 +295,11 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { throw new Error('Invalid node.'); } - project.currentDocument?.insertNode(parentNode, nodeSchema); + if (index < 0 || index > (parentNode.children?.size || 0)) { + throw new Error(`Invalid index '${index}'.`); + } + + project.currentDocument?.insertNode(parentNode, nodeSchema, index); }, parameters: [ { @@ -309,6 +312,11 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { propType: nodeSchemaPropType, description: 'The node to be added.', }, + { + name: 'index', + propType: 'number', + description: 'The index of the node to be added.', + }, ], }); @@ -326,6 +334,14 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { index = 0, } = param; + if (!nodeId) { + throw new Error('Invalid node id.'); + } + + if (!targetNodeId) { + throw new Error('Invalid target node id.'); + } + const node = project.currentDocument?.getNodeById(nodeId); const targetNode = project.currentDocument?.getNodeById(targetNodeId); if (!node) { @@ -350,12 +366,18 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { parameters: [ { name: 'nodeId', - propType: 'string', + propType: { + type: 'string', + isRequired: true, + }, description: 'The id of the node to be moved.', }, { name: 'targetNodeId', - propType: 'string', + propType: { + type: 'string', + isRequired: true, + }, description: 'The id of the target node.', }, { @@ -393,8 +415,8 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { }); command.registerCommand({ - name: 'replace', - description: 'Replace a node with another node.', + name: 'update', + description: 'Update a node.', handler(param: { nodeId: string; nodeSchema: IPublicTypeNodeSchema; @@ -419,12 +441,12 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { { name: 'nodeId', propType: 'string', - description: 'The id of the node to be replaced.', + description: 'The id of the node to be updated.', }, { name: 'nodeSchema', propType: nodeSchemaPropType, - description: 'The node to replace.', + description: 'The node to be updated.', }, ], }); diff --git a/packages/types/src/shell/api/command.ts b/packages/types/src/shell/api/command.ts index 5cbfaa2e10..1f8425dcef 100644 --- a/packages/types/src/shell/api/command.ts +++ b/packages/types/src/shell/api/command.ts @@ -15,12 +15,12 @@ export interface IPublicApiCommand { /** * 通过名称和给定参数执行一个命令,会校验参数是否符合命令定义 */ - executeCommand(name: string, args: IPublicTypeCommandHandlerArgs): void; + executeCommand(name: string, args?: IPublicTypeCommandHandlerArgs): void; /** * 批量执行命令,执行完所有命令后再进行一次重绘,历史记录中只会记录一次 */ - batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[]): void; + batchExecuteCommand(commands: { name: string; args?: IPublicTypeCommandHandlerArgs }[]): void; /** * 列出所有已注册的命令 From 557a462b9f0e90e953862fd5fc7b528d4701a278 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 30 Jan 2024 14:34:53 +0800 Subject: [PATCH 321/361] fix(prop): emit event when delete prop --- .../designer/src/document/node/props/prop.ts | 1 + .../tests/document/node/props/prop.test.ts | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index fd9401314a..d70f0f56ec 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -570,6 +570,7 @@ export class Prop implements IProp, IPropParent { @action remove() { this.parent.delete(this); + this.unset(); } /** diff --git a/packages/designer/tests/document/node/props/prop.test.ts b/packages/designer/tests/document/node/props/prop.test.ts index 8630376b68..ff4147a34a 100644 --- a/packages/designer/tests/document/node/props/prop.test.ts +++ b/packages/designer/tests/document/node/props/prop.test.ts @@ -34,11 +34,14 @@ const mockOwner = { }, isInited: true, emitPropChange: jest.fn(), + delete() {}, }; const mockPropsInst = { owner: mockOwner, + delete() {}, }; + mockPropsInst.props = mockPropsInst; describe('Prop 类测试', () => { @@ -595,6 +598,7 @@ describe('setValue with event', () => { }, }, emitPropChange: jest.fn(), + delete() {}, }; mockEventBusEmit = jest.spyOn(propInstance.owner.document.designer.editor.eventBus, 'emit'); mockEmitPropChange = jest.spyOn(propInstance.owner, 'emitPropChange'); @@ -665,4 +669,29 @@ describe('setValue with event', () => { propInstance.unset(); expect(mockEmitChange).toHaveBeenCalledTimes(1); }); + + // remove + it('should has event when remove call', () => { + const oldValue = propInstance._value; + + propInstance.remove(); + + const expectedPartialPropsInfo = expect.objectContaining({ + key: propInstance.key, + newValue: undefined, // You can specifically test only certain keys + oldValue, + }); + + expect(propInstance.getValue()).toEqual(undefined); + // expect(propInstance.type).toBe('unset'); + expect(mockEmitChange).toHaveBeenCalledWith({ + oldValue, + newValue: undefined, + }); + expect(mockEventBusEmit).toHaveBeenCalledWith(GlobalEvent.Node.Prop.InnerChange, expectedPartialPropsInfo); + expect(mockEmitPropChange).toHaveBeenCalledWith(expectedPartialPropsInfo); + + propInstance.remove(); + expect(mockEmitChange).toHaveBeenCalledTimes(1); + }); }); From 43921cea2d21321fa9366e34e27ea15649a7f944 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 30 Jan 2024 18:31:52 +0800 Subject: [PATCH 322/361] fix(workspace): fix workspace.plugins.xxx api is invalid --- packages/shell/src/api/workspace.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index fd3e82fa90..f5bc79009f 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -90,7 +90,7 @@ export class Workspace implements IPublicApiWorkspace { } get plugins() { - return new Plugins(this[workspaceSymbol].plugins, true); + return new Plugins(this[workspaceSymbol].plugins, true).toProxy(); } get skeleton() { From de95b87b1e2ef1a7bd90b52e7f3cf8ca22a5f999 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 31 Jan 2024 18:53:23 +0800 Subject: [PATCH 323/361] feat: update ts defined --- packages/types/src/shell/api/workspace.ts | 5 ++++- packages/types/src/shell/type/command.ts | 18 +++--------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/packages/types/src/shell/api/workspace.ts b/packages/types/src/shell/api/workspace.ts index 9e1080b31e..b6e7d84cb7 100644 --- a/packages/types/src/shell/api/workspace.ts +++ b/packages/types/src/shell/api/workspace.ts @@ -1,8 +1,9 @@ import { IPublicModelWindow } from '../model'; -import { IPublicApiPlugins, IPublicModelResource, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; +import { IPublicApiPlugins, IPublicApiSkeleton, IPublicModelResource, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; export interface IPublicApiWorkspace< Plugins = IPublicApiPlugins, + Skeleton = IPublicApiSkeleton, ModelWindow = IPublicModelWindow, Resource = IPublicModelResource, > { @@ -15,6 +16,8 @@ export interface IPublicApiWorkspace< plugins: Plugins; + skeleton: Skeleton; + /** 当前设计器的编辑窗口 */ windows: ModelWindow[]; diff --git a/packages/types/src/shell/type/command.ts b/packages/types/src/shell/type/command.ts index dd0420def1..0f301bd658 100644 --- a/packages/types/src/shell/type/command.ts +++ b/packages/types/src/shell/type/command.ts @@ -1,22 +1,10 @@ +import { IPublicTypePropType } from './prop-types'; + // 定义命令处理函数的参数类型 export interface IPublicTypeCommandHandlerArgs { [key: string]: any; } -// 定义复杂参数类型的接口 -export interface IPublicTypeCommandPropType { - - /** - * 参数基础类型 - */ - type: string; - - /** - * 参数是否必需(可选) - */ - isRequired?: boolean; -} - // 定义命令参数的接口 export interface IPublicTypeCommandParameter { @@ -28,7 +16,7 @@ export interface IPublicTypeCommandParameter { /** * 参数类型或详细类型描述 */ - propType: string | IPublicTypeCommandPropType; + propType: string | IPublicTypePropType; /** * 参数描述 From 24393211b404575bd81c62007e324ed1dfdca112 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 1 Feb 2024 12:23:31 +0800 Subject: [PATCH 324/361] refactor(plugin-command): add plugin-command package --- .github/workflows/test packages.yml | 18 ++++- packages/engine/src/engine-core.ts | 2 +- packages/plugin-command/README.md | 11 +++ .../__tests__/node-command.test.ts} | 8 +-- packages/plugin-command/build.json | 9 +++ packages/plugin-command/build.test.json | 19 +++++ packages/plugin-command/package.json | 34 +++++++++ .../plugin-command/src/history-command.ts | 43 ++++++++++++ packages/plugin-command/src/index.ts | 23 +++++++ .../src/node-command.ts} | 69 +++---------------- 10 files changed, 171 insertions(+), 65 deletions(-) create mode 100644 packages/plugin-command/README.md rename packages/{engine/tests/inner-plugins/default-command.test.ts => plugin-command/__tests__/node-command.test.ts} (97%) create mode 100644 packages/plugin-command/build.json create mode 100644 packages/plugin-command/build.test.json create mode 100644 packages/plugin-command/package.json create mode 100644 packages/plugin-command/src/history-command.ts create mode 100644 packages/plugin-command/src/index.ts rename packages/{engine/src/inner-plugins/default-command.ts => plugin-command/src/node-command.ts} (88%) diff --git a/.github/workflows/test packages.yml b/.github/workflows/test packages.yml index abb2973708..573a1ade01 100644 --- a/.github/workflows/test packages.yml +++ b/.github/workflows/test packages.yml @@ -121,4 +121,20 @@ jobs: run: npm i && npm run setup:skip-build - name: test - run: cd packages/editor-core && npm test \ No newline at end of file + run: cd packages/editor-core && npm test + + test-plugin-command + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: install + run: npm i && npm run setup:skip-build + + - name: test + run: cd packages/plugin-command && npm test \ No newline at end of file diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 778438a3d4..5a2cbbc656 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -66,7 +66,7 @@ import { defaultPanelRegistry } from './inner-plugins/default-panel-registry'; import { shellModelFactory } from './modules/shell-model-factory'; import { builtinHotkey } from './inner-plugins/builtin-hotkey'; import { defaultContextMenu } from './inner-plugins/default-context-menu'; -import { defaultCommand } from './inner-plugins/default-command'; +import { defaultCommand } from '@alilc/lowcode-plugin-command'; import { OutlinePlugin } from '@alilc/lowcode-plugin-outline-pane'; export * from './modules/skeleton-types'; diff --git a/packages/plugin-command/README.md b/packages/plugin-command/README.md new file mode 100644 index 0000000000..8476b47e55 --- /dev/null +++ b/packages/plugin-command/README.md @@ -0,0 +1,11 @@ +# `@alilc/plugin-command` + +> TODO: description + +## Usage + +``` +const pluginCommand = require('@alilc/plugin-command'); + +// TODO: DEMONSTRATE API +``` diff --git a/packages/engine/tests/inner-plugins/default-command.test.ts b/packages/plugin-command/__tests__/node-command.test.ts similarity index 97% rename from packages/engine/tests/inner-plugins/default-command.test.ts rename to packages/plugin-command/__tests__/node-command.test.ts index 0e28c642b8..2e9d21b35e 100644 --- a/packages/engine/tests/inner-plugins/default-command.test.ts +++ b/packages/plugin-command/__tests__/node-command.test.ts @@ -1,5 +1,5 @@ import { checkPropTypes } from '@alilc/lowcode-utils/src/check-prop-types'; -import { nodeSchemaPropType } from '../../src/inner-plugins/default-command'; +import { nodeSchemaPropType } from '../src/node-command'; describe('nodeSchemaPropType', () => { const componentName = 'NodeComponent'; @@ -10,8 +10,8 @@ describe('nodeSchemaPropType', () => { const invalidId = 123; // Not a string expect(checkPropTypes(validId, 'id', getPropType('id'), componentName)).toBe(true); expect(checkPropTypes(invalidId, 'id', getPropType('id'), componentName)).toBe(false); - // isRequired - expect(checkPropTypes(undefined, 'id', getPropType('id'), componentName)).toBe(false); + // is not required + expect(checkPropTypes(undefined, 'id', getPropType('id'), componentName)).toBe(true); }); it('should validate the componentName as a string', () => { @@ -71,7 +71,7 @@ describe('nodeSchemaPropType', () => { const invalidLoop = { type: 'JSExpression', value: 123 }; // Not a string expect(checkPropTypes(validLoop, 'loop', getPropType('loop'), componentName)).toBe(true); expect(checkPropTypes(invalidLoop, 'loop', getPropType('loop'), componentName)).toBe(false); - }) + }); it('should validate the loopArgs as an array', () => { const validLoopArgs = ['item']; diff --git a/packages/plugin-command/build.json b/packages/plugin-command/build.json new file mode 100644 index 0000000000..d0aec10385 --- /dev/null +++ b/packages/plugin-command/build.json @@ -0,0 +1,9 @@ +{ + "plugins": [ + "@alilc/build-plugin-lce", + "build-plugin-fusion", + ["build-plugin-moment-locales", { + "locales": ["zh-cn"] + }] + ] +} diff --git a/packages/plugin-command/build.test.json b/packages/plugin-command/build.test.json new file mode 100644 index 0000000000..9596d43e79 --- /dev/null +++ b/packages/plugin-command/build.test.json @@ -0,0 +1,19 @@ +{ + "plugins": [ + [ + "@alilc/build-plugin-lce", + { + "filename": "editor-preset-vision", + "library": "LowcodeEditor", + "libraryTarget": "umd", + "externals": { + "react": "var window.React", + "react-dom": "var window.ReactDOM", + "prop-types": "var window.PropTypes", + "rax": "var window.Rax" + } + } + ], + "@alilc/lowcode-test-mate/plugin/index.ts" + ] +} diff --git a/packages/plugin-command/package.json b/packages/plugin-command/package.json new file mode 100644 index 0000000000..3c84e265ec --- /dev/null +++ b/packages/plugin-command/package.json @@ -0,0 +1,34 @@ +{ + "name": "@alilc/lowcode-plugin-command", + "version": "1.3.1", + "description": "> TODO: description", + "author": "liujuping <liujup@foxmail.com>", + "homepage": "https://github.com/alibaba/lowcode-engine#readme", + "license": "ISC", + "main": "lib/plugin-command.js", + "directories": { + "lib": "lib", + "test": "__tests__" + }, + "files": [ + "lib" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/alibaba/lowcode-engine.git" + }, + "scripts": { + "test": "build-scripts test --config build.test.json --jest-passWithNoTests", + "build": "build-scripts build" + }, + "bugs": { + "url": "https://github.com/alibaba/lowcode-engine/issues" + }, + "dependencies": { + "@alilc/lowcode-types": "^1.3.1", + "@alilc/lowcode-utils": "^1.3.1" + } +} diff --git a/packages/plugin-command/src/history-command.ts b/packages/plugin-command/src/history-command.ts new file mode 100644 index 0000000000..ea7e491bce --- /dev/null +++ b/packages/plugin-command/src/history-command.ts @@ -0,0 +1,43 @@ +import { IPublicModelPluginContext, IPublicTypePlugin } from '@alilc/lowcode-types'; + +export const historyCommand: IPublicTypePlugin = (ctx: IPublicModelPluginContext) => { + const { command, project } = ctx; + return { + init() { + command.registerCommand({ + name: 'undo', + description: 'Undo the last operation.', + handler: () => { + const state = project.currentDocument?.history.getState() || 0; + const enable = !!(state & 1); + if (!enable) { + throw new Error('Can not undo.'); + } + project.currentDocument?.history.back(); + }, + }); + + command.registerCommand({ + name: 'redo', + description: 'Redo the last operation.', + handler: () => { + const state = project.currentDocument?.history.getState() || 0; + const enable = !!(state & 2); + if (!enable) { + throw new Error('Can not redo.'); + } + project.currentDocument?.history.forward(); + }, + }); + }, + destroy() { + command.unregisterCommand('history:undo'); + command.unregisterCommand('history:redo'); + }, + }; +}; + +historyCommand.pluginName = '___history_command___'; +historyCommand.meta = { + commandScope: 'history', +}; diff --git a/packages/plugin-command/src/index.ts b/packages/plugin-command/src/index.ts new file mode 100644 index 0000000000..8e5d64ebcf --- /dev/null +++ b/packages/plugin-command/src/index.ts @@ -0,0 +1,23 @@ +import { IPublicModelPluginContext, IPublicTypePlugin } from '@alilc/lowcode-types'; +import { nodeCommand } from './node-command'; +import { historyCommand } from './history-command'; + +export const defaultCommand: IPublicTypePlugin = (ctx: IPublicModelPluginContext) => { + const { plugins } = ctx; + + return { + async init() { + await plugins.register(nodeCommand, {}, { autoInit: true }); + await plugins.register(historyCommand, {}, { autoInit: true }); + }, + destroy() { + plugins.delete(nodeCommand.pluginName); + plugins.delete(historyCommand.pluginName); + }, + }; +}; + +defaultCommand.pluginName = '___default_command___'; +defaultCommand.meta = { + commandScope: 'common', +}; diff --git a/packages/engine/src/inner-plugins/default-command.ts b/packages/plugin-command/src/node-command.ts similarity index 88% rename from packages/engine/src/inner-plugins/default-command.ts rename to packages/plugin-command/src/node-command.ts index 68d65c5001..eeda1d1688 100644 --- a/packages/engine/src/inner-plugins/default-command.ts +++ b/packages/plugin-command/src/node-command.ts @@ -1,8 +1,4 @@ -import { - IPublicModelPluginContext, - IPublicTypeNodeSchema, - IPublicTypePropType, -} from '@alilc/lowcode-types'; +import { IPublicModelPluginContext, IPublicTypeNodeSchema, IPublicTypePlugin, IPublicTypePropType } from '@alilc/lowcode-types'; import { isNodeSchema } from '@alilc/lowcode-utils'; const sampleNodeSchema: IPublicTypePropType = { @@ -226,45 +222,7 @@ export const nodeSchemaPropType: IPublicTypePropType = { ], }; -export const historyCommand = (ctx: IPublicModelPluginContext) => { - const { command, project } = ctx; - return { - init() { - command.registerCommand({ - name: 'undo', - description: 'Undo the last operation.', - handler: () => { - const state = project.currentDocument?.history.getState() || 0; - const enable = !!(state & 1); - if (!enable) { - throw new Error('Can not undo.'); - } - project.currentDocument?.history.back(); - }, - }); - - command.registerCommand({ - name: 'redo', - description: 'Redo the last operation.', - handler: () => { - const state = project.currentDocument?.history.getState() || 0; - const enable = !!(state & 2); - if (!enable) { - throw new Error('Can not redo.'); - } - project.currentDocument?.history.forward(); - }, - }); - }, - }; -}; - -historyCommand.pluginName = '___history_command___'; -historyCommand.meta = { - commandScope: 'history', -}; - -export const nodeCommand = (ctx: IPublicModelPluginContext) => { +export const nodeCommand: IPublicTypePlugin = (ctx: IPublicModelPluginContext) => { const { command, project } = ctx; return { init() { @@ -521,6 +479,14 @@ export const nodeCommand = (ctx: IPublicModelPluginContext) => { ], }); }, + destroy() { + command.unregisterCommand('node:add'); + command.unregisterCommand('node:move'); + command.unregisterCommand('node:remove'); + command.unregisterCommand('node:update'); + command.unregisterCommand('node:updateProps'); + command.unregisterCommand('node:removeProps'); + }, }; }; @@ -529,18 +495,3 @@ nodeCommand.meta = { commandScope: 'node', }; -export const defaultCommand = (ctx: IPublicModelPluginContext) => { - const { plugins } = ctx; - plugins.register(nodeCommand); - plugins.register(historyCommand); - - return { - init() { - }, - }; -}; - -defaultCommand.pluginName = '___default_command___'; -defaultCommand.meta = { - commandScope: 'common', -}; From 5b46d96df77d738249b0170bad222eedc29a1802 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 1 Feb 2024 14:41:55 +0800 Subject: [PATCH 325/361] refactor(plugin-command): add plugin-command package --- scripts/build.sh | 1 + scripts/sync.sh | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 828bb16d99..751e9094fe 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -10,6 +10,7 @@ lerna run build \ --scope @alilc/lowcode-editor-skeleton \ --scope @alilc/lowcode-designer \ --scope @alilc/lowcode-plugin-designer \ + --scope @alilc/lowcode-plugin-command \ --scope @alilc/lowcode-plugin-outline-pane \ --scope @alilc/lowcode-react-renderer \ --scope @alilc/lowcode-react-simulator-renderer \ diff --git a/scripts/sync.sh b/scripts/sync.sh index e9840eeca6..3edac03845 100755 --- a/scripts/sync.sh +++ b/scripts/sync.sh @@ -13,4 +13,5 @@ tnpm sync @alilc/lowcode-renderer-core tnpm sync @alilc/lowcode-react-renderer tnpm sync @alilc/lowcode-react-simulator-renderer tnpm sync @alilc/lowcode-engine -tnpm sync @alilc/lowcode-workspace \ No newline at end of file +tnpm sync @alilc/lowcode-workspace +tnpm sync @alilc/lowcode-plugin-command \ No newline at end of file From 5657d9c084899e91077008c491284248776ad7d8 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 1 Feb 2024 14:49:25 +0800 Subject: [PATCH 326/361] feat: update test package.yaml --- .github/workflows/test packages.yml | 2 +- packages/workspace/src/context/base-context.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test packages.yml b/.github/workflows/test packages.yml index 573a1ade01..45fa665465 100644 --- a/.github/workflows/test packages.yml +++ b/.github/workflows/test packages.yml @@ -123,7 +123,7 @@ jobs: - name: test run: cd packages/editor-core && npm test - test-plugin-command + test-plugin-command: runs-on: ubuntu-latest steps: - name: checkout diff --git a/packages/workspace/src/context/base-context.ts b/packages/workspace/src/context/base-context.ts index db33597aea..445677a618 100644 --- a/packages/workspace/src/context/base-context.ts +++ b/packages/workspace/src/context/base-context.ts @@ -96,7 +96,7 @@ export class BasicContext implements IBasicContext { designer: IDesigner; registerInnerPlugins: () => Promise<void>; innerSetters: InnerSetters; - innerSkeleton: InnerSkeleton; + innerSkeleton: ISkeleton; innerHotkey: IHotKey; innerPlugins: ILowCodePluginManager; canvas: IPublicApiCanvas; From 76b2a0504959972b38d75fb97101a0ebe2426cc9 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 1 Feb 2024 16:01:36 +0800 Subject: [PATCH 327/361] docs(command): add command api docs --- docs/docs/api/canvas.md | 2 +- docs/docs/api/command.md | 101 ++++++++++++++++++++++++++++ docs/docs/api/common.md | 2 +- docs/docs/api/commonUI.md | 2 +- docs/docs/api/config.md | 2 +- docs/docs/api/configOptions.md | 2 +- docs/docs/api/event.md | 2 +- docs/docs/api/hotkey.md | 2 +- docs/docs/api/init.md | 2 +- docs/docs/api/logger.md | 2 +- docs/docs/api/material.md | 2 +- docs/docs/api/model/_category_.json | 2 +- docs/docs/api/plugins.md | 2 +- docs/docs/api/project.md | 2 +- docs/docs/api/setters.md | 2 +- docs/docs/api/simulatorHost.md | 2 +- docs/docs/api/skeleton.md | 2 +- docs/docs/api/workspace.md | 2 +- 18 files changed, 118 insertions(+), 17 deletions(-) create mode 100644 docs/docs/api/command.md diff --git a/docs/docs/api/canvas.md b/docs/docs/api/canvas.md index 582f2354b5..865b9ac311 100644 --- a/docs/docs/api/canvas.md +++ b/docs/docs/api/canvas.md @@ -1,6 +1,6 @@ --- title: canvas - 画布 API -sidebar_position: 12 +sidebar_position: 10 --- > **@types** [IPublicApiCanvas](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/canvas.ts)<br/> diff --git a/docs/docs/api/command.md b/docs/docs/api/command.md new file mode 100644 index 0000000000..fc36c8ad89 --- /dev/null +++ b/docs/docs/api/command.md @@ -0,0 +1,101 @@ +--- +title: command - 指令 API +sidebar_position: 10 +--- + + + +## 模块概览 + +该模块使得与命令系统的交互成为可能,提供了一种全面的方式来处理、执行和管理应用程序中的命令。 + + + +## 接口 + +### IPublicApiCommand + +与命令交互的接口。它提供了注册、注销、执行和管理命令的方法。 + + + +## 方法 + +### registerCommand + +注册一个新命令及其处理函数。 + +``` +typescriptCopy code +/** + * 注册一个新的命令及其处理程序。 + * @param command {IPublicTypeCommand} - 要注册的命令。 + */ +registerCommand(command: IPublicTypeCommand): void; +``` + +### unregisterCommand + +注销一个已存在的命令。 + +``` +typescriptCopy code +/** + * 注销一个已存在的命令。 + * @param name {string} - 要注销的命令的名称。 + */ +unregisterCommand(name: string): void; +``` + +### executeCommand + +根据名称和提供的参数执行命令,确保参数符合命令的定义。 + +``` +typescriptCopy code +/** + * 根据名称和提供的参数执行命令。 + * @param name {string} - 要执行的命令的名称。 + * @param args {IPublicTypeCommandHandlerArgs} - 命令的参数。 + */ +executeCommand(name: string, args?: IPublicTypeCommandHandlerArgs): void; +``` + +### batchExecuteCommand + +批量执行命令,在所有命令执行后进行重绘,历史记录中只记录一次。 + +``` +typescriptCopy code +/** + * 批量执行命令,随后进行重绘,历史记录中只记录一次。 + * @param commands {Array} - 命令对象的数组,包含名称和可选参数。 + */ +batchExecuteCommand(commands: { name: string; args?: IPublicTypeCommandHandlerArgs }[]): void; +``` + +### listCommands + +列出所有已注册的命令。 + +``` +typescriptCopy code +/** + * 列出所有已注册的命令。 + * @returns {IPublicTypeListCommand[]} - 已注册命令的数组。 + */ +listCommands(): IPublicTypeListCommand[]; +``` + +### onCommandError + +为命令执行过程中的错误注册错误处理回调函数。 + +``` +typescriptCopy code +/** + * 为命令执行过程中的错误注册一个回调函数。 + * @param callback {(name: string, error: Error) => void} - 错误处理的回调函数。 + */ +onCommandError(callback: (name: string, error: Error) => void): void; +``` diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index 1a70436adf..c278bf2ad8 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -1,6 +1,6 @@ --- title: common - 通用 API -sidebar_position: 11 +sidebar_position: 10 --- > **@types** [IPublicApiCommon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/common.ts)<br/> diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index c0bbda588e..45640051f2 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -1,6 +1,6 @@ --- title: commonUI - UI 组件库 -sidebar_position: 11 +sidebar_position: 10 --- ## 简介 diff --git a/docs/docs/api/config.md b/docs/docs/api/config.md index fb631a945f..414cfc979f 100644 --- a/docs/docs/api/config.md +++ b/docs/docs/api/config.md @@ -1,6 +1,6 @@ --- title: config - 配置 API -sidebar_position: 8 +sidebar_position: 5 --- > **@types** [IPublicModelEngineConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/engine-config.ts)<br/> diff --git a/docs/docs/api/configOptions.md b/docs/docs/api/configOptions.md index 67d2fae2c1..5d6e8d7abb 100644 --- a/docs/docs/api/configOptions.md +++ b/docs/docs/api/configOptions.md @@ -1,6 +1,6 @@ --- title: config options - 配置列表 -sidebar_position: 13 +sidebar_position: 5 --- > **@types** [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts)<br/> diff --git a/docs/docs/api/event.md b/docs/docs/api/event.md index 0919b41fd2..c2e86f7106 100644 --- a/docs/docs/api/event.md +++ b/docs/docs/api/event.md @@ -1,6 +1,6 @@ --- title: event - 事件 API -sidebar_position: 7 +sidebar_position: 10 --- > **@types** [IPublicApiEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/event.ts)<br/> diff --git a/docs/docs/api/hotkey.md b/docs/docs/api/hotkey.md index a244b94c27..be6a3033d0 100644 --- a/docs/docs/api/hotkey.md +++ b/docs/docs/api/hotkey.md @@ -1,6 +1,6 @@ --- title: hotkey - 快捷键 API -sidebar_position: 5 +sidebar_position: 10 --- > **@types** [IPublicApiHotkey](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/hotkey.ts)<br/> diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 55b116a579..dd84d9c00f 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -1,6 +1,6 @@ --- title: init - 初始化 API -sidebar_position: 10 +sidebar_position: 0 --- > **@since** v1.0.0 diff --git a/docs/docs/api/logger.md b/docs/docs/api/logger.md index 7493f34dc2..38d986258b 100644 --- a/docs/docs/api/logger.md +++ b/docs/docs/api/logger.md @@ -1,6 +1,6 @@ --- title: logger - 日志 API -sidebar_position: 9 +sidebar_position: 10 --- > **@types** [IPublicApiLogger](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/logger.ts)<br/> diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index b6ef070b2c..0e09441275 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -1,6 +1,6 @@ --- title: material - 物料 API -sidebar_position: 2 +sidebar_position: 10 --- > **@types** [IPublicApiMaterial](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/material.ts)<br/> diff --git a/docs/docs/api/model/_category_.json b/docs/docs/api/model/_category_.json index 5b1f74b36f..3afc4f79b5 100644 --- a/docs/docs/api/model/_category_.json +++ b/docs/docs/api/model/_category_.json @@ -1,6 +1,6 @@ { "label": "模型定义 Models", - "position": 14, + "position": 100, "collapsed": false, "collapsible": true } diff --git a/docs/docs/api/plugins.md b/docs/docs/api/plugins.md index e35411d3a8..df025f49e9 100644 --- a/docs/docs/api/plugins.md +++ b/docs/docs/api/plugins.md @@ -1,6 +1,6 @@ --- title: plugins - 插件 API -sidebar_position: 4 +sidebar_position: 2 --- > **@types** [IPublicApiPlugins](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/plugins.ts)<br/> > **@since** v1.0.0 diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index 49d3193858..54bd1474cf 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -1,6 +1,6 @@ --- title: project - 模型 API -sidebar_position: 3 +sidebar_position: 10 --- ## 模块简介 diff --git a/docs/docs/api/setters.md b/docs/docs/api/setters.md index cc7b6d429c..0d3435b3d3 100644 --- a/docs/docs/api/setters.md +++ b/docs/docs/api/setters.md @@ -1,6 +1,6 @@ --- title: setters - 设置器 API -sidebar_position: 6 +sidebar_position: 10 --- > **@types** [IPublicApiSetters](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/setters.ts)<br/> > **@since** v1.0.0 diff --git a/docs/docs/api/simulatorHost.md b/docs/docs/api/simulatorHost.md index c7f739f6b4..70eaca0220 100644 --- a/docs/docs/api/simulatorHost.md +++ b/docs/docs/api/simulatorHost.md @@ -1,6 +1,6 @@ --- title: simulatorHost - 模拟器 API -sidebar_position: 3 +sidebar_position: 10 --- > **@types** [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts)<br/> > **@since** v1.0.0 diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 0713546e19..396fad9e9e 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -1,6 +1,6 @@ --- title: skeleton - 面板 API -sidebar_position: 1 +sidebar_position: 10 --- > **@types** [IPublicApiSkeleton](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/skeleton.ts)<br/> > **@since** v1.0.0 diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 6d0714ae09..74f7d6950f 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -1,6 +1,6 @@ --- title: workspace - 应用级 API -sidebar_position: 12 +sidebar_position: 10 --- > **[@experimental](./#experimental)**<br/> From 501ad872c476faacf2bba8c25963b189e1a7cac3 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 1 Feb 2024 08:17:01 +0000 Subject: [PATCH 328/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index ce6a969c1f..7facd9db8b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.30", + "version": "1.2.31", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 19eb91725952d34fc90ba470fc639ad1fe60b102 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 1 Feb 2024 15:47:26 +0800 Subject: [PATCH 329/361] refactor(plugin-command): add plugin-command package --- packages/engine/package.json | 1 + packages/engine/src/engine-core.ts | 6 +++--- packages/plugin-command/jest.config.js | 22 ++++++++++++++++++++++ packages/plugin-command/package.json | 9 +++++++-- packages/plugin-command/src/index.ts | 8 +++++--- 5 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 packages/plugin-command/jest.config.js diff --git a/packages/engine/package.json b/packages/engine/package.json index 4b622eaa4b..fb2b42fd09 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -28,6 +28,7 @@ "@alilc/lowcode-shell": "1.3.1", "@alilc/lowcode-utils": "1.3.1", "@alilc/lowcode-workspace": "1.3.1", + "@alilc/lowcode-plugin-command": "1.3.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 5a2cbbc656..4dffa628bd 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -66,7 +66,7 @@ import { defaultPanelRegistry } from './inner-plugins/default-panel-registry'; import { shellModelFactory } from './modules/shell-model-factory'; import { builtinHotkey } from './inner-plugins/builtin-hotkey'; import { defaultContextMenu } from './inner-plugins/default-context-menu'; -import { defaultCommand } from '@alilc/lowcode-plugin-command'; +import { CommandPlugin } from '@alilc/lowcode-plugin-command'; import { OutlinePlugin } from '@alilc/lowcode-plugin-outline-pane'; export * from './modules/skeleton-types'; @@ -84,7 +84,7 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins await plugins.register(builtinHotkey); await plugins.register(registerDefaults, {}, { autoInit: true }); await plugins.register(defaultContextMenu); - await plugins.register(defaultCommand, {}); + await plugins.register(CommandPlugin, {}); return () => { plugins.delete(OutlinePlugin.pluginName); @@ -94,7 +94,7 @@ async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins plugins.delete(builtinHotkey.pluginName); plugins.delete(registerDefaults.pluginName); plugins.delete(defaultContextMenu.pluginName); - plugins.delete(defaultCommand.pluginName); + plugins.delete(CommandPlugin.pluginName); }; } diff --git a/packages/plugin-command/jest.config.js b/packages/plugin-command/jest.config.js new file mode 100644 index 0000000000..822a526b7d --- /dev/null +++ b/packages/plugin-command/jest.config.js @@ -0,0 +1,22 @@ +const fs = require('fs'); +const { join } = require('path'); +const esModules = [].join('|'); +const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.')); + +const jestConfig = { + transformIgnorePatterns: [ + `/node_modules/(?!${esModules})/`, + ], + moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], + collectCoverage: true, + collectCoverageFrom: [ + 'src/**/*.ts', + 'src/**/*.tsx', + ], +}; + +// 只对本仓库内的 pkg 做 mapping +jestConfig.moduleNameMapper = {}; +jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '<rootDir>/../$1/src'; + +module.exports = jestConfig; \ No newline at end of file diff --git a/packages/plugin-command/package.json b/packages/plugin-command/package.json index 3c84e265ec..5cdd99660f 100644 --- a/packages/plugin-command/package.json +++ b/packages/plugin-command/package.json @@ -5,13 +5,15 @@ "author": "liujuping <liujup@foxmail.com>", "homepage": "https://github.com/alibaba/lowcode-engine#readme", "license": "ISC", - "main": "lib/plugin-command.js", + "main": "lib/index.js", + "module": "es/index.js", "directories": { "lib": "lib", "test": "__tests__" }, "files": [ - "lib" + "lib", + "es" ], "publishConfig": { "access": "public" @@ -30,5 +32,8 @@ "dependencies": { "@alilc/lowcode-types": "^1.3.1", "@alilc/lowcode-utils": "^1.3.1" + }, + "devDependencies": { + "@alib/build-scripts": "^0.1.18" } } diff --git a/packages/plugin-command/src/index.ts b/packages/plugin-command/src/index.ts index 8e5d64ebcf..fa6f32b32d 100644 --- a/packages/plugin-command/src/index.ts +++ b/packages/plugin-command/src/index.ts @@ -2,7 +2,7 @@ import { IPublicModelPluginContext, IPublicTypePlugin } from '@alilc/lowcode-typ import { nodeCommand } from './node-command'; import { historyCommand } from './history-command'; -export const defaultCommand: IPublicTypePlugin = (ctx: IPublicModelPluginContext) => { +export const CommandPlugin: IPublicTypePlugin = (ctx: IPublicModelPluginContext) => { const { plugins } = ctx; return { @@ -17,7 +17,9 @@ export const defaultCommand: IPublicTypePlugin = (ctx: IPublicModelPluginContext }; }; -defaultCommand.pluginName = '___default_command___'; -defaultCommand.meta = { +CommandPlugin.pluginName = '___default_command___'; +CommandPlugin.meta = { commandScope: 'common', }; + +export default CommandPlugin; \ No newline at end of file From 86d50e094628602347e09864850d23b49153bb89 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Fri, 2 Feb 2024 17:45:25 +0800 Subject: [PATCH 330/361] fix(setter): params is not shell SettingField --- packages/designer/src/designer/setting/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/designer/setting/utils.ts b/packages/designer/src/designer/setting/utils.ts index 1e061f20ae..75ed1dfc1a 100644 --- a/packages/designer/src/designer/setting/utils.ts +++ b/packages/designer/src/designer/setting/utils.ts @@ -70,7 +70,7 @@ export class Transducer { } if (isDynamicSetter(setter) && isDynamic) { try { - setter = setter.call(context, context); + setter = setter.call(context.internalToShellField(), context.internalToShellField()); } catch (e) { console.error(e); } } From 44beb2a25ad57cbc4cc2c88c577c5467542a9fd4 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 7 Feb 2024 12:52:56 +0800 Subject: [PATCH 331/361] fix(workspace): fix workspace editorView is undefined --- packages/shell/src/api/material.ts | 8 +++++++- packages/shell/src/model/window.ts | 4 ++-- packages/workspace/src/window.ts | 25 ++++++++++++++++--------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/shell/src/api/material.ts b/packages/shell/src/api/material.ts index f0c37d8a4d..284b88fbbf 100644 --- a/packages/shell/src/api/material.ts +++ b/packages/shell/src/api/material.ts @@ -3,7 +3,7 @@ import { IDesigner, isComponentMeta, } from '@alilc/lowcode-designer'; -import { IPublicTypeAssetsJson } from '@alilc/lowcode-utils'; +import { IPublicTypeAssetsJson, getLogger } from '@alilc/lowcode-utils'; import { IPublicTypeComponentAction, IPublicTypeComponentMetadata, @@ -21,6 +21,8 @@ import { editorSymbol, designerSymbol } from '../symbols'; import { ComponentMeta as ShellComponentMeta } from '../model'; import { ComponentType } from 'react'; +const logger = getLogger({ level: 'warn', bizName: 'shell-material' }); + const innerEditorSymbol = Symbol('editor'); export class Material implements IPublicApiMaterial { private readonly [innerEditorSymbol]: IPublicModelEditor; @@ -31,6 +33,10 @@ export class Material implements IPublicApiMaterial { } const workspace: InnerWorkspace = globalContext.get('workspace'); if (workspace.isActive) { + if (!workspace.window.editor) { + logger.error('Material api 调用时机出现问题,请检查'); + return this[innerEditorSymbol]; + } return workspace.window.editor; } diff --git a/packages/shell/src/model/window.ts b/packages/shell/src/model/window.ts index 2b5e0dd8c3..1bc84e661c 100644 --- a/packages/shell/src/model/window.ts +++ b/packages/shell/src/model/window.ts @@ -48,8 +48,8 @@ export class Window implements IPublicModelWindow { } get currentEditorView() { - if (this[windowSymbol].editorView) { - return new EditorView(this[windowSymbol].editorView).toProxy() as any; + if (this[windowSymbol]._editorView) { + return new EditorView(this[windowSymbol]._editorView).toProxy() as any; } return null; } diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index ce5aab4142..cd64a9b112 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -17,7 +17,7 @@ export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'chan editorViews: Map<string, IViewContext>; - editorView: IViewContext; + _editorView: IViewContext; changeViewName: (name: string, ignoreEmit?: boolean) => void; @@ -54,7 +54,7 @@ export class EditorWindow implements IEditorWindow { url: string | undefined; - @obx.ref editorView: Context; + @obx.ref _editorView: Context; @obx editorViews: Map<string, Context> = new Map<string, Context>(); @@ -62,6 +62,13 @@ export class EditorWindow implements IEditorWindow { sleep: boolean | undefined; + get editorView() { + if (!this._editorView) { + return this.editorViews.values().next().value; + } + return this._editorView; + } + constructor(readonly resource: IResource, readonly workspace: IWorkspace, private config: IWindowCOnfig) { makeObservable(this); this.title = config.title; @@ -75,10 +82,10 @@ export class EditorWindow implements IEditorWindow { updateState(state: WINDOW_STATE): void { switch (state) { case WINDOW_STATE.active: - this.editorView?.setActivate(true); + this._editorView?.setActivate(true); break; case WINDOW_STATE.inactive: - this.editorView?.setActivate(false); + this._editorView?.setActivate(false); break; case WINDOW_STATE.destroyed: break; @@ -146,7 +153,7 @@ export class EditorWindow implements IEditorWindow { for (let i = 0; i < editorViews.length; i++) { const name = editorViews[i].viewName; await this.initViewType(name); - if (!this.editorView) { + if (!this._editorView) { this.changeViewName(name); } } @@ -190,14 +197,14 @@ export class EditorWindow implements IEditorWindow { }; changeViewName = (name: string, ignoreEmit: boolean = true) => { - this.editorView?.setActivate(false); - this.editorView = this.editorViews.get(name)!; + this._editorView?.setActivate(false); + this._editorView = this.editorViews.get(name)!; - if (!this.editorView) { + if (!this._editorView) { return; } - this.editorView.setActivate(true); + this._editorView.setActivate(true); if (!ignoreEmit) { this.emitter.emit('window.change.view.type', name); From bd85ca3ca6adc89a5ed67644f1f14322e512db72 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 23 Feb 2024 01:51:23 +0000 Subject: [PATCH 332/361] chore(release): publish 1.3.2 --- lerna.json | 2 +- packages/designer/package.json | 8 ++++---- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 20 +++++++++---------- packages/ignitor/package.json | 2 +- packages/plugin-command/package.json | 6 +++--- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 6 +++--- packages/react-renderer/package.json | 4 ++-- .../react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 14 ++++++------- packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/workspace/package.json | 12 +++++------ 16 files changed, 61 insertions(+), 61 deletions(-) diff --git a/lerna.json b/lerna.json index 7de339c6cd..7fad993f66 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.3.1", + "version": "1.3.2", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index ec7c153c80..97256d3a21 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.3.1", + "version": "1.3.2", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.3.1", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-editor-core": "1.3.2", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 98644ad3d6..55f6d50c39 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.3.1", + "version": "1.3.2", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 7c14943552..63aab7e48b 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.3.1", + "version": "1.3.2", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.3.1", - "@alilc/lowcode-editor-core": "1.3.1", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", + "@alilc/lowcode-editor-core": "1.3.2", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index fb2b42fd09..23b3521213 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.3.1", + "version": "1.3.2", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,16 +19,16 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.3.1", - "@alilc/lowcode-editor-core": "1.3.1", - "@alilc/lowcode-editor-skeleton": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", + "@alilc/lowcode-editor-core": "1.3.2", + "@alilc/lowcode-editor-skeleton": "1.3.2", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.3.1", - "@alilc/lowcode-plugin-outline-pane": "1.3.1", - "@alilc/lowcode-shell": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", - "@alilc/lowcode-workspace": "1.3.1", - "@alilc/lowcode-plugin-command": "1.3.1", + "@alilc/lowcode-plugin-command": "1.3.2", + "@alilc/lowcode-plugin-designer": "1.3.2", + "@alilc/lowcode-plugin-outline-pane": "1.3.2", + "@alilc/lowcode-shell": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", + "@alilc/lowcode-workspace": "1.3.2", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index a32e30783f..0b109a7ad7 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.3.1", + "version": "1.3.2", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-command/package.json b/packages/plugin-command/package.json index 5cdd99660f..4f53e69e36 100644 --- a/packages/plugin-command/package.json +++ b/packages/plugin-command/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-command", - "version": "1.3.1", + "version": "1.3.2", "description": "> TODO: description", "author": "liujuping <liujup@foxmail.com>", "homepage": "https://github.com/alibaba/lowcode-engine#readme", @@ -30,8 +30,8 @@ "url": "https://github.com/alibaba/lowcode-engine/issues" }, "dependencies": { - "@alilc/lowcode-types": "^1.3.1", - "@alilc/lowcode-utils": "^1.3.1" + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2" }, "devDependencies": { "@alib/build-scripts": "^0.1.18" diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 9fb9a75655..ac25097c78 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.3.1", + "version": "1.3.2", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.3.1", - "@alilc/lowcode-editor-core": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", + "@alilc/lowcode-editor-core": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 1539ac6ae3..f50f71cbfe 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.3.1", + "version": "1.3.2", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,8 +13,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index b041823e85..625801bc25 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.3.1", + "version": "1.3.2", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.3.1" + "@alilc/lowcode-renderer-core": "1.3.2" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 1361535099..3c3950a124 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.3.1", + "version": "1.3.2", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.3.1", - "@alilc/lowcode-react-renderer": "1.3.1", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", + "@alilc/lowcode-react-renderer": "1.3.2", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index dd48d361f1..199eac1cac 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.3.1", + "version": "1.3.2", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -32,7 +32,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.11", diff --git a/packages/shell/package.json b/packages/shell/package.json index 87f71a5ee6..c2b62e2270 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.3.1", + "version": "1.3.2", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -13,12 +13,12 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.3.1", - "@alilc/lowcode-editor-core": "1.3.1", - "@alilc/lowcode-editor-skeleton": "1.3.1", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", - "@alilc/lowcode-workspace": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", + "@alilc/lowcode-editor-core": "1.3.2", + "@alilc/lowcode-editor-skeleton": "1.3.2", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", + "@alilc/lowcode-workspace": "1.3.2", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 31dadb5ea0..5651d427d4 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.3.1", + "version": "1.3.2", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index cc363a7292..60605d81e7 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.3.1", + "version": "1.3.2", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.3.1", + "@alilc/lowcode-types": "1.3.2", "lodash": "^4.17.21", "mobx": "^6.3.0", "prop-types": "^15.8.1", diff --git a/packages/workspace/package.json b/packages/workspace/package.json index 7af4a7159c..778b8167f8 100644 --- a/packages/workspace/package.json +++ b/packages/workspace/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-workspace", - "version": "1.3.1", + "version": "1.3.2", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.3.1", - "@alilc/lowcode-editor-core": "1.3.1", - "@alilc/lowcode-editor-skeleton": "1.3.1", - "@alilc/lowcode-types": "1.3.1", - "@alilc/lowcode-utils": "1.3.1", + "@alilc/lowcode-designer": "1.3.2", + "@alilc/lowcode-editor-core": "1.3.2", + "@alilc/lowcode-editor-skeleton": "1.3.2", + "@alilc/lowcode-types": "1.3.2", + "@alilc/lowcode-utils": "1.3.2", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", From 699abd69fb30aff1f8506f3db4ab53965350e897 Mon Sep 17 00:00:00 2001 From: webstar <814566123@qq.com> Date: Fri, 23 Feb 2024 17:48:16 +0800 Subject: [PATCH 333/361] docs: add star history to README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add star history to README。 --- packages/engine/README-zh_CN.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 5442aa58bd..f534bef0ac 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -169,6 +169,12 @@ lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-de 关于提交 PR: 请将目标合并分支设置为 **develop**,不要指定 **main** 分支,在发布正式版本后,develop 分支将会合入 main 分支。 +## ⭐️ Star 历史 + +<a href="https://star-history.com/#alibaba/lowcode-engine"> + <img src="https://api.star-history.com/svg?repos=alibaba/lowcode-engine&type=Date" alt="Star History Chart" width="100%" /> +</a> + ## ❤️ 致谢 感谢所有为引擎项目贡献力量的同学们~ From 1e72c434591b623845e973843d3d5d65a509aba7 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?= <liujup@foxmail.com> Date: Mon, 26 Feb 2024 15:00:01 +0800 Subject: [PATCH 334/361] Update command.md --- docs/docs/api/command.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/docs/api/command.md b/docs/docs/api/command.md index fc36c8ad89..d1b8ad9920 100644 --- a/docs/docs/api/command.md +++ b/docs/docs/api/command.md @@ -25,8 +25,7 @@ sidebar_position: 10 注册一个新命令及其处理函数。 -``` -typescriptCopy code +```typescript /** * 注册一个新的命令及其处理程序。 * @param command {IPublicTypeCommand} - 要注册的命令。 @@ -38,8 +37,7 @@ registerCommand(command: IPublicTypeCommand): void; 注销一个已存在的命令。 -``` -typescriptCopy code +```typescript /** * 注销一个已存在的命令。 * @param name {string} - 要注销的命令的名称。 @@ -51,8 +49,7 @@ unregisterCommand(name: string): void; 根据名称和提供的参数执行命令,确保参数符合命令的定义。 -``` -typescriptCopy code +```typescript /** * 根据名称和提供的参数执行命令。 * @param name {string} - 要执行的命令的名称。 @@ -65,8 +62,7 @@ executeCommand(name: string, args?: IPublicTypeCommandHandlerArgs): void; 批量执行命令,在所有命令执行后进行重绘,历史记录中只记录一次。 -``` -typescriptCopy code +```typescript /** * 批量执行命令,随后进行重绘,历史记录中只记录一次。 * @param commands {Array} - 命令对象的数组,包含名称和可选参数。 @@ -78,8 +74,7 @@ batchExecuteCommand(commands: { name: string; args?: IPublicTypeCommandHandlerAr 列出所有已注册的命令。 -``` -typescriptCopy code +```typescript /** * 列出所有已注册的命令。 * @returns {IPublicTypeListCommand[]} - 已注册命令的数组。 @@ -91,8 +86,7 @@ listCommands(): IPublicTypeListCommand[]; 为命令执行过程中的错误注册错误处理回调函数。 -``` -typescriptCopy code +```typescript /** * 为命令执行过程中的错误注册一个回调函数。 * @param callback {(name: string, error: Error) => void} - 错误处理的回调函数。 From dbd9382117a7e394830a850ae94940ed026811a2 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Mon, 26 Feb 2024 07:02:35 +0000 Subject: [PATCH 335/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 7facd9db8b..574ff28787 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.31", + "version": "1.2.32", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 0d92011863b52b87a8657ba53c2ac2ed97c5ef79 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Tue, 27 Feb 2024 10:51:03 +0800 Subject: [PATCH 336/361] chore: update ts defined --- packages/designer/src/context-menu-actions.ts | 36 ++-- .../designer/src/designer/designer-view.tsx | 6 +- packages/designer/src/designer/designer.ts | 80 ++------ packages/designer/src/designer/dragon.ts | 14 +- .../designer/src/designer/offset-observer.ts | 34 ++-- .../designer/src/document/document-model.ts | 128 +++---------- .../src/document/node/node-children.ts | 89 +++------ packages/designer/src/document/node/node.ts | 171 ++++-------------- .../designer/src/document/node/props/prop.ts | 6 +- .../designer/src/document/node/props/props.ts | 25 +-- .../designer/src/plugin/plugin-context.ts | 2 + packages/editor-skeleton/src/skeleton.ts | 87 +++------ packages/engine/src/engine-core.ts | 2 +- .../src/utils/misc.ts | 51 +++--- packages/shell/src/api/workspace.ts | 4 +- packages/shell/src/model/resource.ts | 2 +- packages/types/src/shell/api/common.ts | 4 +- .../types/src/shell/model/document-model.ts | 2 +- packages/types/src/shell/model/prop.ts | 4 +- packages/types/src/shell/model/resource.ts | 4 +- packages/types/src/shell/type/metadata.ts | 2 +- .../types/src/shell/type/props-transducer.ts | 6 +- .../src/shell/type/widget-base-config.ts | 2 +- packages/utils/src/is-plain-object.ts | 2 +- .../src/__snapshots__/is-react.test.tsx.snap | 0 .../src/__snapshots__/schema.test.ts.snap | 0 .../build-components/buildComponents.test.tsx | 0 .../build-components/getProjectUtils.test.ts | 0 .../build-components/getSubComponent.test.ts | 0 .../src/check-prop-types.test.ts | 0 .../is-action-content-object.test.ts | 0 .../check-types/is-basic-prop-type.test.ts | 0 .../src/check-types/is-custom-view.test.tsx | 0 .../src/check-types/is-dom-text.test.ts | 0 .../check-types/is-drag-any-object.test.ts | 0 .../is-drag-node-data-object.test.ts | 0 .../check-types/is-drag-node-object.test.ts | 0 .../src/check-types/is-dynamic-setter.test.ts | 0 .../src/check-types/is-i18n-data.test.ts | 0 .../src/check-types/is-isfunction.test.ts | 0 .../src/check-types/is-jsblock.test.ts | 0 .../src/check-types/is-jsexpression.test.ts | 0 .../src/check-types/is-jsslot.test.ts | 0 .../is-location-children-detail.test.ts | 0 .../src/check-types/is-location-data.test.ts | 0 .../is-lowcode-component-type.test.ts | 0 .../is-lowcode-project-schema.test.ts | 0 .../src/check-types/is-node-schema.test.ts | 0 .../src/check-types/is-node.test.ts | 0 .../is-procode-component-type.test.ts | 0 .../src/check-types/is-project-schema.test.ts | 0 .../check-types/is-required-prop-type.test.ts | 0 .../src/check-types/is-setter-config.test.ts | 0 .../src/check-types/is-setting-field.test.ts | 0 .../src/check-types/is-title-config.test.ts | 0 .../{test => tests}/src/clone-deep.test.ts | 0 .../src/clone-enumerable-property.test.ts | 0 .../src/create-content.test.tsx | 0 .../{test => tests}/src/create-defer.test.ts | 0 .../{test => tests}/src/is-object.test.ts | 0 .../{test => tests}/src/is-react.test.tsx | 0 .../{test => tests}/src/is-shaken.test.ts | 0 .../utils/{test => tests}/src/misc.test.ts | 0 .../src/navtive-selection.test.ts | 0 .../utils/{test => tests}/src/schema.test.ts | 0 .../utils/{test => tests}/src/script.test.ts | 0 .../{test => tests}/src/svg-icon.test.tsx | 0 .../src/transaction-manager.test.ts | 0 .../{test => tests}/src/unique-id.test.ts | 0 .../workspace/src/context/base-context.ts | 26 +-- packages/workspace/src/resource-type.ts | 10 +- packages/workspace/src/resource.ts | 27 +-- packages/workspace/src/view/window-view.tsx | 4 +- packages/workspace/src/window.ts | 22 +-- packages/workspace/src/workspace.ts | 57 +----- 75 files changed, 226 insertions(+), 683 deletions(-) rename packages/utils/{test => tests}/src/__snapshots__/is-react.test.tsx.snap (100%) rename packages/utils/{test => tests}/src/__snapshots__/schema.test.ts.snap (100%) rename packages/utils/{test => tests}/src/build-components/buildComponents.test.tsx (100%) rename packages/utils/{test => tests}/src/build-components/getProjectUtils.test.ts (100%) rename packages/utils/{test => tests}/src/build-components/getSubComponent.test.ts (100%) rename packages/utils/{test => tests}/src/check-prop-types.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-action-content-object.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-basic-prop-type.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-custom-view.test.tsx (100%) rename packages/utils/{test => tests}/src/check-types/is-dom-text.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-drag-any-object.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-drag-node-data-object.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-drag-node-object.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-dynamic-setter.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-i18n-data.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-isfunction.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-jsblock.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-jsexpression.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-jsslot.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-location-children-detail.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-location-data.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-lowcode-component-type.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-lowcode-project-schema.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-node-schema.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-node.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-procode-component-type.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-project-schema.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-required-prop-type.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-setter-config.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-setting-field.test.ts (100%) rename packages/utils/{test => tests}/src/check-types/is-title-config.test.ts (100%) rename packages/utils/{test => tests}/src/clone-deep.test.ts (100%) rename packages/utils/{test => tests}/src/clone-enumerable-property.test.ts (100%) rename packages/utils/{test => tests}/src/create-content.test.tsx (100%) rename packages/utils/{test => tests}/src/create-defer.test.ts (100%) rename packages/utils/{test => tests}/src/is-object.test.ts (100%) rename packages/utils/{test => tests}/src/is-react.test.tsx (100%) rename packages/utils/{test => tests}/src/is-shaken.test.ts (100%) rename packages/utils/{test => tests}/src/misc.test.ts (100%) rename packages/utils/{test => tests}/src/navtive-selection.test.ts (100%) rename packages/utils/{test => tests}/src/schema.test.ts (100%) rename packages/utils/{test => tests}/src/script.test.ts (100%) rename packages/utils/{test => tests}/src/svg-icon.test.tsx (100%) rename packages/utils/{test => tests}/src/transaction-manager.test.ts (100%) rename packages/utils/{test => tests}/src/unique-id.test.ts (100%) diff --git a/packages/designer/src/context-menu-actions.ts b/packages/designer/src/context-menu-actions.ts index c88e03ac65..3b0283fc40 100644 --- a/packages/designer/src/context-menu-actions.ts +++ b/packages/designer/src/context-menu-actions.ts @@ -5,18 +5,6 @@ import { Menu } from '@alifd/next'; import { engineConfig } from '@alilc/lowcode-editor-core'; import './context-menu-actions.scss'; -export interface IContextMenuActions { - actions: IPublicTypeContextMenuAction[]; - - adjustMenuLayoutFn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]; - - addMenuAction: IPublicApiMaterial['addContextMenuOption']; - - removeMenuAction: IPublicApiMaterial['removeContextMenuOption']; - - adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout']; -} - let adjustMenuLayoutFn: Function = (actions: IPublicTypeContextMenuAction[]) => actions; export class GlobalContextMenuActions { @@ -116,7 +104,7 @@ export class GlobalContextMenuActions { const globalContextMenuActions = new GlobalContextMenuActions(); -export class ContextMenuActions implements IContextMenuActions { +export class ContextMenuActions { actions: IPublicTypeContextMenuAction[] = []; designer: IDesigner; @@ -204,30 +192,32 @@ export class ContextMenuActions implements IContextMenuActions { originalEvent.stopPropagation(); originalEvent.preventDefault(); // 如果右键的节点不在 当前选中的节点中,选中该节点 - if (!designer.currentSelection.has(node.id)) { - designer.currentSelection.select(node.id); + if (!designer.currentSelection?.has(node.id)) { + designer.currentSelection?.select(node.id); } - const nodes = designer.currentSelection.getNodes(); + const nodes = designer.currentSelection?.getNodes(); this.handleContextMenu(nodes, originalEvent); }), ); } - addMenuAction(action: IPublicTypeContextMenuAction) { + addMenuAction: IPublicApiMaterial['addContextMenuOption'] = (action: IPublicTypeContextMenuAction) => { this.actions.push({ type: IPublicEnumContextMenuType.MENU_ITEM, ...action, }); - } + }; - removeMenuAction(name: string) { + removeMenuAction: IPublicApiMaterial['removeContextMenuOption'] = (name: string) => { const i = this.actions.findIndex((action) => action.name === name); if (i > -1) { this.actions.splice(i, 1); } - } + }; - adjustMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) { + adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout'] = (fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) => { adjustMenuLayoutFn = fn; - } -} \ No newline at end of file + }; +} + +export interface IContextMenuActions extends ContextMenuActions {} \ No newline at end of file diff --git a/packages/designer/src/designer/designer-view.tsx b/packages/designer/src/designer/designer-view.tsx index aaf0c9583e..851decf14a 100644 --- a/packages/designer/src/designer/designer-view.tsx +++ b/packages/designer/src/designer/designer-view.tsx @@ -1,16 +1,16 @@ import { Component } from 'react'; import classNames from 'classnames'; import BuiltinDragGhostComponent from './drag-ghost'; -import { Designer, DesignerProps } from './designer'; +import { Designer, DesignerProps, IDesigner } from './designer'; import { ProjectView } from '../project'; import './designer.less'; type IProps = DesignerProps & { - designer?: Designer; + designer?: IDesigner; }; export class DesignerView extends Component<IProps> { - readonly designer: Designer; + readonly designer: IDesigner; readonly viewName: string | undefined; constructor(props: IProps) { diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 1dd4bc04e6..48c163493c 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -6,7 +6,6 @@ import { IPublicTypeComponentAction, IPublicTypeNpmInfo, IPublicModelEditor, - IPublicTypeCompositeObject, IPublicTypePropsList, IPublicTypeNodeSchema, IPublicTypePropsTransducer, @@ -17,15 +16,16 @@ import { IPublicTypeLocationData, IPublicEnumTransformStage, IPublicModelLocateEvent, + IPublicTypePropsMap, } from '@alilc/lowcode-types'; import { mergeAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { IProject, Project } from '../project'; -import { Node, DocumentModel, insertChildren, INode, ISelection } from '../document'; +import { Node, DocumentModel, insertChildren, INode } from '../document'; import { ComponentMeta, IComponentMeta } from '../component-meta'; import { INodeSelector, Component } from '../simulator'; import { Scroller } from './scroller'; import { Dragon, IDragon } from './dragon'; -import { ActiveTracker, IActiveTracker } from './active-tracker'; +import { ActiveTracker } from './active-tracker'; import { Detecting } from './detecting'; import { DropLocation } from './location'; import { OffsetObserver, createOffsetObserver } from './offset-observer'; @@ -47,7 +47,7 @@ export interface DesignerProps { viewName?: string; simulatorProps?: Record<string, any> | ((document: DocumentModel) => object); simulatorComponent?: ComponentType<any>; - dragGhostComponent?: ComponentType<any>; + dragGhostComponent?: ComponentType<{ designer: IDesigner }>; suspensed?: boolean; componentMetadatas?: IPublicTypeComponentMetadata[]; globalComponentActions?: IPublicTypeComponentAction[]; @@ -60,70 +60,10 @@ export interface DesignerProps { ) => void; } -export interface IDesigner { - readonly shellModelFactory: IShellModelFactory; - - viewName: string | undefined; - - readonly project: IProject; - - get dragon(): IDragon; - - get activeTracker(): IActiveTracker; - - get componentActions(): ComponentActions; - - get contextMenuActions(): ContextMenuActions; - - get editor(): IPublicModelEditor; - - get detecting(): Detecting; - - get simulatorComponent(): ComponentType<any> | undefined; - - get currentSelection(): ISelection; - - createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller; - - refreshComponentMetasMap(): void; - - createOffsetObserver(nodeInstance: INodeSelector): OffsetObserver | null; - - /** - * 创建插入位置,考虑放到 dragon 中 - */ - createLocation(locationData: IPublicTypeLocationData<INode>): DropLocation; - - get componentsMap(): { [key: string]: IPublicTypeNpmInfo | Component }; - - loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): Promise<void>; - - getComponentMeta( - componentName: string, - generateMetadata?: () => IPublicTypeComponentMetadata | null, - ): IComponentMeta; - - clearLocation(): void; - - createComponentMeta(data: IPublicTypeComponentMetadata): IComponentMeta | null; - - getComponentMetasMap(): Map<string, IComponentMeta>; - - addPropsReducer(reducer: IPublicTypePropsTransducer, stage: IPublicEnumTransformStage): void; - - postEvent(event: string, ...args: any[]): void; - - transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypeCompositeObject | IPublicTypePropsList; - - createSettingEntry(nodes: INode[]): ISettingTopEntry; - - autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions<any, any>): IReactionDisposer; -} - -export class Designer implements IDesigner { +export class Designer { dragon: IDragon; - viewName: string | undefined; + readonly viewName: string | undefined; readonly componentActions = new ComponentActions(); @@ -423,7 +363,7 @@ export class Designer implements IDesigner { if (props.simulatorProps !== this.props.simulatorProps) { this._simulatorProps = props.simulatorProps; // 重新 setupSelection - if (props.simulatorProps?.designMode !== this.props.simulatorProps?.designMode) { + if ((props.simulatorProps as any)?.designMode !== (this.props.simulatorProps as any)?.designMode) { this.setupSelection(); } } @@ -612,7 +552,7 @@ export class Designer implements IDesigner { return maps; } - transformProps(props: IPublicTypeCompositeObject | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage) { + transformProps(props: IPublicTypePropsMap | IPublicTypePropsList, node: Node, stage: IPublicEnumTransformStage): IPublicTypePropsMap | IPublicTypePropsList { if (Array.isArray(props)) { // current not support, make this future return props; @@ -623,7 +563,7 @@ export class Designer implements IDesigner { return props; } - return reducers.reduce((xprops, reducer) => { + return reducers.reduce((xprops, reducer: IPublicTypePropsTransducer) => { try { return reducer(xprops, node.internalToShellNode() as any, { stage }); } catch (e) { @@ -655,3 +595,5 @@ export class Designer implements IDesigner { // TODO: } } + +export interface IDesigner extends Designer {} diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index 8dcce2b4a2..5c4d0648d4 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -95,17 +95,13 @@ function isDragEvent(e: any): e is DragEvent { return e?.type?.startsWith('drag'); } -export interface IDragon extends IPublicModelDragon< - INode, - ILocateEvent -> { - emitter: IEventBus; -} - /** * Drag-on 拖拽引擎 */ -export class Dragon implements IDragon { +export class Dragon implements IPublicModelDragon< + INode, + ILocateEvent +> { private sensors: IPublicModelSensor[] = []; private nodeInstPointerEvents: boolean; @@ -637,3 +633,5 @@ export class Dragon implements IDragon { }; } } + +export interface IDragon extends Dragon { } diff --git a/packages/designer/src/designer/offset-observer.ts b/packages/designer/src/designer/offset-observer.ts index 2cf5bfee26..3c37be02d9 100644 --- a/packages/designer/src/designer/offset-observer.ts +++ b/packages/designer/src/designer/offset-observer.ts @@ -28,11 +28,11 @@ export class OffsetObserver { @obx private _bottom = 0; @computed get height() { - return this.isRoot ? this.viewport.height : this._height * this.scale; + return this.isRoot ? this.viewport?.height : this._height * this.scale; } @computed get width() { - return this.isRoot ? this.viewport.width : this._width * this.scale; + return this.isRoot ? this.viewport?.width : this._width * this.scale; } @computed get top() { @@ -44,51 +44,51 @@ export class OffsetObserver { } @computed get bottom() { - return this.isRoot ? this.viewport.height : this._bottom * this.scale; + return this.isRoot ? this.viewport?.height : this._bottom * this.scale; } @computed get right() { - return this.isRoot ? this.viewport.width : this._right * this.scale; + return this.isRoot ? this.viewport?.width : this._right * this.scale; } @obx hasOffset = false; @computed get offsetLeft() { if (this.isRoot) { - return this.viewport.scrollX * this.scale; + return (this.viewport?.scrollX || 0) * this.scale; } - if (!this.viewport.scrolling || this.lastOffsetLeft == null) { - this.lastOffsetLeft = this.left + this.viewport.scrollX * this.scale; + if (!this.viewport?.scrolling || this.lastOffsetLeft == null) { + this.lastOffsetLeft = this.left + (this.viewport?.scrollX || 0) * this.scale; } return this.lastOffsetLeft; } @computed get offsetTop() { if (this.isRoot) { - return this.viewport.scrollY * this.scale; + return (this.viewport?.scrollY || 0) * this.scale; } - if (!this.viewport.scrolling || this.lastOffsetTop == null) { - this.lastOffsetTop = this.top + this.viewport.scrollY * this.scale; + if (!this.viewport?.scrolling || this.lastOffsetTop == null) { + this.lastOffsetTop = this.top + (this.viewport?.scrollY || 0) * this.scale; } return this.lastOffsetTop; } @computed get offsetHeight() { - if (!this.viewport.scrolling || this.lastOffsetHeight == null) { - this.lastOffsetHeight = this.isRoot ? this.viewport.height : this.height; + if (!this.viewport?.scrolling || this.lastOffsetHeight == null) { + this.lastOffsetHeight = this.isRoot ? (this.viewport?.height || 0) : this.height; } return this.lastOffsetHeight; } @computed get offsetWidth() { - if (!this.viewport.scrolling || this.lastOffsetWidth == null) { - this.lastOffsetWidth = this.isRoot ? this.viewport.width : this.width; + if (!(this.viewport?.scrolling || 0) || this.lastOffsetWidth == null) { + this.lastOffsetWidth = this.isRoot ? (this.viewport?.width || 0) : this.width; } return this.lastOffsetWidth; } @computed get scale() { - return this.viewport.scale; + return this.viewport?.scale || 0; } private pid: number | undefined; @@ -124,11 +124,11 @@ export class OffsetObserver { return; } - const rect = host.computeComponentInstanceRect(instance!, node.componentMeta.rootSelector); + const rect = host?.computeComponentInstanceRect(instance!, node.componentMeta.rootSelector); if (!rect) { this.hasOffset = false; - } else if (!this.viewport.scrolling || !this.hasOffset) { + } else if (!this.viewport?.scrolling || !this.hasOffset) { this._height = rect.height; this._width = rect.width; this._left = rect.left; diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index edca8fd818..2938395a97 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -56,104 +56,30 @@ export type GetDataType<T, NodeType> = T extends undefined : any : T; -export interface IDocumentModel extends Omit<IPublicModelDocumentModel< - ISelection, - IHistory, - INode, - IDropLocation, - IModalNodesManager, - IProject +export class DocumentModel implements Omit<IPublicModelDocumentModel< +ISelection, +IHistory, +INode, +IDropLocation, +IModalNodesManager, +IProject >, - 'detecting' | - 'checkNesting' | - 'getNodeById' | - // 以下属性在内部的 document 中不存在 - 'exportSchema' | - 'importSchema' | - 'onAddNode' | - 'onRemoveNode' | - 'onChangeDetecting' | - 'onChangeSelection' | - 'onChangeNodeProp' | - 'onImportSchema' | - 'isDetectingNode' | - 'onFocusNodeChanged' | - 'onDropLocationChanged' +'detecting' | +'checkNesting' | +'getNodeById' | +// 以下属性在内部的 document 中不存在 +'exportSchema' | +'importSchema' | +'onAddNode' | +'onRemoveNode' | +'onChangeDetecting' | +'onChangeSelection' | +'onChangeNodeProp' | +'onImportSchema' | +'isDetectingNode' | +'onFocusNodeChanged' | +'onDropLocationChanged' > { - - readonly designer: IDesigner; - - selection: ISelection; - - get rootNode(): INode | null; - - get simulator(): ISimulatorHost | null; - - get active(): boolean; - - get nodesMap(): Map<string, INode>; - - /** - * 是否为非激活状态 - */ - get suspensed(): boolean; - - get fileName(): string; - - get currentRoot(): INode | null; - - isBlank(): boolean; - - /** - * 根据 id 获取节点 - */ - getNode(id: string): INode | null; - - getRoot(): INode | null; - - getHistory(): IHistory; - - checkNesting( - dropTarget: INode, - dragObject: IPublicTypeDragNodeObject | IPublicTypeNodeSchema | INode | IPublicTypeDragNodeDataObject, - ): boolean; - - getNodeCount(): number; - - nextId(possibleId: string | undefined): string; - - import(schema: IPublicTypeRootSchema, checkId?: boolean): void; - - export(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined; - - onNodeCreate(func: (node: INode) => void): IPublicTypeDisposable; - - onNodeDestroy(func: (node: INode) => void): IPublicTypeDisposable; - - onChangeNodeVisible(fn: (node: INode, visible: boolean) => void): IPublicTypeDisposable; - - addWillPurge(node: INode): void; - - removeWillPurge(node: INode): void; - - getComponentMeta(componentName: string): IComponentMeta; - - insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean): INode[]; - - open(): IDocumentModel; - - remove(): void; - - suspense(): void; - - close(): void; - - unlinkNode(node: INode): void; - - destroyNode(node: INode): void; -} - -export class DocumentModel implements IDocumentModel { /** * 根节点 类型有:Page/Component/Block */ @@ -322,7 +248,7 @@ export class DocumentModel implements IDocumentModel { // 兼容 vision this.id = project.getSchema()?.id || this.id; - this.rootNode = this.createNode( + this.rootNode = this.createNode<IRootNode, IPublicTypeRootSchema>( schema || { componentName: 'Page', id: 'root', @@ -425,7 +351,7 @@ export class DocumentModel implements IDocumentModel { * 根据 schema 创建一个节点 */ @action - createNode<T extends INode = INode, C = undefined>(data: GetDataType<C, T>): T { + createNode<T = INode, S = IPublicTypeNodeSchema>(data: S): T { let schema: any; if (isDOMText(data) || isJSExpression(data)) { schema = { @@ -529,7 +455,7 @@ export class DocumentModel implements IDocumentModel { return null; } const wrapper = this.createNode(schema); - if (wrapper.isParental()) { + if (wrapper?.isParental()) { const first = nodes[0]; // TODO: check nesting rules x 2 insertChild(first.parent!, wrapper, first.index); @@ -538,7 +464,7 @@ export class DocumentModel implements IDocumentModel { return wrapper; } - this.removeNode(wrapper); + wrapper && this.removeNode(wrapper); return null; } @@ -928,3 +854,5 @@ export function isDocumentModel(obj: any): obj is IDocumentModel { export function isPageSchema(obj: any): obj is IPublicTypePageSchema { return obj?.componentName === 'Page'; } + +export interface IDocumentModel extends DocumentModel {} \ No newline at end of file diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 65210fe62c..b7f03d9fee 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -10,63 +10,12 @@ export interface IOnChangeOptions { node: Node; } -export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>, - 'importSchema' | - 'exportSchema' | - 'isEmpty' | - 'notEmpty' +export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, +'importSchema' | +'exportSchema' | +'isEmpty' | +'notEmpty' > { - children: INode[]; - - get owner(): INode; - - get length(): number; - - unlinkChild(node: INode): void; - - /** - * 删除一个节点 - */ - internalDelete( - node: INode, - purge: boolean, - useMutator: boolean, - options: NodeRemoveOptions - ): boolean; - - /** - * 插入一个节点,返回新长度 - */ - internalInsert(node: INode, at?: number | null, useMutator?: boolean): void; - - import(data?: IPublicTypeNodeData | IPublicTypeNodeData[], checkId?: boolean): void; - - /** - * 导出 schema - */ - export(stage: IPublicEnumTransformStage): IPublicTypeNodeData[]; - - /** following methods are overriding super interface, using different param types */ - /** overriding methods start */ - - forEach(fn: (item: INode, index: number) => void): void; - - /** - * 根据索引获得节点 - */ - get(index: number): INode | null; - - isEmpty(): boolean; - - notEmpty(): boolean; - - internalInitParent(): void; - - onChange(fn: (info?: IOnChangeOptions) => void): IPublicTypeDisposable; - - /** overriding methods end */ -} -export class NodeChildren implements INodeChildren { @obx.shallow children: INode[]; private emitter: IEventBus = createModuleEventBus('NodeChildren'); @@ -99,11 +48,10 @@ export class NodeChildren implements INodeChildren { constructor( readonly owner: INode, data: IPublicTypeNodeData | IPublicTypeNodeData[], - options: any = {}, ) { makeObservable(this); this.children = (Array.isArray(data) ? data : [data]).filter(child => !!child).map((child) => { - return this.owner.document?.createNode(child, options.checkId); + return this.owner.document?.createNode(child); }); } @@ -142,9 +90,12 @@ export class NodeChildren implements INodeChildren { node = child; node.import(item); } else { - node = this.owner.document?.createNode(item, checkId); + node = this.owner.document?.createNode(item); + } + + if (node) { + children[i] = node; } - children[i] = node; } this.children = children; @@ -176,13 +127,13 @@ export class NodeChildren implements INodeChildren { /** * 回收销毁 */ - purge(useMutator = true) { + purge() { if (this.purged) { return; } this.purged = true; this.children.forEach((child) => { - child.purge(useMutator); + child.purge(); }); } @@ -212,7 +163,7 @@ export class NodeChildren implements INodeChildren { node.internalPurgeStart(); if (node.isParentalNode) { foreachReverse( - node.children, + node.children!, (subNode: Node) => { subNode.remove(useMutator, purge, options); }, @@ -459,11 +410,11 @@ export class NodeChildren implements INodeChildren { const items = adder(this.children); if (items && items.length > 0) { items.forEach((child: IPublicTypeNodeData) => { - const node: INode = this.owner.document?.createNode(child); - this.children.push(node); - node.internalSetParent(this.owner); + const node: INode | null = this.owner.document?.createNode(child); + node && this.children.push(node); + node?.internalSetParent(this.owner); /* istanbul ignore next */ - const editor = node.document?.designer.editor; + const editor = node?.document?.designer.editor; editor?.eventBus.emit('node.add', { node }); }); changed = true; @@ -504,7 +455,7 @@ export class NodeChildren implements INodeChildren { try { callbacks?.onSubtreeModified.call( node.internalToShellNode(), - owner.internalToShellNode(), + owner.internalToShellNode()!, options, ); } catch (e) { @@ -517,3 +468,5 @@ export class NodeChildren implements INodeChildren { } } } + +export interface INodeChildren extends NodeChildren {} \ No newline at end of file diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index c8363d0586..0b698831e9 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -13,7 +13,6 @@ import { GlobalEvent, IPublicTypeComponentAction, IPublicModelNode, - IPublicModelExclusiveGroup, IPublicEnumTransformStage, IPublicTypeDisposable, IBaseModelNode, @@ -37,132 +36,7 @@ export interface NodeStatus { inPlaceEditing: boolean; } -export interface IBaseNode<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> extends Omit<IBaseModelNode< - IDocumentModel, - IBaseNode, - INodeChildren, - IComponentMeta, - ISettingTopEntry, - IProps, - IProp, - IExclusiveGroup ->, - 'isRoot' | - 'isPage' | - 'isComponent' | - 'isModal' | - 'isSlot' | - 'isParental' | - 'isLeaf' | - 'settingEntry' | - // 在内部的 node 模型中不存在 - 'getExtraPropValue' | - 'setExtraPropValue' | - 'exportSchema' | - 'visible' | - 'importSchema' | - // 内外实现有差异 - 'isContainer' | - 'isEmpty' -> { - isNode: boolean; - - get componentMeta(): IComponentMeta; - - get settingEntry(): ISettingTopEntry; - - get isPurged(): boolean; - - get index(): number | undefined; - - get isPurging(): boolean; - - getId(): string; - - getParent(): INode | null; - - /** - * 内部方法,请勿使用 - * @param useMutator 是否触发联动逻辑 - */ - internalSetParent(parent: INode | null, useMutator?: boolean): void; - - setConditionGroup(grp: IPublicModelExclusiveGroup | string | null): void; - - internalToShellNode(): IPublicModelNode | null; - - internalPurgeStart(): void; - - unlinkSlot(slotNode: INode): void; - - /** - * 导出 schema - */ - export<T = Schema>(stage: IPublicEnumTransformStage, options?: any): T; - - emitPropChange(val: IPublicTypePropChangeOptions): void; - - import(data: Schema, checkId?: boolean): void; - - internalSetSlotFor(slotFor: Prop | null | undefined): void; - - addSlot(slotNode: INode): void; - - onVisibleChange(func: (flag: boolean) => any): () => void; - - getSuitablePlace(node: INode, ref: any): any; - - onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable | undefined; - - onPropChange(func: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable; - - isModal(): boolean; - - isRoot(): boolean; - - isPage(): boolean; - - isComponent(): boolean; - - isSlot(): boolean; - - isParental(): boolean; - - isLeaf(): boolean; - - isContainer(): boolean; - - isEmpty(): boolean; - - remove( - useMutator?: boolean, - purge?: boolean, - options?: NodeRemoveOptions, - ): void; - - didDropIn(dragment: INode): void; - - didDropOut(dragment: INode): void; - - purge(): void; - - removeSlot(slotNode: INode): boolean; - - setVisible(flag: boolean): void; - - getVisible(): boolean; - - getChildren(): INodeChildren | null; - - clearPropValue(path: string | number): void; - - setProps(props?: IPublicTypePropsMap | IPublicTypePropsList | Props | null): void; - - mergeProps(props: IPublicTypePropsMap): void; - - /** 是否可以选中 */ - canSelect(): boolean; -} +export interface IBaseNode extends Node {} /** * 基础节点 @@ -212,7 +86,34 @@ export interface IBaseNode<Schema extends IPublicTypeNodeSchema = IPublicTypeNod * isLocked * hidden */ -export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> implements IBaseNode { +export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> implements Omit<IBaseModelNode< + IDocumentModel, + IBaseNode, + INodeChildren, + IComponentMeta, + ISettingTopEntry, + IProps, + IProp, + IExclusiveGroup +>, +'isRoot' | +'isPage' | +'isComponent' | +'isModal' | +'isSlot' | +'isParental' | +'isLeaf' | +'settingEntry' | +// 在内部的 node 模型中不存在 +'getExtraPropValue' | +'setExtraPropValue' | +'exportSchema' | +'visible' | +'importSchema' | +// 内外实现有差异 +'isContainer' | +'isEmpty' +> { private emitter: IEventBus; /** @@ -690,7 +591,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> } /* istanbul ignore next */ - setConditionGroup(grp: IPublicModelExclusiveGroup | string | null) { + setConditionGroup(grp: IExclusiveGroup | string | null) { let _grp: IExclusiveGroup | null = null; if (!grp) { this.getExtraProp('conditionGroup', false)?.remove(); @@ -1389,11 +1290,11 @@ export interface LeafNode extends Node { export type IPublicTypePropChangeOptions = Omit<GlobalEvent.Node.Prop.ChangeOptions, 'node'>; -export type ISlotNode = IBaseNode<IPublicTypeSlotSchema>; -export type IPageNode = IBaseNode<IPublicTypePageSchema>; -export type IComponentNode = IBaseNode<IPublicTypeComponentSchema>; -export type IRootNode = IPageNode | IComponentNode; -export type INode = IPageNode | ISlotNode | IComponentNode | IRootNode; +export interface ISlotNode extends Node<IPublicTypeSlotSchema> {} +export interface IPageNode extends Node<IPublicTypePageSchema> {} +export interface IComponentNode extends Node<IPublicTypeComponentSchema> {} +export interface IRootNode extends Node<IPublicTypePageSchema | IPublicTypeComponentSchema> {} +export interface INode extends Node<IPublicTypePageSchema | IPublicTypeSlotSchema | IPublicTypeComponentSchema | IPublicTypeNodeSchema> {} export function isRootNode(node: INode): node is IRootNode { return node && node.isRootNode; @@ -1505,7 +1406,7 @@ export function insertChild( export function insertChildren( container: INode, - nodes: INode[] | IPublicTypeNodeData[], + nodes: INode[] | IPublicTypeNodeData[] | IPublicModelNode[], at?: number | null, copy?: boolean, ): INode[] { diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index d70f0f56ec..5a7187daa1 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -1,6 +1,6 @@ import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core'; import { GlobalEvent, IPublicEnumTransformStage } from '@alilc/lowcode-types'; -import type { IPublicTypeCompositeValue, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicModelProp } from '@alilc/lowcode-types'; +import type { IPublicTypeCompositeValue, IPublicTypeJSSlot, IPublicTypeSlotSchema, IPublicModelProp, IPublicTypeNodeData } from '@alilc/lowcode-types'; import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot, isNodeSchema } from '@alilc/lowcode-utils'; import { valueToSource } from './value-to-source'; import { IPropParent } from './props'; @@ -227,7 +227,7 @@ export class Prop implements IProp, IPropParent { constructor( public parent: IPropParent, - value: IPublicTypeCompositeValue | UNSET = UNSET, + value: IPublicTypeCompositeValue | IPublicTypeNodeData | IPublicTypeNodeData[] | UNSET = UNSET, key?: string | number, spread = false, options = {}, @@ -351,7 +351,7 @@ export class Prop implements IProp, IPropParent { * set value, val should be JSON Object */ @action - setValue(val: IPublicTypeCompositeValue) { + setValue(val: IPublicTypeCompositeValue | IPublicTypeNodeData | IPublicTypeNodeData[]) { if (val === this._value) return; const oldValue = this._value; this._value = val; diff --git a/packages/designer/src/document/node/props/props.ts b/packages/designer/src/document/node/props/props.ts index 213592a5de..78995df572 100644 --- a/packages/designer/src/document/node/props/props.ts +++ b/packages/designer/src/document/node/props/props.ts @@ -37,30 +37,9 @@ export interface IPropParent { delete(prop: IProp): void; } -export interface IProps extends Omit<IBaseModelProps<IProp>, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'>, IPropParent { +export interface IProps extends Props {} - /** - * 获取 props 对应的 node - */ - getNode(): INode; - - get(path: string, createIfNone?: boolean): IProp | null; - - export(stage?: IPublicEnumTransformStage): { - props?: IPublicTypePropsMap | IPublicTypePropsList; - extras?: ExtrasObject; - }; - - merge(value: IPublicTypePropsMap, extras?: IPublicTypePropsMap): void; - - purge(): void; - - query(path: string, createIfNone: boolean): IProp | null; - - import(value?: IPublicTypePropsMap | IPublicTypePropsList | null, extras?: ExtrasObject): void; -} - -export class Props implements IProps, IPropParent { +export class Props implements Omit<IBaseModelProps<IProp>, | 'getExtraProp' | 'getExtraPropValue' | 'setExtraPropValue' | 'node'>, IPropParent { readonly id = uniqueId('props'); @obx.shallow private items: IProp[] = []; diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index 7f26a2b4f3..d9a47c4511 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -20,6 +20,7 @@ import { IPublicEnumPluginRegisterLevel, IPublicModelWindow, IPublicApiCommonUI, + IPublicApiCommand, } from '@alilc/lowcode-types'; import { IPluginContextOptions, @@ -48,6 +49,7 @@ export default class PluginContext implements editorWindow: IPublicModelWindow; commonUI: IPublicApiCommonUI; isPluginRegisteredInWorkspace: false; + command: IPublicApiCommand; constructor( options: IPluginContextOptions, diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index 7ff462391d..0723707891 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -44,72 +44,27 @@ export enum SkeletonEvents { WIDGET_ENABLE = 'skeleton.widget.enable', } -export interface ISkeleton extends Omit<IPublicApiSkeleton, - 'showPanel' | - 'hidePanel' | - 'showWidget' | - 'enableWidget' | - 'hideWidget' | - 'disableWidget' | - 'showArea' | - 'onShowPanel' | - 'onHidePanel' | - 'onShowWidget' | - 'onHideWidget' | - 'remove' | - 'hideArea' | - 'add' +export interface ISkeleton extends Skeleton {} + +export class Skeleton implements Omit<IPublicApiSkeleton, +'showPanel' | +'hidePanel' | +'showWidget' | +'enableWidget' | +'hideWidget' | +'disableWidget' | +'showArea' | +'onShowPanel' | +'onHidePanel' | +'onShowWidget' | +'onHideWidget' | +'remove' | +'hideArea' | +'add' | +'getAreaItems' | +'onDisableWidget' | +'onEnableWidget' > { - editor: IEditor; - - readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>; - - readonly topArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - - readonly subTopArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - - readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - - readonly leftFixedArea: Area<IPublicTypePanelConfig, Panel>; - - readonly leftFloatArea: Area<IPublicTypePanelConfig, Panel>; - - readonly rightArea: Area<IPublicTypePanelConfig, Panel>; - - readonly mainArea: Area<WidgetConfig | IPublicTypePanelConfig, Widget | Panel>; - - readonly bottomArea: Area<IPublicTypePanelConfig, Panel>; - - readonly stages: Area<StageConfig, Stage>; - - readonly widgets: IWidget[]; - - readonly focusTracker: FocusTracker; - - getPanel(name: string): Panel | undefined; - - getWidget(name: string): IWidget | undefined; - - buildFromConfig(config?: EditorConfig, components?: PluginClassSet): void; - - createStage(config: any): string | undefined; - - getStage(name: string): Stage | null; - - createContainer( - name: string, - handle: (item: any) => any, - exclusive?: boolean, - checkVisible?: () => boolean, - defaultSetCurrent?: boolean, - ): WidgetContainer; - - createPanel(config: IPublicTypePanelConfig): Panel; - - add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined; -} - -export class Skeleton implements ISkeleton { private panels = new Map<string, Panel>(); private configTransducers: IPublicTypeConfigTransducer[] = []; @@ -431,7 +386,7 @@ export class Skeleton implements ISkeleton { } const { content, ...restConfig } = config; if (content) { - if (isPlainObject(content) && !isValidElement(content)) { + if (isPlainObject<IPublicTypePanelConfig>(content) && !isValidElement(content)) { Object.keys(content).forEach((key) => { if (/props$/i.test(key) && restConfig[key]) { restConfig[key] = { diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 4dffa628bd..7590b23f43 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -229,7 +229,7 @@ export async function init( document.body.appendChild(engineContainer); } else { engineOptions = options; - engineContainer = container; + engineContainer = container!; if (!container) { engineContainer = document.createElement('div'); engineContainer.id = 'engine'; diff --git a/packages/react-simulator-renderer/src/utils/misc.ts b/packages/react-simulator-renderer/src/utils/misc.ts index a829a6e95b..95ca6bfbd0 100644 --- a/packages/react-simulator-renderer/src/utils/misc.ts +++ b/packages/react-simulator-renderer/src/utils/misc.ts @@ -1,29 +1,32 @@ -interface UtilsMetadata { - name: string; - npm: { - package: string; - version?: string; - exportName: string; - subName?: string; - destructuring?: boolean; - main?: string; - }; -} +// interface UtilsMetadata { +// name: string; +// npm: { +// package: string; +// version?: string; +// exportName: string; +// subName?: string; +// destructuring?: boolean; +// main?: string; +// }; +// } -interface LibrayMap { - [key: string]: string; -} +// invalid code -export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetadata[]) { - const projectUtils: { [packageName: string]: any } = {}; - if (utilsMetadata) { - utilsMetadata.forEach(meta => { - if (librayMap[meta?.npm.package]) { - const lib = window[librayMap[meta?.npm.package]]; - } - }); - } -} +// interface LibrayMap { +// [key: string]: string; +// } + +// export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetadata[]) { + +// const projectUtils: { [packageName: string]: any } = {}; +// if (utilsMetadata) { +// utilsMetadata.forEach(meta => { +// if (librayMap[meta?.npm.package]) { +// const lib = window[librayMap[meta?.npm.package] as any]; +// } +// }); +// } +// } /** * judges if current simulator renderer deteched or not diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index f5bc79009f..c793a67537 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -1,4 +1,4 @@ -import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; +import { IPublicApiWorkspace, IPublicModelResource, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; import { IWorkspace } from '@alilc/lowcode-workspace'; import { resourceSymbol, workspaceSymbol } from '../symbols'; import { Resource as ShellResource, Window as ShellWindow } from '../model'; @@ -13,7 +13,7 @@ export class Workspace implements IPublicApiWorkspace { } get resourceList() { - return this[workspaceSymbol].getResourceList().map((d) => new ShellResource(d)); + return this[workspaceSymbol].getResourceList().map((d) => new ShellResource(d) as IPublicModelResource); } setResourceList(resourceList: IPublicResourceList) { diff --git a/packages/shell/src/model/resource.ts b/packages/shell/src/model/resource.ts index 29a385b993..da344742d2 100644 --- a/packages/shell/src/model/resource.ts +++ b/packages/shell/src/model/resource.ts @@ -46,7 +46,7 @@ export class Resource implements IPublicModelResource { } get children() { - return this[resourceSymbol].children.map((child) => new Resource(child)); + return this[resourceSymbol].children.map((child) => new Resource(child) as IPublicModelResource); } get viewName() { diff --git a/packages/types/src/shell/api/common.ts b/packages/types/src/shell/api/common.ts index 05ef0da17f..16b02f65d0 100644 --- a/packages/types/src/shell/api/common.ts +++ b/packages/types/src/shell/api/common.ts @@ -1,5 +1,5 @@ -import { Component, ReactNode } from 'react'; +import { Component, ReactElement, ReactNode } from 'react'; import { IPublicTypeI18nData, IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type'; import { IPublicEnumTransitionType } from '../enum'; @@ -73,7 +73,7 @@ export interface IPublicApiCommonUtils { /** * i18n 转换方法 */ - intl(data: IPublicTypeI18nData | string, params?: object): string; + intl(data: IPublicTypeI18nData | string | undefined | ReactElement, params?: object): string; } export interface IPublicApiCommonSkeletonCabin { diff --git a/packages/types/src/shell/model/document-model.ts b/packages/types/src/shell/model/document-model.ts index 4c9344eb48..72496572c9 100644 --- a/packages/types/src/shell/model/document-model.ts +++ b/packages/types/src/shell/model/document-model.ts @@ -108,7 +108,7 @@ export interface IPublicModelDocumentModel< * @param data * @returns */ - createNode<T = Node>(data: IPublicTypeNodeSchema): T | null; + createNode<T = Node, S = IPublicTypeNodeSchema>(data: S): T | null; /** * 移除指定节点/节点id diff --git a/packages/types/src/shell/model/prop.ts b/packages/types/src/shell/model/prop.ts index 71442e64ab..81b6c016dc 100644 --- a/packages/types/src/shell/model/prop.ts +++ b/packages/types/src/shell/model/prop.ts @@ -1,5 +1,5 @@ import { IPublicEnumTransformStage } from '../enum'; -import { IPublicTypeCompositeValue } from '../type'; +import { IPublicTypeCompositeValue, IPublicTypeNodeData } from '../type'; import { IPublicModelNode } from './'; export interface IPublicModelProp< @@ -48,7 +48,7 @@ export interface IPublicModelProp< * set value for this prop * @param val */ - setValue(val: IPublicTypeCompositeValue): void; + setValue(val: IPublicTypeCompositeValue | IPublicTypeNodeData | IPublicTypeNodeData[]): void; /** * 获取值 diff --git a/packages/types/src/shell/model/resource.ts b/packages/types/src/shell/model/resource.ts index acd7d056f5..9de2d6755b 100644 --- a/packages/types/src/shell/model/resource.ts +++ b/packages/types/src/shell/model/resource.ts @@ -1,4 +1,4 @@ -import { ReactElement } from 'react'; +import { ComponentType, ReactElement } from 'react'; export interface IBaseModelResource< Resource @@ -7,7 +7,7 @@ export interface IBaseModelResource< get id(): string | undefined; - get icon(): ReactElement | undefined; + get icon(): ReactElement | undefined | ComponentType; get options(): Record<string, any>; diff --git a/packages/types/src/shell/type/metadata.ts b/packages/types/src/shell/type/metadata.ts index c07d9802e1..bfa87e0490 100644 --- a/packages/types/src/shell/type/metadata.ts +++ b/packages/types/src/shell/type/metadata.ts @@ -102,7 +102,7 @@ export interface IPublicTypeFilterItem { } export interface IPublicTypeAutorunItem { name: string; - autorun: (target: IPublicModelSettingField | null) => any; + autorun: (target: IPublicModelSettingField | null | undefined) => any; } // thinkof Array diff --git a/packages/types/src/shell/type/props-transducer.ts b/packages/types/src/shell/type/props-transducer.ts index b98ec36a6f..b9eb740453 100644 --- a/packages/types/src/shell/type/props-transducer.ts +++ b/packages/types/src/shell/type/props-transducer.ts @@ -1,11 +1,11 @@ import { IPublicEnumTransformStage } from '../enum'; import { IPublicModelNode } from '../model'; -import { IPublicTypeCompositeObject } from './'; +import { IPublicTypePropsMap } from './'; export type IPublicTypePropsTransducer = ( - props: IPublicTypeCompositeObject, + props: IPublicTypePropsMap, node: IPublicModelNode, ctx?: { stage: IPublicEnumTransformStage; }, -) => IPublicTypeCompositeObject; +) => IPublicTypePropsMap; diff --git a/packages/types/src/shell/type/widget-base-config.ts b/packages/types/src/shell/type/widget-base-config.ts index 2764ce1927..02785148c9 100644 --- a/packages/types/src/shell/type/widget-base-config.ts +++ b/packages/types/src/shell/type/widget-base-config.ts @@ -36,7 +36,7 @@ export interface IPublicTypeWidgetBaseConfig { */ area?: IPublicTypeWidgetConfigArea; props?: Record<string, any>; - content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[]; + content?: string | ReactElement | ComponentType<any> | IPublicTypePanelConfig[] | IPublicTypePanelConfig; contentProps?: Record<string, any>; /** diff --git a/packages/utils/src/is-plain-object.ts b/packages/utils/src/is-plain-object.ts index 17bc6266f1..bb199e6302 100644 --- a/packages/utils/src/is-plain-object.ts +++ b/packages/utils/src/is-plain-object.ts @@ -1,6 +1,6 @@ import { isObject } from './is-object'; -export function isPlainObject(value: any): value is any { +export function isPlainObject<T extends object = object>(value: any): value is T { if (!isObject(value)) { return false; } diff --git a/packages/utils/test/src/__snapshots__/is-react.test.tsx.snap b/packages/utils/tests/src/__snapshots__/is-react.test.tsx.snap similarity index 100% rename from packages/utils/test/src/__snapshots__/is-react.test.tsx.snap rename to packages/utils/tests/src/__snapshots__/is-react.test.tsx.snap diff --git a/packages/utils/test/src/__snapshots__/schema.test.ts.snap b/packages/utils/tests/src/__snapshots__/schema.test.ts.snap similarity index 100% rename from packages/utils/test/src/__snapshots__/schema.test.ts.snap rename to packages/utils/tests/src/__snapshots__/schema.test.ts.snap diff --git a/packages/utils/test/src/build-components/buildComponents.test.tsx b/packages/utils/tests/src/build-components/buildComponents.test.tsx similarity index 100% rename from packages/utils/test/src/build-components/buildComponents.test.tsx rename to packages/utils/tests/src/build-components/buildComponents.test.tsx diff --git a/packages/utils/test/src/build-components/getProjectUtils.test.ts b/packages/utils/tests/src/build-components/getProjectUtils.test.ts similarity index 100% rename from packages/utils/test/src/build-components/getProjectUtils.test.ts rename to packages/utils/tests/src/build-components/getProjectUtils.test.ts diff --git a/packages/utils/test/src/build-components/getSubComponent.test.ts b/packages/utils/tests/src/build-components/getSubComponent.test.ts similarity index 100% rename from packages/utils/test/src/build-components/getSubComponent.test.ts rename to packages/utils/tests/src/build-components/getSubComponent.test.ts diff --git a/packages/utils/test/src/check-prop-types.test.ts b/packages/utils/tests/src/check-prop-types.test.ts similarity index 100% rename from packages/utils/test/src/check-prop-types.test.ts rename to packages/utils/tests/src/check-prop-types.test.ts diff --git a/packages/utils/test/src/check-types/is-action-content-object.test.ts b/packages/utils/tests/src/check-types/is-action-content-object.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-action-content-object.test.ts rename to packages/utils/tests/src/check-types/is-action-content-object.test.ts diff --git a/packages/utils/test/src/check-types/is-basic-prop-type.test.ts b/packages/utils/tests/src/check-types/is-basic-prop-type.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-basic-prop-type.test.ts rename to packages/utils/tests/src/check-types/is-basic-prop-type.test.ts diff --git a/packages/utils/test/src/check-types/is-custom-view.test.tsx b/packages/utils/tests/src/check-types/is-custom-view.test.tsx similarity index 100% rename from packages/utils/test/src/check-types/is-custom-view.test.tsx rename to packages/utils/tests/src/check-types/is-custom-view.test.tsx diff --git a/packages/utils/test/src/check-types/is-dom-text.test.ts b/packages/utils/tests/src/check-types/is-dom-text.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-dom-text.test.ts rename to packages/utils/tests/src/check-types/is-dom-text.test.ts diff --git a/packages/utils/test/src/check-types/is-drag-any-object.test.ts b/packages/utils/tests/src/check-types/is-drag-any-object.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-drag-any-object.test.ts rename to packages/utils/tests/src/check-types/is-drag-any-object.test.ts diff --git a/packages/utils/test/src/check-types/is-drag-node-data-object.test.ts b/packages/utils/tests/src/check-types/is-drag-node-data-object.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-drag-node-data-object.test.ts rename to packages/utils/tests/src/check-types/is-drag-node-data-object.test.ts diff --git a/packages/utils/test/src/check-types/is-drag-node-object.test.ts b/packages/utils/tests/src/check-types/is-drag-node-object.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-drag-node-object.test.ts rename to packages/utils/tests/src/check-types/is-drag-node-object.test.ts diff --git a/packages/utils/test/src/check-types/is-dynamic-setter.test.ts b/packages/utils/tests/src/check-types/is-dynamic-setter.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-dynamic-setter.test.ts rename to packages/utils/tests/src/check-types/is-dynamic-setter.test.ts diff --git a/packages/utils/test/src/check-types/is-i18n-data.test.ts b/packages/utils/tests/src/check-types/is-i18n-data.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-i18n-data.test.ts rename to packages/utils/tests/src/check-types/is-i18n-data.test.ts diff --git a/packages/utils/test/src/check-types/is-isfunction.test.ts b/packages/utils/tests/src/check-types/is-isfunction.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-isfunction.test.ts rename to packages/utils/tests/src/check-types/is-isfunction.test.ts diff --git a/packages/utils/test/src/check-types/is-jsblock.test.ts b/packages/utils/tests/src/check-types/is-jsblock.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-jsblock.test.ts rename to packages/utils/tests/src/check-types/is-jsblock.test.ts diff --git a/packages/utils/test/src/check-types/is-jsexpression.test.ts b/packages/utils/tests/src/check-types/is-jsexpression.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-jsexpression.test.ts rename to packages/utils/tests/src/check-types/is-jsexpression.test.ts diff --git a/packages/utils/test/src/check-types/is-jsslot.test.ts b/packages/utils/tests/src/check-types/is-jsslot.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-jsslot.test.ts rename to packages/utils/tests/src/check-types/is-jsslot.test.ts diff --git a/packages/utils/test/src/check-types/is-location-children-detail.test.ts b/packages/utils/tests/src/check-types/is-location-children-detail.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-location-children-detail.test.ts rename to packages/utils/tests/src/check-types/is-location-children-detail.test.ts diff --git a/packages/utils/test/src/check-types/is-location-data.test.ts b/packages/utils/tests/src/check-types/is-location-data.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-location-data.test.ts rename to packages/utils/tests/src/check-types/is-location-data.test.ts diff --git a/packages/utils/test/src/check-types/is-lowcode-component-type.test.ts b/packages/utils/tests/src/check-types/is-lowcode-component-type.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-lowcode-component-type.test.ts rename to packages/utils/tests/src/check-types/is-lowcode-component-type.test.ts diff --git a/packages/utils/test/src/check-types/is-lowcode-project-schema.test.ts b/packages/utils/tests/src/check-types/is-lowcode-project-schema.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-lowcode-project-schema.test.ts rename to packages/utils/tests/src/check-types/is-lowcode-project-schema.test.ts diff --git a/packages/utils/test/src/check-types/is-node-schema.test.ts b/packages/utils/tests/src/check-types/is-node-schema.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-node-schema.test.ts rename to packages/utils/tests/src/check-types/is-node-schema.test.ts diff --git a/packages/utils/test/src/check-types/is-node.test.ts b/packages/utils/tests/src/check-types/is-node.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-node.test.ts rename to packages/utils/tests/src/check-types/is-node.test.ts diff --git a/packages/utils/test/src/check-types/is-procode-component-type.test.ts b/packages/utils/tests/src/check-types/is-procode-component-type.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-procode-component-type.test.ts rename to packages/utils/tests/src/check-types/is-procode-component-type.test.ts diff --git a/packages/utils/test/src/check-types/is-project-schema.test.ts b/packages/utils/tests/src/check-types/is-project-schema.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-project-schema.test.ts rename to packages/utils/tests/src/check-types/is-project-schema.test.ts diff --git a/packages/utils/test/src/check-types/is-required-prop-type.test.ts b/packages/utils/tests/src/check-types/is-required-prop-type.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-required-prop-type.test.ts rename to packages/utils/tests/src/check-types/is-required-prop-type.test.ts diff --git a/packages/utils/test/src/check-types/is-setter-config.test.ts b/packages/utils/tests/src/check-types/is-setter-config.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-setter-config.test.ts rename to packages/utils/tests/src/check-types/is-setter-config.test.ts diff --git a/packages/utils/test/src/check-types/is-setting-field.test.ts b/packages/utils/tests/src/check-types/is-setting-field.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-setting-field.test.ts rename to packages/utils/tests/src/check-types/is-setting-field.test.ts diff --git a/packages/utils/test/src/check-types/is-title-config.test.ts b/packages/utils/tests/src/check-types/is-title-config.test.ts similarity index 100% rename from packages/utils/test/src/check-types/is-title-config.test.ts rename to packages/utils/tests/src/check-types/is-title-config.test.ts diff --git a/packages/utils/test/src/clone-deep.test.ts b/packages/utils/tests/src/clone-deep.test.ts similarity index 100% rename from packages/utils/test/src/clone-deep.test.ts rename to packages/utils/tests/src/clone-deep.test.ts diff --git a/packages/utils/test/src/clone-enumerable-property.test.ts b/packages/utils/tests/src/clone-enumerable-property.test.ts similarity index 100% rename from packages/utils/test/src/clone-enumerable-property.test.ts rename to packages/utils/tests/src/clone-enumerable-property.test.ts diff --git a/packages/utils/test/src/create-content.test.tsx b/packages/utils/tests/src/create-content.test.tsx similarity index 100% rename from packages/utils/test/src/create-content.test.tsx rename to packages/utils/tests/src/create-content.test.tsx diff --git a/packages/utils/test/src/create-defer.test.ts b/packages/utils/tests/src/create-defer.test.ts similarity index 100% rename from packages/utils/test/src/create-defer.test.ts rename to packages/utils/tests/src/create-defer.test.ts diff --git a/packages/utils/test/src/is-object.test.ts b/packages/utils/tests/src/is-object.test.ts similarity index 100% rename from packages/utils/test/src/is-object.test.ts rename to packages/utils/tests/src/is-object.test.ts diff --git a/packages/utils/test/src/is-react.test.tsx b/packages/utils/tests/src/is-react.test.tsx similarity index 100% rename from packages/utils/test/src/is-react.test.tsx rename to packages/utils/tests/src/is-react.test.tsx diff --git a/packages/utils/test/src/is-shaken.test.ts b/packages/utils/tests/src/is-shaken.test.ts similarity index 100% rename from packages/utils/test/src/is-shaken.test.ts rename to packages/utils/tests/src/is-shaken.test.ts diff --git a/packages/utils/test/src/misc.test.ts b/packages/utils/tests/src/misc.test.ts similarity index 100% rename from packages/utils/test/src/misc.test.ts rename to packages/utils/tests/src/misc.test.ts diff --git a/packages/utils/test/src/navtive-selection.test.ts b/packages/utils/tests/src/navtive-selection.test.ts similarity index 100% rename from packages/utils/test/src/navtive-selection.test.ts rename to packages/utils/tests/src/navtive-selection.test.ts diff --git a/packages/utils/test/src/schema.test.ts b/packages/utils/tests/src/schema.test.ts similarity index 100% rename from packages/utils/test/src/schema.test.ts rename to packages/utils/tests/src/schema.test.ts diff --git a/packages/utils/test/src/script.test.ts b/packages/utils/tests/src/script.test.ts similarity index 100% rename from packages/utils/test/src/script.test.ts rename to packages/utils/tests/src/script.test.ts diff --git a/packages/utils/test/src/svg-icon.test.tsx b/packages/utils/tests/src/svg-icon.test.tsx similarity index 100% rename from packages/utils/test/src/svg-icon.test.tsx rename to packages/utils/tests/src/svg-icon.test.tsx diff --git a/packages/utils/test/src/transaction-manager.test.ts b/packages/utils/tests/src/transaction-manager.test.ts similarity index 100% rename from packages/utils/test/src/transaction-manager.test.ts rename to packages/utils/tests/src/transaction-manager.test.ts diff --git a/packages/utils/test/src/unique-id.test.ts b/packages/utils/tests/src/unique-id.test.ts similarity index 100% rename from packages/utils/test/src/unique-id.test.ts rename to packages/utils/tests/src/unique-id.test.ts diff --git a/packages/workspace/src/context/base-context.ts b/packages/workspace/src/context/base-context.ts index 445677a618..3e6063e533 100644 --- a/packages/workspace/src/context/base-context.ts +++ b/packages/workspace/src/context/base-context.ts @@ -55,32 +55,10 @@ import { getLogger, Logger as InnerLogger } from '@alilc/lowcode-utils'; import { IWorkspace } from '../workspace'; import { IEditorWindow } from '../window'; -export interface IBasicContext extends Omit<IPublicModelPluginContext, 'workspace'> { - skeleton: IPublicApiSkeleton; - plugins: IPublicApiPlugins; - project: IPublicApiProject; - setters: IPublicApiSetters; - material: IPublicApiMaterial; - common: IPublicApiCommon; - config: IEngineConfig; - event: IPublicApiEvent; - logger: InnerLogger; - hotkey: IPublicApiHotkey; - innerProject: IProject; - editor: Editor; - designer: IDesigner; - registerInnerPlugins: () => Promise<void>; - innerSetters: InnerSetters; - innerSkeleton: ISkeleton; - innerHotkey: IHotKey; - innerPlugins: ILowCodePluginManager; - canvas: IPublicApiCanvas; - pluginEvent: IPublicApiEvent; - preference: IPluginPreferenceMananger; - workspace: IWorkspace; +export interface IBasicContext extends BasicContext { } -export class BasicContext implements IBasicContext { +export class BasicContext implements Omit<IPublicModelPluginContext, 'workspace' | 'commonUI' | 'command' | 'isPluginRegisteredInWorkspace' | 'editorWindow'> { skeleton: IPublicApiSkeleton; plugins: IPublicApiPlugins; project: IPublicApiProject; diff --git a/packages/workspace/src/resource-type.ts b/packages/workspace/src/resource-type.ts index 28d54e56b3..2ab7b9942f 100644 --- a/packages/workspace/src/resource-type.ts +++ b/packages/workspace/src/resource-type.ts @@ -1,14 +1,8 @@ import { IPublicTypeResourceType } from '@alilc/lowcode-types'; -export interface IResourceType extends Omit<IPublicTypeResourceType, 'resourceName' | 'resourceType'> { - name: string; +export interface IResourceType extends ResourceType {} - type: 'editor' | 'webview'; - - resourceTypeModel: IPublicTypeResourceType; -} - -export class ResourceType implements IResourceType { +export class ResourceType implements Omit<IPublicTypeResourceType, 'resourceName' | 'resourceType'> { constructor(readonly resourceTypeModel: IPublicTypeResourceType) { } diff --git a/packages/workspace/src/resource.ts b/packages/workspace/src/resource.ts index 6e85183853..d65cf08747 100644 --- a/packages/workspace/src/resource.ts +++ b/packages/workspace/src/resource.ts @@ -1,35 +1,14 @@ -import { ISkeleton } from '@alilc/lowcode-editor-skeleton'; import { IPublicTypeEditorView, IPublicResourceData, IPublicResourceTypeConfig, IBaseModelResource, IPublicEnumPluginRegisterLevel } from '@alilc/lowcode-types'; import { Logger } from '@alilc/lowcode-utils'; import { BasicContext, IBasicContext } from './context/base-context'; -import { ResourceType, IResourceType } from './resource-type'; +import { IResourceType } from './resource-type'; import { IWorkspace } from './workspace'; const logger = new Logger({ level: 'warn', bizName: 'workspace:resource' }); -export interface IBaseResource<T> extends IBaseModelResource<T> { - readonly resourceType: ResourceType; +export interface IResource extends Resource {} - skeleton: ISkeleton; - - description?: string; - - get editorViews(): IPublicTypeEditorView[]; - - get defaultViewName(): string | undefined; - - getEditorView(name: string): IPublicTypeEditorView | undefined; - - import(schema: any): Promise<any>; - - save(value: any): Promise<any>; - - url(): Promise<string | undefined>; -} - -export type IResource = IBaseResource<IResource>; - -export class Resource implements IResource { +export class Resource implements IBaseModelResource<IResource> { private context: IBasicContext; resourceTypeInstance: IPublicResourceTypeConfig; diff --git a/packages/workspace/src/view/window-view.tsx b/packages/workspace/src/view/window-view.tsx index 65378bc9c4..e66082910f 100644 --- a/packages/workspace/src/view/window-view.tsx +++ b/packages/workspace/src/view/window-view.tsx @@ -1,13 +1,13 @@ import { PureComponent } from 'react'; import { ResourceView } from './resource-view'; import { engineConfig, observer } from '@alilc/lowcode-editor-core'; -import { EditorWindow } from '../window'; +import { IEditorWindow } from '../window'; import { BuiltinLoading } from '@alilc/lowcode-designer'; import { DesignerView } from '../inner-plugins/webview'; @observer export class WindowView extends PureComponent<{ - window: EditorWindow; + window: IEditorWindow; active: boolean; }, any> { render() { diff --git a/packages/workspace/src/window.ts b/packages/workspace/src/window.ts index cd64a9b112..565575b71c 100644 --- a/packages/workspace/src/window.ts +++ b/packages/workspace/src/window.ts @@ -1,6 +1,6 @@ import { uniqueId } from '@alilc/lowcode-utils'; import { createModuleEventBus, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core'; -import { Context, IViewContext } from './context/view-context'; +import { Context } from './context/view-context'; import { IWorkspace } from './workspace'; import { IResource } from './resource'; import { IPublicModelWindow, IPublicTypeDisposable } from '@alilc/lowcode-types'; @@ -12,23 +12,7 @@ interface IWindowCOnfig { sleep?: boolean; } -export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'changeViewType' | 'currentEditorView' | 'editorViews'> { - readonly resource: IResource; - - editorViews: Map<string, IViewContext>; - - _editorView: IViewContext; - - changeViewName: (name: string, ignoreEmit?: boolean) => void; - - initReady: boolean; - - sleep?: boolean; - - init(): void; - - updateState(state: WINDOW_STATE): void; -} +export interface IEditorWindow extends EditorWindow {} export enum WINDOW_STATE { // 睡眠 @@ -44,7 +28,7 @@ export enum WINDOW_STATE { destroyed = 'destroyed' } -export class EditorWindow implements IEditorWindow { +export class EditorWindow implements Omit<IPublicModelWindow<IResource>, 'changeViewType' | 'currentEditorView' | 'editorViews'> { id: string = uniqueId('window'); icon: React.ReactElement | undefined; diff --git a/packages/workspace/src/workspace.ts b/packages/workspace/src/workspace.ts index 9f1abaa0fb..d7b5a1ea5a 100644 --- a/packages/workspace/src/workspace.ts +++ b/packages/workspace/src/workspace.ts @@ -1,6 +1,6 @@ -import { IDesigner, ILowCodePluginManager, LowCodePluginManager } from '@alilc/lowcode-designer'; -import { createModuleEventBus, Editor, IEditor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core'; -import { IPublicApiPlugins, IPublicApiWorkspace, IPublicEnumPluginRegisterLevel, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types'; +import { IDesigner, LowCodePluginManager } from '@alilc/lowcode-designer'; +import { createModuleEventBus, IEditor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core'; +import { IPublicApiPlugins, IPublicApiWorkspace, IPublicEnumPluginRegisterLevel, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types'; import { BasicContext } from './context/base-context'; import { EditorWindow, WINDOW_STATE } from './window'; import type { IEditorWindow } from './window'; @@ -20,56 +20,11 @@ enum EVENT { const CHANGE_EVENT = 'resource.list.change'; -export interface IWorkspace extends Omit<IPublicApiWorkspace< +export class Workspace implements Omit<IPublicApiWorkspace< LowCodePluginManager, + ISkeleton, IEditorWindow >, 'resourceList' | 'plugins' | 'openEditorWindow' | 'removeEditorWindow'> { - readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<IPublicTypeDisposable>; - - readonly shellModelFactory: IShellModelFactory; - - enableAutoOpenFirstWindow: boolean; - - window: IEditorWindow; - - plugins: ILowCodePluginManager; - - skeleton: ISkeleton; - - resourceTypeMap: Map<string, ResourceType>; - - getResourceList(): IResource[]; - - getResourceType(resourceName: string): IResourceType; - - checkWindowQueue(): void; - - emitWindowRendererReady(): void; - - initWindow(): void; - - setActive(active: boolean): void; - - onChangeActiveEditorView(fn: () => void): IPublicTypeDisposable; - - emitChangeActiveEditorView(): void; - - openEditorWindowByResource(resource: IResource, sleep: boolean): Promise<void>; - - /** - * @deprecated - */ - removeEditorWindow(resourceName: string, id: string): void; - - removeEditorWindowByResource(resource: IResource): void; - - /** - * @deprecated - */ - openEditorWindow(name: string, title: string, options: Object, viewName?: string, sleep?: boolean): Promise<void>; -} - -export class Workspace implements IWorkspace { context: BasicContext; enableAutoOpenFirstWindow: boolean; @@ -377,3 +332,5 @@ export class Workspace implements IWorkspace { }; } } + +export interface IWorkspace extends Workspace {} \ No newline at end of file From d66f712174304b637822f6888912cd7a15cac403 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?= <liujup@foxmail.com> Date: Thu, 29 Feb 2024 15:18:14 +0800 Subject: [PATCH 337/361] Update commonUI.md --- docs/docs/api/commonUI.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/api/commonUI.md b/docs/docs/api/commonUI.md index 45640051f2..e997ac0033 100644 --- a/docs/docs/api/commonUI.md +++ b/docs/docs/api/commonUI.md @@ -3,6 +3,8 @@ title: commonUI - UI 组件库 sidebar_position: 10 --- +> **@since** v1.3.0 + ## 简介 CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开发的插件,可以保证在不同项目和主题切换中能够保持一致性和兼容性。 From 4465866433280577bd775b14eba6488244d2b98e Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 29 Feb 2024 08:48:58 +0000 Subject: [PATCH 338/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 574ff28787..1e203302bf 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.32", + "version": "1.2.33", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 40eb152a4e2e07e16d12ed6d5441ce4937f07241 Mon Sep 17 00:00:00 2001 From: DiscoverForever <595740536@qq.com> Date: Wed, 28 Feb 2024 14:57:51 +0800 Subject: [PATCH 339/361] =?UTF-8?q?docs:=20fix=20incorrect=20word,=20chang?= =?UTF-8?q?e=20"=E6=90=9C=E6=90=9C"=20to=20"=E6=90=9C=E7=B4=A2"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复readme中的错别字,"搜搜"修改为"搜索"。 --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 85da75163c..78ca200063 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,7 +36,7 @@ $ yarn build ## 功能 -- [x] 支持本地离线搜搜 +- [x] 支持本地离线搜索 - [x] 版本化文档管理 - [x] 离线静态部署 - [x] 主题(fork 宜搭开发者中心) From 814d046a43bb5772d679a6b17f4273b174c6aac5 Mon Sep 17 00:00:00 2001 From: zzzhrookie <zzh7498624@163.com> Date: Tue, 27 Feb 2024 23:21:17 +0800 Subject: [PATCH 340/361] docs(chore): fix incorrect link redirects within lowcode-spec.md --- docs/docs/specs/lowcode-spec.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index c277214106..409883aa9f 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -20,7 +20,7 @@ sidebar_position: 0 ### 1.2 协议草案起草人 - 撰写:月飞、康为、林熠 -- 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、戊子、游鹿、光弘、力皓 +- 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、游鹿、光弘、力皓 ### 1.3 版本号 @@ -430,7 +430,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | | list[] | 数据源列表 | **ComponentDataSourceItem**[] | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) | -| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function 描述) | +| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function-描述) | ##### 2.3.1.4 ComponentDataSourceItem 对象描述 @@ -447,7 +447,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; | errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 | | options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见 | 每种请求类型对应不同参数,详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | -**关于 dataHandler 于 errorHandler 的细节说明:** +**关于 dataHandler 与 errorHandler 的细节说明:** request 返回的是一个 promise,dataHandler 和 errorHandler 遵循 Promise 对象的 then 方法,实际使用方式如下: @@ -560,7 +560,7 @@ try { | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | | id | 组件唯一标识 | String | - | | 可选,组件 id 由引擎随机生成(UUID),并保证唯一性,消费方为上层应用平台,在组件发生移动等场景需保持 id 不变 | -| componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系 a) 中的要求 | +| componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系a) 中的要求 | | props {} | 组件属性对象 | **Props**| - | {} | 必填,详见 | 必填,详见 [Props 结构描述](#2311-props-结构描述) | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 | @@ -797,7 +797,7 @@ try { | 参数 | 说明 | 值类型 | 默认值 | 备注 | | ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- | | type | 值类型描述 | String | 'JSSlot' | 固定值 | -| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) | +| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | | params | 函数的参数 | String[] | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 | @@ -1124,7 +1124,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 })); | utils[] | 工具类扩展映射关系 | **UtilItem**[] | - | | | *UtilItem*.name | 工具类扩展项名称 | String | - | | | *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | -| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | | +| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系a) 或 [JSFunction](#2342事件函数类型a) | - | | 描述示例: From 98e9179f23d9898fbb8820f0bc2639ba184119a2 Mon Sep 17 00:00:00 2001 From: zzzhrookie <zzh7498624@163.com> Date: Tue, 27 Feb 2024 23:21:32 +0800 Subject: [PATCH 341/361] docs(chore): update command for developing docs --- docs/docs/participate/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md index e09f2ddad2..7f6452fb1c 100644 --- a/docs/docs/participate/index.md +++ b/docs/docs/participate/index.md @@ -70,7 +70,7 @@ npm start 在 lowcode-engine 目录下执行下面命令 ``` cd docs - +npm install npm start ``` From 72a5a279c36b2b85c7797d5904a5652d6abda90c Mon Sep 17 00:00:00 2001 From: zzzhrookie <zzh7498624@163.com> Date: Wed, 28 Feb 2024 10:05:40 +0800 Subject: [PATCH 342/361] docs(chore): replace English parentheses with Chinese ones --- docs/docs/specs/lowcode-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index 409883aa9f..4806983543 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -94,7 +94,7 @@ sidebar_position: 0 ### 1.9 使用范围 -本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; +本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; ### 1.10 协议目标 From d986beedbcf57f87e7f22bf3ec4e391680054c7b Mon Sep 17 00:00:00 2001 From: zzzhrookie <zzh7498624@163.com> Date: Wed, 28 Feb 2024 17:19:36 +0800 Subject: [PATCH 343/361] docs(chore): fix incorrect module name --- docs/docs/guide/create/useRenderer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/create/useRenderer.md b/docs/docs/guide/create/useRenderer.md index a9fc79909e..9a577bac6f 100644 --- a/docs/docs/guide/create/useRenderer.md +++ b/docs/docs/guide/create/useRenderer.md @@ -20,7 +20,7 @@ sidebar_position: 1 [在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有渲染模块的示例使用方式: ![Mar-13-2022 16-52-49.gif](https://img.alicdn.com/imgextra/i2/O1CN01PRsEl61o7Zct5fJML_!!6000000005178-1-tps-1534-514.gif) -基于官方提供的渲染模块 [@alifd/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。 +基于官方提供的渲染模块 [@alilc/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。 ### 构造渲染模块所需数据 From cc45087225f1aa7bd2e9260e782b83abdc2bfce0 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 1 Mar 2024 00:27:33 +0000 Subject: [PATCH 344/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 1e203302bf..dfe270bac7 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.33", + "version": "1.2.34", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 7cecf91a2528a23713e7649df096ee4394bb4204 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 29 Feb 2024 18:02:29 +0800 Subject: [PATCH 345/361] feat(hotkey): Add mount method to Hotkey class --- docs/docs/api/hotkey.md | 13 +++++++++++++ packages/designer/src/project/project.ts | 2 +- packages/editor-core/src/command.ts | 10 ++-------- packages/editor-core/src/hotkey.ts | 11 ++++++----- packages/shell/src/api/hotkey.ts | 8 ++++++++ packages/types/src/shell/api/hotkey.ts | 6 ++++++ 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/docs/docs/api/hotkey.md b/docs/docs/api/hotkey.md index be6a3033d0..b391e367b4 100644 --- a/docs/docs/api/hotkey.md +++ b/docs/docs/api/hotkey.md @@ -32,6 +32,19 @@ bind( - [IPublicTypeHotkeyCallback](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/hotkey-callback.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) +### mount + +给指定窗口绑定快捷键 + +```typescript +/** + * 给指定窗口绑定快捷键 + * @param window 窗口的 window 对象 + */ +mount(window: Window): IPublicTypeDisposable; + +``` + ## 使用示例 ### 基础示例 diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 94913d9fa7..88978e4678 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -68,7 +68,7 @@ export interface IProject extends Omit<IBaseApiProject< onCurrentDocumentChange(fn: (doc: IDocumentModel) => void): () => void; - onSimulatorReady(fn: (args: any) => void): () => void; + onSimulatorReady(fn: (simulator: ISimulatorHost) => void): () => void; onRendererReady(fn: () => void): () => void; diff --git a/packages/editor-core/src/command.ts b/packages/editor-core/src/command.ts index 7facc33d94..04bd5ba5ae 100644 --- a/packages/editor-core/src/command.ts +++ b/packages/editor-core/src/command.ts @@ -1,18 +1,12 @@ import { IPublicApiCommand, IPublicEnumTransitionType, IPublicModelPluginContext, IPublicTypeCommand, IPublicTypeCommandHandlerArgs, IPublicTypeListCommand } from '@alilc/lowcode-types'; import { checkPropTypes } from '@alilc/lowcode-utils'; -export interface ICommand extends Omit<IPublicApiCommand, 'registerCommand' | 'batchExecuteCommand'> { - registerCommand(command: IPublicTypeCommand, options?: { - commandScope?: string; - }): void; - - batchExecuteCommand(commands: { name: string; args: IPublicTypeCommandHandlerArgs }[], pluginContext?: IPublicModelPluginContext): void; -} +export interface ICommand extends Command {} export interface ICommandOptions { commandScope?: string; } -export class Command implements ICommand { +export class Command implements Omit<IPublicApiCommand, 'registerCommand' | 'batchExecuteCommand'> { private commands: Map<string, IPublicTypeCommand> = new Map(); private commandErrors: Function[] = []; diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index d0dd40cc24..496cec2513 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -1,6 +1,6 @@ import { isEqual } from 'lodash'; import { globalContext } from './di'; -import { IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbackConfig, IPublicTypeHotkeyCallbacks, IPublicApiHotkey } from '@alilc/lowcode-types'; +import { IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbackConfig, IPublicTypeHotkeyCallbacks, IPublicApiHotkey, IPublicTypeDisposable } from '@alilc/lowcode-types'; interface KeyMap { [key: number]: string; @@ -339,11 +339,10 @@ function fireCallback(callback: IPublicTypeHotkeyCallback, e: KeyboardEvent, com } } -export interface IHotKey extends Omit<IPublicApiHotkey, 'bind' | 'callbacks'> { - activate(activate: boolean): void; +export interface IHotKey extends Hotkey { } -export class Hotkey implements IHotKey { +export class Hotkey implements Omit<IPublicApiHotkey, 'bind' | 'callbacks'> { callBacks: IPublicTypeHotkeyCallbacks = {}; private directMap: HotkeyDirectMap = {}; @@ -368,7 +367,7 @@ export class Hotkey implements IHotKey { this.isActivate = activate; } - mount(window: Window) { + mount(window: Window): IPublicTypeDisposable { const { document } = window; const handleKeyEvent = this.handleKeyEvent.bind(this); document.addEventListener('keypress', handleKeyEvent, false); @@ -542,6 +541,8 @@ export class Hotkey implements IHotKey { } private handleKeyEvent(e: KeyboardEvent): void { + console.log(e); + // debugger; if (!this.isActivate) { return; } diff --git a/packages/shell/src/api/hotkey.ts b/packages/shell/src/api/hotkey.ts index 4e65844ceb..78a782994e 100644 --- a/packages/shell/src/api/hotkey.ts +++ b/packages/shell/src/api/hotkey.ts @@ -50,4 +50,12 @@ export class Hotkey implements IPublicApiHotkey { this[hotkeySymbol].unbind(combos, callback, action); }; } + + /** + * 给指定窗口绑定快捷键 + * @param window 窗口的 window 对象 + */ + mount(window: Window) { + return this[hotkeySymbol].mount(window); + } } \ No newline at end of file diff --git a/packages/types/src/shell/api/hotkey.ts b/packages/types/src/shell/api/hotkey.ts index 894eb0e2f9..55bde5d015 100644 --- a/packages/types/src/shell/api/hotkey.ts +++ b/packages/types/src/shell/api/hotkey.ts @@ -22,4 +22,10 @@ export interface IPublicApiHotkey { callback: IPublicTypeHotkeyCallback, action?: string, ): IPublicTypeDisposable; + + /** + * 给指定窗口绑定快捷键 + * @param window 窗口的 window 对象 + */ + mount(window: Window): IPublicTypeDisposable; } From d7dfde5452b2dd3e9e4fcd934708ecd03b0f60ba Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Fri, 1 Mar 2024 01:35:48 +0000 Subject: [PATCH 346/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index dfe270bac7..7c644de33c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.34", + "version": "1.2.35", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 71f9e08cb25cf2bde709a644034e49340b8356fd Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 6 Mar 2024 16:38:19 +0800 Subject: [PATCH 347/361] fix: remove console.log statements, update test, and purge children in NodeChildren class --- packages/designer/jest.config.js | 1 + .../src/designer/setting/setting-field.ts | 54 +----------------- .../src/designer/setting/setting-top-entry.ts | 56 ++++++++----------- .../src/document/node/node-children.ts | 5 ++ packages/designer/src/document/node/node.ts | 2 +- .../setting/setting-top-entry.test.ts | 23 +++++++- packages/editor-core/src/hotkey.ts | 2 - .../src/components/settings/main.ts | 20 ++++--- .../settings/settings-primary-pane.tsx | 19 +++---- 9 files changed, 77 insertions(+), 105 deletions(-) diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 3684a48acb..0d0f7f8f8c 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -22,6 +22,7 @@ const jestConfig = { // testMatch: ['**/selection.test.ts'], // testMatch: ['**/plugin/sequencify.test.ts'], // testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'], + // testMatch: ['**/setting/setting-top-entry.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index 1a63fb7a40..39b0b1e302 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -1,4 +1,3 @@ -import { ReactNode } from 'react'; import { IPublicTypeTitleContent, IPublicTypeSetterType, @@ -7,18 +6,15 @@ import { IPublicTypeFieldConfig, IPublicTypeCustomView, IPublicTypeDisposable, - IPublicModelSettingField, - IBaseModelSettingField, } from '@alilc/lowcode-types'; import type { IPublicTypeSetValueOptions, } from '@alilc/lowcode-types'; import { Transducer } from './utils'; -import { ISettingPropEntry, SettingPropEntry } from './setting-prop-entry'; +import { SettingPropEntry } from './setting-prop-entry'; import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core'; import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils'; import { ISettingTopEntry } from './setting-top-entry'; -import { IComponentMeta, INode } from '@alilc/lowcode-designer'; function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) { let cur = parent; @@ -32,53 +28,9 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c return path.join('.'); } -export interface ISettingField extends ISettingPropEntry, Omit<IBaseModelSettingField< - ISettingTopEntry, - ISettingField, - IComponentMeta, - INode ->, 'setValue' | 'key' | 'node'> { - readonly isSettingField: true; +export interface ISettingField extends SettingField {} - readonly isRequired: boolean; - - readonly isGroup: boolean; - - extraProps: IPublicTypeFieldExtraProps; - - get items(): Array<ISettingField | IPublicTypeCustomView>; - - get title(): string | ReactNode | undefined; - - get setter(): IPublicTypeSetterType | null; - - get expanded(): boolean; - - get valueState(): number; - - setExpanded(value: boolean): void; - - purge(): void; - - setValue( - val: any, - isHotValue?: boolean, - force?: boolean, - extraOptions?: IPublicTypeSetValueOptions, - ): void; - - clearValue(): void; - - valueChange(options: IPublicTypeSetValueOptions): void; - - createField(config: IPublicTypeFieldConfig): ISettingField; - - onEffect(action: () => void): IPublicTypeDisposable; - - internalToShellField(): IPublicModelSettingField; -} - -export class SettingField extends SettingPropEntry implements ISettingField { +export class SettingField extends SettingPropEntry { readonly isSettingField = true; readonly isRequired: boolean; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 85be74b7f6..850cd165ed 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,6 +1,6 @@ import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types'; import { isCustomView } from '@alilc/lowcode-utils'; -import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; +import { computed, IEventBus, createModuleEventBus, obx, makeObservable } from '@alilc/lowcode-editor-core'; import { ISettingEntry } from './setting-entry-type'; import { ISettingField, SettingField } from './setting-field'; import { INode } from '../../document'; @@ -14,33 +14,17 @@ function generateSessionId(nodes: INode[]) { .join(','); } -export interface ISettingTopEntry extends ISettingEntry, IPublicModelSettingTopEntry< +export interface ISettingTopEntry extends SettingTopEntry {} + +export class SettingTopEntry implements ISettingEntry, IPublicModelSettingTopEntry< INode, ISettingField > { - readonly top: ISettingTopEntry; - - readonly parent: ISettingTopEntry; - - readonly path: never[]; - - items: Array<ISettingField | IPublicTypeCustomView>; - - componentMeta: IComponentMeta | null; - - purge(): void; - - getExtraPropValue(propName: string): void; - - setExtraPropValue(propName: string, value: any): void; -} - -export class SettingTopEntry implements ISettingTopEntry { private emitter: IEventBus = createModuleEventBus('SettingTopEntry'); - private _items: Array<SettingField | IPublicTypeCustomView> = []; + private _items: Array<ISettingField | IPublicTypeCustomView> = []; - private _componentMeta: IComponentMeta | null = null; + private _componentMeta: IComponentMeta | null | undefined = null; private _isSame = true; @@ -75,7 +59,7 @@ export class SettingTopEntry implements ISettingTopEntry { } get isLocked(): boolean { - return this.first.isLocked; + return this.first?.isLocked ?? false; } /** @@ -87,7 +71,11 @@ export class SettingTopEntry implements ISettingTopEntry { readonly id: string; - readonly first: INode; + @computed get first(): INode | null { + return this._first; + } + + @obx.ref _first: INode | null; readonly designer: IDesigner | undefined; @@ -96,12 +84,14 @@ export class SettingTopEntry implements ISettingTopEntry { disposeFunctions: any[] = []; constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) { + makeObservable(this); + if (!Array.isArray(nodes) || nodes.length < 1) { throw new ReferenceError('nodes should not be empty'); } this.id = generateSessionId(nodes); - this.first = nodes[0]; - this.designer = this.first.document?.designer; + this._first = nodes[0]; + this.designer = this._first.document?.designer; this.setters = editor.get('setters') as IPublicApiSetters; // setups @@ -116,7 +106,7 @@ export class SettingTopEntry implements ISettingTopEntry { private setupComponentMeta() { // todo: enhance compile a temp configure.compiled const { first } = this; - const meta = first.componentMeta; + const meta = first?.componentMeta; const l = this.nodes.length; let theSame = true; for (let i = 1; i < l; i++) { @@ -160,7 +150,7 @@ export class SettingTopEntry implements ISettingTopEntry { /** * 获取当前属性值 */ - @computed getValue(): any { + getValue(): any { return this.first?.propsData; } @@ -202,14 +192,14 @@ export class SettingTopEntry implements ISettingTopEntry { * 获取子级属性值 */ getPropValue(propName: string | number): any { - return this.first.getProp(propName.toString(), true)?.getValue(); + return this.first?.getProp(propName.toString(), true)?.getValue(); } /** * 获取顶层附属属性值 */ getExtraPropValue(propName: string) { - return this.first.getExtraProp(propName, false)?.getValue(); + return this.first?.getExtraProp(propName, false)?.getValue(); } /** @@ -244,8 +234,9 @@ export class SettingTopEntry implements ISettingTopEntry { this.disposeItems(); this._settingFieldMap = {}; this.emitter.removeAllListeners(); - this.disposeFunctions.forEach(f => f()); + this.disposeFunctions.forEach(f => f?.()); this.disposeFunctions = []; + this._first = null; } getProp(propName: string | number) { @@ -274,7 +265,7 @@ export class SettingTopEntry implements ISettingTopEntry { } getPage() { - return this.first.document; + return this.first?.document; } /** @@ -292,6 +283,7 @@ export class SettingTopEntry implements ISettingTopEntry { interface Purgeable { purge(): void; } + function isPurgeable(obj: any): obj is Purgeable { return obj && obj.purge; } diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index b7f03d9fee..d374daa8e2 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -91,6 +91,7 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, node.import(item); } else { node = this.owner.document?.createNode(item); + child?.purge(); } if (node) { @@ -98,6 +99,10 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, } } + for (let i = data.length; i < originChildren.length; i++) { + originChildren[i].purge(); + } + this.children = children; this.internalInitParent(); if (!shallowEqual(children, originChildren)) { diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 0b698831e9..04c72a8fd7 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -987,7 +987,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> this.autoruns?.forEach((dispose) => dispose()); this.props.purge(); this.settingEntry?.purge(); - // this.document.destroyNode(this); + this.children?.purge(); } internalPurgeStart() { diff --git a/packages/designer/tests/designer/setting/setting-top-entry.test.ts b/packages/designer/tests/designer/setting/setting-top-entry.test.ts index 23a42c2afc..e5234690cd 100644 --- a/packages/designer/tests/designer/setting/setting-top-entry.test.ts +++ b/packages/designer/tests/designer/setting/setting-top-entry.test.ts @@ -1,8 +1,9 @@ import '../../fixtures/window'; -import { Editor, Setters } from '@alilc/lowcode-editor-core'; +import { Editor, Setters, reaction } from '@alilc/lowcode-editor-core'; import { Node } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; import settingSchema from '../../fixtures/schema/setting'; +import { SettingTopEntry } from '../../../src/designer/setting/setting-top-entry'; import divMeta from '../../fixtures/component-metadata/div'; import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; @@ -109,6 +110,26 @@ describe('setting-top-entry 测试', () => { expect(settingEntry.items).toHaveLength(0); }); + it('should notify when _first is set to null', (done) => { + // 创建一个简单的INode数组用于初始化SettingTopEntry实例 + const nodes = [{ id: '1', propsData: {} }, { id: '2', propsData: {} }]; + const entry = new SettingTopEntry(editor as any, nodes as any); + + // 使用MobX的reaction来观察_first属性的变化 + const dispose = reaction( + () => entry.first, + (first) => { + if (first === null) { + dispose(); // 清理reaction监听 + done(); // 结束测试 + } + } + ); + + // 执行purge方法,期望_first被设置为null,触发reaction回调 + entry.purge(); + }); + it('vision 兼容测试', () => { designer.createComponentMeta(divMeta); designer.project.open(settingSchema); diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index 496cec2513..e3482ab4d7 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -541,8 +541,6 @@ export class Hotkey implements Omit<IPublicApiHotkey, 'bind' | 'callbacks'> { } private handleKeyEvent(e: KeyboardEvent): void { - console.log(e); - // debugger; if (!this.isActivate) { return; } diff --git a/packages/editor-skeleton/src/components/settings/main.ts b/packages/editor-skeleton/src/components/settings/main.ts index 6cc672c907..3cca2c861a 100644 --- a/packages/editor-skeleton/src/components/settings/main.ts +++ b/packages/editor-skeleton/src/components/settings/main.ts @@ -1,7 +1,7 @@ -import { Node, Designer, Selection, SettingTopEntry } from '@alilc/lowcode-designer'; +import { INode, IDesigner, Selection, SettingTopEntry } from '@alilc/lowcode-designer'; import { Editor, obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -function generateSessionId(nodes: Node[]) { +function generateSessionId(nodes: INode[]) { return nodes .map((node) => node.id) .sort() @@ -29,7 +29,11 @@ export class SettingsMain { private disposeListener: () => void; - private designer?: Designer; + private _designer?: IDesigner; + + get designer(): IDesigner | undefined { + return this._designer; + } constructor(readonly editor: Editor) { makeObservable(this); @@ -49,12 +53,12 @@ export class SettingsMain { this.editor.removeListener('designer.selection.change', setupSelection); }; const designer = await this.editor.onceGot('designer'); - this.designer = designer; + this._designer = designer; setupSelection(designer.currentSelection); } @action - private setup(nodes: Node[]) { + private setup(nodes: INode[]) { // check nodes change const sessionId = generateSessionId(nodes); if (sessionId === this._sessionId) { @@ -66,15 +70,15 @@ export class SettingsMain { return; } - if (!this.designer) { - this.designer = nodes[0].document.designer; + if (!this._designer) { + this._designer = nodes[0].document.designer; } // 当节点只有一个时,复用 node 上挂载的 settingEntry,不会产生平行的两个实例,这样在整个系统中对 // 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例 if (nodes.length === 1) { this._settings = nodes[0].settingEntry; } else { - this._settings = this.designer.createSettingEntry(nodes); + this._settings = this._designer.createSettingEntry(nodes); } } diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 747a2ea1df..b2eb8c7a8a 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -1,14 +1,14 @@ import React, { Component } from 'react'; import { Tab, Breadcrumb } from '@alifd/next'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; -import { Node, SettingField, isSettingField, INode } from '@alilc/lowcode-designer'; +import { ISettingField, INode } from '@alilc/lowcode-designer'; import classNames from 'classnames'; import { SettingsMain } from './main'; import { SettingsPane } from './settings-pane'; import { StageBox } from '../stage-box'; import { SkeletonContext } from '../../context'; import { intl } from '../../locale'; -import { createIcon } from '@alilc/lowcode-utils'; +import { createIcon, isSettingField } from '@alilc/lowcode-utils'; interface ISettingsPrimaryPaneProps { engineEditor: Editor; @@ -53,8 +53,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { } renderBreadcrumb() { - const { settings, editor } = this.main; - // const shouldIgnoreRoot = config.props?.ignoreRoot; + const { settings, editor, designer } = this.main; const { shouldIgnoreRoot } = this.state; if (!settings) { return null; @@ -73,10 +72,9 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { ); } - const designer = editor.get('designer'); const current = designer?.currentSelection?.getNodes()?.[0]; let node: INode | null = settings.first; - const focusNode = node.document?.focusNode; + const focusNode = node?.document?.focusNode; const items = []; let l = 3; @@ -202,7 +200,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { } let matched = false; - const tabs = (items as SettingField[]).map((field) => { + const tabs = (items as ISettingField[]).map((field) => { if (this._activeKey === field.name) { matched = true; } @@ -235,7 +233,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { </Tab.Item> ); }); - const activeKey = matched ? this._activeKey : (items[0] as SettingField).name; + const activeKey = matched ? this._activeKey : (items[0] as ISettingField).name; const className = classNames('lc-settings-main', { 'lc-settings-hide-tabs': @@ -261,9 +259,10 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { } } -function hoverNode(node: Node, flag: boolean) { +function hoverNode(node: INode, flag: boolean) { node.hover(flag); } -function selectNode(node: Node) { + +function selectNode(node: INode) { node?.select(); } From 0d7ae43b79f7d3f0569806dc371d791a429ed4e5 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 6 Mar 2024 16:50:20 +0800 Subject: [PATCH 348/361] fix: refactor splice method to remove and purge nodes*** --- packages/designer/src/document/node/node-children.ts | 10 ++++++++-- packages/shell/src/model/node-children.ts | 5 +++-- packages/types/src/shell/model/node-children.ts | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index d374daa8e2..2ce2d07de1 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -307,10 +307,16 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, * */ splice(start: number, deleteCount: number, node?: INode): INode[] { + let removedNode; if (node) { - return this.children.splice(start, deleteCount, node); + removedNode = this.children.splice(start, deleteCount, node); + } else { + removedNode = this.children.splice(start, deleteCount); } - return this.children.splice(start, deleteCount); + + removedNode.forEach(d => d?.purge()); + + return removedNode; } /** diff --git a/packages/shell/src/model/node-children.ts b/packages/shell/src/model/node-children.ts index b6d52e86fe..c4e336aa0b 100644 --- a/packages/shell/src/model/node-children.ts +++ b/packages/shell/src/model/node-children.ts @@ -97,8 +97,9 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param deleteCount * @param node */ - splice(start: number, deleteCount: number, node?: IPublicModelNode): any { - this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); + splice(start: number, deleteCount: number, node?: IPublicModelNode): IPublicModelNode[] { + const removedNode = this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); + return removedNode.map((item: InnerNode) => ShellNode.create(item)!); } /** diff --git a/packages/types/src/shell/model/node-children.ts b/packages/types/src/shell/model/node-children.ts index f2be13250b..207db5672d 100644 --- a/packages/types/src/shell/model/node-children.ts +++ b/packages/types/src/shell/model/node-children.ts @@ -78,7 +78,7 @@ export interface IPublicModelNodeChildren< * @param deleteCount * @param node */ - splice(start: number, deleteCount: number, node?: Node): any; + splice(start: number, deleteCount: number, node?: Node): Node[]; /** * 返回指定下标的节点 From d2138d7edb4469eba2daf612dbca426f94370d66 Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Wed, 6 Mar 2024 17:20:51 +0800 Subject: [PATCH 349/361] fix: fix node parent assignment and update settings check --- packages/designer/src/document/node/node-children.ts | 1 + packages/designer/src/document/node/node.ts | 3 ++- .../designer/tests/document/node/node-children.test.ts | 10 ++++++++++ .../src/components/settings/settings-primary-pane.tsx | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 2ce2d07de1..48503ba6c6 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -310,6 +310,7 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, let removedNode; if (node) { removedNode = this.children.splice(start, deleteCount, node); + node.internalSetParent(this.owner); } else { removedNode = this.children.splice(start, deleteCount); } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 04c72a8fd7..4155dedb7b 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -197,7 +197,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> isInited = false; - _settingEntry: ISettingTopEntry; + _settingEntry?: ISettingTopEntry; get settingEntry(): ISettingTopEntry { if (this._settingEntry) return this._settingEntry; @@ -988,6 +988,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> this.props.purge(); this.settingEntry?.purge(); this.children?.purge(); + this._settingEntry = undefined; } internalPurgeStart() { diff --git a/packages/designer/tests/document/node/node-children.test.ts b/packages/designer/tests/document/node/node-children.test.ts index 1aa7e3ccb3..b5b2744ff3 100644 --- a/packages/designer/tests/document/node/node-children.test.ts +++ b/packages/designer/tests/document/node/node-children.test.ts @@ -111,6 +111,16 @@ describe('NodeChildren 方法测试', () => { expect(children.length).toBe(2); }); + it('split add node and update node parent', () => { + const firstBtn = doc.getNode('node_k1ow3cbn')!; + const { children } = firstBtn.parent!; + const node = doc.createNode({ componentName: 'Button' }); + + children.splice(0, 0, node); + + expect(node.parent).toBe(firstBtn.parent); + }) + it('map', () => { const firstBtn = doc.getNode('node_k1ow3cbn')!; const { children } = firstBtn.parent!; diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index b2eb8c7a8a..3aaa9435ac 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -134,7 +134,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { render() { const { settings } = this.main; const editor = this.props.engineEditor; - if (!settings) { + if (!settings || !settings.first) { // 未选中节点,提示选中 或者 显示根节点设置 return ( <div className="lc-settings-main"> From dc98670c378d36d6671ccd9c2b97fd03dcdc758f Mon Sep 17 00:00:00 2001 From: liujuping <liujup@foxmail.com> Date: Thu, 7 Mar 2024 11:09:11 +0800 Subject: [PATCH 350/361] fix: update import statements to use type imports --- packages/designer/src/designer/dragon.ts | 2 +- .../src/designer/setting/setting-entry-type.ts | 8 ++++---- .../designer/src/designer/setting/setting-field.ts | 6 +++--- .../src/designer/setting/setting-prop-entry.ts | 12 ++++++------ .../src/designer/setting/setting-top-entry.ts | 9 +++++---- packages/designer/src/document/document-model.ts | 6 +++--- packages/designer/src/document/document-view.tsx | 2 +- packages/designer/src/document/history.ts | 2 +- packages/designer/src/document/node/node-children.ts | 10 +++++----- packages/designer/src/document/node/node.ts | 6 +++--- .../src/components/settings/settings-pane.tsx | 4 ++-- .../components/settings/settings-primary-pane.tsx | 2 +- 12 files changed, 35 insertions(+), 34 deletions(-) diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index 5c4d0648d4..f96b667b1d 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -13,7 +13,7 @@ import { import { setNativeSelection, cursor } from '@alilc/lowcode-utils'; import { INode, Node } from '../document'; import { ISimulatorHost, isSimulatorHost } from '../simulator'; -import { IDesigner } from './designer'; +import type { IDesigner } from './designer'; import { makeEventsHandler } from '../utils/misc'; export interface ILocateEvent extends IPublicModelLocateEvent { diff --git a/packages/designer/src/designer/setting/setting-entry-type.ts b/packages/designer/src/designer/setting/setting-entry-type.ts index 1aee9016e5..5cbe232abe 100644 --- a/packages/designer/src/designer/setting/setting-entry-type.ts +++ b/packages/designer/src/designer/setting/setting-entry-type.ts @@ -1,7 +1,7 @@ -import { IPublicApiSetters, IPublicModelEditor } from '@alilc/lowcode-types'; -import { IDesigner } from '../designer'; -import { INode } from '../../document'; -import { ISettingField } from './setting-field'; +import type { IPublicApiSetters, IPublicModelEditor } from '@alilc/lowcode-types'; +import type { IDesigner } from '../designer'; +import type { INode } from '../../document'; +import type { ISettingField } from './setting-field'; export interface ISettingEntry { readonly designer: IDesigner | undefined; diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index 39b0b1e302..87415dd98a 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -14,7 +14,7 @@ import { Transducer } from './utils'; import { SettingPropEntry } from './setting-prop-entry'; import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core'; import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils'; -import { ISettingTopEntry } from './setting-top-entry'; +import type { ISettingTopEntry } from './setting-top-entry'; function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) { let cur = parent; @@ -28,8 +28,6 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c return path.join('.'); } -export interface ISettingField extends SettingField {} - export class SettingField extends SettingPropEntry { readonly isSettingField = true; @@ -273,3 +271,5 @@ export class SettingField extends SettingPropEntry { export function isSettingField(obj: any): obj is ISettingField { return obj && obj.isSettingField; } + +export type ISettingField = typeof SettingField; diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index d6904f0c82..6cce4cddcc 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -1,12 +1,12 @@ import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { GlobalEvent, IPublicApiSetters, IPublicModelEditor, IPublicModelSettingField, IPublicTypeFieldExtraProps, IPublicTypeSetValueOptions } from '@alilc/lowcode-types'; -import { uniqueId, isJSExpression } from '@alilc/lowcode-utils'; -import { ISettingEntry } from './setting-entry-type'; -import { INode } from '../../document'; +import { uniqueId, isJSExpression, isSettingField } from '@alilc/lowcode-utils'; +import type { ISettingEntry } from './setting-entry-type'; +import type { INode } from '../../document'; import type { IComponentMeta } from '../../component-meta'; -import { IDesigner } from '../designer'; -import { ISettingTopEntry } from './setting-top-entry'; -import { ISettingField, isSettingField } from './setting-field'; +import type { IDesigner } from '../designer'; +import type { ISettingTopEntry } from './setting-top-entry'; +import type { ISettingField } from './setting-field'; export interface ISettingPropEntry extends ISettingEntry { readonly isGroup: boolean; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 850cd165ed..3a17397880 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,11 +1,12 @@ import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types'; import { isCustomView } from '@alilc/lowcode-utils'; import { computed, IEventBus, createModuleEventBus, obx, makeObservable } from '@alilc/lowcode-editor-core'; -import { ISettingEntry } from './setting-entry-type'; -import { ISettingField, SettingField } from './setting-field'; -import { INode } from '../../document'; +import { SettingField } from './setting-field'; +import type { ISettingEntry } from './setting-entry-type'; +import type { ISettingField } from './setting-field'; +import type { INode } from '../../document'; import type { IComponentMeta } from '../../component-meta'; -import { IDesigner } from '../designer'; +import type { IDesigner } from '../designer'; function generateSessionId(nodes: INode[]) { return nodes diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 2938395a97..dd9258fc11 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -37,10 +37,10 @@ import { isDragNodeDataObject, isNode, } from '@alilc/lowcode-utils'; -import { IProject } from '../project'; -import { ISimulatorHost } from '../simulator'; +import type { IProject } from '../project'; +import type { ISimulatorHost } from '../simulator'; import type { IComponentMeta } from '../component-meta'; -import { IDesigner, IHistory } from '../designer'; +import type { IDesigner, IHistory } from '../designer'; import { insertChildren, insertChild, IRootNode } from './node/node'; import type { INode } from './node/node'; import { Selection, ISelection } from './selection'; diff --git a/packages/designer/src/document/document-view.tsx b/packages/designer/src/document/document-view.tsx index c6dbe76a81..ec588e223f 100644 --- a/packages/designer/src/document/document-view.tsx +++ b/packages/designer/src/document/document-view.tsx @@ -1,7 +1,7 @@ import { Component } from 'react'; import classNames from 'classnames'; import { observer } from '@alilc/lowcode-editor-core'; -import { DocumentModel, IDocumentModel } from './document-model'; +import type { IDocumentModel } from './document-model'; import { BuiltinSimulatorHostView } from '../builtin-simulator'; @observer diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index ca288c03a8..10695e235f 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -1,7 +1,7 @@ import { reaction, untracked, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; import { IPublicTypeNodeSchema, IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types'; import { Logger } from '@alilc/lowcode-utils'; -import { IDocumentModel } from '../designer'; +import type { IDocumentModel } from '../designer'; const logger = new Logger({ level: 'warn', bizName: 'history' }); diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 48503ba6c6..0f0c4a4592 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -1,5 +1,5 @@ import { obx, computed, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -import { Node, INode } from './node'; +import type { INode } from './node'; import { IPublicTypeNodeData, IPublicModelNodeChildren, IPublicEnumTransformStage, IPublicTypeDisposable } from '@alilc/lowcode-types'; import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils'; import { foreachReverse } from '../../utils/tree'; @@ -7,7 +7,7 @@ import { NodeRemoveOptions } from '../../types'; export interface IOnChangeOptions { type: string; - node: Node; + node: INode; } export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, @@ -80,7 +80,7 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, const originChildren = this.children.slice(); this.children.forEach((child) => child.internalSetParent(null)); - const children = new Array<Node>(data.length); + const children = new Array<INode>(data.length); for (let i = 0, l = data.length; i < l; i++) { const child = originChildren[i]; const item = data[i]; @@ -169,14 +169,14 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>, if (node.isParentalNode) { foreachReverse( node.children!, - (subNode: Node) => { + (subNode: INode) => { subNode.remove(useMutator, purge, options); }, (iterable, idx) => (iterable as NodeChildren).get(idx), ); foreachReverse( node.slots, - (slotNode: Node) => { + (slotNode: INode) => { slotNode.remove(useMutator, purge); }, (iterable, idx) => (iterable as [])[idx], diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 4155dedb7b..5a43fc15c3 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -18,11 +18,11 @@ import { IBaseModelNode, } from '@alilc/lowcode-types'; import { compatStage, isDOMText, isJSExpression, isNode, isNodeSchema } from '@alilc/lowcode-utils'; -import { ISettingTopEntry } from '@alilc/lowcode-designer'; +import type { ISettingTopEntry } from '@alilc/lowcode-designer'; import { Props, getConvertedExtraKey, IProps } from './props/props'; import type { IDocumentModel } from '../document-model'; import { NodeChildren, INodeChildren } from './node-children'; -import { IProp, Prop } from './props/prop'; +import type { IProp } from './props/prop'; import type { IComponentMeta } from '../../component-meta'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; import type { IExclusiveGroup } from './exclusive-group'; @@ -495,7 +495,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> } } - internalSetSlotFor(slotFor: Prop | null | undefined) { + internalSetSlotFor(slotFor: IProp | null | undefined) { this._slotFor = slotFor; } diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index 1561bf8bbe..4bb23d2923 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -1,9 +1,9 @@ import { Component, MouseEvent, Fragment, ReactNode } from 'react'; import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core'; -import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter } from '@alilc/lowcode-utils'; +import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter, isSettingField } from '@alilc/lowcode-utils'; import { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton'; import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeDynamicProps } from '@alilc/lowcode-types'; -import { ISettingEntry, IComponentMeta, ISettingField, isSettingField, ISettingTopEntry } from '@alilc/lowcode-designer'; +import type { ISettingEntry, IComponentMeta, ISettingField, ISettingTopEntry } from '@alilc/lowcode-designer'; import { createField } from '../field'; import PopupService, { PopupPipe } from '../popup'; import { SkeletonContext } from '../../context'; diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 3aaa9435ac..5231d9f20d 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { Tab, Breadcrumb } from '@alifd/next'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; -import { ISettingField, INode } from '@alilc/lowcode-designer'; +import type { ISettingField, INode } from '@alilc/lowcode-designer'; import classNames from 'classnames'; import { SettingsMain } from './main'; import { SettingsPane } from './settings-pane'; From 4eb80d446e751cb2e1f2485ad8d72ddd754931e2 Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Fri, 22 Mar 2024 17:20:47 +0800 Subject: [PATCH 351/361] fix(plugin-outline): fix the unsynchronized display of the outline tree during history undo --- packages/plugin-outline-pane/src/index.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/plugin-outline-pane/src/index.tsx b/packages/plugin-outline-pane/src/index.tsx index 822c503f27..ba3d1f0778 100644 --- a/packages/plugin-outline-pane/src/index.tsx +++ b/packages/plugin-outline-pane/src/index.tsx @@ -27,6 +27,11 @@ export function OutlinePaneContext(props: { }); }, []); + useEffect(() => { + return props.pluginContext?.project?.currentDocument?.history.onChangeCursor(() => { + setMasterPaneController(new PaneController(props.paneName || MasterPaneName, treeMaster)); + }); + }, [treeMaster]); return ( <Pane treeMaster={treeMaster} @@ -77,6 +82,8 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => { treeTitleExtra: config.get('treeTitleExtra'), treeMaster, paneName: MasterPaneName, + pluginContext: ctx, + options, }, }); @@ -91,6 +98,8 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => { contentProps: { paneName: BackupPaneName, treeMaster, + pluginContext: ctx, + options, }, index: 1, }); From e6ac33f11ceb37ac25c48eb63066b01e9c22aa31 Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Mon, 25 Mar 2024 10:57:32 +0800 Subject: [PATCH 352/361] fix(plugin-outline): fix matched title highlight --- packages/plugin-outline-pane/src/views/tree-title.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index f822bd644b..f70bb89461 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -85,11 +85,15 @@ export default class TreeTitle extends PureComponent<{ componentDidMount() { const { treeNode } = this.props; + const { filterWorking, matchSelf, keywords } = treeNode.filterReult; this.setState({ editing: false, title: treeNode.titleLabel, condition: treeNode.condition, visible: !treeNode.hidden, + filterWorking, + matchSelf, + keywords, }); treeNode.onTitleLabelChanged(() => { this.setState({ From db2f2d6aa201d5d3548f76bbc7c5bbcce681a531 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?= <liujup@foxmail.com> Date: Thu, 28 Mar 2024 11:13:08 +0800 Subject: [PATCH 353/361] Update skeleton.md --- docs/docs/api/skeleton.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 396fad9e9e..3ae0e35245 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -11,8 +11,9 @@ sidebar_position: 10 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01eVA0U41xYRP3e5zo0_!!6000000006455-2-tps-1780-996.png) -页面上可以扩展的区域共 5 个,具体如下: -![image.png](https://img.alicdn.com/imgextra/i3/O1CN014d2AcS1D5c9TshEiQ_!!6000000000165-2-tps-1892-974.png) +页面上可以扩展的区域共 6 个,具体如下: +![image](https://github.com/alibaba/lowcode-engine/assets/11935995/ba4641dd-d346-4ef7-8b71-8ca211e6eaf4) + ### 基本概念 #### 扩展区域位置 (area) ##### topArea @@ -41,6 +42,11 @@ sidebar_position: 10 ##### rightArea 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 + +##### bottomArea + +底部扩展区域。 + ##### toolbar 跟 topArea 类似,按需放置面板插件~ From 816b58c8d0412ce436e93d5e483e3e6be58c1696 Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Mon, 25 Mar 2024 14:35:13 +0800 Subject: [PATCH 354/361] docs(readme): update participation url --- packages/engine/README-zh_CN.md | 3 +-- packages/engine/README.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 5442aa58bd..e6717d689c 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -160,9 +160,8 @@ lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-de ## 🤝 参与共建 请先阅读: -1. [如何配置引擎调试环境?](https://lowcode-engine.cn/site/docs/participate/prepare) +1. [如何配置引擎调试环境?](https://lowcode-engine.cn/site/docs/participate) 2. [关于引擎的研发协作流程](https://lowcode-engine.cn/site/docs/participate/flow) -3. [引擎的工程化配置](https://lowcode-engine.cn/site/docs/participate/config) > 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。(此段参考 [antd](https://github.com/ant-design/ant-design)) diff --git a/packages/engine/README.md b/packages/engine/README.md index ae4e7fd43b..82d8552369 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -160,9 +160,8 @@ After lowcode-engine is started, several umd files are provided, which can be de ## 🤝 Participation Please read first: -1. [How to configure the engine debugging environment? ](https://lowcode-engine.cn/site/docs/participate/prepare) +1. [How to configure the engine debugging environment? ](https://lowcode-engine.cn/site/docs/participate) 2. [About the R&D collaboration process of the engine](https://lowcode-engine.cn/site/docs/participate/flow) -3. [Engineering Configuration of Engine](https://lowcode-engine.cn/site/docs/participate/config) > Strongly recommend reading ["The Wisdom of Asking Questions"](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way), ["How to Ask Questions to the Open Source Community"](https: //github.com/seajs/seajs/issues/545) and [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html), [ "How to Submit Unanswerable Questions to Open Source Projects"](https://zhuanlan.zhihu.com/p/25795393), better questions are easier to get help. (This paragraph refers to [antd](https://github.com/ant-design/ant-design)) From c1dce149794462599de7d54ebf686da815dcb259 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?= <liujup@foxmail.com> Date: Thu, 28 Mar 2024 15:01:36 +0800 Subject: [PATCH 355/361] Update npms.md --- docs/docs/guide/appendix/npms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guide/appendix/npms.md b/docs/docs/guide/appendix/npms.md index b0292c2739..257e6b1265 100644 --- a/docs/docs/guide/appendix/npms.md +++ b/docs/docs/guide/appendix/npms.md @@ -43,5 +43,5 @@ sidebar_position: 3 | @alilc/lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/fusion-lowcode-materials | | @alilc/antd-lowcode-materials | [https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) | packages/antd-lowcode-materials | | @alifd/layout(原 @alifd/pro-layout 升级后的版本) | [https://github.com/alibaba-fusion/layout](https://github.com/alibaba-fusion/layout) | | -| | | | +| @alilc/lowcode-engine-docs | [https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) | docs | | | | | From 3a9ebd39838adf00ab83dda7a356b104a01a97b3 Mon Sep 17 00:00:00 2001 From: GitHub Action <action@github.com> Date: Thu, 28 Mar 2024 07:02:42 +0000 Subject: [PATCH 356/361] chore(docs): publish documentation --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 7c644de33c..f6b6495064 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.2.35", + "version": "1.2.36", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 16c9a3229f34acade065b9f24b6c5ecce898092f Mon Sep 17 00:00:00 2001 From: AndyJin <jjj706@163.com> Date: Tue, 14 May 2024 11:09:44 +0800 Subject: [PATCH 357/361] fix(renderer): remove the replacement 'div' for ConfigProvider when it is undefined --- .../renderer-core/src/renderer/renderer.tsx | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/renderer-core/src/renderer/renderer.tsx b/packages/renderer-core/src/renderer/renderer.tsx index 300b1cd164..faee9df42a 100644 --- a/packages/renderer-core/src/renderer/renderer.tsx +++ b/packages/renderer-core/src/renderer/renderer.tsx @@ -15,7 +15,7 @@ export default function rendererFactory(): IRenderComponent { const AppContext = contextFactory(); const Div = divFactory(); - const ConfigProvider = adapter.getConfigProvider() || Div; + const ConfigProvider = adapter.getConfigProvider(); const debug = Debug('renderer:entry'); @@ -157,24 +157,25 @@ export default function rendererFactory(): IRenderComponent { } if (Comp) { + const comp = createElement(Comp, { + key: schema.__ctx && `${schema.__ctx.lceKey}_${schema.__ctx.idx || '0'}`, + ref: this.__getRef, + __appHelper: appHelper, + __components: allComponents, + __schema: schema, + __designMode: designMode, + ...this.props, + }); return createElement(AppContext.Provider, { value: { appHelper, components: allComponents, engine: this, }, - }, createElement(ConfigProvider, { + }, ConfigProvider ? createElement(ConfigProvider, { device: this.props.device, locale: this.props.locale, - }, createElement(Comp, { - key: schema.__ctx && `${schema.__ctx.lceKey}_${schema.__ctx.idx || '0'}`, - ref: this.__getRef, - __appHelper: appHelper, - __components: allComponents, - __schema: schema, - __designMode: designMode, - ...this.props, - }))); + }, comp) : comp); } return null; } From 395e60079a7800b2d39343e1e016de52b57f3be2 Mon Sep 17 00:00:00 2001 From: woshilaoge <785431601@qq.com> Date: Wed, 15 May 2024 17:01:52 +0800 Subject: [PATCH 358/361] =?UTF-8?q?fix:=20next=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=89=88=E6=9C=AC=20TS=20=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=AF=BC=E5=87=BA=E9=83=A8=E5=88=86=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=EF=BC=8C=E6=9A=82=E6=97=B6=E8=B0=83=E6=95=B4=E5=A3=B0?= =?UTF-8?q?=E6=98=8E=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E7=BC=96=E8=AF=91=EF=BC=8C=E5=90=8E=E7=BB=AD=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=90=8E=E5=8F=AF=E5=86=8D=E9=85=8D=E5=90=88?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/shell/src/api/commonUI.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/shell/src/api/commonUI.tsx b/packages/shell/src/api/commonUI.tsx index 69dd104b2a..753c24cbe0 100644 --- a/packages/shell/src/api/commonUI.tsx +++ b/packages/shell/src/api/commonUI.tsx @@ -19,7 +19,7 @@ export class CommonUI implements IPublicApiCommonUI { Card = Card; Checkbox = Checkbox; DatePicker = DatePicker; - Dialog = Dialog; + Dialog = Dialog as any; Dropdown = Dropdown; Form = Form; Icon = Icon; @@ -31,15 +31,15 @@ export class CommonUI implements IPublicApiCommonUI { Radio = Radio; Search = Search; Select = Select; - SplitButton = SplitButton; + SplitButton = SplitButton as any; Step = Step; - Switch = Switch; + Switch = Switch as any; Tab = Tab; Table = Table; Tree = Tree; TreeSelect = TreeSelect; Upload = Upload; - Divider = Divider; + Divider = Divider as any; ContextMenu: ((props: { menus: IPublicTypeContextMenuAction[]; From 418a0bdaa231f0e8ad805554a5f2fd9641950155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BE=9C?= <1ncounter.100@gmail.com> Date: Thu, 16 May 2024 15:25:19 +0800 Subject: [PATCH 359/361] Revert "fix: keep `this` in parse expression function" --- packages/renderer-core/src/utils/common.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index a9c5ffb8f0..0462d358a7 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -221,19 +221,22 @@ function parseExpression(a: any, b?: any, c = false) { thisRequired = c; } try { + const contextArr = ['"use strict";', 'var __self = arguments[0];']; + contextArr.push('return '); let tarStr: string; tarStr = (str.value || '').trim(); - let code = `"use strict"; function __wrapper(){ return ${tarStr}} return __wrapper.call(arguments[0])`; + // NOTE: use __self replace 'this' in the original function str + // may be wrong in extreme case which contains '__self' already + tarStr = tarStr.replace(/this(\W|$)/g, (_a: any, b: any) => `__self${b}`); + tarStr = contextArr.join('\n') + tarStr; // 默认调用顶层窗口的parseObj, 保障new Function的window对象是顶层的window对象 if (inSameDomain() && (window.parent as any).__newFunc) { - return (window.parent as any).__newFunc(code)(self); - } - if (!thisRequired) { - code = `with($scope){${code}}`; + return (window.parent as any).__newFunc(tarStr)(self); } + const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`; return new Function('$scope', code)(self); } catch (err) { logger.error(`${logScope || ''} parseExpression.error`, err, str, self?.__self ?? self); From 8d44c588454f5d691da55b476c13896b3c306db6 Mon Sep 17 00:00:00 2001 From: liukairui <krxpro@outlook.com> Date: Fri, 14 Jun 2024 03:21:37 +0800 Subject: [PATCH 360/361] fix: update outline tree when node loop property changes --- .../src/controllers/tree-node.ts | 18 ++++++++++++++++++ .../src/controllers/tree.ts | 5 +++-- .../src/views/tree-title.tsx | 9 ++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/plugin-outline-pane/src/controllers/tree-node.ts b/packages/plugin-outline-pane/src/controllers/tree-node.ts index 34d06fee0b..1526e2a598 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-node.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-node.ts @@ -37,6 +37,8 @@ enum EVENT_NAMES { expandableChanged = 'expandableChanged', conditionChanged = 'conditionChanged', + + loopChanged = 'loopChanged', } export default class TreeNode { @@ -160,6 +162,10 @@ export default class TreeNode { return this.node.hasCondition() && !this.node.conditionGroup; } + get loop(): boolean { + return this.node.hasLoop(); + } + get children(): TreeNode[] | null { return this.node.children?.map((node) => this.tree.getTreeNode(node)) || null; } @@ -222,6 +228,14 @@ export default class TreeNode { }; } + onLoopChanged(fn: (treeNode: TreeNode) => void): IPublicTypeDisposable { + this.event.on(EVENT_NAMES.loopChanged, fn); + + return () => { + this.event.off(EVENT_NAMES.loopChanged, fn); + }; + } + onExpandableChanged(fn: (expandable: boolean) => void): IPublicTypeDisposable { this.event.on(EVENT_NAMES.expandableChanged, fn); return () => { @@ -244,6 +258,10 @@ export default class TreeNode { this.event.emit(EVENT_NAMES.conditionChanged, this.condition); } + notifyLoopChanged(): void { + this.event.emit(EVENT_NAMES.loopChanged, this.loop); + } + setHidden(flag: boolean) { if (this.node.conditionGroup) { return; diff --git a/packages/plugin-outline-pane/src/controllers/tree.ts b/packages/plugin-outline-pane/src/controllers/tree.ts index ca5a43c554..7e75307a04 100644 --- a/packages/plugin-outline-pane/src/controllers/tree.ts +++ b/packages/plugin-outline-pane/src/controllers/tree.ts @@ -36,12 +36,13 @@ export class Tree { doc?.onChangeNodeProp((info: IPublicTypePropChangeOptions) => { const { node, key } = info; + const treeNode = this.getTreeNodeById(node.id); if (key === '___title___') { - const treeNode = this.getTreeNodeById(node.id); treeNode?.notifyTitleLabelChanged(); } else if (key === '___condition___') { - const treeNode = this.getTreeNodeById(node.id); treeNode?.notifyConditionChanged(); + } else if (key === '___loop___') { + treeNode?.notifyLoopChanged(); } }); diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index f822bd644b..d7e29dbe86 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -28,6 +28,7 @@ export default class TreeTitle extends PureComponent<{ editing: boolean; title: string; condition?: boolean; + loop?: boolean; visible?: boolean; filterWorking: boolean; keywords: string; @@ -89,6 +90,7 @@ export default class TreeTitle extends PureComponent<{ editing: false, title: treeNode.titleLabel, condition: treeNode.condition, + loop: treeNode.loop, visible: !treeNode.hidden, }); treeNode.onTitleLabelChanged(() => { @@ -101,6 +103,11 @@ export default class TreeTitle extends PureComponent<{ condition: treeNode.condition, }); }); + treeNode.onLoopChanged(() => { + this.setState({ + loop: treeNode.loop, + }); + }); treeNode.onHiddenChanged((hidden: boolean) => { this.setState({ visible: !hidden, @@ -207,7 +214,7 @@ export default class TreeTitle extends PureComponent<{ <Tip>{intlNode('Slot for {prop}', { prop: node.slotFor.key })}</Tip> </a> )} - {node.hasLoop() && ( + {this.state.loop && ( <a className="tree-node-tag loop"> {/* todo: click todo something */} <IconLoop /> From a8c50ef9cd2a24349641ef71b0b0528d1df1406a Mon Sep 17 00:00:00 2001 From: liukairui <krxpro@outlook.com> Date: Fri, 14 Jun 2024 03:31:19 +0800 Subject: [PATCH 361/361] test: update renderer-core snapshots --- .../renderer/__snapshots__/renderer.test.tsx.snap | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap index 79c5f0f085..4a55c6cd4a 100644 --- a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap +++ b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap @@ -259,10 +259,11 @@ exports[`Base Render renderComp 1`] = ` "hidden": undefined, } } + aria-expanded="false" + aria-label="select" autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -378,10 +379,11 @@ exports[`Base Render renderComp 1`] = ` "hidden": undefined, } } + aria-expanded="false" + aria-label="select" autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -485,7 +487,6 @@ exports[`Base Render renderComp 1`] = ` autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -988,7 +989,6 @@ exports[`Base Render renderComp 1`] = ` autoComplete="off" disabled={false} height="100%" - maxLength={null} onBlur={[Function]} onChange={[Function]} onCompositionEnd={[Function]} @@ -1048,10 +1048,11 @@ exports[`Base Render renderComp 1`] = ` "hidden": undefined, } } + aria-expanded="false" + aria-label="select" autoComplete="off" disabled={false} height="100%" - maxLength={null} name="error" onBlur={[Function]} onChange={[Function]}