feat: optimize outline tree performance and ts definition

This commit is contained in:
liujuping 2023-03-15 16:17:18 +08:00 committed by 林熠
parent 95a1137b46
commit eeb6719a1f
10 changed files with 60 additions and 44 deletions

View File

@ -5,14 +5,13 @@ import {
IPublicTypeProjectSchema,
IPublicTypeRootSchema,
IPublicTypeComponentsMap,
IPublicApiProject,
IPublicModelDocumentModel,
IPublicEnumTransformStage,
IBaseApiProject,
} from '@alilc/lowcode-types';
import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils';
import { ISimulatorHost } from '../simulator';
export interface IProject extends Omit< IPublicApiProject<
export interface IProject extends Omit< IBaseApiProject<
IDocumentModel
>,
'simulatorHost' |

View File

@ -444,7 +444,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicTy
event: e,
detail: {
type: IPublicTypeLocationDetailType.Children,
index: index + 1,
index: (index || 0) + 1,
valid: document?.checkNesting(node.parent!, dragObject as any),
near: { node, pos: 'after' },
focus: checkRecursion(focusNode, dragObject) ? { type: 'node', node: focusNode } : undefined,

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { PureComponent } from 'react';
import './style.less';
import { IconFilter } from '../icons/filter';
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 { IPublicModelPluginContext } from '@alilc/lowcode-types';
export default class Filter extends Component<{
export default class Filter extends PureComponent<{
tree: Tree;
pluginContext: IPublicModelPluginContext;
}, {

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { PureComponent } from 'react';
import { PaneController } from '../controllers/pane-controller';
import TreeView from './tree';
import './style.less';
@ -6,7 +6,7 @@ import { IPublicModelPluginContext } from '@alilc/lowcode-types';
import Filter from './filter';
import { TreeMaster } from '../controllers/tree-master';
export class Pane extends Component<{
export class Pane extends PureComponent<{
config: any;
pluginContext: IPublicModelPluginContext;
treeMaster: TreeMaster;

View File

@ -1,10 +1,10 @@
import { Component } from 'react';
import { PureComponent } from 'react';
import classNames from 'classnames';
import TreeNode from '../controllers/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;
isModal?: boolean;
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;
isModal?: boolean;
pluginContext: IPublicModelPluginContext;
}> {
state = {
}, ITreeNodeChildrenState> {
state: ITreeNodeChildrenState = {
filterWorking: false,
matchSelf: false,
keywords: null,
@ -144,7 +151,7 @@ class TreeNodeChildren extends Component<{
/>
);
treeNode.children?.forEach((child, index) => {
const childIsModal = child.node.componentMeta.isModal || false;
const childIsModal = child.node.componentMeta?.isModal || false;
if (isModal != childIsModal) {
return;
}
@ -180,7 +187,7 @@ class TreeNodeChildren extends Component<{
}
}
class TreeNodeSlots extends Component<{
class TreeNodeSlots extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
}> {

View File

@ -1,4 +1,4 @@
import { Component } from 'react';
import { PureComponent } from 'react';
import classNames from 'classnames';
import TreeNode from '../controllers/tree-node';
import TreeTitle from './tree-title';
@ -6,7 +6,7 @@ import TreeBranches from './tree-branches';
import { IconEyeClose } from '../icons/eye-close';
import { IPublicModelPluginContext, IPublicModelModalNodesManager, IPublicModelDocumentModel, IPublicTypeDisposable } from '@alilc/lowcode-types';
class ModalTreeNodeView extends Component<{
class ModalTreeNodeView extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
}> {
@ -59,11 +59,11 @@ class ModalTreeNodeView extends Component<{
}
}
export default class TreeNodeView extends Component<{
export default class TreeNodeView extends PureComponent<{
treeNode: TreeNode;
isModal?: boolean;
pluginContext: IPublicModelPluginContext;
isRootNode: boolean;
isRootNode?: boolean;
}> {
state = {
expanded: false,

View File

@ -1,5 +1,4 @@
/* eslint-disable max-len */
import { Component, KeyboardEvent, FocusEvent, Fragment } from 'react';
import { KeyboardEvent, FocusEvent, Fragment, PureComponent } from 'react';
import classNames from 'classnames';
import { createIcon } from '@alilc/lowcode-utils';
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;
isModal?: boolean;
expanded: boolean;
@ -36,7 +35,7 @@ export default class TreeTitle extends Component<{
private lastInput?: HTMLInputElement;
private enableEdit = (e) => {
private enableEdit = (e: MouseEvent) => {
e.preventDefault();
this.setState({
editing: true,
@ -205,7 +204,7 @@ export default class TreeTitle extends Component<{
}
}
class RenameBtn extends Component<{
class RenameBtn extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
onClick: (e: any) => void;
@ -225,7 +224,7 @@ class RenameBtn extends Component<{
}
}
class LockBtn extends Component<{
class LockBtn extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
locked: boolean;
@ -249,7 +248,7 @@ class LockBtn extends Component<{
}
}
class HideBtn extends Component<{
class HideBtn extends PureComponent<{
treeNode: TreeNode;
hidden: boolean;
pluginContext: IPublicModelPluginContext;
@ -276,7 +275,7 @@ class HideBtn extends Component<{
}
}
class ExpandBtn extends Component<{
class ExpandBtn extends PureComponent<{
treeNode: TreeNode;
pluginContext: IPublicModelPluginContext;
expanded: boolean;

View File

@ -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 { Tree } from '../controllers/tree';
import TreeNodeView from './tree-node';
import { IPublicEnumDragObjectType, IPublicModelPluginContext, IPublicModelNode } from '@alilc/lowcode-types';
import TreeNode from '../controllers/tree-node';
function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string {
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;
}
export default class TreeView extends Component<{
export default class TreeView extends PureComponent<{
tree: Tree;
pluginContext: IPublicModelPluginContext;
}> {
@ -60,12 +61,12 @@ export default class TreeView extends Component<{
const { id } = node;
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
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)) {
selection.remove(id);
}
} else {
selection.select(id);
selection?.select(id);
const selectedNode = selection?.getNodes()?.[0];
const npm = selectedNode?.componentMeta?.npm;
const selected =
@ -134,21 +135,23 @@ export default class TreeView extends Component<{
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
const isLeftButton = e.button === 0;
if (isLeftButton && !node.contains(focusNode)) {
if (isLeftButton && focusNode && !node.contains(focusNode)) {
let nodes: IPublicModelNode[] = [node];
this.ignoreUpSelected = false;
if (isMulti) {
// multi select mode, directily add
if (!selection.has(node.id)) {
if (!selection?.has(node.id)) {
canvas.activeTracker?.track(node);
selection.add(node.id);
selection?.add(node.id);
this.ignoreUpSelected = true;
}
// todo: remove rootNodes id
selection.remove(focusNode.id);
selection?.remove(focusNode.id);
// 获得顶层 nodes
nodes = selection.getTopNodes();
} else if (selection.has(node.id)) {
if (selection) {
nodes = selection.getTopNodes();
}
} else if (selection?.has(node.id)) {
nodes = selection.getTopNodes();
}
this.boostEvent = e.nativeEvent;
@ -169,7 +172,9 @@ export default class TreeView extends Component<{
doc?.detecting.leave();
};
state = {
state: {
root: TreeNode | null
} = {
root: null,
};

View File

@ -1,6 +1,6 @@
import { Component, ReactNode } from 'react';
import { IPublicTypeNodeSchema } from '../type';
import { IPublicTypeNodeSchema, IPublicTypeTitleContent } from '../type';
import { IPublicEnumTransitionType } from '../enum';
export interface IPublicApiCommonUtils {
@ -82,12 +82,16 @@ export interface IPublicApiCommonEditorCabin {
* Title
* @experimental unstable API, pay extra caution when trying to use this
*/
get Tip(): Component;
get Tip(): React.FC<{}>;
/**
* Tip
* @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 {

View File

@ -3,8 +3,8 @@ import { IPublicEnumTransformStage } from '../enum';
import { IPublicApiSimulatorHost } from './';
import { IPublicModelDocumentModel } from '../model';
export interface IPublicApiProject<
DocumentModel = IPublicModelDocumentModel
export interface IBaseApiProject<
DocumentModel
> {
/**
@ -133,3 +133,5 @@ export interface IPublicApiProject<
*/
setI18n(value: object): void;
}
export interface IPublicApiProject extends IBaseApiProject<IPublicModelDocumentModel> {}