21200: copied branch from arvados-workbench2 Arvados-DCO-1.1-Signed-off-by: Lisa...
[arvados.git] / services / workbench2 / src / views-components / side-panel / side-panel-collapsed.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
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'
15 import {
16     navigateToSharedWithMe,
17     navigateToPublicFavorites,
18     navigateToFavorites,
19     navigateToGroups,
20     navigateToAllProcesses,
21     navigateToTrash,
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'
27
28 type CssRules = 'button' | 'unselected' | 'selected'
29
30 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
31     button: {
32         width: '40px',
33         height: '40px',
34         paddingLeft: '-2rem',
35         marginLeft: '-0.6rem',
36         marginBottom: '-1rem'
37     },
38     unselected: {
39         color: theme.customs.colors.grey600,
40     },
41     selected: {
42         color: theme.palette.primary.main,
43     },
44 })
45
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',
54     GROUPS = 'Groups',
55     TRASH = 'Trash',
56 }
57
58 type TCollapsedCategory = {
59     name: SidePanelCollapsedCategory
60     icon: ReactElement
61     navTarget: RouterAction | ''
62 }
63
64 const sidePanelCollapsedCategories: TCollapsedCategory[] = [
65     {
66         name: SidePanelCollapsedCategory.PROJECTS,
67         icon: <ProjectsIcon />,
68         navTarget: '',
69     },
70     {
71         name: SidePanelCollapsedCategory.FAVORITES,
72         icon: <FavoriteIcon />,
73         navTarget: navigateToFavorites,
74     },
75     {
76         name: SidePanelCollapsedCategory.PUBLIC_FAVORITES,
77         icon: <PublicFavoriteIcon />,
78         navTarget: navigateToPublicFavorites,
79     },
80     {
81         name: SidePanelCollapsedCategory.SHARED_WITH_ME,
82         icon: <ShareMeIcon />,
83         navTarget: navigateToSharedWithMe,
84     },
85     {
86         name: SidePanelCollapsedCategory.ALL_PROCESSES,
87         icon: <ProcessIcon />,
88         navTarget: navigateToAllProcesses,
89     },
90     {
91         name: SidePanelCollapsedCategory.INSTANCE_TYPES,
92         icon: <ResourceIcon />,
93         navTarget: navigateToInstanceTypes,
94     },
95     {
96         name: SidePanelCollapsedCategory.SHELL_ACCESS,
97         icon: <TerminalIcon />,
98         navTarget: navigateToUserVirtualMachines,
99     },
100     {
101         name: SidePanelCollapsedCategory.GROUPS,
102         icon: <GroupsIcon style={{marginLeft: '2px', scale: '85%'}}/>,
103         navTarget: navigateToGroups,
104     },
105     {
106         name: SidePanelCollapsedCategory.TRASH,
107         icon: <TrashIcon />,
108         navTarget: navigateToTrash,
109     },
110 ]
111
112 type SidePanelCollapsedProps = {
113     user: User;
114     selectedPath: string;
115     navToHome: (uuid: string) => void;
116     navTo: (navTarget: RouterAction | '') => void;
117 };
118
119 const mapStateToProps = ({auth, properties }: RootState) => {
120         return {
121             user: auth.user,
122             selectedPath: properties.breadcrumbs
123                 ? properties.breadcrumbs[0].label !== SidePanelTreeCategory.SHELL_ACCESS
124                 ? properties.breadcrumbs[0].label
125                 : SidePanelCollapsedCategory.SHELL_ACCESS
126                 : SidePanelCollapsedCategory.PROJECTS,
127         }
128 }
129
130 const mapDispatchToProps = (dispatch: Dispatch) => {
131     return {
132         navToHome: (navTarget) => dispatch<any>(navigateTo(navTarget)),
133         navTo: (navTarget) => dispatch<any>(navTarget),
134     }
135 }
136
137 export const SidePanelCollapsed = withStyles(styles)(
138     connect(mapStateToProps, mapDispatchToProps)(({ classes, user, selectedPath, navToHome, navTo }: WithStyles & SidePanelCollapsedProps) => {
139
140         const handleClick = (cat: TCollapsedCategory) => {
141             if (cat.name === SidePanelCollapsedCategory.PROJECTS) navToHome(user.uuid)
142             else navTo(cat.navTarget)
143         }
144
145         const { button, unselected, selected } = classes
146         return (
147             <List data-cy='side-panel-collapsed'>
148                 {sidePanelCollapsedCategories.map((cat) => (
149                     <ListItem
150                         key={cat.name}
151                         data-cy={`collapsed-${cat.name.toLowerCase().replace(/\s+/g, '-')}`}
152                         onClick={() => handleClick(cat)}
153                         >
154                         <Tooltip
155                             className={selectedPath === cat.name ? selected : unselected}
156                             title={cat.name}
157                             disableFocusListener
158                             >
159                             <IconButton className={button}>{cat.icon}</IconButton>
160                         </Tooltip>
161                     </ListItem>
162                 ))}
163             </List>
164         );
165     })
166 )