feat(shell): add editor-view model

This commit is contained in:
liujuping 2023-04-23 17:33:32 +08:00 committed by 林熠
parent c50a0823db
commit 358dde43a4
33 changed files with 397 additions and 188 deletions

View File

@ -0,0 +1,21 @@
---
title: EditorView
sidebar_position: 12
---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicModelEditorView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/editor-view.ts)<br/>
> **@since** v1.1.7
窗口编辑视图
## 类型定义
```
import { IPublicModelPluginContext } from "./plugin-context";
export interface IPublicModelEditorView extends IPublicModelPluginContext {};
```
相关类型定义: [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts)

View File

@ -38,6 +38,22 @@ sidebar_position: 12
关联模型 [IPublicModelResource](./resource)
### currentEditorView
窗口当前视图
`@type {IPublicModelEditorView}`
关联模型 [IPublicModelEditorView](./editor-view)
### editorViews
窗口所有视图
`@type {IPublicModelEditorView[]}`
关联模型 [IPublicModelEditorView](./editor-view)
## 方法
### importSchema

View File

@ -17,6 +17,7 @@ import {
IPublicTypePluginMeta,
IPublicTypePluginRegisterOptions,
IPublicModelWindow,
IPublicEnumPluginRegisterLevel,
} from '@alilc/lowcode-types';
import PluginContext from './plugin-context';
@ -58,6 +59,7 @@ export interface ILowCodePluginContextPrivate {
set canvas(canvas: IPublicApiCanvas);
set workspace(workspace: IPublicApiWorkspace);
set editorWindow(window: IPublicModelWindow);
set registerLevel(level: IPublicEnumPluginRegisterLevel);
}
export interface ILowCodePluginContextApiAssembler {
assembleApis(

View File

@ -18,6 +18,7 @@ import {
IPublicTypeDisposable,
IPublicApiPlugins,
IPublicApiWorkspace,
IPublicEnumPluginRegisterLevel,
} from '@alilc/lowcode-types';
import {
Designer,
@ -138,6 +139,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
context.plugins = plugins;
context.logger = new Logger({ level: 'warn', bizName: `plugin:${pluginName}` });
context.workspace = workspace;
context.registerLevel = IPublicEnumPluginRegisterLevel.Default;
},
};

View File

@ -13,8 +13,6 @@
},
"dependencies": {
"@alifd/next": "^1.19.16",
"@alilc/lowcode-designer": "1.1.6",
"@alilc/lowcode-editor-core": "1.1.6",
"@alilc/lowcode-types": "1.1.6",
"@alilc/lowcode-utils": "1.1.6",
"classnames": "^2.2.6",

View File

@ -16,16 +16,15 @@ import {
IPublicModelDropLocation,
IPublicModelScroller,
IPublicModelScrollTarget,
IPublicModelPluginContext,
IPublicModelLocateEvent,
} from '@alilc/lowcode-types';
import TreeNode from './tree-node';
import { IndentTrack } from '../helper/indent-track';
import DwellTimer from '../helper/dwell-timer';
import { ITreeBoard, TreeMaster } from './tree-master';
import { IOutlinePanelPluginContext, ITreeBoard, TreeMaster } from './tree-master';
export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTypeScrollable {
private pluginContext: IPublicModelPluginContext;
private pluginContext: IOutlinePanelPluginContext;
private treeMaster?: TreeMaster;
@ -100,8 +99,8 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
private _shell: HTMLDivElement | null = null;
constructor(at: string | symbol, pluginContext: IPublicModelPluginContext, treeMaster: TreeMaster) {
this.pluginContext = pluginContext;
constructor(at: string | symbol, treeMaster: TreeMaster) {
this.pluginContext = treeMaster.pluginContext;
this.treeMaster = treeMaster;
this.at = at;
let inited = false;
@ -237,7 +236,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
let { node } = treeNode;
if (isDragNodeObject(dragObject)) {
const newNodes = operationalNodes;
let i = newNodes.length;
let i = newNodes?.length;
let p: any = node;
while (i-- > 0) {
if (newNodes[i].contains(p)) {
@ -482,7 +481,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
const isSlotContainer = treeNode.hasSlots();
const isContainer = treeNode.isContainer();
if (container.isSlot && !treeNode.expanded) {
if (container.isSlotNode && !treeNode.expanded) {
// 未展开,直接定位到内部第一个节点
if (isSlotContainer) {
detail.index = null;

View File

@ -1,67 +1,139 @@
import { isLocationChildrenDetail } from '@alilc/lowcode-utils';
import { IPublicModelPluginContext, IPublicTypeActiveTarget, IPublicModelNode } from '@alilc/lowcode-types';
import { IPublicModelPluginContext, IPublicTypeActiveTarget, IPublicModelNode, IPublicTypeDisposable, IPublicEnumPluginRegisterLevel } from '@alilc/lowcode-types';
import TreeNode from './tree-node';
import { Tree } from './tree';
import EventEmitter from 'events';
import { enUS, zhCN } from '../locale';
import { ReactNode } from 'react';
export interface ITreeBoard {
readonly at: string | symbol;
scrollToNode(treeNode: TreeNode, detail?: any): void;
}
enum EVENT_NAMES {
pluginContextChanged = 'pluginContextChanged',
}
export interface IOutlinePanelPluginContext extends IPublicModelPluginContext {
extraTitle?: string;
intlNode(id: string, params?: object): ReactNode;
intl(id: string, params?: object): string;
getLocale(): string;
}
export class TreeMaster {
readonly pluginContext: IPublicModelPluginContext;
pluginContext: IOutlinePanelPluginContext;
private boards = new Set<ITreeBoard>();
private treeMap = new Map<string, Tree>();
constructor(pluginContext: IPublicModelPluginContext) {
this.pluginContext = pluginContext;
private disposeEvents: (IPublicTypeDisposable | undefined)[] = [];
event = new EventEmitter();
constructor(pluginContext: IPublicModelPluginContext, readonly options: {
extraTitle?: string;
}) {
this.setPluginContext(pluginContext);
const { workspace } = this.pluginContext;
this.initEvent();
if (pluginContext.registerLevel === IPublicEnumPluginRegisterLevel.Workspace) {
workspace.onWindowRendererReady(() => {
this.setPluginContext(workspace.window?.currentEditorView);
let dispose: IPublicTypeDisposable | undefined;
const windowViewTypeChangeEvent = () => {
dispose = workspace.window?.onChangeViewType(() => {
this.setPluginContext(workspace.window?.currentEditorView);
});
};
windowViewTypeChangeEvent();
workspace.onChangeActiveWindow(() => {
windowViewTypeChangeEvent();
this.setPluginContext(workspace.window?.currentEditorView);
dispose && dispose();
});
});
}
}
private setPluginContext(pluginContext: IPublicModelPluginContext | undefined) {
if (!pluginContext) {
return;
}
const { intl, intlNode, getLocale } = pluginContext.common.utils.createIntl({
'en-US': enUS,
'zh-CN': zhCN,
});
let _pluginContext: IOutlinePanelPluginContext = Object.assign(pluginContext, {
intl,
intlNode,
getLocale,
});
_pluginContext.extraTitle = this.options && this.options['extraTitle'];
this.pluginContext = _pluginContext;
this.disposeEvent();
this.initEvent();
this.emitPluginContextChange();
}
private disposeEvent() {
this.disposeEvents.forEach(d => {
d && d();
});
}
private initEvent() {
let startTime: any;
const { event, project, canvas } = this.pluginContext;
canvas.dragon?.onDragstart(() => {
startTime = Date.now() / 1000;
// needs?
this.toVision();
});
canvas.activeTracker?.onChange((target: IPublicTypeActiveTarget) => {
const { node, detail } = target;
const tree = this.currentTree;
if (!tree/* || node.document !== tree.document */) {
return;
}
const treeNode = tree.getTreeNode(node);
if (detail && isLocationChildrenDetail(detail)) {
treeNode.expand(true);
} else {
treeNode.expandParents();
}
this.boards.forEach((board) => {
board.scrollToNode(treeNode, detail);
});
});
canvas.dragon?.onDragend(() => {
const endTime: any = Date.now() / 1000;
const nodes = project.currentDocument?.selection?.getNodes();
event.emit('outlinePane.dragend', {
selected: nodes
?.map((n) => {
if (!n) {
return;
}
const npm = n?.componentMeta?.npm;
return (
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || n?.componentMeta?.componentName
);
})
.join('&'),
time: (endTime - startTime).toFixed(2),
});
});
project.onRemoveDocument((data: {id: string}) => {
const { id } = data;
this.treeMap.delete(id);
});
this.disposeEvents = [
canvas.dragon?.onDragstart(() => {
startTime = Date.now() / 1000;
// needs?
this.toVision();
}),
canvas.activeTracker?.onChange((target: IPublicTypeActiveTarget) => {
const { node, detail } = target;
const tree = this.currentTree;
if (!tree/* || node.document !== tree.document */) {
return;
}
const treeNode = tree.getTreeNode(node);
if (detail && isLocationChildrenDetail(detail)) {
treeNode.expand(true);
} else {
treeNode.expandParents();
}
this.boards.forEach((board) => {
board.scrollToNode(treeNode, detail);
});
}),
canvas.dragon?.onDragend(() => {
const endTime: any = Date.now() / 1000;
const nodes = project.currentDocument?.selection?.getNodes();
event.emit('outlinePane.dragend', {
selected: nodes
?.map((n) => {
if (!n) {
return;
}
const npm = n?.componentMeta?.npm;
return (
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || n?.componentMeta?.componentName
);
})
.join('&'),
time: (endTime - startTime).toFixed(2),
});
}),
project.onRemoveDocument((data: {id: string}) => {
const { id } = data;
this.treeMap.delete(id);
}),
];
}
private toVision() {
@ -86,6 +158,14 @@ export class TreeMaster {
// todo others purge
}
onPluginContextChange(fn: () => void) {
this.event.on(EVENT_NAMES.pluginContextChanged, fn);
}
emitPluginContextChange() {
this.event.emit(EVENT_NAMES.pluginContextChanged);
}
get currentTree(): Tree | null {
const doc = this.pluginContext.project.getCurrentDocument();
if (doc) {
@ -93,7 +173,7 @@ export class TreeMaster {
if (this.treeMap.has(id)) {
return this.treeMap.get(id)!;
}
const tree = new Tree(this.pluginContext);
const tree = new Tree(this);
this.treeMap.set(id, tree);
return tree;
}

View File

@ -2,12 +2,12 @@ import {
IPublicTypeTitleContent,
IPublicTypeLocationChildrenDetail,
IPublicModelNode,
IPublicModelPluginContext,
IPublicTypeDisposable,
} from '@alilc/lowcode-types';
import { isI18nData, isLocationChildrenDetail } from '@alilc/lowcode-utils';
import EventEmitter from 'events';
import { Tree } from './tree';
import { IOutlinePanelPluginContext } from './tree-master';
/**
*
@ -38,7 +38,7 @@ enum EVENT_NAMES {
}
export default class TreeNode {
readonly pluginContext: IPublicModelPluginContext;
readonly pluginContext: IOutlinePanelPluginContext;
event = new EventEmitter();
private _node: IPublicModelNode;
@ -160,9 +160,9 @@ export default class TreeNode {
return this._node;
}
constructor(tree: Tree, node: IPublicModelNode, pluginContext: IPublicModelPluginContext) {
constructor(tree: Tree, node: IPublicModelNode) {
this.tree = tree;
this.pluginContext = pluginContext;
this.pluginContext = tree.pluginContext;
this._node = node;
}

View File

@ -1,12 +1,13 @@
import TreeNode from './tree-node';
import { IPublicModelNode, IPublicModelPluginContext, IPublicTypePropChangeOptions } from '@alilc/lowcode-types';
import { IPublicModelNode, IPublicTypePropChangeOptions } from '@alilc/lowcode-types';
import { IOutlinePanelPluginContext, TreeMaster } from './tree-master';
export class Tree {
private treeNodesMap = new Map<string, TreeNode>();
readonly id: string | undefined;
readonly pluginContext: IPublicModelPluginContext;
readonly pluginContext: IOutlinePanelPluginContext;
get root(): TreeNode | null {
if (this.pluginContext.project.currentDocument?.focusNode) {
@ -15,8 +16,11 @@ export class Tree {
return null;
}
constructor(pluginContext: IPublicModelPluginContext) {
this.pluginContext = pluginContext;
readonly treeMaster: TreeMaster;
constructor(treeMaster: TreeMaster) {
this.treeMaster = treeMaster;
this.pluginContext = treeMaster.pluginContext;
const doc = this.pluginContext.project.currentDocument;
this.id = doc?.id;
@ -51,7 +55,7 @@ export class Tree {
return tnode;
}
const treeNode = new TreeNode(this, node, this.pluginContext);
const treeNode = new TreeNode(this, node);
this.treeNodesMap.set(node.id, treeNode);
return treeNode;
}

View File

@ -1,21 +1,13 @@
import { Pane } from './views/pane';
import { IconOutline } from './icons/outline';
import { IPublicModelPluginContext, IPublicModelDocumentModel } from '@alilc/lowcode-types';
import { enUS, zhCN } from './locale';
import { MasterPaneName, BackupPaneName } from './helper/consts';
import { TreeMaster } from './controllers/tree-master';
import { PaneController } from './controllers/pane-controller';
import { useState } from 'react';
export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
const { skeleton, config, common, event, canvas, project } = ctx;
const { intl, intlNode, getLocale } = common.utils.createIntl({
'en-US': enUS,
'zh-CN': zhCN,
});
ctx.intl = intl;
ctx.intlNode = intlNode;
ctx.getLocale = getLocale;
ctx.extraTitle = options && options['extraTitle'];
const { skeleton, config, canvas, project } = ctx;
let isInFloatArea = true;
const hasPreferenceForOutline = config.getPreference().contains('outline-pane-pinned-status-isFloat', 'skeleton');
@ -26,8 +18,7 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
masterPane: false,
backupPane: false,
};
const treeMaster = new TreeMaster(ctx);
let masterPaneController: PaneController | null = null;
const treeMaster = new TreeMaster(ctx, options);
let backupPaneController: PaneController | null = null;
return {
async init() {
@ -40,16 +31,20 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
name: MasterPaneName,
props: {
icon: IconOutline,
description: intlNode('Outline Tree'),
description: treeMaster.pluginContext.intlNode('Outline Tree'),
},
content: (props: any) => {
masterPaneController = new PaneController(MasterPaneName, ctx, treeMaster);
content: function Context(props: any) {
const [masterPaneController, setMasterPaneController] = useState(new PaneController(MasterPaneName, treeMaster));
treeMaster.onPluginContextChange(() => {
setMasterPaneController(new PaneController(MasterPaneName, treeMaster));
});
return (
<Pane
config={config}
pluginContext={ctx}
treeMaster={treeMaster}
controller={masterPaneController}
key={masterPaneController.id}
{...props}
/>
);
@ -73,10 +68,9 @@ export const OutlinePlugin = (ctx: IPublicModelPluginContext, options: any) => {
hiddenWhenInit: true,
},
content: (props: any) => {
backupPaneController = new PaneController(BackupPaneName, ctx, treeMaster);
backupPaneController = new PaneController(BackupPaneName, treeMaster);
return (
<Pane
pluginContext={ctx}
treeMaster={treeMaster}
controller={backupPaneController}
{...props}

View File

@ -5,11 +5,9 @@ import { Search, Checkbox, Balloon, Divider } from '@alifd/next';
import TreeNode from '../controllers/tree-node';
import { Tree } from '../controllers/tree';
import { matchTreeNode, FILTER_OPTIONS } from './filter-tree';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
export default class Filter extends PureComponent<{
tree: Tree;
pluginContext: IPublicModelPluginContext;
}, {
keywords: string;
filterOps: string[];
@ -53,14 +51,16 @@ export default class Filter extends PureComponent<{
return (
<div className="lc-outline-filter">
{/* @ts-ignore */}
<Search
hasClear
shape="simple"
placeholder={this.props.pluginContext.intl('Filter Node')}
placeholder={this.props.tree.pluginContext.intl('Filter Node')}
className="lc-outline-filter-search-input"
value={keywords}
onChange={this.handleSearchChange}
/>
{/* @ts-ignore */}
<Balloon
v2
align="br"
@ -72,14 +72,17 @@ export default class Filter extends PureComponent<{
</div>
)}
>
{/* @ts-ignore */}
<Checkbox
checked={checkAll}
indeterminate={indeterminate}
onChange={this.handleCheckAll}
>
{this.props.pluginContext.intlNode('Check All')}
{this.props.tree.pluginContext.intlNode('Check All')}
</Checkbox>
{/* @ts-ignore */}
<Divider />
{/* @ts-ignore */}
<Checkbox.Group
value={filterOps}
direction="ver"
@ -91,7 +94,7 @@ export default class Filter extends PureComponent<{
value={op.value}
key={op.value}
>
{this.props.pluginContext.intlNode(op.label)}
{this.props.tree.pluginContext.intlNode(op.label)}
</Checkbox>
))}
</Checkbox.Group>

View File

@ -1,47 +1,71 @@
import React, { PureComponent } from 'react';
import { Loading } from '@alifd/next';
import { PaneController } from '../controllers/pane-controller';
import TreeView from './tree';
import './style.less';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
import Filter from './filter';
import { TreeMaster } from '../controllers/tree-master';
import { Tree } from '../controllers/tree';
import { IPublicTypeDisposable } from '@alilc/lowcode-types';
export class Pane extends PureComponent<{
config: any;
pluginContext: IPublicModelPluginContext;
treeMaster: TreeMaster;
controller: PaneController;
}, {
tree: Tree | null;
}> {
private controller;
private treeMaster: TreeMaster;
private dispose: IPublicTypeDisposable;
constructor(props: any) {
super(props);
const { controller, treeMaster } = props;
this.treeMaster = treeMaster;
this.controller = controller;
this.state = {
tree: treeMaster.currentTree,
};
}
componentWillUnmount() {
this.controller.purge();
this.dispose && this.dispose();
}
componentDidMount() {
this.dispose = this.props.treeMaster.pluginContext.project.onSimulatorRendererReady(() => {
this.setState({
tree: this.props.treeMaster.currentTree,
});
});
}
render() {
const tree = this.treeMaster.currentTree;
const tree = this.state.tree;
if (!tree) {
return (
<div className="lc-outline-pane">
<p className="lc-outline-notice">{this.props.pluginContext.intl('Initializing')}</p>
<p className="lc-outline-notice">
{/* @ts-ignore */}
<Loading
style={{
display: 'block',
marginTop: '40px',
}}
tip={this.props.treeMaster.pluginContext.intl('Initializing')}
/>
</p>
</div>
);
}
return (
<div className="lc-outline-pane">
<Filter tree={tree} pluginContext={this.props.pluginContext} />
<Filter tree={tree} />
<div ref={(shell) => this.controller.mount(shell)} className="lc-outline-tree-container">
<TreeView key={tree.id} tree={tree} pluginContext={this.props.pluginContext} />
<TreeView key={tree.id} tree={tree} />
</div>
</div>
);

View File

@ -2,12 +2,11 @@ import { PureComponent } from 'react';
import classNames from 'classnames';
import TreeNode from '../controllers/tree-node';
import TreeNodeView from './tree-node';
import { IPublicModelPluginContext, IPublicModelExclusiveGroup, IPublicTypeDisposable, IPublicTypeLocationChildrenDetail } from '@alilc/lowcode-types';
import { IPublicModelExclusiveGroup, IPublicTypeDisposable, IPublicTypeLocationChildrenDetail } from '@alilc/lowcode-types';
export default class TreeBranches extends PureComponent<{
treeNode: TreeNode;
isModal?: boolean;
pluginContext: IPublicModelPluginContext;
expanded: boolean;
treeChildren: TreeNode[] | null;
}> {
@ -51,12 +50,11 @@ export default class TreeBranches extends PureComponent<{
return (
<div className="tree-node-branches">
{
!isModal && <TreeNodeSlots treeNode={treeNode} pluginContext={this.props.pluginContext} />
!isModal && <TreeNodeSlots treeNode={treeNode} />
}
<TreeNodeChildren
treeNode={treeNode}
isModal={isModal || false}
pluginContext={this.props.pluginContext}
treeChildren={this.props.treeChildren}
/>
</div>
@ -73,7 +71,6 @@ interface ITreeNodeChildrenState {
class TreeNodeChildren extends PureComponent<{
treeNode: TreeNode;
isModal?: boolean;
pluginContext: IPublicModelPluginContext;
treeChildren: TreeNode[] | null;
}, ITreeNodeChildrenState> {
state: ITreeNodeChildrenState = {
@ -84,8 +81,8 @@ class TreeNodeChildren extends PureComponent<{
};
offLocationChanged: IPublicTypeDisposable | undefined;
componentDidMount() {
const { treeNode, pluginContext } = this.props;
const { project } = pluginContext;
const { treeNode } = this.props;
const { project } = treeNode.pluginContext;
const { filterWorking, matchSelf, keywords } = treeNode.filterReult;
const { dropDetail } = treeNode;
this.setState({
@ -122,13 +119,14 @@ class TreeNodeChildren extends PureComponent<{
let groupContents: any[] = [];
let currentGrp: IPublicModelExclusiveGroup;
const { filterWorking, matchSelf, keywords } = this.state;
const Title = this.props.pluginContext.common.editorCabin.Title;
const Title = this.props.treeNode.pluginContext.common.editorCabin.Title;
const endGroup = () => {
if (groupContents.length > 0) {
children.push(
<div key={currentGrp.id} className="condition-group-container" data-id={currentGrp.firstNode?.id}>
<div className="condition-group-title">
{/* @ts-ignore */}
<Title
title={currentGrp.title}
match={filterWorking && matchSelf}
@ -171,12 +169,12 @@ class TreeNodeChildren extends PureComponent<{
children.push(insertion);
}
}
groupContents.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} pluginContext={this.props.pluginContext} />);
groupContents.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} />);
} else {
if (index === dropIndex) {
children.push(insertion);
}
children.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} pluginContext={this.props.pluginContext} />);
children.push(<TreeNodeView key={child.id} treeNode={child} isModal={isModal} />);
}
});
endGroup();
@ -191,14 +189,13 @@ class TreeNodeChildren extends PureComponent<{
class TreeNodeSlots extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
}> {
render() {
const { treeNode } = this.props;
if (!treeNode.hasSlots()) {
return null;
}
const Title = this.props.pluginContext.common.editorCabin.Title;
const Title = this.props.treeNode.pluginContext.common.editorCabin.Title;
return (
<div
className={classNames('tree-node-slots', {
@ -207,10 +204,11 @@ class TreeNodeSlots extends PureComponent<{
data-id={treeNode.id}
>
<div className="tree-node-slots-title">
<Title title={{ type: 'i18n', intl: this.props.pluginContext.intlNode('Slots') }} />
{/* @ts-ignore */}
<Title title={{ type: 'i18n', intl: this.props.treeNode.pluginContext.intlNode('Slots') }} />
</div>
{treeNode.slots.map(tnode => (
<TreeNodeView key={tnode.id} treeNode={tnode} pluginContext={this.props.pluginContext} />
<TreeNodeView key={tnode.id} treeNode={tnode} />
))}
</div>
);

View File

@ -4,22 +4,24 @@ import TreeNode from '../controllers/tree-node';
import TreeTitle from './tree-title';
import TreeBranches from './tree-branches';
import { IconEyeClose } from '../icons/eye-close';
import { IPublicModelPluginContext, IPublicModelModalNodesManager, IPublicTypeDisposable } from '@alilc/lowcode-types';
import { IPublicModelModalNodesManager, IPublicTypeDisposable } from '@alilc/lowcode-types';
import { IOutlinePanelPluginContext } from '../controllers/tree-master';
class ModalTreeNodeView extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
}, {
treeChildren: TreeNode[] | null;
}> {
private modalNodesManager: IPublicModelModalNodesManager | undefined | null;
readonly pluginContext: IPublicModelPluginContext;
readonly pluginContext: IOutlinePanelPluginContext;
constructor(props: any) {
constructor(props: {
treeNode: TreeNode;
}) {
super(props);
// 模态管理对象
this.pluginContext = props.pluginContext;
this.pluginContext = props.treeNode.pluginContext;
const { project } = this.pluginContext;
this.modalNodesManager = project.currentDocument?.modalNodesManager;
this.state = {
@ -72,7 +74,6 @@ class ModalTreeNodeView extends PureComponent<{
treeChildren={this.state.treeChildren}
expanded={expanded}
isModal
pluginContext={this.pluginContext}
/>
</div>
</div>
@ -83,7 +84,6 @@ class ModalTreeNodeView extends PureComponent<{
export default class TreeNodeView extends PureComponent<{
treeNode: TreeNode;
isModal?: boolean;
pluginContext: IPublicModelPluginContext;
isRootNode?: boolean;
}> {
state: {
@ -134,8 +134,8 @@ export default class TreeNodeView extends PureComponent<{
}
componentDidMount() {
const { treeNode, pluginContext } = this.props;
const { project } = pluginContext;
const { treeNode } = this.props;
const { project } = treeNode.pluginContext;
const doc = project.currentDocument;
@ -178,14 +178,14 @@ export default class TreeNodeView extends PureComponent<{
}
shouldShowModalTreeNode(): boolean {
const { treeNode, isRootNode, pluginContext } = this.props;
const { treeNode, isRootNode } = this.props;
if (!isRootNode) {
// 只在 当前树 的根节点展示模态节点
return false;
}
// 当指定了新的根节点时,要从原始的根节点去获取模态节点
const { project } = pluginContext;
const { project } = treeNode.pluginContext;
const rootNode = project.currentDocument?.root;
const rootTreeNode = treeNode.tree.getTreeNode(rootNode!);
const modalNodes = rootTreeNode.children?.filter((item) => {
@ -234,19 +234,16 @@ export default class TreeNodeView extends PureComponent<{
hidden={this.state.hidden}
locked={this.state.locked}
expandable={this.state.expandable}
pluginContext={this.props.pluginContext}
/>
{shouldShowModalTreeNode &&
<ModalTreeNodeView
treeNode={treeNode}
pluginContext={this.props.pluginContext}
/>
}
<TreeBranches
treeNode={treeNode}
isModal={false}
expanded={this.state.expanded}
pluginContext={this.props.pluginContext}
treeChildren={this.state.treeChildren}
/>
</div>

View File

@ -1,7 +1,7 @@
import { KeyboardEvent, FocusEvent, Fragment, PureComponent } from 'react';
import classNames from 'classnames';
import { createIcon } from '@alilc/lowcode-utils';
import { IPublicModelPluginContext, IPublicApiEvent } from '@alilc/lowcode-types';
import { IPublicApiEvent } from '@alilc/lowcode-types';
import TreeNode from '../controllers/tree-node';
import { IconLock, IconUnlock, IconArrowRight, IconEyeClose, IconEye, IconCond, IconLoop, IconRadioActive, IconRadio, IconSetting } from '../icons';
@ -23,7 +23,6 @@ export default class TreeTitle extends PureComponent<{
hidden: boolean;
locked: boolean;
expandable: boolean;
pluginContext: IPublicModelPluginContext;
}> {
state: {
editing: boolean;
@ -53,7 +52,7 @@ export default class TreeTitle extends PureComponent<{
const { treeNode } = this.props;
const value = (e.target as HTMLInputElement).value || '';
treeNode.setTitleLabel(value);
emitOutlineEvent(this.props.pluginContext.event, 'rename', treeNode, { value });
emitOutlineEvent(this.props.treeNode.pluginContext.event, 'rename', treeNode, { value });
this.cancelEdit();
};
@ -90,7 +89,8 @@ export default class TreeTitle extends PureComponent<{
}
render() {
const { treeNode, isModal, pluginContext } = this.props;
const { treeNode, isModal } = this.props;
const { pluginContext } = treeNode;
const { editing } = this.state;
const isCNode = !treeNode.isRoot();
const { node } = treeNode;
@ -153,7 +153,7 @@ export default class TreeTitle extends PureComponent<{
<IconRadio className="tree-node-modal-radio" />
</div>
)}
{isCNode && <ExpandBtn expandable={this.props.expandable} expanded={this.props.expanded} treeNode={treeNode} pluginContext={this.props.pluginContext} />}
{isCNode && <ExpandBtn expandable={this.props.expandable} expanded={this.props.expanded} treeNode={treeNode} />}
<div className="tree-node-icon">{createIcon(treeNode.icon)}</div>
<div className="tree-node-title-label">
{editing ? (
@ -166,6 +166,7 @@ export default class TreeTitle extends PureComponent<{
/>
) : (
<Fragment>
{/* @ts-ignore */}
<Title
title={this.state.title}
match={filterWorking && matchSelf}
@ -175,6 +176,7 @@ export default class TreeTitle extends PureComponent<{
{node.slotFor && (
<a className="tree-node-tag slot">
{/* todo: click redirect to prop */}
{/* @ts-ignore */}
<Tip>{intlNode('Slot for {prop}', { prop: node.slotFor.key })}</Tip>
</a>
)}
@ -182,6 +184,7 @@ export default class TreeTitle extends PureComponent<{
<a className="tree-node-tag loop">
{/* todo: click todo something */}
<IconLoop />
{/* @ts-ignore */}
<Tip>{intlNode('Loop')}</Tip>
</a>
)}
@ -189,15 +192,16 @@ export default class TreeTitle extends PureComponent<{
<a className="tree-node-tag cond">
{/* todo: click todo something */}
<IconCond />
{/* @ts-ignore */}
<Tip>{intlNode('Conditional')}</Tip>
</a>
)}
</Fragment>
)}
</div>
{shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} pluginContext={this.props.pluginContext} />}
{shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} pluginContext={this.props.pluginContext} />}
{shouldEditBtn && <RenameBtn treeNode={treeNode} pluginContext={this.props.pluginContext} onClick={this.enableEdit} /> }
{shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} />}
{shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} />}
{shouldEditBtn && <RenameBtn treeNode={treeNode} onClick={this.enableEdit} /> }
</div>
);
@ -206,11 +210,10 @@ export default class TreeTitle extends PureComponent<{
class RenameBtn extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
onClick: (e: any) => void;
}> {
render() {
const { intl, common } = this.props.pluginContext;
const { intl, common } = this.props.treeNode.pluginContext;
const Tip = common.editorCabin.Tip;
return (
<div
@ -218,6 +221,7 @@ class RenameBtn extends PureComponent<{
onClick={this.props.onClick}
>
<IconSetting />
{/* @ts-ignore */}
<Tip>{intl('Rename')}</Tip>
</div>
);
@ -226,12 +230,11 @@ class RenameBtn extends PureComponent<{
class LockBtn extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
locked: boolean;
}> {
render() {
const { treeNode, locked } = this.props;
const { intl, common } = this.props.pluginContext;
const { intl, common } = this.props.treeNode.pluginContext;
const Tip = common.editorCabin.Tip;
return (
<div
@ -242,6 +245,7 @@ class LockBtn extends PureComponent<{
}}
>
{locked ? <IconUnlock /> : <IconLock /> }
{/* @ts-ignore */}
<Tip>{locked ? intl('Unlock') : intl('Lock')}</Tip>
</div>
);
@ -251,24 +255,24 @@ class LockBtn extends PureComponent<{
class HideBtn extends PureComponent<{
treeNode: TreeNode;
hidden: boolean;
pluginContext: IPublicModelPluginContext;
}, {
hidden: boolean;
}> {
render() {
const { treeNode, hidden } = this.props;
const { intl, common } = this.props.pluginContext;
const { intl, common } = treeNode.pluginContext;
const Tip = common.editorCabin.Tip;
return (
<div
className="tree-node-hide-btn"
onClick={(e) => {
e.stopPropagation();
emitOutlineEvent(this.props.pluginContext.event, hidden ? 'show' : 'hide', treeNode);
emitOutlineEvent(treeNode.pluginContext.event, hidden ? 'show' : 'hide', treeNode);
treeNode.setHidden(!hidden);
}}
>
{hidden ? <IconEye /> : <IconEyeClose />}
{/* @ts-ignore */}
<Tip>{hidden ? intl('Show') : intl('Hide')}</Tip>
</div>
);
@ -277,7 +281,6 @@ class HideBtn extends PureComponent<{
class ExpandBtn extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
expanded: boolean;
expandable: boolean;
}> {
@ -294,7 +297,7 @@ class ExpandBtn extends PureComponent<{
if (expanded) {
e.stopPropagation();
}
emitOutlineEvent(this.props.pluginContext.event, expanded ? 'collapse' : 'expand', treeNode);
emitOutlineEvent(treeNode.pluginContext.event, expanded ? 'collapse' : 'expand', treeNode);
treeNode.setExpanded(!expanded);
}}
>

View File

@ -2,7 +2,7 @@ import { MouseEvent as ReactMouseEvent, PureComponent } from 'react';
import { isFormEvent, canClickNode, isShaken } from '@alilc/lowcode-utils';
import { Tree } from '../controllers/tree';
import TreeNodeView from './tree-node';
import { IPublicEnumDragObjectType, IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types';
import { IPublicEnumDragObjectType, IPublicModelNode } from '@alilc/lowcode-types';
import TreeNode from '../controllers/tree-node';
function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string {
@ -20,12 +20,21 @@ function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string
export default class TreeView extends PureComponent<{
tree: Tree;
pluginContext: IPublicModelPluginContext;
}> {
private shell: HTMLDivElement | null = null;
private ignoreUpSelected = false;
private boostEvent?: MouseEvent;
state: {
root: TreeNode | null;
} = {
root: null,
};
private hover(e: ReactMouseEvent) {
const { project } = this.props.pluginContext;
const { project } = this.props.tree.pluginContext;
const detecting = project.currentDocument?.detecting;
if (detecting?.enable) {
return;
@ -54,7 +63,7 @@ export default class TreeView extends PureComponent<{
return;
}
const { project, event, canvas } = this.props.pluginContext;
const { project, event, canvas } = this.props.tree.pluginContext;
const doc = project.currentDocument;
const selection = doc?.selection;
const focusNode = doc?.focusNode;
@ -109,10 +118,6 @@ export default class TreeView extends PureComponent<{
return tree.getTreeNodeById(id);
}
private ignoreUpSelected = false;
private boostEvent?: MouseEvent;
private onMouseDown = (e: ReactMouseEvent) => {
if (isFormEvent(e.nativeEvent)) {
return;
@ -127,7 +132,7 @@ export default class TreeView extends PureComponent<{
if (!canClickNode(node, e)) {
return;
}
const { project, canvas } = this.props.pluginContext;
const { project, canvas } = this.props.tree.pluginContext;
const selection = project.currentDocument?.selection;
const focusNode = project.currentDocument?.focusNode;
@ -166,22 +171,16 @@ export default class TreeView extends PureComponent<{
};
private onMouseLeave = () => {
const { pluginContext } = this.props;
const { pluginContext } = this.props.tree;
const { project } = pluginContext;
const doc = project.currentDocument;
doc?.detecting.leave();
};
state: {
root: TreeNode | null
} = {
root: null,
};
componentDidMount() {
const { tree, pluginContext } = this.props;
const { tree } = this.props;
const { root } = tree;
const { project } = pluginContext;
const { project } = tree.pluginContext;
this.setState({ root });
const doc = project.currentDocument;
doc?.onFocusNodeChanged(() => {
@ -208,7 +207,6 @@ export default class TreeView extends PureComponent<{
<TreeNodeView
key={this.state.root?.id}
treeNode={this.state.root}
pluginContext={this.props.pluginContext}
isRootNode
/>
</div>

View File

@ -0,0 +1,27 @@
import { editorViewSymbol, pluginContextSymbol } from '../symbols';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
import { IViewContext } from '@alilc/lowcode-workspace';
export class EditorView {
[editorViewSymbol]: IViewContext;
[pluginContextSymbol]: IPublicModelPluginContext;
constructor(editorView: IViewContext) {
this[editorViewSymbol] = editorView;
this[pluginContextSymbol] = this[editorViewSymbol].innerPlugins._getLowCodePluginContext({
pluginName: '',
});
}
toProxy() {
return new Proxy(this, {
get(target, prop, receiver) {
if ((target[pluginContextSymbol] as any)[prop as string]) {
return Reflect.get(target[pluginContextSymbol], prop, receiver);
}
return Reflect.get(target, prop, receiver);
},
});
}
}

View File

@ -19,3 +19,4 @@ export * from './active-tracker';
export * from './plugin-instance';
export * from './window';
export * from './clipboard';
export * from './editor-view';

View File

@ -2,6 +2,7 @@ import { windowSymbol } from '../symbols';
import { IPublicModelResource, IPublicModelWindow, IPublicTypeDisposable } from '@alilc/lowcode-types';
import { IEditorWindow } from '@alilc/lowcode-workspace';
import { Resource as ShellResource } from './resource';
import { EditorView } from './editor-view';
export class Window implements IPublicModelWindow {
private readonly [windowSymbol]: IEditorWindow;
@ -42,7 +43,11 @@ export class Window implements IPublicModelWindow {
return await this[windowSymbol].save();
}
get plugins() {
return this[windowSymbol].plugins;
get currentEditorView() {
return new EditorView(this[windowSymbol].editorView).toProxy() as any;
}
get editorViews() {
return Array.from(this[windowSymbol].editorViews.values()).map(d => new EditorView(d).toProxy() as any);
}
}

View File

@ -34,3 +34,5 @@ export const resourceSymbol = Symbol('resource');
export const clipboardSymbol = Symbol('clipboard');
export const configSymbol = Symbol('configSymbol');
export const conditionGroupSymbol = Symbol('conditionGroup');
export const editorViewSymbol = Symbol('editorView');
export const pluginContextSymbol = Symbol('pluginContext');

View File

@ -3,3 +3,4 @@ export * from './transition-type';
export * from './transform-stage';
export * from './drag-object-type';
export * from './prop-value-changed-type';
export * from './plugin-register-level';

View File

@ -0,0 +1,6 @@
export enum IPublicEnumPluginRegisterLevel {
Default = 'default',
Workspace = 'workspace',
Resource = 'resource',
EditorView = 'editorView',
}

View File

@ -1,5 +1,5 @@
/* eslint-disable max-len */
import { IPublicTypeDragNodeDataObject, IPublicTypeDragObject } from '../type';
import { IPublicTypeDisposable, IPublicTypeDragNodeDataObject, IPublicTypeDragObject } from '../type';
import { IPublicModelDragObject, IPublicModelLocateEvent, IPublicModelNode } from './';
export interface IPublicModelDragon<
@ -19,7 +19,7 @@ export interface IPublicModelDragon<
* @param func
* @returns
*/
onDragstart(func: (e: LocateEvent) => any): () => void;
onDragstart(func: (e: LocateEvent) => any): IPublicTypeDisposable;
/**
* drag
@ -27,7 +27,7 @@ export interface IPublicModelDragon<
* @param func
* @returns
*/
onDrag(func: (e: LocateEvent) => any): () => void;
onDrag(func: (e: LocateEvent) => any): IPublicTypeDisposable;
/**
* dragend
@ -35,7 +35,7 @@ export interface IPublicModelDragon<
* @param func
* @returns
*/
onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): () => void;
onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): IPublicTypeDisposable;
/**
* shell boost

View File

@ -0,0 +1,3 @@
import { IPublicModelPluginContext } from './plugin-context';
export interface IPublicModelEditorView extends IPublicModelPluginContext {}

View File

@ -30,3 +30,4 @@ export * from './sensor';
export * from './resource';
export * from './clipboard';
export * from './setting-field';
export * from './editor-view';

View File

@ -12,18 +12,11 @@ import {
IPublicApiPlugins,
IPublicApiWorkspace,
} from '../api';
import { IPublicEnumPluginRegisterLevel } from '../enum';
import { IPublicModelEngineConfig } from './';
export interface IPublicModelPluginContext {
/**
* context 使
*
* for plugin developers, costom properties can be add to plugin context
* from inside plugin for convenience.
*/
[key: string]: any;
/**
*
* by using this, init options can be accessed from inside plugin
@ -108,6 +101,12 @@ export interface IPublicModelPluginContext {
* @tutorial https://lowcode-engine.cn/site/docs/api/workspace
*/
get workspace(): IPublicApiWorkspace;
/**
*
* @since v1.1.7
*/
get registerLevel(): IPublicEnumPluginRegisterLevel;
}
/**

View File

@ -1,6 +1,7 @@
import { ReactElement } from 'react';
import { IPublicTypeDisposable, IPublicTypeNodeSchema } from '../type';
import { IPublicModelResource } from './resource';
import { IPublicModelEditorView } from './editor-view';
export interface IPublicModelWindow<
Resource = IPublicModelResource
@ -18,6 +19,18 @@ export interface IPublicModelWindow<
/** 窗口资源类型 */
resource?: Resource;
/**
*
* @since v1.1.7
*/
currentEditorView: IPublicModelEditorView;
/**
*
* @since v1.1.7
*/
editorViews: IPublicModelEditorView[];
/** 当前窗口导入 schema */
importSchema(schema: IPublicTypeNodeSchema): void;

View File

@ -44,6 +44,7 @@ import {
IPublicApiProject,
IPublicApiSetters,
IPublicApiSkeleton,
IPublicEnumPluginRegisterLevel,
IPublicModelPluginContext,
IPublicTypePluginMeta,
} from '@alilc/lowcode-types';
@ -100,7 +101,7 @@ export class BasicContext implements IBasicContext {
preference: IPluginPreferenceMananger;
workspace: IWorkspace;
constructor(innerWorkspace: IWorkspace, viewName: string, public editorWindow?: IEditorWindow) {
constructor(innerWorkspace: IWorkspace, viewName: string, registerLevel: IPublicEnumPluginRegisterLevel, public editorWindow?: IEditorWindow) {
const editor = new Editor(viewName, true);
const innerSkeleton = new InnerSkeleton(editor, viewName);
@ -168,6 +169,7 @@ export class BasicContext implements IBasicContext {
if (editorWindow) {
context.editorWindow = new Window(editorWindow);
}
context.registerLevel = registerLevel;
},
};

View File

@ -1,12 +1,16 @@
import { computed, makeObservable, obx } from '@alilc/lowcode-editor-core';
import { IPublicEditorViewConfig, IPublicTypeEditorView } from '@alilc/lowcode-types';
import { IPublicEditorViewConfig, IPublicEnumPluginRegisterLevel, IPublicTypeEditorView } from '@alilc/lowcode-types';
import { flow } from 'mobx';
import { IWorkspace } from '../workspace';
import { BasicContext } from './base-context';
import { BasicContext, IBasicContext } from './base-context';
import { IEditorWindow } from '../window';
import { getWebviewPlugin } from '../inner-plugins/webview';
export class Context extends BasicContext {
export interface IViewContext extends IBasicContext {
}
export class Context extends BasicContext implements IViewContext {
viewName = 'editor-view';
instance: IPublicEditorViewConfig;
@ -30,7 +34,7 @@ export class Context extends BasicContext {
});
constructor(public workspace: IWorkspace, public editorWindow: IEditorWindow, public editorView: IPublicTypeEditorView, options: Object | undefined) {
super(workspace, editorView.viewName, editorWindow);
super(workspace, editorView.viewName, IPublicEnumPluginRegisterLevel.EditorView, editorWindow);
this.viewType = editorView.viewType || 'editor';
this.viewName = editorView.viewName;
this.instance = editorView(this.innerPlugins._getLowCodePluginContext({

View File

@ -4,3 +4,4 @@ export * from './window';
export * from './layouts/workbench';
export { Resource } from './resource';
export type { IResource } from './resource';
export type { IViewContext } from './context/view-context';

View File

@ -1,5 +1,5 @@
import { ISkeleton } from '@alilc/lowcode-editor-skeleton';
import { IPublicTypeEditorView, IPublicResourceData, IPublicResourceTypeConfig, IBaseModelResource } from '@alilc/lowcode-types';
import { IPublicTypeEditorView, IPublicResourceData, IPublicResourceTypeConfig, IBaseModelResource, IPublicEnumPluginRegisterLevel } from '@alilc/lowcode-types';
import { Logger } from '@alilc/lowcode-utils';
import { BasicContext, IBasicContext } from './context/base-context';
import { ResourceType, IResourceType } from './resource-type';
@ -75,7 +75,7 @@ export class Resource implements IResource {
}
constructor(readonly resourceData: IPublicResourceData, readonly resourceType: IResourceType, readonly workspace: IWorkspace) {
this.context = new BasicContext(workspace, `resource-${resourceData.resourceName || resourceType.name}`);
this.context = new BasicContext(workspace, `resource-${resourceData.resourceName || resourceType.name}`, IPublicEnumPluginRegisterLevel.Resource);
this.resourceTypeInstance = resourceType.resourceTypeModel(this.context.innerPlugins._getLowCodePluginContext({
pluginName: '',
}), this.options);

View File

@ -1,6 +1,6 @@
import { uniqueId } from '@alilc/lowcode-utils';
import { createModuleEventBus, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core';
import { Context } from './context/view-context';
import { Context, IViewContext } from './context/view-context';
import { IWorkspace } from './workspace';
import { IResource } from './resource';
import { IPublicTypeDisposable } from '../../types/es/shell/type/disposable';
@ -13,10 +13,12 @@ interface IWindowCOnfig {
sleep?: boolean;
}
export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'changeViewType'> {
export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'changeViewType' | 'currentEditorView' | 'editorViews'> {
readonly resource: IResource;
editorViews: Map<string, Context>;
editorViews: Map<string, IViewContext>;
editorView: IViewContext;
changeViewType: (name: string, ignoreEmit?: boolean) => void;
@ -71,6 +73,9 @@ export class EditorWindow implements IEditorWindow {
async save() {
const value: any = {};
const editorViews = this.resource.editorViews;
if (!editorViews) {
return;
}
for (let i = 0; i < editorViews.length; i++) {
const name = editorViews[i].viewName;
const saveResult = await this.editorViews.get(name)?.save();

View File

@ -1,6 +1,6 @@
import { IDesigner, ILowCodePluginManager, LowCodePluginManager } from '@alilc/lowcode-designer';
import { createModuleEventBus, Editor, IEditor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core';
import { IPublicApiPlugins, IPublicApiWorkspace, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types';
import { IPublicApiPlugins, IPublicApiWorkspace, IPublicEnumPluginRegisterLevel, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types';
import { BasicContext } from './context/base-context';
import { EditorWindow } from './window';
import type { IEditorWindow } from './window';
@ -94,7 +94,7 @@ export class Workspace implements IWorkspace {
readonly registryInnerPlugin: (designer: IDesigner, editor: IEditor, plugins: IPublicApiPlugins) => Promise<IPublicTypeDisposable>,
readonly shellModelFactory: any,
) {
this.context = new BasicContext(this, '');
this.context = new BasicContext(this, '', IPublicEnumPluginRegisterLevel.Workspace);
makeObservable(this);
}