traceFullQuery.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import {Fragment} from 'react';
  2. import GenericDiscoverQuery, {
  3. DiscoverQueryProps,
  4. } from 'sentry/utils/discover/genericDiscoverQuery';
  5. import {
  6. BaseTraceChildrenProps,
  7. FullQuickTrace,
  8. TraceFull,
  9. TraceFullDetailed,
  10. TraceRequestProps,
  11. } from 'sentry/utils/performance/quickTrace/types';
  12. import {
  13. getTraceRequestPayload,
  14. makeEventView,
  15. } from 'sentry/utils/performance/quickTrace/utils';
  16. import withApi from 'sentry/utils/withApi';
  17. type AdditionalQueryProps = {
  18. detailed?: boolean;
  19. eventId?: string;
  20. };
  21. type TraceFullQueryChildrenProps<T> = BaseTraceChildrenProps &
  22. Omit<FullQuickTrace, 'trace'> & {
  23. /**
  24. * The `event-trace` endpoint returns a full trace with the parent-child
  25. * relationships. It can be flattened into a `QuickTraceEvent` if necessary.
  26. */
  27. traces: T | null;
  28. };
  29. type QueryProps<T> = Omit<TraceRequestProps, 'eventView'> &
  30. AdditionalQueryProps & {
  31. children: (props: TraceFullQueryChildrenProps<T>) => React.ReactNode;
  32. };
  33. function getTraceFullRequestPayload({
  34. detailed,
  35. eventId,
  36. ...props
  37. }: DiscoverQueryProps & AdditionalQueryProps) {
  38. const additionalApiPayload: any = getTraceRequestPayload(props);
  39. additionalApiPayload.detailed = detailed ? '1' : '0';
  40. if (eventId) {
  41. additionalApiPayload.event_id = eventId;
  42. }
  43. return additionalApiPayload;
  44. }
  45. function EmptyTrace<T>({children}: Pick<QueryProps<T>, 'children'>) {
  46. return (
  47. <Fragment>
  48. {children({
  49. isLoading: false,
  50. error: null,
  51. traces: null,
  52. type: 'full',
  53. })}
  54. </Fragment>
  55. );
  56. }
  57. function GenericTraceFullQuery<T>({
  58. traceId,
  59. start,
  60. end,
  61. statsPeriod,
  62. children,
  63. ...props
  64. }: QueryProps<T>) {
  65. if (!traceId) {
  66. return <EmptyTrace<T>>{children}</EmptyTrace>;
  67. }
  68. const eventView = makeEventView({start, end, statsPeriod});
  69. return (
  70. <GenericDiscoverQuery<T, AdditionalQueryProps>
  71. route={`events-trace/${traceId}`}
  72. getRequestPayload={getTraceFullRequestPayload}
  73. eventView={eventView}
  74. {...props}
  75. >
  76. {({tableData, ...rest}) =>
  77. children({
  78. // This is using '||` instead of '??` here because
  79. // the client returns a empty string when the response
  80. // is 204. And we want the empty string, undefined and
  81. // null to be converted to null.
  82. traces: tableData || null,
  83. type: 'full',
  84. ...rest,
  85. })
  86. }
  87. </GenericDiscoverQuery>
  88. );
  89. }
  90. export const TraceFullQuery = withApi(
  91. (props: Omit<QueryProps<TraceFull[]>, 'detailed'>) => (
  92. <GenericTraceFullQuery<TraceFull[]> {...props} detailed={false} />
  93. )
  94. );
  95. export const TraceFullDetailedQuery = withApi(
  96. (props: Omit<QueryProps<TraceFullDetailed[]>, 'detailed'>) => (
  97. <GenericTraceFullQuery<TraceFullDetailed[]> {...props} detailed />
  98. )
  99. );