X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/5fd5db805554d3eddd46cc911a5108fbb74b3cfc..10ce16c28de952f6533ca3cc9df909269e3d2a53:/src/components/side-panel/side-panel.tsx diff --git a/src/components/side-panel/side-panel.tsx b/src/components/side-panel/side-panel.tsx index ac2073019d..4240b1bfd2 100644 --- a/src/components/side-panel/side-panel.tsx +++ b/src/components/side-panel/side-panel.tsx @@ -4,110 +4,119 @@ import * as React from 'react'; import { ReactElement } from 'react'; -import { StyleRulesCallback, Theme, WithStyles, withStyles } from '@material-ui/core/styles'; -import List from "@material-ui/core/List/List"; -import ListItem from "@material-ui/core/ListItem/ListItem"; -import ListItemText from "@material-ui/core/ListItemText/ListItemText"; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import Collapse from "@material-ui/core/Collapse/Collapse"; +import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles'; +import { ArvadosTheme } from '../../common/custom-theme'; +import { List, ListItem, ListItemIcon, Collapse } from "@material-ui/core"; +import { SidePanelRightArrowIcon, IconType } from '../icon/icon'; +import * as classnames from "classnames"; +import { ListItemTextIcon } from '../list-item-text-icon/list-item-text-icon'; -import { Typography } from '@material-ui/core'; +type CssRules = 'active' | 'row' | 'root' | 'list' | 'iconClose' | 'iconOpen' | 'toggableIconContainer' | 'toggableIcon'; + +const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ + root: { + overflowY: 'auto', + minWidth: '240px', + whiteSpace: 'nowrap', + marginTop: '52px', + display: 'flex', + flexGrow: 1, + }, + list: { + padding: '5px 0px 5px 14px', + minWidth: '240px', + }, + row: { + display: 'flex', + alignItems: 'center', + }, + toggableIconContainer: { + color: theme.palette.grey["700"], + height: '14px', + position: 'absolute' + }, + toggableIcon: { + fontSize: '14px' + }, + active: { + color: theme.palette.primary.main, + }, + iconClose: { + transition: 'all 0.1s ease', + }, + iconOpen: { + transition: 'all 0.1s ease', + transform: 'rotate(90deg)', + } +}); export interface SidePanelItem { id: string; name: string; - icon: string; + icon: IconType; active?: boolean; open?: boolean; margin?: boolean; openAble?: boolean; } -interface SidePanelProps { +interface SidePanelDataProps { toggleOpen: (id: string) => void; toggleActive: (id: string) => void; sidePanelItems: SidePanelItem[]; + onContextMenu: (event: React.MouseEvent, item: SidePanelItem) => void; } -class SidePanel extends React.Component> { - render(): ReactElement { - const { classes, toggleOpen, toggleActive, sidePanelItems, children } = this.props; - const { listItemText, leftSidePanelContainer, row, list, icon, projectIconMargin, active, activeArrow, inactiveArrow, arrowTransition, arrowRotate } = classes; - return ( -
- - {sidePanelItems.map(it => ( - - toggleActive(it.id)}> - - {it.openAble ? toggleOpen(it.id)} className={`${it.active ? activeArrow : inactiveArrow} - ${it.open ? `fas fa-caret-down ${arrowTransition}` : `fas fa-caret-down ${arrowRotate}`}`} /> : null} - - - - {it.name}} /> - - - {it.openAble ? ( - - {children} - ) : null} - - ))} - -
- ); - } -} +type SidePanelProps = SidePanelDataProps & WithStyles; -type CssRules = 'active' | 'listItemText' | 'row' | 'leftSidePanelContainer' | 'list' | 'icon' | 'projectIconMargin' | - 'activeArrow' | 'inactiveArrow' | 'arrowRotate' | 'arrowTransition'; +export const SidePanel = withStyles(styles)( + class extends React.Component { + render(): ReactElement { + const { classes, toggleOpen, toggleActive, sidePanelItems, children } = this.props; + const { root, row, list, toggableIconContainer } = classes; + return ( +
+ + {sidePanelItems.map(it => ( + + toggleActive(it.id)} + onContextMenu={this.handleRowContextMenu(it)}> + + {it.openAble ? ( + toggleOpen(it.id)} className={toggableIconContainer}> + + < SidePanelRightArrowIcon/> + + + ) : null} + + + + {it.openAble ? ( + + {children} + + ) : null} + + ))} + +
+ ); + } -const styles: StyleRulesCallback = (theme: Theme) => ({ - active: { - color: '#4285F6', - }, - listItemText: { - padding: '0px', - }, - row: { - display: 'flex', - alignItems: 'center', - }, - activeArrow: { - color: '#4285F6', - position: 'absolute', - }, - inactiveArrow: { - position: 'absolute', - }, - arrowTransition: { - transition: 'all 0.1s ease', - }, - arrowRotate: { - transition: 'all 0.1s ease', - transform: 'rotate(-90deg)', - }, - leftSidePanelContainer: { - overflowY: 'auto', - minWidth: '240px', - whiteSpace: 'nowrap', - marginTop: '38px', - display: 'flex', - flexGrow: 1, - }, - list: { - paddingBottom: '5px', - paddingTop: '5px', - paddingLeft: '14px', - minWidth: '240px', - }, - icon: { - minWidth: '20px', - }, - projectIconMargin: { - marginLeft: '17px', - } -}); + getToggableIconClassNames = (isOpen?: boolean, isActive ?: boolean) => { + const { classes } = this.props; + return classnames(classes.toggableIcon, { + [classes.iconOpen]: isOpen, + [classes.iconClose]: !isOpen, + [classes.active]: isActive + }); + } -export default withStyles(styles)(SidePanel); \ No newline at end of file + handleRowContextMenu = (item: SidePanelItem) => + (event: React.MouseEvent) => + item.openAble ? this.props.onContextMenu(event, item) : null + } +);