import TreeNode from './tree-node'; import { IPublicModelNode, IPublicModelPluginContext } from '@alilc/lowcode-types'; export class Tree { private treeNodesMap = new Map(); readonly id: string | undefined; readonly pluginContext: IPublicModelPluginContext; get root(): TreeNode | null { if (this.pluginContext.project.currentDocument?.focusNode) { return this.getTreeNode(this.pluginContext.project.currentDocument.focusNode!); } return null; } constructor(pluginContext: IPublicModelPluginContext) { this.pluginContext = pluginContext; const doc = this.pluginContext.project.currentDocument; this.id = doc?.id; doc?.onMountNode((payload: {node: IPublicModelNode }) => { const { node } = payload; const parentNode = node.parent; if (!parentNode) { return; } const parentTreeNode = this.getTreeNodeById(parentNode.id); parentTreeNode?.notifyExpandableChanged(); }); doc?.onRemoveNode((node: IPublicModelNode) => { const parentNode = node.parent; if (!parentNode) { return; } const parentTreeNode = this.getTreeNodeById(parentNode.id); parentTreeNode?.notifyExpandableChanged(); }); } setNodeSelected(nodeId: string): void { // 目标节点选中,其他节点展开 const treeNode = this.treeNodesMap.get(nodeId); if (!treeNode) { return; } this.expandAllAncestors(treeNode); } getTreeNode(node: IPublicModelNode): TreeNode { if (this.treeNodesMap.has(node.id)) { const tnode = this.treeNodesMap.get(node.id)!; tnode.setNode(node); return tnode; } const treeNode = new TreeNode(this, node, this.pluginContext); this.treeNodesMap.set(node.id, treeNode); return treeNode; } getTreeNodeById(id: string) { return this.treeNodesMap.get(id); } expandAllAncestors(treeNode: TreeNode | undefined | null) { if (!treeNode) { return; } if (treeNode.isRoot()) { return; } const ancestors = []; let currentNode: TreeNode | null | undefined = treeNode; while (!treeNode.isRoot()) { currentNode = currentNode?.parent; if (currentNode) { ancestors.unshift(currentNode); } else { break; } } ancestors.forEach((ancestor) => { ancestor.setExpanded(true); }); } expandAllDecendants(treeNode: TreeNode | undefined | null) { if (!treeNode) { return; } treeNode.setExpanded(true); const children = treeNode && treeNode.children; if (children) { children.forEach((child) => { this.expandAllDecendants(child); }); } } collapseAllDecendants(treeNode: TreeNode | undefined | null): void { if (!treeNode) { return; } treeNode.setExpanded(false); const children = treeNode && treeNode.children; if (children) { children.forEach((child) => { this.collapseAllDecendants(child); }); } } }