From 8e5ec88c2842f902e623105df2e5219603a0d4c3 Mon Sep 17 00:00:00 2001 From: Priscila Oliveira Date: Wed, 28 Aug 2024 10:59:56 +0200 Subject: [PATCH] ref(platformIntegrationSetup): Convert class to func (#76596) --- .../platformIntegrationSetup.tsx | 248 ++++++++---------- .../projectInstall/platformOrIntegration.tsx | 3 +- 2 files changed, 114 insertions(+), 137 deletions(-) diff --git a/static/app/views/projectInstall/platformIntegrationSetup.tsx b/static/app/views/projectInstall/platformIntegrationSetup.tsx index 1a57a0821019b0..f09ee7ff502934 100644 --- a/static/app/views/projectInstall/platformIntegrationSetup.tsx +++ b/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 { - 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 { - const {organization, integrationSlug} = this.props; - - if (!integrationSlug) { - return []; - } - - return [ - [ - 'integrations', - `/organizations/${organization.slug}/config/integrations/?provider_key=${integrationSlug}`, - ], - ]; + if (isLoading) { + return ; } - handleFullDocsClick = () => { - const {organization} = this.props; - trackAnalytics('growth.onboarding_view_full_docs', {organization}); - }; - - redirectToNeutralDocs() { - const {organization, project} = this.props; - - if (!project) { - return; - } + if (isError) { + return ; + } - 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 ( - - - - {!installed ? ( - - - - - - - - ) : ( - - - + + + {!installed ? ( + + + + 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')} /> - - )} - - - ); - } + + + + ) : ( + + + + trackAnalytics('growth.onboarding_view_full_docs', {organization}) + } + /> + + )} + + + ); } const StyledButtonBar = styled(ButtonBar)` @@ -190,5 +168,3 @@ const OuterWrapper = styled('div')` align-items: center; margin-top: 50px; `; - -export default withOrganization(PlatformIntegrationSetup); diff --git a/static/app/views/projectInstall/platformOrIntegration.tsx b/static/app/views/projectInstall/platformOrIntegration.tsx index c34c130313aa51..e7c2f7395900dc 100644 --- a/static/app/views/projectInstall/platformOrIntegration.tsx +++ b/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} /> ); }