diff --git a/docs/config/sidebars.js b/docs/config/sidebars.js index 95a79962f..77a2e1f22 100644 --- a/docs/config/sidebars.js +++ b/docs/config/sidebars.js @@ -39,7 +39,7 @@ module.exports = { type: 'category', label: '扩展编辑器', collapsed: false, - items: getDocsFromDir('guide/expand/editor'), + items: getDocsFromDir('guide/expand/editor', [{ dir: 'guide/expand/editor/parts', label: 'Parts·造物' }]), }, { type: 'category', diff --git a/docs/docs/api/canvas.md b/docs/docs/api/canvas.md index 8340bd348..344223bcb 100644 --- a/docs/docs/api/canvas.md +++ b/docs/docs/api/canvas.md @@ -42,7 +42,7 @@ get dragon(): IPublicModelDragon | null; get activeTracker(): IPublicModelActiveTracker | null; ``` -## 方法签名 +## 方法 ### createLocation 创建一个文档插入位置对象,该对象用来描述一个即将插入的节点在文档中的位置 diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index a6b21974d..e5bfa8629 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -20,7 +20,7 @@ sidebar_position: 11 #### skeletonCabin 面板扩展相关,详见下方方法签名 -## 方法签名 +## 方法 ### utils #### isNodeSchema 是否为合法的 schema 结构 diff --git a/docs/docs/api/config.md b/docs/docs/api/config.md index fee26d436..ea4c7dbfc 100644 --- a/docs/docs/api/config.md +++ b/docs/docs/api/config.md @@ -10,7 +10,7 @@ sidebar_position: 8 ## 模块简介 配置模块,负责配置的读、写等操作。 -## 方法签名 +## 方法 ### get 获取指定 key 的值 diff --git a/docs/docs/api/event.md b/docs/docs/api/event.md index be3c768e0..0eb8b9738 100644 --- a/docs/docs/api/event.md +++ b/docs/docs/api/event.md @@ -10,7 +10,7 @@ sidebar_position: 7 ## 模块简介 负责事件处理 API,支持自定义监听事件、触发事件。 -## 方法签名 +## 方法 ### on 监听事件 diff --git a/docs/docs/api/hotkey.md b/docs/docs/api/hotkey.md index a8c717342..a244b94c2 100644 --- a/docs/docs/api/hotkey.md +++ b/docs/docs/api/hotkey.md @@ -9,7 +9,7 @@ sidebar_position: 5 ## 模块简介 绑定快捷键 API,可以自定义项目快捷键使用。 -## 方法签名 +## 方法 ### bind 绑定快捷键 diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 185e76355..f8bf2cdbe 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -8,7 +8,7 @@ sidebar_position: 10 ## 模块简介 提供 init 等方法 -## 方法签名 +## 方法 #### 1. init 初始化引擎 diff --git a/docs/docs/api/logger.md b/docs/docs/api/logger.md index 68681438b..7493f34dc 100644 --- a/docs/docs/api/logger.md +++ b/docs/docs/api/logger.md @@ -12,7 +12,7 @@ sidebar_position: 9 > 注:日志级别可以通过 url query 动态调整,详见下方[查看示例](#查看示例)。
> 参考 [zen-logger](https://web.npm.alibaba-inc.com/package/zen-logger) 实现进行封装 -## 方法签名 +## 方法 日志记录方法 diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index c060b9bef..0732c568e 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -22,7 +22,7 @@ get componentsMap(): { [key: string]: IPublicTypeNpmInfo | ComponentType | ``` 相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts) -## 方法签名 +## 方法 ### 资产包 #### setAssets diff --git a/docs/docs/api/model/detecting.md b/docs/docs/api/model/detecting.md index 15e1cfca7..ccd60e3a6 100644 --- a/docs/docs/api/model/detecting.md +++ b/docs/docs/api/model/detecting.md @@ -9,7 +9,7 @@ sidebar_position: 6 画布节点悬停模型 -## 变量 +## 属性 ### current @@ -28,7 +28,7 @@ sidebar_position: 6 `@type {boolean}` -## 方法签名 +## 方法 ### capture hover 指定节点 @@ -77,7 +77,7 @@ hover 节点变化事件 * set callback which will be called when hovering object changed. * @since v1.1.0 */ -onDetectingChange(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; +onDetectingChange(fn: (node: IPublicModelNode | null) => void): IPublicTypeDisposable; ``` 相关类型: diff --git a/docs/docs/api/model/document-model.md b/docs/docs/api/model/document-model.md index 9e5064371..c9f338609 100644 --- a/docs/docs/api/model/document-model.md +++ b/docs/docs/api/model/document-model.md @@ -9,7 +9,7 @@ sidebar_position: 0 文档模型 -## 变量 +## 属性 ### id @@ -95,7 +95,7 @@ sidebar_position: 0 **@since v1.1.0** -## 方法签名 +## 方法 ### getNodeById 根据 nodeId 返回 [Node](./node) 实例 diff --git a/docs/docs/api/model/dragon.md b/docs/docs/api/model/dragon.md index 82884224b..995fd1b1f 100644 --- a/docs/docs/api/model/dragon.md +++ b/docs/docs/api/model/dragon.md @@ -18,7 +18,7 @@ import { IPublicModelDragon } from '@alilc/lowcode-types'; **@since** v1.1.0 -## 变量 +## 属性 ### dragging @@ -31,7 +31,7 @@ import { IPublicModelDragon } from '@alilc/lowcode-types'; get dragging(): boolean; ``` -## 方法签名 +## 方法 ### onDragstart diff --git a/docs/docs/api/model/drop-location.md b/docs/docs/api/model/drop-location.md index 37497741c..853da842c 100644 --- a/docs/docs/api/model/drop-location.md +++ b/docs/docs/api/model/drop-location.md @@ -11,7 +11,7 @@ sidebar_position: 13 拖拽放置位置模型 -## 变量 +## 属性 ### target @@ -37,7 +37,7 @@ sidebar_position: 13 相关类型:[IPublicModelLocateEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/location-event.ts) -## 方法签名 +## 方法 ### clone diff --git a/docs/docs/api/model/history.md b/docs/docs/api/model/history.md index db6800850..b8c4d791b 100644 --- a/docs/docs/api/model/history.md +++ b/docs/docs/api/model/history.md @@ -9,7 +9,7 @@ sidebar_position: 5 操作历史记录模型 -## 方法签名 +## 方法 ### go 历史记录跳转到指定位置 diff --git a/docs/docs/api/model/modal-nodes-manager.md b/docs/docs/api/model/modal-nodes-manager.md index ed89ce31b..acff26734 100644 --- a/docs/docs/api/model/modal-nodes-manager.md +++ b/docs/docs/api/model/modal-nodes-manager.md @@ -9,40 +9,86 @@ sidebar_position: 7 模态节点管理器模型 -## 方法签名 +## 方法 ### setNodes -setNodes() - 设置模态节点,触发内部事件 +```typescript +/** + * 设置模态节点,触发内部事件 + * set modal nodes, trigger internal events + */ +setNodes(): void; +``` + ### getModalNodes -getModalNodes() - 获取模态节点(们) +```typescript +/** + * 获取模态节点(们) + * get modal nodes + */ +getModalNodes(): IPublicModelNode[]; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + ### getVisibleModalNode -getVisibleModalNode() - 获取当前可见的模态节点 +```typescript +/** + * 获取当前可见的模态节点 + * get current visible modal node + */ +getVisibleModalNode(): IPublicModelNode | null; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + ### hideModalNodes -hideModalNodes() - 隐藏模态节点(们) +```typescript +/** + * 隐藏模态节点(们) + * hide modal nodes + */ +hideModalNodes(): void; +``` + ### setVisible -setVisible(node: Node) - 设置指定节点为可见态 +```typescript +/** + * 设置指定节点为可见态 + * set specfic model node as visible + * @param node Node + */ +setVisible(node: IPublicModelNode): void; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) + ### setInvisible -setInvisible(node: Node) - 设置指定节点为不可见态 + +```typescript +/** + * 设置指定节点为不可见态 + * set specfic model node as invisible + * @param node Node + */ +setInvisible(node: IPublicModelNode): void; +``` + +相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) diff --git a/docs/docs/api/model/node-children.md b/docs/docs/api/model/node-children.md index 2e8769411..10488a733 100644 --- a/docs/docs/api/model/node-children.md +++ b/docs/docs/api/model/node-children.md @@ -8,7 +8,7 @@ sidebar_position: 2 ## 基本介绍 节点孩子模型 -## 变量 +## 属性 ### owner 返回当前 children 实例所属的节点实例 @@ -41,7 +41,7 @@ children 内的节点实例数 **@since v1.1.0** -## 方法签名 +## 方法 ### delete 删除指定节点 diff --git a/docs/docs/api/model/node.md b/docs/docs/api/model/node.md index 60678ad34..fbc88034b 100644 --- a/docs/docs/api/model/node.md +++ b/docs/docs/api/model/node.md @@ -9,7 +9,7 @@ sidebar_position: 1 节点模型 -## 变量 +## 属性 ### id 节点 id @@ -263,7 +263,7 @@ sidebar_position: 1 **@since v1.1.0** -## 方法签名 +## 方法 ### getRect diff --git a/docs/docs/api/model/plugin-instance.md b/docs/docs/api/model/plugin-instance.md index 8f764c68b..14ce38837 100644 --- a/docs/docs/api/model/plugin-instance.md +++ b/docs/docs/api/model/plugin-instance.md @@ -17,38 +17,24 @@ sidebar_position: 12 插件名字 -```typescript -get name(): string; -``` +`@type {string}` ### dep 插件依赖 -```typescript -get dep(): string[]; -``` +`@type {string[]}` ### disabled 插件是否禁用 -```typescript -get disabled(): boolean - -set disabled(disabled: boolean): void; - -``` +`@type {boolean}` ### meta 插件 meta 信息 -```typescript -get meta(): IPublicTypePluginMeta - -``` - -- [IPublicTypePluginMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-meta.ts) - +`@type {IPublicTypePluginMeta}` +相关类型:[IPublicTypePluginMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-meta.ts) diff --git a/docs/docs/api/model/prop.md b/docs/docs/api/model/prop.md index e619cdc33..d9b0d14f4 100644 --- a/docs/docs/api/model/prop.md +++ b/docs/docs/api/model/prop.md @@ -9,7 +9,7 @@ sidebar_position: 3 属性模型 -## 变量 +## 属性 ### id @@ -46,7 +46,7 @@ key 值 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) -## 方法签名 +## 方法 ### setValue diff --git a/docs/docs/api/model/props.md b/docs/docs/api/model/props.md index f76919d49..9bd6eaa66 100644 --- a/docs/docs/api/model/props.md +++ b/docs/docs/api/model/props.md @@ -9,7 +9,7 @@ sidebar_position: 4 属性集模型 -## 变量 +## 属性 ### id id @@ -32,7 +32,7 @@ id 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) -## 方法签名 +## 方法 ### getProp 获取指定 path 的属性模型实例 diff --git a/docs/docs/api/model/resource.md b/docs/docs/api/model/resource.md index 33a6e3119..30b1e9f41 100644 --- a/docs/docs/api/model/resource.md +++ b/docs/docs/api/model/resource.md @@ -7,7 +7,7 @@ sidebar_position: 12 > **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/resource.ts)
> **@since** v1.1.0 -## 变量 +## 属性 ### title diff --git a/docs/docs/api/model/selection.md b/docs/docs/api/model/selection.md index 529a3e5a2..9fc2e3a1c 100644 --- a/docs/docs/api/model/selection.md +++ b/docs/docs/api/model/selection.md @@ -9,7 +9,7 @@ sidebar_position: 6 画布节点选中模型 -## 变量 +## 属性 ### selected 返回选中的节点 id @@ -25,7 +25,7 @@ sidebar_position: 6 **@since v1.1.0** -## 方法签名 +## 方法 ### select 选中指定节点(覆盖方式) diff --git a/docs/docs/api/model/window.md b/docs/docs/api/model/window.md index f70c33e4d..7814ae6ea 100644 --- a/docs/docs/api/model/window.md +++ b/docs/docs/api/model/window.md @@ -12,7 +12,7 @@ sidebar_position: 12 低代码设计器窗口模型 -## 变量 +## 属性 ### id @@ -38,7 +38,7 @@ sidebar_position: 12 关联模型 [IPublicModelResource](./resource) -## 方法签名 +## 方法 ### importSchema 当前窗口导入 schema, 会调用当前窗口对应资源的 import 钩子 diff --git a/docs/docs/api/plugins.md b/docs/docs/api/plugins.md index 9b1993b10..58be1fde0 100644 --- a/docs/docs/api/plugins.md +++ b/docs/docs/api/plugins.md @@ -8,7 +8,7 @@ sidebar_position: 4 ## 模块简介 插件管理器,提供编排模块中管理插件的能力。 -## 方法签名 +## 方法 ### register 注册插件 diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index 15fb3cb7e..0c7213aac 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -69,7 +69,7 @@ get simulatorHost(): IPublicApiSimulatorHost | null; 相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) -## 方法签名 +## 方法 ### openDocument 打开一个 document diff --git a/docs/docs/api/setters.md b/docs/docs/api/setters.md index 3c5fd9f75..92d24f4e1 100644 --- a/docs/docs/api/setters.md +++ b/docs/docs/api/setters.md @@ -8,7 +8,7 @@ sidebar_position: 6 ## 模块简介 负责注册设置器、管理设置器的 API。注册自定义设置器之后可以在物料中进行使用。 -## 方法签名 +## 方法 ### getSetter 获取指定 setter diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 5ad82accf..e7ae391eb 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -135,7 +135,7 @@ skeleton.add({ }); ``` -## 方法签名 +## 方法 ### add diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md index 138693cfa..81301d110 100644 --- a/docs/docs/api/workspace.md +++ b/docs/docs/api/workspace.md @@ -57,7 +57,7 @@ get resourceList(): IPublicModelResource; 关联模型 [IPublicModelResource](./model/resource) -## 方法签名 +## 方法 ### registerResourceType 注册资源 diff --git a/docs/docs/faq/faq015.md b/docs/docs/faq/faq015.md index 48e97bc22..683e7df3a 100644 --- a/docs/docs/faq/faq015.md +++ b/docs/docs/faq/faq015.md @@ -4,4 +4,4 @@ sidebar_position: 15 tags: [FAQ] --- 你可以通过在线工具「Parts 造物」生产物料描述协议,然后使用到你的项目中去。 -文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/partsIntro) +文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/parts/partsIntro) diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index 74b9fa821..60f44ce87 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -1,6 +1,6 @@ --- title: 低代码生态脚手架 & 调试机制 -sidebar_position: 7 +sidebar_position: 8 --- ## 脚手架简述 diff --git a/docs/docs/guide/expand/editor/metaSpec.md b/docs/docs/guide/expand/editor/metaSpec.md index 2e70550ac..2f874925f 100644 --- a/docs/docs/guide/expand/editor/metaSpec.md +++ b/docs/docs/guide/expand/editor/metaSpec.md @@ -10,7 +10,7 @@ sidebar_position: 2 ## 可视化生成物料描述 -使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/partsIntro) +使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/parts/partsIntro) ## 自动生成物料描述 diff --git a/docs/docs/guide/expand/editor/parts/_category_.json b/docs/docs/guide/expand/editor/parts/_category_.json new file mode 100644 index 000000000..005a3caf6 --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Parts 造物", + "position": 1 +} diff --git a/docs/docs/guide/expand/editor/parts/partsIntro.md b/docs/docs/guide/expand/editor/parts/partsIntro.md new file mode 100644 index 000000000..a6fc6e881 --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/partsIntro.md @@ -0,0 +1,18 @@ +--- +title: 介绍 +sidebar_position: 1 +--- +## 介绍 +![](https://gw.alicdn.com/imgextra/i2/O1CN01Gyq6AZ1nOENPTVXX7_!!6000000005079-2-tps-256-104.png) + + +「Parts·造物」是基于开源低代码引擎打造的次时代物料研发和集成工具,一方面作为低代码引擎搭建低代码平台的一个样板展示开源生态下的各个组件如何集合在一起形成生产力,另一方面也可以生产低代码平台所需的物料。 + +目前「Parts·造物」主要提供两大产品功能: + 1. React 组件导入低代码引擎:通过在线可视化的「物料描述」配置,任意工具开发的 React 组件都可以快速完成对低代码引擎的适配,导入到低代码引擎项目中进行使用。不必额外开发新的组件。 + 2. 低代码生产组件:通过低代码的形式生产组件,极低上手门槛,提供丰富的原子组件用于组合,完善的调试预览和组件生命周期控制。生产的组件既可以在低代码引擎项目中使用,也可以出码后在普通源码项目中使用。 + + +## 联系我们 + + diff --git a/docs/docs/guide/expand/editor/parts/partsassets.md b/docs/docs/guide/expand/editor/parts/partsassets.md new file mode 100644 index 000000000..00670ecad --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/partsassets.md @@ -0,0 +1,267 @@ +--- +title: 资产包管理 +sidebar_position: 4 +--- + +## 介绍 + +通过前述介绍,相信大家已经了解如何使用「[Parts·造物](https://parts.lowcode-engine.cn/)」来将已有的 React 组件快速接入低代码引擎,以及生产低代码组件。 + +大家在使用的过程中,可能会希望构建出来的资产包可以后续随时访问下载,或者希望构建资产包时各个组件的版本等信息可以持久化起来并且能够多人维护。 + +通过「[Parts·造物](https://parts.lowcode-engine.cn/)」的 `资产包` 管理功能帮助大家解决这个问题 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Fkaznh1zWj9wYKpcH_!!6000000006722-2-tps-1702-628.png) + +## 新建资产包 + +首先,我们在 我的资产包 tab 中点击 `新建资产包` +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01qe8zfO1ilysebSfD5_!!6000000004454-2-tps-3064-1432.png) + +- 填写资产包名称 +- 配置资产包管理员,管理员拥有该资产包的所有权限,初始默认为资产包的创建者,还可以添加其他人作为管理员, +- 配置资产包描述 (可选) +- 点击 `确定`, 即可完成资产包的创建 + +接下来需要为资产包添加一个或者多个组件。 + +## 添加组件 + +第二步:新建完资产包以后,我们就可以为其添加组件了,如果是新建资产包流程,新建完成之后会自动弹出组件配置的弹窗,当然,你可可以通过点击资产包卡片的方式打开组件配置的弹窗。 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01kqymdB1nkDQclPk7F_!!6000000005127-2-tps-965-261.png) + +- 点击弹窗中 `添加组件` 按钮,在弹出的组件选择面板中,选中需要添加的组件并点击 `下一步`。 + ![image.png](https://img.alicdn.com/imgextra/i1/O1CN014Baihf1r742Qi1Wel_!!6000000005583-2-tps-1856-1520.png) +- 进入组件版本以及描述协议版本选择界面,选择所需要的正确版本,点击 `安装` 即可完成一个组件的添加。 + ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Y7aWWi1MMPDVlidgz_!!6000000001420-2-tps-1668-1462.png) + +## 构建资产包 + +添加完组件以后就点击 `保存并构建资产包` 进入资产包构建配置弹窗 +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01iZf4Ue1PlXnyKYxnK_!!6000000001881-2-tps-1288-670.png) + +- `开启缓存` : 可充分利用之前的构建结果缓存来加速资产包的生成,我们会将每个组件的构建结果以 包名和版本号为 key 进行缓存。 +- `任务描述` : 当前构建任务的一些描述信息。 + +点击 `确认` 按钮 会自动跳转到当前资产包的构建历史界面: +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01krDaFc1TuTztMPssI_!!6000000002442-2-tps-1726-696.png) +构建历史界面会显示当前资产包所有的构建历史记录,表格状态栏展示了构建的状态:`成功`,`失败`,`正在运行` 三种状态,操作列可以在构建成功时复制或者下载资产包结果 + +## 使用资产包 +你可以在 [lowcode-demo](https://github.com/alibaba/lowcode-demo) 中直接引用,可直接替换 demo 中原来的资产包文件: +例如,在 [demo-lowcode-component](https://github.com/alibaba/lowcode-demo/tree/main/demo-lowcode-component) 中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-lowcode-component/src/services/assets.json),即可快速使用自己的物料了。 + +### 在编辑器中使用资产包 +在使用含有低代码组件的资产包注意 注意引擎版本必须大于等于 `1.1.0-beta.9`。 +然后直接替换 [lowcode-demo](https://github.com/alibaba/lowcode-demo) demo 中的 `assets.json` 文件即可。 + +### 在预览中使用资产包 +在预览中使用资产包的整体思路是从 `资产包` 中提取并转换出 `ReactRenderer` 渲染所需要的 react 组件列表 (`components` 参数),然后将 `schema` 以及 `components` 传入到 `ReactRenderer` 中进行渲染,需要注意的是,在 `资产包` 的转换过程中,我们也需要将 `低代码组件` 转换成 react 组件,具体逻辑可以参考下 [demo-lowcode-component](https://github.com/alibaba/lowcode-demo/tree/main/demo-lowcode-component) 中 `src/parse-assets.ts` 文件的实现。 +基于资产包进行预览的整体逻辑如下: [详见](https://github.com/alibaba/lowcode-demo/blob/main/demo-lowcode-component/src/preview.tsx): +```ts +import ReactDOM from 'react-dom'; +import React, { useState } from 'react'; +import { Loading } from '@alifd/next'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; +import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler'; +import { + getProjectSchemaFromLocalStorage, +} from './services/mockService'; +import assets from './services/assets.json'; +import { parseAssets } from './parse-assets'; + +const getScenarioName = function () { + if (location.search) { + return new URLSearchParams(location.search.slice(1)).get('scenarioName') || 'index'; + } + return 'index'; +}; + +const SamplePreview = () => { + const [data, setData] = useState({}); + async function init() { + const scenarioName = getScenarioName(); + const projectSchema = getProjectSchemaFromLocalStorage(scenarioName); + const { componentsMap: componentsMapArray, componentsTree } = projectSchema; + const schema = componentsTree[0]; + const componentsMap: any = {}; + componentsMapArray.forEach((component: any) => { + componentsMap[component.componentName] = component; + }); + + // 特别提醒重点注意!!!:从资产包中解析出所有的 react 组件列表 + const { components } = await parseAssets(assets); + + setData({ + schema, + components, + }); + } + + const { schema, components } = data; + + if (!schema || !components) { + init(); + return ; + } + + return ( +
+ +
+ ); +}; + +ReactDOM.render(, document.getElementById('ice-container')); +``` + +从资产包中解析 react 组件列表的逻辑如下,[详见](https://github.com/alibaba/lowcode-demo/blob/main/demo-lowcode-component/src/parse-assets.ts): +```ts +import { ComponentDescription, ComponentSchema, RemoteComponentDescription } from '@alilc/lowcode-types'; +import { buildComponents, AssetsJson, AssetLoader } from '@alilc/lowcode-utils'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; +import { injectComponents } from '@alilc/lowcode-plugin-inject'; +import React, { createElement } from 'react'; + +export async function parseAssets(assets: AssetsJson) { + const { components: rawComponents, packages } = assets; + const libraryAsset = []; + const libraryMap = {}; + const packagesMap = {}; + packages.forEach(pkg => { + const { package: _package, library, urls, renderUrls, id } = pkg; + if (_package) { + libraryMap[id || _package] = library; + } + packagesMap[id || _package] = pkg; + if (renderUrls) { + libraryAsset.push(renderUrls); + } else if (urls) { + libraryAsset.push(urls); + } + }); + const assetLoader = new AssetLoader(); + await assetLoader.load(libraryAsset); + let newComponents = rawComponents; + if (rawComponents && rawComponents.length) { + const componentDescriptions: ComponentDescription[] = []; + const remoteComponentDescriptions: RemoteComponentDescription[] = []; + rawComponents.forEach((component: any) => { + if (!component) { + return; + } + if (component.exportName && component.url) { + remoteComponentDescriptions.push(component); + } else { + componentDescriptions.push(component); + } + }); + newComponents = [...componentDescriptions]; + + // 如果有远程组件描述协议,则自动加载并补充到资产包中,同时出发 designer.incrementalAssetsReady 通知组件面板更新数据 + if (remoteComponentDescriptions && remoteComponentDescriptions.length) { + await Promise.all( + remoteComponentDescriptions.map(async (component: any) => { + const { exportName, url, npm } = component; + await (new AssetLoader()).load(url); + function setAssetsComponent(component: any, extraNpmInfo: any = {}) { + const components = component.components; + if (Array.isArray(components)) { + components.forEach(d => { + newComponents = newComponents.concat({ + npm: { + ...npm, + ...extraNpmInfo, + }, + ...d, + } || []); + }); + return; + } + newComponents = newComponents.concat({ + npm: { + ...npm, + ...extraNpmInfo, + }, + ...component.components, + } || []); + } + + function setArrayAssets(value: any[], preExportName: string = '', preSubName: string = '') { + value.forEach((d: any, i: number) => { + const exportName = [preExportName, i.toString()].filter(d => !!d).join('.'); + const subName = [preSubName, i.toString()].filter(d => !!d).join('.'); + Array.isArray(d) ? setArrayAssets(d, exportName, subName) : setAssetsComponent(d, { + exportName, + subName, + }); + }); + } + if (window[exportName]) { + if (Array.isArray(window[exportName])) { + setArrayAssets(window[exportName] as any); + } else { + setAssetsComponent(window[exportName] as any); + } + } + return window[exportName]; + }), + ); + } + } + const lowcodeComponentsArray = []; + const proCodeComponentsMap = newComponents.reduce((acc, cur) => { + if ((cur.devMode || '').toLowerCase() === 'lowcode') { + lowcodeComponentsArray.push(cur); + } else { + acc[cur.componentName] = { + ...(cur.reference || cur.npm), + componentName: cur.componentName, + }; + } + return acc; + }, {}) + + function genLowCodeComponentsMap(components) { + const lowcodeComponentsMap = {}; + lowcodeComponentsArray.forEach((lowcode) => { + const id = lowcode.reference?.id; + const schema = packagesMap[id]?.schema; + const comp = genLowcodeComp(schema, {...components, ...lowcodeComponentsMap}); + lowcodeComponentsMap[lowcode.componentName] = comp; + }); + return lowcodeComponentsMap; + } + let components = await injectComponents(buildComponents(libraryMap, proCodeComponentsMap)); + const lowCodeComponents = genLowCodeComponentsMap(components); + return { + components: { ...components, ...lowCodeComponents } + } +} + +function genLowcodeComp(schema: ComponentSchema, components: any) { + return class LowcodeComp extends React.Component { + render(): React.ReactNode { + return createElement(ReactRenderer, { + ...this.props, + schema, + components, + designMode: '', + }); + } + }; +} +``` +## 联系我们 + + \ No newline at end of file diff --git a/docs/docs/guide/expand/editor/parts/partslcc.md b/docs/docs/guide/expand/editor/parts/partslcc.md new file mode 100644 index 000000000..4d24b72f3 --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/partslcc.md @@ -0,0 +1,92 @@ +--- +title: 低代码组件 +sidebar_position: 2 +--- +## 什么是低代码组件 +我们先了解一下什么是低代码组件,为什么要用低代码组件。 + +低代码组件是通过可视化的方式生产的组件,这些组件既可以用于低代码搭建体系,也可以用于 ProCode 开发体系(后续迭代)。 + +那么为什么我们要使用低代码的形式来开发组件: +* 首先轻快,低代码组件只需通过浏览器秒级完成初始化工作,不需要 ProCode 繁重的环境准备;环境一致(低代码环境),同时能够保证物料的开发环境和真实的运行环境是一致的,不会存在开发和运行环境不一致的问题。 +* 其次通用能力可视化方式抽象,提升研发效能,比如获取远程数据、视图开发、依赖管理、生命周期、事件绑定等功能。 + +低代码组件不是用来替代 ProCode 的开发方式,而是让开发者可以从 ProCode 中重复的工作脱离出来,抽象更多业务垂直的能力,从而起到提效的作用。 + +## 创建组件 + +环境准备:我们可以通过 Parts 提供的通用[低代码组件开发环境](https://parts.lowcode-engine.cn/material#/)开发。 + +点击开发新组件 --> 填写组件标题 --> 填写组件名称 --> 点击确定,完成组件创建工作。 + +![](https://img.alicdn.com/imgextra/i2/O1CN01OTQRew25y6WxuONIx_!!6000000007594-2-tps-3396-1696.png) + +## 组件开发 + +一张图速览低代码组件开发的功能模块,其中大部分功能可以参考[低代码引擎文档](https://lowcode-engine.cn/site/docs/guide/quickStart/intro)。 + +![](https://img.alicdn.com/imgextra/i1/O1CN01gx96E121qzv4smV2v_!!6000000007037-2-tps-3456-1930.png) + +### 依赖管理 + +依赖管理用于管理低代码组件本身的依赖(类似于 dependencies)。步骤:点击添加组件 --> 选择安装的组件 --> 保存并构建 (需要等待几分钟构建)。 + +![](https://img.alicdn.com/imgextra/i4/O1CN01wC9JPK1J9dKLca9wK_!!6000000000986-2-tps-1438-819.png) + +### 属性定义 + +用于定义组件接收外部传入的 propTypes,组件内部可以通过this.props.${属性名称}的方式获取属性值。 + +属性定义前建议先阅读 [物料描述详解](https://lowcode-engine.cn/site/docs/guide/expand/editor/metaSpec)、[预置设置器](https://lowcode-engine.cn/site/docs/guide/appendix/setters)。 + +![](https://img.alicdn.com/imgextra/i2/O1CN01wesIJA1nL1eSPrk7U_!!6000000005072-2-tps-1438-821.png) + +![](https://img.alicdn.com/imgextra/i3/O1CN01FZIRwv1es9lGplgIB_!!6000000003926-2-tps-1438-821.png) + +### 生命周期 + +低代码组件的开发支持 componentDidMount、componentDidUpdate、componentDidCatch、componentWillUnmount 几个生命周期 + +![](https://img.alicdn.com/imgextra/i4/O1CN010bnrxJ1oLlujlfFqj_!!6000000005209-2-tps-1438-819.png) + +### 组件调试 + +我们提供了一套线上实时调试的方案,只需点击右上角的调试按钮,就能自动创建一个低代码应用,在这个应用中可以实时调试当前的低代码组件。 + +![](https://img.alicdn.com/imgextra/i2/O1CN01Tk96vp1xrDeNeIUJD_!!6000000006496-2-tps-1438-820.png) + +在低代码应用中使用,组件面板 --> 低代码组件,找到对应的低代码组件拖入画布即可。 + +![](https://img.alicdn.com/imgextra/i2/O1CN01oGHLea1lzDAhZQQVO_!!6000000004889-2-tps-1438-819.png) + +### 组件发布 + +同时我们提供了组件发布的功能,用于组件版本管理,点击右上角的发布按钮即可发布组件 + +![](https://img.alicdn.com/imgextra/i2/O1CN017suVAD1NXEC8zQgO1_!!6000000001579-2-tps-1438-821.png) + +## 组件使用 + +组件的消费是通过资产包来管理的,详情请参考 [资产包管理](./partsassets)。 + +## 组件导出 + +开发好的低代码组件可以导出成为 React 组件,脱离低代码引擎独立使用。同时导出功能也为您的组件留出一份备份,您可以放心使用本产品的服务,而不用担心万一出现的不能服务的场景。 + +在物料列表页面,低代码组件会有一个导出的动作。 + +![](https://img.alicdn.com/imgextra/i2/O1CN016oUByO21spVHZvvw2_!!6000000007041-2-tps-1395-413.png) + +点击导出后,就会开启导出低代码组件的过程。这个过程持续 10s+,导出完成后会为您自动下载对应的 zip 包。 + +![](https://img.alicdn.com/imgextra/i1/O1CN01lctpIo1aDcEvu75Mo_!!6000000003296-2-tps-1399-512.png) + +zip 包解压后可以看到一个完整的组件脚手架工程,您可以在这个工程里继续开发调试,或者发布到合适的 npm 源中。 + +![](https://img.alicdn.com/imgextra/i1/O1CN010aAjsf1xYRPZBAh7d_!!6000000006455-2-tps-2154-1072.png) + +注意:目前导出功能暂不支持 低代码组件嵌套。 + +## 联系我们 + + \ No newline at end of file diff --git a/docs/docs/guide/expand/editor/partsIntro.md b/docs/docs/guide/expand/editor/parts/prototype.md similarity index 80% rename from docs/docs/guide/expand/editor/partsIntro.md rename to docs/docs/guide/expand/editor/parts/prototype.md index 174afc37a..b90728f65 100644 --- a/docs/docs/guide/expand/editor/partsIntro.md +++ b/docs/docs/guide/expand/editor/parts/prototype.md @@ -1,5 +1,5 @@ --- -title: 利用 Parts 造物快速使用 react 组件 +title: React 组件导入 sidebar_position: 3 --- ## 介绍 @@ -50,8 +50,6 @@ sidebar_position: 3 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01klci7y1IUPflKpeVB_!!6000000000896-2-tps-1193-704.png) #### 给组件增加物料描述 -选中刚刚新增的 BlockPicker 组件,然后给它增加描述: - - 打开左侧 Setter 面板 - 按照组件的属性拖入需要 Setter 类型(如图中组件的 width 属性,拖入数字 Setter) - 各种 Setter 的介绍可以参看这篇文档:[预置设置器列表](/site/docs/guide/appendix/setters) @@ -102,31 +100,22 @@ sidebar_position: 3 - 点击确定发布完成 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uwa8RH1QDwM7FN31k_!!6000000001943-2-tps-1431-734.png) - -## 资产包构建 - +## 资产包 第三步:物料描述发布完成后,接下来我们就需要构建出可用的资产包用于低代码应用中。 #### 资产包构建 +有两种方式可以构建资产包: +- 一种是通过 [`我的资产包`] 资产包管理模块进行整个资产包生命周期的管理,当然也包括资产包的构建,可参考 [资产包管理](./partsassets) +- 一种是通过 [`我的物料`] 组件物料管理模块的 `资产包构建` 进行构建, 具体操作如下: -- 选择需要构建的组件 -- 点击构建资产包按钮 -- 选择刚刚的物料描述配置 -- 开始构建,构建完成后你将得到一份 json 文件(里面包含了物料描述和 umd 包),就可以到项目中使用了 - -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Oc73aw1TH5vlJx9oj_!!6000000002356-2-tps-1431-770.png) + - 选择需要构建的组件 + - 点击构建资产包按钮 + - 选择刚刚的物料描述配置 + - 开始构建,构建完成后你将得到一份 json 文件(里面包含了物料描述和 umd 包),就可以到项目中使用了 #### 资产包使用 +详情请参考 [资产包管理](./partsassets#使用资产包) -**方式一、在 **[**lowcode-demo**](https://github.com/alibaba/lowcode-demo)**中直接引用,可直接替换 demo 中原来的资产包文件:** +## 联系我们 -例如,在 basic-fusion demo 中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json),即可快速使用自己的物料了。 - -**方式二、将新的资产包内容和现有的资产包内容融合:** - -将上面构建完成的资产包与你项目中的[assets.json 文件](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json)合并,主要合并 packages 和 components。 - -- packages 中是构建好的 umd 包; -- components 中是上面配置好的[物料描述](https://lowcode-engine.cn/material),你也可以在基础上二次加工; - -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01m7QkDN1P7hL86mjyH_!!6000000001794-2-tps-1140-744.png) + diff --git a/docs/docs/guide/expand/editor/pluginContextMenu.md b/docs/docs/guide/expand/editor/pluginContextMenu.md index 2f1ab737c..e9dbdf3c4 100644 --- a/docs/docs/guide/expand/editor/pluginContextMenu.md +++ b/docs/docs/guide/expand/editor/pluginContextMenu.md @@ -2,7 +2,9 @@ title: 插件扩展 - 编排扩展 sidebar_position: 6 --- + ## 场景一:扩展选中节点操作项 + ### 增加节点操作项 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01J7PrJc1S86XNDBIFQ_!!6000000002201-2-tps-1240-292.png) @@ -31,7 +33,7 @@ const addHelloAction = (ctx: IPublicModelPluginContext) => { }, important: true, }); - } + }, }; }; addHelloAction.pluginName = 'addHelloAction'; @@ -68,6 +70,7 @@ await plugins.register(removeCopyAction); 具体 API 参考:[API 文档](/site/docs/api/material#removebuiltincomponentaction) ## 实际案例 + ### 区块管理 - 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) diff --git a/docs/docs/guide/expand/editor/pluginWidget.md b/docs/docs/guide/expand/editor/pluginWidget.md index c319bb2a3..7efaffcf0 100644 --- a/docs/docs/guide/expand/editor/pluginWidget.md +++ b/docs/docs/guide/expand/editor/pluginWidget.md @@ -2,6 +2,7 @@ title: 插件扩展 - 面板扩展 sidebar_position: 5 --- + ## 插件简述 插件功能赋予低代码引擎更高的灵活性,低代码引擎的生态提供了一些官方的插件,但是无法满足所有人的需求,所以提供了强大的插件定制功能。 @@ -23,7 +24,7 @@ import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const pluginA = (ctx: IPublicModelPluginContext, options: any) => { return { init() { - console.log(options.key); + console.log(options.key); // 往引擎增加面板 ctx.skeleton.add({ // area 配置见下方说明 @@ -36,9 +37,9 @@ const pluginA = (ctx: IPublicModelPluginContext, options: any) => { }, destroy() { console.log('我被销毁了~'); - } - } -} + }, + }; +}; pluginA.pluginName = 'pluginA'; @@ -56,6 +57,7 @@ plugins.register(pluginA, { key: 'test' }); ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01y05ZHC1Gix0p4nXxH_!!6000000000657-2-tps-3068-1648.png) ### 展示区域 area + #### topArea 展示在设计器的顶部区域,常见的相关区域的插件主要是:、 @@ -76,6 +78,7 @@ plugins.register(pluginA, { key: 'test' }); 4. JS 等代码面板。 可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 + #### centerArea 画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有: @@ -106,12 +109,12 @@ PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主 接入可以参考代码 ```javascript -import { skeleton } from "@alilc/lowcode-engine"; +import { skeleton } from '@alilc/lowcode-engine'; skeleton.add({ - area: "leftArea", // 插件区域 - type: "PanelDock", // 插件类型,弹出面板 - name: "sourceEditor", + area: 'leftArea', // 插件区域 + type: 'PanelDock', // 插件类型,弹出面板 + name: 'sourceEditor', content: SourceEditor, // 插件组件实例 props: { align: "left", @@ -139,12 +142,12 @@ Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中 接入可以参考代码: ```javascript -import {skeleton} from "@alilc/lowcode-engine"; +import { skeleton } from '@alilc/lowcode-engine'; // 注册 logo 面板 skeleton.add({ - area: "topArea", - type: "Widget", - name: "logo", + area: 'topArea', + type: 'Widget', + name: 'logo', content: Logo, // Widget 组件实例 contentProps: { // Widget 插件 props logo: @@ -152,7 +155,7 @@ skeleton.add({ href: "/", }, props: { - align: "left", + align: 'left', width: 100, }, }); @@ -163,7 +166,7 @@ skeleton.add({ 一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。 ```javascript -import { skeleton } from "@alilc/lowcode-engine"; +import { skeleton } from '@alilc/lowcode-engine'; skeleton.add({ area: 'leftArea', @@ -176,12 +179,12 @@ skeleton.add({ props: { align: 'bottom', }, - onClick: function() { + onClick: function () { // 打开外部链接 window.open('https://lowcode-engine.cn'); // 显示 widget skeleton.showWidget('xxx'); - } + }, }); ``` @@ -211,4 +214,4 @@ skeleton.add({ - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - ICON 优化](https://www.bilibili.com/video/BV1zr4y1H7Km/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 自动截图](https://www.bilibili.com/video/BV1GZ4y117VH/) - [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 样式优化](https://www.bilibili.com/video/BV1Pi4y1S7ZT/) - - [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/) \ No newline at end of file + - [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/) diff --git a/docs/docs/guide/expand/editor/setter.md b/docs/docs/guide/expand/editor/setter.md index 6a720374f..01fd949bb 100644 --- a/docs/docs/guide/expand/editor/setter.md +++ b/docs/docs/guide/expand/editor/setter.md @@ -1,6 +1,6 @@ --- title: 设置器扩展 -sidebar_position: 4 +sidebar_position: 5 --- ## 设置器简述 diff --git a/docs/package.json b/docs/package.json index 4102563dc..613cb4831 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.14", + "version": "1.0.17", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ diff --git a/docs/scripts/getDocsFromDir.js b/docs/scripts/getDocsFromDir.js index 666d92c3c..18e67e718 100644 --- a/docs/scripts/getDocsFromDir.js +++ b/docs/scripts/getDocsFromDir.js @@ -8,9 +8,14 @@ module.exports = function getDocsFromDir(dir, cateList) { const baseDir = path.join(__dirname, '../docs/'); const docsDir = path.join(baseDir, dir); + function isNil(value) { + return value === undefined || value === null; + } + function getMarkdownOrder(filepath) { - const data = matter(fs.readFileSync(filepath, 'utf-8')).data; - return (data || {}).sidebar_position || 100; + const { data } = matter(fs.readFileSync(filepath, 'utf-8')); + const { sidebar_position } = data || {}; + return isNil(sidebar_position) ? 100 : sidebar_position; } const docs = glob.sync('*.md?(x)', { @@ -19,17 +24,17 @@ module.exports = function getDocsFromDir(dir, cateList) { }); const result = docs - .filter(doc => !/^index.md(x)?$/.test(doc)) - .map(doc => { + .filter((doc) => !/^index.md(x)?$/.test(doc)) + .map((doc) => { return path.join(docsDir, doc); }) .sort((a, b) => { const orderA = getMarkdownOrder(a); const orderB = getMarkdownOrder(b); - return orderB - orderA; + return orderA - orderB; }) - .map(filepath => { + .map((filepath) => { // /Users/xxx/site/docs/guide/basic/router.md => guide/basic/router const id = path .relative(baseDir, filepath) @@ -38,7 +43,7 @@ module.exports = function getDocsFromDir(dir, cateList) { return id; }); - (cateList || []).forEach(item => { + (cateList || []).forEach((item) => { const { dir, subCategory, ...otherConfig } = item; const indexList = glob.sync('index.md?(x)', { cwd: path.join(baseDir, dir), diff --git a/packages/designer/src/designer/active-tracker.ts b/packages/designer/src/designer/active-tracker.ts index d62ad9fe5..6c7dc9104 100644 --- a/packages/designer/src/designer/active-tracker.ts +++ b/packages/designer/src/designer/active-tracker.ts @@ -6,7 +6,7 @@ import { } from '@alilc/lowcode-types'; import { isNode } from '@alilc/lowcode-utils'; -export interface IActiveTracker extends IPublicModelActiveTracker { +export interface IActiveTracker extends Omit< IPublicModelActiveTracker, 'track' > { track(originalTarget: IPublicTypeActiveTarget | INode): void; } diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 6e4b3c63e..6ade5fea0 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -17,17 +17,16 @@ import { IPublicTypeLocationData, IPublicEnumTransformStage, IPublicModelDragon, - IPublicModelActiveTracker, IPublicModelDropLocation, } from '@alilc/lowcode-types'; import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils'; import { Project } from '../project'; import { Node, DocumentModel, insertChildren, INode } from '../document'; -import { ComponentMeta } from '../component-meta'; +import { ComponentMeta, IComponentMeta } from '../component-meta'; import { INodeSelector, Component } from '../simulator'; import { Scroller } from './scroller'; -import { Dragon, ILocateEvent } from './dragon'; -import { ActiveTracker } from './active-tracker'; +import { Dragon, IDragon, ILocateEvent } from './dragon'; +import { ActiveTracker, IActiveTracker } from './active-tracker'; import { Detecting } from './detecting'; import { DropLocation } from './location'; import { OffsetObserver, createOffsetObserver } from './offset-observer'; @@ -56,24 +55,49 @@ export interface DesignerProps { onMount?: (designer: Designer) => void; onDragstart?: (e: ILocateEvent) => void; onDrag?: (e: ILocateEvent) => void; - onDragend?: (e: { dragObject: IPublicModelDragObject; copy: boolean }, loc?: DropLocation) => void; + onDragend?: ( + e: { dragObject: IPublicModelDragObject; copy: boolean }, + loc?: DropLocation, + ) => void; } export interface IDesigner { + get dragon(): IPublicModelDragon; - get activeTracker(): IPublicModelActiveTracker; + + get activeTracker(): IActiveTracker; + + get componentActions(): ComponentActions; + + get editor(): IPublicModelEditor; + createScroller(scrollable: IPublicModelScrollable): IPublicModelScroller; /** * 创建插入位置,考虑放到 dragon 中 */ createLocation(locationData: IPublicTypeLocationData): IPublicModelDropLocation; + + get componentsMap(): { [key: string]: IPublicTypeNpmInfo | Component }; + + loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): Promise; + + getComponentMeta( + componentName: string, + generateMetadata?: () => IPublicTypeComponentMetadata | null, + ): IComponentMeta; + + createComponentMeta(data: IPublicTypeComponentMetadata): IComponentMeta | null; + + getComponentMetasMap(): Map; + + addPropsReducer(reducer: IPublicTypePropsTransducer, stage: IPublicEnumTransformStage): void; } export class Designer implements IDesigner { - public dragon: Dragon; + dragon: IDragon; - public viewName: string | undefined; + viewName: string | undefined; readonly componentActions = new ComponentActions(); @@ -99,7 +123,7 @@ export class Designer implements IDesigner { private oobxList: OffsetObserver[] = []; - @obx.ref private _componentMetasMap = new Map(); + @obx.ref private _componentMetasMap = new Map(); @obx.ref private _simulatorComponent?: ComponentType; @@ -483,7 +507,7 @@ export class Designer implements IDesigner { metas.forEach((data) => this.createComponentMeta(data)); } - createComponentMeta(data: IPublicTypeComponentMetadata): ComponentMeta | null { + createComponentMeta(data: IPublicTypeComponentMetadata): IComponentMeta | null { const key = data.componentName; if (!key) { return null; @@ -515,7 +539,7 @@ export class Designer implements IDesigner { getComponentMeta( componentName: string, generateMetadata?: () => IPublicTypeComponentMetadata | null, - ) { + ): IComponentMeta { if (this._componentMetasMap.has(componentName)) { return this._componentMetasMap.get(componentName)!; } diff --git a/packages/designer/src/designer/detecting.ts b/packages/designer/src/designer/detecting.ts index b7ada8138..3a6082d5c 100644 --- a/packages/designer/src/designer/detecting.ts +++ b/packages/designer/src/designer/detecting.ts @@ -1,14 +1,18 @@ import { makeObservable, obx, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -import { IPublicModelDetecting, IPublicModelNode, IPublicModelDocumentModel } from '@alilc/lowcode-types'; +import { IPublicModelDetecting } from '@alilc/lowcode-types'; +import { IDocumentModel } from '../document/document-model'; +import { INode } from '../document/node/node'; const DETECTING_CHANGE_EVENT = 'detectingChange'; export interface IDetecting extends Omit< IPublicModelDetecting, 'capture' | 'release' | 'leave' > { - capture(node: IPublicModelNode | null): void; + capture(node: INode | null): void; - release(node: IPublicModelNode | null): void; + release(node: INode | null): void; - leave(document: IPublicModelDocumentModel | undefined): void; + leave(document: IDocumentModel | undefined): void; + + get current(): INode | null; } export class Detecting implements IDetecting { @@ -31,7 +35,7 @@ export class Detecting implements IDetecting { @obx.ref xRayMode = false; - @obx.ref private _current: IPublicModelNode | null = null; + @obx.ref private _current: INode | null = null; private emitter: IEventBus = createModuleEventBus('Detecting'); @@ -43,27 +47,27 @@ export class Detecting implements IDetecting { return this._current; } - capture(node: IPublicModelNode | null) { + capture(node: INode | null) { if (this._current !== node) { this._current = node; this.emitter.emit(DETECTING_CHANGE_EVENT, this.current); } } - release(node: IPublicModelNode | null) { + release(node: INode | null) { if (this._current === node) { this._current = null; this.emitter.emit(DETECTING_CHANGE_EVENT, this.current); } } - leave(document: IPublicModelDocumentModel | undefined) { + leave(document: IDocumentModel | undefined) { if (this.current && this.current.document === document) { this._current = null; } } - onDetectingChange(fn: (node: IPublicModelNode) => void) { + onDetectingChange(fn: (node: INode) => void) { this.emitter.on(DETECTING_CHANGE_EVENT, fn); return () => { this.emitter.off(DETECTING_CHANGE_EVENT, fn); diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 8bccde2ef..26648403b 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -9,21 +9,18 @@ import { IPublicTypeDragNodeDataObject, IPublicModelDocumentModel, IPublicModelHistory, - IPublicModelModalNodesManager, IPublicModelNode, - IPublicApiProject, - IPublicModelDropLocation, IPublicEnumTransformStage, IPublicTypeOnChangeOptions, } from '@alilc/lowcode-types'; -import { Project } from '../project'; +import { IProject, Project } from '../project'; import { ISimulatorHost } from '../simulator'; import { ComponentMeta } from '../component-meta'; -import { IDropLocation, Designer } from '../designer'; +import { IDropLocation, Designer, IHistory } from '../designer'; import { Node, insertChildren, insertChild, isNode, RootNode, INode } from './node/node'; import { Selection, ISelection } from './selection'; import { History } from './history'; -import { ModalNodesManager } from './node'; +import { IModalNodesManager, ModalNodesManager } from './node'; import { uniqueId, isPlainObject, compatStage, isJSExpression, isDOMText, isNodeSchema, isDragNodeObject, isDragNodeDataObject } from '@alilc/lowcode-utils'; import { EDITOR_EVENT } from '../types'; @@ -44,17 +41,31 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel, 'select */ readonly selection: ISelection; + readonly project: IProject; + + /** + * 模态节点管理 + */ + readonly modalNodesManager: IModalNodesManager; + /** * 根据 id 获取节点 */ getNode(id: string): INode | null; + + getHistory(): IHistory; + + get focusNode(): INode | null; + + get rootNode(): INode | null; + } export class DocumentModel implements IDocumentModel { /** * 根节点 类型有:Page/Component/Block */ - rootNode: RootNode | null; + rootNode: INode | null; /** * 文档编号 @@ -74,11 +85,11 @@ export class DocumentModel implements IDocumentModel { /** * 模态节点管理 */ - readonly modalNodesManager: IPublicModelModalNodesManager; + readonly modalNodesManager: IModalNodesManager; private _nodesMap = new Map(); - readonly project: IPublicApiProject; + readonly project: IProject; readonly designer: Designer; @@ -114,7 +125,7 @@ export class DocumentModel implements IDocumentModel { this.rootNode?.getExtraProp('fileName', true)?.setValue(fileName); } - get focusNode() { + get focusNode(): INode { if (this._drillDownNode) { return this._drillDownNode; } @@ -147,7 +158,7 @@ export class DocumentModel implements IDocumentModel { @obx.ref private _dropLocation: IDropLocation | null = null; - set dropLocation(loc: IPublicModelDropLocation | null) { + set dropLocation(loc: IDropLocation | null) { this._dropLocation = loc; // pub event this.designer.editor.eventBus.emit( @@ -626,7 +637,7 @@ export class DocumentModel implements IDocumentModel { return data; } - getHistory(): History { + getHistory(): IHistory { return this.history; } @@ -753,7 +764,7 @@ export class DocumentModel implements IDocumentModel { })); } - onNodeCreate(func: (node: Node) => void) { + onNodeCreate(func: (node: INode) => void) { const wrappedFunc = wrapWithEventSwitch(func); this.emitter.on('nodecreate', wrappedFunc); return () => { @@ -761,7 +772,7 @@ export class DocumentModel implements IDocumentModel { }; } - onNodeDestroy(func: (node: Node) => void) { + onNodeDestroy(func: (node: INode) => void) { const wrappedFunc = wrapWithEventSwitch(func); this.emitter.on('nodedestroy', wrappedFunc); return () => { diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index 5d52f0dd3..5de6ca78a 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -193,7 +193,7 @@ export class History implements IHistory { return this.onStateChange(func); } - onStateChange(func: () => any) { + onStateChange(func: () => any): () => void { this.emitter.on('statechange', func); return () => { this.emitter.removeListener('statechange', func); @@ -208,7 +208,8 @@ export class History implements IHistory { onChangeCursor(func: () => any): () => void { return this.onCursor(func); } - onCursor(func: () => any) { + + onCursor(func: () => any): () => void { this.emitter.on('cursor', func); return () => { this.emitter.removeListener('cursor', func); diff --git a/packages/designer/src/document/node/modal-nodes-manager.ts b/packages/designer/src/document/node/modal-nodes-manager.ts index 68bca607b..585b52f5f 100644 --- a/packages/designer/src/document/node/modal-nodes-manager.ts +++ b/packages/designer/src/document/node/modal-nodes-manager.ts @@ -1,15 +1,15 @@ -import { Node } from './node'; +import { INode, Node } from './node'; import { DocumentModel } from '../document-model'; import { IPublicModelModalNodesManager } from '@alilc/lowcode-types'; import { createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core'; -export function getModalNodes(node: Node) { +export function getModalNodes(node: INode | Node) { if (!node) return []; let nodes: any = []; if (node.componentMeta.isModal) { nodes.push(node); } - const children = node.getChildren(); + const { children } = node; if (children) { children.forEach((child) => { nodes = nodes.concat(getModalNodes(child)); @@ -20,14 +20,17 @@ export function getModalNodes(node: Node) { export interface IModalNodesManager extends IPublicModelModalNodesManager { + getModalNodes(): INode[]; + + getVisibleModalNode(): INode | null; } export class ModalNodesManager implements IModalNodesManager { - public willDestroy: any; + willDestroy: any; private page: DocumentModel; - private modalNodes: Node[]; + private modalNodes: INode[]; private nodeRemoveEvents: any; @@ -45,26 +48,27 @@ export class ModalNodesManager implements IModalNodesManager { ]; } - getModalNodes() { + getModalNodes(): INode[] { return this.modalNodes; } - getVisibleModalNode() { - return this.getModalNodes().find((node: Node) => node.getVisible()); + getVisibleModalNode(): INode | null { + const visibleNode = this.getModalNodes().find((node: INode) => node.getVisible()); + return visibleNode || null; } hideModalNodes() { - this.modalNodes.forEach((node: Node) => { + this.modalNodes.forEach((node: INode) => { node.setVisible(false); }); } - setVisible(node: Node) { + setVisible(node: INode) { this.hideModalNodes(); node.setVisible(true); } - setInvisible(node: Node) { + setInvisible(node: INode) { node.setVisible(false); } @@ -82,7 +86,7 @@ export class ModalNodesManager implements IModalNodesManager { }; } - private addNode(node: Node) { + private addNode(node: INode) { if (node.componentMeta.isModal) { this.hideModalNodes(); this.modalNodes.push(node); @@ -92,7 +96,7 @@ export class ModalNodesManager implements IModalNodesManager { } } - private removeNode(node: Node) { + private removeNode(node: INode) { if (node.componentMeta.isModal) { const index = this.modalNodes.indexOf(node); if (index >= 0) { @@ -106,24 +110,24 @@ export class ModalNodesManager implements IModalNodesManager { } } - private addNodeEvent(node: Node) { - this.nodeRemoveEvents[node.getId()] = + private addNodeEvent(node: INode) { + this.nodeRemoveEvents[node.id] = node.onVisibleChange(() => { this.emitter.emit('visibleChange'); }); } - private removeNodeEvent(node: Node) { - if (this.nodeRemoveEvents[node.getId()]) { - this.nodeRemoveEvents[node.getId()](); - delete this.nodeRemoveEvents[node.getId()]; + private removeNodeEvent(node: INode) { + if (this.nodeRemoveEvents[node.id]) { + this.nodeRemoveEvents[node.id](); + delete this.nodeRemoveEvents[node.id]; } } setNodes() { - const nodes = getModalNodes(this.page.getRoot()!); + const nodes = getModalNodes(this.page.rootNode!); this.modalNodes = nodes; - this.modalNodes.forEach((node: Node) => { + this.modalNodes.forEach((node: INode) => { this.addNodeEvent(node); }); diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 9993f4c04..bcdf897b3 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -11,7 +11,10 @@ export interface IOnChangeOptions { } export interface INodeChildren extends Omit { + get owner(): INode; + unlinkChild(node: INode): void; + /** * 删除一个节点 */ @@ -57,6 +60,11 @@ export interface INodeChildren extends Omit number, ): any; + /** + * 根据索引获得节点 + */ + get(index: number): INode | null; + /** overriding methods end */ } export class NodeChildren implements INodeChildren { @@ -64,6 +72,31 @@ export class NodeChildren implements INodeChildren { private emitter: IEventBus = createModuleEventBus('NodeChildren'); + /** + * 元素个数 + */ + @computed get size(): number { + return this.children.length; + } + + get isEmptyNode(): boolean { + return this.size < 1; + } + get notEmptyNode(): boolean { + return this.size > 0; + } + + @computed get length(): number { + return this.children.length; + } + + private purged = false; + + get [Symbol.toStringTag]() { + // 保证向前兼容性 + return 'Array'; + } + constructor( readonly owner: INode, data: IPublicTypeNodeData | IPublicTypeNodeData[], @@ -130,13 +163,6 @@ export class NodeChildren implements INodeChildren { return this.children.concat(nodes); } - /** - * 元素个数 - */ - @computed get size(): number { - return this.children.length; - } - /** * */ @@ -144,24 +170,10 @@ export class NodeChildren implements INodeChildren { return this.isEmptyNode; } - get isEmptyNode(): boolean { - return this.size < 1; - } - notEmpty() { return this.notEmptyNode; } - get notEmptyNode(): boolean { - return this.size > 0; - } - - @computed get length(): number { - return this.children.length; - } - - private purged = false; - /** * 回收销毁 */ @@ -483,11 +495,6 @@ export class NodeChildren implements INodeChildren { }; } - get [Symbol.toStringTag]() { - // 保证向前兼容性 - return 'Array'; - } - private reportModified(node: INode, owner: INode, options = {}) { if (!node) { return; diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index ef837a329..5525493a1 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -18,11 +18,11 @@ import { } from '@alilc/lowcode-types'; import { compatStage, isDOMText, isJSExpression } from '@alilc/lowcode-utils'; import { SettingTopEntry } from '@alilc/lowcode-designer'; -import { Props, getConvertedExtraKey } from './props/props'; +import { Props, getConvertedExtraKey, IProps } from './props/props'; import { DocumentModel, IDocumentModel } from '../document-model'; import { NodeChildren, INodeChildren } from './node-children'; -import { Prop } from './props/prop'; -import { ComponentMeta } from '../../component-meta'; +import { IProp, Prop } from './props/prop'; +import { ComponentMeta, IComponentMeta } from '../../component-meta'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; import { includeSlot, removeSlot } from '../../utils/slot'; import { foreachReverse } from '../../utils/tree'; @@ -36,6 +36,39 @@ export interface NodeStatus { export interface INode extends IPublicModelNode { + /** + * 当前节点子集 + */ + get children(): INodeChildren | null; + + /** + * 获取上一个兄弟节点 + */ + get prevSibling(): INode | null; + + /** + * 获取下一个兄弟节点 + */ + get nextSibling(): INode | null; + + /** + * 父级节点 + */ + get parent(): INode | null; + + get slots(): INode[]; + + /** + * 关联属性 + */ + get slotFor(): IProp | null; + + get props(): IProps; + + get componentMeta(): IComponentMeta; + + get document(): IDocumentModel; + setVisible(flag: boolean): void; getVisible(): boolean; @@ -61,8 +94,6 @@ export interface INode extends IPublicModelNode { */ export(stage: IPublicEnumTransformStage, options?: any): IPublicTypeNodeSchema; - get document(): IDocumentModel; - emitPropChange(val: IPublicTypePropChangeOptions): void; import(data: IPublicTypeNodeSchema, checkId?: boolean): void; @@ -70,6 +101,14 @@ export interface INode extends IPublicModelNode { internalSetSlotFor(slotFor: Prop | null | undefined): void; addSlot(slotNode: INode): void; + + onVisibleChange(func: (flag: boolean) => any): () => void; + + getProp(path: string, createIfNone?: boolean): IProp | null; + + getExtraProp(key: string, createIfNone?: boolean): IProp | null; + + replaceChild(node: INode, data: any): INode; } /** @@ -148,7 +187,7 @@ export class Node /** * 属性抽象 */ - props: Props; + props: IProps; protected _children?: INodeChildren; @@ -204,6 +243,74 @@ export class Node isInited = false; + _settingEntry: SettingTopEntry; + + get settingEntry(): SettingTopEntry { + if (this._settingEntry) return this._settingEntry; + this._settingEntry = this.document.designer.createSettingEntry([this]); + return this._settingEntry; + } + + private autoruns?: Array<() => void>; + + private _isRGLContainer = false; + + set isRGLContainer(status: boolean) { + this._isRGLContainer = status; + } + + get isRGLContainer(): boolean { + return !!this._isRGLContainer; + } + + set isRGLContainerNode(status: boolean) { + this._isRGLContainer = status; + } + + get isRGLContainerNode(): boolean { + return !!this._isRGLContainer; + } + + private _slotFor?: IProp | null = null; + + @obx.shallow _slots: INode[] = []; + + get slots(): INode[] { + return this._slots; + } + + /* istanbul ignore next */ + @obx.ref private _conditionGroup: IPublicModelExclusiveGroup | null = null; + + /* istanbul ignore next */ + get conditionGroup(): IPublicModelExclusiveGroup | null { + return this._conditionGroup; + } + + private purged = false; + + /** + * 是否已销毁 + */ + get isPurged() { + return this.purged; + } + + private purging: boolean = false; + + /** + * 是否正在销毁 + */ + get isPurging() { + return this.purging; + } + + @obx.shallow status: NodeStatus = { + inPlaceEditing: false, + locking: false, + pseudo: false, + }; + constructor(readonly document: IDocumentModel, nodeSchema: Schema, options: any = {}) { makeObservable(this); const { componentName, id, children, props, ...extras } = nodeSchema; @@ -237,14 +344,6 @@ export class Node }); } - _settingEntry: SettingTopEntry; - - get settingEntry(): SettingTopEntry { - if (this._settingEntry) return this._settingEntry; - this._settingEntry = this.document.designer.createSettingEntry([this]); - return this._settingEntry; - } - /** * 节点初始化期间就把内置的一些 prop 初始化好,避免后续不断构造实例导致 reaction 执行多次 */ @@ -268,8 +367,6 @@ export class Node return this.document.designer.transformProps(props, this, IPublicEnumTransformStage.Upgrade); } - private autoruns?: Array<() => void>; - private setupAutoruns() { const autoruns = this.componentMeta.getMetadata().configure.advanced?.autoruns; if (!autoruns || autoruns.length < 1) { @@ -296,24 +393,6 @@ export class Node return children || []; } - private _isRGLContainer = false; - - set isRGLContainer(status: boolean) { - this._isRGLContainer = status; - } - - get isRGLContainer(): boolean { - return !!this._isRGLContainer; - } - - set isRGLContainerNode(status: boolean) { - this._isRGLContainer = status; - } - - get isRGLContainerNode(): boolean { - return !!this._isRGLContainer; - } - isContainer(): boolean { return this.isContainerNode; } @@ -449,8 +528,6 @@ export class Node } } - private _slotFor?: Prop | null = null; - internalSetSlotFor(slotFor: Prop | null | undefined) { this._slotFor = slotFor; } @@ -462,7 +539,7 @@ export class Node /** * 关联属性 */ - get slotFor() { + get slotFor(): IProp | null { return this._slotFor; } @@ -536,24 +613,10 @@ export class Node return this.props.export(IPublicEnumTransformStage.Serilize).props || null; } - @obx.shallow _slots: INode[] = []; - hasSlots() { return this._slots.length > 0; } - get slots() { - return this._slots; - } - - /* istanbul ignore next */ - @obx.ref private _conditionGroup: IPublicModelExclusiveGroup | null = null; - - /* istanbul ignore next */ - get conditionGroup(): IPublicModelExclusiveGroup | null { - return this._conditionGroup; - } - /* istanbul ignore next */ setConditionGroup(grp: IPublicModelExclusiveGroup | string | null) { if (!grp) { @@ -632,10 +695,10 @@ export class Node /** * 替换子节点 * - * @param {Node} node + * @param {INode} node * @param {object} data */ - replaceChild(node: Node, data: any): Node { + replaceChild(node: INode, data: any): INode { if (this.children?.has(node)) { const selected = this.document.selection.has(node.id); @@ -670,11 +733,11 @@ export class Node }; } - getProp(path: string, createIfNone = true): Prop | null { + getProp(path: string, createIfNone = true): IProp | null { return this.props.query(path, createIfNone) || null; } - getExtraProp(key: string, createIfNone = true): Prop | null { + getExtraProp(key: string, createIfNone = true): IProp | null { return this.props.get(getConvertedExtraKey(key), createIfNone) || null; } @@ -734,7 +797,7 @@ export class Node /** * 获取下一个兄弟节点 */ - get nextSibling(): Node | null { + get nextSibling(): INode | null { if (!this.parent) { return null; } @@ -748,7 +811,7 @@ export class Node /** * 获取上一个兄弟节点 */ - get prevSibling(): Node | null { + get prevSibling(): INode | null { if (!this.parent) { return null; } @@ -929,15 +992,6 @@ export class Node this.children?.delete(node); } - private purged = false; - - /** - * 是否已销毁 - */ - get isPurged() { - return this.purged; - } - /** * 销毁 */ @@ -952,18 +1006,10 @@ export class Node // this.document.destroyNode(this); } - private purging: boolean = false; internalPurgeStart() { this.purging = true; } - /** - * 是否正在销毁 - */ - get isPurging() { - return this.purging; - } - /** * 是否可执行某action */ @@ -1044,12 +1090,6 @@ export class Node this.children?.mergeChildren(remover, adder, sorter); } - @obx.shallow status: NodeStatus = { - inPlaceEditing: false, - locking: false, - pseudo: false, - }; - /** * @deprecated */ diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index f140b30d4..582d5fdeb 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -1,6 +1,6 @@ import { obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core'; -import { Designer } from '../designer'; -import { DocumentModel, isDocumentModel } from '../document'; +import { IDesigner } from '../designer'; +import { DocumentModel, IDocumentModel, isDocumentModel } from '../document'; import { IPublicTypeProjectSchema, IPublicTypeRootSchema, @@ -12,14 +12,60 @@ import { import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils'; import { ISimulatorHost } from '../simulator'; -export interface IProject extends IPublicApiProject { +export interface IProject extends Omit< IPublicApiProject, 'simulatorHost' | 'importSchema' | 'exportSchema' | 'openDocument' | 'getDocumentById' | 'getCurrentDocument' | 'addPropsTransducer' | 'onRemoveDocument' | 'onChangeDocument' | 'onSimulatorHostReady' | 'onSimulatorRendererReady' | 'setI18n' > { + get designer(): IDesigner; + + get simulator(): ISimulatorHost | null; + + get currentDocument(): IDocumentModel | null; + + get documents(): IDocumentModel[]; + + open(doc?: string | IDocumentModel | IPublicTypeRootSchema): IDocumentModel | null; + + getDocumentByFileName(fileName: string): IDocumentModel | null; + + createDocument(data?: IPublicTypeRootSchema): IDocumentModel; + + load(schema?: IPublicTypeProjectSchema, autoOpen?: boolean | string): void; + + getSchema( + stage: IPublicEnumTransformStage, + ): IPublicTypeProjectSchema; + + getDocument(id: string): IDocumentModel | null; + + onCurrentDocumentChange(fn: (doc: IDocumentModel) => void): () => void; + + onSimulatorReady(fn: (args: any) => void): () => void; + + onRendererReady(fn: () => void): () => void; + + /** + * 分字段设置储存数据,不记录操作记录 + */ + set( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + key: + | 'version' + | 'componentsTree' + | 'componentsMap' + | 'utils' + | 'constants' + | 'i18n' + | 'css' + | 'dataSource' + | string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + value: any, + ): void; } export class Project implements IProject { private emitter: IEventBus = createModuleEventBus('Project'); - @obx.shallow readonly documents: IPublicModelDocumentModel[] = []; + @obx.shallow readonly documents: IDocumentModel[] = []; private data: IPublicTypeProjectSchema = { version: '1.0.0', @@ -41,14 +87,7 @@ export class Project implements IProject { key = Math.random(); - // TODO: 考虑项目级别 History - - constructor(readonly designer: Designer, schema?: IPublicTypeProjectSchema, readonly viewName = 'global') { - makeObservable(this); - this.load(schema); - } - - @computed get currentDocument() { + @computed get currentDocument(): IDocumentModel | null { return this.documents.find((doc) => doc.active); } @@ -69,6 +108,13 @@ export class Project implements IProject { this._i18n = value || {}; } + private documentsMap = new Map(); + + constructor(readonly designer: IDesigner, schema?: IPublicTypeProjectSchema, readonly viewName = 'global') { + makeObservable(this); + this.load(schema); + } + private getComponentsMap(): IPublicTypeComponentsMap { return this.documents.reduce(( compomentsMap: IPublicTypeComponentsMap, @@ -104,7 +150,9 @@ export class Project implements IProject { /** * 获取项目整体 schema */ - getSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save): IPublicTypeProjectSchema { + getSchema( + stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save, + ): IPublicTypeProjectSchema { return { ...this.data, componentsMap: this.getComponentsMap(), @@ -240,26 +288,24 @@ export class Project implements IProject { return Reflect.get(this.data, key); } - private documentsMap = new Map(); - - getDocument(id: string): DocumentModel | null { + getDocument(id: string): IDocumentModel | null { // 此处不能使用 this.documentsMap.get(id),因为在乐高 rollback 场景,document.id 会被改成其他值 return this.documents.find((doc) => doc.id === id) || null; } - getDocumentByFileName(fileName: string): DocumentModel | null { + getDocumentByFileName(fileName: string): IDocumentModel | null { return this.documents.find((doc) => doc.fileName === fileName) || null; } @action - createDocument(data?: IPublicTypeRootSchema): DocumentModel { + createDocument(data?: IPublicTypeRootSchema): IDocumentModel { const doc = new DocumentModel(this, data || this?.data?.componentsTree?.[0]); this.documents.push(doc); this.documentsMap.set(doc.id, doc); return doc; } - open(doc?: string | DocumentModel | IPublicTypeRootSchema): DocumentModel | null { + open(doc?: string | IDocumentModel | IPublicTypeRootSchema): IDocumentModel | null { if (!doc) { const got = this.documents.find((item) => item.isBlank()); if (got) { @@ -341,7 +387,7 @@ export class Project implements IProject { }; } - onCurrentDocumentChange(fn: (doc: DocumentModel) => void): () => void { + onCurrentDocumentChange(fn: (doc: IDocumentModel) => void): () => void { this.emitter.on('current-document.change', fn); return () => { this.emitter.removeListener('current-document.change', fn); diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index 656c6af6e..30390daca 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, IPublicApiHotkey } from '@alilc/lowcode-types'; +import { IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbackConfig, IPublicTypeHotkeyCallbacks, IPublicApiHotkey } from '@alilc/lowcode-types'; interface KeyMap { [key: number]: string; @@ -14,23 +14,10 @@ interface ActionEvent { type: string; } -interface IPublicTypeHotkeyCallbacks { - [key: string]: IPublicTypeHotkeyCallbackCfg[]; -} - interface HotkeyDirectMap { [key: string]: IPublicTypeHotkeyCallback; } -interface IPublicTypeHotkeyCallbackCfg { - callback: IPublicTypeHotkeyCallback; - modifiers: string[]; - action: string; - seq?: string; - level?: number; - combo?: string; -} - interface KeyInfo { key: string; modifiers: string[]; @@ -444,10 +431,10 @@ export class Hotkey implements IHotKey { sequenceName?: string, combination?: string, level?: number, - ): IPublicTypeHotkeyCallbackCfg[] { + ): IPublicTypeHotkeyCallbackConfig[] { let i: number; - let callback: IPublicTypeHotkeyCallbackCfg; - const matches: IPublicTypeHotkeyCallbackCfg[] = []; + let callback: IPublicTypeHotkeyCallbackConfig; + const matches: IPublicTypeHotkeyCallbackConfig[] = []; const action: string = e.type; // if there are no events related to this keycode @@ -498,7 +485,7 @@ export class Hotkey implements IHotKey { } private handleKey(character: string, modifiers: string[], e: KeyboardEvent): void { - const callbacks: IPublicTypeHotkeyCallbackCfg[] = this.getMatches(character, modifiers, e); + const callbacks: IPublicTypeHotkeyCallbackConfig[] = this.getMatches(character, modifiers, e); let i: number; const doNotReset: SequenceLevels = {}; let maxLevel = 0; diff --git a/packages/shell/src/api/canvas.ts b/packages/shell/src/api/canvas.ts index 4436514fb..3c3129957 100644 --- a/packages/shell/src/api/canvas.ts +++ b/packages/shell/src/api/canvas.ts @@ -14,9 +14,11 @@ import { IDesigner, } from '@alilc/lowcode-designer'; import { editorSymbol, designerSymbol, nodeSymbol } from '../symbols'; -import { Dragon } from '../model'; -import { DropLocation } from '../model/drop-location'; -import { ActiveTracker } from '../model/active-tracker'; +import { + Dragon as ShellDragon, + DropLocation as ShellDropLocation, + ActiveTracker as ShellActiveTracker, +} from '../model'; export class Canvas implements IPublicApiCanvas { private readonly [editorSymbol]: IPublicModelEditor; @@ -25,6 +27,15 @@ export class Canvas implements IPublicApiCanvas { return this[editorSymbol].get('designer') as IDesigner; } + get dragon(): IPublicModelDragon | null { + return ShellDragon.create(this[designerSymbol].dragon, this.workspaceMode); + } + + get activeTracker(): IPublicModelActiveTracker | null { + const activeTracker = new ShellActiveTracker(this[designerSymbol].activeTracker); + return activeTracker; + } + constructor(editor: IPublicModelEditor, readonly workspaceMode: boolean = false) { this[editorSymbol] = editor; } @@ -47,19 +58,10 @@ export class Canvas implements IPublicApiCanvas { }); } - get dragon(): IPublicModelDragon | null { - return Dragon.create(this[designerSymbol].dragon, this.workspaceMode); - } - - get activeTracker(): IPublicModelActiveTracker | null { - const activeTracker = new ActiveTracker(this[designerSymbol].activeTracker); - return activeTracker; - } - /** * @deprecated */ get dropLocation() { - return DropLocation.create((this[designerSymbol] as any).dropLocation || null); + return ShellDropLocation.create((this[designerSymbol] as any).dropLocation || null); } } \ No newline at end of file diff --git a/packages/shell/src/api/common.tsx b/packages/shell/src/api/common.tsx index ee87bea15..9954fdfe6 100644 --- a/packages/shell/src/api/common.tsx +++ b/packages/shell/src/api/common.tsx @@ -58,7 +58,7 @@ import { computed as innerComputed, observer as innerObserver, } from '@alilc/lowcode-editor-core'; -import { Dragon } from '../model'; +import { Dragon as ShellDragon } from '../model'; import { ReactNode, Component } from 'react'; class DesignerCabin implements IPublicApiCommonDesignerCabin { @@ -149,7 +149,7 @@ class DesignerCabin implements IPublicApiCommonDesignerCabin { * @deprecated please use canvas.dragon */ get dragon(): IPublicModelDragon | null { - return Dragon.create(this[designerSymbol].dragon); + return ShellDragon.create(this[designerSymbol].dragon, false); } } diff --git a/packages/shell/src/api/event.ts b/packages/shell/src/api/event.ts index 1f82d5f87..746d9ae6a 100644 --- a/packages/shell/src/api/event.ts +++ b/packages/shell/src/api/event.ts @@ -14,12 +14,6 @@ export class Event implements IPublicApiEvent { private readonly [eventBusSymbol]: EventBus; private readonly options: EventOptions; - // TODO: - /** - * 内核触发的事件名 - */ - readonly names = []; - constructor(eventBus: EventBus, options: EventOptions, public workspaceMode = false) { this[eventBusSymbol] = eventBus; this.options = options; diff --git a/packages/shell/src/api/hotkey.ts b/packages/shell/src/api/hotkey.ts index 2e9e2043d..4e65844ce 100644 --- a/packages/shell/src/api/hotkey.ts +++ b/packages/shell/src/api/hotkey.ts @@ -1,6 +1,6 @@ import { globalContext, Hotkey as InnerHotkey } from '@alilc/lowcode-editor-core'; import { hotkeySymbol } from '../symbols'; -import { IPublicTypeDisposable, IPublicTypeHotkeyCallback, IPublicApiHotkey } from '@alilc/lowcode-types'; +import { IPublicTypeDisposable, IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbacks, IPublicApiHotkey } from '@alilc/lowcode-types'; const innerHotkeySymbol = Symbol('innerHotkey'); @@ -22,15 +22,17 @@ export class Hotkey implements IPublicApiHotkey { this[innerHotkeySymbol] = hotkey; } - get callbacks(): any { + get callbacks(): IPublicTypeHotkeyCallbacks { return this[hotkeySymbol].callBacks; } + /** * @deprecated */ get callBacks() { return this.callbacks; } + /** * 绑定快捷键 * @param combos 快捷键,格式如:['command + s'] 、['ctrl + shift + s'] 等 @@ -38,7 +40,11 @@ export class Hotkey implements IPublicApiHotkey { * @param action * @returns */ - bind(combos: string[] | string, callback: IPublicTypeHotkeyCallback, action?: string): IPublicTypeDisposable { + bind( + combos: string[] | string, + callback: IPublicTypeHotkeyCallback, + action?: string, + ): IPublicTypeDisposable { this[hotkeySymbol].bind(combos, callback, action); return () => { this[hotkeySymbol].unbind(combos, callback, action); diff --git a/packages/shell/src/api/material.ts b/packages/shell/src/api/material.ts index 08deefdcc..eca386c5a 100644 --- a/packages/shell/src/api/material.ts +++ b/packages/shell/src/api/material.ts @@ -1,6 +1,6 @@ -import { Editor, globalContext } from '@alilc/lowcode-editor-core'; +import { globalContext } from '@alilc/lowcode-editor-core'; import { - Designer, + IDesigner, isComponentMeta, } from '@alilc/lowcode-designer'; import { IPublicTypeAssetsJson } from '@alilc/lowcode-utils'; @@ -11,21 +11,22 @@ import { IPublicTypeMetadataTransducer, IPublicModelComponentMeta, IPublicTypeNpmInfo, + IPublicModelEditor, } from '@alilc/lowcode-types'; -import { Workspace } from '@alilc/lowcode-workspace'; +import { Workspace as InnerWorkspace } from '@alilc/lowcode-workspace'; import { editorSymbol, designerSymbol } from '../symbols'; -import { ComponentMeta } from '../model/component-meta'; +import { ComponentMeta as ShellComponentMeta } from '../model'; import { ComponentType } from 'react'; const innerEditorSymbol = Symbol('editor'); export class Material implements IPublicApiMaterial { - private readonly [innerEditorSymbol]: Editor; + private readonly [innerEditorSymbol]: IPublicModelEditor; - get [editorSymbol](): Editor { + get [editorSymbol](): IPublicModelEditor { if (this.workspaceMode) { return this[innerEditorSymbol]; } - const workspace: Workspace = globalContext.get('workspace'); + const workspace: InnerWorkspace = globalContext.get('workspace'); if (workspace.isActive) { return workspace.window.editor; } @@ -33,11 +34,11 @@ export class Material implements IPublicApiMaterial { return this[innerEditorSymbol]; } - get [designerSymbol](): Designer { + get [designerSymbol](): IDesigner { return this[editorSymbol].get('designer')!; } - constructor(editor: Editor, readonly workspaceMode: boolean = false) { + constructor(editor: IPublicModelEditor, readonly workspaceMode: boolean = false) { this[innerEditorSymbol] = editor; } @@ -103,7 +104,7 @@ export class Material implements IPublicApiMaterial { */ getComponentMeta(componentName: string): IPublicModelComponentMeta | null { const innerMeta = this[designerSymbol].getComponentMeta(componentName); - return ComponentMeta.create(innerMeta); + return ShellComponentMeta.create(innerMeta); } /** @@ -112,7 +113,7 @@ export class Material implements IPublicApiMaterial { * @returns */ createComponentMeta(metadata: IPublicTypeComponentMetadata) { - return ComponentMeta.create(this[designerSymbol].createComponentMeta(metadata)); + return ShellComponentMeta.create(this[designerSymbol].createComponentMeta(metadata)); } /** @@ -158,7 +159,10 @@ export class Material implements IPublicApiMaterial { * @param actionName * @param handle */ - modifyBuiltinComponentAction(actionName: string, handle: (action: IPublicTypeComponentAction) => void) { + modifyBuiltinComponentAction( + actionName: string, + handle: (action: IPublicTypeComponentAction) => void, + ) { this[designerSymbol].componentActions.modifyBuiltinComponentAction(actionName, handle); } diff --git a/packages/shell/src/api/plugins.ts b/packages/shell/src/api/plugins.ts index 681628515..6e2b9c6b7 100644 --- a/packages/shell/src/api/plugins.ts +++ b/packages/shell/src/api/plugins.ts @@ -9,7 +9,7 @@ import { IPublicTypePluginRegisterOptions, IPublicTypePreferenceValueType, } from '@alilc/lowcode-types'; -import { PluginInstance } from '../model/plugin-instance'; +import { PluginInstance as ShellPluginInstance } from '../model'; import { pluginsSymbol } from '../symbols'; const innerPluginsSymbol = Symbol('plugin'); @@ -43,21 +43,23 @@ export class Plugins implements IPublicApiPlugins { await this[pluginsSymbol].init(registerOptions); } - getPluginPreference(pluginName: string): Record | null | undefined { + getPluginPreference( + pluginName: string, + ): Record | null | undefined { return this[pluginsSymbol].getPluginPreference(pluginName); } get(pluginName: string): IPublicModelPluginInstance | null { const instance = this[pluginsSymbol].get(pluginName); if (instance) { - return new PluginInstance(instance); + return new ShellPluginInstance(instance); } return null; } getAll() { - return this[pluginsSymbol].getAll()?.map(d => new PluginInstance(d)); + return this[pluginsSymbol].getAll()?.map((d) => new ShellPluginInstance(d)); } has(pluginName: string) { diff --git a/packages/shell/src/api/project.ts b/packages/shell/src/api/project.ts index 3ad977584..04feb81f3 100644 --- a/packages/shell/src/api/project.ts +++ b/packages/shell/src/api/project.ts @@ -1,6 +1,6 @@ import { BuiltinSimulatorHost, - Project as InnerProject, + IProject as InnerProject, } from '@alilc/lowcode-designer'; import { globalContext } from '@alilc/lowcode-editor-core'; import { @@ -14,9 +14,7 @@ import { IPublicEnumTransformStage, IPublicTypeDisposable, } from '@alilc/lowcode-types'; - - -import { DocumentModel } from '../model/document-model'; +import { DocumentModel as ShellDocumentModel } from '../model'; import { SimulatorHost } from './simulator-host'; import { editorSymbol, projectSymbol, simulatorHostSymbol, documentSymbol } from '../symbols'; @@ -61,7 +59,7 @@ export class Project implements IPublicApiProject { * @returns */ get documents(): IPublicModelDocumentModel[] { - return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!); + return this[projectSymbol].documents.map((doc) => ShellDocumentModel.create(doc)!); } /** @@ -85,8 +83,10 @@ export class Project implements IPublicApiProject { */ openDocument(doc?: string | IPublicTypeRootSchema | undefined) { const documentModel = this[projectSymbol].open(doc); - if (!documentModel) return null; - return DocumentModel.create(documentModel); + if (!documentModel) { + return null; + } + return ShellDocumentModel.create(documentModel); } /** @@ -96,7 +96,7 @@ export class Project implements IPublicApiProject { */ createDocument(data?: IPublicTypeRootSchema): IPublicModelDocumentModel | null { const doc = this[projectSymbol].createDocument(data); - return DocumentModel.create(doc); + return ShellDocumentModel.create(doc); } /** @@ -113,7 +113,8 @@ export class Project implements IPublicApiProject { * @returns */ getDocumentByFileName(fileName: string): IPublicModelDocumentModel | null { - return DocumentModel.create(this[projectSymbol].getDocumentByFileName(fileName)); + const innerDocumentModel = this[projectSymbol].getDocumentByFileName(fileName); + return ShellDocumentModel.create(innerDocumentModel); } /** @@ -122,7 +123,7 @@ export class Project implements IPublicApiProject { * @returns */ getDocumentById(id: string): IPublicModelDocumentModel | null { - return DocumentModel.create(this[projectSymbol].getDocument(id)); + return ShellDocumentModel.create(this[projectSymbol].getDocument(id)); } /** @@ -146,7 +147,7 @@ export class Project implements IPublicApiProject { * @returns */ getCurrentDocument(): IPublicModelDocumentModel | null { - return DocumentModel.create(this[projectSymbol].currentDocument); + return ShellDocumentModel.create(this[projectSymbol].currentDocument); } /** @@ -154,7 +155,10 @@ export class Project implements IPublicApiProject { * @param transducer * @param stage */ - addPropsTransducer(transducer: IPublicTypePropsTransducer, stage: IPublicEnumTransformStage): void { + addPropsTransducer( + transducer: IPublicTypePropsTransducer, + stage: IPublicEnumTransformStage, + ): void { this[projectSymbol].designer.addPropsReducer(transducer, stage); } @@ -175,10 +179,10 @@ export class Project implements IPublicApiProject { */ onChangeDocument(fn: (doc: IPublicModelDocumentModel) => void): IPublicTypeDisposable { const offFn = this[projectSymbol].onCurrentDocumentChange((originalDoc) => { - fn(DocumentModel.create(originalDoc)!); + fn(ShellDocumentModel.create(originalDoc)!); }); if (this[projectSymbol].currentDocument) { - fn(DocumentModel.create(this[projectSymbol].currentDocument)!); + fn(ShellDocumentModel.create(this[projectSymbol].currentDocument)!); } return offFn; } diff --git a/packages/shell/src/api/skeleton.ts b/packages/shell/src/api/skeleton.ts index 51a30d018..8d5e2dc75 100644 --- a/packages/shell/src/api/skeleton.ts +++ b/packages/shell/src/api/skeleton.ts @@ -23,7 +23,11 @@ export class Skeleton implements IPublicApiSkeleton { return this[innerSkeletonSymbol]; } - constructor(skeleton: InnerSkeleton, pluginName: string, readonly workspaceMode: boolean = false) { + constructor( + skeleton: InnerSkeleton, + pluginName: string, + readonly workspaceMode: boolean = false, + ) { this[innerSkeletonSymbol] = skeleton; this.pluginName = pluginName; } diff --git a/packages/shell/src/api/workspace.ts b/packages/shell/src/api/workspace.ts index f32b403b1..be6eb3ef7 100644 --- a/packages/shell/src/api/workspace.ts +++ b/packages/shell/src/api/workspace.ts @@ -1,9 +1,8 @@ import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeResourceType } from '@alilc/lowcode-types'; import { Workspace as InnerWorkSpace } from '@alilc/lowcode-workspace'; import { Plugins } from '@alilc/lowcode-shell'; -import { Window } from '../model/window'; import { workspaceSymbol } from '../symbols'; -import { Resource } from '../model'; +import { Resource as ShellResource, Window as ShellWindow } from '../model'; export class Workspace implements IPublicApiWorkspace { readonly [workspaceSymbol]: InnerWorkSpace; @@ -13,7 +12,7 @@ export class Workspace implements IPublicApiWorkspace { } get resourceList() { - return this[workspaceSymbol].getResourceList().map(d => new Resource(d)); + return this[workspaceSymbol].getResourceList().map((d) => new ShellResource(d)); } setResourceList(resourceList: IPublicResourceList) { @@ -29,14 +28,14 @@ export class Workspace implements IPublicApiWorkspace { } get window() { - return new Window(this[workspaceSymbol].window); + return new ShellWindow(this[workspaceSymbol].window); } registerResourceType(resourceTypeModel: IPublicTypeResourceType): void { this[workspaceSymbol].registerResourceType(resourceTypeModel); } - openEditorWindow(resourceName: string, title: string, extra: Object, viewName?: string) { + openEditorWindow(resourceName: string, title: string, extra: object, viewName?: string) { this[workspaceSymbol].openEditorWindow(resourceName, title, extra, viewName); } @@ -57,7 +56,7 @@ export class Workspace implements IPublicApiWorkspace { } get windows() { - return this[workspaceSymbol].windows.map(d => new Window(d)); + return this[workspaceSymbol].windows.map((d) => new ShellWindow(d)); } onChangeWindows(fn: () => void) { diff --git a/packages/shell/src/model/active-tracker.ts b/packages/shell/src/model/active-tracker.ts index 0c9c42efe..77ddeffab 100644 --- a/packages/shell/src/model/active-tracker.ts +++ b/packages/shell/src/model/active-tracker.ts @@ -1,16 +1,14 @@ import { IPublicModelActiveTracker, IPublicModelNode, IPublicTypeActiveTarget } from '@alilc/lowcode-types'; -import { IActiveTracker } from '@alilc/lowcode-designer'; -import { Node } from './node'; +import { IActiveTracker as InnerActiveTracker, INode as InnerNode } from '@alilc/lowcode-designer'; +import { Node as ShellNode } from './node'; import { nodeSymbol } from '../symbols'; const activeTrackerSymbol = Symbol('activeTracker'); - export class ActiveTracker implements IPublicModelActiveTracker { - private readonly [activeTrackerSymbol]: IActiveTracker; + private readonly [activeTrackerSymbol]: InnerActiveTracker; - - constructor(innerTracker: IActiveTracker) { + constructor(innerTracker: InnerActiveTracker) { this[activeTrackerSymbol] = innerTracker; } @@ -20,7 +18,7 @@ export class ActiveTracker implements IPublicModelActiveTracker { } return this[activeTrackerSymbol].onChange((t: IPublicTypeActiveTarget) => { const { node: innerNode, detail, instance } = t; - const publicNode = Node.create(innerNode); + const publicNode = ShellNode.create(innerNode as InnerNode); const publicActiveTarget = { node: publicNode!, detail, diff --git a/packages/shell/src/model/component-meta.ts b/packages/shell/src/model/component-meta.ts index 8fcab78ef..67cb2895d 100644 --- a/packages/shell/src/model/component-meta.ts +++ b/packages/shell/src/model/component-meta.ts @@ -1,5 +1,5 @@ import { - ComponentMeta as InnerComponentMeta, + IComponentMeta as InnerComponentMeta, INode, } from '@alilc/lowcode-designer'; import { IPublicTypeNodeData, IPublicTypeNodeSchema, IPublicModelComponentMeta, IPublicTypeI18nData, IPublicTypeIconType, IPublicTypeNpmInfo, IPublicTypeTransformedComponentMetadata, IPublicModelNode } from '@alilc/lowcode-types'; @@ -9,6 +9,8 @@ import { ReactElement } from 'react'; export class ComponentMeta implements IPublicModelComponentMeta { private readonly [componentMetaSymbol]: InnerComponentMeta; + isComponentMeta = true; + constructor(componentMeta: InnerComponentMeta) { this[componentMetaSymbol] = componentMeta; } @@ -83,7 +85,7 @@ export class ComponentMeta implements IPublicModelComponentMeta { * @deprecated */ get prototype() { - return this[componentMetaSymbol].prototype; + return (this[componentMetaSymbol] as any).prototype; } get availableActions(): any { @@ -106,7 +108,6 @@ export class ComponentMeta implements IPublicModelComponentMeta { return this[componentMetaSymbol].getMetadata(); } - isComponentMeta = true; /** * check if the current node could be placed in parent node * @param my @@ -124,9 +125,15 @@ export class ComponentMeta implements IPublicModelComponentMeta { * @param parent * @returns */ - checkNestingDown(my: IPublicModelNode | IPublicTypeNodeData, target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[]) { + checkNestingDown( + my: IPublicModelNode | IPublicTypeNodeData, + target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[], + ) { const curNode = (my as any)?.isNode ? (my as any)[nodeSymbol] : my; - return this[componentMetaSymbol].checkNestingDown(curNode as any, (target as any)[nodeSymbol] || target); + return this[componentMetaSymbol].checkNestingDown( + curNode as any, + (target as any)[nodeSymbol] || target, + ); } refreshMetadata(): void { diff --git a/packages/shell/src/model/detecting.ts b/packages/shell/src/model/detecting.ts index f99423eae..7ce0fe1e5 100644 --- a/packages/shell/src/model/detecting.ts +++ b/packages/shell/src/model/detecting.ts @@ -2,6 +2,7 @@ import { Node as ShellNode } from './node'; import { Detecting as InnerDetecting, IDocumentModel as InnerDocumentModel, + INode as InnerNode, } from '@alilc/lowcode-designer'; import { documentSymbol, detectingSymbol } from '../symbols'; import { IPublicModelDetecting, IPublicModelNode, IPublicTypeDisposable } from '@alilc/lowcode-types'; @@ -52,7 +53,11 @@ export class Detecting implements IPublicModelDetecting { this[detectingSymbol].leave(this[documentSymbol]); } - onDetectingChange(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable { - return this[detectingSymbol].onDetectingChange(fn); + onDetectingChange(fn: (node: IPublicModelNode | null) => void): IPublicTypeDisposable { + const innerFn = (innerNode: InnerNode) => { + const shellNode = ShellNode.create(innerNode); + fn(shellNode); + }; + return this[detectingSymbol].onDetectingChange(innerFn); } } \ No newline at end of file diff --git a/packages/shell/src/model/document-model.ts b/packages/shell/src/model/document-model.ts index 256cbd960..13fc49bae 100644 --- a/packages/shell/src/model/document-model.ts +++ b/packages/shell/src/model/document-model.ts @@ -1,8 +1,6 @@ -import { Editor } from '@alilc/lowcode-editor-core'; import { - DocumentModel as InnerDocumentModel, - Node as InnerNode, - isDragNodeObject, + IDocumentModel as InnerDocumentModel, + INode as InnerNode, } from '@alilc/lowcode-designer'; import { IPublicEnumTransformStage, @@ -23,23 +21,24 @@ import { IPublicModelDropLocation, IPublicApiCanvas, IPublicTypeDisposable, + IPublicModelEditor, } from '@alilc/lowcode-types'; -import { Node } from './node'; -import { Selection } from './selection'; -import { Detecting } from './detecting'; -import { History } from './history'; -import { DropLocation } from './drop-location'; -import { Project } from '../api/project'; -import { Prop } from './prop'; +import { isDragNodeObject } from '@alilc/lowcode-utils'; +import { Node as ShellNode } from './node'; +import { Selection as ShellSelection } from './selection'; +import { Detecting as ShellDetecting } from './detecting'; +import { History as ShellHistory } from './history'; +import { DropLocation as ShellDropLocation } from './drop-location'; +import { Project as ShellProject, Canvas as ShellCanvas } from '../api'; +import { Prop as ShellProp } from './prop'; import { ModalNodesManager } from './modal-nodes-manager'; import { documentSymbol, editorSymbol, nodeSymbol } from '../symbols'; -import { Canvas } from '../api'; const shellDocSymbol = Symbol('shellDocSymbol'); export class DocumentModel implements IPublicModelDocumentModel { private readonly [documentSymbol]: InnerDocumentModel; - private readonly [editorSymbol]: Editor; + private readonly [editorSymbol]: IPublicModelEditor; private _focusNode: IPublicModelNode | null; selection: IPublicModelSelection; detecting: IPublicModelDetecting; @@ -52,13 +51,13 @@ export class DocumentModel implements IPublicModelDocumentModel { constructor(document: InnerDocumentModel) { this[documentSymbol] = document; - this[editorSymbol] = document.designer?.editor as Editor; - this.selection = new Selection(document); - this.detecting = new Detecting(document); - this.history = new History(document); - this.canvas = new Canvas(this[editorSymbol]); + this[editorSymbol] = document.designer?.editor as IPublicModelEditor; + this.selection = new ShellSelection(document); + this.detecting = new ShellDetecting(document); + this.history = new ShellHistory(document); + this.canvas = new ShellCanvas(this[editorSymbol]); - this._focusNode = Node.create(this[documentSymbol].focusNode); + this._focusNode = ShellNode.create(this[documentSymbol].focusNode); } static create(document: InnerDocumentModel | undefined | null): IPublicModelDocumentModel | null { @@ -91,7 +90,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @returns */ get project(): IPublicApiProject { - return Project.create(this[documentSymbol].project); + return ShellProject.create(this[documentSymbol].project); } /** @@ -100,7 +99,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @returns */ get root(): IPublicModelNode | null { - return Node.create(this[documentSymbol].getRoot()); + return ShellNode.create(this[documentSymbol].rootNode); } get focusNode(): IPublicModelNode | null { @@ -135,7 +134,7 @@ export class DocumentModel implements IPublicModelDocumentModel { } get dropLocation(): IPublicModelDropLocation | null { - return DropLocation.create(this[documentSymbol].dropLocation); + return ShellDropLocation.create(this[documentSymbol].dropLocation); } set dropLocation(loc: IPublicModelDropLocation | null) { @@ -148,7 +147,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @param {string} nodeId */ getNodeById(nodeId: string): IPublicModelNode | null { - return Node.create(this[documentSymbol].getNode(nodeId)); + return ShellNode.create(this[documentSymbol].getNode(nodeId)); } /** @@ -189,7 +188,7 @@ export class DocumentModel implements IPublicModelDocumentModel { at, copy, ); - return Node.create(node); + return ShellNode.create(node); } /** @@ -198,7 +197,7 @@ export class DocumentModel implements IPublicModelDocumentModel { * @returns */ createNode(data: any): IPublicModelNode | null { - return Node.create(this[documentSymbol].createNode(data)); + return ShellNode.create(this[documentSymbol].createNode(data)); } /** @@ -243,7 +242,7 @@ export class DocumentModel implements IPublicModelDocumentModel { */ onAddNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable { return this[documentSymbol].onNodeCreate((node: InnerNode) => { - fn(Node.create(node)!); + fn(ShellNode.create(node)!); }); } @@ -262,7 +261,7 @@ export class DocumentModel implements IPublicModelDocumentModel { */ onRemoveNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable { return this[documentSymbol].onNodeDestroy((node: InnerNode) => { - fn(Node.create(node)!); + fn(ShellNode.create(node)!); }); } @@ -271,7 +270,7 @@ export class DocumentModel implements IPublicModelDocumentModel { */ onChangeDetecting(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable { return this[documentSymbol].designer.detecting.onDetectingChange((node: InnerNode) => { - fn(Node.create(node)!); + fn(ShellNode.create(node)!); }); } @@ -290,7 +289,7 @@ export class DocumentModel implements IPublicModelDocumentModel { */ onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): void { this[documentSymbol].onChangeNodeVisible((node: IPublicModelNode, visible: boolean) => { - fn(Node.create(node)!, visible); + fn(ShellNode.create(node)!, visible); }); } @@ -305,7 +304,7 @@ export class DocumentModel implements IPublicModelDocumentModel { } fn({ type: info.type, - node: Node.create(info.node)!, + node: ShellNode.create(info.node)!, }); }); } @@ -322,8 +321,8 @@ export class DocumentModel implements IPublicModelDocumentModel { key: info.key, oldValue: info.oldValue, newValue: info.newValue, - prop: Prop.create(info.prop)!, - node: Node.create(info.node as any)!, + prop: ShellProp.create(info.prop)!, + node: ShellNode.create(info.node as any)!, }); }, ); diff --git a/packages/shell/src/model/drag-object.ts b/packages/shell/src/model/drag-object.ts index 02389e511..dc4157bd2 100644 --- a/packages/shell/src/model/drag-object.ts +++ b/packages/shell/src/model/drag-object.ts @@ -9,7 +9,7 @@ export class DragObject implements IPublicModelDragObject { this[dragObjectSymbol] = dragObject; } - static create(dragObject: InnerDragObject): IPublicModelDragObject | null { + static create(dragObject: InnerDragObject | null): IPublicModelDragObject | null { if (!dragObject) { return null; } diff --git a/packages/shell/src/model/dragon.ts b/packages/shell/src/model/dragon.ts index cc3f7a0f1..392e3d158 100644 --- a/packages/shell/src/model/dragon.ts +++ b/packages/shell/src/model/dragon.ts @@ -15,7 +15,6 @@ import { export const innerDragonSymbol = Symbol('innerDragonSymbol'); - export class Dragon implements IPublicModelDragon { private readonly [innerDragonSymbol]: IPublicModelDragon; @@ -38,7 +37,10 @@ export class Dragon implements IPublicModelDragon { return designer.dragon; } - static create(dragon: IPublicModelDragon | null, workspaceMode: boolean): IPublicModelDragon | null { + static create( + dragon: IPublicModelDragon | null, + workspaceMode: boolean, + ): IPublicModelDragon | null { if (!dragon) { return null; } diff --git a/packages/shell/src/model/drop-location.ts b/packages/shell/src/model/drop-location.ts index e4b13a668..d927c969f 100644 --- a/packages/shell/src/model/drop-location.ts +++ b/packages/shell/src/model/drop-location.ts @@ -1,5 +1,5 @@ import { - DropLocation as InnerDropLocation, + IDropLocation as InnerDropLocation, } from '@alilc/lowcode-designer'; import { dropLocationSymbol } from '../symbols'; import { Node } from './node'; diff --git a/packages/shell/src/model/history.ts b/packages/shell/src/model/history.ts index e872847de..d16f1e3f8 100644 --- a/packages/shell/src/model/history.ts +++ b/packages/shell/src/model/history.ts @@ -1,11 +1,11 @@ -import { DocumentModel as InnerDocumentModel } from '@alilc/lowcode-designer'; +import { IDocumentModel as InnerDocumentModel, IHistory as InnerHistory } from '@alilc/lowcode-designer'; import { historySymbol, documentSymbol } from '../symbols'; import { IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types'; export class History implements IPublicModelHistory { private readonly [documentSymbol]: InnerDocumentModel; - private get [historySymbol]() { + private get [historySymbol](): InnerHistory { return this[documentSymbol].getHistory(); } @@ -64,7 +64,7 @@ export class History implements IPublicModelHistory { * @returns */ onChangeState(func: () => any): IPublicTypeDisposable { - return this[historySymbol].onStateChange(func); + return this[historySymbol].onChangeState(func); } /** @@ -73,6 +73,6 @@ export class History implements IPublicModelHistory { * @returns */ onChangeCursor(func: () => any): IPublicTypeDisposable { - return this[historySymbol].onCursor(func); + return this[historySymbol].onChangeCursor(func); } } diff --git a/packages/shell/src/model/index.ts b/packages/shell/src/model/index.ts index d0e45cc94..d20120c3e 100644 --- a/packages/shell/src/model/index.ts +++ b/packages/shell/src/model/index.ts @@ -14,4 +14,7 @@ export * from './props'; export * from './selection'; export * from './setting-prop-entry'; export * from './setting-top-entry'; -export * from './resource'; \ No newline at end of file +export * from './resource'; +export * from './active-tracker'; +export * from './plugin-instance'; +export * from './window'; \ No newline at end of file diff --git a/packages/shell/src/model/modal-nodes-manager.ts b/packages/shell/src/model/modal-nodes-manager.ts index 71c94666c..b1e27596f 100644 --- a/packages/shell/src/model/modal-nodes-manager.ts +++ b/packages/shell/src/model/modal-nodes-manager.ts @@ -1,6 +1,9 @@ -import { ModalNodesManager as InnerModalNodesManager } from '@alilc/lowcode-designer'; +import { + IModalNodesManager as InnerModalNodesManager, + INode as InnerNode, +} from '@alilc/lowcode-designer'; import { IPublicModelModalNodesManager, IPublicModelNode } from '@alilc/lowcode-types'; -import { Node } from './node'; +import { Node as ShellNode } from './node'; import { nodeSymbol, modalNodesManagerSymbol } from '../symbols'; export class ModalNodesManager implements IPublicModelModalNodesManager { @@ -28,18 +31,24 @@ export class ModalNodesManager implements IPublicModelModalNodesManager { /** * 获取模态节点(们) - * @returns */ - getModalNodes(): any { - return this[modalNodesManagerSymbol].getModalNodes().map((node) => Node.create(node)); + getModalNodes(): IPublicModelNode[] { + const innerNodes = this[modalNodesManagerSymbol].getModalNodes(); + const shellNodes: IPublicModelNode[] = []; + innerNodes?.forEach((node: InnerNode) => { + const shellNode = ShellNode.create(node); + if (shellNode) { + shellNodes.push(shellNode); + } + }); + return shellNodes; } /** * 获取当前可见的模态节点 - * @returns */ - getVisibleModalNode(): any { - return Node.create(this[modalNodesManagerSymbol].getVisibleModalNode()); + getVisibleModalNode(): IPublicModelNode | null { + return ShellNode.create(this[modalNodesManagerSymbol].getVisibleModalNode()); } /** @@ -54,7 +63,7 @@ export class ModalNodesManager implements IPublicModelModalNodesManager { * @param node Node */ setVisible(node: IPublicModelNode): void { - this[modalNodesManagerSymbol].setVisible(node[nodeSymbol]); + this[modalNodesManagerSymbol].setVisible((node as any)[nodeSymbol]); } /** @@ -62,6 +71,6 @@ export class ModalNodesManager implements IPublicModelModalNodesManager { * @param node Node */ setInvisible(node: IPublicModelNode): void { - this[modalNodesManagerSymbol].setInvisible(node[nodeSymbol]); + this[modalNodesManagerSymbol].setInvisible((node as any)[nodeSymbol]); } } \ No newline at end of file diff --git a/packages/shell/src/model/node-children.ts b/packages/shell/src/model/node-children.ts index 9f8792ee3..0192268bc 100644 --- a/packages/shell/src/model/node-children.ts +++ b/packages/shell/src/model/node-children.ts @@ -1,6 +1,6 @@ import { INode as InnerNode, INodeChildren } from '@alilc/lowcode-designer'; import { IPublicTypeNodeData, IPublicEnumTransformStage, IPublicModelNodeChildren, IPublicModelNode } from '@alilc/lowcode-types'; -import { Node } from './node'; +import { Node as ShellNode } from './node'; import { nodeSymbol, nodeChildrenSymbol } from '../symbols'; export class NodeChildren implements IPublicModelNodeChildren { @@ -21,7 +21,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * 返回当前 children 实例所属的节点实例 */ get owner(): IPublicModelNode | null { - return Node.create(this[nodeChildrenSymbol].owner); + return ShellNode.create(this[nodeChildrenSymbol].owner); } /** @@ -107,7 +107,7 @@ export class NodeChildren implements IPublicModelNodeChildren { * @returns */ get(index: number): IPublicModelNode | null { - return Node.create(this[nodeChildrenSymbol].get(index)); + return ShellNode.create(this[nodeChildrenSymbol].get(index)); } /** @@ -125,7 +125,7 @@ export class NodeChildren implements IPublicModelNodeChildren { */ forEach(fn: (node: IPublicModelNode, index: number) => void): void { this[nodeChildrenSymbol].forEach((item: InnerNode, index: number) => { - fn(Node.create(item)!, index); + fn(ShellNode.create(item)!, index); }); } @@ -135,7 +135,7 @@ export class NodeChildren implements IPublicModelNodeChildren { */ map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null { return this[nodeChildrenSymbol].map((item: InnerNode, index: number) => { - return fn(Node.create(item)!, index); + return fn(ShellNode.create(item)!, index); }); } @@ -145,7 +145,7 @@ export class NodeChildren implements IPublicModelNodeChildren { */ every(fn: (node: IPublicModelNode, index: number) => boolean): boolean { return this[nodeChildrenSymbol].every((item: InnerNode, index: number) => { - return fn(Node.create(item)!, index); + return fn(ShellNode.create(item)!, index); }); } @@ -155,7 +155,7 @@ export class NodeChildren implements IPublicModelNodeChildren { */ some(fn: (node: IPublicModelNode, index: number) => boolean): boolean { return this[nodeChildrenSymbol].some((item: InnerNode, index: number) => { - return fn(Node.create(item)!, index); + return fn(ShellNode.create(item)!, index); }); } @@ -166,9 +166,9 @@ export class NodeChildren implements IPublicModelNodeChildren { filter(fn: (node: IPublicModelNode, index: number) => boolean): any { return this[nodeChildrenSymbol] .filter((item: InnerNode, index: number) => { - return fn(Node.create(item)!, index); + return fn(ShellNode.create(item)!, index); }) - .map((item: InnerNode) => Node.create(item)!); + .map((item: InnerNode) => ShellNode.create(item)!); } /** @@ -176,9 +176,9 @@ export class NodeChildren implements IPublicModelNodeChildren { * @param fn */ find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null { - return Node.create( + return ShellNode.create( this[nodeChildrenSymbol].find((item: InnerNode, index: number) => { - return fn(Node.create(item)!, index); + return fn(ShellNode.create(item)!, index); }), ); } @@ -189,7 +189,7 @@ export class NodeChildren implements IPublicModelNodeChildren { */ reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void { return this[nodeChildrenSymbol].reduce((acc: any, cur: InnerNode) => { - return fn(acc, Node.create(cur)!); + return fn(acc, ShellNode.create(cur)!); }, initialValue); } @@ -226,10 +226,11 @@ export class NodeChildren implements IPublicModelNodeChildren { sorter = () => 0; } this[nodeChildrenSymbol].mergeChildren( - (node: InnerNode, idx: number) => remover(Node.create(node)!, idx), - (children: InnerNode[]) => adder(children.map((node) => Node.create(node)!)), - (firstNode: InnerNode, secondNode: InnerNode) => - sorter(Node.create(firstNode)!, Node.create(secondNode)!), + (node: InnerNode, idx: number) => remover(ShellNode.create(node)!, idx), + (children: InnerNode[]) => adder(children.map((node) => ShellNode.create(node)!)), + (firstNode: InnerNode, secondNode: InnerNode) => { + return sorter(ShellNode.create(firstNode)!, ShellNode.create(secondNode)!); + }, ); } } diff --git a/packages/shell/src/model/node.ts b/packages/shell/src/model/node.ts index d9f86c8a8..40bad153d 100644 --- a/packages/shell/src/model/node.ts +++ b/packages/shell/src/model/node.ts @@ -283,7 +283,7 @@ export class Node implements IPublicModelNode { * 节点上挂载的插槽节点们 */ get slots(): IPublicModelNode[] { - return this[nodeSymbol].slots.map((node: IPublicModelNode) => Node.create(node)!); + return this[nodeSymbol].slots.map((node: InnerNode) => Node.create(node)!); } /** @@ -318,7 +318,7 @@ export class Node implements IPublicModelNode { return ShellSettingTopEntry.create(this[nodeSymbol].settingEntry as any); } - constructor(node: IPublicModelNode) { + constructor(node: InnerNode) { this[nodeSymbol] = node; this[documentSymbol] = node.document; @@ -351,7 +351,7 @@ export class Node implements IPublicModelNode { * @deprecated */ getDOMNode() { - return this[nodeSymbol].getDOMNode(); + return (this[nodeSymbol] as any).getDOMNode(); } /** @@ -512,7 +512,10 @@ export class Node implements IPublicModelNode { * @param options * @returns */ - exportSchema(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render, options?: any): IPublicTypeNodeSchema { + exportSchema( + stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Render, + options?: any, + ): IPublicTypeNodeSchema { return this[nodeSymbol].export(stage, options); } diff --git a/packages/types/src/shell/api/hotkey.ts b/packages/types/src/shell/api/hotkey.ts index c8da780af..894eb0e2f 100644 --- a/packages/types/src/shell/api/hotkey.ts +++ b/packages/types/src/shell/api/hotkey.ts @@ -1,7 +1,14 @@ -import { IPublicTypeDisposable, IPublicTypeHotkeyCallback } from '../type'; +import { IPublicTypeDisposable, IPublicTypeHotkeyCallback, IPublicTypeHotkeyCallbacks } from '../type'; export interface IPublicApiHotkey { - get callbacks(): any; + + /** + * 获取当前快捷键配置 + * + * @experimental + * @since v1.1.0 + */ + get callbacks(): IPublicTypeHotkeyCallbacks; /** * 绑定快捷键 @@ -9,7 +16,6 @@ export interface IPublicApiHotkey { * @param combos 快捷键,格式如:['command + s'] 、['ctrl + shift + s'] 等 * @param callback 回调函数 * @param action - * @returns */ bind( combos: string[] | string, diff --git a/packages/types/src/shell/api/project.ts b/packages/types/src/shell/api/project.ts index 823159e7b..edafabb48 100644 --- a/packages/types/src/shell/api/project.ts +++ b/packages/types/src/shell/api/project.ts @@ -3,8 +3,8 @@ import { IPublicEnumTransformStage } from '../enum'; import { IPublicApiSimulatorHost } from './'; import { IPublicModelDocumentModel } from '../model'; - export interface IPublicApiProject { + /** * 获取当前的 document * get current document @@ -40,7 +40,6 @@ export interface IPublicApiProject { */ createDocument(data?: IPublicTypeRootSchema): IPublicModelDocumentModel | null; - /** * 删除一个 document * remove a document diff --git a/packages/types/src/shell/model/component-meta.ts b/packages/types/src/shell/model/component-meta.ts index 238d916cf..160c7107d 100644 --- a/packages/types/src/shell/model/component-meta.ts +++ b/packages/types/src/shell/model/component-meta.ts @@ -3,6 +3,7 @@ import { ReactElement } from 'react'; import { IPublicModelNode } from './node'; export interface IPublicModelComponentMeta { + /** * 组件名 */ @@ -79,6 +80,5 @@ export interface IPublicModelComponentMeta { target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[], ): boolean; - refreshMetadata(): void; } diff --git a/packages/types/src/shell/model/detecting.ts b/packages/types/src/shell/model/detecting.ts index d828ace32..9bc215f9a 100644 --- a/packages/types/src/shell/model/detecting.ts +++ b/packages/types/src/shell/model/detecting.ts @@ -42,5 +42,5 @@ export interface IPublicModelDetecting { * set callback which will be called when hovering object changed. * @since v1.1.0 */ - onDetectingChange(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; + onDetectingChange(fn: (node: IPublicModelNode | null) => void): IPublicTypeDisposable; } diff --git a/packages/types/src/shell/model/editor.ts b/packages/types/src/shell/model/editor.ts index 4f7211387..11d75aac7 100644 --- a/packages/types/src/shell/model/editor.ts +++ b/packages/types/src/shell/model/editor.ts @@ -3,7 +3,7 @@ import { EventEmitter } from 'events'; import StrictEventEmitter from 'strict-event-emitter-types'; import * as GlobalEvent from '../../event'; import { IPublicApiEvent } from '../api'; -import { IPublicTypeEditorValueKey, IPublicTypeEditorGetOptions, IPublicTypeEditorGetResult, IPublicTypeEditorRegisterOptions } from '../type'; +import { IPublicTypeEditorValueKey, IPublicTypeEditorGetOptions, IPublicTypeEditorGetResult, IPublicTypeEditorRegisterOptions, IPublicTypeAssetsJson } from '../type'; export interface IPublicModelEditor extends StrictEventEmitter { get: ( @@ -25,4 +25,6 @@ export interface IPublicModelEditor extends StrictEventEmitter void; get eventBus(): IPublicApiEvent; + + setAssets(assets: IPublicTypeAssetsJson): void; } diff --git a/packages/types/src/shell/model/modal-nodes-manager.ts b/packages/types/src/shell/model/modal-nodes-manager.ts index d24a3d037..bfbba50ec 100644 --- a/packages/types/src/shell/model/modal-nodes-manager.ts +++ b/packages/types/src/shell/model/modal-nodes-manager.ts @@ -1,36 +1,41 @@ import { IPublicModelNode } from './'; export interface IPublicModelModalNodesManager { + /** * 设置模态节点,触发内部事件 + * set modal nodes, trigger internal events */ setNodes(): void; /** * 获取模态节点(们) - * @returns + * get modal nodes */ - getModalNodes(): any; + getModalNodes(): IPublicModelNode[]; /** * 获取当前可见的模态节点 - * @returns + * get current visible modal node */ - getVisibleModalNode(): any; + getVisibleModalNode(): IPublicModelNode | null; /** * 隐藏模态节点(们) + * hide modal nodes */ hideModalNodes(): void; /** * 设置指定节点为可见态 + * set specfic model node as visible * @param node Node */ setVisible(node: IPublicModelNode): void; /** * 设置指定节点为不可见态 + * set specfic model node as invisible * @param node Node */ setInvisible(node: IPublicModelNode): void; diff --git a/packages/types/src/shell/model/resource.ts b/packages/types/src/shell/model/resource.ts index cfa48f189..5f26c8d7b 100644 --- a/packages/types/src/shell/model/resource.ts +++ b/packages/types/src/shell/model/resource.ts @@ -1,5 +1,4 @@ import { ReactElement } from 'react'; -import { IPublicModelResourceType } from './resource-type'; export interface IPublicModelResource { get title(): string | undefined; diff --git a/packages/types/src/shell/type/hotkey-callback-config.ts b/packages/types/src/shell/type/hotkey-callback-config.ts new file mode 100644 index 000000000..1903d6a84 --- /dev/null +++ b/packages/types/src/shell/type/hotkey-callback-config.ts @@ -0,0 +1,10 @@ +import { IPublicTypeHotkeyCallback } from './'; + +export interface IPublicTypeHotkeyCallbackConfig { + callback: IPublicTypeHotkeyCallback; + modifiers: string[]; + action: string; + seq?: string; + level?: number; + combo?: string; +} \ No newline at end of file diff --git a/packages/types/src/shell/type/hotkey-callbacks.ts b/packages/types/src/shell/type/hotkey-callbacks.ts new file mode 100644 index 000000000..3fd80a480 --- /dev/null +++ b/packages/types/src/shell/type/hotkey-callbacks.ts @@ -0,0 +1,5 @@ +import { IPublicTypeHotkeyCallbackConfig } from './'; + +export interface IPublicTypeHotkeyCallbacks { + [key: string]: IPublicTypeHotkeyCallbackConfig[]; +} \ 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 f66094f3d..a066e1f57 100644 --- a/packages/types/src/shell/type/index.ts +++ b/packages/types/src/shell/type/index.ts @@ -86,4 +86,6 @@ export * from './editor-register-options'; export * from './editor-view'; export * from './resource-type'; export * from './resource-type-config'; -export * from './editor-view-config'; \ No newline at end of file +export * from './editor-view-config'; +export * from './hotkey-callback-config'; +export * from './hotkey-callbacks'; \ No newline at end of file diff --git a/packages/workspace/src/resource.ts b/packages/workspace/src/resource.ts index 9753339f0..2495909b4 100644 --- a/packages/workspace/src/resource.ts +++ b/packages/workspace/src/resource.ts @@ -7,12 +7,16 @@ import { Workspace as InnerWorkSpace } from './workspace'; const logger = new Logger({ level: 'warn', bizName: 'workspace:resource' }); export class Resource implements IPublicModelResource { + private context: BasicContext; + resourceTypeInstance: IPublicResourceTypeConfig; editorViewMap: Map = new Map(); constructor(readonly resourceData: IPublicResourceData, readonly resourceType: ResourceType, workspace: InnerWorkSpace) { - this.resourceTypeInstance = resourceType.resourceTypeModel(new BasicContext(workspace, ''), {}); + this.context = new BasicContext(workspace, ''); + this.resourceTypeInstance = resourceType.resourceTypeModel(this.context, {}); + this.init(); if (this.resourceTypeInstance.editorViews) { this.resourceTypeInstance.editorViews.forEach((d: any) => { this.editorViewMap.set(d.viewName, d); @@ -51,6 +55,11 @@ export class Resource implements IPublicModelResource { return this.resourceData?.category; } + async init() { + await this.resourceTypeInstance.init?.(); + await this.context.innerPlugins.init(); + } + async import(schema: any) { return await this.resourceTypeInstance.import?.(schema); }