Compare commits

...

14 Commits

Author SHA1 Message Date
JackLian
7263758224 chore(release): publish 1.1.0-beta.6 2022-12-14 16:34:40 +08:00
JackLian
af99e92227 chore(release): publish 1.1.0-beta.5 2022-12-14 16:32:34 +08:00
JackLian
a885cd2a53 chore(release): publish 1.1.0-beta.4 2022-12-14 16:29:44 +08:00
liujuping
79812a6fc2 fix: conflict 2022-12-14 16:27:25 +08:00
JackLian
bddaa537e1 feat: add types for shell/plugins and logger 2022-12-14 16:27:19 +08:00
JackLian
5e96db046e docs: some minor doc optimizations 2022-12-14 16:26:32 +08:00
liujuping
4f3b0e9883 feat: fix conflict 2022-12-14 16:26:31 +08:00
JackLian
6bb6a2c308 chore(release): publish 1.1.0-beta.3 2022-12-13 20:44:51 +08:00
liujuping
c4bb6c4e76 fix: 修复globalContext 未定义的问题 2022-12-13 20:42:16 +08:00
JackLian
734b4f305e chore(release): publish 1.1.0-beta.2 2022-12-13 20:02:06 +08:00
JackLian
5fa7d6298a feat: merge from develop 2022-12-13 19:59:23 +08:00
JackLian
94e8a0e585 chore(release): publish 1.1.0-beta.1 2022-12-13 18:38:49 +08:00
JackLian
6130212e6a chore: update versions 2022-12-13 18:38:17 +08:00
JackLian
f0e60bb9f8 feat: support workspace 2022-12-13 18:29:01 +08:00
138 changed files with 3676 additions and 821 deletions

View File

@ -3,9 +3,39 @@ title: API 总览
sidebar_position: 0
---
引擎直接提供 9 大类 API以及若干间接的 API具体如下图
引擎提供的公开 API 分为`命名空间``模型`两类,其中`命名空间`用于聚合一大类的 API`模型`为各 API 涉及到的对象模型。
### 命名空间
引擎直接提供以下几大类 API
- skeleton 面板 API
- material 物料 API
- project 模型 API
- simulator-host 模拟器 API
- hotkey 快捷键 API
- setters 设置器 API
- event 事件 API
- config 配置 API
- common 通用 API
- logger 日志 API
- init 初始化 API
### 模型
以下模型通过前面的 API 以返回值等形式间接透出。
- document-model 文档
- node 节点
- node-children 节点孩子
- props 属性集
- prop 属性
- setting-prop-entry 设置属性
- setting-top-entry 设置属性集
- component-meta 物料元数据
- selection 画布选中
- detecting 画布 hover
- history 操作历史
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01ZA2RMv1nYlWf6ThGf_!!6000000005102-2-tps-1278-1390.png)
### API 设计约定
一些 API 设计约定:

View File

@ -30,7 +30,8 @@ material.setAssets(assets);
通过物料中心接口动态引入资产包
```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine'
import { material, plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
// 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => {

View File

@ -26,6 +26,7 @@ pluginConfigCreator 是一个 ILowCodePluginConfig 生成函数ILowCodePlugin
#### 简单示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const builtinPluginRegistry = (ctx: ILowCodePluginContext) => {
return {
@ -58,6 +59,7 @@ await plugins.register(builtinPluginRegistry);
#### 使用 exports 示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const pluginA = (ctx: ILowCodePluginContext) => {
return {
@ -89,6 +91,7 @@ await plugins.register(pluginB);
#### 设置兼容引擎版本示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const builtinPluginRegistry = (ctx: ILowCodePluginContext) => {
return {
@ -108,6 +111,7 @@ await plugins.register(builtinPluginRegistry);
#### 设置插件参数版本示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const builtinPluginRegistry = (ctx: ILowCodePluginContext, options: any) => {
return {
@ -223,16 +227,16 @@ plugins.delete('builtinPluginRegistry');
**类型定义**
```typescript
export interface ILowCodePluginContext {
skeleton: Skeleton; // 参考面板 API
hotkey: Hotkey; // 参考快捷键 API
setters: Setters; // 参考设置器 API
config: EngineConfig; // 参考配置 API
material: Material; // 参考物料 API
event: Event; // 参考事件 API
project: Project; // 参考模型 API
common: Common; // 参考模型 API
logger: Logger; // 参考日志 API
plugins: ILowCodePluginManager; // 即本文档描述内容
get skeleton(): IPublicApiSkeleton;
get hotkey(): IPublicApiHotkey;
get setters(): IPublicApiSetters;
get config(): IEngineConfig;
get material(): IPublicApiMaterial;
get event(): IPublicApiEvent;
get project(): IPublicApiProject;
get common(): IPublicApiCommon;
logger: IPublicApiLogger;
plugins: IPublicApiPlugins;
preference: IPluginPreferenceMananger;
}
```

View File

@ -79,8 +79,8 @@ addPropsTransducer(transducer: PropsTransducer, stage: TransformStage)
**示例 1在保存的时候删除每一个组件的 props.hidden**
```typescript
import { ILowCodePluginContext, project } from '@alilc/lowcode-engine';
import { CompositeObject, TransformStage } from '@alilc/lowcode-types';
import { project } from '@alilc/lowcode-engine';
import { CompositeObject, TransformStage, ILowCodePluginContext } from '@alilc/lowcode-types';
export const deleteHiddenTransducer = (ctx: ILowCodePluginContext) => {
return {

View File

@ -38,6 +38,7 @@ function registerSetter(
```typescript
import { setters, skeleton } from '@alilc/lowcode-engine';
import { setterMap, pluginMap } from '@alilc/lowcode-engine-ext';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const setterRegistry = (ctx: ILowCodePluginContext) => {
return {
@ -209,6 +210,7 @@ function registerSetter(
```typescript
import { setters, skeleton } from '@alilc/lowcode-engine';
import { setterMap, pluginMap } from '@alilc/lowcode-engine-ext';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const setterRegistry = (ctx: ILowCodePluginContext) => {
return {

View File

@ -1,7 +1,8 @@
---
title: DataSource - 数据源 API
sidebar_position: 12
title: demo 使用相关 API
sidebar_position: 2
---
## 数据源相关
### 请求数据源
```javascript
// 请求 userListuserList 在数据源面板中定义)

View File

@ -3,4 +3,4 @@ title: 如何通过 API 手动调用数据源请求
sidebar_position: 6
tags: [FAQ]
---
参考:[DataSource API](/site/docs/api/datasource)
参考:[DataSource API](/site/docs/demoUsage/appendix/api)

View File

@ -1,4 +1,6 @@
{
"label": "扩展低代码编辑器",
"position": 1
"label": "扩展编辑态",
"position": 1,
"collapsed": false,
"collapsible": true
}

View File

@ -130,6 +130,7 @@ npm publish
2. 在引擎初始化侧引入插件
```typescript
import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
export default async () => {
// 注意 Inject 插件必须在其他插件前注册,且所有插件的注册必须 await

View File

@ -270,7 +270,8 @@ npm publish
### 在项目中引入资产包
```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine';
import { material, plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
// 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => {

View File

@ -10,6 +10,7 @@ sidebar_position: 6
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
import { Icon, Message } from '@alifd/next';
const addHelloAction = (ctx: ILowCodePluginContext) => {
@ -46,6 +47,7 @@ await plugins.register(addHelloAction);
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const removeCopyAction = (ctx: ILowCodePluginContext) => {
return {

View File

@ -17,7 +17,8 @@ sidebar_position: 5
## 注册插件 API
```typescript
import { plugins, ILowCodePluginContext } from '@alilc/lowcode-engine';
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const pluginA = (ctx: ILowCodePluginContext, options: any) => {
return {

View File

@ -1,5 +1,5 @@
---
title: 低代码扩展简述
title: 编辑态扩展简述
sidebar_position: 0
---
## 扩展点简述
@ -34,7 +34,8 @@ material.setAssets(assets);
也可以通过异步加载物料中心上的物料。
```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine';
import { material, plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
// 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => {
@ -57,7 +58,8 @@ plugins.register((ctx: ILowCodePluginContext) => {
### 配置插件
可以通过 npm 包的方式引入社区插件,配置如下所示:
```typescript
import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine';
import { plugins } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker';
// 注册一个提 issue 组件到您的编辑器中,方位默认在左栏下侧

View File

@ -1,4 +1,6 @@
{
"label": "扩展低代码运行时",
"position": 2
"label": "扩展运行时",
"position": 2,
"collapsed": false,
"collapsible": true
}

View File

@ -125,7 +125,7 @@ Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8
可以在 demo/sample-plugins 直接新增插件,这里我新增的插件目录是 plugin-demo。并且新增了 index.tsx 文件,将下面的代码粘贴到 index.tsx 中。
```javascript
import * as React from 'react';
import { ILowCodePluginContext } from '@alilc/lowcode-engine';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
const LowcodePluginPluginDemo = (ctx: ILowCodePluginContext) => {
return {

View File

@ -9,6 +9,7 @@ sidebar_position: 3
<!-- engine-ext 引擎的扩展包,负责收拢内置 setters / plugins方便迭代 -->
<script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@1.0.1/dist/js/engine-ext.js"></script>
```
> 注,这里的版本号是示例,请尽量选用最新版
工程化配置我们进行了统一,具体如下:
```shell
@ -22,7 +23,6 @@ sidebar_position: 3
"react": "var window.React",
"react-dom": "var window.ReactDOM",
"prop-types": "var window.PropTypes",
"rax": "var window.Rax",
"@alilc/lowcode-engine": "var window.AliLowCodeEngine",
"@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
"moment": "var moment",
@ -39,7 +39,7 @@ sidebar_position: 3
["build-plugin-fusion", {
}],
["build-plugin-moment-locales", {
"locales": ["zh-cn"]
"locales": ["zh-CN"]
}],
"./build.plugin.js"
]

View File

@ -19,7 +19,8 @@ sidebar_position: 2
几点要求:
1. commit message 格式遵循 [ConvensionalCommits](https://www.conventionalcommits.org/en/v1.0.0/#summary)
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01M9UzVM1iqYpyxECdV_!!6000000004464-2-tps-2070-594.png)
<img src="https://img.alicdn.com/imgextra/i3/O1CN01M9UzVM1iqYpyxECdV_!!6000000004464-2-tps-2070-594.png" width="700"/>
2. 请按照一个 bugfix / feature 对应一个 commit假如不是请 rebase 后再提交 MR不要一堆无用的、试验性的 commit。
好处:从引擎的整体 commit 历史来看,会很清晰,**每个 commit 完成一件确定的事changelog 也能自动生成**。另外,假如因为某个 commit 导致了 bug也很容易通过 rebase drop 等方式快速修复。
@ -42,7 +43,7 @@ sidebar_position: 2
> 此处是理想节奏,实际情况可能会有调整
- 日常迭代 2 周,一般月中或月底
- 日常迭代 2 周,一般月中或月底,发版日两天前发最后一个 beta 版本,原则上不接受新 pr灰度 2 天后,发正式版。
- 特殊情况紧急迭代随时发
- 大 Feature 迭代,每年 2 - 4 次
@ -79,7 +80,34 @@ sidebar_position: 2
如果是发布 beta 版本,步骤如下(以发布 1.0.1 版本为例):
#### 发某版本首个 beta如 1.0.1-beta.0
#### 发某 y 位版本首个 beta如 1.1.0-beta.0
1. 拉 develop 分支
```bash
git checkout develop
```
更新到最新(如需)
```bash
git pull
```
2. 拉 release 分支,此处以 1.1.0 版本做示例
```bash
git checkout -b release/1.1.0-beta
git push --set-upstream origin release/1.1.0-beta
```
3. build
```bash
npm run build
```
4. 发布,此处需有 @alilc scope 发包权限
```bash
npm run pub:preminor
```
5. 同步到 tnpm 源 & alifd CDN
```bash
tnpm run sync
```
#### 发某 z 位版本首个 beta如 1.0.1-beta.0
1. 拉 develop 分支
```bash
git checkout develop

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-engine-docs",
"version": "1.0.7",
"version": "1.0.8",
"description": "低代码引擎版本化文档",
"license": "MIT",
"files": [

View File

@ -1,6 +1,6 @@
{
"lerna": "4.0.0",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [

View File

@ -34,7 +34,7 @@
"@alife/build-plugin-lowcode": "^1.0.7",
"@alib/build-scripts": "^0.1.3",
"@alifd/adaptor-generate": "^0.1.3",
"build-plugin-component": "^0.2.0",
"build-plugin-component": "^1.0.0",
"build-plugin-fusion": "^0.1.0",
"build-plugin-fusion-cool": "^0.1.0",
"build-plugin-moment-locales": "^0.1.0",

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-designer",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "Designer for Ali LowCode Engine",
"main": "lib/index.js",
"module": "es/index.js",
@ -15,9 +15,9 @@
},
"license": "MIT",
"dependencies": {
"@alilc/lowcode-editor-core": "1.0.17",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-editor-core": "1.1.0-beta.6",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"react": "^16",
"react-dom": "^16.7.0",
@ -27,10 +27,12 @@
},
"devDependencies": {
"@alib/build-scripts": "^0.1.29",
"@alilc/lowcode-shell": "1.0.17",
"@alilc/lowcode-shell": "1.1.0-beta.6",
"@alilc/lowcode-test-mate": "^1.0.1",
"@testing-library/react": "^11.2.2",
"@types/classnames": "^2.2.7",
"@types/enzyme": "^3.10.12",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/jest": "^26.0.16",
"@types/lodash": "^4.14.165",
"@types/medium-editor": "^5.0.3",
@ -42,9 +44,7 @@
"build-plugin-component": "^1.0.0",
"build-scripts-config": "^3.0.3",
"enzyme": "^3.11.0",
"@types/enzyme": "^3.10.12",
"enzyme-adapter-react-16": "^1.15.5",
"@types/enzyme-adapter-react-16": "^1.0.6",
"jest": "^26.6.3",
"lodash": "^4.17.20",
"moment": "^2.29.1",
@ -61,5 +61,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/designer"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -172,7 +172,8 @@ export class BoxResizingInstance extends Component<{
metadata.configure.advanced.callbacks.onResizeEnd(e, cbNode);
}
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||

View File

@ -131,7 +131,8 @@ function createAction(content: ReactNode | ComponentType<any> | ActionContentObj
className="lc-borders-action"
onClick={() => {
action && action(node);
const editor = globalContext.get('editor');
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||

View File

@ -22,6 +22,7 @@ export function createSimulator(
const doc = iframe.contentDocument!;
win.LCSimulatorHost = host;
win._ = window._;
const styles: any = {};
const scripts: any = {};

View File

@ -23,8 +23,8 @@ export class BuiltinSimulatorHostView extends Component<SimulatorHostProps> {
constructor(props: any) {
super(props);
const { project, onMount } = this.props;
this.host = (project.simulator as BuiltinSimulatorHost) || new BuiltinSimulatorHost(project);
const { project, onMount, designer } = this.props;
this.host = (project.simulator as BuiltinSimulatorHost) || new BuiltinSimulatorHost(project, designer);
this.host.setProps(this.props);
onMount?.(this.host);
}
@ -76,7 +76,8 @@ class Content extends Component<{ host: BuiltinSimulatorHost }> {
private dispose?: () => void;
componentDidMount() {
const editor = globalContext.get('editor');
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const onEnableEvents = (type: boolean) => {
this.setState({
disabledEvents: type,
@ -97,7 +98,7 @@ class Content extends Component<{ host: BuiltinSimulatorHost }> {
render() {
const sim = this.props.host;
const { disabledEvents } = this.state;
const { viewport } = sim;
const { viewport, designer } = sim;
const frameStyle: any = {
transform: `scale(${viewport.scale})`,
height: viewport.contentHeight,
@ -107,10 +108,12 @@ class Content extends Component<{ host: BuiltinSimulatorHost }> {
frameStyle.pointerEvents = 'none';
}
const name = designer.name;
return (
<div className="lc-simulator-content">
<iframe
name="SimulatorRenderer"
name={`${name}-SimulatorRenderer`}
className="lc-simulator-content-frame"
style={frameStyle}
ref={(frame) => sim.mountContentFrame(frame)}

View File

@ -64,7 +64,7 @@ import {
DragNodeObject,
} from '@alilc/lowcode-types';
import { BuiltinSimulatorRenderer } from './renderer';
import clipboard from '../designer/clipboard';
import { clipboard } from '../designer/clipboard';
import { LiveEditing } from './live-editing/live-editing';
import { Project } from '../project';
import { Scroller } from '../designer/scroller';
@ -192,10 +192,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
this.renderer?.enableAutoRepaintNode();
}
constructor(project: Project) {
constructor(project: Project, designer: Designer) {
makeObservable(this);
this.project = project;
this.designer = project?.designer;
this.designer = designer;
this.scroller = this.designer.createScroller(this.viewport);
this.autoRender = !engineConfig.get('disableAutoRender', false);
this.componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
@ -418,7 +418,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
this.renderer?.rerender?.();
}
async mountContentFrame(iframe: HTMLIFrameElement | null) {
async mountContentFrame(iframe: HTMLIFrameElement | null): Promise<void> {
if (!iframe || this._iframe === iframe) {
return;
}
@ -478,6 +478,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
this.setupEvents();
// bind hotkey & clipboard
const hotkey = this.designer.editor.get('innerHotkey');
hotkey.mount(this._contentWindow);
focusTracker.mount(this._contentWindow);
clipboard.injectCopyPaster(this._contentDocument);

View File

@ -52,7 +52,8 @@ export class LiveEditing {
const targetElement = event.target as HTMLElement;
const { liveTextEditing } = node.componentMeta;
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || node?.componentMeta?.componentName || '';

View File

@ -62,7 +62,8 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
if (canClick && typeof node.select === 'function') {
node.select();
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const npm = node?.componentMeta?.npm;
const selected =
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||

View File

@ -1,354 +0,0 @@
import { hotkey, Editor, globalContext } from '@alilc/lowcode-editor-core';
import { isFormEvent } from '@alilc/lowcode-utils';
import { focusing } from './focusing';
import { insertChildren, TransformStage } from '../document';
import clipboard from './clipboard';
export function isInLiveEditing() {
if (globalContext.has(Editor)) {
return Boolean(
globalContext.get(Editor).get('designer')?.project?.simulator?.liveEditing?.editing,
);
}
}
/* istanbul ignore next */
function getNextForSelect(next: any, head?: any, parent?: any): any {
if (next) {
if (!head) {
return next;
}
let ret;
if (next.isContainer()) {
const children = next.getChildren() || [];
if (children && !children.isEmpty()) {
ret = getNextForSelect(children.get(0));
if (ret) {
return ret;
}
}
}
ret = getNextForSelect(next.nextSibling);
if (ret) {
return ret;
}
}
if (parent) {
return getNextForSelect(parent.nextSibling, false, parent.getParent());
}
return null;
}
/* istanbul ignore next */
function getPrevForSelect(prev: any, head?: any, parent?: any): any {
if (prev) {
let ret;
if (!head && prev.isContainer()) {
const children = prev.getChildren() || [];
const lastChild = children && !children.isEmpty() ? children.get(children.size - 1) : null;
ret = getPrevForSelect(lastChild);
if (ret) {
return ret;
}
}
if (!head) {
return prev;
}
ret = getPrevForSelect(prev.prevSibling);
if (ret) {
return ret;
}
}
if (parent) {
return parent;
}
return null;
}
// hotkey binding
hotkey.bind(['backspace', 'del'], (e: KeyboardEvent) => {
if (isInLiveEditing()) return;
// TODO: use focus-tracker
const doc = focusing.focusDesigner?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const sel = doc.selection;
const topItems = sel.getTopNodes();
// TODO: check can remove
topItems.forEach((node) => {
if (node.canPerformAction('remove')) {
doc.removeNode(node);
}
});
sel.clear();
});
hotkey.bind('escape', (e: KeyboardEvent) => {
// const currentFocus = focusing.current;
if (isInLiveEditing()) return;
const sel = focusing.focusDesigner?.currentDocument?.selection;
if (isFormEvent(e) || !sel) {
return;
}
e.preventDefault();
sel.clear();
// currentFocus.esc();
});
// command + c copy command + x cut
hotkey.bind(['command+c', 'ctrl+c', 'command+x', 'ctrl+x'], (e, action) => {
if (isInLiveEditing()) return;
const doc = focusing.focusDesigner?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
let selected = doc.selection.getTopNodes(true);
selected = selected.filter((node) => {
return node.canPerformAction('copy');
});
if (!selected || selected.length < 1) {
return;
}
const componentsMap = {};
const componentsTree = selected.map((item) => item.export(TransformStage.Clone));
// FIXME: clear node.id
const data = { type: 'nodeSchema', componentsMap, componentsTree };
clipboard.setData(data);
const cutMode = action && action.indexOf('x') > 0;
if (cutMode) {
selected.forEach((node) => {
const parentNode = node.getParent();
parentNode?.select();
node.remove();
});
}
});
// command + v paste
hotkey.bind(['command+v', 'ctrl+v'], (e) => {
if (isInLiveEditing()) return;
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !designer || !doc) {
return;
}
/* istanbul ignore next */
clipboard.waitPasteData(e, ({ componentsTree }) => {
if (componentsTree) {
const { target, index } = designer.getSuitableInsertion(componentsTree) || {};
if (!target) {
return;
}
let canAddComponentsTree = componentsTree.filter((i) => {
return doc.checkNestingUp(target, i);
});
if (canAddComponentsTree.length === 0) return;
const nodes = insertChildren(target, canAddComponentsTree, index);
if (nodes) {
doc.selection.selectAll(nodes.map((o) => o.id));
setTimeout(() => designer.activeTracker.track(nodes[0]), 10);
}
}
});
});
// command + z undo
hotkey.bind(['command+z', 'ctrl+z'], (e) => {
if (isInLiveEditing()) return;
const his = focusing.focusDesigner?.currentHistory;
if (isFormEvent(e) || !his) {
return;
}
e.preventDefault();
const selection = focusing.focusDesigner?.currentSelection;
const curSelected = Array.from(selection?.selected);
his.back();
selection?.selectAll(curSelected);
});
// command + shift + z redo
hotkey.bind(['command+y', 'ctrl+y', 'command+shift+z'], (e) => {
if (isInLiveEditing()) return;
const his = focusing.focusDesigner?.currentHistory;
if (isFormEvent(e) || !his) {
return;
}
e.preventDefault();
const selection = focusing.focusDesigner?.currentSelection;
const curSelected = Array.from(selection?.selected);
his.forward();
selection?.selectAll(curSelected);
});
// sibling selection
hotkey.bind(['left', 'right'], (e, action) => {
if (isInLiveEditing()) return;
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
const firstNode = selected[0];
const silbing = action === 'left' ? firstNode?.prevSibling : firstNode?.nextSibling;
silbing?.select();
});
hotkey.bind(['up', 'down'], (e, action) => {
if (isInLiveEditing()) return;
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
const firstNode = selected[0];
if (action === 'down') {
const next = getNextForSelect(firstNode, true, firstNode.getParent());
next?.select();
} else if (action === 'up') {
const prev = getPrevForSelect(firstNode, true, firstNode.getParent());
prev?.select();
}
});
hotkey.bind(['option+left', 'option+right'], (e, action) => {
if (isInLiveEditing()) return;
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
// TODO: 此处需要增加判断当前节点是否可被操作移动原ve里是用 node.canOperating()来判断
// TODO: 移动逻辑也需要重新梳理,对于移动目标位置的选择,是否可以移入,需要增加判断
const firstNode = selected[0];
const parent = firstNode.getParent();
if (!parent) return;
const isPrev = action && /(left)$/.test(action);
const silbing = isPrev ? firstNode.prevSibling : firstNode.nextSibling;
if (silbing) {
if (isPrev) {
parent.insertBefore(firstNode, silbing);
} else {
parent.insertAfter(firstNode, silbing);
}
firstNode?.select();
}
});
hotkey.bind(['option+up'], (e) => {
if (isInLiveEditing()) return;
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
// TODO: 此处需要增加判断当前节点是否可被操作移动原ve里是用 node.canOperating()来判断
// TODO: 移动逻辑也需要重新梳理,对于移动目标位置的选择,是否可以移入,需要增加判断
const firstNode = selected[0];
const parent = firstNode.getParent();
if (!parent) {
return;
}
const silbing = firstNode.prevSibling;
if (silbing) {
if (silbing.isContainer()) {
const place = silbing.getSuitablePlace(firstNode, null);
place.container.insertAfter(firstNode, place.ref);
} else {
parent.insertBefore(firstNode, silbing);
}
firstNode?.select();
} else {
const place = parent.getSuitablePlace(firstNode, null); // upwards
if (place) {
place.container.insertBefore(firstNode, place.ref);
firstNode?.select();
}
}
});
hotkey.bind(['option+down'], (e) => {
if (isInLiveEditing()) return;
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
// TODO: 此处需要增加判断当前节点是否可被操作移动原ve里是用 node.canOperating()来判断
// TODO: 移动逻辑也需要重新梳理,对于移动目标位置的选择,是否可以移入,需要增加判断
const firstNode = selected[0];
const parent = firstNode.getParent();
if (!parent) {
return;
}
const silbing = firstNode.nextSibling;
if (silbing) {
if (silbing.isContainer()) {
// const place = silbing.getSuitablePlace(firstNode, null);
silbing.insertBefore(firstNode, undefined);
// place.container.insertBefore(firstNode, place.ref);
} else {
parent.insertAfter(firstNode, silbing);
}
firstNode?.select();
} else {
const place = parent.getSuitablePlace(firstNode, null); // upwards
if (place) {
place.container.insertAfter(firstNode, place.ref);
firstNode?.select();
}
}
});

View File

@ -109,4 +109,4 @@ class Clipboard {
}
}
export default new Clipboard();
export const clipboard = new Clipboard();

View File

@ -4,16 +4,18 @@ import BuiltinDragGhostComponent from './drag-ghost';
import { Designer, DesignerProps } from './designer';
import { ProjectView } from '../project';
import './designer.less';
import clipboard from './clipboard';
import { clipboard } from './clipboard';
export class DesignerView extends Component<DesignerProps & {
designer?: Designer;
}> {
readonly designer: Designer;
readonly name: string;
constructor(props: any) {
super(props);
const { designer, ...designerProps } = props;
this.name = designer.name;
if (designer) {
this.designer = designer;
designer.setProps(designerProps);

View File

@ -74,14 +74,17 @@ export class Designer {
return this.currentDocument?.selection;
}
name: string;
constructor(props: DesignerProps) {
makeObservable(this);
const { editor, shellModelFactory } = props;
const { editor, name, shellModelFactory } = props;
this.editor = editor;
this.name = name;
this.shellModelFactory = shellModelFactory;
this.setProps(props);
this.project = new Project(this, props.defaultSchema);
this.project = new Project(this, props.defaultSchema, name);
this.dragon.onDragstart((e) => {
this.detecting.enable = false;
@ -364,12 +367,12 @@ export class Designer {
const { components, packages } = incrementalAssets;
components && this.buildComponentMetasMap(components);
if (packages) {
await this.project.simulator!.setupComponents(packages);
await this.project.simulator?.setupComponents(packages);
}
if (components) {
// 合并assets
let assets = this.editor.get('assets');
// 合并 assets
let assets = this.editor.get('assets') || {};
let newAssets = megreAssets(assets, incrementalAssets);
// 对于 assets 存在需要二次网络下载的过程,必须 await 等待结束之后,再进行事件触发
await this.editor.set('assets', newAssets);
@ -403,6 +406,21 @@ export class Designer {
return this._simulatorProps || {};
}
/**
*
*/
@computed get projectSimulatorProps(): any {
return {
...this.simulatorProps,
project: this.project,
designer: this,
onMount: (simulator: any) => {
this.project.mountSimulator(simulator);
this.editor.set('simulator', simulator);
},
};
}
@obx.ref private _suspensed = false;
get suspensed(): boolean {

View File

@ -145,6 +145,8 @@ function isDragEvent(e: any): e is DragEvent {
export class Dragon {
private sensors: ISensor[] = [];
key = Math.random();
/**
* current active sensor,
*/
@ -162,10 +164,13 @@ export class Dragon {
return this._dragging;
}
name: string;
private emitter = new EventEmitter();
constructor(readonly designer: Designer) {
makeObservable(this);
this.name = designer.name;
}
/**

View File

@ -1,5 +1,3 @@
import './builtin-hotkey';
export * from './designer';
export * from './designer-view';
export * from './dragon';
@ -9,3 +7,6 @@ export * from './offset-observer';
export * from './scroller';
export * from './setting';
export * from './active-tracker';
export * from './focusing';
export * from '../document';
export * from './clipboard';

View File

@ -1,4 +1,4 @@
import { obx, computed, makeObservable, runInAction } from '@alilc/lowcode-editor-core';
import { obx, computed, makeObservable, runInAction, Setters } from '@alilc/lowcode-editor-core';
import { GlobalEvent, IEditor, ISetValueOptions } from '@alilc/lowcode-types';
import { uniqueId, isJSExpression } from '@alilc/lowcode-utils';
import { SettingEntry } from './setting-entry';
@ -18,6 +18,8 @@ export class SettingPropEntry implements SettingEntry {
readonly isSingle: boolean;
readonly setters: Setters;
readonly nodes: Node[];
readonly componentMeta: ComponentMeta | null;
@ -70,6 +72,7 @@ export class SettingPropEntry implements SettingEntry {
// copy parent static properties
this.editor = parent.editor;
this.nodes = parent.nodes;
this.setters = parent.setters;
this.componentMeta = parent.componentMeta;
this.isSameComponent = parent.isSameComponent;
this.isMultiple = parent.isMultiple;

View File

@ -72,6 +72,8 @@ export class SettingTopEntry implements SettingEntry {
readonly designer: Designer;
readonly setters: any;
disposeFunctions: any[] = [];
constructor(readonly editor: IEditor, readonly nodes: Node[]) {
@ -81,6 +83,7 @@ export class SettingTopEntry implements SettingEntry {
this.id = generateSessionId(nodes);
this.first = nodes[0];
this.designer = this.first.document.designer;
this.setters = editor.get('setters');
// setups
this.setupComponentMeta();

View File

@ -2,7 +2,6 @@
import { isValidElement } from 'react';
import { FieldConfig, SetterConfig } from '@alilc/lowcode-types';
import { isSetterConfig, isDynamicSetter } from '@alilc/lowcode-utils';
import { getSetter } from '@alilc/lowcode-editor-core';
import { SettingField } from './setting-field';
function getHotterFromSetter(setter) {
@ -64,7 +63,7 @@ export class Transducer {
isDynamic = dynamicFlag !== false;
}
if (typeof setter === 'string') {
const { component, isDynamic: dynamicFlag } = getSetter(setter) || {};
const { component, isDynamic: dynamicFlag } = context.setters.getSetter(setter) || {};
setter = component;
// 如果在物料配置中声明了,在 registerSetter 没有声明,取物料配置中的声明
isDynamic = dynamicFlag === undefined ? isDynamic : dynamicFlag !== false;

View File

@ -118,7 +118,8 @@ export class History<T = NodeSchema> {
}
const cursor = this.session.cursor - 1;
this.go(cursor);
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
if (!editor) {
return;
}
@ -131,7 +132,8 @@ export class History<T = NodeSchema> {
}
const cursor = this.session.cursor + 1;
this.go(cursor);
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
if (!editor) {
return;
}

View File

@ -161,7 +161,9 @@ export class NodeChildren {
const { document } = node;
/* istanbul ignore next */
if (globalContext.has('editor')) {
globalContext.get('editor').emit('node.remove', { node, index: i });
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
editor.emit('node.remove', { node, index: i });
}
document.unlinkNode(node);
document.selection.remove(node.id);
@ -196,12 +198,14 @@ export class NodeChildren {
const i = children.indexOf(node);
if (node.parent) {
/* istanbul ignore next */
globalContext.has('editor') &&
globalContext.get('editor').emit('node.remove.topLevel', {
if (globalContext.has('editor')) {
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
editor.emit('node.remove.topLevel', {
node,
index: node.index,
});
}
}
if (i < 0) {
@ -231,7 +235,9 @@ export class NodeChildren {
this.emitter.emit('insert', node);
/* istanbul ignore next */
if (globalContext.has('editor')) {
globalContext.get('editor').emit('node.add', { node });
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
editor.emit('node.add', { node });
}
if (useMutator) {
this.reportModified(node, this.owner, { type: 'insert' });

View File

@ -1018,7 +1018,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
}
/**
* @deprecated
* TODO: replace non standard metas with standard ones.
*/
getSuitablePlace(node: Node, ref: any): any {
const focusNode = this.document?.focusNode;

View File

@ -1,6 +1,5 @@
/* eslint-disable no-multi-assign */
import { EngineConfig, engineConfig } from '@alilc/lowcode-editor-core';
import { ILowCodePluginManager } from '@alilc/lowcode-designer';
import { engineConfig } from '@alilc/lowcode-editor-core';
import {
IPublicApiHotkey,
IPublicApiProject,
@ -9,14 +8,16 @@ import {
IPublicApiMaterial,
IPublicApiEvent,
IPublicApiCommon,
} from '@alilc/lowcode-types';
import { getLogger, Logger } from '@alilc/lowcode-utils';
import {
ILowCodePluginContext,
IPluginPreferenceMananger,
PreferenceValueType,
IEngineConfig,
IPublicApiLogger,
IPublicApiPlugins,
} from '@alilc/lowcode-types';
import {
IPluginContextOptions,
ILowCodePluginPreferenceDeclaration,
PreferenceValueType,
IPluginPreferenceMananger,
ILowCodePluginContextApiAssembler,
ILowCodePluginContextPrivate,
} from './plugin-types';
@ -30,21 +31,18 @@ export default class PluginContext implements ILowCodePluginContext, ILowCodePlu
setters: IPublicApiSetters;
material: IPublicApiMaterial;
event: IPublicApiEvent;
config: EngineConfig;
config: IEngineConfig;
common: IPublicApiCommon;
logger: Logger;
plugins: ILowCodePluginManager;
logger: IPublicApiLogger;
plugins: IPublicApiPlugins;
preference: IPluginPreferenceMananger;
constructor(
plugins: ILowCodePluginManager,
options: IPluginContextOptions,
contextApiAssembler: ILowCodePluginContextApiAssembler,
) {
contextApiAssembler.assembleApis(this);
this.plugins = plugins;
const { pluginName = 'anonymous' } = options;
this.logger = getLogger({ level: 'warn', bizName: `designer:plugin:${pluginName}` });
contextApiAssembler.assembleApis(this, pluginName);
const enhancePluginContextHook = engineConfig.get('enhancePluginContextHook');
if (enhancePluginContextHook) {

View File

@ -2,12 +2,8 @@ import { engineConfig } from '@alilc/lowcode-editor-core';
import { getLogger } from '@alilc/lowcode-utils';
import {
ILowCodePlugin,
ILowCodePluginConfig,
ILowCodePluginManager,
ILowCodePluginContext,
ILowCodeRegisterOptions,
IPluginContextOptions,
PreferenceValueType,
ILowCodePluginConfigMeta,
PluginPreference,
ILowCodePluginPreferenceDeclaration,
@ -21,25 +17,31 @@ import LowCodePluginContext from './plugin-context';
import { invariant } from '../utils';
import sequencify from './sequencify';
import semverSatisfies from 'semver/functions/satisfies';
import {
ILowCodePluginContext,
ILowCodePluginConfig,
ILowCodeRegisterOptions,
PreferenceValueType,
} from '@alilc/lowcode-types';
const logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' });
export class LowCodePluginManager implements ILowCodePluginManager {
private plugins: ILowCodePlugin[] = [];
private pluginsMap: Map<string, ILowCodePlugin> = new Map();
pluginsMap: Map<string, ILowCodePlugin> = new Map();
private pluginPreference?: PluginPreference = new Map();
contextApiAssembler: ILowCodePluginContextApiAssembler;
constructor(contextApiAssembler: ILowCodePluginContextApiAssembler) {
constructor(contextApiAssembler: ILowCodePluginContextApiAssembler, readonly name = 'unknown') {
this.contextApiAssembler = contextApiAssembler;
}
private _getLowCodePluginContext(options: IPluginContextOptions) {
return new LowCodePluginContext(this, options, this.contextApiAssembler);
}
_getLowCodePluginContext = (options: IPluginContextOptions) => {
return new LowCodePluginContext(options, this.contextApiAssembler);
};
isEngineVersionMatched(versionExp: string): boolean {
const engineVersion = engineConfig.get('ENGINE_VERSION');
@ -105,8 +107,10 @@ export class LowCodePluginManager implements ILowCodePluginManager {
}
const plugin = new LowCodePlugin(pluginName, this, config, meta);
// support initialization of those plugins which registered after normal initialization by plugin-manager
// support initialization of those plugins which registered
// after normal initialization by plugin-manager
if (registerOptions?.autoInit) {
// debugger
await plugin.init();
}
this.plugins.push(plugin);

View File

@ -1,4 +1,3 @@
import Logger from 'zen-logger';
import {
IPublicApiHotkey,
IPublicApiProject,
@ -10,11 +9,14 @@ import {
CompositeObject,
ComponentAction,
MetadataTransducer,
IPublicApiPlugins,
ILowCodePluginContext,
ILowCodePluginConfig,
IPublicApiLogger,
ILowCodeRegisterOptions,
PreferenceValueType,
IEngineConfig,
} from '@alilc/lowcode-types';
import { EngineConfig } from '@alilc/lowcode-editor-core';
import { Setters } from '../types';
export type PreferenceValueType = string | number | boolean;
export interface ILowCodePluginPreferenceDeclarationProperty {
// shape like 'name' or 'group.name' or 'group.subGroup.name'
@ -51,12 +53,6 @@ export interface ILowCodePluginPreferenceDeclaration {
export type PluginPreference = Map<string, Record<string, PreferenceValueType>>;
export interface ILowCodePluginConfig {
dep?: string | string[];
init?(): void;
destroy?(): void;
exports?(): any;
}
export interface ILowCodePluginConfigMetaEngineConfig {
lowcodeEngine?: string;
@ -73,7 +69,7 @@ export interface ILowCodePluginCore {
dep: string[];
disabled: boolean;
config: ILowCodePluginConfig;
logger: Logger;
logger: IPublicApiLogger;
on(event: string | symbol, listener: (...args: any[]) => void): any;
emit(event: string | symbol, ...args: any[]): boolean;
removeAllListeners(event?: string | symbol): this;
@ -96,42 +92,22 @@ export interface IDesignerCabin {
removeBuiltinComponentAction: (actionName: string) => void;
}
export interface IPluginPreferenceMananger {
// eslint-disable-next-line max-len
getPreferenceValue: (
key: string,
defaultValue?: PreferenceValueType,
) => PreferenceValueType | undefined;
}
export interface ILowCodePluginContext {
get skeleton(): IPublicApiSkeleton;
get hotkey(): IPublicApiHotkey;
get setters(): IPublicApiSetters;
get config(): EngineConfig;
get material(): IPublicApiMaterial;
get event(): IPublicApiEvent;
get project(): IPublicApiProject;
get common(): IPublicApiCommon;
logger: Logger;
plugins: ILowCodePluginManager;
preference: IPluginPreferenceMananger;
}
export interface ILowCodePluginContextPrivate {
set hotkey(hotkey: IPublicApiHotkey);
set project(project: IPublicApiProject);
set skeleton(skeleton: IPublicApiSkeleton);
set setters(setters: Setters);
set setters(setters: IPublicApiSetters);
set material(material: IPublicApiMaterial);
set event(event: IPublicApiEvent);
set config(config: EngineConfig);
set config(config: IEngineConfig);
set common(common: IPublicApiCommon);
set plugins(plugins: IPublicApiPlugins);
set logger(plugins: IPublicApiLogger);
}
export interface ILowCodePluginContextApiAssembler {
assembleApis: (context: ILowCodePluginContextPrivate) => void;
assembleApis: (context: ILowCodePluginContextPrivate, pluginName: string) => void;
}
interface ILowCodePluginManagerPluginAccessor {
[pluginName: string]: ILowCodePlugin | any;
}
@ -157,15 +133,6 @@ export function isLowCodeRegisterOptions(opts: any): opts is ILowCodeRegisterOpt
return opts && ('autoInit' in opts || 'override' in opts);
}
export interface ILowCodeRegisterOptions {
/** Will enable plugin registered with auto-initialization immediately
* other than plugin-manager init all plugins at certain time.
* It is helpful when plugin register is later than plugin-manager initialization. */
autoInit?: boolean;
/** allow overriding existing plugin with same name when override === true */
override?: boolean;
}
export interface IPluginContextOptions {
pluginName: string;
}
@ -178,14 +145,4 @@ export interface IPluginMetaDefinition {
/** e.g. '^1.0.0' */
lowcodeEngine?: string;
};
}
interface IPluginConfigCreatorFn<T extends Record<string, any> = Record<string, any>> {
(ctx: ILowCodePluginContext, pluginOptions?: T): ILowCodePluginConfig;
}
export type IPluginConfigCreator<T extends Record<string, any> = Record<string, any>> =
IPluginConfigCreatorFn<T> & {
pluginName: string;
meta?: IPluginMetaDefinition;
};
}

View File

@ -1,10 +1,12 @@
import { getLogger, Logger } from '@alilc/lowcode-utils';
import {
ILowCodePlugin,
ILowCodePluginConfig,
ILowCodePluginManager,
ILowCodePluginConfigMeta,
} from './plugin-types';
import {
ILowCodePluginConfig,
} from '@alilc/lowcode-types';
import { EventEmitter } from 'events';
import { invariant } from '../utils';

View File

@ -26,8 +26,7 @@ export class ProjectView extends Component<{ designer: Designer }> {
}
render() {
const { designer } = this.props;
const { project } = designer;
const { simulatorProps } = project;
const { project, projectSimulatorProps: simulatorProps } = designer;
const Simulator = designer.simulatorComponent || BuiltinSimulatorHostView;
const Loading = engineConfig.get('loadingComponent', BuiltinLoading);

View File

@ -13,6 +13,10 @@
padding-top: 50%;
}
.lc-simulator {
background: rgb(237, 239, 243);
}
.lc-simulator-shell {
width: 100%;
height: 100%;

View File

@ -1,5 +1,5 @@
import { EventEmitter } from 'events';
import { obx, computed, makeObservable, action } from '@alilc/lowcode-editor-core';
import { obx, computed, makeObservable, action, engineConfig } from '@alilc/lowcode-editor-core';
import { Designer } from '../designer';
import { DocumentModel, isDocumentModel } from '../document';
import {
@ -32,9 +32,11 @@ export class Project {
return this._simulator || null;
}
key = Math.random();
// TODO: 考虑项目级别 History
constructor(readonly designer: Designer, schema?: ProjectSchema) {
constructor(readonly designer: Designer, schema?: ProjectSchema, public name = 'unknown') {
makeObservable(this);
this.load(schema);
}
@ -301,25 +303,9 @@ export class Project {
});
}
/**
*
*/
@computed get simulatorProps(): object {
let { simulatorProps } = this.designer;
if (typeof simulatorProps === 'function') {
simulatorProps = simulatorProps(this);
}
return {
...simulatorProps,
project: this,
onMount: this.mountSimulator.bind(this),
};
}
private mountSimulator(simulator: ISimulatorHost) {
mountSimulator(simulator: ISimulatorHost) {
// TODO: 多设备 simulator 支持
this._simulator = simulator;
this.designer.editor.set('simulator', simulator);
this.emitter.emit('lowcode_engine_simulator_ready', simulator);
}

View File

@ -1,7 +1,8 @@
import '../fixtures/window';
import { Editor, engineConfig } from '@alilc/lowcode-editor-core';
import { LowCodePluginManager } from '../../src/plugin/plugin-manager';
import { ILowCodePluginContext, ILowCodePluginManager, ILowCodePluginContextApiAssembler } from '../../src/plugin/plugin-types';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
import { ILowCodePluginManager } from '../../src/plugin/plugin-types';
const editor = new Editor();
const contextApiAssembler = {

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-editor-core",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "Core Api for Ali lowCode engine",
"license": "MIT",
"main": "lib/index.js",
@ -14,8 +14,8 @@
},
"dependencies": {
"@alifd/next": "^1.19.16",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"debug": "^4.1.1",
"intl-messageformat": "^9.3.1",
@ -49,5 +49,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/editor-core"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -44,32 +44,72 @@ function getInitialFromSetter(setter: any) {
) || null; // eslint-disable-line
}
export function getSetter(type: string): RegisteredSetter | null {
return settersMap.get(type) || null;
}
export function getSettersMap() {
return settersMap;
}
export class Setters {
constructor(public name: string = 'unknown') {}
export function createSetterContent(setter: any, props: Record<string, any>): ReactNode {
if (typeof setter === 'string') {
setter = getSetter(setter);
if (!setter) {
return null;
settersMap = new Map<string, RegisteredSetter & {
type: string;
}>();
getSetter = (type: string): RegisteredSetter | null => {
return this.settersMap.get(type) || null;
};
registerSetter = (
typeOrMaps: string | { [key: string]: CustomView | RegisteredSetter },
setter?: CustomView | RegisteredSetter,
) => {
if (typeof typeOrMaps === 'object') {
Object.keys(typeOrMaps).forEach(type => {
this.registerSetter(type, typeOrMaps[type]);
});
return;
}
if (setter.defaultProps) {
props = {
...setter.defaultProps,
...props,
if (!setter) {
return;
}
if (isCustomView(setter)) {
setter = {
component: setter,
// todo: intl
title: (setter as any).displayName || (setter as any).name || 'CustomSetter',
};
}
setter = setter.component;
}
if (!setter.initialValue) {
const initial = getInitialFromSetter(setter.component);
if (initial) {
setter.initialValue = (field: any) => {
return initial.call(field, field.getValue());
};
}
}
this.settersMap.set(typeOrMaps, { type: typeOrMaps, ...setter });
};
// Fusion的表单组件都是通过 'value' in props 来判断是否使用 defaultValue
if ('value' in props && typeof props.value === 'undefined') {
delete props.value;
}
getSettersMap = () => {
return this.settersMap;
};
return createContent(setter, props);
}
createSetterContent = (setter: any, props: Record<string, any>): ReactNode => {
if (typeof setter === 'string') {
setter = this.getSetter(setter);
if (!setter) {
return null;
}
if (setter.defaultProps) {
props = {
...setter.defaultProps,
...props,
};
}
setter = setter.component;
}
// Fusion的表单组件都是通过 'value' in props 来判断是否使用 defaultValue
if ('value' in props && typeof props.value === 'undefined') {
delete props.value;
}
return createContent(setter, props);
};
}

View File

@ -51,6 +51,10 @@ export declare interface Editor extends StrictEventEmitter<EventEmitter, GlobalE
// eslint-disable-next-line no-redeclare
export class Editor extends (EventEmitter as any) implements IEditor {
constructor(public name: string = 'unknown', public workspaceMode: boolean = false) {
// eslint-disable-next-line constructor-super
super();
}
/**
* Ioc Container
*/
@ -114,11 +118,47 @@ export class Editor extends (EventEmitter as any) implements IEditor {
if (remoteComponentDescriptions && remoteComponentDescriptions.length) {
await Promise.all(
remoteComponentDescriptions.map(async (component: any) => {
const { exportName, url } = component;
const { exportName, url, npm } = component;
await (new AssetLoader()).load(url);
function setAssetsComponent(component: any, extraNpmInfo: any = {}) {
const components = component.components;
if (Array.isArray(components)) {
components.forEach(d => {
assets.components = assets.components.concat({
npm: {
...npm,
...extraNpmInfo,
},
...d,
} || []);
});
return;
}
assets.components = assets.components.concat({
npm: {
...npm,
...extraNpmInfo,
},
...component.components,
} || []);
// assets.componentList = assets.componentList.concat(component.componentList || []);
}
function setArrayAssets(value: any[], preExportName: string = '', preSubName: string = '') {
value.forEach((d: any, i: number) => {
const exportName = [preExportName, i.toString()].filter(d => !!d).join('.');
const subName = [preSubName, i.toString()].filter(d => !!d).join('.');
Array.isArray(d) ? setArrayAssets(d, exportName, subName) : setAssetsComponent(d, {
exportName,
subName,
});
});
}
if (window[exportName]) {
assets.components = assets.components.concat((window[exportName] as any).components || []);
assets.componentList = assets.componentList?.concat((window[exportName] as any).componentList || []);
if (Array.isArray(window[exportName])) {
setArrayAssets(window[exportName] as any);
} else {
setAssetsComponent(window[exportName] as any);
}
}
return window[exportName];
}),

View File

@ -330,7 +330,8 @@ function getKeyInfo(combination: string, action?: string): KeyInfo {
*/
function fireCallback(callback: HotkeyCallback, e: KeyboardEvent, combo?: string, sequence?: string): void {
try {
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const designer = editor.get('designer');
const node = designer?.currentSelection?.getNodes()?.[0];
const npm = node?.componentMeta?.npm;
@ -353,7 +354,7 @@ function fireCallback(callback: HotkeyCallback, e: KeyboardEvent, combo?: string
}
export class Hotkey {
private callBacks: HotkeyCallbacks = {};
callBacks: HotkeyCallbacks = {};
private directMap: HotkeyDirectMap = {};
@ -367,6 +368,16 @@ export class Hotkey {
private nextExpectedAction: boolean | string = false;
private isActivate = true;
constructor(readonly name: string = 'unknown') {
this.mount(window);
}
activate(activate: boolean): void {
this.isActivate = activate;
}
mount(window: Window) {
const { document } = window;
const handleKeyEvent = this.handleKeyEvent.bind(this);
@ -541,6 +552,9 @@ export class Hotkey {
}
private handleKeyEvent(e: KeyboardEvent): void {
if (!this.isActivate) {
return;
}
const character = characterFromEvent(e);
// no character found then stop
@ -644,5 +658,5 @@ export class Hotkey {
}
}
export const hotkey = new Hotkey();
hotkey.mount(window);
// export const hotkey = new Hotkey();
// hotkey.mount(window);

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-editor-skeleton",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "alibaba lowcode editor skeleton",
"main": "lib/index.js",
"module": "es/index.js",
@ -18,10 +18,10 @@
],
"dependencies": {
"@alifd/next": "^1.20.12",
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-editor-core": "1.0.17",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-editor-core": "1.1.0-beta.6",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"react": "^16.8.1",
"react-dom": "^16.8.1"
@ -42,5 +42,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/editor-skeleton"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -1,5 +1,5 @@
import { Component, MouseEvent, Fragment } from 'react';
import { shallowIntl, createSetterContent, observer, obx, engineConfig, runInAction, globalContext } from '@alilc/lowcode-editor-core';
import { shallowIntl, observer, obx, engineConfig, runInAction, globalContext } from '@alilc/lowcode-editor-core';
import { createContent, isJSSlot, isSetterConfig } from '@alilc/lowcode-utils';
import { Skeleton } from '@alilc/lowcode-editor-skeleton';
import { CustomView } from '@alilc/lowcode-types';
@ -8,6 +8,7 @@ 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: ComponentMeta | null) {
if (!componentMeta) return false;
@ -38,6 +39,8 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
stageName: string | undefined;
setters: Setters;
constructor(props: SettingFieldViewProps) {
super(props);
@ -45,8 +48,10 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
const { extraProps } = field;
const { display } = extraProps;
const editor = globalContext.get('editor');
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');
let stageName;
if (display === 'entry') {
runInAction(() => {
@ -192,7 +197,6 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
setterProps = {},
setterType,
initialValue = null,
} = this.setterInfo;
const value = this.value;
@ -215,7 +219,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
...extraProps,
},
!stageName &&
createSetterContent(setterType, {
this.setters.createSetterContent(setterType, {
...shallowIntl(setterProps),
forceInline: extraProps.forceInline,
key: field.id,
@ -268,7 +272,8 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
const { field } = this.props;
const { extraProps } = field;
const { display } = extraProps;
const editor = globalContext.get('editor');
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const { stages } = editor.get('skeleton') as Skeleton;
// const items = field.items;

View File

@ -14,19 +14,25 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
state = {
shouldIgnoreRoot: false,
};
private main = new SettingsMain(globalContext.get('editor'));
private main;
@obx.ref private _activeKey?: any;
constructor(props) {
super(props);
makeObservable(this);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
this.main = new SettingsMain(editor);
}
componentDidMount() {
this.setShouldIgnoreRoot();
globalContext.get('editor').on('designer.selection.change', () => {
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
editor.on('designer.selection.change', () => {
if (!engineConfig.get('stayOnTheSameSettingTab', false)) {
this._activeKey = null;
}
@ -65,7 +71,8 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
);
}
const editor = globalContext.get('editor');
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const designer = editor.get('designer');
const current = designer?.currentSelection?.getNodes()?.[0];
let node: Node | null = settings.first;
@ -128,7 +135,8 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
render() {
const { settings } = this.main;
const editor = globalContext.get('editor');
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
if (!settings) {
// 未选中节点,提示选中 或者 显示根节点设置
return (

View File

@ -116,12 +116,14 @@ export class DraggableLineView extends Component<{ panel: Panel }> {
}
// 抛出事件,对于有些需要 panel 插件随着 度变化进行再次渲染的由panel插件内部监听事件实现
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
editor?.emit('dockpane.drag', width);
}
onDragChange(type: 'start' | 'end') {
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
editor?.emit('dockpane.dragchange', type);
// builtinSimulator 屏蔽掉 鼠标事件
editor?.emit('designer.builtinSimulator.disabledEvents', type === 'start');
@ -185,7 +187,8 @@ export class TitledPanelView extends Component<{ panel: Panel; area?: string }>
if (!panel.inited) {
return null;
}
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const panelName = area ? `${area}-${panel.name}` : panel.name;
editor?.emit('skeleton.panel.toggle', {
name: panelName || '',
@ -247,7 +250,8 @@ export class PanelView extends Component<{
if (!panel.inited) {
return null;
}
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const panelName = area ? `${area}-${panel.name}` : panel.name;
editor?.emit('skeleton.panel.toggle', {
name: panelName || '',

View File

@ -65,7 +65,6 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }>
this.props.area.setVisible(false);
},
onBlur: () => {
// debugger
this.props.area.setVisible(false);
},
});

View File

@ -133,11 +133,38 @@ body {
}
}
.lc-workbench {
.workspace-engine-main {
height: 100%;
display: flex;
flex-direction: column;
background-color: #edeff3;
.lc-workbench {
}
.engine-editor-view {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
&.active {
z-index: 999;
}
}
}
.lc-workbench {
&.engine-main {
height: 100%;
display: flex;
flex-direction: column;
background-color: #edeff3;
}
.lc-top-area {
height: var(--top-area-height);
background-color: var(--color-pane-background);
@ -349,6 +376,7 @@ body {
}
.lc-main-area {
flex: 1;
background-color: #edeff3;
}
.lc-bottom-area {
height: var(--bottom-area-height);

View File

@ -1,4 +1,4 @@
import { Editor, action, makeObservable } from '@alilc/lowcode-editor-core';
import { Editor, action, makeObservable, obx } from '@alilc/lowcode-editor-core';
import {
DockConfig,
PanelConfig,
@ -56,13 +56,13 @@ export class Skeleton {
readonly rightArea: Area<PanelConfig, Panel>;
readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>;
@obx readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>;
readonly bottomArea: Area<PanelConfig, Panel>;
readonly stages: Area<StageConfig, Stage>;
constructor(readonly editor: Editor) {
constructor(readonly editor: Editor, readonly name: string = 'unknown') {
makeObservable(this);
this.leftArea = new Area(
this,
@ -366,6 +366,12 @@ export class Skeleton {
...this.parseConfig(config),
...extraConfig,
};
parsedConfig.contentProps = {
context: this.editor.get('innerPlugins')?._getLowCodePluginContext({
pluginName: 'any',
}),
...(parsedConfig.contentProps || {}),
};
let { area } = parsedConfig;
if (!area) {
if (parsedConfig.type === 'Panel') {

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-engine",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系",
"main": "lib/engine-core.js",
"module": "es/engine-core.js",
@ -19,14 +19,14 @@
"license": "MIT",
"dependencies": {
"@alifd/next": "^1.19.12",
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-editor-core": "1.0.17",
"@alilc/lowcode-editor-skeleton": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-editor-core": "1.1.0-beta.6",
"@alilc/lowcode-editor-skeleton": "1.1.0-beta.6",
"@alilc/lowcode-engine-ext": "^1.0.0",
"@alilc/lowcode-plugin-designer": "1.0.17",
"@alilc/lowcode-plugin-outline-pane": "1.0.17",
"@alilc/lowcode-shell": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-plugin-designer": "1.1.0-beta.6",
"@alilc/lowcode-plugin-outline-pane": "1.1.0-beta.6",
"@alilc/lowcode-shell": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"react": "^16.8.1",
"react-dom": "^16.8.1"
},
@ -53,5 +53,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/engine"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -1,23 +1,34 @@
/* eslint-disable no-param-reassign */
import { createElement } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { globalContext, Editor, engineConfig, EngineOptions } from '@alilc/lowcode-editor-core';
import {
globalContext,
Editor,
engineConfig,
Setters as InnerSetters,
Hotkey as InnerHotkey,
} from '@alilc/lowcode-editor-core';
import {
EngineOptions,
IPublicModelDocumentModel,
ILowCodePluginContext,
} from '@alilc/lowcode-types';
import {
Designer,
LowCodePluginManager,
ILowCodePluginContext,
ILowCodePluginContextPrivate,
ILowCodePluginContextApiAssembler,
PluginPreference,
} from '@alilc/lowcode-designer';
import {
Skeleton as InnerSkeleton,
SettingsPrimaryPane,
registerDefaults,
} from '@alilc/lowcode-editor-skeleton';
import {
WorkSpace,
Workbench as WorkSpaceWorkbench,
} from '@alilc/lowcode-workspace';
import Outline, { OutlineBackupPane, getTreeMaster } from '@alilc/lowcode-plugin-outline-pane';
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
import {
Hotkey,
Project,
@ -25,14 +36,19 @@ import {
Setters,
Material,
Event,
DocumentModel,
Plugins,
Common,
Logger,
} from '@alilc/lowcode-shell';
import { getLogger, isPlainObject } from '@alilc/lowcode-utils';
import { isPlainObject } from '@alilc/lowcode-utils';
import './modules/live-editing';
import classes from './modules/classes';
import symbols from './modules/symbols';
import { componentMetaParser } from './inner-plugins/component-meta-parser';
import { setterRegistry } from './inner-plugins/setter-registry';
import { defaultPanelRegistry } from './inner-plugins/default-panel-registry';
import { shellModelFactory } from './modules/shell-model-factory';
import { builtinHotkey } from './inner-plugins/builtin-hotkey';
export * from './modules/skeleton-types';
export * from './modules/designer-types';
@ -40,9 +56,11 @@ export * from './modules/lowcode-types';
registerDefaults();
const workSpace = new WorkSpace();
const editor = new Editor();
globalContext.register(editor, Editor);
globalContext.register(editor, 'editor');
globalContext.register(workSpace, 'workSpace');
const innerSkeleton = new InnerSkeleton(editor);
editor.set('skeleton' as any, innerSkeleton);
@ -51,18 +69,26 @@ const designer = new Designer({ editor, shellModelFactory });
editor.set('designer' as any, designer);
const { project: innerProject } = designer;
const hotkey = new Hotkey();
const innerHotkey = new InnerHotkey();
const hotkey = new Hotkey(innerHotkey);
const project = new Project(innerProject);
const skeleton = new Skeleton(innerSkeleton);
const setters = new Setters();
const innerSetters = new InnerSetters();
const setters = new Setters(innerSetters);
const material = new Material(editor);
editor.set('project', project);
editor.set('setters' as any, setters);
editor.set('material', material);
editor.set('innerHotkey', innerHotkey);
const config = engineConfig;
const event = new Event(editor, { prefix: 'common' });
const logger = getLogger({ level: 'warn', bizName: 'common' });
const logger = new Logger({ level: 'warn', bizName: 'common' });
const common = new Common(editor, innerSkeleton);
let plugins: Plugins;
const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
assembleApis: (context: ILowCodePluginContextPrivate) => {
assembleApis: (context: ILowCodePluginContextPrivate, pluginName: string) => {
context.hotkey = hotkey;
context.project = project;
context.skeleton = skeleton;
@ -71,9 +97,14 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
context.event = event;
context.config = config;
context.common = common;
context.plugins = plugins;
context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` });
},
};
const plugins = new LowCodePluginManager(pluginContextApiAssembler).toProxy();
const innerPlugins = new LowCodePluginManager(pluginContextApiAssembler);
plugins = new Plugins(innerPlugins).toProxy();
editor.set('innerPlugins' as any, innerPlugins);
editor.set('plugins' as any, plugins);
export {
@ -89,6 +120,7 @@ export {
common,
// 兼容原 editor 的事件功能
event as editor,
workSpace,
};
// declare this is open-source version
export const isOpenSource = true;
@ -98,99 +130,6 @@ export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
};
engineConfig.set('isOpenSource', isOpenSource);
// 注册一批内置插件
(async function registerPlugins() {
// 处理 editor.set('assets'),将组件元数据创建好
const componentMetaParser = (ctx: ILowCodePluginContext) => {
return {
init() {
editor.onGot('assets', (assets: any) => {
const { components = [] } = assets;
designer.buildComponentMetasMap(components);
});
},
};
};
componentMetaParser.pluginName = '___component_meta_parser___';
await plugins.register(componentMetaParser);
// 注册默认的 setters
const setterRegistry = (ctx: ILowCodePluginContext) => {
return {
init() {
if (engineConfig.get('disableDefaultSetters')) return;
const builtinSetters = require('@alilc/lowcode-engine-ext')?.setters;
if (builtinSetters) {
ctx.setters.registerSetter(builtinSetters);
}
},
};
};
setterRegistry.pluginName = '___setter_registry___';
await plugins.register(setterRegistry);
// 注册默认的面板
const defaultPanelRegistry = (ctx: ILowCodePluginContext) => {
return {
init() {
skeleton.add({
area: 'mainArea',
name: 'designer',
type: 'Widget',
content: DesignerPlugin,
});
if (!engineConfig.get('disableDefaultSettingPanel')) {
skeleton.add({
area: 'rightArea',
name: 'settingsPane',
type: 'Panel',
content: SettingsPrimaryPane,
props: {
ignoreRoot: true,
},
});
}
// by default in float area;
let isInFloatArea = true;
const hasPreferenceForOutline = editor
?.getPreference()
?.contains('outline-pane-pinned-status-isFloat', 'skeleton');
if (hasPreferenceForOutline) {
isInFloatArea = editor
?.getPreference()
?.get('outline-pane-pinned-status-isFloat', 'skeleton');
}
skeleton.add({
area: 'leftArea',
name: 'outlinePane',
type: 'PanelDock',
content: Outline,
panelProps: {
area: isInFloatArea ? 'leftFloatArea' : 'leftFixedArea',
keepVisibleWhileDragging: true,
...engineConfig.get('defaultOutlinePaneProps'),
},
});
skeleton.add({
area: 'rightArea',
name: 'backupOutline',
type: 'Panel',
props: {
condition: () => {
return designer.dragon.dragging && !getTreeMaster(designer).hasVisibleTreeBoard();
},
},
content: OutlineBackupPane,
});
},
};
};
defaultPanelRegistry.pluginName = '___default_panel___';
await plugins.register(defaultPanelRegistry);
})();
// container which will host LowCodeEngine DOM
let engineContainer: HTMLElement;
// @ts-ignore webpack Define variable
@ -202,6 +141,7 @@ export async function init(
options?: EngineOptions,
pluginPreference?: PluginPreference,
) {
await destroy();
let engineOptions = null;
if (isPlainObject(container)) {
@ -220,9 +160,42 @@ export async function init(
}
engineConfig.setEngineOptions(engineOptions as any);
if (options && options.enableWorkspaceMode) {
render(
createElement(WorkSpaceWorkbench, {
workSpace,
className: 'engine-main',
topAreaItemClassName: 'engine-actionitem',
}),
engineContainer,
);
workSpace.setActive(true);
return;
}
// 注册一批内置插件
await plugins.register(componentMetaParser(designer));
await plugins.register(setterRegistry);
await plugins.register(defaultPanelRegistry(editor, designer));
await plugins.register(builtinHotkey);
await plugins.init(pluginPreference as any);
const { Workbench } = common.skeletonCabin;
if (options && options.enableWorkspaceMode) {
render(
createElement(WorkSpaceWorkbench, {
workSpace,
// skeleton: workSpace.skeleton,
className: 'engine-main',
topAreaItemClassName: 'engine-actionitem',
}),
engineContainer,
);
return;
}
render(
createElement(Workbench, {
skeleton: innerSkeleton,
@ -237,7 +210,7 @@ export async function destroy() {
// remove all documents
const { documents } = project;
if (Array.isArray(documents) && documents.length > 0) {
documents.forEach(((doc: DocumentModel) => project.removeDocument(doc)));
documents.forEach(((doc: IPublicModelDocumentModel) => project.removeDocument(doc)));
}
// TODO: delete plugins except for core plugins

View File

@ -0,0 +1,409 @@
import { IPublicModelNode } from './../../../types/src/shell/model/node';
import { Editor, globalContext } from '@alilc/lowcode-editor-core';
import { isFormEvent } from '@alilc/lowcode-utils';
import {
focusing,
insertChildren,
TransformStage,
clipboard,
} from '@alilc/lowcode-designer';
import {
ILowCodePluginContext,
} from '@alilc/lowcode-types';
export function isInLiveEditing() {
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return Boolean(
workSpace.window.editor.get('designer')?.project?.simulator?.liveEditing?.editing,
);
}
if (globalContext.has(Editor)) {
return Boolean(
globalContext.get(Editor).get('designer')?.project?.simulator?.liveEditing?.editing,
);
}
}
/* istanbul ignore next */
function getNextForSelect(next: IPublicModelNode | null, head?: any, parent?: IPublicModelNode | null): any {
if (next) {
if (!head) {
return next;
}
let ret;
if (next.isContainer) {
const children = next.children;
if (children && !children.isEmpty) {
ret = getNextForSelect(children.get(0));
if (ret) {
return ret;
}
}
}
ret = getNextForSelect(next.nextSibling);
if (ret) {
return ret;
}
}
if (parent) {
return getNextForSelect(parent.nextSibling, false, parent?.parent);
}
return null;
}
/* istanbul ignore next */
function getPrevForSelect(prev: IPublicModelNode | null, head?: any, parent?: IPublicModelNode | null): any {
if (prev) {
let ret;
if (!head && prev.isContainer) {
const children = prev.children;
const lastChild = children && !children.isEmpty ? children.get(children.size - 1) : null;
ret = getPrevForSelect(lastChild);
if (ret) {
return ret;
}
}
if (!head) {
return prev;
}
ret = getPrevForSelect(prev.prevSibling);
if (ret) {
return ret;
}
}
if (parent) {
return parent;
}
return null;
}
// 注册默认的 setters
export const builtinHotkey = (ctx: ILowCodePluginContext) => {
return {
init() {
const { hotkey, project, logger } = ctx;
// hotkey binding
hotkey.bind(['backspace', 'del'], (e: KeyboardEvent, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
// TODO: use focus-tracker
const doc = project.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const sel = doc.selection;
const topItems = sel.getTopNodes();
// TODO: check can remove
topItems.forEach((node) => {
if (node?.canPerformAction('remove')) {
node && doc.removeNode(node);
}
});
sel.clear();
});
hotkey.bind('escape', (e: KeyboardEvent, action) => {
logger.info(`action ${action} is triggered`);
// const currentFocus = focusing.current;
if (isInLiveEditing()) {
return;
}
const sel = focusing.focusDesigner?.currentDocument?.selection;
if (isFormEvent(e) || !sel) {
return;
}
e.preventDefault();
sel.clear();
// currentFocus.esc();
});
// command + c copy command + x cut
hotkey.bind(['command+c', 'ctrl+c', 'command+x', 'ctrl+x'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const doc = project.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
let selected = doc.selection.getTopNodes(true);
selected = selected.filter((node) => {
return node?.canPerformAction('copy');
});
if (!selected || selected.length < 1) {
return;
}
const componentsMap = {};
const componentsTree = selected.map((item) => item?.exportSchema(TransformStage.Clone));
// FIXME: clear node.id
const data = { type: 'nodeSchema', componentsMap, componentsTree };
clipboard.setData(data);
const cutMode = action && action.indexOf('x') > 0;
if (cutMode) {
selected.forEach((node) => {
const parentNode = node?.parent;
parentNode?.select();
node?.remove();
});
}
});
// command + v paste
hotkey.bind(['command+v', 'ctrl+v'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
if (isInLiveEditing()) return;
// TODO
const designer = focusing.focusDesigner;
const doc = designer?.currentDocument;
if (isFormEvent(e) || !designer || !doc) {
return;
}
/* istanbul ignore next */
clipboard.waitPasteData(e, ({ componentsTree }) => {
if (componentsTree) {
const { target, index } = designer.getSuitableInsertion(componentsTree) || {};
if (!target) {
return;
}
let canAddComponentsTree = componentsTree.filter((i) => {
return doc.checkNestingUp(target, i);
});
if (canAddComponentsTree.length === 0) return;
const nodes = insertChildren(target, canAddComponentsTree, index);
if (nodes) {
doc.selection.selectAll(nodes.map((o) => o.id));
setTimeout(() => designer.activeTracker.track(nodes[0]), 10);
}
}
});
});
// command + z undo
hotkey.bind(['command+z', 'ctrl+z'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const history = project.currentDocument?.history;
if (isFormEvent(e) || !history) {
return;
}
e.preventDefault();
const selection = project.currentDocument?.selection;
const curSelected = selection?.selected && Array.from(selection?.selected);
history.back();
selection?.selectAll(curSelected);
});
// command + shift + z redo
hotkey.bind(['command+y', 'ctrl+y', 'command+shift+z'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const history = project.currentDocument?.history;
if (isFormEvent(e) || !history) {
return;
}
e.preventDefault();
const selection = project.currentDocument?.selection;
const curSelected = selection?.selected && Array.from(selection?.selected);
history.forward();
selection?.selectAll(curSelected);
});
// sibling selection
hotkey.bind(['left', 'right'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const doc = project.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
const firstNode = selected[0];
const silbing = action === 'left' ? firstNode?.prevSibling : firstNode?.nextSibling;
silbing?.select();
});
hotkey.bind(['up', 'down'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const doc = project.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
const firstNode = selected[0];
if (action === 'down') {
const next = getNextForSelect(firstNode, true, firstNode?.parent);
next?.select();
} else if (action === 'up') {
const prev = getPrevForSelect(firstNode, true, firstNode?.parent);
prev?.select();
}
});
hotkey.bind(['option+left', 'option+right'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const doc = project.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
// TODO: 此处需要增加判断当前节点是否可被操作移动原ve里是用 node.canOperating()来判断
// TODO: 移动逻辑也需要重新梳理,对于移动目标位置的选择,是否可以移入,需要增加判断
const firstNode = selected[0];
const parent = firstNode?.parent;
if (!parent) return;
const isPrev = action && /(left)$/.test(action);
const silbing = isPrev ? firstNode.prevSibling : firstNode.nextSibling;
if (silbing) {
if (isPrev) {
parent.insertBefore(firstNode, silbing);
} else {
parent.insertAfter(firstNode, silbing);
}
firstNode?.select();
}
});
hotkey.bind(['option+up'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const doc = project.currentDocument;
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
// TODO: 此处需要增加判断当前节点是否可被操作移动原ve里是用 node.canOperating()来判断
// TODO: 移动逻辑也需要重新梳理,对于移动目标位置的选择,是否可以移入,需要增加判断
const firstNode = selected[0];
const parent = firstNode?.parent;
if (!parent) {
return;
}
const silbing = firstNode.prevSibling;
if (silbing) {
if (silbing.isContainer) {
const place = silbing.getSuitablePlace(firstNode, null);
silbing.insertAfter(place, place.ref);
} else {
parent.insertBefore(firstNode, silbing);
}
firstNode?.select();
} else {
const place = parent.getSuitablePlace(firstNode, null); // upwards
if (place) {
place.container.insertBefore(firstNode, place.ref);
firstNode?.select();
}
}
});
hotkey.bind(['option+down'], (e, action) => {
logger.info(`action ${action} is triggered`);
if (isInLiveEditing()) {
return;
}
const doc = project.getCurrentDocument();
if (isFormEvent(e) || !doc) {
return;
}
e.preventDefault();
const selected = doc.selection.getTopNodes(true);
if (!selected || selected.length < 1) {
return;
}
// TODO: 此处需要增加判断当前节点是否可被操作移动,原 ve 里是用 node.canOperating() 来判断
// TODO: 移动逻辑也需要重新梳理,对于移动目标位置的选择,是否可以移入,需要增加判断
const firstNode = selected[0];
const parent = firstNode?.parent;
if (!parent) {
return;
}
const silbing = firstNode.nextSibling;
if (silbing) {
if (silbing.isContainer) {
// const place = silbing.getSuitablePlace(firstNode, null);
silbing.insertBefore(firstNode, undefined);
// place.container.insertBefore(firstNode, place.ref);
} else {
parent.insertAfter(firstNode, silbing);
}
firstNode?.select();
} else {
const place = parent.getSuitablePlace(firstNode, null); // upwards
if (place) {
place.container.insertAfter(firstNode, place.ref);
firstNode?.select();
}
}
});
},
};
};
builtinHotkey.pluginName = '___builtin_hotkey___';

View File

@ -0,0 +1,20 @@
import { ILowCodePluginContext } from '@alilc/lowcode-types';
export const componentMetaParser = (designer: any) => {
const fun = (ctx: ILowCodePluginContext) => {
return {
init() {
const { material } = ctx;
material.onChangeAssets(() => {
const assets = material.getAssets();
const { components = [] } = assets;
designer.buildComponentMetasMap(components);
});
},
};
};
fun.pluginName = '___component_meta_parser___';
return fun;
};

View File

@ -0,0 +1,97 @@
import { engineConfig } from '@alilc/lowcode-editor-core';
import { ILowCodePluginContext } from '@alilc/lowcode-types';
import { SettingsPrimaryPane } from '@alilc/lowcode-editor-skeleton';
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
import Outline, { getTreeMaster, OutlineBackupPane } from '@alilc/lowcode-plugin-outline-pane';
// 注册默认的面板
export const defaultPanelRegistry = (editor: any, designer: any) => {
const fun = (ctx: ILowCodePluginContext) => {
return {
init() {
const { skeleton, config } = ctx;
skeleton.add({
area: 'mainArea',
name: 'designer',
type: 'Widget',
content: <DesignerPlugin
engineConfig={config}
engineEditor={editor}
/>,
});
if (!config.get('disableDefaultSettingPanel')) {
skeleton.add({
area: 'rightArea',
name: 'settingsPane',
type: 'Panel',
content: SettingsPrimaryPane,
props: {
ignoreRoot: true,
},
});
}
// by default in float area;
let isInFloatArea = true;
const hasPreferenceForOutline = editor
?.getPreference()
?.contains('outline-pane-pinned-status-isFloat', 'skeleton');
if (hasPreferenceForOutline) {
isInFloatArea = editor
?.getPreference()
?.get('outline-pane-pinned-status-isFloat', 'skeleton');
}
skeleton.add({
area: 'leftArea',
name: 'outlinePane',
type: 'PanelDock',
content: {
...Outline,
content: (props: any) => {
const Content = Outline.content;
return (
<Content
engineConfig={config}
engineEditor={editor}
{...props}
/>
);
},
},
panelProps: {
area: isInFloatArea ? 'leftFloatArea' : 'leftFixedArea',
keepVisibleWhileDragging: true,
...config.get('defaultOutlinePaneProps'),
},
contentProps: {
treeTitleExtra: engineConfig.get('treeTitleExtra'),
},
});
skeleton.add({
area: 'rightArea',
name: 'backupOutline',
type: 'Panel',
props: {
condition: () => {
return designer.dragon.dragging && !getTreeMaster(designer).hasVisibleTreeBoard();
},
},
content: () => (
<OutlineBackupPane
engineConfig={config}
engineEditor={editor}
/>
),
});
},
};
};
fun.pluginName = '___default_panel___';
return fun;
};
export default defaultPanelRegistry;

View File

@ -0,0 +1,17 @@
import { ILowCodePluginContext } from '@alilc/lowcode-types';
// 注册默认的 setters
export const setterRegistry = (ctx: ILowCodePluginContext) => {
return {
init() {
const { config } = ctx;
if (config.get('disableDefaultSetters')) return;
const builtinSetters = require('@alilc/lowcode-engine-ext')?.setters;
if (builtinSetters) {
ctx.setters.registerSetter(builtinSetters);
}
},
};
};
setterRegistry.pluginName = '___setter_registry___';

View File

@ -9,8 +9,5 @@ export type EditingTarget = designerCabin.EditingTarget;
export type SaveHandler = designerCabin.SaveHandler;
export type ComponentMeta = designerCabin.ComponentMeta;
export type SettingField = designerCabin.SettingField;
export type ILowCodePluginConfig = designerCabin.ILowCodePluginConfig;
export type ILowCodePluginManager = designerCabin.ILowCodePluginManager;
export type ILowCodePluginContext = designerCabin.ILowCodePluginContext;
export type IPluginConfigCreator = designerCabin.IPluginConfigCreator;
export type PluginPreference = designerCabin.PluginPreference;

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-ignitor",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "点火器bootstrap lce project",
"main": "lib/index.js",
"private": true,

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-plugin-designer",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "alibaba lowcode editor designer plugin",
"files": [
"es",
@ -18,9 +18,9 @@
],
"author": "xiayang.xy",
"dependencies": {
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-editor-core": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-editor-core": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"react": "^16.8.1",
"react-dom": "^16.8.1"
},
@ -38,5 +38,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/plugin-designer"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -5,7 +5,9 @@ import { Asset } from '@alilc/lowcode-utils';
import './index.scss';
export interface PluginProps {
editor: Editor;
// editor?: Editor;
// engineConfig?: any;
engineEditor?: any;
}
interface DesignerPluginState {
@ -46,7 +48,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
}
private async setupAssets() {
const editor = globalContext.get('editor');
const editor = this.props.engineEditor;
try {
const assets = await editor.onceGot('assets');
const renderEnv = engineConfig.get('renderEnv') || editor.get('renderEnv');
@ -85,7 +87,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
}
private handleDesignerMount = (designer: Designer): void => {
const editor = globalContext.get('editor');
const editor = this.props.engineEditor;
editor.set('designer', designer);
editor.emit('designer.ready', designer);
editor.onGot('schema', (schema) => {
@ -94,7 +96,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
};
render(): React.ReactNode {
const editor = globalContext.get('editor');
const editor = this.props.engineEditor;
const {
componentMetadatas,
utilsMetadata,
@ -119,6 +121,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
onMount={this.handleDesignerMount}
className="lowcode-plugin-designer"
editor={editor}
name={editor.name}
designer={editor.get('designer')}
componentMetadatas={componentMetadatas}
simulatorProps={{

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-plugin-outline-pane",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "Outline pane for Ali lowCode engine",
"files": [
"es",
@ -13,10 +13,10 @@
},
"dependencies": {
"@alifd/next": "^1.19.16",
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-editor-core": "1.0.17",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-editor-core": "1.1.0-beta.6",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"react": "^16",
"react-dom": "^16.7.0",
@ -41,5 +41,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/plugin-outline-pane"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -0,0 +1,20 @@
import { globalContext } from '@alilc/lowcode-editor-core';
import { ReactElement } from 'react';
const TREE_TITLE_EXTRA_KEY = 'TREE_TITLE_EXTRA_KEY';
export const registerTreeTitleExtra = (extra: ReactElement) => {
if (extra && !globalContext.has(TREE_TITLE_EXTRA_KEY)) {
globalContext.register(extra, TREE_TITLE_EXTRA_KEY);
}
};
export const getTreeTitleExtra = () => {
try {
return globalContext.get(TREE_TITLE_EXTRA_KEY);
} catch (e) {
// console.error('getTreeTitleExtra Error', e);
}
return null;
};

View File

@ -5,11 +5,12 @@ import { OutlinePane } from './pane';
export const Backup = Symbol.for('backup-outline');
export class OutlineBackupPane extends PureComponent<PluginProps> {
export class OutlineBackupPane extends PureComponent<any> {
render() {
return (
<OutlinePane
editor={globalContext.get('editor')}
editor={this.props.engineEditor}
engineEditor={this.props.engineEditor}
config={{
name: Backup,
}}

View File

@ -6,15 +6,26 @@ import TreeView from './tree';
import './style.less';
import { IEditor } from '@alilc/lowcode-types';
import Filter from './filter';
import { registerTreeTitleExtra } from '../helper/tree-title-extra';
interface Props { config: any; editor: IEditor }
@observer
export class OutlinePane extends Component<{ config: any; editor: IEditor }> {
private main = new OutlineMain(globalContext.get('editor'), this.props.config.name || this.props.config.pluginKey);
export class OutlinePane extends Component<any> {
private main;
constructor(props: Props) {
super(props);
this.main = new OutlineMain(this.props.engineEditor, this.props.config.name || this.props.config.pluginKey);
}
componentWillUnmount() {
this.main.purge();
}
componentDidMount() {
registerTreeTitleExtra(this.props?.config?.contentProps?.treeTitleExtra);
}
render() {
const tree = this.main.currentTree;

View File

@ -13,10 +13,12 @@ import { IconLoop } from '../icons/loop';
import { IconRadioActive } from '../icons/radio-active';
import { IconRadio } from '../icons/radio';
import { IconLock, IconUnlock } from '../icons';
import { getTreeTitleExtra } from '../helper/tree-title-extra';
function emitOutlineEvent(type: string, treeNode: TreeNode, rest?: Record<string, unknown>) {
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const node = treeNode?.node;
const npm = node?.componentMeta?.npm;
const selected =
@ -97,6 +99,7 @@ export default class TreeTitle extends Component<{
};
}
const { filterWorking, matchSelf, keywords } = treeNode.filterReult;
const Extra = getTreeTitleExtra();
return (
<div
@ -153,6 +156,7 @@ export default class TreeTitle extends Component<{
match={filterWorking && matchSelf}
keywords={keywords}
/>
{Extra && <Extra node={treeNode?.node} />}
{node.slotFor && (
<a className="tree-node-tag slot">
{/* todo: click redirect to prop */}

View File

@ -67,7 +67,8 @@ export default class TreeView extends Component<{ tree: Tree }> {
}
} else {
selection.select(id);
const editor = globalContext.get(Editor);
const workSpace = globalContext.get('workSpace');
const editor = workSpace.isActive ? workSpace.window.editor : globalContext.get('editor');
const selectedNode = designer.currentSelection?.getNodes()?.[0];
const npm = selectedNode?.componentMeta?.npm;
const selected =

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-rax-renderer",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"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.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-renderer-core": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"rax-find-dom-node": "^1.0.1"
},
"devDependencies": {
@ -49,5 +49,5 @@
},
"license": "MIT",
"homepage": "https://unpkg.alibaba-inc.com/@alilc/lowcode-rax-renderer@0.1.2/build/index.html",
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-rax-simulator-renderer",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "rax simulator renderer for alibaba lowcode designer",
"main": "lib/index.js",
"module": "es/index.js",
@ -13,10 +13,10 @@
"build:umd": "build-scripts build --config build.umd.json"
},
"dependencies": {
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-rax-renderer": "1.0.17",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-rax-renderer": "1.1.0-beta.6",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"driver-universal": "^3.1.3",
"history": "^5.0.0",
@ -51,5 +51,5 @@
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/rax-simulator-renderer"
},
"homepage": "https://unpkg.alibaba-inc.com/@alilc/lowcode-rax-simulator-renderer@1.0.73/build/index.html",
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -245,7 +245,6 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
constructor() {
this.dispose = host.connect(this, () => {
// sync layout config
// debugger;
this._layout = host.project.get('config').layout;
// todo: split with others, not all should recompute
if (this._libraryMap !== host.libraryMap || this._componentsMap !== host.designer.componentsMap) {

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-react-renderer",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "react renderer for ali lowcode engine",
"main": "lib/index.js",
"module": "es/index.js",
@ -22,7 +22,7 @@
],
"dependencies": {
"@alifd/next": "^1.21.16",
"@alilc/lowcode-renderer-core": "1.0.17"
"@alilc/lowcode-renderer-core": "1.1.0-beta.6"
},
"devDependencies": {
"@alib/build-scripts": "^0.1.18",
@ -43,5 +43,5 @@
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer"
},
"homepage": "https://unpkg.alibaba-inc.com/@alilc/lowcode-react-renderer@1.0.21/build/index.html",
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-react-simulator-renderer",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "react simulator renderer for alibaba lowcode designer",
"main": "lib/index.js",
"module": "es/index.js",
@ -17,10 +17,10 @@
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
},
"dependencies": {
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-react-renderer": "1.0.17",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-react-renderer": "1.1.0-beta.6",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"mobx": "^6.3.0",
"mobx-react": "^7.2.0",
@ -44,5 +44,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/react-simulator-renderer"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -171,6 +171,7 @@ class Renderer extends Component<{
this.schemaChangedSymbol = false;
if (!container.autoRender || isRendererDetached()) return null;
return (
<LowCodeRenderer
locale={locale}

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-renderer-core",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "renderer core",
"license": "MIT",
"main": "lib/index.js",
@ -16,8 +16,8 @@
},
"dependencies": {
"@alilc/lowcode-datasource-engine": "^1.0.0",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"debug": "^4.1.1",
"fetch-jsonp": "^1.1.3",
@ -33,7 +33,7 @@
"devDependencies": {
"@alib/build-scripts": "^0.1.18",
"@alifd/next": "^1.26.0",
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-test-mate": "^1.0.1",
"@babel/plugin-transform-typescript": "^7.16.8",
"@testing-library/react": "^11.2.2",
@ -59,5 +59,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/renderer-core"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-shell",
"version": "1.0.17",
"version": "1.1.0-beta.6",
"description": "Shell Layer for AliLowCodeEngine",
"main": "lib/index.js",
"module": "es/index.js",
@ -15,11 +15,11 @@
},
"license": "MIT",
"dependencies": {
"@alilc/lowcode-designer": "1.0.17",
"@alilc/lowcode-editor-core": "1.0.17",
"@alilc/lowcode-editor-skeleton": "1.0.17",
"@alilc/lowcode-types": "1.0.17",
"@alilc/lowcode-utils": "1.0.17",
"@alilc/lowcode-designer": "1.1.0-beta.6",
"@alilc/lowcode-editor-core": "1.1.0-beta.6",
"@alilc/lowcode-editor-skeleton": "1.1.0-beta.6",
"@alilc/lowcode-types": "1.1.0-beta.6",
"@alilc/lowcode-utils": "1.1.0-beta.6",
"classnames": "^2.2.6",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
@ -57,5 +57,5 @@
"type": "http",
"url": "https://github.com/alibaba/lowcode-engine/tree/main/packages/shell"
},
"gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6"
"gitHead": "af99e922275064495abd78bce42342c0a2614b78"
}

View File

@ -48,7 +48,7 @@ import {
shallowIntl as innerShallowIntl,
createIntl as innerCreateIntl,
intl as innerIntl,
createSetterContent as innerCreateSetterContent,
// createSetterContent as innerCreateSetterContent,
globalLocale as innerGlobalLocale,
obx as innerObx,
observable as innerObservable,
@ -59,7 +59,6 @@ import {
} from '@alilc/lowcode-editor-core';
import { ReactNode } from 'react';
class DesignerCabin implements IPublicCommonDesignerCabin {
private readonly [editorSymbol]: Editor;
/**
@ -225,6 +224,11 @@ class Utils implements IPublicCommonUtils {
}
class EditorCabin {
private readonly [editorSymbol]: Editor;
constructor(editor: Editor) {
this[editorSymbol] = editor;
}
/**
* @deprecated
*/
@ -263,9 +267,10 @@ class EditorCabin {
/**
* @deprecated
*/
createSetterContent(setter: any, props: Record<string, any>): ReactNode {
return innerCreateSetterContent(setter, props);
}
createSetterContent = (setter: any, props: Record<string, any>): ReactNode => {
const setters = this[editorSymbol].get('setters');
return setters.createSetterContent(setter, props);
};
/**
* @deprecated
@ -327,7 +332,7 @@ export default class Common implements IPublicApiCommon {
constructor(editor: Editor, skeleton: InnerSkeleton) {
this.__designerCabin = new DesignerCabin(editor);
this.__skeletonCabin = new SkeletonCabin(skeleton);
this.__editorCabin = new EditorCabin();
this.__editorCabin = new EditorCabin(editor);
this.__utils = new Utils();
}

View File

@ -106,6 +106,7 @@ export default class ComponentMeta implements IPublicModelComponentMeta {
return this[componentMetaSymbol].getMetadata();
}
isComponentMeta = true;
/**
* check if the current node could be placed in parent node
* @param my

View File

@ -33,7 +33,7 @@ import Canvas from './canvas';
import ModalNodesManager from './modal-nodes-manager';
import { documentSymbol, editorSymbol, nodeSymbol } from './symbols';
const Events = {
export const Events = {
IMPORT_SCHEMA: 'shell.document.importSchema',
};

View File

@ -5,6 +5,7 @@ import {
import { dragonSymbol } from './symbols';
import LocateEvent from './locate-event';
import DragObject from './drag-object';
import { globalContext } from '@alilc/lowcode-editor-core';
import {
IPublicModelDragon,
IPublicModelLocateEvent,
@ -13,11 +14,26 @@ import {
DragNodeDataObject,
} from '@alilc/lowcode-types';
export default class Dragon implements IPublicModelDragon {
private readonly [dragonSymbol]: InnerDragon;
export const innerDragonSymbol = Symbol('innerDragonSymbol');
export default class Dragon implements IPublicModelDragon {
constructor(dragon: InnerDragon) {
this[dragonSymbol] = dragon;
this[innerDragonSymbol] = dragon;
}
private readonly [innerDragonSymbol]: InnerDragon;
get [dragonSymbol](): any {
const workSpace = globalContext.get('workSpace');
let editor = globalContext.get('editor');
if (workSpace.isActive) {
editor = workSpace.window.editor;
}
const designer = editor.get('designer');
return designer.dragon;
}
static create(dragon: InnerDragon | null): IPublicModelDragon | null {

View File

@ -1,4 +1,4 @@
import { Editor as InnerEditor } from '@alilc/lowcode-editor-core';
import { Editor as InnerEditor, globalContext } from '@alilc/lowcode-editor-core';
import { getLogger } from '@alilc/lowcode-utils';
import { editorSymbol } from './symbols';
import { IPublicApiEvent } from '@alilc/lowcode-types';
@ -9,8 +9,11 @@ type EventOptions = {
prefix: string;
};
const innerEditorSymbol = Symbol('editor');
export default class Event implements IPublicApiEvent {
private readonly [editorSymbol]: InnerEditor;
private readonly [innerEditorSymbol]: InnerEditor;
// private readonly [editorSymbol]: InnerEditor;
private readonly options: EventOptions;
// TODO:
@ -19,8 +22,20 @@ export default class Event implements IPublicApiEvent {
*/
readonly names = [];
constructor(editor: InnerEditor, options: EventOptions) {
this[editorSymbol] = editor;
get [editorSymbol](): InnerEditor {
if (this.workspaceMode) {
return this[innerEditorSymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.editor;
}
return this[innerEditorSymbol];
}
constructor(editor: InnerEditor, options: EventOptions, public workspaceMode = false) {
this[innerEditorSymbol] = editor;
this.options = options;
if (!this.options.prefix) {
logger.warn('prefix is required while initializing Event');

View File

@ -1,9 +1,29 @@
import { hotkey } from '@alilc/lowcode-editor-core';
import { globalContext, Hotkey as InnerHotkey } from '@alilc/lowcode-editor-core';
import { hotkeySymbol } from './symbols';
import { Disposable, HotkeyCallback, IPublicApiHotkey } from '@alilc/lowcode-types';
const innerHotkeySymbol = Symbol('innerHotkey');
export default class Hotkey implements IPublicApiHotkey {
get callbacks() {
return hotkey.callBacks;
private readonly [innerHotkeySymbol]: InnerHotkey;
get [hotkeySymbol](): InnerHotkey {
if (this.workspaceMode) {
return this[innerHotkeySymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.innerHotkey;
}
return this[innerHotkeySymbol];
}
constructor(hotkey: InnerHotkey, public name: string = 'unknown', public workspaceMode: boolean = false) {
this[innerHotkeySymbol] = hotkey;
}
get callbacks(): any {
return this[hotkeySymbol].callBacks;
}
/**
* @deprecated
@ -19,9 +39,9 @@ export default class Hotkey implements IPublicApiHotkey {
* @returns
*/
bind(combos: string[] | string, callback: HotkeyCallback, action?: string): Disposable {
hotkey.bind(combos, callback, action);
this[hotkeySymbol].bind(combos, callback, action);
return () => {
hotkey.unbind(combos, callback, action);
this[hotkeySymbol].unbind(combos, callback, action);
};
}
}

View File

@ -15,6 +15,8 @@ import Dragon from './dragon';
import SettingPropEntry from './setting-prop-entry';
import SettingTopEntry from './setting-top-entry';
import Common from './common';
import Plugins from './plugins';
import Logger from './logger';
export * from './symbols';
@ -44,4 +46,6 @@ export {
Dragon,
Common,
getEvent,
Plugins,
Logger,
};

View File

@ -0,0 +1,41 @@
import { getLogger } from '@alilc/lowcode-utils';
import { IPublicApiLogger, ILoggerOptions } from '@alilc/lowcode-types';
const innerLoggerSymbol = Symbol('logger');
export default class Logger implements IPublicApiLogger {
private readonly [innerLoggerSymbol]: any;
constructor(options: ILoggerOptions) {
this[innerLoggerSymbol] = getLogger(options as any);
}
/**
* debug info
*/
debug(...args: any | any[]): void {
this[innerLoggerSymbol].debug(...args);
}
/**
* normal info output
*/
info(...args: any | any[]): void {
this[innerLoggerSymbol].info(...args);
}
/**
* warning info output
*/
warn(...args: any | any[]): void {
this[innerLoggerSymbol].warn(...args);
}
/**
* error info output
*/
error(...args: any | any[]): void {
this[innerLoggerSymbol].error(...args);
}
}

View File

@ -1,4 +1,4 @@
import { Editor } from '@alilc/lowcode-editor-core';
import { Editor, globalContext } from '@alilc/lowcode-editor-core';
import {
Designer,
registerMetadataTransducer,
@ -19,13 +19,31 @@ import {
import { editorSymbol, designerSymbol } from './symbols';
import ComponentMeta from './component-meta';
const innerEditorSymbol = Symbol('editor');
export default class Material implements IPublicApiMaterial {
private readonly [editorSymbol]: Editor;
private readonly [designerSymbol]: Designer;
// private readonly [editorSymbol]: Editor;
private readonly [innerEditorSymbol]: Editor;
// private readonly [designerSymbol]: Designer;
constructor(editor: Editor) {
this[editorSymbol] = editor;
this[designerSymbol] = editor.get('designer')!;
get [editorSymbol](): Editor {
if (this.workspaceMode) {
return this[innerEditorSymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.editor;
}
return this[innerEditorSymbol];
}
get [designerSymbol](): Designer {
return this[editorSymbol].get('designer')!;
}
constructor(editor: Editor, public workspaceMode: boolean = false, public name: string = 'unknown') {
this[innerEditorSymbol] = editor;
// this[designerSymbol] = editor.get('designer')!;
}
/**
@ -52,6 +70,10 @@ export default class Material implements IPublicApiMaterial {
return this[editorSymbol].get('assets');
}
async asyncGetAssets() {
return await this[editorSymbol].get('assets');
}
/**
*
* @param incrementalAssets

View File

@ -10,11 +10,11 @@ export default class NodeChildren implements IPublicModelNodeChildren {
this[nodeChildrenSymbol] = nodeChildren;
}
static create(nodeChldren: InnerNodeChildren | null): IPublicModelNodeChildren | null {
if (!nodeChldren) {
static create(nodeChildren: InnerNodeChildren | null): IPublicModelNodeChildren | null {
if (!nodeChildren) {
return null;
}
return new NodeChildren(nodeChldren);
return new NodeChildren(nodeChildren);
}
/**

View File

@ -527,4 +527,8 @@ export default class Node implements IPublicModelNode {
internalToShellNode() {
return this;
}
canPerformAction(actionName: string): boolean {
return this[nodeSymbol].canPerformAction(actionName);
}
}

View File

@ -0,0 +1,64 @@
import {
LowCodePluginManager,
} from '@alilc/lowcode-designer';
import { globalContext } from '@alilc/lowcode-editor-core';
import {
IPublicApiPlugins,
ILowCodePluginContext,
ILowCodePluginConfig,
ILowCodeRegisterOptions,
PreferenceValueType,
} from '@alilc/lowcode-types';
import { pluginsSymbol } from './symbols';
const innerPluginsSymbol = Symbol('plugin');
export default class Plugins implements IPublicApiPlugins {
private readonly [innerPluginsSymbol]: LowCodePluginManager;
get [pluginsSymbol](): LowCodePluginManager {
if (this.workspaceMode) {
return this[innerPluginsSymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.innerPlugins;
}
return this[innerPluginsSymbol];
}
constructor(plugins: LowCodePluginManager, public workspaceMode: boolean = false) {
this[innerPluginsSymbol] = plugins;
}
async register(
pluginConfigCreator: (ctx: ILowCodePluginContext, options: any) => ILowCodePluginConfig,
options?: any,
registerOptions?: ILowCodeRegisterOptions,
): Promise<void> {
await this[pluginsSymbol].register(pluginConfigCreator, options, registerOptions);
}
async init(registerOptions: any) {
await this[pluginsSymbol].init(registerOptions);
}
getPluginPreference(pluginName: string): Record<string, PreferenceValueType> | null | undefined {
return this[pluginsSymbol].getPluginPreference(pluginName);
}
toProxy() {
return new Proxy(this, {
get(target, prop, receiver) {
const _target = target[pluginsSymbol];
if (_target.pluginsMap.has(prop as string)) {
// 禁用态的插件,直接返回 undefined
if (_target.pluginsMap.get(prop as string)!.disabled) {
return undefined;
}
return _target.pluginsMap.get(prop as string)?.toProxy();
}
return Reflect.get(target, prop, receiver);
},
});
}
}

View File

@ -3,6 +3,7 @@ import {
Project as InnerProject,
TransformStage,
} from '@alilc/lowcode-designer';
import { globalContext } from '@alilc/lowcode-editor-core';
import {
RootSchema,
ProjectSchema,
@ -12,18 +13,32 @@ import {
IPublicModelDocumentModel,
PropsTransducer,
} from '@alilc/lowcode-types';
import DocumentModel from './document-model';
import SimulatorHost from './simulator-host';
import { editorSymbol, projectSymbol, simulatorHostSymbol, simulatorRendererSymbol, documentSymbol } from './symbols';
const innerProjectSymbol = Symbol('innerProject');
export default class Project implements IPublicApiProject {
private readonly [projectSymbol]: InnerProject;
private readonly [editorSymbol]: IEditor;
private readonly [innerProjectSymbol]: InnerProject;
private [simulatorHostSymbol]: BuiltinSimulatorHost;
private [simulatorRendererSymbol]: any;
get [projectSymbol](): InnerProject {
if (this.workspaceMode) {
return this[innerProjectSymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.innerProject;
}
constructor(project: InnerProject) {
this[projectSymbol] = project;
return this[innerProjectSymbol];
}
constructor(project: InnerProject, public workspaceMode: boolean = false) {
this[innerProjectSymbol] = project;
this[editorSymbol] = project?.designer.editor;
}
@ -122,6 +137,7 @@ export default class Project implements IPublicApiProject {
*/
importSchema(schema?: ProjectSchema): void {
this[projectSymbol].load(schema, true);
// this[editorSymbol].emit(Events.IMPORT_SCHEMA, schema);
}
/**

View File

@ -92,7 +92,7 @@ export default class Selection implements IPublicModelSelection {
* getTopNodes() will return [A, B], subA will be removed
* @returns
*/
getTopNodes(): Array<IPublicModelNode | null> {
return this[selectionSymbol].getTopNodes().map((node: InnerNode) => Node.create(node));
getTopNodes(includeRoot: boolean = false): Array<IPublicModelNode | null> {
return this[selectionSymbol].getTopNodes(includeRoot).map((node: InnerNode) => Node.create(node));
}
}

View File

@ -1,15 +1,38 @@
import { getSetter, registerSetter, getSettersMap } from '@alilc/lowcode-editor-core';
import { CustomView, IPublicApiSetters, RegisteredSetter } from '@alilc/lowcode-types';
import { Setters as InnerSetters, globalContext } from '@alilc/lowcode-editor-core';
import { ReactNode } from 'react';
const innerSettersSymbol = Symbol('setters');
const settersSymbol = Symbol('setters');
export default class Setters implements IPublicApiSetters {
readonly [innerSettersSymbol]: InnerSetters;
get [settersSymbol](): InnerSetters {
if (this.workspaceMode) {
return this[innerSettersSymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.innerSetters;
}
return this[innerSettersSymbol];
}
constructor(innerSetters: InnerSetters, readonly workspaceMode = false) {
this[innerSettersSymbol] = innerSetters;
}
/**
* setter
* @param type
* @returns
*/
getSetter(type: string): RegisteredSetter | null {
return getSetter(type);
}
getSetter = (type: string) => {
return this[settersSymbol].getSetter(type);
};
/**
* settersMap
@ -18,7 +41,7 @@ export default class Setters implements IPublicApiSetters {
getSettersMap(): Map<string, RegisteredSetter & {
type: string;
}> {
return getSettersMap();
return this[settersSymbol].getSettersMap();
}
/**
@ -27,10 +50,14 @@ export default class Setters implements IPublicApiSetters {
* @param setter
* @returns
*/
registerSetter(
registerSetter = (
typeOrMaps: string | { [key: string]: CustomView | RegisteredSetter },
setter?: CustomView | RegisteredSetter | undefined,
) {
return registerSetter(typeOrMaps, setter);
}
) => {
return this[settersSymbol].registerSetter(typeOrMaps, setter);
};
createSetterContent = (setter: any, props: Record<string, any>): ReactNode => {
return this[settersSymbol].createSetterContent(setter, props);
};
}

View File

@ -1,3 +1,4 @@
import { globalContext } from '@alilc/lowcode-editor-core';
import {
Skeleton as InnerSkeleton,
SkeletonEvents,
@ -5,11 +6,24 @@ import {
import { skeletonSymbol } from './symbols';
import { IPublicApiSkeleton, IWidgetBaseConfig, IWidgetConfigArea } from '@alilc/lowcode-types';
const innerSkeletonSymbol = Symbol('skeleton');
export default class Skeleton implements IPublicApiSkeleton {
private readonly [skeletonSymbol]: InnerSkeleton;
private readonly [innerSkeletonSymbol]: InnerSkeleton;
constructor(skeleton: InnerSkeleton) {
this[skeletonSymbol] = skeleton;
get [skeletonSymbol]() {
if (this.workspaceMode) {
return this[innerSkeletonSymbol];
}
const workSpace = globalContext.get('workSpace');
if (workSpace.isActive) {
return workSpace.window.innerSkeleton;
}
return this[innerSkeletonSymbol];
}
constructor(skeleton: InnerSkeleton, readonly workspaceMode: boolean = false) {
this[innerSkeletonSymbol] = skeleton;
}
/**

View File

@ -24,4 +24,6 @@ export const simulatorHostSymbol = Symbol('simulatorHost');
export const simulatorRendererSymbol = Symbol('simulatorRenderer');
export const dragObjectSymbol = Symbol('dragObject');
export const locateEventSymbol = Symbol('locateEvent');
export const designerCabinSymbol = Symbol('designerCabin');
export const designerCabinSymbol = Symbol('designerCabin');
export const hotkeySymbol = Symbol('hotkey');
export const pluginsSymbol = Symbol('plugins');

Some files were not shown because too many files have changed in this diff Show More