miniAggregateWaterfall.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import styled from '@emotion/styled';
  2. import type {Location} from 'history';
  3. import {LinkButton} from 'sentry/components/button';
  4. import {noFilter} from 'sentry/components/events/interfaces/spans/filter';
  5. import {ActualMinimap} from 'sentry/components/events/interfaces/spans/header';
  6. import {useSpanWaterfallModelFromTransaction} from 'sentry/components/events/interfaces/spans/useSpanWaterfallModelFromTransaction';
  7. import OpsBreakdown from 'sentry/components/events/opsBreakdown';
  8. import LoadingIndicator from 'sentry/components/loadingIndicator';
  9. import {t} from 'sentry/locale';
  10. import {space} from 'sentry/styles/space';
  11. import {useLocation} from 'sentry/utils/useLocation';
  12. import {LandingDisplayField} from 'sentry/views/performance/browser/webVitals/pageOverview';
  13. type Props = {
  14. transaction: string;
  15. aggregateSpansLocation?: Location;
  16. };
  17. export function MiniAggregateWaterfall({transaction, aggregateSpansLocation}: Props) {
  18. const location = useLocation();
  19. // Pageload transactions don't seem to store http.method, so don't include one here
  20. const {waterfallModel, event, isLoading} =
  21. useSpanWaterfallModelFromTransaction(transaction);
  22. if (isLoading) {
  23. return <LoadingIndicator />;
  24. }
  25. const AggregateSpanWaterfallLocation = aggregateSpansLocation ?? {
  26. ...location,
  27. query: {
  28. ...location.query,
  29. tab: LandingDisplayField.SPANS,
  30. },
  31. };
  32. const minimap = (
  33. <ActualMinimap
  34. spans={waterfallModel.getWaterfall({
  35. viewStart: 0,
  36. viewEnd: 1,
  37. })}
  38. generateBounds={waterfallModel.generateBounds({
  39. viewStart: 0,
  40. viewEnd: 1,
  41. })}
  42. dividerPosition={0}
  43. rootSpan={waterfallModel.rootSpan.span}
  44. />
  45. );
  46. const opsBreakdown = (
  47. <OpsBreakdown operationNameFilters={noFilter} event={event} topN={3} hideHeader />
  48. );
  49. return (
  50. <span>
  51. <MinimapContainer>{minimap}</MinimapContainer>
  52. <BreakdownContainer>{opsBreakdown}</BreakdownContainer>
  53. <LinkButton
  54. aria-label="View Full Waterfall"
  55. size="sm"
  56. to={AggregateSpanWaterfallLocation}
  57. >
  58. {t('View Full Waterfall')}
  59. </LinkButton>
  60. </span>
  61. );
  62. }
  63. const MinimapContainer = styled('div')`
  64. position: relative;
  65. height: 120px;
  66. `;
  67. // Not ideal, but OpsBreakdown has margins in nested components. Easiest way to update them for now.
  68. const BreakdownContainer = styled('div')`
  69. > div {
  70. margin: 0;
  71. }
  72. margin: ${space(2)} 0;
  73. `;