1- import * as React from 'react'
1+ import { useEffect , useState } from 'react'
2+ import { getRouteApi } from '@tanstack/react-router'
23import {
3- type ColumnDef ,
4- type ColumnFiltersState ,
54 type SortingState ,
65 type VisibilityState ,
76 flexRender ,
@@ -13,6 +12,7 @@ import {
1312 getSortedRowModel ,
1413 useReactTable ,
1514} from '@tanstack/react-table'
15+ import { useTableUrlState } from '@/hooks/use-table-url-state'
1616import {
1717 Table ,
1818 TableBody ,
@@ -21,26 +21,43 @@ import {
2121 TableHeader ,
2222 TableRow ,
2323} from '@/components/ui/table'
24+ import { type Task } from '../data/schema'
2425import { DataTableBulkActions } from './data-table-bulk-actions'
2526import { DataTablePagination } from './data-table-pagination'
2627import { DataTableToolbar } from './data-table-toolbar'
28+ import { tasksColumns as columns } from './tasks-columns'
2729
28- type DataTableProps < TData , TValue > = {
29- columns : ColumnDef < TData , TValue > [ ]
30- data : TData [ ]
30+ const route = getRouteApi ( '/_authenticated/tasks/' )
31+
32+ type DataTableProps = {
33+ data : Task [ ]
3134}
3235
33- export function TasksTable < TData , TValue > ( {
34- columns,
35- data,
36- } : DataTableProps < TData , TValue > ) {
37- const [ rowSelection , setRowSelection ] = React . useState ( { } )
38- const [ columnVisibility , setColumnVisibility ] =
39- React . useState < VisibilityState > ( { } )
40- const [ columnFilters , setColumnFilters ] = React . useState < ColumnFiltersState > (
41- [ ]
42- )
43- const [ sorting , setSorting ] = React . useState < SortingState > ( [ ] )
36+ export function TasksTable ( { data } : DataTableProps ) {
37+ // Local UI-only states
38+ const [ rowSelection , setRowSelection ] = useState ( { } )
39+ const [ sorting , setSorting ] = useState < SortingState > ( [ ] )
40+ const [ columnVisibility , setColumnVisibility ] = useState < VisibilityState > ( { } )
41+
42+ // Synced with URL states
43+ const {
44+ globalFilter,
45+ onGlobalFilterChange,
46+ columnFilters,
47+ onColumnFiltersChange,
48+ pagination,
49+ onPaginationChange,
50+ ensurePageInRange,
51+ } = useTableUrlState ( {
52+ search : route . useSearch ( ) ,
53+ navigate : route . useNavigate ( ) ,
54+ pagination : { defaultPage : 1 , defaultPageSize : 10 } ,
55+ globalFilter : { enabled : true , key : 'filter' } ,
56+ columnFilters : [
57+ { columnId : 'status' , searchKey : 'status' , type : 'array' } ,
58+ { columnId : 'priority' , searchKey : 'priority' , type : 'array' } ,
59+ ] ,
60+ } )
4461
4562 const table = useReactTable ( {
4663 data,
@@ -50,20 +67,36 @@ export function TasksTable<TData, TValue>({
5067 columnVisibility,
5168 rowSelection,
5269 columnFilters,
70+ globalFilter,
71+ pagination,
5372 } ,
5473 enableRowSelection : true ,
5574 onRowSelectionChange : setRowSelection ,
5675 onSortingChange : setSorting ,
57- onColumnFiltersChange : setColumnFilters ,
5876 onColumnVisibilityChange : setColumnVisibility ,
77+ globalFilterFn : ( row , _columnId , filterValue ) => {
78+ const id = String ( row . getValue ( 'id' ) ) . toLowerCase ( )
79+ const title = String ( row . getValue ( 'title' ) ) . toLowerCase ( )
80+ const searchValue = String ( filterValue ) . toLowerCase ( )
81+
82+ return id . includes ( searchValue ) || title . includes ( searchValue )
83+ } ,
5984 getCoreRowModel : getCoreRowModel ( ) ,
6085 getFilteredRowModel : getFilteredRowModel ( ) ,
6186 getPaginationRowModel : getPaginationRowModel ( ) ,
6287 getSortedRowModel : getSortedRowModel ( ) ,
6388 getFacetedRowModel : getFacetedRowModel ( ) ,
6489 getFacetedUniqueValues : getFacetedUniqueValues ( ) ,
90+ onPaginationChange,
91+ onGlobalFilterChange,
92+ onColumnFiltersChange,
6593 } )
6694
95+ const pageCount = table . getPageCount ( )
96+ useEffect ( ( ) => {
97+ ensurePageInRange ( pageCount )
98+ } , [ pageCount , ensurePageInRange ] )
99+
67100 return (
68101 < div className = 'space-y-4 max-sm:has-[div[role="toolbar"]]:mb-16' >
69102 < DataTableToolbar table = { table } />
0 commit comments