setupDocs.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import {Fragment, useCallback, useEffect, useMemo, useState} from 'react';
  2. import {browserHistory} from 'react-router';
  3. import styled from '@emotion/styled';
  4. import {motion} from 'framer-motion';
  5. import {SdkDocumentation} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
  6. import {ProductSolution} from 'sentry/components/onboarding/productSelection';
  7. import platforms from 'sentry/data/platforms';
  8. import {t} from 'sentry/locale';
  9. import {space} from 'sentry/styles/space';
  10. import {trackAnalytics} from 'sentry/utils/analytics';
  11. import {platformToIntegrationMap} from 'sentry/utils/integrationUtil';
  12. import {decodeList} from 'sentry/utils/queryString';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import SetupIntroduction from 'sentry/views/onboarding/components/setupIntroduction';
  15. import {SetupDocsLoader} from 'sentry/views/onboarding/setupDocsLoader';
  16. import FirstEventFooter from './components/firstEventFooter';
  17. import IntegrationSetup from './integrationSetup';
  18. import {StepProps} from './types';
  19. function SetupDocs({location, recentCreatedProject: project}: StepProps) {
  20. const organization = useOrganization();
  21. const [integrationUseManualSetup, setIntegrationUseManualSetup] = useState(false);
  22. const products = useMemo<ProductSolution[]>(
  23. () => decodeList(location.query.product ?? []) as ProductSolution[],
  24. [location.query.product]
  25. );
  26. const currentPlatformKey = project?.platform ?? 'other';
  27. const currentPlatform = platforms.find(p => p.id === currentPlatformKey);
  28. const [showLoaderOnboarding, setShowLoaderOnboarding] = useState(
  29. currentPlatformKey === 'javascript'
  30. );
  31. useEffect(() => {
  32. setShowLoaderOnboarding(currentPlatformKey === 'javascript');
  33. }, [currentPlatformKey]);
  34. const hideLoaderOnboarding = useCallback(() => {
  35. setShowLoaderOnboarding(false);
  36. if (!project?.id) {
  37. return;
  38. }
  39. trackAnalytics('onboarding.js_loader_npm_docs_shown', {
  40. organization,
  41. platform: currentPlatformKey,
  42. project_id: project?.id,
  43. });
  44. }, [organization, currentPlatformKey, project?.id]);
  45. if (!project || !currentPlatform) {
  46. return null;
  47. }
  48. const platformName = currentPlatform?.name ?? '';
  49. const integrationSlug = project?.platform && platformToIntegrationMap[project.platform];
  50. const showIntegrationOnboarding = integrationSlug && !integrationUseManualSetup;
  51. return (
  52. <Fragment>
  53. <Wrapper>
  54. <MainContent>
  55. {showIntegrationOnboarding ? (
  56. <IntegrationSetup
  57. integrationSlug={integrationSlug}
  58. project={project}
  59. onClickManualSetup={() => {
  60. setIntegrationUseManualSetup(true);
  61. }}
  62. />
  63. ) : (
  64. <Fragment>
  65. <SetupIntroduction
  66. stepHeaderText={t('Configure %s SDK', platformName)}
  67. platform={currentPlatformKey}
  68. />
  69. {showLoaderOnboarding ? (
  70. <SetupDocsLoader
  71. organization={organization}
  72. project={project}
  73. location={location}
  74. platform={currentPlatform.id}
  75. close={hideLoaderOnboarding}
  76. newOrg
  77. />
  78. ) : (
  79. <SdkDocumentation
  80. platform={currentPlatform}
  81. organization={organization}
  82. projectSlug={project.slug}
  83. projectId={project.id}
  84. activeProductSelection={products}
  85. newOrg
  86. />
  87. )}
  88. </Fragment>
  89. )}
  90. </MainContent>
  91. </Wrapper>
  92. <FirstEventFooter
  93. project={project}
  94. organization={organization}
  95. isLast
  96. onClickSetupLater={() => {
  97. const orgIssuesURL = `/organizations/${organization.slug}/issues/?project=${project.id}&referrer=onboarding-setup-docs`;
  98. trackAnalytics('growth.onboarding_clicked_setup_platform_later', {
  99. organization,
  100. platform: currentPlatformKey,
  101. project_id: project.id,
  102. });
  103. browserHistory.push(orgIssuesURL);
  104. }}
  105. />
  106. </Fragment>
  107. );
  108. }
  109. export default SetupDocs;
  110. const AnimatedContentWrapper = styled(motion.div)`
  111. overflow: hidden;
  112. `;
  113. AnimatedContentWrapper.defaultProps = {
  114. initial: {
  115. height: 0,
  116. },
  117. animate: {
  118. height: 'auto',
  119. },
  120. exit: {
  121. height: 0,
  122. },
  123. };
  124. const DocsWrapper = styled(motion.div)``;
  125. DocsWrapper.defaultProps = {
  126. initial: {opacity: 0, y: 40},
  127. animate: {opacity: 1, y: 0},
  128. exit: {opacity: 0},
  129. };
  130. const Wrapper = styled('div')`
  131. display: flex;
  132. flex-direction: row;
  133. margin: ${space(2)};
  134. justify-content: center;
  135. `;
  136. const MainContent = styled('div')`
  137. max-width: 850px;
  138. min-width: 0;
  139. flex-grow: 1;
  140. `;