useSpanMetrics.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import {Location} from 'history';
  2. import EventView from 'sentry/utils/discover/eventView';
  3. import {Sort} from 'sentry/utils/discover/fields';
  4. import {DiscoverDatasets} from 'sentry/utils/discover/types';
  5. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  6. import {useLocation} from 'sentry/utils/useLocation';
  7. import {
  8. MetricsProperty,
  9. MetricsResponse,
  10. SpanMetricsQueryFilters,
  11. } from 'sentry/views/starfish/types';
  12. import {useWrappedDiscoverQuery} from 'sentry/views/starfish/utils/useSpansQuery';
  13. interface UseSpanMetricsOptions<Fields> {
  14. cursor?: string;
  15. fields?: Fields;
  16. filters?: SpanMetricsQueryFilters;
  17. limit?: number;
  18. referrer?: string;
  19. sorts?: Sort[];
  20. }
  21. export const useSpanMetrics = <Fields extends MetricsProperty[]>(
  22. options: UseSpanMetricsOptions<Fields> = {}
  23. ) => {
  24. const {fields = [], filters = {}, sorts = [], limit, cursor, referrer} = options;
  25. const location = useLocation();
  26. const eventView = getEventView(filters, fields, sorts, location);
  27. const enabled = Object.values(filters).every(value => Boolean(value));
  28. const result = useWrappedDiscoverQuery({
  29. eventView,
  30. initialData: [],
  31. limit,
  32. enabled,
  33. referrer,
  34. cursor,
  35. });
  36. // 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
  37. // eslint-disable-next-line @typescript-eslint/ban-types
  38. const data = (result?.data ?? []) as Pick<MetricsResponse, Fields[number]>[] | [];
  39. return {
  40. ...result,
  41. data,
  42. isEnabled: enabled,
  43. };
  44. };
  45. function getEventView(
  46. filters: SpanMetricsQueryFilters = {},
  47. fields: string[] = [],
  48. sorts: Sort[] = [],
  49. location: Location
  50. ) {
  51. const query = MutableSearch.fromQueryObject(filters);
  52. // TODO: This condition should be enforced everywhere
  53. // query.addFilterValue('has', 'span.description');
  54. const eventView = EventView.fromNewQueryWithLocation(
  55. {
  56. name: '',
  57. query: query.formatString(),
  58. fields,
  59. dataset: DiscoverDatasets.SPANS_METRICS,
  60. version: 2,
  61. },
  62. location
  63. );
  64. if (sorts.length > 0) {
  65. eventView.sorts = sorts;
  66. }
  67. return eventView;
  68. }