useDiscover.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import type {PageFilters} from 'sentry/types/core';
  2. import EventView from 'sentry/utils/discover/eventView';
  3. import type {Sort} from 'sentry/utils/discover/fields';
  4. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  5. import type {MutableSearch} from 'sentry/utils/tokenizeSearch';
  6. import usePageFilters from 'sentry/utils/usePageFilters';
  7. import {useWrappedDiscoverQuery} from 'sentry/views/insights/common/queries/useSpansQuery';
  8. import type {
  9. EAPSpanProperty,
  10. EAPSpanResponse,
  11. MetricsProperty,
  12. MetricsResponse,
  13. OurlogsFields,
  14. SpanIndexedProperty,
  15. SpanIndexedResponse,
  16. SpanMetricsProperty,
  17. SpanMetricsResponse,
  18. } from 'sentry/views/insights/types';
  19. interface UseMetricsOptions<Fields> {
  20. cursor?: string;
  21. enabled?: boolean;
  22. fields?: Fields;
  23. limit?: number;
  24. noPagination?: boolean;
  25. pageFilters?: PageFilters;
  26. search?: MutableSearch | string; // TODO - ideally this probably would be only `Mutable Search`, but it doesn't handle some situations well
  27. sorts?: Sort[];
  28. }
  29. export const useSpansIndexed = <Fields extends SpanIndexedProperty[]>(
  30. options: UseMetricsOptions<Fields> = {},
  31. referrer: string
  32. ) => {
  33. return useDiscover<Fields, SpanIndexedResponse>(
  34. options,
  35. DiscoverDatasets.SPANS_INDEXED,
  36. referrer
  37. );
  38. };
  39. export const useOurlogs = <Fields extends Array<keyof OurlogsFields>>(
  40. options: UseMetricsOptions<Fields> = {},
  41. referrer: string
  42. ) => {
  43. const {data, ...rest} = useDiscover<Fields, OurlogsFields>(
  44. options,
  45. DiscoverDatasets.OURLOGS,
  46. referrer
  47. );
  48. const castData = data as OurlogsFields[];
  49. return {...rest, data: castData};
  50. };
  51. export const useEAPSpans = <Fields extends EAPSpanProperty[]>(
  52. options: UseMetricsOptions<Fields> = {},
  53. referrer: string
  54. ) => {
  55. return useDiscover<Fields, EAPSpanResponse>(
  56. options,
  57. DiscoverDatasets.SPANS_EAP,
  58. referrer
  59. );
  60. };
  61. export const useSpanMetrics = <Fields extends SpanMetricsProperty[]>(
  62. options: UseMetricsOptions<Fields> = {},
  63. referrer: string
  64. ) => {
  65. return useDiscover<Fields, SpanMetricsResponse>(
  66. options,
  67. DiscoverDatasets.SPANS_METRICS,
  68. referrer
  69. );
  70. };
  71. export const useMetrics = <Fields extends MetricsProperty[]>(
  72. options: UseMetricsOptions<Fields> = {},
  73. referrer: string
  74. ) => {
  75. return useDiscover<Fields, MetricsResponse>(
  76. options,
  77. DiscoverDatasets.METRICS,
  78. referrer
  79. );
  80. };
  81. const useDiscover = <T extends Array<Extract<keyof ResponseType, string>>, ResponseType>(
  82. options: UseMetricsOptions<T> = {},
  83. dataset: DiscoverDatasets,
  84. referrer: string
  85. ) => {
  86. const {
  87. fields = [],
  88. search = undefined,
  89. sorts = [],
  90. limit,
  91. cursor,
  92. pageFilters: pageFiltersFromOptions,
  93. noPagination,
  94. } = options;
  95. const pageFilters = usePageFilters();
  96. const eventView = getEventView(
  97. search,
  98. fields,
  99. sorts,
  100. pageFiltersFromOptions ?? pageFilters.selection,
  101. dataset
  102. );
  103. const result = useWrappedDiscoverQuery({
  104. eventView,
  105. initialData: [],
  106. limit,
  107. enabled: options.enabled,
  108. referrer,
  109. cursor,
  110. noPagination,
  111. });
  112. // 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
  113. const data = (result?.data ?? []) as Array<Pick<ResponseType, T[number]>>;
  114. return {
  115. ...result,
  116. data,
  117. isEnabled: options.enabled,
  118. };
  119. };
  120. function getEventView(
  121. search: MutableSearch | string | undefined,
  122. fields: string[] = [],
  123. sorts: Sort[] = [],
  124. pageFilters: PageFilters,
  125. dataset: DiscoverDatasets
  126. ) {
  127. const query = typeof search === 'string' ? search : search?.formatString() ?? '';
  128. const eventView = EventView.fromNewQueryWithPageFilters(
  129. {
  130. name: '',
  131. query,
  132. fields,
  133. dataset,
  134. version: 2,
  135. },
  136. pageFilters
  137. );
  138. if (sorts.length > 0) {
  139. eventView.sorts = sorts;
  140. }
  141. return eventView;
  142. }