replayTimeline.tsx 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 userCrumbs = crumbs.filter(crumb => USER_ACTIONS.includes(crumb.type));
  32. const networkSpans = replay.getNetworkSpans();
  33. return (
  34. <Panel>
  35. <ScrubberMouseTracking>
  36. <Resizeable>
  37. {({width}) => (
  38. <Stacked>
  39. <MinorGridlines durationMs={durationMs} width={width} />
  40. <MajorGridlines durationMs={durationMs} width={width} />
  41. <TimelineScrubber />
  42. <UnderTimestamp paddingTop="36px">
  43. <ReplayTimelineSpans
  44. durationMs={durationMs}
  45. spans={networkSpans}
  46. startTimestampMs={startTimestampMs}
  47. />
  48. </UnderTimestamp>
  49. <UnderTimestamp paddingTop="0">
  50. <ReplayTimelineEvents
  51. crumbs={userCrumbs}
  52. durationMs={durationMs}
  53. startTimestampMs={startTimestampMs}
  54. width={width}
  55. />
  56. </UnderTimestamp>
  57. </Stacked>
  58. )}
  59. </Resizeable>
  60. </ScrubberMouseTracking>
  61. </Panel>
  62. );
  63. }
  64. const UnderTimestamp = styled('div')<{paddingTop: string}>`
  65. /* Weird size to put equal space above/below a <small> node that MajorGridlines emits */
  66. padding-top: ${p => p.paddingTop};
  67. `;
  68. export default ReplayTimeline;