import { useCallback, useMemo } from 'react'; import { Column, IdType, useGroupBy, UseGroupByColumnOptions, UseGroupByInstanceProps, UseGroupByOptions, UseGroupByState, } from 'react-table'; import { values } from 'lodash-es'; import { GroupSetter, IRelatableStateInstance, TableAddOnReturn } from '../relatable.types'; import { DEFAULT_AGGREGATE_OPTIONS } from '../constants'; import { ValueAggregate, ICellProps } from '../components/renderers'; export interface IWithGroupingOptions extends UseGroupByOptions { defaultAggregate?: string[] | string | ((values: any[]) => any); defaultAggregateCell?: React.FC; onGroupChange?: GroupSetter; // react-table state override https://react-table.js.org/api/useGroupBy groupBy?: IdType[]; } export interface IWithGroupingState extends UseGroupByState {} export interface IWithGroupingInstance extends UseGroupByInstanceProps, IRelatableStateInstance>{ onCustomGroupingChange: GroupSetter; defaultColumn: Partial & UseGroupByColumnOptions>; } export default function withGrouping(options: IWithGroupingOptions = {}): TableAddOnReturn { const { groupBy, onGroupChange, defaultAggregateCell, defaultAggregate = DEFAULT_AGGREGATE_OPTIONS, ...rest } = options; const stateParams = groupBy ? { groupBy } : {}; const onCustomGroupingChange: GroupSetter = useCallback((column, group) => { if (onGroupChange) { onGroupChange(column, group); return; } column.toggleGroupBy(); }, [onGroupChange]); const tableParams = { ...rest, onCustomGroupingChange, defaultColumn: { aggregate: defaultAggregate, Aggregated: defaultAggregateCell || ValueAggregate, }, }; return [ withGrouping.name, null, ({ canGroupBy }) => canGroupBy, ({ defaultColumn }) => useMemo((): Partial => ({ ...tableParams, // @ts-ignore defaultColumn: { ...defaultColumn, ...tableParams.defaultColumn, }, }), [onCustomGroupingChange, defaultAggregateCell, defaultAggregate, ...values(rest)]), () => useMemo(() => stateParams, [groupBy]), useGroupBy, ]; }