@@ -51,6 +51,7 @@ import { Size } from '../../models/size'
51
51
import LiveView from '../LiveView/LiveView'
52
52
import SessionData , { createSessionData } from '../../models/session-data'
53
53
import { useNavigate } from 'react-router-dom'
54
+ import ColumnSelector from './ColumnSelector'
54
55
55
56
function descendingComparator < T > ( a : T , b : T , orderBy : keyof T ) : number {
56
57
if ( orderBy === 'sessionDurationMillis' ) {
@@ -94,7 +95,7 @@ interface HeadCell {
94
95
numeric : boolean
95
96
}
96
97
97
- const headCells : HeadCell [ ] = [
98
+ const fixedHeadCells : HeadCell [ ] = [
98
99
{ id : 'id' , numeric : false , label : 'Session' } ,
99
100
{ id : 'capabilities' , numeric : false , label : 'Capabilities' } ,
100
101
{ id : 'startTime' , numeric : false , label : 'Start time' } ,
@@ -107,10 +108,11 @@ interface EnhancedTableProps {
107
108
property : keyof SessionData ) => void
108
109
order : Order
109
110
orderBy : string
111
+ headCells : HeadCell [ ]
110
112
}
111
113
112
114
function EnhancedTableHead ( props : EnhancedTableProps ) : JSX . Element {
113
- const { order, orderBy, onRequestSort } = props
115
+ const { order, orderBy, onRequestSort, headCells } = props
114
116
const createSortHandler = ( property : keyof SessionData ) => ( event : React . MouseEvent < unknown > ) => {
115
117
onRequestSort ( event , property )
116
118
}
@@ -181,6 +183,16 @@ function RunningSessions (props) {
181
183
const [ rowsPerPage , setRowsPerPage ] = useState ( 10 )
182
184
const [ searchFilter , setSearchFilter ] = useState ( '' )
183
185
const [ searchBarHelpOpen , setSearchBarHelpOpen ] = useState ( false )
186
+ const [ selectedColumns , setSelectedColumns ] = useState < string [ ] > ( ( ) => {
187
+ try {
188
+ const savedColumns = localStorage . getItem ( 'selenium-grid-selected-columns' )
189
+ return savedColumns ? JSON . parse ( savedColumns ) : [ ]
190
+ } catch ( e ) {
191
+ console . error ( 'Error loading saved columns:' , e )
192
+ return [ ]
193
+ }
194
+ } )
195
+ const [ headCells , setHeadCells ] = useState < HeadCell [ ] > ( fixedHeadCells )
184
196
const liveViewRef = useRef ( null )
185
197
const navigate = useNavigate ( )
186
198
@@ -264,8 +276,27 @@ function RunningSessions (props) {
264
276
265
277
const { sessions, origin, sessionId } = props
266
278
279
+ const getCapabilityValue = ( capabilitiesStr : string , key : string ) : string => {
280
+ try {
281
+ const capabilities = JSON . parse ( capabilitiesStr as string )
282
+ const value = capabilities [ key ]
283
+
284
+ if ( value === undefined || value === null ) {
285
+ return ''
286
+ }
287
+
288
+ if ( typeof value === 'object' ) {
289
+ return JSON . stringify ( value )
290
+ }
291
+
292
+ return String ( value )
293
+ } catch ( e ) {
294
+ return ''
295
+ }
296
+ }
297
+
267
298
const rows = sessions . map ( ( session ) => {
268
- return createSessionData (
299
+ const sessionData = createSessionData (
269
300
session . id ,
270
301
session . capabilities ,
271
302
session . startTime ,
@@ -276,6 +307,12 @@ function RunningSessions (props) {
276
307
session . slot ,
277
308
origin
278
309
)
310
+
311
+ selectedColumns . forEach ( column => {
312
+ sessionData [ column ] = getCapabilityValue ( session . capabilities , column )
313
+ } )
314
+
315
+ return sessionData
279
316
} )
280
317
const emptyRows = rowsPerPage - Math . min ( rowsPerPage , rows . length - page * rowsPerPage )
281
318
@@ -291,19 +328,39 @@ function RunningSessions (props) {
291
328
setRowLiveViewOpen ( s )
292
329
}
293
330
} , [ sessionId , sessions ] )
331
+
332
+ useEffect ( ( ) => {
333
+ const dynamicHeadCells = selectedColumns . map ( column => ( {
334
+ id : column ,
335
+ numeric : false ,
336
+ label : column
337
+ } ) )
338
+
339
+ setHeadCells ( [ ...fixedHeadCells , ...dynamicHeadCells ] )
340
+ } , [ selectedColumns ] )
294
341
295
342
return (
296
343
< Box width = '100%' >
297
344
{ rows . length > 0 && (
298
345
< div >
299
346
< Paper sx = { { width : '100%' , marginBottom : 2 } } >
300
347
< EnhancedTableToolbar title = 'Running' >
301
- < RunningSessionsSearchBar
302
- searchFilter = { searchFilter }
303
- handleSearch = { setSearchFilter }
304
- searchBarHelpOpen = { searchBarHelpOpen }
305
- setSearchBarHelpOpen = { setSearchBarHelpOpen }
306
- />
348
+ < Box display = "flex" alignItems = "center" >
349
+ < ColumnSelector
350
+ sessions = { sessions }
351
+ selectedColumns = { selectedColumns }
352
+ onColumnSelectionChange = { ( columns ) => {
353
+ setSelectedColumns ( columns )
354
+ localStorage . setItem ( 'selenium-grid-selected-columns' , JSON . stringify ( columns ) )
355
+ } }
356
+ />
357
+ < RunningSessionsSearchBar
358
+ searchFilter = { searchFilter }
359
+ handleSearch = { setSearchFilter }
360
+ searchBarHelpOpen = { searchBarHelpOpen }
361
+ setSearchBarHelpOpen = { setSearchBarHelpOpen }
362
+ />
363
+ </ Box >
307
364
</ EnhancedTableToolbar >
308
365
< TableContainer >
309
366
< Table
@@ -316,6 +373,7 @@ function RunningSessions (props) {
316
373
order = { order }
317
374
orderBy = { orderBy }
318
375
onRequestSort = { handleRequestSort }
376
+ headCells = { headCells }
319
377
/>
320
378
< TableBody >
321
379
{ stableSort ( rows , getComparator ( order , orderBy ) )
@@ -494,6 +552,10 @@ function RunningSessions (props) {
494
552
< TableCell align = 'left' >
495
553
{ row . nodeUri }
496
554
</ TableCell >
555
+ { /* Add dynamic columns */ }
556
+ { selectedColumns . map ( column => (
557
+ < TableCell key = { column } align = 'left' > { row [ column ] } </ TableCell >
558
+ ) ) }
497
559
</ TableRow >
498
560
)
499
561
} ) }
0 commit comments