import { jotaiStore } from '../../../lib/jotai'; import { selectedIdsFamily } from './atoms'; export interface TreeNode { children?: TreeNode[]; item: T; hidden?: boolean; parent: TreeNode | null; depth: number; } export interface SelectableTreeNode { node: TreeNode; depth: number; index: number; } export function getSelectedItems( treeId: string, selectableItems: SelectableTreeNode[], ) { const selectedItemIds = jotaiStore.get(selectedIdsFamily(treeId)); return selectableItems .filter((i) => selectedItemIds.includes(i.node.item.id)) .map((i) => i.node.item); } export function equalSubtree( a: TreeNode, b: TreeNode, getItemKey: (t: T) => string, ): boolean { if (getNodeKey(a, getItemKey) !== getNodeKey(b, getItemKey)) return false; const ak = a.children ?? []; const bk = b.children ?? []; if (ak.length !== bk.length) return false; for (let i = 0; i < ak.length; i++) { if (!equalSubtree(ak[i]!, bk[i]!, getItemKey)) return false; } return true; } export function getNodeKey(a: TreeNode, getItemKey: (i: T) => string) { return getItemKey(a.item) + a.hidden; } export function hasAncestor(node: TreeNode, ancestorId: string) { if (node.parent == null) return false; if (node.parent.item.id === ancestorId) return true; // Check parents recursively return hasAncestor(node.parent, ancestorId); }