import { useState, useMemo, useCallback } from 'react'; import get from 'lodash/get'; import orderBy from 'lodash/orderBy'; import type { SortAction } from '../types'; import { SORT } from '../constants'; /** * Get sort direction field from a string param */ const getSortDirection = (directionParam: string | undefined): SortAction['direction'] => { if (typeof directionParam === 'undefined') { return ''; } if (['asc', 'desc'].includes(directionParam)) { return directionParam as SortAction['direction']; } return ''; }; export const getSortFn = (fieldPath: string, getCustomSort: UseRowsSortParams['getCustomSort']) => (item: TRow) => { if (!fieldPath) { return getCustomSort(item); } return get(item, fieldPath) || 0; }; interface UseRowsSortParams { rows: Array; initialField?: string; initialDirection?: string; getCustomSort: (item: any) => Array; setQueryState: (queryParams: { sortBy: SortAction['field']; direction: SortAction['direction']; }) => void; } interface UseRowsSort { items: Array; sort: SortAction; updateSort: (params: SortAction) => void; } export const useRowsSort = ({ rows, initialField = 'runs[0].delta', initialDirection = 'desc', getCustomSort, setQueryState, }: UseRowsSortParams): UseRowsSort => { const [sort, setSort] = useState({ field: initialField, direction: getSortDirection(initialDirection), }); const updateSort = useCallback( (newState: SortAction) => { // 1. Update local state setSort(newState); // 2. Update query state params setQueryState({ sortBy: newState.field, direction: newState.direction }); }, [setQueryState, setSort], ); const orderedRows = useMemo( () => orderBy( rows, getSortFn(sort.field, getCustomSort), // if direction is empty (reset), sort asc sort.direction !== '' ? sort.direction : (SORT.ASC as any), ), [rows, sort], ); return { sort, updateSort, items: orderedRows, }; };