import type { InternalTreeNode, TreeNode } from "typings/custom"; type MapItem = { node: InternalTreeNode; parent?: MapItem; setExpanded?: Function; }; const ROOT_KEY = "0"; export class TreeHandler { private _nodeMap: { [key: string]: MapItem }; private _nameKeyMap: { [key: string]: string }; constructor() { this._nodeMap = {}; this._nameKeyMap = {}; } getNode(key: string): InternalTreeNode | undefined { return this._nodeMap[key] && this._nodeMap[key].node; } getKeyByName(name: string): string | undefined { return name && this._nameKeyMap[name]; } initialize(treeRoot: TreeNode): InternalTreeNode { return this.convert(treeRoot); } expandToSelected(selectedKey?: string) { if (selectedKey) { this.expandParents(this._nodeMap[selectedKey]); } } registerSetExpanded({ key, setExpanded }: { key: string; setExpanded: Function; }) { const item = this._nodeMap[key]; if (item) { item.setExpanded = setExpanded; } } private convert( node: TreeNode, level: number = 0, parent?: MapItem, position?: number ): InternalTreeNode { const convertedNode: InternalTreeNode = { label: node.label, name: node.name, key: this.calculateKey( (parent && parent.node.key) || ROOT_KEY, position ), level: level, isExpanded: node.isExpanded || false, isChildrenLoading: node.isChildrenLoading || false, link: node.link, method: node.method, showForwardArrow: node.showForwardArrow }; const mapItem = { node: convertedNode, parent }; if (node.children && node.children.length > 0) { convertedNode.children = node.children.map((child, index) => this.convert(child, level + 1, mapItem, index) ); } this._nodeMap[convertedNode.key] = mapItem; this._nameKeyMap[convertedNode.name] = convertedNode.key; return convertedNode; } private calculateKey(parentKey: string, position?: number): string { if (position === undefined) { return parentKey; } return `${parentKey}.${position}`; } private expandParents(treeNode?: MapItem) { if (!treeNode) { return; } treeNode.node.isExpanded = true; if (treeNode.setExpanded) { treeNode.setExpanded(true); } this.expandParents(treeNode.parent); } }