replayTimeline.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import styled from '@emotion/styled';
  2. import {Panel} from 'sentry/components/panels';
  3. import Placeholder from 'sentry/components/placeholder';
  4. import {
  5. MajorGridlines,
  6. MinorGridlines,
  7. } from 'sentry/components/replays/breadcrumbs/gridlines';
  8. import ReplayTimelineEvents from 'sentry/components/replays/breadcrumbs/replayTimelineEvents';
  9. import ReplayTimelineSpans from 'sentry/components/replays/breadcrumbs/replayTimelineSpans';
  10. import Stacked from 'sentry/components/replays/breadcrumbs/stacked';
  11. import {TimelineScrubber} from 'sentry/components/replays/player/scrubber';
  12. import ScrubberMouseTracking from 'sentry/components/replays/player/scrubberMouseTracking';
  13. import {useReplayContext} from 'sentry/components/replays/replayContext';
  14. import {Resizeable} from 'sentry/components/replays/resizeable';
  15. import {BreadcrumbType} from 'sentry/types/breadcrumbs';
  16. type Props = {};
  17. const USER_ACTIONS = [
  18. BreadcrumbType.ERROR,
  19. BreadcrumbType.NAVIGATION,
  20. BreadcrumbType.UI,
  21. BreadcrumbType.USER,
  22. ];
  23. function ReplayTimeline({}: Props) {
  24. const {replay} = useReplayContext();
  25. if (!replay) {
  26. return <Placeholder height="48px" bottomGutter={2} />;
  27. }
  28. const durationMs = replay.getDurationMs();
  29. const startTimestampMs = replay.getReplay().startedAt.getTime();
  30. const crumbs = replay.getRawCrumbs() || [];
  31. const spans = replay.getRawSpans() || [];
  32. const userCrumbs = crumbs.filter(crumb => USER_ACTIONS.includes(crumb.type));
  33. const networkSpans = spans.filter(replay.isNetworkSpan);
  34. return (
  35. <Panel>
  36. <ScrubberMouseTracking>
  37. <Resizeable>
  38. {({width}) => (
  39. <Stacked>
  40. <MinorGridlines durationMs={durationMs} width={width} />
  41. <MajorGridlines durationMs={durationMs} width={width} />
  42. <TimelineScrubber />
  43. <UnderTimestamp paddingTop="36px">
  44. <ReplayTimelineSpans
  45. durationMs={durationMs}
  46. spans={networkSpans}
  47. startTimestampMs={startTimestampMs}
  48. />
  49. </UnderTimestamp>
  50. <UnderTimestamp paddingTop="0">
  51. <ReplayTimelineEvents
  52. crumbs={userCrumbs}
  53. durationMs={durationMs}
  54. startTimestampMs={startTimestampMs}
  55. width={width}
  56. />
  57. </UnderTimestamp>
  58. </Stacked>
  59. )}
  60. </Resizeable>
  61. </ScrubberMouseTracking>
  62. </Panel>
  63. );
  64. }
  65. const UnderTimestamp = styled('div')<{paddingTop: string}>`
  66. /* Weird size to put equal space above/below a <small> node that MajorGridlines emits */
  67. padding-top: ${p => p.paddingTop};
  68. `;
  69. export default ReplayTimeline;