1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React, { ReactElement } from 'react'
6 import { connect } from 'react-redux'
7 import { ProjectsIcon, ProcessIcon, FavoriteIcon, ShareMeIcon, TrashIcon, PublicFavoriteIcon, GroupsIcon, ResourceIcon } from 'components/icon/icon'
8 import { TerminalIcon } from 'components/icon/icon'
9 import { IconButton, List, ListItem, Tooltip } from '@material-ui/core'
10 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles'
11 import { ArvadosTheme } from 'common/custom-theme'
12 import { navigateTo, navigateToInstanceTypes } from 'store/navigation/navigation-action'
13 import { RootState } from 'store/store'
14 import { Dispatch } from 'redux'
16 navigateToSharedWithMe,
17 navigateToPublicFavorites,
20 navigateToAllProcesses,
22 } from 'store/navigation/navigation-action'
23 import { navigateToUserVirtualMachines } from 'store/navigation/navigation-action'
24 import { RouterAction } from 'react-router-redux'
25 import { User } from 'models/user'
26 import { SidePanelTreeCategory } from 'store/side-panel-tree/side-panel-tree-actions'
28 type CssRules = 'button' | 'unselected' | 'selected'
30 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
35 marginLeft: '-0.6rem',
39 color: theme.customs.colors.grey600,
42 color: theme.palette.primary.main,
46 enum SidePanelCollapsedCategory {
47 PROJECTS = 'Home Projects',
48 FAVORITES = 'My Favorites',
49 PUBLIC_FAVORITES = 'Public Favorites',
50 SHARED_WITH_ME = 'Shared with me',
51 ALL_PROCESSES = 'All Processes',
52 INSTANCE_TYPES = 'Instance Types',
53 SHELL_ACCESS = 'Shell Access',
58 type TCollapsedCategory = {
59 name: SidePanelCollapsedCategory
61 navTarget: RouterAction | ''
64 const sidePanelCollapsedCategories: TCollapsedCategory[] = [
66 name: SidePanelCollapsedCategory.PROJECTS,
67 icon: <ProjectsIcon />,
71 name: SidePanelCollapsedCategory.FAVORITES,
72 icon: <FavoriteIcon />,
73 navTarget: navigateToFavorites,
76 name: SidePanelCollapsedCategory.PUBLIC_FAVORITES,
77 icon: <PublicFavoriteIcon />,
78 navTarget: navigateToPublicFavorites,
81 name: SidePanelCollapsedCategory.SHARED_WITH_ME,
82 icon: <ShareMeIcon />,
83 navTarget: navigateToSharedWithMe,
86 name: SidePanelCollapsedCategory.ALL_PROCESSES,
87 icon: <ProcessIcon />,
88 navTarget: navigateToAllProcesses,
91 name: SidePanelCollapsedCategory.INSTANCE_TYPES,
92 icon: <ResourceIcon />,
93 navTarget: navigateToInstanceTypes,
96 name: SidePanelCollapsedCategory.SHELL_ACCESS,
97 icon: <TerminalIcon />,
98 navTarget: navigateToUserVirtualMachines,
101 name: SidePanelCollapsedCategory.GROUPS,
102 icon: <GroupsIcon style={{marginLeft: '2px', scale: '85%'}}/>,
103 navTarget: navigateToGroups,
106 name: SidePanelCollapsedCategory.TRASH,
108 navTarget: navigateToTrash,
112 type SidePanelCollapsedProps = {
114 selectedPath: string;
115 navToHome: (uuid: string) => void;
116 navTo: (navTarget: RouterAction | '') => void;
119 const mapStateToProps = ({auth, properties }: RootState) => {
122 selectedPath: properties.breadcrumbs
123 ? properties.breadcrumbs[0].label !== SidePanelTreeCategory.SHELL_ACCESS
124 ? properties.breadcrumbs[0].label
125 : SidePanelCollapsedCategory.SHELL_ACCESS
126 : SidePanelCollapsedCategory.PROJECTS,
130 const mapDispatchToProps = (dispatch: Dispatch) => {
132 navToHome: (navTarget) => dispatch<any>(navigateTo(navTarget)),
133 navTo: (navTarget) => dispatch<any>(navTarget),
137 export const SidePanelCollapsed = withStyles(styles)(
138 connect(mapStateToProps, mapDispatchToProps)(({ classes, user, selectedPath, navToHome, navTo }: WithStyles & SidePanelCollapsedProps) => {
140 const handleClick = (cat: TCollapsedCategory) => {
141 if (cat.name === SidePanelCollapsedCategory.PROJECTS) navToHome(user.uuid)
142 else navTo(cat.navTarget)
145 const { button, unselected, selected } = classes
147 <List data-cy='side-panel-collapsed'>
148 {sidePanelCollapsedCategories.map((cat) => (
151 data-cy={`collapsed-${cat.name.toLowerCase().replace(/\s+/g, '-')}`}
152 onClick={() => handleClick(cat)}
155 className={selectedPath === cat.name ? selected : unselected}
159 <IconButton className={button}>{cat.icon}</IconButton>