X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/a0e9ecd6a913a6465b500f642412daf1e1a6420b..2ee1db29750704c6cd381483c44c98c6cff656e0:/src/components/tree/tree.tsx diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx index df3fc7f3..41498fc0 100644 --- a/src/components/tree/tree.tsx +++ b/src/components/tree/tree.tsx @@ -3,11 +3,11 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { List, ListItem, ListItemIcon, Collapse, Checkbox } from "@material-ui/core"; +import { List, ListItem, ListItemIcon, Collapse, Checkbox, Radio } from "@material-ui/core"; import { StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core/styles'; import { ReactElement } from "react"; import CircularProgress from '@material-ui/core/CircularProgress'; -import * as classnames from "classnames"; +import classnames from "classnames"; import { ArvadosTheme } from '~/common/custom-theme'; import { SidePanelRightArrowIcon } from '../icon/icon'; @@ -83,28 +83,49 @@ export interface TreeItem { export interface TreeProps { disableRipple?: boolean; + currentItemUuid?: string; items?: Array>; level?: number; onContextMenu: (event: React.MouseEvent, item: TreeItem) => void; render: (item: TreeItem, level?: number) => ReactElement<{}>; - showSelection?: boolean; + showSelection?: boolean | ((item: TreeItem) => boolean); + levelIndentation?: number; + itemRightPadding?: number; toggleItemActive: (event: React.MouseEvent, item: TreeItem) => void; toggleItemOpen: (event: React.MouseEvent, item: TreeItem) => void; toggleItemSelection?: (event: React.MouseEvent, item: TreeItem) => void; + + /** + * When set to true use radio buttons instead of checkboxes for item selection. + * This does not guarantee radio group behavior (i.e item mutual exclusivity). + * Any item selection logic must be done in the toggleItemActive callback prop. + */ + useRadioButtons?: boolean; } export const Tree = withStyles(styles)( class Component extends React.Component & WithStyles, {}> { render(): ReactElement { const level = this.props.level ? this.props.level : 0; - const { classes, render, toggleItemOpen, items, toggleItemActive, onContextMenu, disableRipple } = this.props; + const { classes, render, toggleItemOpen, items, toggleItemActive, onContextMenu, disableRipple, currentItemUuid, useRadioButtons } = this.props; const { list, listItem, loader, toggableIconContainer, renderContainer } = classes; - return + const showSelection = typeof this.props.showSelection === 'function' + ? this.props.showSelection + : () => this.props.showSelection ? true : false; + + const { levelIndentation = 20, itemRightPadding = 20 } = this.props; + + return {items && items.map((it: TreeItem, idx: number) =>
- toggleItemActive(event, it)} + selected={showSelection(it) && it.id === currentItemUuid} onContextMenu={this.handleRowContextMenu(it)}> {it.status === TreeItemStatus.PENDING ? : null} @@ -114,12 +135,17 @@ export const Tree = withStyles(styles)( {this.getProperArrowAnimation(it.status, it.items!)} - {this.props.showSelection && + {showSelection(it) && !useRadioButtons && } + {showSelection(it) && useRadioButtons && + }
{render(it, level)}
@@ -142,7 +168,7 @@ export const Tree = withStyles(styles)( } getProperArrowAnimation = (status: string, items: Array>) => { - return this.isSidePanelIconNotNeeded(status, items) ? : ; + return this.isSidePanelIconNotNeeded(status, items) ? : ; } isSidePanelIconNotNeeded = (status: string, items: Array>) => {