content.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import {useEffect} from 'react';
  2. import styled from '@emotion/styled';
  3. import {t} from 'sentry/locale';
  4. import {space} from 'sentry/styles/space';
  5. import {trackAnalytics} from 'sentry/utils/analytics';
  6. import {getFrameMethod, getFrameStatus} from 'sentry/utils/replays/resourceFrame';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
  9. import getOutputType, {
  10. Output,
  11. } from 'sentry/views/replays/detail/network/details/getOutputType';
  12. import {
  13. Setup,
  14. UnsupportedOp,
  15. } from 'sentry/views/replays/detail/network/details/onboarding';
  16. import type {SectionProps} from 'sentry/views/replays/detail/network/details/sections';
  17. import {
  18. GeneralSection,
  19. QueryParamsSection,
  20. RequestHeadersSection,
  21. RequestPayloadSection,
  22. ResponseHeadersSection,
  23. ResponsePayloadSection,
  24. } from 'sentry/views/replays/detail/network/details/sections';
  25. type Props = Parameters<typeof getOutputType>[0] & SectionProps;
  26. export default function NetworkDetailsContent(props: Props) {
  27. const {item, isSetup, visibleTab} = props;
  28. const output = getOutputType(props);
  29. const organization = useOrganization();
  30. useEffect(() => {
  31. trackAnalytics('replay.details-network-tab-changed', {
  32. is_sdk_setup: isSetup,
  33. organization,
  34. output,
  35. resource_method: getFrameMethod(item),
  36. resource_status: String(getFrameStatus(item)),
  37. resource_type: item.op,
  38. tab: visibleTab,
  39. });
  40. }, [isSetup, item, organization, output, visibleTab]);
  41. switch (visibleTab) {
  42. case 'request':
  43. return (
  44. <OverflowFluidHeight>
  45. <SectionList>
  46. <QueryParamsSection {...props} />
  47. {output === Output.DATA && <RequestPayloadSection {...props} />}
  48. </SectionList>
  49. {[Output.SETUP, Output.URL_SKIPPED, Output.BODY_SKIPPED].includes(output) && (
  50. <Setup showSnippet={output} {...props} />
  51. )}
  52. {output === Output.UNSUPPORTED && <UnsupportedOp type="bodies" />}
  53. </OverflowFluidHeight>
  54. );
  55. case 'response':
  56. return (
  57. <OverflowFluidHeight>
  58. {output === Output.DATA && (
  59. <SectionList>
  60. <ResponsePayloadSection {...props} />
  61. </SectionList>
  62. )}
  63. {[Output.SETUP, Output.URL_SKIPPED, Output.BODY_SKIPPED].includes(output) && (
  64. <Setup showSnippet={output} {...props} />
  65. )}
  66. {output === Output.UNSUPPORTED && <UnsupportedOp type="bodies" />}
  67. {output === Output.BODY_PARSE_ERROR && (
  68. <ParseError>{t('The SDK was unable to parse the response body.')}</ParseError>
  69. )}
  70. {output === Output.BODY_PARSE_TIMEOUT && (
  71. <ParseError>
  72. {t(
  73. 'The SDK timed out while parsing response body. This is to reduce CPU usage on client browsers.'
  74. )}
  75. </ParseError>
  76. )}
  77. </OverflowFluidHeight>
  78. );
  79. case 'details':
  80. default:
  81. return (
  82. <OverflowFluidHeight>
  83. <SectionList>
  84. <GeneralSection {...props} />
  85. {output === Output.DATA && <RequestHeadersSection {...props} />}
  86. {output === Output.DATA && <ResponseHeadersSection {...props} />}
  87. </SectionList>
  88. {[Output.SETUP, Output.URL_SKIPPED, Output.DATA].includes(output) && (
  89. <Setup showSnippet={output} {...props} />
  90. )}
  91. {output === Output.UNSUPPORTED && <UnsupportedOp type="headers" />}
  92. </OverflowFluidHeight>
  93. );
  94. }
  95. }
  96. const OverflowFluidHeight = styled(FluidHeight)`
  97. overflow: auto;
  98. `;
  99. const SectionList = styled('dl')`
  100. margin: 0;
  101. `;
  102. const ParseError = styled('p')`
  103. padding: ${space(2)};
  104. `;