Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/javascript/grid-ui/src/components/RunningSessions/ColumnSelector.tsx
2887 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
import React, { useState, useEffect } from 'react'
19
import {
20
Box,
21
Button,
22
Checkbox,
23
Dialog,
24
DialogActions,
25
DialogContent,
26
DialogTitle,
27
FormControlLabel,
28
FormGroup,
29
IconButton,
30
Tooltip,
31
Typography
32
} from '@mui/material'
33
import { ViewColumn as ViewColumnIcon } from '@mui/icons-material'
34
35
interface ColumnSelectorProps {
36
sessions: any[]
37
selectedColumns: string[]
38
onColumnSelectionChange: (columns: string[]) => void
39
}
40
41
const ColumnSelector: React.FC<ColumnSelectorProps> = ({
42
sessions,
43
selectedColumns,
44
onColumnSelectionChange
45
}) => {
46
const [open, setOpen] = useState(false)
47
const [availableColumns, setAvailableColumns] = useState<string[]>([])
48
const [localSelectedColumns, setLocalSelectedColumns] = useState<string[]>(selectedColumns)
49
50
useEffect(() => {
51
setLocalSelectedColumns(selectedColumns)
52
}, [selectedColumns])
53
54
useEffect(() => {
55
let allKeys = new Set<string>()
56
try {
57
const savedKeys = localStorage.getItem('selenium-grid-all-capability-keys')
58
if (savedKeys) {
59
const parsedKeys = JSON.parse(savedKeys)
60
parsedKeys.forEach((key: string) => allKeys.add(key))
61
}
62
} catch (e) {
63
console.error('Error loading saved capability keys:', e)
64
}
65
66
sessions.forEach(session => {
67
try {
68
const capabilities = JSON.parse(session.capabilities)
69
Object.keys(capabilities).forEach(key => {
70
if (
71
typeof capabilities[key] !== 'object' &&
72
!key.startsWith('goog:') &&
73
!key.startsWith('moz:') &&
74
key !== 'alwaysMatch' &&
75
key !== 'firstMatch'
76
) {
77
allKeys.add(key)
78
}
79
})
80
} catch (e) {
81
console.error('Error parsing capabilities:', e)
82
}
83
})
84
85
const keysArray = Array.from(allKeys).sort()
86
localStorage.setItem('selenium-grid-all-capability-keys', JSON.stringify(keysArray))
87
88
setAvailableColumns(keysArray)
89
}, [sessions])
90
91
const handleToggle = (column: string) => {
92
setLocalSelectedColumns(prev => {
93
if (prev.includes(column)) {
94
return prev.filter(col => col !== column)
95
} else {
96
return [...prev, column]
97
}
98
})
99
}
100
101
const handleClose = () => {
102
setOpen(false)
103
}
104
105
const handleSave = () => {
106
onColumnSelectionChange(localSelectedColumns)
107
setOpen(false)
108
}
109
110
const handleSelectAll = (checked: boolean) => {
111
if (checked) {
112
setLocalSelectedColumns([...availableColumns])
113
} else {
114
setLocalSelectedColumns([])
115
}
116
}
117
118
return (
119
<Box>
120
<Tooltip title="Select columns to display" arrow placement="top">
121
<IconButton
122
aria-label="select columns"
123
onClick={() => setOpen(true)}
124
>
125
<ViewColumnIcon />
126
</IconButton>
127
</Tooltip>
128
129
<Dialog
130
open={open}
131
onClose={handleClose}
132
maxWidth="sm"
133
fullWidth
134
>
135
<DialogTitle>
136
Select Columns to Display
137
</DialogTitle>
138
<DialogContent dividers>
139
<Typography variant="body2" gutterBottom>
140
Select capability fields to display as additional columns:
141
</Typography>
142
<FormGroup>
143
<FormControlLabel
144
control={
145
<Checkbox
146
checked={localSelectedColumns.length === availableColumns.length && availableColumns.length > 0}
147
indeterminate={localSelectedColumns.length > 0 && localSelectedColumns.length < availableColumns.length}
148
onChange={(e) => handleSelectAll(e.target.checked)}
149
/>
150
}
151
label={<Typography fontWeight="bold">Select All / Unselect All</Typography>}
152
/>
153
{availableColumns.map(column => (
154
<FormControlLabel
155
key={column}
156
control={
157
<Checkbox
158
checked={localSelectedColumns.includes(column)}
159
onChange={() => handleToggle(column)}
160
/>
161
}
162
label={column}
163
/>
164
))}
165
</FormGroup>
166
</DialogContent>
167
<DialogActions>
168
<Button onClick={handleClose}>Cancel</Button>
169
<Button onClick={handleSave} variant="contained" color="primary">
170
Apply
171
</Button>
172
</DialogActions>
173
</Dialog>
174
</Box>
175
)
176
}
177
178
export default ColumnSelector
179
180