1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { ReactElement } from 'react';
7 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
8 import { ArvadosTheme } from '../../common/custom-theme';
9 import { List, ListItem, ListItemIcon, Collapse } from "@material-ui/core";
10 import { SidePanelRightArrowIcon, IconType } from '../icon/icon';
11 import * as classnames from "classnames";
12 import { ListItemTextIcon } from '../list-item-text-icon/list-item-text-icon';
14 type CssRules = 'active' | 'row' | 'root' | 'list' | 'iconClose' | 'iconOpen' | 'toggableIconContainer' | 'toggableIcon';
16 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
26 padding: '5px 0px 5px 14px',
33 toggableIconContainer: {
34 color: theme.palette.grey["700"],
42 color: theme.palette.primary.main,
45 transition: 'all 0.1s ease',
48 transition: 'all 0.1s ease',
49 transform: 'rotate(90deg)',
53 export interface SidePanelItem {
64 interface SidePanelDataProps {
65 toggleOpen: (id: string) => void;
66 toggleActive: (id: string) => void;
67 sidePanelItems: SidePanelItem[];
68 onContextMenu: (event: React.MouseEvent<HTMLElement>, item: SidePanelItem) => void;
71 type SidePanelProps = SidePanelDataProps & WithStyles<CssRules>;
73 export const SidePanel = withStyles(styles)(
74 class extends React.Component<SidePanelProps> {
75 render(): ReactElement<any> {
76 const { classes, toggleOpen, toggleActive, sidePanelItems, children } = this.props;
77 const { root, row, list, toggableIconContainer } = classes;
79 <div className={root}>
81 {sidePanelItems.map(it => (
83 <ListItem button className={list} onClick={() => toggleActive(it.id)}
84 onContextMenu={this.handleRowContextMenu(it)}>
85 <span className={row}>
87 <i onClick={() => toggleOpen(it.id)} className={toggableIconContainer}>
89 className={this.getToggableIconClassNames(it.open, it.active)}>
90 < SidePanelRightArrowIcon/>
94 <ListItemTextIcon icon={it.icon} name={it.name} isActive={it.active}
95 hasMargin={it.margin}/>
99 <Collapse in={it.open} timeout="auto" unmountOnExit>
110 getToggableIconClassNames = (isOpen?: boolean, isActive ?: boolean) => {
111 const { classes } = this.props;
112 return classnames(classes.toggableIcon, {
113 [classes.iconOpen]: isOpen,
114 [classes.iconClose]: !isOpen,
115 [classes.active]: isActive
119 handleRowContextMenu = (item: SidePanelItem) =>
120 (event: React.MouseEvent<HTMLElement>) =>
121 item.openAble ? this.props.onContextMenu(event, item) : null