useSpanSamples.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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 {getDateConditions} from 'sentry/views/insights/common/utils/getDateConditions';
  8. import type {SpanIndexedField, SpanIndexedResponse} from 'sentry/views/insights/types';
  9. interface UseSpanSamplesOptions<Fields> {
  10. enabled?: boolean;
  11. fields?: Fields;
  12. max?: number;
  13. min?: number;
  14. referrer?: string;
  15. search?: MutableSearch;
  16. }
  17. export const useSpanSamples = <Fields extends SpanIndexedField[]>(
  18. options: UseSpanSamplesOptions<Fields> = {}
  19. ) => {
  20. const {
  21. fields = [],
  22. search = undefined,
  23. referrer,
  24. enabled,
  25. min = undefined,
  26. max = undefined,
  27. } = options;
  28. const {selection} = usePageFilters();
  29. const organization = useOrganization();
  30. if (defined(min) && min < 0) {
  31. throw new Error('Minimum must be greater than 0');
  32. }
  33. if (defined(min) && defined(max) && min >= max) {
  34. throw new Error('Maximum must be higher than minimum');
  35. }
  36. const dateConditions = getDateConditions(selection);
  37. const result = useApiQuery<{
  38. data:
  39. | Pick<
  40. SpanIndexedResponse,
  41. | Fields[number]
  42. // These fields are returned by default
  43. | SpanIndexedField.PROJECT
  44. | SpanIndexedField.TRANSACTION_ID
  45. | SpanIndexedField.TIMESTAMP
  46. | SpanIndexedField.ID
  47. | SpanIndexedField.PROFILE_ID
  48. | SpanIndexedField.SPAN_SELF_TIME
  49. >[]
  50. // 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
  51. // eslint-disable-next-line @typescript-eslint/ban-types
  52. | [];
  53. }>(
  54. [
  55. `/api/0/organizations/${organization.slug}/spans-samples/`,
  56. {
  57. query: {
  58. query: search?.formatString(),
  59. project: selection.projects,
  60. ...dateConditions,
  61. ...{utc: selection.datetime.utc},
  62. lowerBound: min,
  63. firstBound: max && max * (1 / 3),
  64. secondBound: max && max * (2 / 3),
  65. upperBound: max,
  66. additionalFields: fields,
  67. referrer,
  68. },
  69. },
  70. ],
  71. {
  72. enabled,
  73. staleTime: Infinity,
  74. retry: false,
  75. }
  76. );
  77. return {
  78. ...result,
  79. data: result.data?.data ?? [],
  80. };
  81. };