details.tsx 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. return (
  73. <Page
  74. orgSlug={orgSlug}
  75. crumbs={replay?.getRawCrumbs()}
  76. replayRecord={replay?.getReplay()}
  77. >
  78. <Layout layout={getLayout()} />
  79. </Page>
  80. );
  81. }
  82. export default ReplayDetails;