useSorts.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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(() => getSorts(fields, location), [fields, location]);
  27. const setSort = useCallback(
  28. (newSorts: Sort[]) => {
  29. const formatted = newSorts.map(newSort => {
  30. return newSort.kind === 'desc' ? `-${newSort.field}` : newSort.field;
  31. });
  32. navigate({
  33. ...location,
  34. query: {
  35. ...location.query,
  36. sort: formatted,
  37. },
  38. });
  39. },
  40. [location, navigate]
  41. );
  42. return [sorts, setSort];
  43. }
  44. export function getSorts(fields: Field[], location: Location) {
  45. const rawSorts = decodeSorts(location.query.sort);
  46. // Try to assign a default sort if possible
  47. if (!rawSorts.length || !rawSorts.some(rawSort => fields.includes(rawSort.field))) {
  48. if (fields.includes('timestamp')) {
  49. return [
  50. {
  51. field: 'timestamp',
  52. kind: 'desc' as const,
  53. },
  54. ];
  55. }
  56. if (fields.length) {
  57. return [
  58. {
  59. field: fields[0],
  60. kind: 'desc' as const,
  61. },
  62. ];
  63. }
  64. return [];
  65. }
  66. return rawSorts;
  67. }