useSorts.tsx 1.8 KB

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