Skip to content

Commit

Permalink
Merge branch 'infintescroll' into alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
mguellsegarra committed Jul 4, 2024
2 parents c27409a + 6d9de62 commit cda349a
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 20 deletions.
48 changes: 28 additions & 20 deletions src/components/InfiniteTable/InfiniteTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { useDeepArrayMemo } from "@/hooks/useDeepArrayMemo";
import debounce from "lodash/debounce";
import { HeaderCheckbox } from "./HeaderCheckbox";
import { useRowSelection } from "./useRowSelection";
import { useAutoFitColumns } from "./useAutoFitColumns";
import { getPersistedColumnState } from "./columnStateHelper";

const DEBOUNCE_TIME = 50;

Expand Down Expand Up @@ -72,8 +74,14 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
const gridRef = useRef<AgGridReact>(null);
const firstTimeOnBodyScroll = useRef(true);
const allRowSelectedModeRef = useRef<boolean>(false);
const columnsPersistedState = useRef<any>();
const firstTimeResized = useRef(false);
const columnsPersistedStateRef = useRef<any>();
const containerRef = useRef<HTMLDivElement>(null);

const { autoSizeColumnsIfNecessary } = useAutoFitColumns({
gridRef,
containerRef,
columnsPersistedStateRef,
});

// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedOnColumnChanged = useCallback(
Expand Down Expand Up @@ -120,12 +128,6 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
allRowSelectedModeRef.current = allRowSelectedMode;
}, [allRowSelectedMode]);

useEffect(() => {
if (!columnsPersistedState.current) {
columnsPersistedState.current = onGetColumnsState?.();
}
}, [onGetColumnsState]);

const columns = useDeepArrayMemo(columnsProps, "key");

const defaultColDef = useMemo<ColDef>(() => ({}), []);
Expand Down Expand Up @@ -167,14 +169,19 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
totalRows,
]);

const autoResizeColumnsIfNecessary = useCallback(() => {
if (!columnsPersistedState.current && !firstTimeResized.current) {
firstTimeResized.current = true;
setTimeout(() => {
gridRef.current?.api.autoSizeAllColumns();
}, 50);
const columnKeys = useMemo(
() => columns.map((column) => column.key),
[columns],
);

useEffect(() => {
if (!columnsPersistedStateRef.current) {
columnsPersistedStateRef.current = getPersistedColumnState({
actualColumnKeys: columnKeys,
persistedColumnState: columnsPersistedStateRef.current,
});
}
}, []);
}, [columnKeys, onGetColumnsState]);

const getRows = useCallback(
async (params: IGetRowsParams) => {
Expand Down Expand Up @@ -209,10 +216,10 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
}
}
gridRef.current?.api.hideOverlay();
autoResizeColumnsIfNecessary();
autoSizeColumnsIfNecessary();
},
[
autoResizeColumnsIfNecessary,
autoSizeColumnsIfNecessary,
onGetSelectedRowKeys,
onRequestData,
selectedRowKeysPendingToRender,
Expand All @@ -222,9 +229,9 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(

const onGridReady = useCallback(
(params: GridReadyEvent) => {
if (columnsPersistedState.current) {
if (columnsPersistedStateRef.current) {
params.api.applyColumnState({
state: columnsPersistedState.current,
state: columnsPersistedStateRef.current,
applyOrder: true,
});
}
Expand Down Expand Up @@ -267,8 +274,9 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(

return (
<div
ref={containerRef}
className={`ag-grid-default-table ag-theme-quartz`}
style={{ height: height || 600 }}
style={{ height: height || 600, width: "100%" }}
>
<AgGridReact
ref={gridRef}
Expand Down
24 changes: 24 additions & 0 deletions src/components/InfiniteTable/columnStateHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const getPersistedColumnState = ({
actualColumnKeys,
persistedColumnState,
}: {
actualColumnKeys: string[];
persistedColumnState: any[];
}) => {
if (!persistedColumnState) {
return undefined;
}
const persistedColumnKeys = persistedColumnState.map(
(col) => col.colId as string,
);
// we now have to sort both actualColumnKeys and persistedColumnKeys, and detect if there are differences
const sortedActualColumnKeys = [...actualColumnKeys].sort();
const sortedPersistedColumnKeys = [...persistedColumnKeys].sort();
const areColumnKeysEqual =
JSON.stringify(sortedActualColumnKeys) ===
JSON.stringify(sortedPersistedColumnKeys);
if (!areColumnKeysEqual) {
return undefined;
}
return persistedColumnState;
};
56 changes: 56 additions & 0 deletions src/components/InfiniteTable/useAutoFitColumns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Column } from "ag-grid-community";
import { AgGridReact } from "ag-grid-react";
import { RefObject, useCallback, useRef } from "react";

export const useAutoFitColumns = ({
gridRef,
containerRef,
columnsPersistedStateRef,
}: {
gridRef: RefObject<AgGridReact>;
containerRef: RefObject<HTMLDivElement>;
columnsPersistedStateRef: RefObject<any>;
}) => {
const firstTimeResized = useRef(false);

const remainingBlankSpace = useCallback(
(allColumns: Array<Column<any>>) => {
const totalColumnWidth = allColumns?.reduce(
(acc, column) => acc + column.getActualWidth(),
0,
);
const gridRefWidth = containerRef?.current?.clientWidth;
if (!gridRefWidth || !totalColumnWidth) return 0;
return gridRefWidth - totalColumnWidth;
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[],
);

const autoSizeColumnsIfNecessary = useCallback(() => {
if (!columnsPersistedStateRef.current && !firstTimeResized.current) {
firstTimeResized.current = true;
setTimeout(() => {
gridRef?.current?.api.autoSizeAllColumns();
const allColumns = gridRef?.current?.api.getAllGridColumns();
if (!allColumns) return;
const blankSpace = remainingBlankSpace(allColumns);
if (blankSpace > 0) {
const spacePerColumn = blankSpace / (allColumns.length - 1); // we skip the first checkbox column, since it's not resizable
const state = gridRef?.current?.api.getColumnState()!;
const newState = state.map((col: any) => ({
...col,
// colId 0 is the checkbox column
width: col.colId !== "0" ? col.width + spacePerColumn : col.width,
}));
gridRef?.current?.api.applyColumnState({ state: newState });
}
}, 50);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [remainingBlankSpace]);

return {
autoSizeColumnsIfNecessary,
};
};

0 comments on commit cda349a

Please sign in to comment.