Skip to content

Commit 80839ec

Browse files
enable Table defaultSorting through theme and context props
1 parent 9a1668a commit 80839ec

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

modules/components/src/Table/helpers/context.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const TableContextProvider = ({
3434
children,
3535
columns: customColumns,
3636
customFetcher,
37+
defaultSorting: customSorting,
3738
documentType: customDocumentType,
3839
fetchRetryLimit = 5,
3940
}: TableContextProviderProps): ReactElement<TableContextInterface> => {
@@ -66,16 +67,17 @@ export const TableContextProvider = ({
6667
callerName: 'TableContextProvider',
6768
});
6869

69-
const { components: { Table: { defaultSort: themeDefaultSorting } = emptyObj } = emptyObj } = useThemeContext({
70+
const { components: { Table: { defaultSorting: themeDefaultSorting } = emptyObj } = emptyObj } = useThemeContext({
7071
callerName: 'TableContextProvider',
7172
});
7273

7374
const defaultSorting = useMemo(
7475
() =>
76+
(Array.isArray(customSorting) && customSorting.length > 0 && customSorting) ||
7577
(Array.isArray(themeDefaultSorting) && themeDefaultSorting.length > 0 && themeDefaultSorting) ||
7678
tableConfigs?.defaultSorting ||
7779
[],
78-
[tableConfigs?.defaultSorting, themeDefaultSorting],
80+
[customSorting, tableConfigs?.defaultSorting, themeDefaultSorting],
7981
);
8082

8183
useEffect(() => {
@@ -247,13 +249,18 @@ export const TableContextProvider = ({
247249
export const useTableContext = ({
248250
callerName,
249251
customFetcher: localFetcher,
252+
defaultSorting: localDefaultSorting,
250253
}: UseTableContextProps = emptyObj): TableContextInterface => {
251254
const defaultContext = useContext(TableContext);
252255

253256
defaultContext.missingProvider && missingProviderHandler(TableContext.displayName, callerName);
254257

255258
return {
256259
...defaultContext,
260+
defaultSorting:
261+
Array.isArray(localDefaultSorting) && localDefaultSorting.length > 0
262+
? localDefaultSorting
263+
: defaultContext.defaultSorting,
257264
fetchData: localFetcher || defaultContext.fetchData,
258265
};
259266
};

modules/components/src/Table/helpers/index.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ import { type ReactNode, useEffect, useState } from 'react';
1010

1111
import { SELECTION_COLUMN_ID, type UseTableDataProps } from '#Table/types.js';
1212
import { useThemeContext } from '#ThemeContext/index.js';
13+
import type { ColumnSortingInterface } from '#types.js';
1314
import { emptyObj } from '#utils/noops.js';
1415

1516
import { makeTableColumns } from './columns.js';
1617
import { useTableContext } from './context.js';
1718

18-
export const getSingleValue = (data: Record<string, any> | ReactNode): ReactNode => {
19+
export const getSingleValue = (data: Record<string, unknown> | ReactNode): ReactNode => {
1920
if (typeof data === 'object' && data) {
2021
return getSingleValue(Object.values(data)[0]);
2122
} else {
@@ -25,9 +26,26 @@ export const getSingleValue = (data: Record<string, any> | ReactNode): ReactNode
2526

2627
const defaultSelectionColumnWidth = 28;
2728

29+
const sanitizeCustomSortingDesc = (sortingArray) => {
30+
return (sortingArray || []).map((field) => ({ ...field, desc: field.desc || false }));
31+
};
32+
33+
type SortingConverter = <T extends 'ReactTable' | 'Arranger'>(
34+
sortingArray: T extends 'ReactTable' ? ColumnSortingInterface[] : SortingState,
35+
direction: T,
36+
) => T extends 'ReactTable' ? SortingState : ColumnSortingInterface[];
37+
38+
const convertSorting: SortingConverter = (sortingArray, direction) => {
39+
return sanitizeCustomSortingDesc(sortingArray).map((field) => ({
40+
desc: field.desc,
41+
...(direction === 'ReactTable' ? { id: field.fieldName } : { fieldName: field.id }),
42+
})) as any; // because TS goes stupid with array methods
43+
};
44+
2845
export const useTableData = ({
2946
columnTypes: customColumnTypes,
3047
defaultColumnWidth: customColumnWidth,
48+
defaultSorting: customDefaultSorting,
3149
disableColumnResizing: customDisableColumnResizing,
3250
disableRowSelection: customDisableRowSelection,
3351
disableRowSorting: customDisableRowSorting,
@@ -48,6 +66,7 @@ export const useTableData = ({
4866
visibleColumnsDict,
4967
} = useTableContext({
5068
callerName: 'Table - useTableData',
69+
defaultSorting: sanitizeCustomSortingDesc(customDefaultSorting),
5170
});
5271

5372
const {
@@ -68,21 +87,20 @@ export const useTableData = ({
6887
const defaultColumnWidth = customColumnWidth || themeColumnWidth;
6988
const [tableColumns, setTableColumns] = useState<ColumnDef<unknown, string>[]>([]);
7089

90+
const initialSortingForReactTable = convertSorting(defaultSorting, 'ReactTable');
7191
const [reactTableSorting, setReactTableSorting] = useState<SortingState>([]);
7292

7393
const onSortingChange: OnChangeFn<SortingState> = (handleSorting) => {
7494
if (typeof handleSorting === 'function') {
7595
const newReactTableSorting = handleSorting(reactTableSorting);
7696

97+
const isValidNewReactTableSorting = Array.isArray(newReactTableSorting) && newReactTableSorting.length;
98+
7799
// update the data context for other Arranger components
78-
setSorting(
79-
newReactTableSorting.length
80-
? newReactTableSorting.map(({ id, desc }) => ({ fieldName: id, desc }))
81-
: defaultSorting,
82-
);
100+
setSorting(isValidNewReactTableSorting ? convertSorting(newReactTableSorting, 'Arranger') : defaultSorting);
83101

84102
// update react-table's internal state
85-
setReactTableSorting(newReactTableSorting);
103+
setReactTableSorting(isValidNewReactTableSorting ? newReactTableSorting : initialSortingForReactTable);
86104
} else {
87105
console.info('react-table is doing something unexpected with the sorting', handleSorting);
88106
}
@@ -106,8 +124,7 @@ export const useTableData = ({
106124
state: {
107125
...(allowRowSelection && { rowSelection: selectedRowsDict }),
108126
...(allowRowSorting && {
109-
// sorting: sorting.map(({ desc, fieldName }) => ({ desc, id: fieldName })),
110-
sorting: reactTableSorting,
127+
sorting: reactTableSorting.length ? reactTableSorting : initialSortingForReactTable,
111128
}),
112129
},
113130
});

modules/components/src/Table/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ export interface TableContextProviderProps {
6363
children?: React.ReactNode;
6464
columns?: ColumnMappingInterface[];
6565
customFetcher?: FetchDataFn;
66+
defaultSorting?: ColumnSortingInterface[];
6667
documentType?: string;
6768
fetchRetryLimit?: number;
6869
}
6970

7071
export interface UseTableContextProps {
7172
callerName?: string;
7273
customFetcher?: FetchDataFn;
74+
defaultSorting?: ColumnSortingInterface[];
7375
}
7476

7577
type TableBoxModelProperties = Omit<ThemeCommon.NonButtonThemeProps, 'flex'>;
@@ -121,6 +123,7 @@ export type ColumnTypesObject = Record<
121123
interface TableContextThemeProps {
122124
columnTypes: ColumnTypesObject;
123125
defaultColumnWidth: number;
126+
defaultSorting: ColumnSortingInterface[];
124127
disableColumnResizing: boolean;
125128
disableRowSelection: boolean;
126129
disableRowSorting: boolean;
@@ -130,7 +133,6 @@ export interface TableThemeProps
130133
extends TableContextThemeProps,
131134
ThemeCommon.FontProperties,
132135
Omit<TableBoxModelProperties, 'borderRadius'> {
133-
defaultSort: ColumnSortingInterface[];
134136
hideLoader: boolean;
135137
noColumnsMessage?: ReactNode;
136138
noDataMessage?: ReactNode;

0 commit comments

Comments
 (0)