import { NodeApi } from "../interfaces/node-api"; import { TreeApi } from "../interfaces/tree-api"; import { IdObj } from "../types/utils"; export function createList(tree: TreeApi) { if (tree.isFiltered) { return flattenAndFilterTree(tree.root, tree.isMatch.bind(tree)); } else { return flattenTree(tree.root); } } function flattenTree(root: NodeApi): NodeApi[] { const list: NodeApi[] = []; function collect(node: NodeApi) { if (node.level >= 0) { list.push(node); } if (node.isOpen) { node.children?.forEach(collect); } } collect(root); list.forEach(assignRowIndex); return list; } function flattenAndFilterTree( root: NodeApi, isMatch: (n: NodeApi) => boolean ): NodeApi[] { const matches: Record = {}; const list: NodeApi[] = []; function markMatch(node: NodeApi) { const yes = !node.isRoot && isMatch(node); if (yes) { matches[node.id] = true; let parent = node.parent; while (parent) { matches[parent.id] = true; parent = parent.parent; } } if (node.children) { for (let child of node.children) markMatch(child); } } function collect(node: NodeApi) { if (node.level >= 0 && matches[node.id]) { list.push(node); } if (node.isOpen) { node.children?.forEach(collect); } } markMatch(root); collect(root); list.forEach(assignRowIndex); return list; } function assignRowIndex(node: NodeApi, index: number) { node.rowIndex = index; }