import * as React from 'react';
import { List, ListItem, ListItemIcon, Checkbox, Radio, Collapse } from "@material-ui/core";
import { StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core/styles';
-import { ProjectIcon } from '~/components/icon/icon';
+import { CollectionIcon, DefaultIcon, DirectoryIcon, FileIcon, ProjectIcon } from '~/components/icon/icon';
import { ReactElement } from "react";
import CircularProgress from '@material-ui/core/CircularProgress';
import classnames from "classnames";
import { ArvadosTheme } from '~/common/custom-theme';
import { SidePanelRightArrowIcon } from '../icon/icon';
+import { ResourceKind } from '~/models/resource';
type CssRules = 'list'
| 'listItem'
currentItemUuid?: string;
items?: Array<TreeItem<T>>;
level?: number;
+ itemsMap?: Map<string, TreeItem<T>>;
onContextMenu: (event: React.MouseEvent<HTMLElement>, item: TreeItem<T>) => void;
render: (item: TreeItem<T>, level?: number) => ReactElement<{}>;
showSelection?: boolean | ((item: TreeItem<T>) => boolean);
toggleItemActive: Function;
getToggableIconClassNames: Function;
getProperArrowAnimation: Function;
+ itemsMap?: Map<string, TreeItem<any>>;
classes: any;
}
+const FLAT_TREE_ACTIONS = {
+ toggleOpen: 'TOGGLE_OPEN',
+ contextMenu: 'CONTEXT_MENU',
+ toggleActive: 'TOGGLE_ACTIVE',
+};
+
+const ItemIcon = React.memo(({type, kind, active, classes}: any) => {
+ let Icon = ProjectIcon;
+
+ if (type) {
+ switch (type) {
+ case 'directory':
+ Icon = DirectoryIcon;
+ break;
+ case 'file':
+ Icon = FileIcon;
+ break;
+ default:
+ Icon = DefaultIcon;
+ }
+ }
+
+ if (kind) {
+ switch(kind) {
+ case ResourceKind.COLLECTION:
+ Icon = CollectionIcon;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return <Icon className={classnames({ [classes.active]: active }, classes.childItemIcon)} />;
+});
+
const FlatTree = (props: FlatTreeProps) =>
<div
onContextMenu={(event) => {
- const [action, id] = getActionAndId(event, 'CONTEXT_MENU');
+ const [action, id] = getActionAndId(event, FLAT_TREE_ACTIONS.contextMenu);
props.onContextMenu(event, { id } as any);
}}
onClick={(event) => {
const [action, id] = getActionAndId(event);
if (action && id) {
+ const item = props.itemsMap ? props.itemsMap[id] : { id };
+
switch (action) {
- case 'TOGGLE_OPEN':
- props.handleToggleItemOpen({ id } as any, event);
+ case FLAT_TREE_ACTIONS.toggleOpen:
+ props.handleToggleItemOpen(item as any, event);
break;
- case 'TOGGLE_ACTIVE':
- props.toggleItemActive(event, { id } as any);
+ case FLAT_TREE_ACTIONS.toggleActive:
+ props.toggleItemActive(event, item as any);
break;
default:
break;
.map((item: any) => <div key={item.id} data-id={item.id}
className={classnames(props.classes.childItem, { [props.classes.active]: item.active })}
style={{ paddingLeft: `${item.depth * props.levelIndentation}px` }}>
- <i data-action="TOGGLE_OPEN" className={props.classes.toggableIconContainer}>
+ <i data-action={FLAT_TREE_ACTIONS.toggleOpen} className={props.classes.toggableIconContainer}>
<ListItemIcon className={props.getToggableIconClassNames(item.open, item.active)}>
{props.getProperArrowAnimation(item.status, item.items!)}
</ListItemIcon>
</i>
- <div data-action="TOGGLE_ACTIVE" className={props.classes.renderContainer}>
+ <div data-action={FLAT_TREE_ACTIONS.toggleActive} className={props.classes.renderContainer}>
<span style={{ display: 'flex', alignItems: 'center' }}>
- <ProjectIcon className={classnames({ [props.classes.active]: item.active }, props.classes.childItemIcon)} />
+ <ItemIcon type={item.data.type} active={item.active} kind={item.data.kind} classes={props.classes} />
<span style={{ fontSize: '0.875rem' }}>
{item.data.name}
</span>
class Component<T> extends React.Component<TreeProps<T> & WithStyles<CssRules>, {}> {
render(): ReactElement<any> {
const level = this.props.level ? this.props.level : 0;
- const { classes, render, items, toggleItemActive, toggleItemOpen, disableRipple, currentItemUuid, useRadioButtons } = this.props;
+ const { classes, render, items, toggleItemActive, toggleItemOpen, disableRipple, currentItemUuid, useRadioButtons, itemsMap } = this.props;
const { list, listItem, loader, toggableIconContainer, renderContainer } = classes;
const showSelection = typeof this.props.showSelection === 'function'
? this.props.showSelection
it.flatTree ?
<FlatTree
it={it}
+ itemsMap={itemsMap}
classes={this.props.classes}
levelIndentation={levelIndentation}
onContextMenu={this.props.onContextMenu}