X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/540d41f964c7ad3495cead777d6d175ff8f76b53..fb1ecf2421f8aac07d733d3bb56bb39312274f8c:/src/models/tree.ts diff --git a/src/models/tree.ts b/src/models/tree.ts index 61e7d860..a5fb49cf 100644 --- a/src/models/tree.ts +++ b/src/models/tree.ts @@ -1,5 +1,3 @@ -import { Children } from "../../node_modules/@types/react"; - // Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 @@ -8,7 +6,7 @@ export type Tree = Record>; export const TREE_ROOT_ID = ''; -export interface TreeNode { +export interface TreeNode { children: string[]; value: T; id: string; @@ -23,7 +21,7 @@ export const setNode = (node: TreeNode) => (tree: Tree): Tree => { const [newTree] = [tree] .map(tree => getNode(node.id)(tree) === node ? tree - : Object.assign({}, tree, { [node.id]: node })) + : { ...tree, [node.id]: node }) .map(addChild(node.parent, node.id)); return newTree; }; @@ -48,25 +46,32 @@ export const setNodeValueWith = (mapFn: (value: T) => T) => (id: string) => ( }; export const mapTreeValues = (mapFn: (value: T) => R) => (tree: Tree): Tree => - getNodeDescendants('')(tree) + getNodeDescendantsIds('')(tree) .map(id => getNode(id)(tree)) .map(mapNodeValue(mapFn)) .reduce((newTree, node) => setNode(node)(newTree), createTree()); -export const mapTree = (mapFn: (node: TreeNode) => TreeNode) => (tree: Tree): Tree => - getNodeDescendants('')(tree) +export const mapTree = (mapFn: (node: TreeNode) => TreeNode) => (tree: Tree): Tree => + getNodeDescendantsIds('')(tree) .map(id => getNode(id)(tree)) .map(mapFn) .reduce((newTree, node) => setNode(node)(newTree), createTree()); -export const getNodeAncestors = (id: string) => (tree: Tree): string[] => { +export const getNodeAncestors = (id: string) => (tree: Tree) => + mapIdsToNodes(getNodeAncestorsIds(id)(tree))(tree); + + +export const getNodeAncestorsIds = (id: string) => (tree: Tree): string[] => { const node = getNode(id)(tree); return node && node.parent - ? [...getNodeAncestors(node.parent)(tree), node.parent] + ? [...getNodeAncestorsIds(node.parent)(tree), node.parent] : []; }; -export const getNodeDescendants = (id: string, limit = Infinity) => (tree: Tree): string[] => { +export const getNodeDescendants = (id: string, limit = Infinity) => (tree: Tree) => + mapIdsToNodes(getNodeDescendantsIds(id, limit)(tree))(tree); + +export const getNodeDescendantsIds = (id: string, limit = Infinity) => (tree: Tree): string[] => { const node = getNode(id)(tree); const children = node ? node.children : id === TREE_ROOT_ID @@ -77,12 +82,18 @@ export const getNodeDescendants = (id: string, limit = Infinity) => (tree: Tr .concat(limit < 1 ? [] : children - .map(id => getNodeDescendants(id, limit - 1)(tree)) + .map(id => getNodeDescendantsIds(id, limit - 1)(tree)) .reduce((nodes, nodeChildren) => [...nodes, ...nodeChildren], [])); }; -export const getNodeChildren = (id: string) => (tree: Tree): string[] => - getNodeDescendants(id, 0)(tree); +export const getNodeChildren = (id: string) => (tree: Tree) => + mapIdsToNodes(getNodeChildrenIds(id)(tree))(tree); + +export const getNodeChildrenIds = (id: string) => (tree: Tree): string[] => + getNodeDescendantsIds(id, 0)(tree); + +export const mapIdsToNodes = (ids: string[]) => (tree: Tree) => + ids.map(id => getNode(id)(tree)).filter((node): node is TreeNode => node !== undefined); const mapNodeValue = (mapFn: (value: T) => R) => (node: TreeNode): TreeNode => ({ ...node, value: mapFn(node.value) });