Browse Source

ref(platformIntegrationSetup): Convert class to func (#76596)

Priscila Oliveira 6 months ago
parent
commit
8e5ec88c28

+ 112 - 136
static/app/views/projectInstall/platformIntegrationSetup.tsx

@@ -1,19 +1,19 @@
-import {Fragment} from 'react';
+import {Fragment, useEffect, useState} from 'react';
 import styled from '@emotion/styled';
 
 import {Button} from 'sentry/components/button';
 import ButtonBar from 'sentry/components/buttonBar';
-import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
+import LoadingError from 'sentry/components/loadingError';
+import LoadingIndicator from 'sentry/components/loadingIndicator';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import type {IntegrationProvider} from 'sentry/types/integrations';
-import type {Organization} from 'sentry/types/organization';
 import type {PlatformIntegration, Project} from 'sentry/types/project';
 import {trackAnalytics} from 'sentry/utils/analytics';
-import {browserHistory} from 'sentry/utils/browserHistory';
-import {trackIntegrationAnalytics} from 'sentry/utils/integrationUtil';
+import {useApiQuery} from 'sentry/utils/queryClient';
 import normalizeUrl from 'sentry/utils/url/normalizeUrl';
-import withOrganization from 'sentry/utils/withOrganization';
+import {useNavigate} from 'sentry/utils/useNavigate';
+import useOrganization from 'sentry/utils/useOrganization';
 import AddInstallationInstructions from 'sentry/views/onboarding/components/integrations/addInstallationInstructions';
 import PostInstallCodeSnippet from 'sentry/views/onboarding/components/integrations/postInstallCodeSnippet';
 import {PlatformDocHeader} from 'sentry/views/projectInstall/platformDocHeader';
@@ -21,152 +21,130 @@ import {AddIntegrationButton} from 'sentry/views/settings/organizationIntegratio
 
 import FirstEventFooter from './components/firstEventFooter';
 
-type Props = {
+interface PlatformIntegrationSetupProps {
   integrationSlug: string;
+  loading: boolean;
   onClickManualSetup: () => void;
-  organization: Organization;
   platform: PlatformIntegration | undefined;
   project: Project | undefined;
-} & DeprecatedAsyncComponent['props'];
-
-type State = {
-  installed: boolean;
-  integrations: {providers: IntegrationProvider[]};
-} & DeprecatedAsyncComponent['state'];
-
-class PlatformIntegrationSetup extends DeprecatedAsyncComponent<Props, State> {
-  getDefaultState() {
-    return {
-      ...super.getDefaultState(),
-      installed: false,
-      integrations: {providers: []},
-    };
-  }
-
-  componentDidMount() {
-    super.componentDidMount();
-    window.scrollTo(0, 0);
+}
 
-    const {platform} = this.props;
+export function PlatformIntegrationSetup({
+  project,
+  platform,
+  onClickManualSetup,
+  integrationSlug,
+  loading,
+}: PlatformIntegrationSetupProps) {
+  const organization = useOrganization();
+  const [installed, setInstalled] = useState(false);
+  const navigate = useNavigate();
+
+  const {
+    data: integrations,
+    isPending,
+    isError,
+    refetch,
+  } = useApiQuery<{providers: IntegrationProvider[]}>(
+    [
+      `/organizations/${organization.slug}/config/integrations/?provider_key=${integrationSlug}`,
+    ],
+    {
+      enabled: !!integrationSlug,
+      staleTime: 0,
+    }
+  );
 
+  useEffect(() => {
+    window.scrollTo(0, 0);
     // redirect if platform is not known.
-    if (!platform || platform.id === 'other') {
-      this.redirectToNeutralDocs();
+    if ((!platform || platform.id === 'other') && !!project?.slug) {
+      navigate(
+        normalizeUrl(
+          `/organizations/${organization.slug}/projects/${project.slug}/getting-started/`
+        )
+      );
     }
-  }
+  }, [platform, organization.slug, navigate, project?.slug]);
 
-  get provider() {
-    const {providers} = this.state.integrations;
-    return providers.length ? providers[0] : null;
-  }
+  const isLoading = isPending || loading;
 
-  getEndpoints(): ReturnType<DeprecatedAsyncComponent['getEndpoints']> {
-    const {organization, integrationSlug} = this.props;
-
-    if (!integrationSlug) {
-      return [];
-    }
-
-    return [
-      [
-        'integrations',
-        `/organizations/${organization.slug}/config/integrations/?provider_key=${integrationSlug}`,
-      ],
-    ];
+  if (isLoading) {
+    return <LoadingIndicator />;
   }
 
-  handleFullDocsClick = () => {
-    const {organization} = this.props;
-    trackAnalytics('growth.onboarding_view_full_docs', {organization});
-  };
-
-  redirectToNeutralDocs() {
-    const {organization, project} = this.props;
-
-    if (!project) {
-      return;
-    }
+  if (isError) {
+    return <LoadingError onRetry={refetch} />;
+  }
 
-    const url = `/organizations/${organization.slug}/projects/${project.slug}/getting-started/`;
+  const provider = integrations?.providers.length ? integrations.providers[0] : null;
 
-    browserHistory.push(normalizeUrl(url));
+  if (!provider || !platform || !project) {
+    return null;
   }
 
-  handleAddIntegration = () => {
-    this.setState({installed: true});
-  };
-
-  trackSwitchToManual = () => {
-    const {onClickManualSetup, organization, integrationSlug} = this.props;
-    onClickManualSetup();
-    trackIntegrationAnalytics('integrations.switch_manual_sdk_setup', {
-      integration_type: 'first_party',
-      integration: integrationSlug,
-      view: 'project_creation',
-      organization,
-    });
-  };
-
-  render() {
-    const {organization, project, platform} = this.props;
-    const {installed} = this.state;
-    const provider = this.provider;
-
-    if (!provider || !platform || !project) {
-      return null;
-    }
-
-    // TODO: make dynamic when adding more integrations
-    const docsLink =
-      'https://docs.sentry.io/product/integrations/cloud-monitoring/aws-lambda/';
-
-    return (
-      <OuterWrapper>
-        <InnerWrapper>
-          <PlatformDocHeader
-            platform={{
-              key: platform.id,
-              id: platform.id,
-              name: platform.name,
-              link: platform.link,
-            }}
-            projectSlug={project.slug}
-            title={t('Automatically instrument %s', platform.name)}
-          />
-          {!installed ? (
-            <Fragment>
-              <AddInstallationInstructions />
-              <StyledButtonBar gap={1}>
-                <AddIntegrationButton
-                  provider={provider}
-                  onAddIntegration={this.handleAddIntegration}
-                  organization={organization}
-                  priority="primary"
-                  size="sm"
-                  analyticsParams={{view: 'project_creation', already_installed: false}}
-                  modalParams={{projectId: project.id}}
-                  aria-label={t('Add integration')}
-                />
-                <Button size="sm" onClick={this.trackSwitchToManual}>
-                  {t('Manual Setup')}
-                </Button>
-              </StyledButtonBar>
-            </Fragment>
-          ) : (
-            <Fragment>
-              <PostInstallCodeSnippet provider={provider} />
-              <FirstEventFooter
-                project={project}
+  return (
+    <OuterWrapper>
+      <InnerWrapper>
+        <PlatformDocHeader
+          platform={{
+            key: platform.id,
+            id: platform.id,
+            name: platform.name,
+            link: platform.link,
+          }}
+          projectSlug={project.slug}
+          title={t('Automatically instrument %s', platform.name)}
+        />
+        {!installed ? (
+          <Fragment>
+            <AddInstallationInstructions />
+            <StyledButtonBar gap={1}>
+              <AddIntegrationButton
+                provider={provider}
+                onAddIntegration={() => setInstalled(true)}
                 organization={organization}
-                docsLink={docsLink}
-                docsOnClick={this.handleFullDocsClick}
+                priority="primary"
+                size="sm"
+                analyticsParams={{view: 'project_creation', already_installed: false}}
+                modalParams={{projectId: project.id}}
+                aria-label={t('Add integration')}
               />
-            </Fragment>
-          )}
-        </InnerWrapper>
-      </OuterWrapper>
-    );
-  }
+              <Button
+                size="sm"
+                onClick={() => {
+                  onClickManualSetup();
+                  trackAnalytics('integrations.switch_manual_sdk_setup', {
+                    integration_type: 'first_party',
+                    integration: integrationSlug,
+                    view: 'project_creation',
+                    organization,
+                  });
+                }}
+              >
+                {t('Manual Setup')}
+              </Button>
+            </StyledButtonBar>
+          </Fragment>
+        ) : (
+          <Fragment>
+            <PostInstallCodeSnippet provider={provider} />
+            <FirstEventFooter
+              project={project}
+              organization={organization}
+              docsLink={
+                // TODO: make dynamic when adding more integrations
+                'https://docs.sentry.io/product/integrations/cloud-monitoring/aws-lambda/'
+              }
+              docsOnClick={() =>
+                trackAnalytics('growth.onboarding_view_full_docs', {organization})
+              }
+            />
+          </Fragment>
+        )}
+      </InnerWrapper>
+    </OuterWrapper>
+  );
 }
 
 const StyledButtonBar = styled(ButtonBar)`
@@ -190,5 +168,3 @@ const OuterWrapper = styled('div')`
   align-items: center;
   margin-top: 50px;
 `;
-
-export default withOrganization(PlatformIntegrationSetup);

+ 2 - 1
static/app/views/projectInstall/platformOrIntegration.tsx

@@ -9,7 +9,7 @@ import useProjects from 'sentry/utils/useProjects';
 
 import GettingStarted from './gettingStarted';
 import {ProjectInstallPlatform} from './platform';
-import PlatformIntegrationSetup from './platformIntegrationSetup';
+import {PlatformIntegrationSetup} from './platformIntegrationSetup';
 
 type Props = RouteComponentProps<{projectId: string}, {}>;
 
@@ -41,6 +41,7 @@ function PlatformOrIntegration({params}: Props) {
         onClickManualSetup={() => setIntegrationUseManualSetup(true)}
         project={project}
         platform={currentPlatform}
+        loading={loadingProjects}
       />
     );
   }