All files / blong-browser/src/hooks useFilter.ts

57.35% Statements 39/68
100% Branches 1/1
0% Functions 0/1
57.35% Lines 39/68

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 691x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                           1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/**
 * useFilter — DataTable filter/sort/pagination state.
 */
import {useCallback, useState} from 'react';
 
export interface IFilterState<T = Record<string, unknown>> {
    filter: T;
    sort: {field: string; order: 1 | -1} | null;
    page: number;
    pageSize: number;
}

export interface IUseFilterResult<T = Record<string, unknown>> {
    filterState: IFilterState<T>;
    setFilter: (filter: Partial<T>) => void;
    setSort: (sort: IFilterState['sort']) => void;
    setPage: (page: number) => void;
    setPageSize: (size: number) => void;
    resetFilter: () => void;
    /** Build params object for a fetch call */
    buildParams: () => IFilterState<T>;
}

export function useFilter<T extends Record<string, unknown>>(
    initialFilter?: Partial<T>,
    initialPageSize = 20,
): IUseFilterResult<T> {
    const [filterState, setFilterState] = useState<IFilterState<T>>({
        filter: (initialFilter ?? {}) as T,
        sort: null,
        page: 1,
        pageSize: initialPageSize,
    });

    const setFilter = useCallback((filter: Partial<T>) => {
        setFilterState(prev => ({...prev, filter: {...prev.filter, ...filter}, page: 1}));
    }, []);

    const setSort = useCallback((sort: IFilterState['sort']) => {
        setFilterState(prev => ({...prev, sort, page: 1}));
    }, []);
 
    const setPage = useCallback((page: number) => {
        setFilterState(prev => ({...prev, page}));
    }, []);
 
    const setPageSize = useCallback((pageSize: number) => {
        setFilterState(prev => ({...prev, pageSize, page: 1}));
    }, []);
 
    const resetFilter = useCallback(() => {
        setFilterState(prev => ({
            ...prev,
            filter: (initialFilter ?? {}) as T,
            page: 1,
        }));
    }, [initialFilter]);
 
    return {
        filterState,
        setFilter,
        setSort,
        setPage,
        setPageSize,
        resetFilter,
        buildParams: () => filterState,
    };
}