index.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import TreeView from '@material-ui/lab/TreeView';
  2. import TreeItem from '@material-ui/lab/TreeItem';
  3. import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
  4. import ChevronRightIcon from '@material-ui/icons/ChevronRight';
  5. export type TreeNodeType = 'db' | 'collection' | 'partition' | 'segment';
  6. export interface CustomTreeItem {
  7. children?: CustomTreeItem[];
  8. id: string;
  9. name: string;
  10. type: TreeNodeType;
  11. expanded?: boolean;
  12. }
  13. interface CustomToolProps {
  14. data: CustomTreeItem;
  15. onNodeToggle?: (event: React.ChangeEvent<{}>, nodeIds: string[]) => void;
  16. multiSelect?: true;
  17. disableSelection?: boolean;
  18. defaultSelected?: string[];
  19. onNodeClick?: (node: CustomTreeItem) => void;
  20. }
  21. // get expanded nodes from data
  22. const getExpanded = (nodes: CustomTreeItem[]) => {
  23. const expanded: string[] = [];
  24. nodes.forEach(node => {
  25. if (node.expanded) {
  26. expanded.push(node.id);
  27. }
  28. if (node.children && node.children.length > 0) {
  29. expanded.push(...getExpanded(node.children));
  30. }
  31. });
  32. return expanded;
  33. };
  34. const CustomTree: React.FC<CustomToolProps> = ({
  35. data,
  36. onNodeToggle,
  37. multiSelect,
  38. disableSelection,
  39. defaultSelected = [],
  40. onNodeClick,
  41. }) => {
  42. // UI data
  43. const expanded = getExpanded([data]);
  44. // render children
  45. const renderTree = (nodes: CustomTreeItem[]) => {
  46. return nodes.map(node => {
  47. if (node.children && node.children.length > 0) {
  48. return (
  49. <TreeItem
  50. key={node.id}
  51. nodeId={node.id}
  52. label={node.name}
  53. onClick={event => {
  54. event.stopPropagation();
  55. if (onNodeClick) {
  56. onNodeClick(node);
  57. }
  58. }}
  59. >
  60. {renderTree(node.children)}
  61. </TreeItem>
  62. );
  63. }
  64. return (
  65. <TreeItem
  66. key={node.id}
  67. nodeId={node.id}
  68. label={node.name}
  69. onClick={event => {
  70. event.stopPropagation();
  71. if (onNodeClick) {
  72. onNodeClick(node);
  73. }
  74. }}
  75. />
  76. );
  77. });
  78. };
  79. return (
  80. <TreeView
  81. defaultCollapseIcon={<ExpandMoreIcon />}
  82. defaultExpandIcon={<ChevronRightIcon />}
  83. expanded={expanded}
  84. onNodeToggle={onNodeToggle}
  85. selected={defaultSelected}
  86. multiSelect={multiSelect}
  87. disableSelection={disableSelection}
  88. >
  89. {data && (
  90. <TreeItem
  91. key={data.id}
  92. nodeId={data.id}
  93. label={data.name}
  94. onClick={event => {
  95. event.stopPropagation();
  96. if (onNodeClick) {
  97. onNodeClick(data);
  98. }
  99. }}
  100. >
  101. {data.children && data.children.length > 0
  102. ? renderTree(data.children)
  103. : [<div key="stub" />]}
  104. </TreeItem>
  105. )}
  106. </TreeView>
  107. );
  108. };
  109. export default CustomTree;