1
- import Grid from '@mui/material/Grid' ;
1
+ import { Button , Grid , ToggleButton as MuiToggledButton , ToggleButtonGroup } from '@mui/material' ;
2
+ import { styled } from '@mui/system' ;
2
3
import React from 'react' ;
3
4
import { useTranslation } from 'react-i18next' ;
4
5
import { generatePath , useHistory } from 'react-router-dom' ;
@@ -8,6 +9,13 @@ import { createRouteURL } from '../../../lib/router';
8
9
import { getClusterPrefixedPath } from '../../../lib/util' ;
9
10
import SquareButton from './SquareButton' ;
10
11
12
+ const ToggleButton = styled ( MuiToggledButton ) ( {
13
+ textTransform : 'none' ,
14
+ } ) ;
15
+
16
+ /** Allow selecting multiple recent clusters. */
17
+ const MULTI_ENABLED = import . meta. env . REACT_APP_MULTI_ENABLED === 'true' || true ;
18
+
11
19
interface ClusterButtonProps extends React . PropsWithChildren < { } > {
12
20
/** The cluster to display this button for. */
13
21
cluster : Cluster ;
@@ -49,6 +57,8 @@ export default function RecentClusters(props: RecentClustersProps) {
49
57
}
50
58
} , [ ] ) ;
51
59
const { t } = useTranslation ( ) ;
60
+ const [ selectedClusters , setSelectedClusters ] = React . useState < Cluster [ ] > ( [ ] ) ;
61
+
52
62
const recentClustersLabelId = 'recent-clusters-label' ;
53
63
const maxRecentClusters = 3 ;
54
64
// We slice it here for the maximum recent clusters just for extra safety, since this
@@ -85,6 +95,33 @@ export default function RecentClusters(props: RecentClustersProps) {
85
95
} ) ;
86
96
}
87
97
98
+ /**
99
+ * Callback for when different clusters are toggled.
100
+ *
101
+ * @param event - The event that triggered the toggle.
102
+ * @param clusters - The clusters that are toggled.
103
+ */
104
+ function onClustersToggled ( event : React . MouseEvent < HTMLElement > , clusters : Cluster [ ] ) {
105
+ setSelectedClusters ( clusters ) ;
106
+ }
107
+
108
+ /**
109
+ * Callback for when the "View" button is clicked. It will navigate to the selected clusters.
110
+ */
111
+ function onViewClusters ( ) {
112
+ selectedClusters . forEach ( cluster => {
113
+ helpers . setRecentCluster ( cluster ) ;
114
+ } ) ;
115
+
116
+ history . push ( {
117
+ pathname : generatePath ( getClusterPrefixedPath ( ) , {
118
+ cluster : selectedClusters . map ( cluster => cluster . name ) . join ( '+' ) ,
119
+ } ) ,
120
+ } ) ;
121
+ }
122
+
123
+ const doMulti = recentClusters . length > 1 && MULTI_ENABLED ;
124
+
88
125
return (
89
126
< Grid
90
127
aria-labelledby = { `#${ recentClustersLabelId } ` }
@@ -93,15 +130,42 @@ export default function RecentClusters(props: RecentClustersProps) {
93
130
alignItems = "flex-start"
94
131
spacing = { 2 }
95
132
>
96
- { recentClusters . map ( ( cluster , i ) => (
97
- < Grid item key = { cluster . name } >
98
- < ClusterButton
99
- focusedRef = { i === 0 ? focusedRef : undefined }
100
- cluster = { cluster }
101
- onClick = { ( ) => onClusterButtonClicked ( cluster ) }
102
- />
133
+ { ! doMulti &&
134
+ recentClusters . map ( ( cluster , i ) => (
135
+ < Grid item key = { cluster . name } >
136
+ < ClusterButton
137
+ focusedRef = { i === 0 ? focusedRef : undefined }
138
+ cluster = { cluster }
139
+ onClick = { ( ) => onClusterButtonClicked ( cluster ) }
140
+ />
141
+ </ Grid >
142
+ ) ) }
143
+ { doMulti && (
144
+ < Grid container item alignItems = "center" >
145
+ < ToggleButtonGroup
146
+ value = { selectedClusters }
147
+ onChange = { onClustersToggled }
148
+ aria-label = "selected clusters"
149
+ exclusive = { false }
150
+ >
151
+ { recentClusters . map ( cluster => (
152
+ < ToggleButton key = { cluster . name } value = { cluster } >
153
+ { cluster . name }
154
+ </ ToggleButton >
155
+ ) ) }
156
+ </ ToggleButtonGroup >
157
+ < Grid item pl = { 2 } >
158
+ < Button
159
+ variant = "contained"
160
+ disabled = { selectedClusters . length < 1 }
161
+ color = "primary"
162
+ onClick = { onViewClusters }
163
+ >
164
+ View
165
+ </ Button >
166
+ </ Grid >
103
167
</ Grid >
104
- ) ) }
168
+ ) }
105
169
{ helpers . isElectron ( ) && (
106
170
< Grid item >
107
171
< SquareButton
0 commit comments