From c83e7b4da669169cb669a09ec23726ece3cc8fa7 Mon Sep 17 00:00:00 2001 From: DonOmalVindula Date: Fri, 28 Jun 2024 14:34:34 +0530 Subject: [PATCH 1/3] chore(react): Fix loading state issues in the React SDK --- packages/react/src/components/SignIn/SignIn.tsx | 12 ++++++------ .../components/SignIn/fragments/IdentifierFirst.tsx | 2 +- packages/react/src/hooks/use-translations.ts | 8 ++++++++ packages/react/src/models/auth-context.ts | 2 ++ packages/react/src/providers/AsgardeoProvider.tsx | 8 ++++++-- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/react/src/components/SignIn/SignIn.tsx b/packages/react/src/components/SignIn/SignIn.tsx index 682a37d7..174923b2 100644 --- a/packages/react/src/components/SignIn/SignIn.tsx +++ b/packages/react/src/components/SignIn/SignIn.tsx @@ -74,7 +74,6 @@ const SignIn: FC = (props: SignInProps): ReactElement => { totpChildren, } = props; - const [isComponentLoading, setIsComponentLoading] = useState(true); const [alert, setAlert] = useState(); const [showSelfSignUp, setShowSelfSignUp] = useState(showSignUp); const [componentBranding, setComponentBranding] = useState(); @@ -104,12 +103,13 @@ const SignIn: FC = (props: SignInProps): ReactElement => { authorize() .then((response: AuthApiResponse) => { authContext?.setAuthResponse(response); - setIsComponentLoading(false); }) .catch((error: Error) => { setAlert({alertType: {error: true}, key: keys.common.error}); - setIsComponentLoading(false); throw new AsgardeoUIException('REACT_UI-SIGN_IN-SI-SE01', 'Authorization failed', error.stack); + }) + .finally(() => { + authContext.setIsComponentLoading(false); }); }, []); @@ -345,7 +345,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { /** * Renders the circular progress component while the component or text is loading. */ - if (isComponentLoading || isLoading || authContext.isBrandingLoading) { + if (authContext.isComponentLoading || isLoading || authContext.isBrandingLoading) { return (
@@ -364,14 +364,14 @@ const SignIn: FC = (props: SignInProps): ReactElement => { return ( - {showLogo && !(isLoading || isComponentLoading) && ( + {showLogo && !(isLoading || authContext.isComponentLoading) && ( )} {authContext?.authResponse?.flowStatus !== FlowStatus.SuccessCompleted && !isAuthenticated && ( <> {renderSignIn()} - {showFooter && !(isLoading || isComponentLoading) && ( + {showFooter && !(isLoading || authContext.isComponentLoading) && ( { const [isLoading, setIsLoading] = useState(true); + const {setIsTextLoading} = useContext(AsgardeoContext); + const contextValue: I18n = useContext(I18nContext); const {text, setTranslations} = contextValue; useEffect(() => { setTranslations({componentLocaleOverride, componentTextOverrides, screen}).then((response: boolean) => { setIsLoading(!response); + setIsTextLoading(!response); }); }, [componentLocaleOverride, componentTextOverrides, screen, setTranslations]); + useEffect(() => { + setIsTextLoading(isLoading); + }, [isLoading]); + /** * `t` is a function that retrieves a specific translation from the fetched translations. * It takes a key as an argument, which is a string that represents a path to the desired translation. diff --git a/packages/react/src/models/auth-context.ts b/packages/react/src/models/auth-context.ts index ae6794de..8bebb966 100644 --- a/packages/react/src/models/auth-context.ts +++ b/packages/react/src/models/auth-context.ts @@ -25,6 +25,7 @@ interface AuthContext { isAuthLoading: boolean; isAuthenticated: boolean | undefined; isBrandingLoading: boolean; + isComponentLoading: boolean; isGlobalLoading: boolean; isTextLoading: boolean; onSignOutRef: React.MutableRefObject; @@ -32,6 +33,7 @@ interface AuthContext { setAuthentication: () => void; setIsAuthLoading: (value: boolean) => void; setIsBrandingLoading: (value: boolean) => void; + setIsComponentLoading: (value: boolean) => void; setIsTextLoading: (value: boolean) => void; setOnSignIn: (response?: any) => void | Promise; setOnSignOut: (response?: any) => void | Promise; diff --git a/packages/react/src/providers/AsgardeoProvider.tsx b/packages/react/src/providers/AsgardeoProvider.tsx index 77a47fa4..50b5cf77 100644 --- a/packages/react/src/providers/AsgardeoProvider.tsx +++ b/packages/react/src/providers/AsgardeoProvider.tsx @@ -55,10 +55,10 @@ const AsgardeoProvider: FC> = ( const [accessToken, setAccessToken] = useState(''); const [isAuthenticated, setIsAuthenticated] = useState(); const [user, setUser] = useState(); - const [isBrandingLoading, setIsBrandingLoading] = useState(true); const [isTextLoading, setIsTextLoading] = useState(true); const [isAuthLoading, setIsAuthLoading] = useState(false); + const [isComponentLoading, setIsComponentLoading] = useState(true); const [authResponse, setAuthResponse] = useState(); const [username, setUsername] = useState(''); @@ -137,13 +137,15 @@ const AsgardeoProvider: FC> = ( isAuthLoading, isAuthenticated, isBrandingLoading, - isGlobalLoading: isBrandingLoading || isTextLoading || isAuthLoading, + isComponentLoading, + isGlobalLoading: isAuthLoading || isBrandingLoading || isComponentLoading || isTextLoading, isTextLoading, onSignOutRef, setAuthResponse, setAuthentication, setIsAuthLoading, setIsBrandingLoading, + setIsComponentLoading, setIsTextLoading, setOnSignIn, setOnSignOut, @@ -158,9 +160,11 @@ const AsgardeoProvider: FC> = ( isAuthLoading, isAuthenticated, isBrandingLoading, + isComponentLoading, isTextLoading, setAuthResponse, setAuthentication, + setIsComponentLoading, setOnSignIn, setOnSignOut, setUsername, From 9d577ed83b3ba138b884d2a2aa0f51f4dc2d7d79 Mon Sep 17 00:00:00 2001 From: DonOmalVindula Date: Fri, 28 Jun 2024 14:35:50 +0530 Subject: [PATCH 2/3] chore(workspace): Add changeset --- .changeset/brave-colts-double.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/brave-colts-double.md diff --git a/.changeset/brave-colts-double.md b/.changeset/brave-colts-double.md new file mode 100644 index 00000000..9610211a --- /dev/null +++ b/.changeset/brave-colts-double.md @@ -0,0 +1,5 @@ +--- +"@asgardeo/react": patch +--- + +Fix loading state issues in the React SDK From 0362e93b1f8823fabfcbaa89d57b927bdd194737 Mon Sep 17 00:00:00 2001 From: DonOmalVindula Date: Fri, 28 Jun 2024 14:54:41 +0530 Subject: [PATCH 3/3] fix(react): Add null checks for AuthContext --- .../react/src/components/SignIn/SignIn.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/react/src/components/SignIn/SignIn.tsx b/packages/react/src/components/SignIn/SignIn.tsx index 174923b2..27033f19 100644 --- a/packages/react/src/components/SignIn/SignIn.tsx +++ b/packages/react/src/components/SignIn/SignIn.tsx @@ -109,7 +109,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { throw new AsgardeoUIException('REACT_UI-SIGN_IN-SI-SE01', 'Authorization failed', error.stack); }) .finally(() => { - authContext.setIsComponentLoading(false); + authContext?.setIsComponentLoading(false); }); }, []); @@ -125,7 +125,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { throw new AsgardeoUIException('REACT_UI-SIGN_IN-HA-IV02', 'Auth response is undefined.'); } - authContext.setIsAuthLoading(true); + authContext?.setIsAuthLoading(true); const resp: AuthApiResponse = await authenticate({ flowId: authContext?.authResponse.flowId, @@ -135,7 +135,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { }, }).catch((authnError: Error) => { setAlert({alertType: {error: true}, key: keys.common.error}); - authContext.setIsAuthLoading(false); + authContext?.setIsAuthLoading(false); throw new AsgardeoUIException('REACT_UI-SIGN_IN-HA-SE03', 'Authentication failed.', authnError.stack); }); @@ -185,7 +185,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { await authInstance.requestAccessToken(resp.authData.code, resp.authData.session_state, state); - authContext.setAuthentication(); + authContext?.setAuthentication(); } else if (resp.flowStatus === FlowStatus.FailIncomplete) { authContext?.setAuthResponse({ ...resp, @@ -198,7 +198,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { setShowSelfSignUp(false); } - authContext.setIsAuthLoading(false); + authContext?.setIsAuthLoading(false); }; const renderLoginOptions = (authenticators: Authenticator[]): ReactElement[] => { @@ -208,7 +208,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { const displayName: string = authenticator.idp === 'LOCAL' ? authenticator.authenticator : authenticator.idp; LoginOptions.push( => handleAuthenticate(authenticator.authenticatorId)} @@ -345,7 +345,7 @@ const SignIn: FC = (props: SignInProps): ReactElement => { /** * Renders the circular progress component while the component or text is loading. */ - if (authContext.isComponentLoading || isLoading || authContext.isBrandingLoading) { + if (authContext?.isComponentLoading || isLoading || authContext?.isBrandingLoading) { return (
@@ -364,14 +364,14 @@ const SignIn: FC = (props: SignInProps): ReactElement => { return ( - {showLogo && !(isLoading || authContext.isComponentLoading) && ( + {showLogo && !(isLoading || authContext?.isComponentLoading) && ( )} {authContext?.authResponse?.flowStatus !== FlowStatus.SuccessCompleted && !isAuthenticated && ( <> {renderSignIn()} - {showFooter && !(isLoading || authContext.isComponentLoading) && ( + {showFooter && !(isLoading || authContext?.isComponentLoading) && (