mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-12 19:52:51 +00:00
Merge branch 'release/1.7.0'
This commit is contained in:
commit
0e90ea81bb
33
.github/workflows/check base branch.yml
vendored
Normal file
33
.github/workflows/check base branch.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: Check Base Branch
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
code-review:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# 判断用户是否有写仓库权限
|
||||
- name: 'Check User Permission'
|
||||
uses: 'lannonbr/repo-permission-check-action@2.0.0'
|
||||
with:
|
||||
permission: 'write'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: 'Check base branch name is develop or not'
|
||||
if: github.event.pull_request.base.ref != 'develop' # check the target branch if it's master
|
||||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: 'create-comment'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
感谢你的 PR,根据引擎的 [研发协作流程](https://lowcode-engine.cn/site/docs/participate/flow),请将目标合入分支设置为 **develop**。
|
||||
|
||||
Thanks in advance, according to the [Contribution Guideline](https://lowcode-engine.cn/site/docs/participate/flow), please set the base branch to **develop**.
|
||||
|
||||
@${{ github.event.pull_request.user.login }}
|
||||
4
.github/workflows/cov packages.yml
vendored
4
.github/workflows/cov packages.yml
vendored
@ -73,7 +73,7 @@ jobs:
|
||||
package-manager: yarn
|
||||
annotations: none
|
||||
|
||||
cov-utils:
|
||||
cov-utils:
|
||||
runs-on: ubuntu-latest
|
||||
# skip fork's PR, otherwise it fails while making a comment
|
||||
if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }}
|
||||
@ -91,6 +91,6 @@ cov-utils:
|
||||
- uses: ArtiomTr/jest-coverage-report-action@v2
|
||||
with:
|
||||
working-directory: packages/utils
|
||||
test-script: npm test
|
||||
test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json
|
||||
package-manager: yarn
|
||||
annotations: none
|
||||
2
.github/workflows/help wanted.yml
vendored
2
.github/workflows/help wanted.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Issue Reply
|
||||
name: Help Wanted
|
||||
|
||||
on:
|
||||
issues:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
name: Issue Reply
|
||||
name: Insufficient Info
|
||||
|
||||
on:
|
||||
issues:
|
||||
|
||||
2
.github/workflows/test modules.yml
vendored
2
.github/workflows/test modules.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: lint & test
|
||||
name: Lint & Test (Mods)
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
52
.github/workflows/test packages.yml
vendored
52
.github/workflows/test packages.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: lint & test
|
||||
name: Lint & Test (Pkgs)
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -43,7 +43,7 @@ jobs:
|
||||
- name: test
|
||||
run: cd packages/designer && npm test
|
||||
|
||||
editor-skeleton:
|
||||
test-editor-skeleton:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
@ -58,3 +58,51 @@ jobs:
|
||||
|
||||
- name: test
|
||||
run: cd packages/editor-skeleton && npm test
|
||||
|
||||
test-renderer-core:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
|
||||
- name: install
|
||||
run: npm i && npm run setup:skip-build
|
||||
|
||||
- name: test
|
||||
run: cd packages/renderer-core && npm test
|
||||
|
||||
test-react-simulator-renderer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
|
||||
- name: install
|
||||
run: npm i && npm run setup:skip-build
|
||||
|
||||
- name: test
|
||||
run: cd packages/react-simulator-renderer && npm test
|
||||
|
||||
test-utils:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
|
||||
- name: install
|
||||
run: npm i && npm run setup:skip-build
|
||||
|
||||
- name: test
|
||||
run: cd packages/utils && npm test
|
||||
@ -95,6 +95,17 @@ common.utils.startTransaction(() => {
|
||||
}, IPublicEnumTransitionType.repaint);
|
||||
```
|
||||
|
||||
#### getConvertedExtraKey
|
||||
|
||||
props key 转化工具
|
||||
|
||||
```typescript
|
||||
getConvertedExtraKey(key: string): string
|
||||
|
||||
```
|
||||
|
||||
**@since v1.0.17**
|
||||
|
||||
#### createIntl
|
||||
i18n 相关工具
|
||||
```typescript
|
||||
|
||||
@ -105,6 +105,17 @@ getPreference(): IPublicModelPreference;
|
||||
|
||||
**@since v1.1.0**
|
||||
|
||||
示例
|
||||
|
||||
```javascript
|
||||
import { config } from '@alilc/lowcode-engine';
|
||||
|
||||
const panelName = 'outline-master-pane';
|
||||
|
||||
// 设置大纲树面板钉住,在大纲树下次重新打开时生效
|
||||
config.getPreference().set(`${panelName}-pinned-status-isFloat`, false, 'skeleton')
|
||||
```
|
||||
|
||||
## 事件
|
||||
|
||||
### onceGot
|
||||
|
||||
@ -245,6 +245,7 @@ material.getComponentMeta('Input');
|
||||
```
|
||||
|
||||
#### getComponentMetasMap
|
||||
|
||||
获取所有已注册的物料元数据
|
||||
|
||||
```typescript
|
||||
@ -264,6 +265,15 @@ import { material } from '@alilc/lowcode-engine';
|
||||
material.getComponentMetasMap();
|
||||
```
|
||||
|
||||
#### refreshComponentMetasMap
|
||||
|
||||
刷新 componentMetasMap,可触发模拟器里的 components 重新构建
|
||||
|
||||
**@since v1.1.7**
|
||||
|
||||
```typescript
|
||||
refreshComponentMetasMap(): void;
|
||||
```
|
||||
|
||||
### 物料元数据管道函数
|
||||
#### registerMetadataTransducer
|
||||
|
||||
21
docs/docs/api/model/editor-view.md
Normal file
21
docs/docs/api/model/editor-view.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: EditorView
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
> **[@experimental](./#experimental)**<br/>
|
||||
> **@types** [IPublicModelEditorView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/editor-view.ts)<br/>
|
||||
> **@since** v1.1.7
|
||||
|
||||
窗口编辑视图
|
||||
|
||||
## 类型定义
|
||||
|
||||
```
|
||||
import { IPublicModelPluginContext } from "./plugin-context";
|
||||
|
||||
export interface IPublicModelEditorView extends IPublicModelPluginContext {};
|
||||
|
||||
```
|
||||
|
||||
相关类型定义: [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts)
|
||||
@ -62,11 +62,11 @@ delete(node: IPublicModelNode): boolean;
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 删除指定节点
|
||||
* delete the node
|
||||
* 插入一个节点
|
||||
* insert the node
|
||||
* @param node
|
||||
*/
|
||||
delete(node: IPublicModelNode): boolean;
|
||||
insert(node: IPublicModelNode): boolean;
|
||||
```
|
||||
|
||||
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
|
||||
|
||||
@ -38,6 +38,25 @@ sidebar_position: 12
|
||||
|
||||
关联模型 [IPublicModelResource](./resource)
|
||||
|
||||
### currentEditorView
|
||||
窗口当前视图
|
||||
|
||||
`@type {IPublicModelEditorView}`
|
||||
|
||||
关联模型 [IPublicModelEditorView](./editor-view)
|
||||
|
||||
**@since v1.1.7**
|
||||
|
||||
### editorViews
|
||||
|
||||
窗口所有视图
|
||||
|
||||
`@type {IPublicModelEditorView[]}`
|
||||
|
||||
关联模型 [IPublicModelEditorView](./editor-view)
|
||||
|
||||
**@since v1.1.7**
|
||||
|
||||
## 方法
|
||||
|
||||
### importSchema
|
||||
@ -74,3 +93,15 @@ onChangeViewType(fn: (viewName: string) => void): IPublicTypeDisposable;
|
||||
```
|
||||
|
||||
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
|
||||
|
||||
### onSave
|
||||
|
||||
窗口视图保存事件
|
||||
|
||||
```
|
||||
onSave(fn: () => void): IPublicTypeDisposable;
|
||||
```
|
||||
|
||||
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
|
||||
|
||||
**@since v1.1.7**
|
||||
|
||||
@ -145,7 +145,7 @@ export default class AltStringSetter extends React.PureComponent<AltStringSetter
|
||||
```typescript
|
||||
import AltStringSetter from './AltStringSetter';
|
||||
import { setters } from '@alilc/lowcode-engine';
|
||||
const { registerSetter } = registerSetter;
|
||||
const { registerSetter } = setters;
|
||||
registerSetter('AltStringSetter', AltStringSetter);
|
||||
```
|
||||
注册之后,我们就可以在物料中使用了,其中核心配置如下:
|
||||
|
||||
@ -45,16 +45,13 @@ window.Next.Message.success('成功')
|
||||
|
||||
- 读取:每次打开面板时,都会尝试读取 schema 中的 originCode 字段,如果没有,则从 schema 上的字段还原代码;
|
||||
- 写入:在关闭代码编辑面板(主动点击叉或者点击非代码编辑区块的被动关闭都算)时,将自动写入到 schema 中;您也可以在编辑过程中点击“保存”按钮手动保存;
|
||||
| 源码面板中 | schema 中 |
|
||||
|
||||
| 源码面板中 | Schema 中 |
|
||||
| --- | --- |
|
||||
| 本地数据初始值设置:
|
||||
 |  |
|
||||
| 生命周期方法:
|
||||
 |  |
|
||||
| 自定义函数:
|
||||
 |  |
|
||||
| 编译前全量代码:
|
||||
 |  |
|
||||
| 本地数据初始值设置: |  |
|
||||
| 生命周期方法: |  |
|
||||
| 自定义函数: |  |
|
||||
| 编译前全量代码: |  |
|
||||
|
||||
|
||||
- 异常处理:如果代码解析失败,它将无法被正常保存到 schema 中,此时编辑器会弹层提示:
|
||||
|
||||
@ -336,7 +336,7 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参
|
||||
1. **画布内拖拽:**此时 sensor 是 simulatorHost,拖拽完成之后,会根据拖拽的位置来完成节点的精确插入。
|
||||
2. **从组件面板拖拽到画布**:此时的 sensor 还是 simulatorHost,因为拖拽结束的目标还是画布。
|
||||
3. **大纲树面板拖拽到画布中**:此时有两个 sensor,一个是大纲树,当我们拖拽到画布区域时,画布区域内的 simulatorHost 开始接管。
|
||||
4. **画布拖拽到画布中**:从画布中开始拖拽时,最新生效的是 simulatorHost,当离开画布到大纲树时,大纲树 sensor 开始接管生效。当拖拽到大纲树的某一个节点下时,大纲树会将大纲树中的信息转化为 schema,然后渲染到画布中。
|
||||
4. **画布拖拽到大纲树中**:从画布中开始拖拽时,最新生效的是 simulatorHost,当离开画布到大纲树时,大纲树 sensor 开始接管生效。当拖拽到大纲树的某一个节点下时,大纲树会将大纲树中的信息转化为 schema,然后渲染到画布中。
|
||||
### 其他
|
||||
|
||||
引擎的编排能力远远不止上述所描述的功能,这里只描述了其核心和关键的功能。在整个引擎的迭代和设计过程中还有很多细节来使我们的引擎更好用、更容易扩展。
|
||||
|
||||
155
docs/docs/guide/expand/editor/graph.md
Normal file
155
docs/docs/guide/expand/editor/graph.md
Normal file
@ -0,0 +1,155 @@
|
||||
---
|
||||
title: 图编排扩展
|
||||
sidebar_position: 9
|
||||
---
|
||||
## 项目运行
|
||||
### 前置准备
|
||||
1. 参考 https://lowcode-engine.cn/site/docs/guide/quickStart/start
|
||||
2. 参考至Demo下载 https://lowcode-engine.cn/site/docs/guide/quickStart/start#%E4%B8%8B%E8%BD%BD-demo
|
||||
### 选择demo-graph-x6
|
||||
在根目录下执行:
|
||||
```bash
|
||||
cd demo-graph-x6
|
||||
```
|
||||
### 安装依赖
|
||||
在 lowcode-demo/demo-graph-x6目录下执行:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
### 启动Demo
|
||||
在 lowcode-demo/demo-graph-x6 目录下执行:
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
之后就可以通过 http://localhost:5556/ 来访问我们的 DEMO 了。
|
||||
|
||||
## 认识Demo
|
||||
这里的Demo即通过图编排引擎加入了几个简单的物料而来,已经是可以面向真是用户的产品界面。
|
||||

|
||||
### 区域组成
|
||||
#### 顶部:操作区
|
||||
- 右侧:保存到本地、重置页面、自定义按钮
|
||||
#### 顶部:工具区
|
||||
- 左侧:删除、撤销、重做、放大、缩小
|
||||
#### 左侧:面板与操作区
|
||||
- 物料面板:可以查找节点,并在此拖动节点到编辑器画布中
|
||||
#### 中部:可视化页面编辑画布区域
|
||||
- 点击节点/边在右侧面板中能够显示出对应组件的属性配置选项
|
||||
- 拖拽修改节点的排列顺序
|
||||
#### 右侧:组件级别配置
|
||||
- 选中的组件:从页面开始一直到当前选中的节点/边位置,点击对应的名称可以切换到对应的节点上
|
||||
- 选中组件的配置:属性:节点的基础属性值设置
|
||||
|
||||
> 每个区域的组成都可以被替换和自定义来生成开发者需要的业务产品。
|
||||
|
||||
## 目录介绍
|
||||

|
||||
|
||||
- public:与其他demo保持一致,均是lowcode engine所必要依赖
|
||||
- src
|
||||
- plugins::自定义插件,完成了x6的切面回调处理功能
|
||||
- services:mock数据,真实场景中可能为异步获取数据
|
||||
|
||||
## 开发插件
|
||||
```typescript
|
||||
function pluginX6DesignerExtension(ctx: IPublicModelPluginContext) {
|
||||
return {
|
||||
init() {
|
||||
// 获取 x6 designer 内置插件的导出 api
|
||||
const x6Designer = ctx.plugins['plugin-x6-designer'] as IDesigner;
|
||||
|
||||
x6Designer.onNodeRender((model, node) => {
|
||||
// @ts-ignore
|
||||
// 自定义 node 渲染逻辑
|
||||
const { name, title } = model.propsData;
|
||||
node.attr('text/textWrap/text', title || name);
|
||||
});
|
||||
|
||||
x6Designer.onEdgeRender((model, edge) => {
|
||||
// @ts-ignore
|
||||
const { source, target, sourcePortId, targetPortId } = model.propsData;
|
||||
console.log(sourcePortId, targetPortId);
|
||||
requestAnimationFrame(() => {
|
||||
edge.setSource({ cell: source, port: sourcePortId });
|
||||
edge.setTarget({ cell: target, port: targetPortId });
|
||||
});
|
||||
|
||||
// https://x6.antv.vision/zh/docs/tutorial/intermediate/edge-labels x6 标签模块
|
||||
// appendLabel 会触发 onEdgeLabelRender
|
||||
edge.appendLabel({
|
||||
markup: Markup.getForeignObjectMarkup(),
|
||||
attrs: {
|
||||
fo: {
|
||||
width: 120,
|
||||
height: 30,
|
||||
x: -60,
|
||||
y: -15,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
x6Designer.onEdgeLabelRender((args) => {
|
||||
const { selectors } = args
|
||||
const content = selectors.foContent as HTMLDivElement
|
||||
if (content) {
|
||||
ReactDOM.render(<div>自定义 react 标签</div>, content)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginX6DesignerExtension.pluginName = 'plugin-x6-designer-extension';
|
||||
|
||||
export default pluginX6DesignerExtension;
|
||||
```
|
||||
x6Designer为图实例暴露出来的一些接口,可基于此进行一些图的必要插件的封装,整个插件的封装完全follow低代码引擎的插件,详情可参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/pluginWidget
|
||||
|
||||
## 开发物料
|
||||
```bash
|
||||
npm init @alilc/element your-material-demo
|
||||
```
|
||||

|
||||
|
||||
仓库初始化完成
|
||||

|
||||
|
||||
接下来即可编写物料内容了
|
||||
图物料与低代码的dom场景存在画布的差异,因此暂不支持物料单独调试,须通过项目demo进行物料调试
|
||||
|
||||
### 资产描述
|
||||
```bash
|
||||
npm run lowcode:build
|
||||
```
|
||||
如果物料是个React组件,则在执行上述命令时会自动生成对应的meta.ts,<b>但图物料很多时候并非一个React组件,因此须手动生产meta.ts</b>
|
||||
|
||||
可参考: https://github.com/alibaba/lowcode-materials/blob/main/packages/graph-x6-materials/lowcode/send-email/meta.ts
|
||||
同时会自动生成物料描述文件
|
||||
|
||||
### 物料调试
|
||||
#### 物料侧
|
||||
物料想要支持被项目动态inject调试,须在build.lowcode.js中加入
|
||||
```javascript
|
||||
[
|
||||
'@alilc/build-plugin-alt',
|
||||
{
|
||||
type: 'component',
|
||||
inject: true,
|
||||
library
|
||||
},
|
||||
]
|
||||
```
|
||||

|
||||
|
||||
本地启动
|
||||
```bash
|
||||
npm run lowcode:dev
|
||||
```
|
||||
#### 项目侧
|
||||
通过@alilc/lce-graph-core加载物料的天然支持了debug,因此无须特殊处理。
|
||||
若项目中自行加载,则参考 https://lowcode-engine.cn/site/docs/guide/expand/editor/cli
|
||||
项目访问地址后拼接query "?debug"即可进入物料调试
|
||||

|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-engine-docs",
|
||||
"version": "1.0.25",
|
||||
"version": "1.0.30",
|
||||
"description": "低代码引擎版本化文档",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"lerna": "4.0.0",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"packages": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-code-generator",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.2",
|
||||
"description": "出码引擎 for LowCode Engine",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
|
||||
@ -9,7 +9,7 @@ import { createModuleBuilder } from './generator/ModuleBuilder';
|
||||
import { createDiskPublisher } from './publisher/disk';
|
||||
import { createZipPublisher } from './publisher/zip';
|
||||
import createIceJsProjectBuilder, { plugins as icejsPlugins } from './solutions/icejs';
|
||||
import createIce3JsProjectBuilder, { plugins as icejs3Plugins } from './solutions/icejs3';
|
||||
import createIceJs3ProjectBuilder, { plugins as icejs3Plugins } from './solutions/icejs3';
|
||||
import createRaxAppProjectBuilder, { plugins as raxPlugins } from './solutions/rax-app';
|
||||
|
||||
// 引入说明
|
||||
@ -42,7 +42,7 @@ export default {
|
||||
createModuleBuilder,
|
||||
solutions: {
|
||||
icejs: createIceJsProjectBuilder,
|
||||
icejs3: createIce3JsProjectBuilder,
|
||||
icejs3: createIceJs3ProjectBuilder,
|
||||
rax: createRaxAppProjectBuilder,
|
||||
},
|
||||
solutionParts: {
|
||||
|
||||
@ -32,7 +32,7 @@ import {
|
||||
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
||||
|
||||
import { getErrorMessage } from '../utils/errors';
|
||||
import { handleSubNodes, isValidContainerType } from '../utils/schema';
|
||||
import { handleSubNodes, isValidContainerType, ContainerType } from '../utils/schema';
|
||||
import { uniqueArray } from '../utils/common';
|
||||
import { componentAnalyzer } from '../analyzer/componentAnalyzer';
|
||||
import { ensureValidClassName } from '../utils/validate';
|
||||
@ -106,6 +106,11 @@ function processChildren(schema: IPublicTypeNodeSchema): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getInternalDep(internalDeps: Record<string, IInternalDependency>, depName: string) {
|
||||
const dep = internalDeps[depName];
|
||||
return (dep && dep.type !== InternalDependencyType.PAGE) ? dep : null;
|
||||
}
|
||||
|
||||
export class SchemaParser implements ISchemaParser {
|
||||
validate(schema: IPublicTypeProjectSchema): boolean {
|
||||
if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) {
|
||||
@ -161,7 +166,8 @@ export class SchemaParser implements ISchemaParser {
|
||||
...subRoot,
|
||||
componentName: getRootComponentName(subRoot.componentName, compDeps),
|
||||
containerType: subRoot.componentName,
|
||||
moduleName: ensureValidClassName(changeCase.pascalCase(subRoot.fileName)),
|
||||
moduleName: ensureValidClassName(subRoot.componentName === ContainerType.Component ?
|
||||
subRoot.fileName : changeCase.pascalCase(subRoot.fileName)),
|
||||
};
|
||||
return container;
|
||||
});
|
||||
@ -220,12 +226,11 @@ export class SchemaParser implements ISchemaParser {
|
||||
}
|
||||
});
|
||||
|
||||
// 分析容器内部组件依赖
|
||||
containers.forEach((container) => {
|
||||
const depNames = this.getComponentNames(container);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
container.deps = uniqueArray<string>(depNames, (i: string) => i)
|
||||
.map((depName) => internalDeps[depName] || compDeps[depName])
|
||||
.map((depName) => getInternalDep(internalDeps, depName) || compDeps[depName])
|
||||
.filter(Boolean);
|
||||
// container.deps = Object.keys(compDeps).map((depName) => compDeps[depName]);
|
||||
});
|
||||
|
||||
@ -21,6 +21,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
|
||||
if (ir && ir.deps && ir.deps.length > 0) {
|
||||
let lowcodeMaterialsStyleAdded = false;
|
||||
let fusionUIStyleAdded = false;
|
||||
let nextStyleAddedMap: Record<string, boolean> = {};
|
||||
ir.deps.forEach((dep: any) => {
|
||||
if (dep.package === '@alifd/next' && !nextStyleAddedMap[dep.exportName]) {
|
||||
@ -41,6 +42,15 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
||||
});
|
||||
lowcodeMaterialsStyleAdded = true;
|
||||
} else if (dep.package === '@alifd/fusion-ui' && !fusionUIStyleAdded) {
|
||||
chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
||||
content: 'import \'@alifd/fusion-ui/lib/style\';',
|
||||
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
||||
});
|
||||
fusionUIStyleAdded = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
||||
content: `static displayName = '${changeCase.pascalCase(ir.moduleName)}';`,
|
||||
content: `static displayName = '${ir.moduleName}';`,
|
||||
linkAfter: [
|
||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
||||
],
|
||||
|
||||
@ -58,7 +58,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
||||
generateCompositeType(
|
||||
{
|
||||
type: 'JSFunction',
|
||||
value: input.value || 'null',
|
||||
value: input.value || 'function () {}',
|
||||
},
|
||||
Scope.createRootScope(),
|
||||
),
|
||||
|
||||
@ -20,7 +20,7 @@ const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig
|
||||
|
||||
const codePrettier: PostProcessor = (content: string, fileType: string) => {
|
||||
let parser: prettier.BuiltInParserName | any;
|
||||
if (fileType === 'js' || fileType === 'jsx') {
|
||||
if (fileType === 'js' || fileType === 'jsx' || fileType === 'ts' || fileType === 'tsx') {
|
||||
parser = 'babel';
|
||||
} else if (fileType === 'json') {
|
||||
parser = 'json-stringify';
|
||||
|
||||
@ -8,7 +8,8 @@ import './polyfills/buffer';
|
||||
import { createProjectBuilder } from './generator/ProjectBuilder';
|
||||
import { createModuleBuilder } from './generator/ModuleBuilder';
|
||||
import { createZipPublisher } from './publisher/zip';
|
||||
import createIceJsProjectBuilder, { plugins as reactPlugins } from './solutions/icejs';
|
||||
import createIceJsProjectBuilder, { plugins as icejsPlugins } from './solutions/icejs';
|
||||
import createIceJs3ProjectBuilder, { plugins as icejs3Plugins } from './solutions/icejs3';
|
||||
import createRaxAppProjectBuilder, { plugins as raxPlugins } from './solutions/rax-app';
|
||||
|
||||
// 引入说明
|
||||
@ -18,6 +19,7 @@ import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '
|
||||
// 引入通用插件组
|
||||
import esmodule from './plugins/common/esmodule';
|
||||
import requireUtils from './plugins/common/requireUtils';
|
||||
import styleImport from './plugins/common/styleImport';
|
||||
|
||||
import css from './plugins/component/style/css';
|
||||
import constants from './plugins/project/constants';
|
||||
@ -32,6 +34,7 @@ import * as CONSTANTS from './const';
|
||||
|
||||
// 引入内置解决方案模块
|
||||
import icejs from './plugins/project/framework/icejs';
|
||||
import icejs3 from './plugins/project/framework/icejs3';
|
||||
import rax from './plugins/project/framework/rax';
|
||||
|
||||
export default {
|
||||
@ -39,10 +42,12 @@ export default {
|
||||
createModuleBuilder,
|
||||
solutions: {
|
||||
icejs: createIceJsProjectBuilder,
|
||||
icejs3: createIceJs3ProjectBuilder,
|
||||
rax: createRaxAppProjectBuilder,
|
||||
},
|
||||
solutionParts: {
|
||||
icejs,
|
||||
icejs3,
|
||||
rax,
|
||||
},
|
||||
publishers: {
|
||||
@ -50,6 +55,7 @@ export default {
|
||||
},
|
||||
plugins: {
|
||||
common: {
|
||||
|
||||
/**
|
||||
* 处理 ES Module
|
||||
* @deprecated please use esModule
|
||||
@ -57,12 +63,7 @@ export default {
|
||||
esmodule,
|
||||
esModule: esmodule,
|
||||
requireUtils,
|
||||
},
|
||||
react: {
|
||||
...reactPlugins,
|
||||
},
|
||||
rax: {
|
||||
...raxPlugins,
|
||||
styleImport,
|
||||
},
|
||||
style: {
|
||||
css,
|
||||
@ -72,6 +73,22 @@ export default {
|
||||
i18n,
|
||||
utils,
|
||||
},
|
||||
icejs: {
|
||||
...icejsPlugins,
|
||||
},
|
||||
icejs3: {
|
||||
...icejs3Plugins,
|
||||
},
|
||||
rax: {
|
||||
...raxPlugins,
|
||||
},
|
||||
|
||||
/**
|
||||
* @deprecated please use icejs
|
||||
*/
|
||||
react: {
|
||||
...icejsPlugins,
|
||||
},
|
||||
},
|
||||
postprocessor: {
|
||||
prettier,
|
||||
|
||||
@ -148,3 +148,9 @@ export function isValidContainerType(schema: IPublicTypeNodeSchema) {
|
||||
'Block',
|
||||
].includes(schema.componentName);
|
||||
}
|
||||
|
||||
export const enum ContainerType {
|
||||
Page = 'Page',
|
||||
Component = 'Component',
|
||||
Block = 'Block',
|
||||
}
|
||||
@ -52,7 +52,7 @@
|
||||
"yarn": "^1.22.17",
|
||||
"rimraf": "^3.0.2",
|
||||
"@types/react-router": "5.1.18",
|
||||
"build-plugin-component": "^1.12.0",
|
||||
"@alilc/build-plugin-lce": "^0.0.3",
|
||||
"babel-jest": "^26.5.2",
|
||||
"@alilc/lowcode-test-mate": "^1.0.1"
|
||||
},
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component"
|
||||
"@alilc/build-plugin-lce"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
||||
],
|
||||
"babelPlugins": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-designer",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "Designer for Ali LowCode Engine",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -9,15 +9,15 @@
|
||||
"es"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "build-scripts build --skip-demo",
|
||||
"build": "build-scripts build",
|
||||
"test": "build-scripts test --config build.test.json",
|
||||
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alilc/lowcode-editor-core": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-editor-core": "1.1.7",
|
||||
"@alilc/lowcode-types": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"classnames": "^2.2.6",
|
||||
"react": "^16",
|
||||
"react-dom": "^16.7.0",
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import DragResizeEngine from './drag-resize-engine';
|
||||
import { observer, computed, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { observer, computed } from '@alilc/lowcode-editor-core';
|
||||
import classNames from 'classnames';
|
||||
import { SimulatorContext } from '../context';
|
||||
import { BuiltinSimulatorHost } from '../host';
|
||||
import { OffsetObserver, Designer } from '../../designer';
|
||||
import { OffsetObserver, Designer, INode } from '../../designer';
|
||||
import { Node } from '../../document';
|
||||
import { normalizeTriggers } from '../../utils/misc';
|
||||
|
||||
@ -135,7 +135,7 @@ export class BoxResizingInstance extends Component<{
|
||||
// this.hoveringCapture.setBoundary(this.outline);
|
||||
this.willBind();
|
||||
|
||||
const resize = (e: MouseEvent, direction: string, node: any, moveX: number, moveY: number) => {
|
||||
const resize = (e: MouseEvent, direction: string, node: INode, moveX: number, moveY: number) => {
|
||||
const { advanced } = node.componentMeta;
|
||||
if (
|
||||
advanced.callbacks &&
|
||||
@ -149,7 +149,7 @@ export class BoxResizingInstance extends Component<{
|
||||
}
|
||||
};
|
||||
|
||||
const resizeStart = (e: MouseEvent, direction: string, node: any) => {
|
||||
const resizeStart = (e: MouseEvent, direction: string, node: INode) => {
|
||||
const { advanced } = node.componentMeta;
|
||||
if (
|
||||
advanced.callbacks &&
|
||||
@ -161,7 +161,7 @@ export class BoxResizingInstance extends Component<{
|
||||
}
|
||||
};
|
||||
|
||||
const resizeEnd = (e: MouseEvent, direction: string, node: any) => {
|
||||
const resizeEnd = (e: MouseEvent, direction: string, node: INode) => {
|
||||
const { advanced } = node.componentMeta;
|
||||
if (
|
||||
advanced.callbacks &&
|
||||
@ -172,8 +172,7 @@ export class BoxResizingInstance extends Component<{
|
||||
advanced.callbacks.onResizeEnd(e, cbNode);
|
||||
}
|
||||
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = node.document?.designer.editor;
|
||||
const npm = node?.componentMeta?.npm;
|
||||
const selected =
|
||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
ComponentType,
|
||||
} from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { observer, computed, Tip, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { observer, computed, Tip } from '@alilc/lowcode-editor-core';
|
||||
import { createIcon, isReactComponent, isActionContentObject } from '@alilc/lowcode-utils';
|
||||
import { IPublicTypeActionContentObject } from '@alilc/lowcode-types';
|
||||
import { BuiltinSimulatorHost } from '../host';
|
||||
@ -131,8 +131,7 @@ function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActio
|
||||
className="lc-borders-action"
|
||||
onClick={() => {
|
||||
action && action(node.internalToShellNode()!);
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = node.document?.designer.editor;
|
||||
const npm = node?.componentMeta?.npm;
|
||||
const selected =
|
||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
|
||||
|
||||
@ -20,7 +20,9 @@ export function createSimulator(
|
||||
): Promise<BuiltinSimulatorRenderer> {
|
||||
const win: any = iframe.contentWindow;
|
||||
const doc = iframe.contentDocument!;
|
||||
const innerPlugins = host.designer.editor.get('innerPlugins');
|
||||
|
||||
win.AliLowCodeEngine = innerPlugins._getLowCodePluginContext({});
|
||||
win.LCSimulatorHost = host;
|
||||
win._ = window._;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import { observer, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { observer } from '@alilc/lowcode-editor-core';
|
||||
import { BuiltinSimulatorHost, BuiltinSimulatorProps } from './host';
|
||||
import { BemTools } from './bem-tools';
|
||||
import { Project } from '../project';
|
||||
@ -76,8 +76,7 @@ class Content extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
private dispose?: () => void;
|
||||
|
||||
componentDidMount() {
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = this.props.host.designer.editor;
|
||||
const onEnableEvents = (type: boolean) => {
|
||||
this.setState({
|
||||
disabledEvents: type,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { obx, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { obx } from '@alilc/lowcode-editor-core';
|
||||
import { IPublicTypePluginConfig, IPublicTypeLiveTextEditingConfig } from '@alilc/lowcode-types';
|
||||
import { Node, Prop } from '../../document';
|
||||
import { INode, Prop } from '../../document';
|
||||
|
||||
const EDITOR_KEY = 'data-setter-prop';
|
||||
|
||||
@ -17,7 +17,7 @@ function defaultSaveContent(content: string, prop: Prop) {
|
||||
}
|
||||
|
||||
export interface EditingTarget {
|
||||
node: Node;
|
||||
node: INode;
|
||||
rootElement: HTMLElement;
|
||||
event: MouseEvent;
|
||||
}
|
||||
@ -47,13 +47,16 @@ export class LiveEditing {
|
||||
|
||||
@obx.ref private _editing: Prop | null = null;
|
||||
|
||||
private _dispose?: () => void;
|
||||
|
||||
private _save?: () => void;
|
||||
|
||||
apply(target: EditingTarget) {
|
||||
const { node, event, rootElement } = target;
|
||||
const targetElement = event.target as HTMLElement;
|
||||
const { liveTextEditing } = node.componentMeta;
|
||||
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = node.document?.designer.editor;
|
||||
const npm = node?.componentMeta?.npm;
|
||||
const selected =
|
||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || node?.componentMeta?.componentName || '';
|
||||
@ -166,10 +169,6 @@ export class LiveEditing {
|
||||
return this._editing;
|
||||
}
|
||||
|
||||
private _dispose?: () => void;
|
||||
|
||||
private _save?: () => void;
|
||||
|
||||
saveAndDispose() {
|
||||
if (this._save) {
|
||||
this._save();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Overlay } from '@alifd/next';
|
||||
import React, { MouseEvent } from 'react';
|
||||
import { Title, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { Title } from '@alilc/lowcode-editor-core';
|
||||
import { canClickNode } from '@alilc/lowcode-utils';
|
||||
import './index.less';
|
||||
|
||||
@ -66,8 +66,7 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
||||
|
||||
if (canClick && typeof node.select === 'function') {
|
||||
node.select();
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = node.document?.designer.editor;
|
||||
const npm = node?.componentMeta?.npm;
|
||||
const selected =
|
||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
|
||||
|
||||
@ -56,8 +56,8 @@ export class ComponentActions {
|
||||
const { isRGL, rglNode } = node.getRGL();
|
||||
if (isRGL) {
|
||||
// 复制 layout 信息
|
||||
let layout = rglNode.getPropValue('layout') || [];
|
||||
let curLayout = layout.filter((item) => item.i === node.getPropValue('fieldId'));
|
||||
const layout = rglNode.getPropValue('layout') || [];
|
||||
const curLayout = layout.filter((item) => item.i === node.getPropValue('fieldId'));
|
||||
if (curLayout && curLayout[0]) {
|
||||
layout.push({
|
||||
...curLayout[0],
|
||||
|
||||
@ -60,6 +60,8 @@ export function buildFilter(rule?: string | string[] | RegExp | IPublicTypeNesti
|
||||
export interface IComponentMeta extends IPublicModelComponentMeta<INode> {
|
||||
prototype?: any;
|
||||
|
||||
liveTextEditing?: IPublicTypeLiveTextEditingConfig[];
|
||||
|
||||
get rootSelector(): string | undefined;
|
||||
|
||||
setMetadata(metadata: IPublicTypeComponentMetadata): void;
|
||||
|
||||
@ -7,6 +7,8 @@ import {
|
||||
import { isNode } from '@alilc/lowcode-utils';
|
||||
|
||||
export interface IActiveTracker extends Omit< IPublicModelActiveTracker, 'track' | 'onChange' > {
|
||||
_target: ActiveTarget | INode;
|
||||
|
||||
track(originalTarget: ActiveTarget | INode): void;
|
||||
|
||||
onChange(fn: (target: ActiveTarget) => void): () => void;
|
||||
@ -17,10 +19,10 @@ export interface ActiveTarget extends Omit< IPublicTypeActiveTarget, 'node' > {
|
||||
}
|
||||
|
||||
export class ActiveTracker implements IActiveTracker {
|
||||
private emitter: IEventBus = createModuleEventBus('ActiveTracker');
|
||||
|
||||
@obx.ref private _target?: ActiveTarget | INode;
|
||||
|
||||
private emitter: IEventBus = createModuleEventBus('ActiveTracker');
|
||||
|
||||
track(originalTarget: ActiveTarget | INode) {
|
||||
let target = originalTarget;
|
||||
if (isNode(originalTarget)) {
|
||||
|
||||
@ -141,13 +141,17 @@ export interface IDocumentModel extends Omit<IPublicModelDocumentModel<
|
||||
|
||||
insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean): INode[];
|
||||
|
||||
open(): DocumentModel;
|
||||
open(): IDocumentModel;
|
||||
|
||||
remove(): void;
|
||||
|
||||
suspense(): void;
|
||||
|
||||
close(): void;
|
||||
|
||||
unlinkNode(node: INode): void;
|
||||
|
||||
destroyNode(node: INode): void;
|
||||
}
|
||||
|
||||
export class DocumentModel implements IDocumentModel {
|
||||
@ -333,6 +337,7 @@ export class DocumentModel implements IDocumentModel {
|
||||
this.import(schema as IPublicTypeRootSchema, true);
|
||||
this.simulator?.rerender();
|
||||
},
|
||||
this,
|
||||
);
|
||||
|
||||
this.setupListenActiveNodes();
|
||||
@ -834,13 +839,18 @@ export class DocumentModel implements IDocumentModel {
|
||||
}
|
||||
// 合并外界传入的自定义渲染的组件
|
||||
if (Array.isArray(extraComps)) {
|
||||
extraComps.forEach(c => {
|
||||
if (c && !exsitingMap[c]) {
|
||||
const m = this.getComponentMeta(c);
|
||||
if (m && m.npm?.package) {
|
||||
extraComps.forEach((componentName) => {
|
||||
if (componentName && !exsitingMap[componentName]) {
|
||||
const meta = this.getComponentMeta(componentName);
|
||||
if (meta?.npm?.package) {
|
||||
componentsMap.push({
|
||||
...m?.npm,
|
||||
componentName: c,
|
||||
...meta?.npm,
|
||||
componentName,
|
||||
});
|
||||
} else {
|
||||
componentsMap.push({
|
||||
devMode: 'lowCode',
|
||||
componentName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { reaction, untracked, globalContext, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||
import { reaction, untracked, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||
import { IPublicTypeNodeSchema, IPublicModelHistory, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||
import { Logger } from '@alilc/lowcode-utils';
|
||||
import { IDocumentModel } from '../designer';
|
||||
|
||||
const logger = new Logger({ level: 'warn', bizName: 'history' });
|
||||
|
||||
@ -37,10 +38,12 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
|
||||
return this.session.data;
|
||||
}
|
||||
|
||||
private timeGap: number = 1000;
|
||||
|
||||
constructor(
|
||||
dataFn: () => T | null,
|
||||
private redoer: (data: T) => void,
|
||||
private timeGap: number = 1000,
|
||||
private document?: IDocumentModel,
|
||||
) {
|
||||
this.session = new Session(0, null, this.timeGap);
|
||||
this.records = [this.session];
|
||||
@ -130,8 +133,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
|
||||
}
|
||||
const cursor = this.session.cursor - 1;
|
||||
this.go(cursor);
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = this.document?.designer.editor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
@ -144,8 +146,7 @@ export class History<T = IPublicTypeNodeSchema> implements IHistory {
|
||||
}
|
||||
const cursor = this.session.cursor + 1;
|
||||
this.go(cursor);
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = this.document?.designer.editor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed, globalContext, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||
import { Node, INode } from './node';
|
||||
import { IPublicTypeNodeData, IPublicModelNodeChildren, IPublicEnumTransformStage, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||
import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils';
|
||||
@ -16,12 +16,12 @@ export interface INodeChildren extends Omit<IPublicModelNodeChildren<INode>,
|
||||
'isEmpty' |
|
||||
'notEmpty'
|
||||
> {
|
||||
children: INode[];
|
||||
|
||||
get owner(): INode;
|
||||
|
||||
get length(): number;
|
||||
|
||||
children: INode[];
|
||||
|
||||
unlinkChild(node: INode): void;
|
||||
|
||||
/**
|
||||
@ -239,11 +239,8 @@ export class NodeChildren implements INodeChildren {
|
||||
}
|
||||
const { document } = node;
|
||||
/* istanbul ignore next */
|
||||
if (globalContext.has('editor')) {
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
editor.eventBus.emit('node.remove', { node, index: i });
|
||||
}
|
||||
const editor = node.document?.designer.editor;
|
||||
editor?.eventBus.emit('node.remove', { node, index: i });
|
||||
document?.unlinkNode(node);
|
||||
document?.selection.remove(node.id);
|
||||
document?.destroyNode(node);
|
||||
@ -281,14 +278,11 @@ export class NodeChildren implements INodeChildren {
|
||||
const i = children.map(d => d.id).indexOf(node.id);
|
||||
|
||||
if (node.parent) {
|
||||
if (globalContext.has('editor')) {
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
editor.eventBus.emit('node.remove.topLevel', {
|
||||
node,
|
||||
index: node.index,
|
||||
});
|
||||
}
|
||||
const editor = node.document?.designer.editor;
|
||||
editor?.eventBus.emit('node.remove.topLevel', {
|
||||
node,
|
||||
index: node.index,
|
||||
});
|
||||
}
|
||||
|
||||
if (i < 0) {
|
||||
@ -317,11 +311,8 @@ export class NodeChildren implements INodeChildren {
|
||||
});
|
||||
this.emitter.emit('insert', node);
|
||||
/* istanbul ignore next */
|
||||
if (globalContext.has('editor')) {
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
editor.eventBus.emit('node.add', { node });
|
||||
}
|
||||
const editor = node.document?.designer.editor;
|
||||
editor?.eventBus.emit('node.add', { node });
|
||||
if (useMutator) {
|
||||
this.reportModified(node, this.owner, { type: 'insert' });
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@ export type UNSET = typeof UNSET;
|
||||
export interface IProp extends Omit<IPublicModelProp<
|
||||
INode
|
||||
>, 'exportSchema' | 'node'>, IPropParent {
|
||||
spread: boolean;
|
||||
|
||||
key: string | number | undefined;
|
||||
|
||||
readonly props: IProps;
|
||||
@ -42,6 +44,8 @@ export interface IProp extends Omit<IPublicModelProp<
|
||||
|
||||
setupItems(): IProp[] | null;
|
||||
|
||||
isVirtual(): boolean;
|
||||
|
||||
get type(): ValueTypes;
|
||||
|
||||
get size(): number;
|
||||
@ -336,13 +340,9 @@ export class Prop implements IProp, IPropParent {
|
||||
if (!this._items) {
|
||||
return this._value;
|
||||
}
|
||||
const values = this.items!.map((prop) => {
|
||||
return this.items!.map((prop) => {
|
||||
return prop?.export(stage);
|
||||
});
|
||||
if (values.every((val) => val === undefined)) {
|
||||
return undefined;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@ import {
|
||||
IPublicTypePluginDeclaration,
|
||||
IPublicApiCanvas,
|
||||
IPublicApiWorkspace,
|
||||
IPublicEnumPluginRegisterLevel,
|
||||
IPublicModelWindow,
|
||||
} from '@alilc/lowcode-types';
|
||||
import {
|
||||
IPluginContextOptions,
|
||||
@ -41,6 +43,8 @@ export default class PluginContext implements
|
||||
pluginEvent: IPublicApiEvent;
|
||||
canvas: IPublicApiCanvas;
|
||||
workspace: IPublicApiWorkspace;
|
||||
registerLevel: IPublicEnumPluginRegisterLevel;
|
||||
editorWindow: IPublicModelWindow;
|
||||
|
||||
constructor(
|
||||
options: IPluginContextOptions,
|
||||
|
||||
@ -143,11 +143,10 @@ export class LowCodePluginManager implements ILowCodePluginManager {
|
||||
}
|
||||
|
||||
async delete(pluginName: string): Promise<boolean> {
|
||||
const idx = this.plugins.findIndex((plugin) => plugin.name === pluginName);
|
||||
if (idx === -1) return false;
|
||||
const plugin = this.plugins[idx];
|
||||
const plugin = this.plugins.find(({ name }) => name === pluginName);
|
||||
if (!plugin) return false;
|
||||
await plugin.destroy();
|
||||
|
||||
const idx = this.plugins.indexOf(plugin);
|
||||
this.plugins.splice(idx, 1);
|
||||
return this.pluginsMap.delete(pluginName);
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@ import {
|
||||
IPublicApiWorkspace,
|
||||
IPublicTypePluginMeta,
|
||||
IPublicTypePluginRegisterOptions,
|
||||
IPublicModelWindow,
|
||||
IPublicEnumPluginRegisterLevel,
|
||||
} from '@alilc/lowcode-types';
|
||||
import PluginContext from './plugin-context';
|
||||
|
||||
@ -56,6 +58,8 @@ export interface ILowCodePluginContextPrivate {
|
||||
set pluginEvent(event: IPublicApiEvent);
|
||||
set canvas(canvas: IPublicApiCanvas);
|
||||
set workspace(workspace: IPublicApiWorkspace);
|
||||
set editorWindow(window: IPublicModelWindow);
|
||||
set registerLevel(level: IPublicEnumPluginRegisterLevel);
|
||||
}
|
||||
export interface ILowCodePluginContextApiAssembler {
|
||||
assembleApis(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||
import { IDesigner } from '../designer';
|
||||
import { DocumentModel, isDocumentModel } from '../document';
|
||||
import type { IDocumentModel } from "../document";
|
||||
import type { IDocumentModel } from '../document';
|
||||
import {
|
||||
IPublicTypeComponentsMap,
|
||||
IPublicEnumTransformStage,
|
||||
@ -317,13 +317,13 @@ export class Project implements IProject {
|
||||
doc = this.createDocument();
|
||||
return doc.open();
|
||||
}
|
||||
if (typeof doc === 'string') {
|
||||
const got = this.documents.find((item) => item.fileName === doc || item.id === doc);
|
||||
if (typeof doc === 'string' || typeof doc === 'number') {
|
||||
const got = this.documents.find((item) => item.fileName === String(doc) || String(item.id) === String(doc));
|
||||
if (got) {
|
||||
return got.open();
|
||||
}
|
||||
|
||||
const data = this.data.componentsTree.find((data) => data.fileName === doc);
|
||||
const data = this.data.componentsTree.find((data) => data.fileName === String(doc));
|
||||
if (data) {
|
||||
doc = this.createDocument(data);
|
||||
return doc.open();
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { IPublicTypePluginMeta } from './../../../../lib/packages/types/src/shell/type/plugin-meta.d';
|
||||
import '../fixtures/window';
|
||||
import {
|
||||
Editor,
|
||||
@ -22,6 +23,7 @@ import { BuiltinSimulatorHost } from '../../src/builtin-simulator/host';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory';
|
||||
import { Setters, Workspace } from '@alilc/lowcode-shell';
|
||||
import { ILowCodePluginContextApiAssembler, ILowCodePluginContextPrivate, LowCodePluginManager } from '@alilc/lowcode-designer';
|
||||
|
||||
describe('Host 测试', () => {
|
||||
let editor: Editor;
|
||||
@ -32,10 +34,20 @@ describe('Host 测试', () => {
|
||||
|
||||
beforeAll(() => {
|
||||
editor = new Editor();
|
||||
const innerWorkspace = new InnerWorkspace();
|
||||
const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
assembleApis: (context: ILowCodePluginContextPrivate, pluginName: string, meta: IPublicTypePluginMeta) => {
|
||||
context.project = project;
|
||||
const eventPrefix = meta?.eventPrefix || 'common';
|
||||
context.workspace = workspace;
|
||||
},
|
||||
};
|
||||
const innerPlugins = new LowCodePluginManager(pluginContextApiAssembler);
|
||||
const innerWorkspace = new InnerWorkspace(() => {}, {});
|
||||
const workspace = new Workspace(innerWorkspace);
|
||||
editor.set('innerHotkey', new InnerHotkey())
|
||||
editor.set('setters', new Setters(new InnerSetters()));
|
||||
editor.set('innerPlugins' as any, innerPlugins);
|
||||
!globalContext.has(Editor) && globalContext.register(editor, Editor);
|
||||
!globalContext.has('workspace') && globalContext.register(innerWorkspace, 'workspace');
|
||||
});
|
||||
|
||||
@ -435,7 +435,7 @@ describe('Prop 类测试', () => {
|
||||
|
||||
it('should return undefined when all items are undefined', () => {
|
||||
prop = new Prop(mockPropsInst, [undefined, undefined], '___loopArgs___');
|
||||
expect(prop.getValue()).toBeUndefined();
|
||||
expect(prop.getValue()).toEqual([undefined, undefined]);
|
||||
});
|
||||
|
||||
it('迭代器 / map / forEach', () => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"build-plugin-fusion",
|
||||
"./build.plugin.js"
|
||||
]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-editor-core",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "Core Api for Ali lowCode engine",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
@ -10,12 +10,12 @@
|
||||
"es"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "build-scripts build --skip-demo"
|
||||
"build": "build-scripts build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alifd/next": "^1.19.16",
|
||||
"@alilc/lowcode-types": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"classnames": "^2.2.6",
|
||||
"debug": "^4.1.1",
|
||||
"intl-messageformat": "^9.3.1",
|
||||
|
||||
@ -145,6 +145,16 @@ const VALID_ENGINE_OPTIONS = {
|
||||
type: 'function',
|
||||
description: '配置指定节点为根组件',
|
||||
},
|
||||
enableAutoOpenFirstWindow: {
|
||||
type: 'boolean',
|
||||
description: '应用级设计模式下,自动打开第一个窗口',
|
||||
default: true,
|
||||
},
|
||||
enableWorkspaceMode: {
|
||||
type: 'boolean',
|
||||
description: '是否开启应用级设计模式',
|
||||
default: false,
|
||||
},
|
||||
};
|
||||
|
||||
const getStrictModeValue = (engineOptions: IPublicTypeEngineOptions, defaultValue: boolean): boolean => {
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { IPublicTypeCustomView, IPublicTypeRegisteredSetter } from '@alilc/lowcode-types';
|
||||
import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeRegisteredSetter } from '@alilc/lowcode-types';
|
||||
import { createContent, isCustomView } from '@alilc/lowcode-utils';
|
||||
|
||||
|
||||
const settersMap = new Map<string, IPublicTypeRegisteredSetter & {
|
||||
type: string;
|
||||
}>();
|
||||
@ -44,13 +43,17 @@ function getInitialFromSetter(setter: any) {
|
||||
) || null; // eslint-disable-line
|
||||
}
|
||||
|
||||
export class Setters {
|
||||
constructor(readonly viewName: string = 'global') {}
|
||||
export interface ISetters extends IPublicApiSetters {
|
||||
|
||||
}
|
||||
|
||||
export class Setters implements ISetters {
|
||||
settersMap = new Map<string, IPublicTypeRegisteredSetter & {
|
||||
type: string;
|
||||
}>();
|
||||
|
||||
constructor(readonly viewName: string = 'global') {}
|
||||
|
||||
getSetter = (type: string): IPublicTypeRegisteredSetter | null => {
|
||||
return this.settersMap.get(type) || null;
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"build-plugin-fusion",
|
||||
["build-plugin-moment-locales", {
|
||||
"locales": ["zh-cn"]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
||||
],
|
||||
"babelPlugins": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-editor-skeleton",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "alibaba lowcode editor skeleton",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -11,7 +11,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"test": "build-scripts test --config build.test.json",
|
||||
"build": "build-scripts build --skip-demo"
|
||||
"build": "build-scripts build"
|
||||
},
|
||||
"keywords": [
|
||||
"lowcode",
|
||||
@ -19,10 +19,10 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@alifd/next": "^1.20.12",
|
||||
"@alilc/lowcode-designer": "1.1.6",
|
||||
"@alilc/lowcode-editor-core": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-designer": "1.1.7",
|
||||
"@alilc/lowcode-editor-core": "1.1.7",
|
||||
"@alilc/lowcode-types": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"classnames": "^2.2.6",
|
||||
"react": "^16.8.1",
|
||||
"react-dom": "^16.8.1"
|
||||
|
||||
@ -4,6 +4,22 @@ import { uniqueId } from '@alilc/lowcode-utils';
|
||||
import { IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||
import './style.less';
|
||||
|
||||
export interface PopupExtProps {
|
||||
width?: number;
|
||||
hasMask?: boolean;
|
||||
trigger?: ReactNode;
|
||||
canCloseByOutSideClick?: boolean
|
||||
className?: string;
|
||||
safeNode?: string[];
|
||||
}
|
||||
|
||||
interface PopupProps extends PopupExtProps{
|
||||
content?: ReactNode,
|
||||
title?: ReactNode,
|
||||
actionKey?: string
|
||||
}
|
||||
|
||||
|
||||
export const PopupContext = createContext<PopupPipe>({} as any);
|
||||
|
||||
export class PopupPipe {
|
||||
@ -11,7 +27,7 @@ export class PopupPipe {
|
||||
|
||||
private currentId?: string;
|
||||
|
||||
create(props?: object): {
|
||||
create(props?: PopupExtProps): {
|
||||
send: (content: ReactNode, title: ReactNode) => void;
|
||||
show: (target: Element) => void;
|
||||
} {
|
||||
@ -45,13 +61,13 @@ export class PopupPipe {
|
||||
};
|
||||
}
|
||||
|
||||
private popup(props: object, target?: Element) {
|
||||
private popup(props: PopupProps, target?: Element) {
|
||||
Promise.resolve().then(() => {
|
||||
this.emitter.emit('popupchange', props, target);
|
||||
});
|
||||
}
|
||||
|
||||
onPopupChange(fn: (props: object, target?: Element) => void): () => void {
|
||||
onPopupChange(fn: (props: PopupProps, target?: Element) => void): () => void {
|
||||
this.emitter.on('popupchange', fn);
|
||||
return () => {
|
||||
this.emitter.removeListener('popupchange', fn);
|
||||
@ -86,18 +102,23 @@ export default class PopupService extends Component<{
|
||||
}
|
||||
}
|
||||
|
||||
interface StateType extends PopupProps {
|
||||
visible?: boolean,
|
||||
offsetX?: number,
|
||||
pos?: {top: number, height: number}
|
||||
}
|
||||
export class PopupContent extends PureComponent<{ safeId?: string; popupContainer?: string }> {
|
||||
static contextType = PopupContext;
|
||||
|
||||
popupContainerId = uniqueId('popupContainer');
|
||||
|
||||
state: any = {
|
||||
state: StateType = {
|
||||
visible: false,
|
||||
offsetX: -300,
|
||||
};
|
||||
|
||||
private dispose = (this.context as PopupPipe).onPopupChange((props, target) => {
|
||||
const state: any = {
|
||||
const state: StateType = {
|
||||
...props,
|
||||
visible: true,
|
||||
};
|
||||
@ -132,7 +153,7 @@ export class PopupContent extends PureComponent<{ safeId?: string; popupContaine
|
||||
};
|
||||
|
||||
render() {
|
||||
const { content, visible, title, actionKey, pos, offsetX } = this.state;
|
||||
const { content, visible, title, actionKey, pos, offsetX, width = 360, hasMask = false, canCloseByOutSideClick = true, safeNode = [] } = this.state;
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
@ -146,10 +167,10 @@ export class PopupContent extends PureComponent<{ safeId?: string; popupContaine
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
width={360}
|
||||
width={width}
|
||||
visible={visible}
|
||||
offset={[offsetX, 0]}
|
||||
hasMask={false}
|
||||
hasMask={hasMask}
|
||||
onVisibleChange={(_visible, type) => {
|
||||
if (avoidLaterHidden) {
|
||||
return;
|
||||
@ -160,11 +181,11 @@ export class PopupContent extends PureComponent<{ safeId?: string; popupContaine
|
||||
}}
|
||||
trigger={<div className="lc-popup-placeholder" style={pos} />}
|
||||
triggerType="click"
|
||||
canCloseByOutSideClick
|
||||
canCloseByOutSideClick={canCloseByOutSideClick}
|
||||
animation={false}
|
||||
onClose={this.onClose}
|
||||
id={this.props.safeId}
|
||||
safeNode={id}
|
||||
safeNode={[id, ...safeNode]}
|
||||
closeable
|
||||
container={this.props.popupContainer}
|
||||
>
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import { Component, MouseEvent, Fragment } from 'react';
|
||||
import { shallowIntl, observer, obx, engineConfig, runInAction, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { createContent, isJSSlot, isSetterConfig } from '@alilc/lowcode-utils';
|
||||
import { Component, MouseEvent, Fragment, ReactNode } from 'react';
|
||||
import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core';
|
||||
import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter } from '@alilc/lowcode-utils';
|
||||
import { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton';
|
||||
import { IPublicTypeCustomView } from '@alilc/lowcode-types';
|
||||
import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeDynamicProps } from '@alilc/lowcode-types';
|
||||
import { ISettingEntry, IComponentMeta, ISettingField, isSettingField, ISettingTopEntry } from '@alilc/lowcode-designer';
|
||||
import { createField } from '../field';
|
||||
import PopupService, { PopupPipe } from '../popup';
|
||||
import { SkeletonContext } from '../../context';
|
||||
import { intl } from '../../locale';
|
||||
import { Setters } from '@alilc/lowcode-shell';
|
||||
|
||||
function isStandardComponent(componentMeta: IComponentMeta | null) {
|
||||
if (!componentMeta) return false;
|
||||
@ -40,7 +39,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||
|
||||
stageName: string | undefined;
|
||||
|
||||
setters: Setters;
|
||||
setters?: IPublicApiSetters;
|
||||
|
||||
constructor(props: SettingFieldViewProps) {
|
||||
super(props);
|
||||
@ -49,10 +48,10 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||
const { extraProps } = field;
|
||||
const { display } = extraProps;
|
||||
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const { stages } = editor.get('skeleton') as Skeleton;
|
||||
this.setters = editor.get('setters');
|
||||
const editor = field.designer?.editor;
|
||||
const skeleton = editor?.get('skeleton') as Skeleton;
|
||||
const { stages } = skeleton || {};
|
||||
this.setters = editor?.get('setters');
|
||||
let stageName;
|
||||
if (display === 'entry') {
|
||||
runInAction(() => {
|
||||
@ -112,7 +111,9 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||
const { defaultValue } = extraProps;
|
||||
|
||||
const { setter } = this.field;
|
||||
let setterProps: any = {};
|
||||
let setterProps: {
|
||||
setters?: (ReactNode | string)[];
|
||||
} & Record<string, unknown> | IPublicTypeDynamicProps = {};
|
||||
let setterType: any;
|
||||
let initialValue: any = null;
|
||||
|
||||
@ -154,23 +155,29 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||
const supportVariable = this.field.extraProps?.supportVariable;
|
||||
// supportVariableGlobally 只对标准组件生效,vc 需要单独配置
|
||||
const supportVariableGlobally = engineConfig.get('supportVariableGlobally', false) && isStandardComponent(componentMeta);
|
||||
if (supportVariable || supportVariableGlobally) {
|
||||
if (setterType === 'MixedSetter') {
|
||||
// VariableSetter 不单独使用
|
||||
if (Array.isArray(setterProps.setters) && !setterProps.setters.includes('VariableSetter')) {
|
||||
setterProps.setters.push('VariableSetter');
|
||||
}
|
||||
} else {
|
||||
setterType = 'MixedSetter';
|
||||
setterProps = {
|
||||
setters: [
|
||||
setter,
|
||||
'VariableSetter',
|
||||
],
|
||||
};
|
||||
}
|
||||
const isUseVariableSetter = shouldUseVariableSetter(supportVariable, supportVariableGlobally);
|
||||
if (isUseVariableSetter === false) {
|
||||
return {
|
||||
setterProps,
|
||||
initialValue,
|
||||
setterType,
|
||||
};
|
||||
}
|
||||
|
||||
if (setterType === 'MixedSetter') {
|
||||
// VariableSetter 不单独使用
|
||||
if (Array.isArray(setterProps.setters) && !setterProps.setters.includes('VariableSetter')) {
|
||||
setterProps.setters.push('VariableSetter');
|
||||
}
|
||||
} else {
|
||||
setterType = 'MixedSetter';
|
||||
setterProps = {
|
||||
setters: [
|
||||
setter,
|
||||
'VariableSetter',
|
||||
],
|
||||
};
|
||||
}
|
||||
return {
|
||||
setterProps,
|
||||
initialValue,
|
||||
@ -236,7 +243,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||
...extraProps,
|
||||
},
|
||||
!stageName &&
|
||||
this.setters.createSetterContent(setterType, {
|
||||
this.setters?.createSetterContent(setterType, {
|
||||
...shallowIntl(setterProps),
|
||||
forceInline: extraProps.forceInline,
|
||||
key: field.id,
|
||||
@ -291,9 +298,8 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
|
||||
const { field } = this.props;
|
||||
const { extraProps } = field;
|
||||
const { display } = extraProps;
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const { stages } = editor.get('skeleton') as Skeleton;
|
||||
const editor = this.props.field.designer?.editor;
|
||||
const { stages } = editor?.get('skeleton') as Skeleton;
|
||||
// const items = field.items;
|
||||
|
||||
let stageName;
|
||||
@ -343,15 +349,15 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
|
||||
}
|
||||
}
|
||||
|
||||
export function createSettingFieldView(item: ISettingField | IPublicTypeCustomView, field: ISettingEntry, index?: number) {
|
||||
if (isSettingField(item)) {
|
||||
if (item.isGroup) {
|
||||
return <SettingGroupView field={item} key={item.id} />;
|
||||
export function createSettingFieldView(field: ISettingField | IPublicTypeCustomView, fieldEntry: ISettingEntry, index?: number) {
|
||||
if (isSettingField(field)) {
|
||||
if (field.isGroup) {
|
||||
return <SettingGroupView field={field} key={field.id} />;
|
||||
} else {
|
||||
return <SettingFieldView field={item} key={item.id} />;
|
||||
return <SettingFieldView field={field} key={field.id} />;
|
||||
}
|
||||
} else {
|
||||
return createContent(item, { key: index, field });
|
||||
return createContent(field, { key: index, field: fieldEntry });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,8 +53,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||
}
|
||||
|
||||
renderBreadcrumb() {
|
||||
const { settings } = this.main;
|
||||
const { config } = this.props;
|
||||
const { settings, editor } = this.main;
|
||||
// const shouldIgnoreRoot = config.props?.ignoreRoot;
|
||||
const { shouldIgnoreRoot } = this.state;
|
||||
if (!settings) {
|
||||
@ -73,8 +72,6 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||
);
|
||||
}
|
||||
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = this.props.engineEditor;
|
||||
const designer = editor.get('designer');
|
||||
const current = designer?.currentSelection?.getNodes()?.[0];
|
||||
let node: INode | null = settings.first;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Component, ReactElement } from 'react';
|
||||
import { Icon } from '@alifd/next';
|
||||
import classNames from 'classnames';
|
||||
import { Title, observer, Tip, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { Title, observer, Tip } from '@alilc/lowcode-editor-core';
|
||||
import { DockProps } from '../../types';
|
||||
import { PanelDock } from '../../widget/panel-dock';
|
||||
import { composeTitle } from '../../widget/utils';
|
||||
@ -116,14 +116,12 @@ export class DraggableLineView extends Component<{ panel: Panel }> {
|
||||
}
|
||||
|
||||
// 抛出事件,对于有些需要 panel 插件随着 度变化进行再次渲染的,由panel插件内部监听事件实现
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = this.props.panel.skeleton.editor;
|
||||
editor?.eventBus.emit('dockpane.drag', width);
|
||||
}
|
||||
|
||||
onDragChange(type: 'start' | 'end') {
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = this.props.panel.skeleton.editor;
|
||||
editor?.eventBus.emit('dockpane.dragchange', type);
|
||||
// builtinSimulator 屏蔽掉 鼠标事件
|
||||
editor?.eventBus.emit('designer.builtinSimulator.disabledEvents', type === 'start');
|
||||
@ -187,8 +185,7 @@ export class TitledPanelView extends Component<{ panel: Panel; area?: string }>
|
||||
if (!panel.inited) {
|
||||
return null;
|
||||
}
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = panel.skeleton.editor;
|
||||
const panelName = area ? `${area}-${panel.name}` : panel.name;
|
||||
editor?.eventBus.emit('skeleton.panel.toggle', {
|
||||
name: panelName || '',
|
||||
@ -250,8 +247,7 @@ export class PanelView extends Component<{
|
||||
if (!panel.inited) {
|
||||
return null;
|
||||
}
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const editor = panel.skeleton.editor;
|
||||
const panelName = area ? `${area}-${panel.name}` : panel.name;
|
||||
editor?.eventBus.emit('skeleton.panel.toggle', {
|
||||
name: panelName || '',
|
||||
|
||||
@ -56,7 +56,8 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton,
|
||||
'onShowWidget' |
|
||||
'onHideWidget' |
|
||||
'remove' |
|
||||
'hideArea'
|
||||
'hideArea' |
|
||||
'add'
|
||||
> {
|
||||
editor: IEditor;
|
||||
|
||||
@ -101,6 +102,8 @@ export interface ISkeleton extends Omit<IPublicApiSkeleton,
|
||||
): WidgetContainer;
|
||||
|
||||
createPanel(config: PanelConfig): Panel;
|
||||
|
||||
add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined;
|
||||
}
|
||||
|
||||
export class Skeleton {
|
||||
@ -440,7 +443,7 @@ export class Skeleton {
|
||||
return restConfig;
|
||||
}
|
||||
|
||||
add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>) {
|
||||
add(config: IPublicTypeSkeletonConfig, extraConfig?: Record<string, any>): IWidget | Widget | Panel | Stage | Dock | PanelDock | undefined {
|
||||
const parsedConfig = {
|
||||
...this.parseConfig(config),
|
||||
...extraConfig,
|
||||
|
||||
@ -211,6 +211,10 @@ export class Panel implements IWidget {
|
||||
this.setActive(false);
|
||||
}
|
||||
|
||||
disable() {}
|
||||
|
||||
enable(): void {}
|
||||
|
||||
show() {
|
||||
this.setActive(true);
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||
|
||||
[![codecov][codecov-image-url]][codecov-url]
|
||||
[![codecov][codecov-image-url]][codecov-url] [](https://github.com/lowcode-workspace/awesome-lowcode-engine)
|
||||
|
||||
[](https://opensource.alibaba.com/contribution_leaderboard/details?projectValue=lowcode-engine)
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ An enterprise-class low-code technology stack with scale-out design
|
||||
|
||||
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]
|
||||
|
||||
[![codecov][codecov-image-url]][codecov-url]
|
||||
[![codecov][codecov-image-url]][codecov-url] [](https://github.com/lowcode-workspace/awesome-lowcode-engine)
|
||||
|
||||
[](https://opensource.alibaba.com/contribution_leaderboard/details?projectValue=lowcode-engine)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
[
|
||||
"build-plugin-fusion",
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
{
|
||||
"filename": "editor-preset-vision",
|
||||
"library": "LowcodeEditor",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-engine",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系",
|
||||
"main": "lib/engine-core.js",
|
||||
"module": "es/engine-core.js",
|
||||
@ -12,22 +12,22 @@
|
||||
"scripts": {
|
||||
"start": "build-scripts start",
|
||||
"version:update": "node ./scripts/version.js",
|
||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --skip-demo",
|
||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build",
|
||||
"build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json",
|
||||
"test": "build-scripts test --config build.test.json --jest-passWithNoTests"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alifd/next": "^1.19.12",
|
||||
"@alilc/lowcode-designer": "1.1.6",
|
||||
"@alilc/lowcode-editor-core": "1.1.6",
|
||||
"@alilc/lowcode-editor-skeleton": "1.1.6",
|
||||
"@alilc/lowcode-designer": "1.1.7",
|
||||
"@alilc/lowcode-editor-core": "1.1.7",
|
||||
"@alilc/lowcode-editor-skeleton": "1.1.7",
|
||||
"@alilc/lowcode-engine-ext": "^1.0.0",
|
||||
"@alilc/lowcode-plugin-designer": "1.1.6",
|
||||
"@alilc/lowcode-plugin-outline-pane": "1.1.6",
|
||||
"@alilc/lowcode-shell": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-workspace": "1.1.6",
|
||||
"@alilc/lowcode-plugin-designer": "1.1.7",
|
||||
"@alilc/lowcode-plugin-outline-pane": "1.1.7",
|
||||
"@alilc/lowcode-shell": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"@alilc/lowcode-workspace": "1.1.7",
|
||||
"react": "^16.8.1",
|
||||
"react-dom": "^16.8.1"
|
||||
},
|
||||
|
||||
@ -9,11 +9,16 @@ import {
|
||||
engineConfig,
|
||||
Setters as InnerSetters,
|
||||
Hotkey as InnerHotkey,
|
||||
IEditor,
|
||||
} from '@alilc/lowcode-editor-core';
|
||||
import {
|
||||
IPublicTypeEngineOptions,
|
||||
IPublicModelDocumentModel,
|
||||
IPublicTypePluginMeta,
|
||||
IPublicTypeDisposable,
|
||||
IPublicApiPlugins,
|
||||
IPublicApiWorkspace,
|
||||
IPublicEnumPluginRegisterLevel,
|
||||
} from '@alilc/lowcode-types';
|
||||
import {
|
||||
Designer,
|
||||
@ -21,6 +26,7 @@ import {
|
||||
ILowCodePluginContextPrivate,
|
||||
ILowCodePluginContextApiAssembler,
|
||||
PluginPreference,
|
||||
IDesigner,
|
||||
} from '@alilc/lowcode-designer';
|
||||
import {
|
||||
Skeleton as InnerSkeleton,
|
||||
@ -29,6 +35,7 @@ import {
|
||||
import {
|
||||
Workspace as InnerWorkspace,
|
||||
Workbench as WorkSpaceWorkbench,
|
||||
IWorkspace,
|
||||
} from '@alilc/lowcode-workspace';
|
||||
|
||||
import {
|
||||
@ -60,18 +67,30 @@ export * from './modules/skeleton-types';
|
||||
export * from './modules/designer-types';
|
||||
export * from './modules/lowcode-types';
|
||||
|
||||
async function registryInnerPlugin(designer: Designer, editor: Editor, plugins: Plugins) {
|
||||
async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins: IPublicApiPlugins): Promise<IPublicTypeDisposable> {
|
||||
// 注册一批内置插件
|
||||
const componentMetaParserPlugin = componentMetaParser(designer);
|
||||
const defaultPanelRegistryPlugin = defaultPanelRegistry(editor);
|
||||
await plugins.register(OutlinePlugin, {}, { autoInit: true });
|
||||
await plugins.register(componentMetaParser(designer));
|
||||
await plugins.register(componentMetaParserPlugin);
|
||||
await plugins.register(setterRegistry, {});
|
||||
await plugins.register(defaultPanelRegistry(editor));
|
||||
await plugins.register(defaultPanelRegistryPlugin);
|
||||
await plugins.register(builtinHotkey);
|
||||
await plugins.register(registerDefaults, {}, { autoInit: true });
|
||||
|
||||
return () => {
|
||||
plugins.delete(OutlinePlugin.pluginName);
|
||||
plugins.delete(componentMetaParserPlugin.pluginName);
|
||||
plugins.delete(setterRegistry.pluginName);
|
||||
plugins.delete(defaultPanelRegistryPlugin.pluginName);
|
||||
plugins.delete(defaultPanelRegistryPlugin.pluginName);
|
||||
plugins.delete(builtinHotkey.pluginName);
|
||||
plugins.delete(registerDefaults.pluginName);
|
||||
};
|
||||
}
|
||||
|
||||
const innerWorkspace = new InnerWorkspace(registryInnerPlugin, shellModelFactory);
|
||||
const workspace = new Workspace(innerWorkspace);
|
||||
const innerWorkspace: IWorkspace = new InnerWorkspace(registryInnerPlugin, shellModelFactory);
|
||||
const workspace: IPublicApiWorkspace = new Workspace(innerWorkspace);
|
||||
const editor = new Editor();
|
||||
globalContext.register(editor, Editor);
|
||||
globalContext.register(editor, 'editor');
|
||||
@ -120,6 +139,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
|
||||
context.plugins = plugins;
|
||||
context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` });
|
||||
context.workspace = workspace;
|
||||
context.registerLevel = IPublicEnumPluginRegisterLevel.Default;
|
||||
},
|
||||
};
|
||||
|
||||
@ -139,8 +159,6 @@ export {
|
||||
logger,
|
||||
hotkey,
|
||||
common,
|
||||
// 兼容原 editor 的事件功能
|
||||
event as editor,
|
||||
workspace,
|
||||
canvas,
|
||||
};
|
||||
@ -158,7 +176,7 @@ let engineContainer: HTMLElement;
|
||||
export const version = VERSION_PLACEHOLDER;
|
||||
engineConfig.set('ENGINE_VERSION', version);
|
||||
|
||||
registryInnerPlugin(designer, editor, plugins);
|
||||
const pluginPromise = registryInnerPlugin(designer, editor, plugins);
|
||||
|
||||
export async function init(
|
||||
container?: HTMLElement,
|
||||
@ -183,10 +201,10 @@ export async function init(
|
||||
}
|
||||
engineConfig.setEngineOptions(engineOptions as any);
|
||||
|
||||
await plugins.init(pluginPreference as any);
|
||||
|
||||
const { Workbench } = common.skeletonCabin;
|
||||
if (options && options.enableWorkspaceMode) {
|
||||
const disposeFun = await pluginPromise;
|
||||
disposeFun && disposeFun();
|
||||
render(
|
||||
createElement(WorkSpaceWorkbench, {
|
||||
workspace: innerWorkspace,
|
||||
@ -196,12 +214,16 @@ export async function init(
|
||||
}),
|
||||
engineContainer,
|
||||
);
|
||||
innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true);
|
||||
innerWorkspace.setActive(true);
|
||||
innerWorkspace.initWindow();
|
||||
innerHotkey.activate(false);
|
||||
await innerWorkspace.plugins.init(pluginPreference);
|
||||
return;
|
||||
}
|
||||
|
||||
await plugins.init(pluginPreference as any);
|
||||
|
||||
render(
|
||||
createElement(Workbench, {
|
||||
skeleton: innerSkeleton,
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
Selection,
|
||||
Prop,
|
||||
SimulatorHost,
|
||||
SkeletonItem,
|
||||
} from '@alilc/lowcode-shell';
|
||||
import { Node as InnerNode } from '@alilc/lowcode-designer';
|
||||
|
||||
@ -26,4 +27,5 @@ export default {
|
||||
Selection,
|
||||
Prop,
|
||||
SimulatorHost,
|
||||
SkeletonItem,
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
designerCabinSymbol,
|
||||
propSymbol,
|
||||
simulatorHostSymbol,
|
||||
skeletonItemSymbol,
|
||||
} from '@alilc/lowcode-shell';
|
||||
|
||||
export default {
|
||||
@ -26,4 +27,5 @@ export default {
|
||||
designerCabinSymbol,
|
||||
propSymbol,
|
||||
simulatorHostSymbol,
|
||||
skeletonItemSymbol,
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-ignitor",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "点火器,bootstrap lce project",
|
||||
"main": "lib/index.js",
|
||||
"private": true,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component"
|
||||
"@alilc/build-plugin-lce"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-plugin-designer",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "alibaba lowcode editor designer plugin",
|
||||
"files": [
|
||||
"es",
|
||||
@ -10,7 +10,7 @@
|
||||
"module": "es/index.js",
|
||||
"stylePath": "style.js",
|
||||
"scripts": {
|
||||
"build": "build-scripts build --skip-demo"
|
||||
"build": "build-scripts build"
|
||||
},
|
||||
"keywords": [
|
||||
"lowcode",
|
||||
@ -18,9 +18,9 @@
|
||||
],
|
||||
"author": "xiayang.xy",
|
||||
"dependencies": {
|
||||
"@alilc/lowcode-designer": "1.1.6",
|
||||
"@alilc/lowcode-editor-core": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-designer": "1.1.7",
|
||||
"@alilc/lowcode-editor-core": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"react": "^16.8.1",
|
||||
"react-dom": "^16.8.1"
|
||||
},
|
||||
|
||||
@ -62,6 +62,11 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
||||
if (!this._mounted) {
|
||||
return;
|
||||
}
|
||||
engineConfig.onGot('locale', (locale) => {
|
||||
this.setState({
|
||||
locale,
|
||||
});
|
||||
});
|
||||
const { components, packages, extraEnvironment, utils } = assets;
|
||||
const state = {
|
||||
componentMetadatas: components || [],
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"build-plugin-fusion",
|
||||
["build-plugin-moment-locales", {
|
||||
"locales": ["zh-cn"]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-plugin-outline-pane",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "Outline pane for Ali lowCode engine",
|
||||
"files": [
|
||||
"es",
|
||||
@ -9,14 +9,12 @@
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"scripts": {
|
||||
"build": "build-scripts build --skip-demo"
|
||||
"build": "build-scripts build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alifd/next": "^1.19.16",
|
||||
"@alilc/lowcode-designer": "1.1.6",
|
||||
"@alilc/lowcode-editor-core": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"classnames": "^2.2.6",
|
||||
"react": "^16",
|
||||
"react-dom": "^16.7.0",
|
||||
|
||||
@ -16,16 +16,15 @@ import {
|
||||
IPublicModelDropLocation,
|
||||
IPublicModelScroller,
|
||||
IPublicModelScrollTarget,
|
||||
IPublicModelPluginContext,
|
||||
IPublicModelLocateEvent,
|
||||
} from '@alilc/lowcode-types';
|
||||
import TreeNode from './tree-node';
|
||||
import { IndentTrack } from '../helper/indent-track';
|
||||
import DwellTimer from '../helper/dwell-timer';
|
||||
import { ITreeBoard, TreeMaster } from './tree-master';
|
||||
import { IOutlinePanelPluginContext, ITreeBoard, TreeMaster } from './tree-master';
|
||||
|
||||
export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTypeScrollable {
|
||||
private pluginContext: IPublicModelPluginContext;
|
||||
private pluginContext: IOutlinePanelPluginContext;
|
||||
|
||||
private treeMaster?: TreeMaster;
|
||||
|
||||
@ -100,8 +99,8 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
|
||||
|
||||
private _shell: HTMLDivElement | null = null;
|
||||
|
||||
constructor(at: string | symbol, pluginContext: IPublicModelPluginContext, treeMaster: TreeMaster) {
|
||||
this.pluginContext = pluginContext;
|
||||
constructor(at: string | symbol, treeMaster: TreeMaster) {
|
||||
this.pluginContext = treeMaster.pluginContext;
|
||||
this.treeMaster = treeMaster;
|
||||
this.at = at;
|
||||
let inited = false;
|
||||
@ -237,7 +236,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
|
||||
let { node } = treeNode;
|
||||
if (isDragNodeObject(dragObject)) {
|
||||
const newNodes = operationalNodes;
|
||||
let i = newNodes.length;
|
||||
let i = newNodes?.length;
|
||||
let p: any = node;
|
||||
while (i-- > 0) {
|
||||
if (newNodes[i].contains(p)) {
|
||||
@ -482,7 +481,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
|
||||
const isSlotContainer = treeNode.hasSlots();
|
||||
const isContainer = treeNode.isContainer();
|
||||
|
||||
if (container.isSlot && !treeNode.expanded) {
|
||||
if (container.isSlotNode && !treeNode.expanded) {
|
||||
// 未展开,直接定位到内部第一个节点
|
||||
if (isSlotContainer) {
|
||||
detail.index = null;
|
||||
|
||||
@ -1,30 +1,96 @@
|
||||
import { isLocationChildrenDetail } from '@alilc/lowcode-utils';
|
||||
import { IPublicModelPluginContext, IPublicTypeActiveTarget, IPublicModelNode } from '@alilc/lowcode-types';
|
||||
import { IPublicModelPluginContext, IPublicTypeActiveTarget, IPublicModelNode, IPublicTypeDisposable, IPublicEnumPluginRegisterLevel } from '@alilc/lowcode-types';
|
||||
import TreeNode from './tree-node';
|
||||
import { Tree } from './tree';
|
||||
import EventEmitter from 'events';
|
||||
import { enUS, zhCN } from '../locale';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export interface ITreeBoard {
|
||||
readonly at: string | symbol;
|
||||
scrollToNode(treeNode: TreeNode, detail?: any): void;
|
||||
}
|
||||
|
||||
enum EVENT_NAMES {
|
||||
pluginContextChanged = 'pluginContextChanged',
|
||||
}
|
||||
|
||||
export interface IOutlinePanelPluginContext extends IPublicModelPluginContext {
|
||||
extraTitle?: string;
|
||||
intlNode(id: string, params?: object): ReactNode;
|
||||
intl(id: string, params?: object): string;
|
||||
getLocale(): string;
|
||||
}
|
||||
|
||||
export class TreeMaster {
|
||||
readonly pluginContext: IPublicModelPluginContext;
|
||||
pluginContext: IOutlinePanelPluginContext;
|
||||
|
||||
private boards = new Set<ITreeBoard>();
|
||||
|
||||
private treeMap = new Map<string, Tree>();
|
||||
|
||||
constructor(pluginContext: IPublicModelPluginContext) {
|
||||
this.pluginContext = pluginContext;
|
||||
private disposeEvents: (IPublicTypeDisposable | undefined)[] = [];
|
||||
|
||||
event = new EventEmitter();
|
||||
|
||||
constructor(pluginContext: IPublicModelPluginContext, readonly options: {
|
||||
extraTitle?: string;
|
||||
}) {
|
||||
this.setPluginContext(pluginContext);
|
||||
const { workspace } = this.pluginContext;
|
||||
this.initEvent();
|
||||
if (pluginContext.registerLevel === IPublicEnumPluginRegisterLevel.Workspace) {
|
||||
this.setPluginContext(workspace.window?.currentEditorView);
|
||||
workspace.onWindowRendererReady(() => {
|
||||
this.setPluginContext(workspace.window?.currentEditorView);
|
||||
let dispose: IPublicTypeDisposable | undefined;
|
||||
const windowViewTypeChangeEvent = () => {
|
||||
dispose = workspace.window?.onChangeViewType(() => {
|
||||
this.setPluginContext(workspace.window?.currentEditorView);
|
||||
});
|
||||
};
|
||||
|
||||
windowViewTypeChangeEvent();
|
||||
|
||||
workspace.onChangeActiveWindow(() => {
|
||||
windowViewTypeChangeEvent();
|
||||
this.setPluginContext(workspace.window?.currentEditorView);
|
||||
dispose && dispose();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private setPluginContext(pluginContext: IPublicModelPluginContext | undefined | null) {
|
||||
if (!pluginContext) {
|
||||
return;
|
||||
}
|
||||
const { intl, intlNode, getLocale } = pluginContext.common.utils.createIntl({
|
||||
'en-US': enUS,
|
||||
'zh-CN': zhCN,
|
||||
});
|
||||
let _pluginContext: IOutlinePanelPluginContext = Object.assign(pluginContext, {
|
||||
intl,
|
||||
intlNode,
|
||||
getLocale,
|
||||
});
|
||||
_pluginContext.extraTitle = this.options && this.options['extraTitle'];
|
||||
this.pluginContext = _pluginContext;
|
||||
this.disposeEvent();
|
||||
this.initEvent();
|
||||
this.emitPluginContextChange();
|
||||
}
|
||||
|
||||
private disposeEvent() {
|
||||
this.disposeEvents.forEach(d => {
|
||||
d && d();
|
||||
});
|
||||
}
|
||||
|
||||
private initEvent() {
|
||||
let startTime: any;
|
||||
const { event, project, canvas } = this.pluginContext;
|
||||
canvas.dragon?.onDragstart(() => {
|
||||
startTime = Date.now() / 1000;
|
||||
// needs?
|
||||
this.toVision();
|
||||
});
|
||||
canvas.activeTracker?.onChange((target: IPublicTypeActiveTarget) => {
|
||||
const setExpandByActiveTracker = (target: IPublicTypeActiveTarget) => {
|
||||
const { node, detail } = target;
|
||||
const tree = this.currentTree;
|
||||
if (!tree/* || node.document !== tree.document */) {
|
||||
@ -39,29 +105,40 @@ export class TreeMaster {
|
||||
this.boards.forEach((board) => {
|
||||
board.scrollToNode(treeNode, detail);
|
||||
});
|
||||
});
|
||||
canvas.dragon?.onDragend(() => {
|
||||
const endTime: any = Date.now() / 1000;
|
||||
const nodes = project.currentDocument?.selection?.getNodes();
|
||||
event.emit('outlinePane.dragend', {
|
||||
selected: nodes
|
||||
?.map((n) => {
|
||||
if (!n) {
|
||||
return;
|
||||
}
|
||||
const npm = n?.componentMeta?.npm;
|
||||
return (
|
||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || n?.componentMeta?.componentName
|
||||
);
|
||||
})
|
||||
.join('&'),
|
||||
time: (endTime - startTime).toFixed(2),
|
||||
});
|
||||
});
|
||||
project.onRemoveDocument((data: {id: string}) => {
|
||||
const { id } = data;
|
||||
this.treeMap.delete(id);
|
||||
});
|
||||
};
|
||||
this.disposeEvents = [
|
||||
canvas.dragon?.onDragstart(() => {
|
||||
startTime = Date.now() / 1000;
|
||||
// needs?
|
||||
this.toVision();
|
||||
}),
|
||||
canvas.activeTracker?.onChange(setExpandByActiveTracker),
|
||||
canvas.dragon?.onDragend(() => {
|
||||
const endTime: any = Date.now() / 1000;
|
||||
const nodes = project.currentDocument?.selection?.getNodes();
|
||||
event.emit('outlinePane.dragend', {
|
||||
selected: nodes
|
||||
?.map((n) => {
|
||||
if (!n) {
|
||||
return;
|
||||
}
|
||||
const npm = n?.componentMeta?.npm;
|
||||
return (
|
||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || n?.componentMeta?.componentName
|
||||
);
|
||||
})
|
||||
.join('&'),
|
||||
time: (endTime - startTime).toFixed(2),
|
||||
});
|
||||
}),
|
||||
project.onRemoveDocument((data: {id: string}) => {
|
||||
const { id } = data;
|
||||
this.treeMap.delete(id);
|
||||
}),
|
||||
];
|
||||
if (canvas.activeTracker?.target) {
|
||||
setExpandByActiveTracker(canvas.activeTracker?.target);
|
||||
}
|
||||
}
|
||||
|
||||
private toVision() {
|
||||
@ -86,6 +163,14 @@ export class TreeMaster {
|
||||
// todo others purge
|
||||
}
|
||||
|
||||
onPluginContextChange(fn: () => void) {
|
||||
this.event.on(EVENT_NAMES.pluginContextChanged, fn);
|
||||
}
|
||||
|
||||
emitPluginContextChange() {
|
||||
this.event.emit(EVENT_NAMES.pluginContextChanged);
|
||||
}
|
||||
|
||||
get currentTree(): Tree | null {
|
||||
const doc = this.pluginContext.project.getCurrentDocument();
|
||||
if (doc) {
|
||||
@ -93,7 +178,7 @@ export class TreeMaster {
|
||||
if (this.treeMap.has(id)) {
|
||||
return this.treeMap.get(id)!;
|
||||
}
|
||||
const tree = new Tree(this.pluginContext);
|
||||
const tree = new Tree(this);
|
||||
this.treeMap.set(id, tree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
@ -2,12 +2,12 @@ import {
|
||||
IPublicTypeTitleContent,
|
||||
IPublicTypeLocationChildrenDetail,
|
||||
IPublicModelNode,
|
||||
IPublicModelPluginContext,
|
||||
IPublicTypeDisposable,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { isI18nData, isLocationChildrenDetail } from '@alilc/lowcode-utils';
|
||||
import EventEmitter from 'events';
|
||||
import { Tree } from './tree';
|
||||
import { IOutlinePanelPluginContext } from './tree-master';
|
||||
|
||||
/**
|
||||
* 大纲树过滤结果
|
||||
@ -35,10 +35,12 @@ enum EVENT_NAMES {
|
||||
titleLabelChanged = 'titleLabelChanged',
|
||||
|
||||
expandableChanged = 'expandableChanged',
|
||||
|
||||
conditionChanged = 'conditionChanged',
|
||||
}
|
||||
|
||||
export default class TreeNode {
|
||||
readonly pluginContext: IPublicModelPluginContext;
|
||||
readonly pluginContext: IOutlinePanelPluginContext;
|
||||
event = new EventEmitter();
|
||||
|
||||
private _node: IPublicModelNode;
|
||||
@ -152,6 +154,10 @@ export default class TreeNode {
|
||||
return this.node.slots.map((node) => this.tree.getTreeNode(node));
|
||||
}
|
||||
|
||||
get condition(): boolean {
|
||||
return this.node.hasCondition() && !this.node.conditionGroup;
|
||||
}
|
||||
|
||||
get children(): TreeNode[] | null {
|
||||
return this.node.children?.map((node) => this.tree.getTreeNode(node)) || null;
|
||||
}
|
||||
@ -160,9 +166,9 @@ export default class TreeNode {
|
||||
return this._node;
|
||||
}
|
||||
|
||||
constructor(tree: Tree, node: IPublicModelNode, pluginContext: IPublicModelPluginContext) {
|
||||
constructor(tree: Tree, node: IPublicModelNode) {
|
||||
this.tree = tree;
|
||||
this.pluginContext = pluginContext;
|
||||
this.pluginContext = tree.pluginContext;
|
||||
this._node = node;
|
||||
}
|
||||
|
||||
@ -203,6 +209,15 @@ export default class TreeNode {
|
||||
this.event.off(EVENT_NAMES.titleLabelChanged, fn);
|
||||
};
|
||||
}
|
||||
|
||||
onConditionChanged(fn: (treeNode: TreeNode) => void): IPublicTypeDisposable {
|
||||
this.event.on(EVENT_NAMES.conditionChanged, fn);
|
||||
|
||||
return () => {
|
||||
this.event.off(EVENT_NAMES.conditionChanged, fn);
|
||||
};
|
||||
}
|
||||
|
||||
onExpandableChanged(fn: (expandable: boolean) => void): IPublicTypeDisposable {
|
||||
this.event.on(EVENT_NAMES.expandableChanged, fn);
|
||||
return () => {
|
||||
@ -221,11 +236,17 @@ export default class TreeNode {
|
||||
this.event.emit(EVENT_NAMES.titleLabelChanged, this.title);
|
||||
}
|
||||
|
||||
notifyConditionChanged(): void {
|
||||
this.event.emit(EVENT_NAMES.conditionChanged, this.condition);
|
||||
}
|
||||
|
||||
setHidden(flag: boolean) {
|
||||
if (this.node.conditionGroup) {
|
||||
return;
|
||||
}
|
||||
this.node.visible = !flag;
|
||||
if (this.node.visible !== !flag) {
|
||||
this.node.visible = !flag;
|
||||
}
|
||||
this.event.emit(EVENT_NAMES.hiddenChanged, flag);
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import TreeNode from './tree-node';
|
||||
import { IPublicModelNode, IPublicModelPluginContext, IPublicTypePropChangeOptions } from '@alilc/lowcode-types';
|
||||
import { IPublicModelNode, IPublicTypePropChangeOptions } from '@alilc/lowcode-types';
|
||||
import { IOutlinePanelPluginContext, TreeMaster } from './tree-master';
|
||||
|
||||
export class Tree {
|
||||
private treeNodesMap = new Map<string, TreeNode>();
|
||||
|
||||
readonly id: string | undefined;
|
||||
|
||||
readonly pluginContext: IPublicModelPluginContext;
|
||||
readonly pluginContext: IOutlinePanelPluginContext;
|
||||
|
||||
get root(): TreeNode | null {
|
||||
if (this.pluginContext.project.currentDocument?.focusNode) {
|
||||
@ -15,8 +16,11 @@ export class Tree {
|
||||
return null;
|
||||
}
|
||||
|
||||
constructor(pluginContext: IPublicModelPluginContext) {
|
||||
this.pluginContext = pluginContext;
|
||||
readonly treeMaster: TreeMaster;
|
||||
|
||||
constructor(treeMaster: TreeMaster) {
|
||||
this.treeMaster = treeMaster;
|
||||
this.pluginContext = treeMaster.pluginContext;
|
||||
const doc = this.pluginContext.project.currentDocument;
|
||||
this.id = doc?.id;
|
||||
|
||||
@ -31,8 +35,16 @@ export class Tree {
|
||||
if (key === '___title___') {
|
||||
const treeNode = this.getTreeNodeById(node.id);
|
||||
treeNode?.notifyTitleLabelChanged();
|
||||
} else if (key === '___condition___') {
|
||||
const treeNode = this.getTreeNodeById(node.id);
|
||||
treeNode?.notifyConditionChanged();
|
||||
}
|
||||
});
|
||||
|
||||
doc?.onChangeNodeVisible((node: IPublicModelNode, visible: boolean) => {
|
||||
const treeNode = this.getTreeNodeById(node.id);
|
||||
treeNode?.setHidden(!visible);
|
||||
});
|
||||
}
|
||||
|
||||
setNodeSelected(nodeId: string): void {
|
||||
@ -51,7 +63,7 @@ export class Tree {
|
||||
return tnode;
|
||||
}
|
||||
|
||||
const treeNode = new TreeNode(this, node, this.pluginContext);
|
||||
const treeNode = new TreeNode(this, node);
|
||||
this.treeNodesMap.set(node.id, treeNode);
|
||||
return treeNode;
|
||||
}
|
||||
|
||||
@ -1,21 +1,43 @@
|
||||
import { Pane } from './views/pane';
|
||||
import { IconOutline } from './icons/outline';
|
||||
import { IPublicModelPluginContext, IPublicModelDocumentModel } from '@alilc/lowcode-types';
|
||||
import { enUS, zhCN } from './locale';
|
||||
import { MasterPaneName, BackupPaneName } from './helper/consts';
|
||||
import { TreeMaster } from './controllers/tree-master';
|
||||
import { PaneController } from './controllers/pane-controller';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export function OutlinePaneContext(props: {
|
||||
treeMaster?: TreeMaster;
|
||||
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
|
||||
options: any;
|
||||
|
||||
paneName: string;
|
||||
|
||||
hideFilter?: boolean;
|
||||
}) {
|
||||
const treeMaster = props.treeMaster || new TreeMaster(props.pluginContext, props.options);
|
||||
const [masterPaneController, setMasterPaneController] = useState(new PaneController(props.paneName || MasterPaneName, treeMaster));
|
||||
useEffect(() => {
|
||||
return treeMaster.onPluginContextChange(() => {
|
||||
setMasterPaneController(new PaneController(props.paneName || MasterPaneName, treeMaster));
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Pane
|
||||
treeMaster={treeMaster}
|
||||
controller={masterPaneController}
|
||||
key={masterPaneController.id}
|
||||
hideFilter={props.hideFilter}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
|
||||
const { skeleton, config, common, event, canvas, project } = ctx;
|
||||
const { intl, intlNode, getLocale } = common.utils.createIntl({
|
||||
'en-US': enUS,
|
||||
'zh-CN': zhCN,
|
||||
});
|
||||
ctx.intl = intl;
|
||||
ctx.intlNode = intlNode;
|
||||
ctx.getLocale = getLocale;
|
||||
ctx.extraTitle = options && options['extraTitle'];
|
||||
const { skeleton, config, canvas, project } = ctx;
|
||||
|
||||
let isInFloatArea = true;
|
||||
const hasPreferenceForOutline = config.getPreference().contains('outline-pane-pinned-status-isFloat', 'skeleton');
|
||||
@ -26,9 +48,7 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
|
||||
masterPane: false,
|
||||
backupPane: false,
|
||||
};
|
||||
const treeMaster = new TreeMaster(ctx);
|
||||
let masterPaneController: PaneController | null = null;
|
||||
let backupPaneController: PaneController | null = null;
|
||||
const treeMaster = new TreeMaster(ctx, options);
|
||||
return {
|
||||
async init() {
|
||||
skeleton.add({
|
||||
@ -40,20 +60,9 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
|
||||
name: MasterPaneName,
|
||||
props: {
|
||||
icon: IconOutline,
|
||||
description: intlNode('Outline Tree'),
|
||||
},
|
||||
content: (props: any) => {
|
||||
masterPaneController = new PaneController(MasterPaneName, ctx, treeMaster);
|
||||
return (
|
||||
<Pane
|
||||
config={config}
|
||||
pluginContext={ctx}
|
||||
treeMaster={treeMaster}
|
||||
controller={masterPaneController}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
description: treeMaster.pluginContext.intlNode('Outline Tree'),
|
||||
},
|
||||
content: OutlinePaneContext,
|
||||
},
|
||||
panelProps: {
|
||||
area: isInFloatArea ? 'leftFloatArea' : 'leftFixedArea',
|
||||
@ -62,6 +71,8 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
|
||||
},
|
||||
contentProps: {
|
||||
treeTitleExtra: config.get('treeTitleExtra'),
|
||||
treeMaster,
|
||||
paneName: MasterPaneName,
|
||||
},
|
||||
});
|
||||
|
||||
@ -72,16 +83,10 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
|
||||
props: {
|
||||
hiddenWhenInit: true,
|
||||
},
|
||||
content: (props: any) => {
|
||||
backupPaneController = new PaneController(BackupPaneName, ctx, treeMaster);
|
||||
return (
|
||||
<Pane
|
||||
pluginContext={ctx}
|
||||
treeMaster={treeMaster}
|
||||
controller={backupPaneController}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
content: OutlinePaneContext,
|
||||
contentProps: {
|
||||
paneName: BackupPaneName,
|
||||
treeMaster,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -5,11 +5,9 @@ import { Search, Checkbox, Balloon, Divider } from '@alifd/next';
|
||||
import TreeNode from '../controllers/tree-node';
|
||||
import { Tree } from '../controllers/tree';
|
||||
import { matchTreeNode, FILTER_OPTIONS } from './filter-tree';
|
||||
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
|
||||
|
||||
export default class Filter extends PureComponent<{
|
||||
tree: Tree;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
}, {
|
||||
keywords: string;
|
||||
filterOps: string[];
|
||||
@ -56,7 +54,7 @@ export default class Filter extends PureComponent<{
|
||||
<Search
|
||||
hasClear
|
||||
shape="simple"
|
||||
placeholder={this.props.pluginContext.intl('Filter Node')}
|
||||
placeholder={this.props.tree.pluginContext.intl('Filter Node')}
|
||||
className="lc-outline-filter-search-input"
|
||||
value={keywords}
|
||||
onChange={this.handleSearchChange}
|
||||
@ -77,7 +75,7 @@ export default class Filter extends PureComponent<{
|
||||
indeterminate={indeterminate}
|
||||
onChange={this.handleCheckAll}
|
||||
>
|
||||
{this.props.pluginContext.intlNode('Check All')}
|
||||
{this.props.tree.pluginContext.intlNode('Check All')}
|
||||
</Checkbox>
|
||||
<Divider />
|
||||
<Checkbox.Group
|
||||
@ -91,7 +89,7 @@ export default class Filter extends PureComponent<{
|
||||
value={op.value}
|
||||
key={op.value}
|
||||
>
|
||||
{this.props.pluginContext.intlNode(op.label)}
|
||||
{this.props.tree.pluginContext.intlNode(op.label)}
|
||||
</Checkbox>
|
||||
))}
|
||||
</Checkbox.Group>
|
||||
|
||||
@ -1,47 +1,75 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Loading } from '@alifd/next';
|
||||
import { PaneController } from '../controllers/pane-controller';
|
||||
import TreeView from './tree';
|
||||
import './style.less';
|
||||
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
|
||||
import Filter from './filter';
|
||||
import { TreeMaster } from '../controllers/tree-master';
|
||||
import { Tree } from '../controllers/tree';
|
||||
import { IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||
|
||||
export class Pane extends PureComponent<{
|
||||
config: any;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
treeMaster: TreeMaster;
|
||||
controller: PaneController;
|
||||
hideFilter?: boolean;
|
||||
}, {
|
||||
tree: Tree | null;
|
||||
}> {
|
||||
private controller;
|
||||
private treeMaster: TreeMaster;
|
||||
|
||||
private simulatorRendererReadyDispose: IPublicTypeDisposable;
|
||||
private changeDocumentDispose: IPublicTypeDisposable;
|
||||
private removeDocumentDispose: IPublicTypeDisposable;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
const { controller, treeMaster } = props;
|
||||
this.treeMaster = treeMaster;
|
||||
this.controller = controller;
|
||||
this.state = {
|
||||
tree: treeMaster.currentTree,
|
||||
};
|
||||
this.simulatorRendererReadyDispose = this.props.treeMaster.pluginContext?.project?.onSimulatorRendererReady(this.changeTree);
|
||||
this.changeDocumentDispose = this.props.treeMaster.pluginContext?.project?.onChangeDocument(this.changeTree);
|
||||
this.removeDocumentDispose = this.props.treeMaster.pluginContext?.project?.onRemoveDocument(this.changeTree);
|
||||
}
|
||||
|
||||
changeTree = () => {
|
||||
this.setState({
|
||||
tree: this.props.treeMaster.currentTree,
|
||||
});
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
this.controller.purge();
|
||||
this.simulatorRendererReadyDispose?.();
|
||||
this.changeDocumentDispose?.();
|
||||
this.removeDocumentDispose?.();
|
||||
}
|
||||
|
||||
render() {
|
||||
const tree = this.treeMaster.currentTree;
|
||||
const tree = this.state.tree;
|
||||
|
||||
if (!tree) {
|
||||
return (
|
||||
<div className="lc-outline-pane">
|
||||
<p className="lc-outline-notice">{this.props.pluginContext.intl('Initializing')}</p>
|
||||
<p className="lc-outline-notice">
|
||||
<Loading
|
||||
style={{
|
||||
display: 'block',
|
||||
marginTop: '40px',
|
||||
}}
|
||||
tip={this.props.treeMaster.pluginContext.intl('Initializing')}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="lc-outline-pane">
|
||||
<Filter tree={tree} pluginContext={this.props.pluginContext} />
|
||||
<div ref={(shell) => this.controller.mount(shell)} className="lc-outline-tree-container">
|
||||
<TreeView key={tree.id} tree={tree} pluginContext={this.props.pluginContext} />
|
||||
{ !this.props.hideFilter && <Filter tree={tree} /> }
|
||||
<div ref={(shell) => this.controller.mount(shell)} className={`lc-outline-tree-container ${ this.props.hideFilter ? 'lc-hidden-outline-filter' : '' }`}>
|
||||
<TreeView key={tree.id} tree={tree} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -14,10 +14,14 @@
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
> .lc-outline-tree-container.lc-hidden-outline-filter {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
> .lc-outline-filter {
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
justify-content: right;
|
||||
|
||||
.lc-outline-filter-search-input {
|
||||
@ -27,7 +31,6 @@
|
||||
.lc-outline-filter-icon {
|
||||
background: #ebecf0;
|
||||
border: 1px solid #c4c6cf;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0 2px 2px 0;
|
||||
|
||||
@ -2,12 +2,11 @@ import { PureComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import TreeNode from '../controllers/tree-node';
|
||||
import TreeNodeView from './tree-node';
|
||||
import { IPublicModelPluginContext, IPublicModelExclusiveGroup, IPublicTypeDisposable, IPublicTypeLocationChildrenDetail } from '@alilc/lowcode-types';
|
||||
import { IPublicModelExclusiveGroup, IPublicTypeDisposable, IPublicTypeLocationChildrenDetail } from '@alilc/lowcode-types';
|
||||
|
||||
export default class TreeBranches extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
isModal?: boolean;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
expanded: boolean;
|
||||
treeChildren: TreeNode[] | null;
|
||||
}> {
|
||||
@ -51,12 +50,11 @@ export default class TreeBranches extends PureComponent<{
|
||||
return (
|
||||
<div className="tree-node-branches">
|
||||
{
|
||||
!isModal && <TreeNodeSlots treeNode={treeNode} pluginContext={this.props.pluginContext} />
|
||||
!isModal && <TreeNodeSlots treeNode={treeNode} />
|
||||
}
|
||||
<TreeNodeChildren
|
||||
treeNode={treeNode}
|
||||
isModal={isModal || false}
|
||||
pluginContext={this.props.pluginContext}
|
||||
treeChildren={this.props.treeChildren}
|
||||
/>
|
||||
</div>
|
||||
@ -73,7 +71,6 @@ interface ITreeNodeChildrenState {
|
||||
class TreeNodeChildren extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
isModal?: boolean;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
treeChildren: TreeNode[] | null;
|
||||
}, ITreeNodeChildrenState> {
|
||||
state: ITreeNodeChildrenState = {
|
||||
@ -84,8 +81,8 @@ class TreeNodeChildren extends PureComponent<{
|
||||
};
|
||||
offLocationChanged: IPublicTypeDisposable | undefined;
|
||||
componentDidMount() {
|
||||
const { treeNode, pluginContext } = this.props;
|
||||
const { project } = pluginContext;
|
||||
const { treeNode } = this.props;
|
||||
const { project } = treeNode.pluginContext;
|
||||
const { filterWorking, matchSelf, keywords } = treeNode.filterReult;
|
||||
const { dropDetail } = treeNode;
|
||||
this.setState({
|
||||
@ -122,13 +119,14 @@ class TreeNodeChildren extends PureComponent<{
|
||||
let groupContents: any[] = [];
|
||||
let currentGrp: IPublicModelExclusiveGroup;
|
||||
const { filterWorking, matchSelf, keywords } = this.state;
|
||||
const Title = this.props.pluginContext.common.editorCabin.Title;
|
||||
const Title = this.props.treeNode.pluginContext.common.editorCabin.Title;
|
||||
|
||||
const endGroup = () => {
|
||||
if (groupContents.length > 0) {
|
||||
children.push(
|
||||
<div key={currentGrp.id} className="condition-group-container" data-id={currentGrp.firstNode?.id}>
|
||||
<div className="condition-group-title">
|
||||
{/* @ts-ignore */}
|
||||
<Title
|
||||
title={currentGrp.title}
|
||||
match={filterWorking && matchSelf}
|
||||
@ -171,12 +169,12 @@ class TreeNodeChildren extends PureComponent<{
|
||||
children.push(insertion);
|
||||
}
|
||||
}
|
||||
groupContents.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} pluginContext={this.props.pluginContext} />);
|
||||
groupContents.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} />);
|
||||
} else {
|
||||
if (index === dropIndex) {
|
||||
children.push(insertion);
|
||||
}
|
||||
children.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} pluginContext={this.props.pluginContext} />);
|
||||
children.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} />);
|
||||
}
|
||||
});
|
||||
endGroup();
|
||||
@ -191,14 +189,13 @@ class TreeNodeChildren extends PureComponent<{
|
||||
|
||||
class TreeNodeSlots extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
}> {
|
||||
render() {
|
||||
const { treeNode } = this.props;
|
||||
if (!treeNode.hasSlots()) {
|
||||
return null;
|
||||
}
|
||||
const Title = this.props.pluginContext.common.editorCabin.Title;
|
||||
const Title = this.props.treeNode.pluginContext.common.editorCabin.Title;
|
||||
return (
|
||||
<div
|
||||
className={classNames('tree-node-slots', {
|
||||
@ -207,10 +204,11 @@ class TreeNodeSlots extends PureComponent<{
|
||||
data-id={treeNode.id}
|
||||
>
|
||||
<div className="tree-node-slots-title">
|
||||
<Title title={{ type: 'i18n', intl: this.props.pluginContext.intlNode('Slots') }} />
|
||||
{/* @ts-ignore */}
|
||||
<Title title={{ type: 'i18n', intl: this.props.treeNode.pluginContext.intlNode('Slots') }} />
|
||||
</div>
|
||||
{treeNode.slots.map(tnode => (
|
||||
<TreeNodeView key={tnode.id} treeNode={tnode} pluginContext={this.props.pluginContext} />
|
||||
<TreeNodeView key={tnode.id} treeNode={tnode} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -4,34 +4,56 @@ import TreeNode from '../controllers/tree-node';
|
||||
import TreeTitle from './tree-title';
|
||||
import TreeBranches from './tree-branches';
|
||||
import { IconEyeClose } from '../icons/eye-close';
|
||||
import { IPublicModelPluginContext, IPublicModelModalNodesManager, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||
import { IPublicModelModalNodesManager, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||
import { IOutlinePanelPluginContext } from '../controllers/tree-master';
|
||||
|
||||
class ModalTreeNodeView extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
}, {
|
||||
treeChildren: TreeNode[] | null;
|
||||
}> {
|
||||
private modalNodesManager: IPublicModelModalNodesManager | undefined | null;
|
||||
readonly pluginContext: IPublicModelPluginContext;
|
||||
readonly pluginContext: IOutlinePanelPluginContext;
|
||||
|
||||
constructor(props: any) {
|
||||
constructor(props: {
|
||||
treeNode: TreeNode;
|
||||
}) {
|
||||
super(props);
|
||||
|
||||
// 模态管理对象
|
||||
this.pluginContext = props.pluginContext;
|
||||
this.pluginContext = props.treeNode.pluginContext;
|
||||
const { project } = this.pluginContext;
|
||||
this.modalNodesManager = project.currentDocument?.modalNodesManager;
|
||||
this.state = {
|
||||
treeChildren: this.rootTreeNode.children,
|
||||
};
|
||||
}
|
||||
|
||||
hideAllNodes() {
|
||||
this.modalNodesManager?.hideModalNodes();
|
||||
}
|
||||
|
||||
render() {
|
||||
componentDidMount(): void {
|
||||
const rootTreeNode = this.rootTreeNode;
|
||||
rootTreeNode.onExpandableChanged(() => {
|
||||
this.setState({
|
||||
treeChildren: rootTreeNode.children,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
get rootTreeNode() {
|
||||
const { treeNode } = this.props;
|
||||
// 当指定了新的根节点时,要从原始的根节点去获取模态节点
|
||||
const { project } = this.pluginContext;
|
||||
const rootNode = project.currentDocument?.root;
|
||||
const rootTreeNode = treeNode.tree.getTreeNode(rootNode!);
|
||||
|
||||
return rootTreeNode;
|
||||
}
|
||||
|
||||
render() {
|
||||
const rootTreeNode = this.rootTreeNode;
|
||||
const { expanded } = rootTreeNode;
|
||||
|
||||
const hasVisibleModalNode = !!this.modalNodesManager?.getVisibleModalNode();
|
||||
@ -49,10 +71,9 @@ class ModalTreeNodeView extends PureComponent<{
|
||||
<div className="tree-pane-modal-content">
|
||||
<TreeBranches
|
||||
treeNode={rootTreeNode}
|
||||
treeChildren={rootTreeNode.children}
|
||||
treeChildren={this.state.treeChildren}
|
||||
expanded={expanded}
|
||||
isModal
|
||||
pluginContext={this.pluginContext}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -63,7 +84,6 @@ class ModalTreeNodeView extends PureComponent<{
|
||||
export default class TreeNodeView extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
isModal?: boolean;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
isRootNode?: boolean;
|
||||
}> {
|
||||
state: {
|
||||
@ -114,8 +134,8 @@ export default class TreeNodeView extends PureComponent<{
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { treeNode, pluginContext } = this.props;
|
||||
const { project } = pluginContext;
|
||||
const { treeNode } = this.props;
|
||||
const { project } = treeNode.pluginContext;
|
||||
|
||||
const doc = project.currentDocument;
|
||||
|
||||
@ -158,14 +178,14 @@ export default class TreeNodeView extends PureComponent<{
|
||||
}
|
||||
|
||||
shouldShowModalTreeNode(): boolean {
|
||||
const { treeNode, isRootNode, pluginContext } = this.props;
|
||||
const { treeNode, isRootNode } = this.props;
|
||||
if (!isRootNode) {
|
||||
// 只在 当前树 的根节点展示模态节点
|
||||
return false;
|
||||
}
|
||||
|
||||
// 当指定了新的根节点时,要从原始的根节点去获取模态节点
|
||||
const { project } = pluginContext;
|
||||
const { project } = treeNode.pluginContext;
|
||||
const rootNode = project.currentDocument?.root;
|
||||
const rootTreeNode = treeNode.tree.getTreeNode(rootNode!);
|
||||
const modalNodes = rootTreeNode.children?.filter((item) => {
|
||||
@ -214,19 +234,16 @@ export default class TreeNodeView extends PureComponent<{
|
||||
hidden={this.state.hidden}
|
||||
locked={this.state.locked}
|
||||
expandable={this.state.expandable}
|
||||
pluginContext={this.props.pluginContext}
|
||||
/>
|
||||
{shouldShowModalTreeNode &&
|
||||
<ModalTreeNodeView
|
||||
treeNode={treeNode}
|
||||
pluginContext={this.props.pluginContext}
|
||||
/>
|
||||
}
|
||||
<TreeBranches
|
||||
treeNode={treeNode}
|
||||
isModal={false}
|
||||
expanded={this.state.expanded}
|
||||
pluginContext={this.props.pluginContext}
|
||||
treeChildren={this.state.treeChildren}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { KeyboardEvent, FocusEvent, Fragment, PureComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { createIcon } from '@alilc/lowcode-utils';
|
||||
import { IPublicModelPluginContext, IPublicApiEvent } from '@alilc/lowcode-types';
|
||||
import { IPublicApiEvent } from '@alilc/lowcode-types';
|
||||
import TreeNode from '../controllers/tree-node';
|
||||
import { IconLock, IconUnlock, IconArrowRight, IconEyeClose, IconEye, IconCond, IconLoop, IconRadioActive, IconRadio, IconSetting } from '../icons';
|
||||
|
||||
@ -23,11 +23,12 @@ export default class TreeTitle extends PureComponent<{
|
||||
hidden: boolean;
|
||||
locked: boolean;
|
||||
expandable: boolean;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
}> {
|
||||
state: {
|
||||
editing: boolean;
|
||||
title: string;
|
||||
condition?: boolean;
|
||||
visible?: boolean;
|
||||
} = {
|
||||
editing: false,
|
||||
title: '',
|
||||
@ -53,7 +54,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
const { treeNode } = this.props;
|
||||
const value = (e.target as HTMLInputElement).value || '';
|
||||
treeNode.setTitleLabel(value);
|
||||
emitOutlineEvent(this.props.pluginContext.event, 'rename', treeNode, { value });
|
||||
emitOutlineEvent(this.props.treeNode.pluginContext.event, 'rename', treeNode, { value });
|
||||
this.cancelEdit();
|
||||
};
|
||||
|
||||
@ -81,16 +82,28 @@ export default class TreeTitle extends PureComponent<{
|
||||
this.setState({
|
||||
editing: false,
|
||||
title: treeNode.titleLabel,
|
||||
condition: treeNode.condition,
|
||||
});
|
||||
treeNode.onTitleLabelChanged(() => {
|
||||
this.setState({
|
||||
title: treeNode.titleLabel,
|
||||
});
|
||||
});
|
||||
treeNode.onConditionChanged(() => {
|
||||
this.setState({
|
||||
condition: treeNode.condition,
|
||||
});
|
||||
});
|
||||
treeNode.onHiddenChanged((hidden: boolean) => {
|
||||
this.setState({
|
||||
visible: !hidden,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode, isModal, pluginContext } = this.props;
|
||||
const { treeNode, isModal } = this.props;
|
||||
const { pluginContext } = treeNode;
|
||||
const { editing } = this.state;
|
||||
const isCNode = !treeNode.isRoot();
|
||||
const { node } = treeNode;
|
||||
@ -125,7 +138,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
data-id={treeNode.id}
|
||||
onClick={() => {
|
||||
if (isModal) {
|
||||
if (node.visible) {
|
||||
if (this.state.visible) {
|
||||
node.document?.modalNodesManager?.setInvisible(node);
|
||||
} else {
|
||||
node.document?.modalNodesManager?.setVisible(node);
|
||||
@ -137,7 +150,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isModal && node.visible && (
|
||||
{isModal && this.state.visible && (
|
||||
<div onClick={() => {
|
||||
node.document?.modalNodesManager?.setInvisible(node);
|
||||
}}
|
||||
@ -145,7 +158,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
<IconRadioActive className="tree-node-modal-radio-active" />
|
||||
</div>
|
||||
)}
|
||||
{isModal && !node.visible && (
|
||||
{isModal && !this.state.visible && (
|
||||
<div onClick={() => {
|
||||
node.document?.modalNodesManager?.setVisible(node);
|
||||
}}
|
||||
@ -153,7 +166,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
<IconRadio className="tree-node-modal-radio" />
|
||||
</div>
|
||||
)}
|
||||
{isCNode && <ExpandBtn expandable={this.props.expandable} expanded={this.props.expanded} treeNode={treeNode} pluginContext={this.props.pluginContext} />}
|
||||
{isCNode && <ExpandBtn expandable={this.props.expandable} expanded={this.props.expanded} treeNode={treeNode} />}
|
||||
<div className="tree-node-icon">{createIcon(treeNode.icon)}</div>
|
||||
<div className="tree-node-title-label">
|
||||
{editing ? (
|
||||
@ -166,6 +179,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
/>
|
||||
) : (
|
||||
<Fragment>
|
||||
{/* @ts-ignore */}
|
||||
<Title
|
||||
title={this.state.title}
|
||||
match={filterWorking && matchSelf}
|
||||
@ -175,6 +189,7 @@ export default class TreeTitle extends PureComponent<{
|
||||
{node.slotFor && (
|
||||
<a className="tree-node-tag slot">
|
||||
{/* todo: click redirect to prop */}
|
||||
{/* @ts-ignore */}
|
||||
<Tip>{intlNode('Slot for {prop}', { prop: node.slotFor.key })}</Tip>
|
||||
</a>
|
||||
)}
|
||||
@ -182,22 +197,24 @@ export default class TreeTitle extends PureComponent<{
|
||||
<a className="tree-node-tag loop">
|
||||
{/* todo: click todo something */}
|
||||
<IconLoop />
|
||||
{/* @ts-ignore */}
|
||||
<Tip>{intlNode('Loop')}</Tip>
|
||||
</a>
|
||||
)}
|
||||
{node.hasCondition() && !node.conditionGroup && (
|
||||
{this.state.condition && (
|
||||
<a className="tree-node-tag cond">
|
||||
{/* todo: click todo something */}
|
||||
<IconCond />
|
||||
{/* @ts-ignore */}
|
||||
<Tip>{intlNode('Conditional')}</Tip>
|
||||
</a>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
{shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} pluginContext={this.props.pluginContext} />}
|
||||
{shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} pluginContext={this.props.pluginContext} />}
|
||||
{shouldEditBtn && <RenameBtn treeNode={treeNode} pluginContext={this.props.pluginContext} onClick={this.enableEdit} /> }
|
||||
{shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} />}
|
||||
{shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} />}
|
||||
{shouldEditBtn && <RenameBtn treeNode={treeNode} onClick={this.enableEdit} /> }
|
||||
|
||||
</div>
|
||||
);
|
||||
@ -206,11 +223,10 @@ export default class TreeTitle extends PureComponent<{
|
||||
|
||||
class RenameBtn extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
onClick: (e: any) => void;
|
||||
}> {
|
||||
render() {
|
||||
const { intl, common } = this.props.pluginContext;
|
||||
const { intl, common } = this.props.treeNode.pluginContext;
|
||||
const Tip = common.editorCabin.Tip;
|
||||
return (
|
||||
<div
|
||||
@ -218,6 +234,7 @@ class RenameBtn extends PureComponent<{
|
||||
onClick={this.props.onClick}
|
||||
>
|
||||
<IconSetting />
|
||||
{/* @ts-ignore */}
|
||||
<Tip>{intl('Rename')}</Tip>
|
||||
</div>
|
||||
);
|
||||
@ -226,12 +243,11 @@ class RenameBtn extends PureComponent<{
|
||||
|
||||
class LockBtn extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
locked: boolean;
|
||||
}> {
|
||||
render() {
|
||||
const { treeNode, locked } = this.props;
|
||||
const { intl, common } = this.props.pluginContext;
|
||||
const { intl, common } = this.props.treeNode.pluginContext;
|
||||
const Tip = common.editorCabin.Tip;
|
||||
return (
|
||||
<div
|
||||
@ -242,6 +258,7 @@ class LockBtn extends PureComponent<{
|
||||
}}
|
||||
>
|
||||
{locked ? <IconUnlock /> : <IconLock /> }
|
||||
{/* @ts-ignore */}
|
||||
<Tip>{locked ? intl('Unlock') : intl('Lock')}</Tip>
|
||||
</div>
|
||||
);
|
||||
@ -251,24 +268,24 @@ class LockBtn extends PureComponent<{
|
||||
class HideBtn extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
hidden: boolean;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
}, {
|
||||
hidden: boolean;
|
||||
}> {
|
||||
render() {
|
||||
const { treeNode, hidden } = this.props;
|
||||
const { intl, common } = this.props.pluginContext;
|
||||
const { intl, common } = treeNode.pluginContext;
|
||||
const Tip = common.editorCabin.Tip;
|
||||
return (
|
||||
<div
|
||||
className="tree-node-hide-btn"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
emitOutlineEvent(this.props.pluginContext.event, hidden ? 'show' : 'hide', treeNode);
|
||||
emitOutlineEvent(treeNode.pluginContext.event, hidden ? 'show' : 'hide', treeNode);
|
||||
treeNode.setHidden(!hidden);
|
||||
}}
|
||||
>
|
||||
{hidden ? <IconEye /> : <IconEyeClose />}
|
||||
{/* @ts-ignore */}
|
||||
<Tip>{hidden ? intl('Show') : intl('Hide')}</Tip>
|
||||
</div>
|
||||
);
|
||||
@ -277,7 +294,6 @@ class HideBtn extends PureComponent<{
|
||||
|
||||
class ExpandBtn extends PureComponent<{
|
||||
treeNode: TreeNode;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
expanded: boolean;
|
||||
expandable: boolean;
|
||||
}> {
|
||||
@ -294,7 +310,7 @@ class ExpandBtn extends PureComponent<{
|
||||
if (expanded) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
emitOutlineEvent(this.props.pluginContext.event, expanded ? 'collapse' : 'expand', treeNode);
|
||||
emitOutlineEvent(treeNode.pluginContext.event, expanded ? 'collapse' : 'expand', treeNode);
|
||||
treeNode.setExpanded(!expanded);
|
||||
}}
|
||||
>
|
||||
|
||||
@ -2,7 +2,7 @@ import { MouseEvent as ReactMouseEvent, PureComponent } from 'react';
|
||||
import { isFormEvent, canClickNode, isShaken } from '@alilc/lowcode-utils';
|
||||
import { Tree } from '../controllers/tree';
|
||||
import TreeNodeView from './tree-node';
|
||||
import { IPublicEnumDragObjectType, IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types';
|
||||
import { IPublicEnumDragObjectType, IPublicModelNode } from '@alilc/lowcode-types';
|
||||
import TreeNode from '../controllers/tree-node';
|
||||
|
||||
function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string {
|
||||
@ -20,12 +20,21 @@ function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string
|
||||
|
||||
export default class TreeView extends PureComponent<{
|
||||
tree: Tree;
|
||||
pluginContext: IPublicModelPluginContext;
|
||||
}> {
|
||||
private shell: HTMLDivElement | null = null;
|
||||
|
||||
private ignoreUpSelected = false;
|
||||
|
||||
private boostEvent?: MouseEvent;
|
||||
|
||||
state: {
|
||||
root: TreeNode | null;
|
||||
} = {
|
||||
root: null,
|
||||
};
|
||||
|
||||
private hover(e: ReactMouseEvent) {
|
||||
const { project } = this.props.pluginContext;
|
||||
const { project } = this.props.tree.pluginContext;
|
||||
const detecting = project.currentDocument?.detecting;
|
||||
if (detecting?.enable) {
|
||||
return;
|
||||
@ -54,7 +63,7 @@ export default class TreeView extends PureComponent<{
|
||||
return;
|
||||
}
|
||||
|
||||
const { project, event, canvas } = this.props.pluginContext;
|
||||
const { project, event, canvas } = this.props.tree.pluginContext;
|
||||
const doc = project.currentDocument;
|
||||
const selection = doc?.selection;
|
||||
const focusNode = doc?.focusNode;
|
||||
@ -109,10 +118,6 @@ export default class TreeView extends PureComponent<{
|
||||
return tree.getTreeNodeById(id);
|
||||
}
|
||||
|
||||
private ignoreUpSelected = false;
|
||||
|
||||
private boostEvent?: MouseEvent;
|
||||
|
||||
private onMouseDown = (e: ReactMouseEvent) => {
|
||||
if (isFormEvent(e.nativeEvent)) {
|
||||
return;
|
||||
@ -127,7 +132,7 @@ export default class TreeView extends PureComponent<{
|
||||
if (!canClickNode(node, e)) {
|
||||
return;
|
||||
}
|
||||
const { project, canvas } = this.props.pluginContext;
|
||||
const { project, canvas } = this.props.tree.pluginContext;
|
||||
const selection = project.currentDocument?.selection;
|
||||
const focusNode = project.currentDocument?.focusNode;
|
||||
|
||||
@ -166,22 +171,16 @@ export default class TreeView extends PureComponent<{
|
||||
};
|
||||
|
||||
private onMouseLeave = () => {
|
||||
const { pluginContext } = this.props;
|
||||
const { pluginContext } = this.props.tree;
|
||||
const { project } = pluginContext;
|
||||
const doc = project.currentDocument;
|
||||
doc?.detecting.leave();
|
||||
};
|
||||
|
||||
state: {
|
||||
root: TreeNode | null
|
||||
} = {
|
||||
root: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { tree, pluginContext } = this.props;
|
||||
const { tree } = this.props;
|
||||
const { root } = tree;
|
||||
const { project } = pluginContext;
|
||||
const { project } = tree.pluginContext;
|
||||
this.setState({ root });
|
||||
const doc = project.currentDocument;
|
||||
doc?.onFocusNodeChanged(() => {
|
||||
@ -208,7 +207,6 @@ export default class TreeView extends PureComponent<{
|
||||
<TreeNodeView
|
||||
key={this.state.root?.id}
|
||||
treeNode={this.state.root}
|
||||
pluginContext={this.props.pluginContext}
|
||||
isRootNode
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-rax-renderer",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "Rax renderer for Ali lowCode engine",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -30,8 +30,8 @@
|
||||
"build": "build-scripts build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alilc/lowcode-renderer-core": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-renderer-core": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"rax-find-dom-node": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"plugins": ["build-plugin-component", "./build.plugin.js"]
|
||||
"plugins": ["@alilc/build-plugin-lce", "./build.plugin.js"]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-rax-simulator-renderer",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "rax simulator renderer for alibaba lowcode designer",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -9,14 +9,14 @@
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --skip-demo",
|
||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build",
|
||||
"build:umd": "build-scripts build --config build.umd.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alilc/lowcode-designer": "1.1.6",
|
||||
"@alilc/lowcode-rax-renderer": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-designer": "1.1.7",
|
||||
"@alilc/lowcode-rax-renderer": "1.1.7",
|
||||
"@alilc/lowcode-types": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"classnames": "^2.2.6",
|
||||
"driver-universal": "^3.1.3",
|
||||
"history": "^5.0.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"build-plugin-fusion",
|
||||
["build-plugin-moment-locales", {
|
||||
"locales": ["zh-cn"]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-react-renderer",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "react renderer for ali lowcode engine",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -12,7 +12,7 @@
|
||||
"scripts": {
|
||||
"test": "build-scripts test --config build.test.json",
|
||||
"start": "build-scripts start",
|
||||
"build": "build-scripts build --skip-demo",
|
||||
"build": "build-scripts build",
|
||||
"build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json"
|
||||
},
|
||||
"keywords": [
|
||||
@ -22,7 +22,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@alifd/next": "^1.21.16",
|
||||
"@alilc/lowcode-renderer-core": "1.1.6"
|
||||
"@alilc/lowcode-renderer-core": "1.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alib/build-scripts": "^0.1.18",
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"plugins": ["build-plugin-component", "./build.plugin.js"]
|
||||
"plugins": ["@alilc/build-plugin-lce", "./build.plugin.js"]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@alilc/lowcode-react-simulator-renderer",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"description": "react simulator renderer for alibaba lowcode designer",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -12,15 +12,15 @@
|
||||
],
|
||||
"scripts": {
|
||||
"test": "build-scripts test --config build.test.json",
|
||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --skip-demo",
|
||||
"build": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build",
|
||||
"build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json",
|
||||
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alilc/lowcode-designer": "1.1.6",
|
||||
"@alilc/lowcode-react-renderer": "1.1.6",
|
||||
"@alilc/lowcode-types": "1.1.6",
|
||||
"@alilc/lowcode-utils": "1.1.6",
|
||||
"@alilc/lowcode-designer": "1.1.7",
|
||||
"@alilc/lowcode-react-renderer": "1.1.7",
|
||||
"@alilc/lowcode-types": "1.1.7",
|
||||
"@alilc/lowcode-utils": "1.1.7",
|
||||
"classnames": "^2.2.6",
|
||||
"mobx": "^6.3.0",
|
||||
"mobx-react": "^7.2.0",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
[
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
{
|
||||
"babelPlugins": ["@babel/plugin-transform-typescript"]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"build-plugin-component",
|
||||
"@alilc/build-plugin-lce",
|
||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
||||
]
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user