Skip to content

Commit

Permalink
Merge branch 'feat/add-status-column' into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
mguellsegarra committed Jul 29, 2024
2 parents 164808e + e716fd0 commit a128b97
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 32 deletions.
102 changes: 73 additions & 29 deletions src/components/InfiniteTable/InfiniteTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export type InfiniteTableProps = Omit<
onAllRowSelectedModeChange?: (allRowSelectedMode: boolean) => void;
footer?: React.ReactNode;
footerHeight?: number;
hasStatusColumn?: boolean;
onRowStatus?: (item: any) => any;
statusComponent?: (status: any) => React.ReactNode;
};

export type InfiniteTableRef = {
Expand All @@ -73,6 +76,9 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
allRowSelectedMode: allRowSelectedModeProps,
footer,
footerHeight = 50,
onRowStatus,
statusComponent,
hasStatusColumn = false,
} = props;

const gridRef = useRef<AgGridReact>(null);
Expand All @@ -88,6 +94,7 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
gridRef,
containerRef,
columnsPersistedStateRef,
hasStatusColumn,
});

// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -144,41 +151,61 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
const defaultColDef = useMemo<ColDef>(() => ({}), []);

const colDefs = useMemo((): ColDef[] => {
const checkboxColumn = {
checkboxSelection: true,
suppressMovable: true,
sortable: false,
lockPosition: true,
pinned: "left",
maxWidth: 50,
resizable: false,
headerComponent: () => (
<HeaderCheckbox
totalRows={totalRows}
selectedRowKeysLength={internalSelectedRowKeys.length}
allRowSelected={
totalRows === internalSelectedRowKeys.length && totalRows > 0
}
allRowSelectedMode={allRowSelectedMode}
onHeaderCheckboxChange={onHeaderCheckboxChange}
/>
),
} as ColDef;

const restOfColumns = columns.map((column) => ({
field: column.key,
sortable: false,
headerName: column.title,
cellRenderer: column.render
? (cell: any) => column.render(cell.value)
: undefined,
}));

const statusColumn = {
field: "$status",
suppressMovable: true,
sortable: false,
lockPosition: true,
maxWidth: 30,
type: "leftAligned",
pinned: "left",
resizable: false,
headerComponent: () => null,
cellRenderer: (cell: any) => statusComponent?.(cell.value),
} as ColDef;

return [
{
checkboxSelection: true,
suppressMovable: true,
sortable: false,
lockPosition: true,
pinned: "left",
maxWidth: 50,
resizable: false,
headerComponent: () => (
<HeaderCheckbox
totalRows={totalRows}
selectedRowKeysLength={internalSelectedRowKeys.length}
allRowSelected={
totalRows === internalSelectedRowKeys.length && totalRows > 0
}
allRowSelectedMode={allRowSelectedMode}
onHeaderCheckboxChange={onHeaderCheckboxChange}
/>
),
},
...columns.map((column) => ({
field: column.key,
sortable: false,
headerName: column.title,
cellRenderer: column.render
? (cell: any) => column.render(cell.value)
: undefined,
})),
checkboxColumn,
...(hasStatusColumn ? [statusColumn] : []),
...restOfColumns,
];
}, [
allRowSelectedMode,
columns,
hasStatusColumn,
internalSelectedRowKeys.length,
onHeaderCheckboxChange,
statusComponent,
totalRows,
]);

Expand All @@ -191,7 +218,22 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
if (data.length < endRow - startRow) {
lastRow = startRow + data.length;
}
params.successCallback(data, lastRow);

// We must call onRowStatus for each item of the data array and merge the result
// with the data array
const finalData = hasStatusColumn
? await Promise.all(
data.map(async (item) => {
const status = await onRowStatus?.(item);
return {
...item,
$status: status,
};
}),
)
: data;

params.successCallback(finalData, lastRow);
if (allRowSelectedModeRef.current) {
gridRef?.current?.api.forEachNode((node) => {
node.setSelected(true);
Expand Down Expand Up @@ -219,8 +261,10 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
},
[
autoSizeColumnsIfNecessary,
hasStatusColumn,
onGetSelectedRowKeys,
onRequestData,
onRowStatus,
selectedRowKeysPendingToRender,
setSelectedRowKeysPendingToRender,
],
Expand Down
15 changes: 12 additions & 3 deletions src/components/InfiniteTable/useAutoFitColumns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ export const useAutoFitColumns = ({
gridRef,
containerRef,
columnsPersistedStateRef,
hasStatusColumn,
}: {
gridRef: RefObject<AgGridReact>;
containerRef: RefObject<HTMLDivElement>;
columnsPersistedStateRef: RefObject<any>;
hasStatusColumn: boolean;
}) => {
const firstTimeResized = useRef(false);

const columnsToIgnore = ["0"]; // 0 is for header checkbox column
if (hasStatusColumn) {
columnsToIgnore.push("$status");
}

const remainingBlankSpace = useCallback(
(allColumns: Array<Column<any>>) => {
const totalColumnWidth = allColumns?.reduce(
Expand All @@ -36,12 +43,14 @@ export const useAutoFitColumns = ({
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 spacePerColumn =
blankSpace / (allColumns.length - columnsToIgnore.length);
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,
width: columnsToIgnore.includes(col.colId)
? col.width
: col.width + spacePerColumn,
}));
gridRef?.current?.api.applyColumnState({ state: newState });
}
Expand Down
4 changes: 4 additions & 0 deletions src/stories/InfiniteTable.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ export const HeavyTable = (): React.ReactElement => {
return columnsState ? JSON.parse(columnsState) : undefined;
}}
footer={<p>This is a footer</p>}
onRowStatus={(record: any) => {
return record.id;
}}
statusComponent={(status: any) => <strong>{status}</strong>}
/>
</>
);
Expand Down

0 comments on commit a128b97

Please sign in to comment.