import "./tree-view.scss"; import React, { useEffect, useRef } from "react"; import { Icon } from "../icon"; import TreeView from "@material-ui/lab/TreeView"; import TreeItem from "@material-ui/lab/TreeItem"; import { cssNames } from "../../utils"; import _ from "lodash"; import getDeepDash from "deepdash"; const deepDash = getDeepDash(_); export interface NavigationTree { id: string; parentId: string; name: string; selected?: boolean; children?: NavigationTree[]; } interface Props { data: NavigationTree[] } function scrollToItem(id: string) { document.getElementById(id)?.scrollIntoView(); } function getSelectedNode(data: NavigationTree[]) { return deepDash.findDeep(data, (value, key) => key === "selected" && value === true)?.parent; } export function RecursiveTreeView({ data }: Props) { const [expanded, setExpanded] = React.useState([]); const prevData = useRef(data); const handleToggle = (event: React.ChangeEvent<{}>, nodeIds: string[]) => { setExpanded(nodeIds); }; const expandTopLevelNodes = () => { setExpanded(data.map(node => node.id)); }; const expandParentNode = () => { const node = getSelectedNode(data) as any as NavigationTree; const id = node?.parentId; if (id && !expanded.includes(id)) { setExpanded([...expanded, id]); } }; const onLabelClick = (event: React.MouseEvent, nodeId: string) => { event.preventDefault(); scrollToItem(nodeId); }; const renderTree = (nodes: NavigationTree[]) => { return nodes.map(node => ( onLabelClick(event, node.id)} className={cssNames({selected: node.selected})} title={node.name} > {Array.isArray(node.children) ? node.children.map((node) => renderTree([node])) : null} )); }; useEffect(() => { if (!prevData.current.length) { expandTopLevelNodes(); } else { expandParentNode(); } prevData.current = data; }, [data]); if (!data.length) { return null; } return ( } defaultExpandIcon={} > {renderTree(data)} ); }