content.tsx 3.1 KB

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