-
Notifications
You must be signed in to change notification settings - Fork 5
/
TableBuilder.tsx
128 lines (114 loc) · 3.22 KB
/
TableBuilder.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { useState } from 'react'
import {
useReactTable,
getCoreRowModel,
getSortedRowModel,
getFilteredRowModel,
ColumnFiltersState,
ColumnDef,
} from '@tanstack/react-table'
import { Button, Form } from 'react-bootstrap'
import Table from 'react-bootstrap/Table'
import TableHeader from './TableHeader'
import TableRow from './TableRow'
/*
This component uses TanStack Table to add filtering
and sorting functionality.
For documentation, visit: https://tanstack.com/table/v8/docs/introduction
*/
interface GlobalFilter {
label: string
checked: boolean
loading?: boolean
onChange: () => void
}
interface TableBuilderProps<T> {
data: T[]
columns: ColumnDef<T>[]
filterableInputs?: string[]
globalFilter?: GlobalFilter
}
function TableBuilder<T extends object>({
data,
columns,
filterableInputs = [],
globalFilter,
}: TableBuilderProps<T>) {
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
const [sorting, setSorting] = useState([])
const table = useReactTable<T>({
data,
columns: columns,
state: {
sorting,
columnFilters,
},
onColumnFiltersChange: setColumnFilters,
getSortedRowModel: getSortedRowModel(),
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
})
const resetFilters = () => {
table.resetColumnFilters()
if (globalFilter) {
globalFilter.onChange()
}
}
const renderTableBody = () => {
const rows = table.getRowModel().rows
if (!rows.length) {
return (
<tr className="border">
<td colSpan={100} className="text-center py-4">
<span className="text-muted">No results found</span>
</td>
</tr>
)
}
return rows.map((row) => <TableRow row={row} key={row.id} />)
}
return (
<div className="pt-2">
<Table striped borderless>
<thead>
{(!!filterableInputs.length || globalFilter) && (
<tr className="border">
<td colSpan={100} className="text-end pe-2">
<div className="d-inline-flex align-items-center gap-3">
{globalFilter && (
<Form.Check
type="checkbox"
id="treasury-files-filter"
label={globalFilter.label}
checked={globalFilter.checked}
onChange={globalFilter.onChange}
disabled={globalFilter.loading}
className="mb-0"
/>
)}
<Button
className="btn btn-secondary"
size="sm"
onClick={resetFilters}
>
Reset filters
</Button>
</div>
</td>
</tr>
)}
{table.getHeaderGroups().map((headerGroup) => (
<TableHeader
key={headerGroup.id}
headerGroup={headerGroup}
filterableInputs={filterableInputs}
/>
))}
</thead>
<tbody>{renderTableBody()}</tbody>
</Table>
</div>
)
}
export default TableBuilder