details.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {Fragment} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import DetailedError from 'sentry/components/errors/detailedError';
  4. import NotFound from 'sentry/components/errors/notFound';
  5. import {
  6. Provider as ReplayContextProvider,
  7. useReplayContext,
  8. } from 'sentry/components/replays/replayContext';
  9. import {t} from 'sentry/locale';
  10. import {PageContent} from 'sentry/styles/organization';
  11. import useReplayData from 'sentry/utils/replays/hooks/useReplayData';
  12. import useReplayLayout from 'sentry/utils/replays/hooks/useReplayLayout';
  13. import Layout from 'sentry/views/replays/detail/layout';
  14. import Page from 'sentry/views/replays/detail/page';
  15. type Props = RouteComponentProps<
  16. {orgSlug: string; replaySlug: string},
  17. {},
  18. any,
  19. {t: number}
  20. >;
  21. function ReplayDetails({
  22. location: {
  23. query: {
  24. t: initialTimeOffset, // Time, in seconds, where the video should start
  25. },
  26. },
  27. params: {orgSlug, replaySlug},
  28. }: Props) {
  29. const {fetching, onRetry, replay} = useReplayData({
  30. replaySlug,
  31. orgSlug,
  32. });
  33. if (!fetching && !replay) {
  34. return (
  35. <Page orgSlug={orgSlug}>
  36. <PageContent>
  37. <NotFound />
  38. </PageContent>
  39. </Page>
  40. );
  41. }
  42. if (!fetching && replay && replay.getRRWebEvents().length < 2) {
  43. return (
  44. <Page orgSlug={orgSlug} replayRecord={replay.getReplay()}>
  45. <DetailedError
  46. onRetry={onRetry}
  47. hideSupportLinks
  48. heading={t('Expected two or more replay events')}
  49. message={
  50. <Fragment>
  51. <p>{t('This Replay may not have captured any user actions.')}</p>
  52. <p>
  53. {t(
  54. 'Or there may be an issue loading the actions from the server, click to try loading the Replay again.'
  55. )}
  56. </p>
  57. </Fragment>
  58. }
  59. />
  60. </Page>
  61. );
  62. }
  63. return (
  64. <ReplayContextProvider replay={replay} initialTimeOffset={initialTimeOffset}>
  65. <LoadedDetails orgSlug={orgSlug} />
  66. </ReplayContextProvider>
  67. );
  68. }
  69. function LoadedDetails({orgSlug}: {orgSlug: string}) {
  70. const {getLayout} = useReplayLayout();
  71. const {replay} = useReplayContext();
  72. const durationMs = replay?.getDurationMs();
  73. return (
  74. <Page
  75. orgSlug={orgSlug}
  76. crumbs={replay?.getRawCrumbs()}
  77. durationMs={durationMs}
  78. replayRecord={replay?.getReplay()}
  79. >
  80. <Layout layout={getLayout()} />
  81. </Page>
  82. );
  83. }
  84. export default ReplayDetails;