Merge branch 'main' into 19302-left-side-panel-changes
[arvados-workbench2.git] / 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 } from 'components/icon/icon'
8 import { TerminalIcon } from 'components/icon/icon'
9 import { 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 } 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
26 type CssRules = 'root' | 'unselected' | 'selected'
27
28 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
29     root: {},
30     unselected: {
31         color: theme.customs.colors.grey600,
32     },
33     selected: {
34         color: theme.palette.primary.main,
35     },
36 })
37
38 enum SidePanelCollapsedCategory {
39     PROJECTS = 'Home Projects',
40     FAVORITES = 'My Favorites',
41     PUBLIC_FAVORITES = 'Public Favorites',
42     SHARED_WITH_ME = 'Shared with me',
43     ALL_PROCESSES = 'All Processes',
44     SHELL_ACCESS = 'Shell Access',
45     GROUPS = 'Groups',
46     TRASH = 'Trash',
47 }
48
49 type TCollapsedCategory = {
50     name: SidePanelCollapsedCategory
51     icon: ReactElement
52     navTarget: RouterAction | ''
53 }
54
55 const sidePanelCollapsedCategories: TCollapsedCategory[] = [
56     {
57         name: SidePanelCollapsedCategory.PROJECTS,
58         icon: <ProjectsIcon />,
59         navTarget: '',
60     },
61     {
62         name: SidePanelCollapsedCategory.FAVORITES,
63         icon: <FavoriteIcon />,
64         navTarget: navigateToFavorites,
65     },
66     {
67         name: SidePanelCollapsedCategory.PUBLIC_FAVORITES,
68         icon: <PublicFavoriteIcon />,
69         navTarget: navigateToPublicFavorites,
70     },
71     {
72         name: SidePanelCollapsedCategory.SHARED_WITH_ME,
73         icon: <ShareMeIcon />,
74         navTarget: navigateToSharedWithMe,
75     },
76     {
77         name: SidePanelCollapsedCategory.ALL_PROCESSES,
78         icon: <ProcessIcon />,
79         navTarget: navigateToAllProcesses,
80     },
81     {
82         name: SidePanelCollapsedCategory.SHELL_ACCESS,
83         icon: <TerminalIcon />,
84         navTarget: navigateToUserVirtualMachines,
85     },
86     {
87         name: SidePanelCollapsedCategory.GROUPS,
88         icon: <GroupsIcon style={{marginLeft: '3px'}}/>,
89         navTarget: navigateToGroups,
90     },
91     {
92         name: SidePanelCollapsedCategory.TRASH,
93         icon: <TrashIcon />,
94         navTarget: navigateToTrash,
95     },
96 ]
97
98 const mapStateToProps = ({auth, properties }: RootState) => {
99         return {
100             user: auth.user,
101             selectedPath: properties.breadcrumbs
102                 ? properties.breadcrumbs[0].label !== 'Virtual Machines'
103                 ? properties.breadcrumbs[0].label
104                 : SidePanelCollapsedCategory.SHELL_ACCESS
105                 : SidePanelCollapsedCategory.PROJECTS,
106         }
107 }
108
109 const mapDispatchToProps = (dispatch: Dispatch) => {
110     return {
111         navToHome: (navTarget) => dispatch<any>(navigateTo(navTarget)),
112         navTo: (navTarget) => dispatch<any>(navTarget),
113     }
114 }
115
116 export const SidePanelCollapsed = withStyles(styles)(
117     connect(mapStateToProps, mapDispatchToProps)(({ classes, user, selectedPath, navToHome, navTo }: WithStyles & any) => {
118
119         const handleClick = (cat: TCollapsedCategory) => {
120             if (cat.name === SidePanelCollapsedCategory.PROJECTS) navToHome(user.uuid)
121             else navTo(cat.navTarget)
122         }
123
124         const { root, unselected, selected } = classes
125         return (
126             <List data-cy="side-panel-collapsed" className={root}>
127                 {sidePanelCollapsedCategories.map((cat) => (
128                     <ListItem
129                         key={cat.name}
130                         data-cy={`collapsed-${cat.name.toLowerCase().replace(/\s+/g, '-')}`}
131                         className={selectedPath === cat.name ? selected : unselected}
132                         onClick={() => handleClick(cat)}
133                     >
134                         <Tooltip
135                             title={cat.name}
136                             disableFocusListener
137                         >
138                             {cat.icon}
139                         </Tooltip>
140                     </ListItem>
141                 ))}
142             </List>
143         )
144     })
145 )