Просмотр исходного кода

fix(onboarding): platform doc not being loaded (#46369)

Priscila Oliveira 1 год назад
Родитель
Сommit
346a9b0885

+ 12 - 7
static/app/views/onboarding/components/createProjectsFooter.tsx

@@ -21,6 +21,7 @@ import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAna
 import getPlatformName from 'sentry/utils/getPlatformName';
 import testableTransition from 'sentry/utils/testableTransition';
 import useApi from 'sentry/utils/useApi';
+import useProjects from 'sentry/utils/useProjects';
 import useTeams from 'sentry/utils/useTeams';
 
 import {OnboardingState} from '../types';
@@ -50,6 +51,7 @@ export default function CreateProjectsFooter({
   const api = useApi();
   const {teams} = useTeams();
   const [clientState, setClientState] = usePersistedOnboardingState();
+  const {projects} = useProjects();
 
   const createProjects = async () => {
     if (!clientState) {
@@ -62,14 +64,17 @@ export default function CreateProjectsFooter({
         singleSelectPlatform ? t('Creating project') : t('Creating projects')
       );
 
+      const createProjectForPlatforms = platforms
+        .filter(platform => !clientState.platformToProjectIdMap[platform])
+        // filter out platforms that already have a project
+        .filter(platform => !projects.find(p => p.platform === platform));
+
       const responses = await Promise.all(
-        platforms
-          .filter(platform => !clientState.platformToProjectIdMap[platform])
-          .map(platform =>
-            createProject(api, organization.slug, teams[0].slug, platform, platform, {
-              defaultRules: true,
-            })
-          )
+        createProjectForPlatforms.map(platform =>
+          createProject(api, organization.slug, teams[0].slug, platform, platform, {
+            defaultRules: true,
+          })
+        )
       );
       const nextState: OnboardingState = {
         platformToProjectIdMap: clientState.platformToProjectIdMap,

+ 20 - 2
static/app/views/onboarding/components/firstEventFooter.tsx

@@ -1,15 +1,16 @@
-import {Fragment} from 'react';
+import {Fragment, useContext, useEffect} from 'react';
 import styled from '@emotion/styled';
 import {motion, Variants} from 'framer-motion';
 
 import {Button} from 'sentry/components/button';
 import ButtonBar from 'sentry/components/buttonBar';
 import Link from 'sentry/components/links/link';
+import {OnboardingContext} from 'sentry/components/onboarding/onboardingContext';
 import {IconCheckmark} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import pulsingIndicatorStyles from 'sentry/styles/pulsingIndicator';
 import {space} from 'sentry/styles/space';
-import {Group, Organization, Project} from 'sentry/types';
+import {Group, OnboardingStatus, Organization, Project} from 'sentry/types';
 import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import EventWaiter from 'sentry/utils/eventWaiter';
 import testableTransition from 'sentry/utils/testableTransition';
@@ -38,6 +39,23 @@ export default function FirstEventFooter({
 }: FirstEventFooterProps) {
   const source = 'targeted_onboarding_first_event_footer';
   const [clientState, setClientState] = usePersistedOnboardingState();
+  const onboardingContext = useContext(OnboardingContext);
+
+  useEffect(() => {
+    if (!project.slug) {
+      return;
+    }
+
+    if (onboardingContext.data[project.id]?.status === OnboardingStatus.WAITING) {
+      return;
+    }
+
+    onboardingContext.setProjectData({
+      projectId: project.id,
+      projectSlug: project.slug,
+      status: OnboardingStatus.WAITING,
+    });
+  }, [project.id, project.slug, onboardingContext]);
 
   const getSecondaryCta = () => {
     // if hasn't sent first event, allow skiping.

+ 1 - 0
static/app/views/onboarding/onboarding.tsx

@@ -360,6 +360,7 @@ function Onboarding(props: Props) {
                 router={props.router}
                 location={props.location}
                 jumpToSetupProject={jumpToSetupProject}
+                selectedProjectSlug={selectedProjectSlug}
                 {...{
                   genSkipOnboardingLink,
                 }}

+ 17 - 11
static/app/views/onboarding/setupDocs.tsx

@@ -120,11 +120,14 @@ function ProjectDocs(props: {
   );
 }
 
-function SetupDocs({search, route, router, location}: Props) {
+function SetupDocs({search, route, router, location, ...props}: Props) {
   const api = useApi();
   const organization = useOrganization();
   const {projects: rawProjects} = useProjects();
   const [clientState, setClientState] = usePersistedOnboardingState();
+  const [selectedProjectSlug, _setSelectedProjectSlug] = useState(
+    props.selectedProjectSlug
+  );
 
   const {logExperiment, experimentAssignment} = useExperiment(
     'OnboardingNewFooterExperiment',
@@ -176,7 +179,8 @@ function SetupDocs({search, route, router, location}: Props) {
   const firstProjectNoError = projects.findIndex(p => selectedProjectsSet.has(p.slug));
   // Select a project based on search params. If non exist, use the first project without first event.
   const projectIndex = rawProjectIndex >= 0 ? rawProjectIndex : firstProjectNoError;
-  const project = projects[projectIndex];
+  const project =
+    projects[projectIndex] ?? rawProjects.find(p => p.slug === selectedProjectSlug);
 
   // find the next project that doesn't have a first event
   const nextProject = projects.find(
@@ -201,7 +205,7 @@ function SetupDocs({search, route, router, location}: Props) {
       return;
     }
 
-    let platform = String(project.platform);
+    let loadPlatform = String(project.platform);
     if (
       organization.features?.includes('onboarding-docs-with-product-selection') &&
       project.platform === 'javascript-react'
@@ -214,13 +218,13 @@ function SetupDocs({search, route, router, location}: Props) {
         products.includes(PRODUCT.PERFORMANCE_MONITORING) &&
         products.includes(PRODUCT.SESSION_REPLAY)
       ) {
-        platform = ReactDocVariant.ErrorMonitoringPerformanceAndReplay;
+        loadPlatform = ReactDocVariant.ErrorMonitoringPerformanceAndReplay;
       } else if (products.includes(PRODUCT.PERFORMANCE_MONITORING)) {
-        platform = ReactDocVariant.ErrorMonitoringAndPerformance;
+        loadPlatform = ReactDocVariant.ErrorMonitoringAndPerformance;
       } else if (products.includes(PRODUCT.SESSION_REPLAY)) {
-        platform = ReactDocVariant.ErrorMonitoringAndSessionReplay;
+        loadPlatform = ReactDocVariant.ErrorMonitoringAndSessionReplay;
       } else {
-        platform = ReactDocVariant.ErrorMonitoring;
+        loadPlatform = ReactDocVariant.ErrorMonitoring;
       }
     }
 
@@ -229,7 +233,7 @@ function SetupDocs({search, route, router, location}: Props) {
         api,
         orgSlug: organization.slug,
         projectSlug: project.slug,
-        platform: platform as PlatformKey,
+        platform: loadPlatform as PlatformKey,
       });
       setPlatformDocs(loadedDocs);
       setLoadedPlatform(project.platform);
@@ -239,9 +243,11 @@ function SetupDocs({search, route, router, location}: Props) {
       throw error;
     }
   }, [
-    project,
+    project?.slug,
+    project?.platform,
     api,
-    organization,
+    organization.slug,
+    organization.features,
     integrationSlug,
     integrationUseManualSetup,
     location.query.product,
@@ -249,7 +255,7 @@ function SetupDocs({search, route, router, location}: Props) {
 
   useEffect(() => {
     fetchData();
-  }, [fetchData, location.query.product]);
+  }, [fetchData, location.query.product, project?.platform]);
 
   // log experiment on mount if feature enabled
   useEffect(() => {

+ 1 - 0
static/app/views/onboarding/types.ts

@@ -18,6 +18,7 @@ export type StepProps = Pick<
   orgId: string;
   search: string;
   stepIndex: number;
+  selectedProjectSlug?: string;
 };
 
 export type StepDescriptor = {