mirror of
https://github.com/UniversityOfHelsinkiCS/oodikone.git
synced 2026-10-12 19:03:39 +03:00
[OT] Spread TData and TValue
This commit is contained in:
@@ -4,14 +4,13 @@ import Table from '@mui/material/Table'
|
||||
import TableBody from '@mui/material/TableBody'
|
||||
import TableContainer from '@mui/material/TableContainer'
|
||||
import TableHead from '@mui/material/TableHead'
|
||||
|
||||
import { type Table as TableType } from '@tanstack/react-table'
|
||||
import type { RowData, Table as TableType } from '@tanstack/react-table'
|
||||
import { ReactNode } from 'react'
|
||||
import { OodiTableDataRow } from '@/components/OodiTable/components/Cell'
|
||||
import { OodiTableHeaderGroup } from '@/components/OodiTable/components/Header'
|
||||
import { OodiTablePagination } from '@/components/OodiTable/components/Pagination'
|
||||
|
||||
export const OodiTableContainer = <OTData,>({
|
||||
export const OodiTableContainer = <OTData extends RowData>({
|
||||
table,
|
||||
toolbarContent,
|
||||
isExportView,
|
||||
|
||||
@@ -2,12 +2,12 @@ import './styles.css'
|
||||
|
||||
import TableCell from '@mui/material/TableCell'
|
||||
import TableRow from '@mui/material/TableRow'
|
||||
import type { Row } from '@tanstack/react-table'
|
||||
import type { Row, RowData } from '@tanstack/react-table'
|
||||
|
||||
import { flexRender } from '@/components/OodiTable/components/util'
|
||||
import { getCommonPinningStyles } from '@/components/OodiTable/styles'
|
||||
|
||||
export const OodiTableDataRow = <OTData,>(row: Row<OTData>, aggregate = false) => (
|
||||
export const OodiTableDataRow = <OTData extends RowData>(row: Row<OTData>, aggregate = false) => (
|
||||
<TableRow key={row.id}>
|
||||
{row.getVisibleCells().map(cell => {
|
||||
const { size, maxSize } = cell.column.columnDef
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { styled, SxProps, Theme } from '@mui/material/styles'
|
||||
import TableCell from '@mui/material/TableCell'
|
||||
import TableRow from '@mui/material/TableRow'
|
||||
import type { Header, HeaderGroup } from '@tanstack/react-table'
|
||||
import type { Header, HeaderGroup, RowData } from '@tanstack/react-table'
|
||||
|
||||
import { useRef } from 'react'
|
||||
import { OodiTableSortIcons, OtSortIconWrapper } from '@/components/OodiTable/components/SortIcons'
|
||||
@@ -30,11 +30,11 @@ const OtVerticalContentWrapper = styled('div')({
|
||||
margin: '0 auto',
|
||||
})
|
||||
|
||||
const OodiTableHeaderSinglton = <OTData,>({
|
||||
const OodiTableHeaderSinglton = <OTData extends RowData, OTValue = unknown>({
|
||||
header,
|
||||
isVerticalHeader,
|
||||
}: {
|
||||
header: Header<OTData, unknown>
|
||||
header: Header<OTData, OTValue>
|
||||
isVerticalHeader: boolean
|
||||
}) => {
|
||||
const base = useRef(null)
|
||||
@@ -75,7 +75,10 @@ const OodiTableHeaderSinglton = <OTData,>({
|
||||
)
|
||||
}
|
||||
|
||||
export const OodiTableHeaderGroup = <OTData,>(headerGroup: HeaderGroup<OTData>, verticalHeaders: string[]) => (
|
||||
export const OodiTableHeaderGroup = <OTData extends RowData>(
|
||||
headerGroup: HeaderGroup<OTData>,
|
||||
verticalHeaders: string[]
|
||||
) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => {
|
||||
if (header.depth - header.column.depth > 1) return null
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
import { Cell, CellContext, Column, Row, Table, TableFeature } from '@tanstack/react-table'
|
||||
import type { Cell, CellContext, Column, Row, RowData, Table, TableFeature } from '@tanstack/react-table'
|
||||
|
||||
/**
|
||||
* This doesn't implement all the features of Row, so be aware of that
|
||||
*/
|
||||
/* eslint-disable-line import-x/no-unused-modules */ export interface AggregationRow<TData> extends Row<TData> {
|
||||
/* eslint-disable-line import-x/no-unused-modules */ export interface AggregationRow<TData extends RowData>
|
||||
extends Row<TData> {
|
||||
getIsAggregationRow: () => true
|
||||
}
|
||||
|
||||
type AggregationRowValueFn<TData, TValue = unknown> = (ctx: {
|
||||
type AggregationRowValueFn<TData extends RowData, TValue = unknown> = (ctx: {
|
||||
table: Table<TData>
|
||||
rowId: string
|
||||
column: Column<TData, TValue>
|
||||
}) => TValue
|
||||
|
||||
interface AggregationRowCellDef<TData, TValue = unknown> {
|
||||
interface AggregationRowCellDef<TData extends RowData, TValue = unknown> {
|
||||
id: string
|
||||
value: TValue | AggregationRowValueFn<TData, TValue>
|
||||
}
|
||||
|
||||
export type AggregationRowsInput<TData, TValue = unknown> =
|
||||
export type AggregationRowsInput<TData extends RowData, TValue = unknown> =
|
||||
| AggregationRowCellDef<TData, TValue>[]
|
||||
| ((ctx: { table: Table<TData>; column: Column<TData> }) => AggregationRowCellDef<TData, TValue>[])
|
||||
|
||||
export interface AggregationRowModel<TData> {
|
||||
export interface AggregationRowModel<TData extends RowData> {
|
||||
rows: AggregationRow<TData>[]
|
||||
flatRows: AggregationRow<TData>[]
|
||||
rowsById: Record<string, AggregationRow<TData>>
|
||||
}
|
||||
|
||||
const resolveAggregationRowsArray = <TData, TValue>(
|
||||
const resolveAggregationRowsArray = <TData extends RowData, TValue>(
|
||||
table: Table<TData>,
|
||||
column: Column<TData, TValue>
|
||||
): AggregationRowCellDef<TData, TValue>[] => {
|
||||
@@ -37,7 +38,7 @@ const resolveAggregationRowsArray = <TData, TValue>(
|
||||
return typeof input === 'function' ? (input({ table, column }) ?? []) : input
|
||||
}
|
||||
|
||||
const collectAggregationRowIds = <TData>(table: Table<TData>): string[] => {
|
||||
const collectAggregationRowIds = <TData extends RowData>(table: Table<TData>): string[] => {
|
||||
const seen: string[] = []
|
||||
const set = new Set<string>()
|
||||
|
||||
@@ -54,26 +55,28 @@ const collectAggregationRowIds = <TData>(table: Table<TData>): string[] => {
|
||||
return seen
|
||||
}
|
||||
|
||||
const resolveAggregationCellValue = <TData, TValue>(
|
||||
const resolveAggregationCellValue = <TData extends RowData, TValue>(
|
||||
table: Table<TData>,
|
||||
column: Column<TData, unknown>,
|
||||
column: Column<TData, TValue>,
|
||||
aggRowId: string
|
||||
): TValue | undefined => {
|
||||
const defs = resolveAggregationRowsArray(table, column)
|
||||
const def = defs.find(def => def.id === aggRowId)
|
||||
if (!def) return undefined
|
||||
const { value } = def
|
||||
|
||||
if (typeof value === 'function') {
|
||||
return (value as AggregationRowValueFn<TData>)({
|
||||
return (value as AggregationRowValueFn<TData, TValue>)({
|
||||
table,
|
||||
rowId: aggRowId,
|
||||
column,
|
||||
}) as TValue
|
||||
})
|
||||
}
|
||||
return value as TValue
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
const buildAggregationRowModel = <TData>(table: Table<TData>): AggregationRowModel<TData> => {
|
||||
const buildAggregationRowModel = <TData extends RowData>(table: Table<TData>): AggregationRowModel<TData> => {
|
||||
const aggRowIds = collectAggregationRowIds(table)
|
||||
|
||||
if (!aggRowIds.length) {
|
||||
@@ -81,7 +84,7 @@ const buildAggregationRowModel = <TData>(table: Table<TData>): AggregationRowMod
|
||||
rows: [],
|
||||
flatRows: [],
|
||||
rowsById: {},
|
||||
} as unknown as AggregationRowModel<TData>
|
||||
}
|
||||
}
|
||||
|
||||
const visibleLeafColumns =
|
||||
@@ -96,13 +99,13 @@ const buildAggregationRowModel = <TData>(table: Table<TData>): AggregationRowMod
|
||||
id: aggRowId,
|
||||
index,
|
||||
depth: 0,
|
||||
original: undefined as any,
|
||||
original: undefined as TData,
|
||||
parentId: undefined,
|
||||
_valuesCache: {},
|
||||
_uniqueValuesCache: {},
|
||||
_groupingValuesCache: {},
|
||||
getValue: <TValue>(columnId: string): TValue => {
|
||||
const column = table.getColumn(columnId)
|
||||
const column = table.getColumn(columnId) as Column<TData, TValue> | undefined
|
||||
return column
|
||||
? (resolveAggregationCellValue<TData, TValue>(table, column, aggRowId) as TValue)
|
||||
: (undefined as TValue)
|
||||
|
||||
@@ -11,7 +11,7 @@ declare module '@tanstack/react-table' {
|
||||
interface TableState extends VerticalHeaders {}
|
||||
interface TableState extends Zebrastripes {}
|
||||
|
||||
interface ColumnDefBase<TData, TValue = unknown> {
|
||||
interface ColumnDefBase<TData extends RowData, TValue> {
|
||||
/**
|
||||
* Accepts two kinds of inputs:
|
||||
*
|
||||
@@ -28,7 +28,7 @@ declare module '@tanstack/react-table' {
|
||||
aggregationRows?: AggregationRowsInput<TData, TValue>
|
||||
}
|
||||
|
||||
interface Table<TData> {
|
||||
interface Table<TData extends RowData> {
|
||||
/**
|
||||
* Aggregation rows are not included in pagination/sorting.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TableFeature } from '@tanstack/react-table'
|
||||
import type { TableFeature } from '@tanstack/react-table'
|
||||
|
||||
export interface Zebrastripes {
|
||||
useZebrastripes: boolean
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ColumnDef, TableOptions } from '@tanstack/react-table'
|
||||
import type { ColumnDef, RowData, Table, TableOptions } from '@tanstack/react-table'
|
||||
import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel } from '@tanstack/react-table'
|
||||
import { useState, type ReactNode } from 'react'
|
||||
|
||||
@@ -19,7 +19,7 @@ import { OodiTableContainer } from '@/components/OodiTable/OodiTable'
|
||||
* @returns Table instance
|
||||
*/
|
||||
|
||||
export const OodiTable = <TData,>({
|
||||
export const OodiTable = <TData extends RowData>({
|
||||
data,
|
||||
columns,
|
||||
isExportView,
|
||||
@@ -36,17 +36,18 @@ export const OodiTable = <TData,>({
|
||||
}) => {
|
||||
const [fallbackData] = useState()
|
||||
|
||||
// should maybe use a deep merging tool or write own
|
||||
const { ...config }: Partial<TableOptions<TData>> = options
|
||||
|
||||
const table = useReactTable<TData>({
|
||||
_features: [VerticalHeaderFeature, AggregationRowFeature, ZebrastripesFeature],
|
||||
data: data ?? fallbackData,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
...config,
|
||||
})
|
||||
const table: Table<TData> = useReactTable<TData>(
|
||||
Object.assign<TableOptions<TData>, Partial<TableOptions<TData>>>(
|
||||
{
|
||||
_features: [VerticalHeaderFeature, AggregationRowFeature, ZebrastripesFeature],
|
||||
data: data ?? fallbackData,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
getPaginationRowModel: getPaginationRowModel(),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
},
|
||||
options
|
||||
)
|
||||
)
|
||||
return <OodiTableContainer cy={cy} isExportView={isExportView} table={table} toolbarContent={toolbarContent} />
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type { SxProps, Theme } from '@mui/material/styles'
|
||||
import type { Column } from '@tanstack/react-table'
|
||||
import type { Column, RowData } from '@tanstack/react-table'
|
||||
|
||||
export const getCommonPinningStyles = <TData>(column: Column<TData>): SxProps<Theme> => {
|
||||
export const getCommonPinningStyles = <TData extends RowData, TValue = unknown>(
|
||||
column: Column<TData, TValue>
|
||||
): SxProps<Theme> => {
|
||||
const isPinned = column.getIsPinned()
|
||||
return isPinned
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user