From 4561cb310699d62c0850e44b564fe94638da3ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Gu=CC=88ell=20Segarra?= Date: Wed, 14 Aug 2024 12:58:38 +0200 Subject: [PATCH 1/2] fix: more adjustments --- .../InfiniteTable/InfiniteTable.tsx | 64 +++++++------------ .../InfiniteTable/useColumnState.ts | 18 ------ 2 files changed, 24 insertions(+), 58 deletions(-) diff --git a/src/components/InfiniteTable/InfiniteTable.tsx b/src/components/InfiniteTable/InfiniteTable.tsx index 989076c..ceabea7 100644 --- a/src/components/InfiniteTable/InfiniteTable.tsx +++ b/src/components/InfiniteTable/InfiniteTable.tsx @@ -13,10 +13,8 @@ import "@/styles/ag-theme-quartz.css"; import { BodyScrollEvent, ColDef, - ColumnMovedEvent, ColumnResizedEvent, ColumnState, - DragStoppedEvent, FirstDataRenderedEvent, GridReadyEvent, IGetRowsParams, @@ -24,7 +22,6 @@ import { } from "ag-grid-community"; import { TableProps } from "@/types"; import { useDeepArrayMemo } from "@/hooks/useDeepArrayMemo"; -import debounce from "lodash/debounce"; import { HeaderCheckbox } from "./HeaderCheckbox"; import { useRowSelection } from "./useRowSelection"; import { useColumnState } from "./useColumnState"; @@ -133,36 +130,33 @@ const InfiniteTableComp = forwardRef( onGetColumnsState, }); - const debouncedOnColumnChanged = useCallback( - (state: ColumnState[]) => { - if (!columnChangeListenerReady.current) { - columnChangeListenerReady.current = true; + const onColumnChanged = useCallback(() => { + const state = gridRef?.current?.api.getColumnState(); + if (!columnChangeListenerReady.current) { + columnChangeListenerReady.current = true; + return; + } + if (!state) { + return; + } + applyAndUpdateNewState(state); + onColumnsChangedProps?.(state); + }, [applyAndUpdateNewState, onColumnsChangedProps]); + + const onColumnMoved = useCallback(() => { + onColumnChanged(); + }, [onColumnChanged]); + + const onColumnResized = useCallback( + (event: ColumnResizedEvent) => { + if (!event.finished) { return; } - applyAndUpdateNewState(state); - onColumnsChangedProps?.(state); + onColumnChanged(); }, - [applyAndUpdateNewState, onColumnsChangedProps], + [onColumnChanged], ); - const onColumnChanged = useCallback( - (event: DragStoppedEvent | ColumnResizedEvent) => { - // if (!event.finished) { - // return; - // } - // const et = event.source === "uiColumnResized"; - console.log({ event }); - const state = gridRef?.current?.api.getColumnState(); - if (!state) { - return; - } - debouncedOnColumnChanged(state); - }, - [debouncedOnColumnChanged], - ); - - const defaultColDef = useMemo(() => ({}), []); - const colDefs = useMemo((): ColDef[] => { const checkboxColumn = { checkboxSelection: true, @@ -299,14 +293,6 @@ const InfiniteTableComp = forwardRef( ], ); - console.log("-----"); - console.log("InfiniteTable render"); - console.log({ - internalState: gridRef.current?.api?.getColumnState(), - columnsPersistedStateRef: columnsPersistedStateRef.current, - }); - console.log("-----"); - const onGridReady = useCallback( (params: GridReadyEvent) => { params.api.setGridOption("datasource", { @@ -361,7 +347,6 @@ const InfiniteTableComp = forwardRef( ( suppressRowClickSelection={true} rowBuffer={0} rowSelection={"multiple"} - onDragStopped={onColumnChanged} - // onColumnMoved={onColumnChanged} - onColumnResized={onColumnChanged} + onDragStopped={onColumnMoved} + onColumnResized={onColumnResized} rowModelType={"infinite"} cacheBlockSize={20} onSelectionChanged={onSelectionChangedDebounced} diff --git a/src/components/InfiniteTable/useColumnState.ts b/src/components/InfiniteTable/useColumnState.ts index 5c7813c..d2b581a 100644 --- a/src/components/InfiniteTable/useColumnState.ts +++ b/src/components/InfiniteTable/useColumnState.ts @@ -53,33 +53,20 @@ export const useColumnState = ({ const applyPersistedState = useCallback(() => { runDeferredCallback(() => { - console.log( - "1- Applying column state: ", - columnsPersistedStateRef.current, - ); gridRef?.current?.api.applyColumnState({ state: columnsPersistedStateRef.current, applyOrder: true, }); - console.log( - "Checking state after applyColumnState: ", - gridRef?.current?.api.getColumnState()!, - ); }); }, [gridRef, runDeferredCallback]); const applyAndUpdateNewState = useCallback( (state: ColumnState[]) => { - console.log("3- Applying column state: ", state); columnsPersistedStateRef.current = state; gridRef?.current?.api.applyColumnState({ state: columnsPersistedStateRef.current, applyOrder: true, }); - console.log( - "Checking state after applyColumnState: ", - gridRef?.current?.api.getColumnState()!, - ); }, [gridRef], ); @@ -100,12 +87,7 @@ export const useColumnState = ({ ? col.width : col.width + spacePerColumn, })); - console.log("2- Applying column state: ", newState); gridRef?.current?.api.applyColumnState({ state: newState }); - console.log( - "Checking state after applyColumnState: ", - gridRef?.current?.api.getColumnState()!, - ); } }); }, [columnsToIgnore, gridRef, remainingBlankSpace, runDeferredCallback]); From c2c2407b4fe4715cfc6307484e8a65ad1194532c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Gu=CC=88ell=20Segarra?= Date: Thu, 15 Aug 2024 10:27:00 +0200 Subject: [PATCH 2/2] feat: add sort feature to columns --- .../InfiniteTable/InfiniteTable.tsx | 45 +++++++++++++++++-- src/types/index.ts | 3 ++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/components/InfiniteTable/InfiniteTable.tsx b/src/components/InfiniteTable/InfiniteTable.tsx index ceabea7..42bf995 100644 --- a/src/components/InfiniteTable/InfiniteTable.tsx +++ b/src/components/InfiniteTable/InfiniteTable.tsx @@ -19,6 +19,7 @@ import { GridReadyEvent, IGetRowsParams, RowDoubleClickedEvent, + SortDirection, } from "ag-grid-community"; import { TableProps } from "@/types"; import { useDeepArrayMemo } from "@/hooks/useDeepArrayMemo"; @@ -33,7 +34,15 @@ export type InfiniteTableProps = Omit< TableProps, "dataSource" & "loading" & "loadingComponent" & "height" > & { - onRequestData: (startRow: number, endRow: number) => Promise; + onRequestData: ({ + startRow, + endRow, + sortFields, + }: { + startRow: number; + endRow: number; + sortFields?: Record; + }) => Promise; height?: number; onColumnChanged?: (columnsState: ColumnState[]) => void; onGetColumnsState?: () => ColumnState[] | undefined; @@ -157,6 +166,30 @@ const InfiniteTableComp = forwardRef( [onColumnChanged], ); + const onSortChanged = useCallback(() => { + gridRef.current?.api?.purgeInfiniteCache(); + }, []); + + const getSortedFields = useCallback((): + | Record + | undefined => { + const state = gridRef?.current?.api.getColumnState()!; + + const columnsWithSort = state.filter((col) => col.sort); + if (columnsWithSort.length === 0) { + return undefined; + } + const sortFields = columnsWithSort.reduce( + (acc, col) => ({ + ...acc, + [col.colId]: col.sort, + }), + {}, + ); + + return sortFields; + }, []); + const colDefs = useMemo((): ColDef[] => { const checkboxColumn = { checkboxSelection: true, @@ -186,7 +219,7 @@ const InfiniteTableComp = forwardRef( const restOfColumns = columns.map((column) => ({ field: column.key, - sortable: false, + sortable: column.isSortable, headerName: column.title, cellRenderer: column.render ? (cell: any) => column.render(cell.value) @@ -236,7 +269,11 @@ const InfiniteTableComp = forwardRef( async (params: IGetRowsParams) => { gridRef.current?.api.showLoadingOverlay(); const { startRow, endRow } = params; - const data = await onRequestData(startRow, endRow); + const data = await onRequestData({ + startRow, + endRow, + sortFields: getSortedFields(), + }); let lastRow = -1; if (data.length < endRow - startRow) { lastRow = startRow + data.length; @@ -284,6 +321,7 @@ const InfiniteTableComp = forwardRef( }, [ applyColumnState, + getSortedFields, hasStatusColumn, onGetSelectedRowKeys, onRequestData, @@ -370,6 +408,7 @@ const InfiniteTableComp = forwardRef( onBodyScroll={onBodyScroll} blockLoadDebounceMillis={DEBOUNCE_TIME} suppressDragLeaveHidesColumns={true} + onSortChanged={onSortChanged} /> {footer &&
{footer}
} diff --git a/src/types/index.ts b/src/types/index.ts index 5192936..eab55b9 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -6,6 +6,7 @@ export type TableColumn = { title: string; render?: (item: any) => React.ReactNode; sorter?: (a: any, b: any, column: string, desc: boolean) => number; + isSortable?: boolean; }; export type Sorter = { @@ -64,3 +65,5 @@ export type TableProps = { export interface TableRef { unselectAll: () => void; } + +export type SortDirection = "asc" | "desc" | null | undefined;