17426: Add "enableWhenPristine" option for dialog boxes.
[arvados-workbench2.git] / src / components / tree / tree.tsx
index 9680e3c0780dc9000fe756c4e7a59375c117a50b..908ee28ca8b24a139c21ef76358a6cbeaa723c5b 100644 (file)
@@ -5,13 +5,14 @@
 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'
@@ -105,6 +106,7 @@ export interface TreeProps<T> {
     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);
@@ -150,16 +152,45 @@ interface FlatTreeProps {
     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) => {
@@ -170,12 +201,14 @@ const FlatTree = (props: FlatTreeProps) =>
             const [action, id] = getActionAndId(event);
 
             if (action && id) {
+                const item = props.itemsMap ? props.itemsMap[id] : { id };
+
                 switch (action) {
                     case FLAT_TREE_ACTIONS.toggleOpen:
-                        props.handleToggleItemOpen({ id } as any, event);
+                        props.handleToggleItemOpen(item as any, event);
                         break;
                     case FLAT_TREE_ACTIONS.toggleActive:
-                        props.toggleItemActive(event, { id } as any);
+                        props.toggleItemActive(event, item as any);
                         break;
                     default:
                         break;
@@ -195,7 +228,7 @@ const FlatTree = (props: FlatTreeProps) =>
                     </i>
                     <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>
@@ -209,7 +242,7 @@ export const Tree = withStyles(styles)(
     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
@@ -257,6 +290,7 @@ export const Tree = withStyles(styles)(
                                 it.flatTree ?
                                     <FlatTree
                                         it={it}
+                                        itemsMap={itemsMap}
                                         classes={this.props.classes}
                                         levelIndentation={levelIndentation}
                                         onContextMenu={this.props.onContextMenu}