// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; import List from "@material-ui/core/List/List"; import ListItem from "@material-ui/core/ListItem/ListItem"; import { StyleRulesCallback, Theme, withStyles, WithStyles } from '@material-ui/core/styles'; import { ReactElement } from "react"; import Collapse from "@material-ui/core/Collapse/Collapse"; import CircularProgress from '@material-ui/core/CircularProgress'; export enum TreeItemStatus { Initial, Pending, Loaded } export interface TreeItem { data: T; id: string; open: boolean; active: boolean; status: TreeItemStatus; toggled?: boolean; items?: Array>; } interface TreeProps { items?: Array>; render: (item: TreeItem, level?: number) => ReactElement<{}>; toggleItemOpen: (id: string, status: TreeItemStatus) => void; toggleItemActive: (id: string, status: TreeItemStatus) => void; level?: number; } class Tree extends React.Component & WithStyles, {}> { renderArrow(status: TreeItemStatus, arrowClass: string, open: boolean, id: string) { const { arrowTransition, arrowVisibility, arrowRotate } = this.props.classes; return this.props.toggleItemOpen(id, status)} className={` ${arrowClass} ${status === TreeItemStatus.Pending ? arrowVisibility : ''} ${open ? `fas fa-caret-down ${arrowTransition}` : `fas fa-caret-down ${arrowRotate}`}`} />; } render(): ReactElement { const level = this.props.level ? this.props.level : 0; const { classes, render, toggleItemOpen, items, toggleItemActive } = this.props; const { list, inactiveArrow, activeArrow, loader } = classes; return {items && items.map((it: TreeItem, idx: number) =>
toggleItemActive(it.id, it.status)}> {it.status === TreeItemStatus.Pending ? : null} {it.toggled && it.items && it.items.length === 0 ? null : this.renderArrow(it.status, it.active ? activeArrow : inactiveArrow, it.open, it.id)} {render(it, level)} {it.items && it.items.length > 0 && }
)}
; } } type CssRules = 'list' | 'activeArrow' | 'inactiveArrow' | 'arrowRotate' | 'arrowTransition' | 'loader' | 'arrowVisibility'; const styles: StyleRulesCallback = (theme: Theme) => ({ list: { paddingBottom: '3px', paddingTop: '3px', }, activeArrow: { color: '#4285F6', position: 'absolute', }, inactiveArrow: { position: 'absolute', }, arrowTransition: { transition: 'all 0.1s ease', }, arrowRotate: { transition: 'all 0.1s ease', transform: 'rotate(-90deg)', }, arrowVisibility: { opacity: 0, }, loader: { position: 'absolute', transform: 'translate(0px)', top: '3px' } }); const StyledTree = withStyles(styles)(Tree); export default StyledTree;