/
column.utils.ts
123 lines (116 loc) · 3.84 KB
/
column.utils.ts
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
import { type Row } from '@tanstack/react-table';
import {
type MRT_Column,
type MRT_ColumnDef,
type MRT_ColumnOrderState,
type MRT_DefinedColumnDef,
type MRT_DefinedTableOptions,
type MRT_FilterOption,
type MRT_RowData,
} from '../types';
export const getColumnId = <TData extends MRT_RowData>(
columnDef: MRT_ColumnDef<TData>,
): string =>
columnDef.id ?? columnDef.accessorKey?.toString?.() ?? columnDef.header;
export const getAllLeafColumnDefs = <TData extends MRT_RowData>(
columns: MRT_ColumnDef<TData>[],
): MRT_ColumnDef<TData>[] => {
const allLeafColumnDefs: MRT_ColumnDef<TData>[] = [];
const getLeafColumns = (cols: MRT_ColumnDef<TData>[]) => {
cols.forEach((col) => {
if (col.columns) {
getLeafColumns(col.columns);
} else {
allLeafColumnDefs.push(col);
}
});
};
getLeafColumns(columns);
return allLeafColumnDefs;
};
export const prepareColumns = <TData extends MRT_RowData>({
columnDefs,
tableOptions,
}: {
columnDefs: MRT_ColumnDef<TData>[];
tableOptions: MRT_DefinedTableOptions<TData>;
}): MRT_DefinedColumnDef<TData>[] => {
const {
aggregationFns = {},
defaultDisplayColumn,
filterFns = {},
sortingFns = {},
state: { columnFilterFns = {} } = {},
} = tableOptions;
return columnDefs.map((columnDef) => {
//assign columnId
if (!columnDef.id) columnDef.id = getColumnId(columnDef);
//assign columnDefType
if (!columnDef.columnDefType) columnDef.columnDefType = 'data';
if (columnDef.columns?.length) {
columnDef.columnDefType = 'group';
//recursively prepare columns if this is a group column
columnDef.columns = prepareColumns({
columnDefs: columnDef.columns,
tableOptions,
});
} else if (columnDef.columnDefType === 'data') {
//assign aggregationFns if multiple aggregationFns are provided
if (Array.isArray(columnDef.aggregationFn)) {
const aggFns = columnDef.aggregationFn as string[];
columnDef.aggregationFn = (
columnId: string,
leafRows: Row<TData>[],
childRows: Row<TData>[],
) =>
aggFns.map((fn) =>
aggregationFns[fn]?.(columnId, leafRows, childRows),
);
}
//assign filterFns
if (Object.keys(filterFns).includes(columnFilterFns[columnDef.id])) {
columnDef.filterFn =
filterFns[columnFilterFns[columnDef.id]] ?? filterFns.fuzzy;
(columnDef as MRT_DefinedColumnDef<TData>)._filterFn =
columnFilterFns[columnDef.id];
}
//assign sortingFns
if (Object.keys(sortingFns).includes(columnDef.sortingFn as string)) {
// @ts-ignore
columnDef.sortingFn = sortingFns[columnDef.sortingFn];
}
} else if (columnDef.columnDefType === 'display') {
columnDef = {
...(defaultDisplayColumn as MRT_ColumnDef<TData>),
...columnDef,
};
}
return columnDef;
}) as MRT_DefinedColumnDef<TData>[];
};
export const reorderColumn = <TData extends MRT_RowData>(
draggedColumn: MRT_Column<TData>,
targetColumn: MRT_Column<TData>,
columnOrder: MRT_ColumnOrderState,
): MRT_ColumnOrderState => {
if (draggedColumn.getCanPin()) {
draggedColumn.pin(targetColumn.getIsPinned());
}
const newColumnOrder = [...columnOrder];
newColumnOrder.splice(
newColumnOrder.indexOf(targetColumn.id),
0,
newColumnOrder.splice(newColumnOrder.indexOf(draggedColumn.id), 1)[0],
);
return newColumnOrder;
};
export const getDefaultColumnFilterFn = <TData extends MRT_RowData>(
columnDef: MRT_ColumnDef<TData>,
): MRT_FilterOption => {
const { filterVariant } = columnDef;
if (filterVariant === 'multi-select') return 'arrIncludesSome';
if (filterVariant?.includes('range')) return 'betweenInclusive';
if (filterVariant === 'select' || filterVariant === 'checkbox')
return 'equals';
return 'fuzzy';
};