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, Theme, WithStyles, withStyles } from '@material-ui/core/styles';
8 import List from "@material-ui/core/List/List";
9 import ListItem from "@material-ui/core/ListItem/ListItem";
10 import ListItemText from "@material-ui/core/ListItemText/ListItemText";
11 import ListItemIcon from '@material-ui/core/ListItemIcon';
12 import Collapse from "@material-ui/core/Collapse/Collapse";
14 import { Typography } from '@material-ui/core';
16 export interface SidePanelItem {
26 interface SidePanelProps {
27 toggleOpen: (id: string) => void;
28 toggleActive: (id: string) => void;
29 sidePanelItems: SidePanelItem[];
30 onContextMenu: (event: React.MouseEvent<HTMLElement>, item: SidePanelItem) => void;
33 class SidePanel extends React.Component<SidePanelProps & WithStyles<CssRules>> {
34 render(): ReactElement<any> {
35 const { classes, toggleOpen, toggleActive, sidePanelItems, children } = this.props;
36 const { listItemText, leftSidePanelContainer, row, list, icon, projectIconMargin, active, activeArrow, inactiveArrow, arrowTransition, arrowRotate } = classes;
38 <div className={leftSidePanelContainer}>
40 {sidePanelItems.map(it => (
42 <ListItem button className={list} onClick={() => toggleActive(it.id)} onContextMenu={this.handleRowContextMenu(it)}>
43 <span className={row}>
44 {it.openAble ? <i onClick={() => toggleOpen(it.id)} className={`${it.active ? activeArrow : inactiveArrow}
45 ${it.open ? `fas fa-caret-down ${arrowTransition}` : `fas fa-caret-down ${arrowRotate}`}`} /> : null}
46 <ListItemIcon className={it.active ? active : ''}>
47 <i className={`${it.icon} ${icon} ${it.margin ? projectIconMargin : ''}`} />
49 <ListItemText className={listItemText} primary={<Typography className={it.active ? active : ''}>{it.name}</Typography>} />
53 <Collapse in={it.open} timeout="auto" unmountOnExit>
63 handleRowContextMenu = (item: SidePanelItem) =>
64 (event: React.MouseEvent<HTMLElement>) =>
65 item.openAble ? this.props.onContextMenu(event, item) : null
69 type CssRules = 'active' | 'listItemText' | 'row' | 'leftSidePanelContainer' | 'list' | 'icon' | 'projectIconMargin' |
70 'activeArrow' | 'inactiveArrow' | 'arrowRotate' | 'arrowTransition';
72 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
91 transition: 'all 0.1s ease',
94 transition: 'all 0.1s ease',
95 transform: 'rotate(-90deg)',
97 leftSidePanelContainer: {
100 whiteSpace: 'nowrap',
106 paddingBottom: '5px',
119 export default withStyles(styles)(SidePanel);