useSort.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import {useCallback, useMemo} from 'react';
  2. import type {Location} from 'history';
  3. import {decodeScalar} from 'sentry/utils/queryString';
  4. import {useLocation} from 'sentry/utils/useLocation';
  5. import {useNavigate} from 'sentry/utils/useNavigate';
  6. import type {Field} from './useSampleFields';
  7. interface Options {
  8. fields: Field[];
  9. }
  10. export type Direction = 'asc' | 'desc';
  11. export type Sort = {
  12. direction: Direction;
  13. field: Field;
  14. };
  15. export function useSort(props): [Sort, (newSort: Sort) => void] {
  16. const location = useLocation();
  17. const navigate = useNavigate();
  18. const options = {location, navigate, ...props};
  19. return useSortImpl(options);
  20. }
  21. interface ImplOptions extends Options {
  22. location: Location;
  23. navigate: ReturnType<typeof useNavigate>;
  24. }
  25. function useSortImpl({
  26. fields,
  27. location,
  28. navigate,
  29. }: ImplOptions): [Sort, (newSort: Sort) => void] {
  30. const rawSort = decodeScalar(location.query.sort);
  31. const direction: Direction = !rawSort || rawSort.startsWith('-') ? 'desc' : 'asc';
  32. const field: Field = useMemo(() => {
  33. let f = rawSort;
  34. if (direction === 'desc') {
  35. f = f?.substring(1);
  36. }
  37. f = f || 'timestamp';
  38. if (fields.length && !fields.includes(f)) {
  39. f = fields[0];
  40. }
  41. return f;
  42. }, [rawSort, direction, fields]);
  43. const sort: Sort = useMemo(() => {
  44. return {
  45. direction,
  46. field,
  47. };
  48. }, [direction, field]);
  49. const setSort = useCallback(
  50. (newSort: Sort) => {
  51. const formatted =
  52. newSort.direction === 'desc' ? `-${newSort.field}` : newSort.field;
  53. navigate({
  54. ...location,
  55. query: {
  56. ...location.query,
  57. sort: formatted,
  58. },
  59. });
  60. },
  61. [location, navigate]
  62. );
  63. return [sort, setSort];
  64. }