useSpanSamples.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // TODO: This is a _more general_ version of `useSpanSamples` from `/starfish/queries`. That hook should rely on this one _or_ they should be consolidated.
  2. import {defined} from 'sentry/utils';
  3. import {useApiQuery} from 'sentry/utils/queryClient';
  4. import type {MutableSearch} from 'sentry/utils/tokenizeSearch';
  5. import useOrganization from 'sentry/utils/useOrganization';
  6. import usePageFilters from 'sentry/utils/usePageFilters';
  7. import type {
  8. IndexedProperty,
  9. IndexedResponse,
  10. SpanIndexedField,
  11. } from 'sentry/views/starfish/types';
  12. import {getDateConditions} from 'sentry/views/starfish/utils/getDateConditions';
  13. interface UseSpanSamplesOptions<Fields> {
  14. enabled?: boolean;
  15. fields?: Fields;
  16. max?: number;
  17. min?: number;
  18. referrer?: string;
  19. search?: MutableSearch;
  20. }
  21. export const useSpanSamples = <Fields extends IndexedProperty[]>(
  22. options: UseSpanSamplesOptions<Fields> = {}
  23. ) => {
  24. const {
  25. fields = [],
  26. search = undefined,
  27. referrer,
  28. enabled,
  29. min = undefined,
  30. max = undefined,
  31. } = options;
  32. const {selection} = usePageFilters();
  33. const organization = useOrganization();
  34. if (defined(min) && min < 0) {
  35. throw new Error('Minimum must be greater than 0');
  36. }
  37. if (defined(min) && defined(max) && min >= max) {
  38. throw new Error('Maximum must be higher than minimum');
  39. }
  40. const dateConditions = getDateConditions(selection);
  41. const result = useApiQuery<{
  42. data:
  43. | Pick<
  44. IndexedResponse,
  45. | Fields[number]
  46. // These fields are returned by default
  47. | SpanIndexedField.PROJECT
  48. | SpanIndexedField.TRANSACTION_ID
  49. | SpanIndexedField.TIMESTAMP
  50. | SpanIndexedField.ID
  51. | SpanIndexedField.PROFILE_ID
  52. >[]
  53. // This type is a little awkward but it explicitly states that the response could be empty. This doesn't enable unchecked access errors, but it at least indicates that it's possible that there's no data
  54. // eslint-disable-next-line @typescript-eslint/ban-types
  55. | [];
  56. meta: 'hello';
  57. }>(
  58. [
  59. `/api/0/organizations/${organization.slug}/spans-samples/`,
  60. {
  61. query: {
  62. query: search?.formatString(),
  63. project: selection.projects,
  64. ...dateConditions,
  65. ...{utc: selection.datetime.utc},
  66. lowerBound: min,
  67. firstBound: max && max * (1 / 3),
  68. secondBound: max && max * (2 / 3),
  69. upperBound: max,
  70. additionalFields: fields,
  71. referrer,
  72. },
  73. },
  74. ],
  75. {
  76. enabled,
  77. staleTime: Infinity,
  78. retry: false,
  79. }
  80. );
  81. return {
  82. ...result,
  83. data: result.data?.data ?? [],
  84. };
  85. };