DataTableProvider.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import type {
  2. ColumnDef,
  3. ColumnFiltersState,
  4. PaginationState,
  5. RowSelectionState,
  6. SortingState,
  7. Table,
  8. VisibilityState,
  9. } from '@tanstack/react-table'
  10. import { createContext, ReactNode, useContext, useMemo } from 'react'
  11. import { DataTableFilterField } from '../DataTable.types'
  12. import { QuerySearchParamsType } from '@/components/interfaces/UnifiedLogs/UnifiedLogs.types'
  13. import { ResponseError } from '@/types'
  14. // REMINDER: read about how to move controlled state out of the useReactTable hook
  15. // https://github.com/TanStack/table/discussions/4005#discussioncomment-7303569
  16. interface DataTableStateContextType {
  17. columnFilters: ColumnFiltersState
  18. sorting: SortingState
  19. rowSelection: RowSelectionState
  20. columnOrder: string[]
  21. columnVisibility: VisibilityState
  22. pagination: PaginationState
  23. enableColumnOrdering: boolean
  24. searchParameters: QuerySearchParamsType
  25. openRowId: string | undefined
  26. setOpenRowId: (id: string | undefined) => void
  27. }
  28. interface DataTableBaseContextType<TData = unknown, TValue = unknown> {
  29. table: Table<TData>
  30. error: ResponseError | null
  31. filterFields: DataTableFilterField<TData>[]
  32. columns: ColumnDef<TData, TValue>[]
  33. isFetching: boolean
  34. isError: boolean
  35. isLoading: boolean
  36. isLoadingCounts: boolean
  37. getFacetedUniqueValues?: (table: Table<TData>, columnId: string) => Map<string, number>
  38. getFacetedMinMaxValues?: (table: Table<TData>, columnId: string) => undefined | [number, number]
  39. }
  40. interface DataTableContextType<TData = unknown, TValue = unknown>
  41. extends DataTableStateContextType, DataTableBaseContextType<TData, TValue> {}
  42. export const DataTableContext = createContext<DataTableContextType<any, any> | null>(null)
  43. export function DataTableProvider<TData, TValue>({
  44. children,
  45. ...props
  46. }: Partial<DataTableStateContextType> &
  47. DataTableBaseContextType<TData, TValue> & {
  48. children: ReactNode
  49. }) {
  50. const value = useMemo(
  51. () => ({
  52. ...props,
  53. columnFilters: props.columnFilters ?? [],
  54. sorting: props.sorting ?? [],
  55. rowSelection: props.rowSelection ?? {},
  56. columnOrder: props.columnOrder ?? [],
  57. columnVisibility: props.columnVisibility ?? {},
  58. pagination: props.pagination ?? { pageIndex: 0, pageSize: 10 },
  59. enableColumnOrdering: props.enableColumnOrdering ?? false,
  60. searchParameters: props.searchParameters ?? ({} as any),
  61. openRowId: props.openRowId,
  62. setOpenRowId: props.setOpenRowId ?? (() => {}),
  63. }),
  64. [props]
  65. )
  66. return <DataTableContext.Provider value={value}>{children}</DataTableContext.Provider>
  67. }
  68. export function useDataTable<TData, TValue>() {
  69. const context = useContext(DataTableContext)
  70. if (!context) {
  71. throw new Error('useDataTable must be used within a DataTableProvider')
  72. }
  73. return context as DataTableContextType<TData, TValue>
  74. }