Skip to content

Commit 5474548

Browse files
committed
ref(integrations): Convert AddIntegration from class render prop to useAddIntegration hook
Replace the class-based AddIntegration render prop component with a useAddIntegration hook. This modernizes the integration setup flow to use hooks and prepares for the API-driven pipeline modal by adding feature-flag-gated support for opening a React pipeline modal instead of the legacy Django popup window. - Convert AddIntegration class component to useAddIntegration hook - Refactor AddIntegrationButton to use the hook directly - Add API pipeline feature flag support for github and gitlab providers - Rewrite tests to use renderHookWithProviders with comprehensive coverage for both legacy and API pipeline flows
1 parent cbb90a8 commit 5474548

File tree

5 files changed

+577
-226
lines changed

5 files changed

+577
-226
lines changed

static/app/views/integrationOrganizationLink/index.tsx

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
3131
import {useLocation} from 'sentry/utils/useLocation';
3232
import {useParams} from 'sentry/utils/useParams';
3333
import RouteError from 'sentry/views/routeError';
34-
import {AddIntegration} from 'sentry/views/settings/organizationIntegrations/addIntegration';
34+
import {useAddIntegration} from 'sentry/views/settings/organizationIntegrations/addIntegration';
3535
import {IntegrationLayout} from 'sentry/views/settings/organizationIntegrations/detailedView/integrationLayout';
3636

3737
interface GitHubIntegrationInstallation {
@@ -228,37 +228,19 @@ export default function IntegrationOrganizationLink() {
228228

229229
const {IntegrationFeatures} = getIntegrationFeatureGate();
230230

231-
// Github uses a different installation flow with the installationId as a parameter
232-
// We have to wrap our installation button with AddIntegration so we can get the
233-
// addIntegrationWithInstallationId callback.
234-
// if we don't have an installationId, we need to use the finishInstallation callback.
235231
return (
236232
<IntegrationFeatures organization={organization} features={featuresComponents}>
237233
{({disabled, disabledReason}) => (
238-
<AddIntegration
234+
<AddIntegrationButton
239235
provider={provider}
240-
onInstall={onInstallWithInstallationId}
241236
organization={organization}
242-
>
243-
{addIntegrationWithInstallationId => (
244-
<ButtonWrapper>
245-
<Button
246-
priority="primary"
247-
disabled={!hasAccess || disabled}
248-
onClick={() =>
249-
installationId
250-
? addIntegrationWithInstallationId({
251-
installation_id: installationId,
252-
})
253-
: finishInstallation()
254-
}
255-
>
256-
{t('Install %s', provider.name)}
257-
</Button>
258-
{disabled && <IntegrationLayout.DisabledNotice reason={disabledReason} />}
259-
</ButtonWrapper>
260-
)}
261-
</AddIntegration>
237+
onInstall={onInstallWithInstallationId}
238+
installationId={installationId}
239+
hasAccess={hasAccess}
240+
disabled={disabled}
241+
disabledReason={disabledReason}
242+
finishInstallation={finishInstallation}
243+
/>
262244
)}
263245
</IntegrationFeatures>
264246
);
@@ -420,6 +402,45 @@ export default function IntegrationOrganizationLink() {
420402
);
421403
}
422404

405+
function AddIntegrationButton({
406+
provider,
407+
organization,
408+
onInstall,
409+
installationId,
410+
hasAccess,
411+
disabled,
412+
disabledReason,
413+
finishInstallation,
414+
}: {
415+
disabled: boolean;
416+
disabledReason: React.ReactNode;
417+
finishInstallation: () => void;
418+
hasAccess: boolean | undefined;
419+
onInstall: (data: Integration) => void;
420+
organization: Organization;
421+
provider: IntegrationProvider;
422+
installationId?: string;
423+
}) {
424+
const {startFlow} = useAddIntegration({provider, organization, onInstall});
425+
426+
return (
427+
<ButtonWrapper>
428+
<Button
429+
priority="primary"
430+
disabled={!hasAccess || disabled}
431+
onClick={() =>
432+
installationId
433+
? startFlow({installation_id: installationId})
434+
: finishInstallation()
435+
}
436+
>
437+
{t('Install %s', provider.name)}
438+
</Button>
439+
{disabled && <IntegrationLayout.DisabledNotice reason={disabledReason} />}
440+
</ButtonWrapper>
441+
);
442+
}
443+
423444
const InstallLink = styled('pre')`
424445
margin-bottom: 0;
425446
background: #fbe3e1;

0 commit comments

Comments
 (0)