3
3
import { type ColumnDef , type Table } from '@tanstack/react-table' ;
4
4
import { Pin } from 'lucide-react' ;
5
5
import { Checkbox } from '~/components/ui/checkbox' ;
6
- import { type ComponentType } from 'react' ;
7
6
8
7
import { type Activity , type Photo } from '~/server/db/schema' ;
9
8
import { Button } from '~/components/ui/button' ;
10
9
11
10
import { DataTableColumnHeader } from './data-table' ;
12
- import { activityFields } from '~/settings/activity' ;
11
+ import {
12
+ activityFields ,
13
+ type ActivityField ,
14
+ type ActivityValueType ,
15
+ } from '~/settings/activity' ;
13
16
14
17
import { ActivityCard , DescriptionCard } from './card' ;
15
18
import { EditActivity } from './edit' ;
16
19
import { PhotoLightbox } from './photo' ;
17
20
18
- type ActivityField = {
19
- formatter : ( value : any ) => string | null ;
20
- Icon ?: ComponentType < any > ;
21
- title : string ;
22
- reducer ?: ( values : any [ ] ) => number ;
23
- reducerSymbol ?: string ;
24
- summaryFormatter ?: ( value : any ) => string ;
25
- accessorFn ?: ( row : Activity ) => any ;
26
- } ;
27
-
28
- function columnFromField (
21
+ function columnFromField < K extends ActivityValueType > (
29
22
id : keyof typeof activityFields ,
30
- spec : ActivityField ,
23
+ spec : ActivityField < K > ,
31
24
) : ColumnDef < Activity > {
32
25
const footer = ( { table } : { table : Table < Activity > } ) => {
33
26
const rows =
@@ -38,21 +31,20 @@ function columnFromField(
38
31
: table . getState ( ) . summaryRow == 'all'
39
32
? table . getFilteredRowModel ( ) . rows
40
33
: table . getSelectedRowModel ( ) . rows ;
41
- const values = rows . map ( ( row ) => row . getValue ( id ) ) ;
34
+ const values : K [ ] = rows . map ( ( row ) => row . getValue ( id ) ) ;
42
35
const reducedValue = spec . reducer ? spec . reducer ( values ) : null ;
43
- const summary =
44
- spec . summaryFormatter && reducedValue != null
45
- ? spec . summaryFormatter ( reducedValue )
46
- : reducedValue != null
47
- ? `${ spec . reducerSymbol ?? '' } ${ spec . formatter ( reducedValue ) } `
48
- : '' ;
36
+ const summary = spec . summary
37
+ ? spec . summary ( values )
38
+ : reducedValue != null
39
+ ? `${ spec . reducerSymbol ?? '' } ${ spec . formatter ( reducedValue ) } `
40
+ : '' ;
49
41
return < div className = "text-right w-full" > { summary } </ div > ;
50
42
} ;
51
43
52
44
return {
53
45
id,
54
46
cell : ( { getValue } ) => (
55
- < div className = "text-right w-full" > { spec . formatter ( getValue ( ) ) } </ div >
47
+ < div className = "text-right w-full" > { spec . formatter ( getValue ( ) as K ) } </ div >
56
48
) ,
57
49
meta : {
58
50
title : spec . title ,
@@ -68,7 +60,7 @@ function columnFromField(
68
60
enableResizing : true ,
69
61
...( spec . accessorFn && { accessorFn : spec . accessorFn } ) ,
70
62
...( ! spec . accessorFn && { accessorKey : id } ) ,
71
- ...( spec . reducer && { footer } ) ,
63
+ ...( ( spec . reducer ?? spec . summary ) && { footer } ) ,
72
64
} ;
73
65
}
74
66
@@ -80,9 +72,11 @@ export const columns: ColumnDef<Activity>[] = [
80
72
< DataTableColumnHeader table = { table } column = { column } title = "ID" />
81
73
) ,
82
74
enableHiding : false ,
83
- filterFn : ( row , columnId , filterValue ) => {
84
- return filterValue . includes ( row . original . public_id ) ;
85
- } ,
75
+ filterFn : (
76
+ row : { original : Activity } ,
77
+ _columnId : string ,
78
+ filterValue : number [ ] ,
79
+ ) => filterValue . includes ( row . original . id ) ,
86
80
} ,
87
81
{
88
82
id : 'name' ,
@@ -128,7 +122,10 @@ export const columns: ColumnDef<Activity>[] = [
128
122
enableHiding : false ,
129
123
} ,
130
124
...Object . entries ( activityFields ) . map ( ( [ id , spec ] ) =>
131
- columnFromField ( id as keyof typeof activityFields , spec as ActivityField ) ,
125
+ columnFromField (
126
+ id as keyof typeof activityFields ,
127
+ spec as ActivityField < ActivityValueType > ,
128
+ ) ,
132
129
) ,
133
130
{
134
131
id : 'description' ,
0 commit comments