mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-11 18:42:56 +00:00
feat: optimize outline tree performance and ts definition
This commit is contained in:
parent
95a1137b46
commit
eeb6719a1f
@ -5,14 +5,13 @@ import {
|
|||||||
IPublicTypeProjectSchema,
|
IPublicTypeProjectSchema,
|
||||||
IPublicTypeRootSchema,
|
IPublicTypeRootSchema,
|
||||||
IPublicTypeComponentsMap,
|
IPublicTypeComponentsMap,
|
||||||
IPublicApiProject,
|
|
||||||
IPublicModelDocumentModel,
|
|
||||||
IPublicEnumTransformStage,
|
IPublicEnumTransformStage,
|
||||||
|
IBaseApiProject,
|
||||||
} from '@alilc/lowcode-types';
|
} from '@alilc/lowcode-types';
|
||||||
import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils';
|
import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils';
|
||||||
import { ISimulatorHost } from '../simulator';
|
import { ISimulatorHost } from '../simulator';
|
||||||
|
|
||||||
export interface IProject extends Omit< IPublicApiProject<
|
export interface IProject extends Omit< IBaseApiProject<
|
||||||
IDocumentModel
|
IDocumentModel
|
||||||
>,
|
>,
|
||||||
'simulatorHost' |
|
'simulatorHost' |
|
||||||
|
|||||||
@ -444,7 +444,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
|
|||||||
event: e,
|
event: e,
|
||||||
detail: {
|
detail: {
|
||||||
type: IPublicTypeLocationDetailType.Children,
|
type: IPublicTypeLocationDetailType.Children,
|
||||||
index: index + 1,
|
index: (index || 0) + 1,
|
||||||
valid: document?.checkNesting(node.parent!, dragObject as any),
|
valid: document?.checkNesting(node.parent!, dragObject as any),
|
||||||
near: { node, pos: 'after' },
|
near: { node, pos: 'after' },
|
||||||
focus: checkRecursion(focusNode, dragObject) ? { type: 'node', node: focusNode } : undefined,
|
focus: checkRecursion(focusNode, dragObject) ? { type: 'node', node: focusNode } : undefined,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
import { IconFilter } from '../icons/filter';
|
import { IconFilter } from '../icons/filter';
|
||||||
import { Search, Checkbox, Balloon, Divider } from '@alifd/next';
|
import { Search, Checkbox, Balloon, Divider } from '@alifd/next';
|
||||||
@ -7,7 +7,7 @@ import { Tree } from '../controllers/tree';
|
|||||||
import { matchTreeNode, FILTER_OPTIONS } from './filter-tree';
|
import { matchTreeNode, FILTER_OPTIONS } from './filter-tree';
|
||||||
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
|
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
export default class Filter extends Component<{
|
export default class Filter extends PureComponent<{
|
||||||
tree: Tree;
|
tree: Tree;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { PaneController } from '../controllers/pane-controller';
|
import { PaneController } from '../controllers/pane-controller';
|
||||||
import TreeView from './tree';
|
import TreeView from './tree';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
@ -6,7 +6,7 @@ import { IPublicModelPluginContext } from '@alilc/lowcode-types';
|
|||||||
import Filter from './filter';
|
import Filter from './filter';
|
||||||
import { TreeMaster } from '../controllers/tree-master';
|
import { TreeMaster } from '../controllers/tree-master';
|
||||||
|
|
||||||
export class Pane extends Component<{
|
export class Pane extends PureComponent<{
|
||||||
config: any;
|
config: any;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
treeMaster: TreeMaster;
|
treeMaster: TreeMaster;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { Component } from 'react';
|
import { PureComponent } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import TreeNode from '../controllers/tree-node';
|
import TreeNode from '../controllers/tree-node';
|
||||||
import TreeNodeView from './tree-node';
|
import TreeNodeView from './tree-node';
|
||||||
import { IPublicModelPluginContext, IPublicModelExclusiveGroup, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
import { IPublicModelPluginContext, IPublicModelExclusiveGroup, IPublicTypeDisposable, IPublicTypeLocationChildrenDetail } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
export default class TreeBranches extends Component<{
|
export default class TreeBranches extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
isModal?: boolean;
|
isModal?: boolean;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
@ -62,12 +62,19 @@ export default class TreeBranches extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TreeNodeChildren extends Component<{
|
|
||||||
|
interface ITreeNodeChildrenState {
|
||||||
|
filterWorking: boolean;
|
||||||
|
matchSelf: boolean;
|
||||||
|
keywords: string | null;
|
||||||
|
dropDetail: IPublicTypeLocationChildrenDetail | undefined | null;
|
||||||
|
}
|
||||||
|
class TreeNodeChildren extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
isModal?: boolean;
|
isModal?: boolean;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
}> {
|
}, ITreeNodeChildrenState> {
|
||||||
state = {
|
state: ITreeNodeChildrenState = {
|
||||||
filterWorking: false,
|
filterWorking: false,
|
||||||
matchSelf: false,
|
matchSelf: false,
|
||||||
keywords: null,
|
keywords: null,
|
||||||
@ -144,7 +151,7 @@ class TreeNodeChildren extends Component<{
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
treeNode.children?.forEach((child, index) => {
|
treeNode.children?.forEach((child, index) => {
|
||||||
const childIsModal = child.node.componentMeta.isModal || false;
|
const childIsModal = child.node.componentMeta?.isModal || false;
|
||||||
if (isModal != childIsModal) {
|
if (isModal != childIsModal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -180,7 +187,7 @@ class TreeNodeChildren extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TreeNodeSlots extends Component<{
|
class TreeNodeSlots extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
}> {
|
}> {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component } from 'react';
|
import { PureComponent } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import TreeNode from '../controllers/tree-node';
|
import TreeNode from '../controllers/tree-node';
|
||||||
import TreeTitle from './tree-title';
|
import TreeTitle from './tree-title';
|
||||||
@ -6,7 +6,7 @@ import TreeBranches from './tree-branches';
|
|||||||
import { IconEyeClose } from '../icons/eye-close';
|
import { IconEyeClose } from '../icons/eye-close';
|
||||||
import { IPublicModelPluginContext, IPublicModelModalNodesManager, IPublicModelDocumentModel, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
import { IPublicModelPluginContext, IPublicModelModalNodesManager, IPublicModelDocumentModel, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
class ModalTreeNodeView extends Component<{
|
class ModalTreeNodeView extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
}> {
|
}> {
|
||||||
@ -59,11 +59,11 @@ class ModalTreeNodeView extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TreeNodeView extends Component<{
|
export default class TreeNodeView extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
isModal?: boolean;
|
isModal?: boolean;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
isRootNode: boolean;
|
isRootNode?: boolean;
|
||||||
}> {
|
}> {
|
||||||
state = {
|
state = {
|
||||||
expanded: false,
|
expanded: false,
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable max-len */
|
import { KeyboardEvent, FocusEvent, Fragment, PureComponent } from 'react';
|
||||||
import { Component, KeyboardEvent, FocusEvent, Fragment } from 'react';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { createIcon } from '@alilc/lowcode-utils';
|
import { createIcon } from '@alilc/lowcode-utils';
|
||||||
import { IPublicModelPluginContext, IPublicApiEvent } from '@alilc/lowcode-types';
|
import { IPublicModelPluginContext, IPublicApiEvent } from '@alilc/lowcode-types';
|
||||||
@ -17,7 +16,7 @@ function emitOutlineEvent(event: IPublicApiEvent, type: string, treeNode: TreeNo
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TreeTitle extends Component<{
|
export default class TreeTitle extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
isModal?: boolean;
|
isModal?: boolean;
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
@ -36,7 +35,7 @@ export default class TreeTitle extends Component<{
|
|||||||
|
|
||||||
private lastInput?: HTMLInputElement;
|
private lastInput?: HTMLInputElement;
|
||||||
|
|
||||||
private enableEdit = (e) => {
|
private enableEdit = (e: MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.setState({
|
this.setState({
|
||||||
editing: true,
|
editing: true,
|
||||||
@ -205,7 +204,7 @@ export default class TreeTitle extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RenameBtn extends Component<{
|
class RenameBtn extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
onClick: (e: any) => void;
|
onClick: (e: any) => void;
|
||||||
@ -225,7 +224,7 @@ class RenameBtn extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LockBtn extends Component<{
|
class LockBtn extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
locked: boolean;
|
locked: boolean;
|
||||||
@ -249,7 +248,7 @@ class LockBtn extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HideBtn extends Component<{
|
class HideBtn extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
hidden: boolean;
|
hidden: boolean;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
@ -276,7 +275,7 @@ class HideBtn extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExpandBtn extends Component<{
|
class ExpandBtn extends PureComponent<{
|
||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { Component, MouseEvent as ReactMouseEvent } from 'react';
|
import { MouseEvent as ReactMouseEvent, PureComponent } from 'react';
|
||||||
import { isFormEvent, canClickNode, isShaken } from '@alilc/lowcode-utils';
|
import { isFormEvent, canClickNode, isShaken } from '@alilc/lowcode-utils';
|
||||||
import { Tree } from '../controllers/tree';
|
import { Tree } from '../controllers/tree';
|
||||||
import TreeNodeView from './tree-node';
|
import TreeNodeView from './tree-node';
|
||||||
import { IPublicEnumDragObjectType, IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types';
|
import { IPublicEnumDragObjectType, IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types';
|
||||||
|
import TreeNode from '../controllers/tree-node';
|
||||||
|
|
||||||
function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string {
|
function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string {
|
||||||
let target: Element | null = e.target as Element;
|
let target: Element | null = e.target as Element;
|
||||||
@ -17,7 +18,7 @@ function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string
|
|||||||
return (target as HTMLDivElement).dataset.id || null;
|
return (target as HTMLDivElement).dataset.id || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TreeView extends Component<{
|
export default class TreeView extends PureComponent<{
|
||||||
tree: Tree;
|
tree: Tree;
|
||||||
pluginContext: IPublicModelPluginContext;
|
pluginContext: IPublicModelPluginContext;
|
||||||
}> {
|
}> {
|
||||||
@ -60,12 +61,12 @@ export default class TreeView extends Component<{
|
|||||||
const { id } = node;
|
const { id } = node;
|
||||||
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
||||||
canvas.activeTracker?.track(node);
|
canvas.activeTracker?.track(node);
|
||||||
if (isMulti && !node.contains(focusNode) && selection.has(id)) {
|
if (isMulti && focusNode && !node.contains(focusNode) && selection?.has(id)) {
|
||||||
if (!isFormEvent(e.nativeEvent)) {
|
if (!isFormEvent(e.nativeEvent)) {
|
||||||
selection.remove(id);
|
selection.remove(id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selection.select(id);
|
selection?.select(id);
|
||||||
const selectedNode = selection?.getNodes()?.[0];
|
const selectedNode = selection?.getNodes()?.[0];
|
||||||
const npm = selectedNode?.componentMeta?.npm;
|
const npm = selectedNode?.componentMeta?.npm;
|
||||||
const selected =
|
const selected =
|
||||||
@ -134,21 +135,23 @@ export default class TreeView extends Component<{
|
|||||||
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
|
||||||
const isLeftButton = e.button === 0;
|
const isLeftButton = e.button === 0;
|
||||||
|
|
||||||
if (isLeftButton && !node.contains(focusNode)) {
|
if (isLeftButton && focusNode && !node.contains(focusNode)) {
|
||||||
let nodes: IPublicModelNode[] = [node];
|
let nodes: IPublicModelNode[] = [node];
|
||||||
this.ignoreUpSelected = false;
|
this.ignoreUpSelected = false;
|
||||||
if (isMulti) {
|
if (isMulti) {
|
||||||
// multi select mode, directily add
|
// multi select mode, directily add
|
||||||
if (!selection.has(node.id)) {
|
if (!selection?.has(node.id)) {
|
||||||
canvas.activeTracker?.track(node);
|
canvas.activeTracker?.track(node);
|
||||||
selection.add(node.id);
|
selection?.add(node.id);
|
||||||
this.ignoreUpSelected = true;
|
this.ignoreUpSelected = true;
|
||||||
}
|
}
|
||||||
// todo: remove rootNodes id
|
// todo: remove rootNodes id
|
||||||
selection.remove(focusNode.id);
|
selection?.remove(focusNode.id);
|
||||||
// 获得顶层 nodes
|
// 获得顶层 nodes
|
||||||
nodes = selection.getTopNodes();
|
if (selection) {
|
||||||
} else if (selection.has(node.id)) {
|
nodes = selection.getTopNodes();
|
||||||
|
}
|
||||||
|
} else if (selection?.has(node.id)) {
|
||||||
nodes = selection.getTopNodes();
|
nodes = selection.getTopNodes();
|
||||||
}
|
}
|
||||||
this.boostEvent = e.nativeEvent;
|
this.boostEvent = e.nativeEvent;
|
||||||
@ -169,7 +172,9 @@ export default class TreeView extends Component<{
|
|||||||
doc?.detecting.leave();
|
doc?.detecting.leave();
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state: {
|
||||||
|
root: TreeNode | null
|
||||||
|
} = {
|
||||||
root: null,
|
root: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { Component, ReactNode } from 'react';
|
import { Component, ReactNode } from 'react';
|
||||||
import { IPublicTypeNodeSchema } from '../type';
|
import { IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type';
|
||||||
import { IPublicEnumTransitionType } from '../enum';
|
import { IPublicEnumTransitionType } from '../enum';
|
||||||
|
|
||||||
export interface IPublicApiCommonUtils {
|
export interface IPublicApiCommonUtils {
|
||||||
@ -82,12 +82,16 @@ export interface IPublicApiCommonEditorCabin {
|
|||||||
* Title 组件
|
* Title 组件
|
||||||
* @experimental unstable API, pay extra caution when trying to use this
|
* @experimental unstable API, pay extra caution when trying to use this
|
||||||
*/
|
*/
|
||||||
get Tip(): Component;
|
get Tip(): React.FC<{}>;
|
||||||
/**
|
/**
|
||||||
* Tip 组件
|
* Tip 组件
|
||||||
* @experimental unstable API, pay extra caution when trying to use this
|
* @experimental unstable API, pay extra caution when trying to use this
|
||||||
*/
|
*/
|
||||||
get Title(): Component;
|
get Title(): React.FC<{
|
||||||
|
title: IPublicTypeTitleContent | undefined;
|
||||||
|
match?: boolean;
|
||||||
|
keywords?: string | null;
|
||||||
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPublicApiCommonDesignerCabin {
|
export interface IPublicApiCommonDesignerCabin {
|
||||||
|
|||||||
@ -3,8 +3,8 @@ import { IPublicEnumTransformStage } from '../enum';
|
|||||||
import { IPublicApiSimulatorHost } from './';
|
import { IPublicApiSimulatorHost } from './';
|
||||||
import { IPublicModelDocumentModel } from '../model';
|
import { IPublicModelDocumentModel } from '../model';
|
||||||
|
|
||||||
export interface IPublicApiProject<
|
export interface IBaseApiProject<
|
||||||
DocumentModel = IPublicModelDocumentModel
|
DocumentModel
|
||||||
> {
|
> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,3 +133,5 @@ export interface IPublicApiProject<
|
|||||||
*/
|
*/
|
||||||
setI18n(value: object): void;
|
setI18n(value: object): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPublicApiProject extends IBaseApiProject<IPublicModelDocumentModel> {}
|
||||||
Loading…
x
Reference in New Issue
Block a user