import { useEffect, useRef, useState } from 'react'; import { autorun } from 'mobx'; import { IdType, InMemoryDataSource, Preprocessors } from '@servicetitan/data-query'; import { useInitializedRef } from '@servicetitan/react-hooks'; import { TableState, TableStateConstructorParams } from '../table-state'; // export enum ResetPaginationMode { Never, OnUpdateDataRoot, Always, } export interface DatasourceOptions { idSelector: (row: T) => TID; datasourcePreprocessors?: Preprocessors; } export const useObservingTableState = < T, TID extends IdType = any, P = never, PID extends IdType = never, >( data: T[], tableArgs: TableStateConstructorParams, datasourceOptions: DatasourceOptions, resetPagination: ResetPaginationMode = ResetPaginationMode.OnUpdateDataRoot ): TableState => { const tableStateRef = useInitializedRef(() => new TableState(tableArgs)); const datasourceDataRef = useRef(); const tableStateDataRef = useRef(); const [dataSource, setDataSource] = useState>(); useEffect(() => { const disposer = autorun(() => { setDataSource( new InMemoryDataSource( data, datasourceOptions.idSelector, datasourceOptions.datasourcePreprocessors ) ); datasourceDataRef.current = data; }); return () => disposer(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [data]); useEffect(() => { if (dataSource) { if ( tableStateRef.current.skip >= (datasourceDataRef.current?.length ?? 0) || resetPagination === ResetPaginationMode.Always || (resetPagination === ResetPaginationMode.OnUpdateDataRoot && tableStateDataRef.current !== datasourceDataRef.current) ) { tableStateRef.current.setDataSource(dataSource); } else { const state = tableStateRef.current.exportState(); tableStateRef.current.setDataSource(dataSource, { initialState: state }); } tableStateDataRef.current = datasourceDataRef.current; } }, [dataSource, resetPagination, tableStateRef]); return tableStateRef.current; };