trace.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import styled from '@emotion/styled';
  2. import Loading from 'sentry/components/loadingIndicator';
  3. import Placeholder from 'sentry/components/placeholder';
  4. import {IconSad} from 'sentry/icons';
  5. import {t} from 'sentry/locale';
  6. import {useLocation} from 'sentry/utils/useLocation';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import TraceView from 'sentry/views/performance/traceDetails/traceView';
  9. import EmptyState from 'sentry/views/replays/detail/emptyState';
  10. import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
  11. import {
  12. useFetchTransactions,
  13. useTransactionData,
  14. } from 'sentry/views/replays/detail/trace/replayTransactionContext';
  15. import type {ReplayRecord} from 'sentry/views/replays/types';
  16. type Props = {
  17. replayRecord: undefined | ReplayRecord;
  18. };
  19. function Trace({replayRecord}: Props) {
  20. const location = useLocation();
  21. const organization = useOrganization();
  22. const {
  23. state: {didInit, errors, isFetching, traces},
  24. eventView,
  25. } = useTransactionData();
  26. useFetchTransactions();
  27. if (!replayRecord || !didInit || (isFetching && !traces?.length)) {
  28. // Show the blank screen until we start fetching, thats when you get a spinner
  29. return (
  30. <StyledPlaceholder height="100%">
  31. {isFetching ? <Loading /> : null}
  32. </StyledPlaceholder>
  33. );
  34. }
  35. if (errors.length) {
  36. // Same style as <EmptyStateWarning>
  37. return (
  38. <BorderedSection>
  39. <EmptyState withIcon={false}>
  40. <IconSad legacySize="54px" />
  41. <p>{t('Unable to retrieve traces')}</p>
  42. </EmptyState>
  43. </BorderedSection>
  44. );
  45. }
  46. if (!traces?.length) {
  47. return (
  48. <BorderedSection>
  49. <EmptyState>
  50. <p>{t('No traces found')}</p>
  51. </EmptyState>
  52. </BorderedSection>
  53. );
  54. }
  55. return (
  56. <FluidHeight>
  57. <TraceView
  58. meta={null}
  59. traces={traces ?? null}
  60. location={location}
  61. organization={organization}
  62. traceEventView={eventView!}
  63. traceSlug="Replay"
  64. />
  65. </FluidHeight>
  66. );
  67. }
  68. // This has the gray background, to match other loaders on Replay Details
  69. const StyledPlaceholder = styled(Placeholder)`
  70. border: 1px solid ${p => p.theme.border};
  71. border-radius: ${p => p.theme.borderRadius};
  72. `;
  73. // White background, to match the loaded component
  74. const BorderedSection = styled(FluidHeight)`
  75. border: 1px solid ${p => p.theme.border};
  76. border-radius: ${p => p.theme.borderRadius};
  77. `;
  78. export default Trace;