1- import { __internal_useUserEnterpriseConnections , useSession } from '@clerk/shared/react' ;
2- import type { __experimental_ConfigureSSOProps } from '@clerk/shared/types' ;
1+ import {
2+ __internal_useEnterpriseConnectionTestRuns ,
3+ __internal_useUserEnterpriseConnections ,
4+ useSession ,
5+ } from '@clerk/shared/react' ;
6+ import type { __experimental_ConfigureSSOProps , EnterpriseConnectionResource } from '@clerk/shared/types' ;
37import React from 'react' ;
48
59import { useProtect } from '@/common' ;
610import { withCoreUserGuard } from '@/contexts' ;
711import { Col , descriptors , Flex , Flow , Heading , Icon , localizationKeys , Text } from '@/customizables' ;
8- import { withCardStateProvider } from '@/elements/contexts' ;
12+ import { useCardState , withCardStateProvider } from '@/elements/contexts' ;
913import { ProfileCard } from '@/elements/ProfileCard' ;
1014import { ExclamationTriangle } from '@/icons' ;
1115import { Route , Switch } from '@/router' ;
@@ -16,7 +20,7 @@ import { ConfigureSSONavbar } from './ConfigureSSONavbar';
1620import { ConfigureSSOSkeleton } from './ConfigureSSOSkeleton' ;
1721import { ProfileCardFooter , ProfileCardHeader } from './elements/ProfileCard' ;
1822import { Step } from './elements/Step' ;
19- import { Wizard } from './elements/Wizard' ;
23+ import { useWizard , Wizard } from './elements/Wizard' ;
2024import { ConfigureStep , ConfirmationStep , SelectProviderStep , TestConfigurationStep , VerifyDomainStep } from './steps' ;
2125
2226const ConfigureSSOInternal = ( ) => {
@@ -64,19 +68,31 @@ const AuthenticatedContent = withCoreUserGuard(() => {
6468} ) ;
6569
6670const ConfigureSSOCardContent = ( { contentRef } : { contentRef : React . RefObject < HTMLDivElement > } ) => {
67- const { data : enterpriseConnections , isLoading } = __internal_useUserEnterpriseConnections ( { enabled : true } ) ;
68-
71+ const {
72+ data : enterpriseConnections ,
73+ isLoading : isLoadingEnterpriseConnections ,
74+ createEnterpriseConnection,
75+ updateEnterpriseConnection,
76+ deleteEnterpriseConnection,
77+ } = __internal_useUserEnterpriseConnections ( { enabled : true } ) ;
6978 // Currently FAPI only supports one enterprise connection per user
7079 const enterpriseConnection = enterpriseConnections ?. [ 0 ] ;
7180
72- if ( isLoading && ! enterpriseConnection ) {
81+ const { hasSuccessfulTestRun, isLoading : isLoadingTestRuns } = useHasSuccessfulTestRun ( enterpriseConnection ) ;
82+
83+ const isLoading = isLoadingEnterpriseConnections || isLoadingTestRuns ;
84+ if ( isLoading ) {
7385 return < ConfigureSSOSkeleton /> ;
7486 }
7587
7688 return (
7789 < ConfigureSSOProvider
90+ hasSuccessfulTestRun = { hasSuccessfulTestRun }
7891 enterpriseConnection = { enterpriseConnection }
7992 contentRef = { contentRef }
93+ createEnterpriseConnection = { createEnterpriseConnection }
94+ updateEnterpriseConnection = { updateEnterpriseConnection }
95+ deleteEnterpriseConnection = { deleteEnterpriseConnection }
8096 >
8197 < ConfigureSSOSteps />
8298 </ ConfigureSSOProvider >
@@ -88,6 +104,7 @@ const ConfigureSSOSteps = () => {
88104
89105 return (
90106 < Wizard initialStepId = { initialStepId } >
107+ < ResetCardErrorOnStepChange />
91108 < ConfigureSSOHeader />
92109
93110 < Wizard . Step id = 'select-provider' >
@@ -183,5 +200,45 @@ const MissingManageEnterpriseConnectionsPermission = () => (
183200 </ >
184201) ;
185202
203+ /**
204+ * Sentinel component rendered inside `<Wizard>`
205+ *
206+ * Clears any card-level error whenever the active step transitions, so a stale failure from one step
207+ * doesn't leak into the next
208+ */
209+ const ResetCardErrorOnStepChange = ( ) : null => {
210+ const { currentStep } = useWizard ( ) ;
211+ const card = useCardState ( ) ;
212+ const previousStepIdRef = React . useRef ( currentStep ?. id ) ;
213+
214+ React . useEffect ( ( ) => {
215+ if ( previousStepIdRef . current === currentStep ?. id ) {
216+ return ;
217+ }
218+
219+ previousStepIdRef . current = currentStep ?. id ;
220+ card . setError ( undefined ) ;
221+ } , [ currentStep ?. id , card ] ) ;
222+
223+ return null ;
224+ } ;
225+
226+ /**
227+ * Fetches a single successful test run for the given connection on mount
228+ */
229+ const useHasSuccessfulTestRun = (
230+ enterpriseConnection : EnterpriseConnectionResource | undefined ,
231+ ) : { hasSuccessfulTestRun : boolean ; isLoading : boolean } => {
232+ const { data : successfulTestRuns , isLoading } = __internal_useEnterpriseConnectionTestRuns ( {
233+ enterpriseConnectionId : enterpriseConnection ?. id ?? null ,
234+ params : { initialPage : 1 , pageSize : 1 , status : [ 'success' ] } ,
235+ } ) ;
236+
237+ return {
238+ hasSuccessfulTestRun : ( successfulTestRuns ?. length ?? 0 ) > 0 ,
239+ isLoading,
240+ } ;
241+ } ;
242+
186243export const ConfigureSSO : React . ComponentType < __experimental_ConfigureSSOProps > =
187244 withCardStateProvider ( ConfigureSSOInternal ) ;
0 commit comments