22
33import { ConnectIntegrationDialog } from '@/components/integrations/ConnectIntegrationDialog' ;
44import { useApi } from '@/hooks/use-api' ;
5+ import { useIntegrationMutations } from '@/hooks/use-integration-platform' ;
56import { usePermissions } from '@/hooks/use-permissions' ;
67import { ManageIntegrationDialog } from '@/components/integrations/ManageIntegrationDialog' ;
78import { CLOUD_RECONNECT_CUTOFF_LABEL , requiresCloudReconnect } from '@/lib/cloud-reconnect-policy' ;
@@ -10,6 +11,7 @@ import { Add, Settings } from '@trycompai/design-system/icons';
1011import { useSearchParams , useRouter } from 'next/navigation' ;
1112import { useCallback , useMemo , useState } from 'react' ;
1213import { toast } from 'sonner' ;
14+ import { mutate as globalMutate } from 'swr' ;
1315import { isCloudProviderSlug } from '../constants' ;
1416import type { Finding , Provider } from '../types' ;
1517import { CloudSettingsModal } from './CloudSettingsModal' ;
@@ -51,9 +53,11 @@ export function TestsLayout({ initialFindings, initialProviders, orgId }: TestsL
5153 const canRunScan = hasPermission ( 'integration' , 'update' ) ;
5254 const canCreateIntegration = hasPermission ( 'integration' , 'create' ) ;
5355 const api = useApi ( ) ;
56+ const { deleteConnection } = useIntegrationMutations ( ) ;
5457 const [ showSettings , setShowSettings ] = useState ( false ) ;
5558 const [ viewingResults , setViewingResults ] = useState ( true ) ;
5659 const [ isScanning , setIsScanning ] = useState ( false ) ;
60+ const [ isReconnecting , setIsReconnecting ] = useState ( false ) ;
5761 const searchParams = useSearchParams ( ) ;
5862 const router = useRouter ( ) ;
5963 const [ activeProviderTab , setActiveProviderTabState ] = useState < string | null > (
@@ -217,6 +221,37 @@ export function TestsLayout({ initialFindings, initialProviders, orgId }: TestsL
217221 setViewingResults ( true ) ;
218222 } ;
219223
224+ const handleReconnect = async ( providerType : string ) => {
225+ const providerName = PROVIDER_NAME [ providerType ] || providerType . toUpperCase ( ) ;
226+ if (
227+ ! confirm (
228+ `This will disconnect all your ${ providerName } connections and redirect you to set up a fresh connection. Continue?` ,
229+ )
230+ ) {
231+ return ;
232+ }
233+
234+ setIsReconnecting ( true ) ;
235+ try {
236+ const connections = providerGroups [ providerType ] || [ ] ;
237+ await Promise . all (
238+ connections . map ( ( connection ) =>
239+ connection . isLegacy
240+ ? api . delete ( `/v1/cloud-security/legacy/${ connection . id } ` )
241+ : deleteConnection ( connection . id ) ,
242+ ) ,
243+ ) ;
244+ await Promise . all ( [ mutateProviders ( ) , mutateFindings ( ) ] ) ;
245+ // Clear integration connections cache so the target page doesn't flash stale data
246+ await globalMutate ( [ 'integration-connections' , orgId ] ) ;
247+ router . push ( `/${ orgId } /integrations/${ providerType } ` ) ;
248+ } catch {
249+ toast . error ( 'Failed to disconnect connections. Please try again.' ) ;
250+ } finally {
251+ setIsReconnecting ( false ) ;
252+ }
253+ } ;
254+
220255 if ( connectedProviders . length === 0 || ! viewingResults ) {
221256 return (
222257 < EmptyState
@@ -339,6 +374,8 @@ export function TestsLayout({ initialFindings, initialProviders, orgId }: TestsL
339374 }
340375 canRunScan = { canRunScan }
341376 canAddConnection = { canCreateIntegration }
377+ isReconnecting = { isReconnecting }
378+ onReconnect = { handleReconnect }
342379 orgId = { orgId }
343380 />
344381
0 commit comments