@@ -12,8 +12,11 @@ import GetStartedTest from "@components/ui/GetStartedTest";
12
12
import { NotificationCountBadge } from "@components/ui/NotificationCountBadge" ;
13
13
import {
14
14
ColumnDef ,
15
+ ColumnFiltersState ,
15
16
RowSelectionState ,
16
17
SortingState ,
18
+ Table ,
19
+ VisibilityState ,
17
20
} from "@tanstack/react-table" ;
18
21
import { uniqBy } from "lodash" ;
19
22
import { ExternalLinkIcon } from "lucide-react" ;
@@ -65,6 +68,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
65
68
{
66
69
id : "name" ,
67
70
accessorFn : ( peer ) => `${ peer ?. name } ${ peer ?. dns_label } ` ,
71
+ enableHiding : false ,
68
72
header : ( { column } ) => {
69
73
return < DataTableHeader column = { column } > Name</ DataTableHeader > ;
70
74
} ,
@@ -83,6 +87,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
83
87
accessorFn : ( peer ) => peer . connected ,
84
88
} ,
85
89
{
90
+ id : "ip" ,
86
91
accessorKey : "ip" ,
87
92
sortingFn : "text" ,
88
93
} ,
@@ -96,18 +101,21 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
96
101
} ,
97
102
{
98
103
id : "dns_label" ,
104
+ enableHiding : false ,
99
105
accessorKey : "dns_label" ,
100
106
header : ( { column } ) => {
101
107
return < DataTableHeader column = { column } > Address</ DataTableHeader > ;
102
108
} ,
103
109
cell : ( { row } ) => < PeerAddressCell peer = { row . original } /> ,
104
110
} ,
105
111
{
112
+ id : "group_name_strings" ,
106
113
accessorKey : "group_name_strings" ,
107
114
accessorFn : ( peer ) => peer . groups ?. map ( ( g ) => g ?. name || "" ) . join ( ", " ) ,
108
115
sortingFn : "text" ,
109
116
} ,
110
117
{
118
+ id : "group_names" ,
111
119
accessorKey : "group_names" ,
112
120
accessorFn : ( peer ) => peer . groups ?. map ( ( g ) => g ?. name || "" ) ,
113
121
sortingFn : "text" ,
@@ -126,6 +134,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
126
134
) ,
127
135
} ,
128
136
{
137
+ id : "last_seen" ,
129
138
accessorKey : "last_seen" ,
130
139
header : ( { column } ) => {
131
140
return < DataTableHeader column = { column } > Last seen</ DataTableHeader > ;
@@ -150,6 +159,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
150
159
sortingFn : "text" ,
151
160
} ,
152
161
{
162
+ id : "version" ,
153
163
accessorKey : "version" ,
154
164
header : ( { column } ) => {
155
165
return < DataTableHeader column = { column } > Version</ DataTableHeader > ;
@@ -176,6 +186,7 @@ const PeersTableColumns: ColumnDef<Peer>[] = [
176
186
} ,
177
187
{
178
188
id : "actions" ,
189
+ enableHiding : false ,
179
190
accessorKey : "id" ,
180
191
header : "" ,
181
192
cell : ( { row } ) => (
@@ -234,13 +245,60 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
234
245
}
235
246
} ;
236
247
248
+ const filteredColunms = [
249
+ "connected" ,
250
+ "approval_required" ,
251
+ "group_name_strings" ,
252
+ "group_names" ,
253
+ ] ;
254
+
255
+ /**
256
+ * This function overrides the given column filters and reuses the previous filters
257
+ *
258
+ * Table index and selection is also cleared
259
+ */
260
+ const overrideTableFilter = ( table : Table < Peer > , change : ColumnFiltersState ) => {
261
+ let filters = [ ] as ColumnFiltersState ;
262
+
263
+ filteredColunms . forEach ( ( columnId ) => {
264
+ let columnFilter = change . find ( ( entry ) => entry . id == columnId ) ;
265
+ if ( columnFilter === undefined ) {
266
+ columnFilter = {
267
+ id : columnId ,
268
+ value : table . getColumn ( columnId ) ?. getFilterValue ( )
269
+ }
270
+ }
271
+ filters . push ( columnFilter ) ;
272
+ } )
273
+ table . setPageIndex ( 0 ) ;
274
+ table . setColumnFilters ( filters ) ;
275
+ resetSelectedRows ( ) ;
276
+ } ;
277
+
278
+ const columnVisibility : VisibilityState = {
279
+ select : ! isUser ,
280
+ actions : ! isUser ,
281
+ groups : ! isUser ,
282
+ connected : false ,
283
+ approval_required : false ,
284
+
285
+ // hidden, but usefull for lookup
286
+ serial : false ,
287
+ group_name_strings : false ,
288
+ group_names : false ,
289
+ ip : false ,
290
+ user_name : false ,
291
+ user_email : false ,
292
+ } ;
293
+
237
294
return (
238
295
< >
239
296
< PeerMultiSelect
240
297
selectedPeers = { selectedRows }
241
298
onCanceled = { ( ) => setSelectedRows ( { } ) }
242
299
/>
243
300
< DataTable
301
+ keepStateInLocalStorage = { true }
244
302
headingTarget = { headingTarget }
245
303
rowSelection = { selectedRows }
246
304
setRowSelection = { setSelectedRows }
@@ -251,19 +309,7 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
251
309
columns = { PeersTableColumns }
252
310
data = { peers }
253
311
searchPlaceholder = { "Search by name, IP, Serial, owner or group..." }
254
- columnVisibility = { {
255
- select : ! isUser ,
256
- connected : false ,
257
- approval_required : false ,
258
- group_name_strings : false ,
259
- group_names : false ,
260
- ip : false ,
261
- serial : false ,
262
- user_name : false ,
263
- user_email : false ,
264
- actions : ! isUser ,
265
- groups : ! isUser ,
266
- } }
312
+ columnVisibility = { columnVisibility }
267
313
isLoading = { isLoading }
268
314
getStartedCard = {
269
315
< GetStartedTest
@@ -302,29 +348,12 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
302
348
< ButtonGroup . Button
303
349
disabled = { peers ?. length == 0 }
304
350
onClick = { ( ) => {
305
- table . setPageIndex ( 0 ) ;
306
- let groupFilters = table
307
- . getColumn ( "group_names" )
308
- ?. getFilterValue ( ) ;
309
- table . setColumnFilters ( [
351
+ overrideTableFilter ( table , [
310
352
{
311
353
id : "connected" ,
312
354
value : undefined ,
313
355
} ,
314
- {
315
- id : "approval_required" ,
316
- value : undefined ,
317
- } ,
318
- {
319
- id : "group_names" ,
320
- value : groupFilters ?? [ ] ,
321
- } ,
322
- {
323
- id : "group_names" ,
324
- value : groupFilters ?? [ ] ,
325
- } ,
326
356
] ) ;
327
- resetSelectedRows ( ) ;
328
357
} }
329
358
variant = {
330
359
table . getColumn ( "connected" ) ?. getFilterValue ( ) == undefined
@@ -336,29 +365,12 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
336
365
</ ButtonGroup . Button >
337
366
< ButtonGroup . Button
338
367
onClick = { ( ) => {
339
- table . setPageIndex ( 0 ) ;
340
- let groupFilters = table
341
- . getColumn ( "group_names" )
342
- ?. getFilterValue ( ) ;
343
- table . setColumnFilters ( [
368
+ overrideTableFilter ( table , [
344
369
{
345
370
id : "connected" ,
346
371
value : true ,
347
372
} ,
348
- {
349
- id : "approval_required" ,
350
- value : undefined ,
351
- } ,
352
- {
353
- id : "group_names" ,
354
- value : groupFilters ?? [ ] ,
355
- } ,
356
- {
357
- id : "group_names" ,
358
- value : groupFilters ?? [ ] ,
359
- } ,
360
373
] ) ;
361
- resetSelectedRows ( ) ;
362
374
} }
363
375
disabled = { peers ?. length == 0 }
364
376
variant = {
@@ -371,25 +383,12 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
371
383
</ ButtonGroup . Button >
372
384
< ButtonGroup . Button
373
385
onClick = { ( ) => {
374
- table . setPageIndex ( 0 ) ;
375
- let groupFilters = table
376
- . getColumn ( "group_names" )
377
- ?. getFilterValue ( ) ;
378
- table . setColumnFilters ( [
386
+ overrideTableFilter ( table , [
379
387
{
380
388
id : "connected" ,
381
389
value : false ,
382
390
} ,
383
- {
384
- id : "approval_required" ,
385
- value : undefined ,
386
- } ,
387
- {
388
- id : "group_names" ,
389
- value : groupFilters ?? [ ] ,
390
- } ,
391
391
] ) ;
392
- resetSelectedRows ( ) ;
393
392
} }
394
393
disabled = { peers ?. length == 0 }
395
394
variant = {
@@ -406,29 +405,21 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
406
405
< Button
407
406
disabled = { peers ?. length == 0 }
408
407
onClick = { ( ) => {
409
- table . setPageIndex ( 0 ) ;
410
408
let current =
411
409
table . getColumn ( "approval_required" ) ?. getFilterValue ( ) ===
412
- undefined
410
+ undefined
413
411
? true
414
412
: undefined ;
415
-
416
- table . setColumnFilters ( [
417
- {
418
- id : "connected" ,
419
- value : undefined ,
420
- } ,
413
+ overrideTableFilter ( table , [
421
414
{
422
415
id : "approval_required" ,
423
416
value : current ,
424
417
} ,
425
418
] ) ;
426
-
427
- resetSelectedRows ( ) ;
428
419
} }
429
420
variant = {
430
421
table . getColumn ( "approval_required" ) ?. getFilterValue ( ) ===
431
- true
422
+ true
432
423
? "tertiary"
433
424
: "secondary"
434
425
}
@@ -438,30 +429,33 @@ export default function PeersTable({ peers, isLoading, headingTarget }: Props) {
438
429
</ Button >
439
430
) }
440
431
441
- < DataTableRowsPerPage table = { table } disabled = { peers ?. length == 0 } />
442
-
443
- { ! isUser && (
432
+ {
433
+ ! isUser
434
+ && tableGroups . length > 1 // if length == 1, it means only "All" group exists, case not relevant
435
+ && (
444
436
< GroupSelector
445
437
disabled = { peers ?. length == 0 }
446
438
values = {
447
439
( table
448
440
. getColumn ( "group_names" )
449
441
?. getFilterValue ( ) as string [ ] ) || [ ]
450
442
}
451
- onChange = { ( groups ) => {
452
- table . setPageIndex ( 0 ) ;
453
- if ( groups . length == 0 ) {
454
- table . getColumn ( "group_names" ) ?. setFilterValue ( undefined ) ;
455
- return ;
456
- } else {
457
- table . getColumn ( "group_names" ) ?. setFilterValue ( groups ) ;
458
- }
459
- resetSelectedRows ( ) ;
443
+ onChange = { ( anyOfValues ) => {
444
+ const normalizedAnyOf = ( anyOfValues . length == 0 ) ? undefined : anyOfValues ;
445
+ overrideTableFilter ( table , [
446
+ {
447
+ id : "group_names" ,
448
+ value : normalizedAnyOf
449
+ } ,
450
+ ]
451
+ ) ;
460
452
} }
461
453
groups = { tableGroups }
462
454
/>
463
455
) }
464
456
457
+ < DataTableRowsPerPage table = { table } disabled = { peers ?. length == 0 } />
458
+
465
459
< DataTableRefreshButton
466
460
isDisabled = { peers ?. length == 0 }
467
461
onClick = { ( ) => {
0 commit comments