configureReplayCard.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import type {ReactNode} from 'react';
  2. import {ClassNames} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {Button, LinkButton} from 'sentry/components/button';
  5. import {Hovercard} from 'sentry/components/hovercard';
  6. import {IconOpen, IconQuestion} from 'sentry/icons';
  7. import {t, tct} from 'sentry/locale';
  8. import {space} from 'sentry/styles/space';
  9. import {trackAnalytics} from 'sentry/utils/analytics';
  10. import useOrganization from 'sentry/utils/useOrganization';
  11. function Resource({
  12. title,
  13. subtitle,
  14. link,
  15. }: {
  16. link: string;
  17. subtitle: ReactNode;
  18. title: string;
  19. }) {
  20. const organization = useOrganization();
  21. return (
  22. <StyledLinkButton
  23. icon={<IconOpen />}
  24. borderless
  25. external
  26. href={link}
  27. onClick={() => {
  28. trackAnalytics('replay.details-resource-docs-clicked', {
  29. organization,
  30. title,
  31. });
  32. }}
  33. >
  34. <ButtonContent>
  35. <ButtonTitle>{title}</ButtonTitle>
  36. <ButtonSubtitle>{subtitle}</ButtonSubtitle>
  37. </ButtonContent>
  38. </StyledLinkButton>
  39. );
  40. }
  41. function ResourceButtons() {
  42. return (
  43. <ButtonContainer>
  44. <Resource
  45. title={t('General')}
  46. subtitle={t('Configure sampling rates and recording thresholds')}
  47. link="https://docs.sentry.io/platforms/javascript/session-replay/configuration/#general-integration-configuration"
  48. />
  49. <Resource
  50. title={t('Element Masking/Blocking')}
  51. subtitle={t('Unmask text (****) and unblock media (img, svg, video, etc.)')}
  52. link="https://docs.sentry.io/platforms/javascript/session-replay/privacy/"
  53. />
  54. <Resource
  55. title={t('Network Details')}
  56. subtitle={t('Capture request and response headers or bodies')}
  57. link="https://docs.sentry.io/platforms/javascript/session-replay/configuration/#network-details"
  58. />
  59. <Resource
  60. title={t('Canvas Support')}
  61. subtitle={tct(
  62. 'Opt-in to record HTML [code:canvas] elements, added in SDK version 7.98.0',
  63. {code: <code />}
  64. )}
  65. link="https://docs.sentry.io/platforms/javascript/session-replay/#canvas-recording"
  66. />
  67. </ButtonContainer>
  68. );
  69. }
  70. export default function ConfigureReplayCard() {
  71. return (
  72. <ClassNames>
  73. {({css}) => (
  74. <Hovercard
  75. body={<ResourceButtons />}
  76. bodyClassName={css`
  77. padding: ${space(1)};
  78. `}
  79. position="top-end"
  80. >
  81. <Button
  82. size="sm"
  83. icon={<IconQuestion />}
  84. aria-label={t('replay configure resources')}
  85. >
  86. {t('Configure Replay')}
  87. </Button>
  88. </Hovercard>
  89. )}
  90. </ClassNames>
  91. );
  92. }
  93. const ButtonContainer = styled('div')`
  94. display: flex;
  95. flex-direction: column;
  96. gap: ${space(1)};
  97. align-items: flex-start;
  98. `;
  99. const ButtonContent = styled('div')`
  100. display: flex;
  101. flex-direction: column;
  102. text-align: left;
  103. white-space: pre-line;
  104. gap: ${space(0.25)};
  105. `;
  106. const ButtonTitle = styled('div')`
  107. font-weight: normal;
  108. `;
  109. const ButtonSubtitle = styled('div')`
  110. color: ${p => p.theme.gray300};
  111. font-weight: normal;
  112. font-size: ${p => p.theme.fontSizeSmall};
  113. `;
  114. const StyledLinkButton = styled(LinkButton)`
  115. padding: ${space(1)};
  116. height: auto;
  117. `;