Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brave-colts-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@asgardeo/react": patch
---

Fix loading state issues in the React SDK
22 changes: 11 additions & 11 deletions packages/react/src/components/SignIn/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ const SignIn: FC<SignInProps> = (props: SignInProps): ReactElement => {
totpChildren,
} = props;

const [isComponentLoading, setIsComponentLoading] = useState<boolean>(true);
const [alert, setAlert] = useState<AlertType>();
const [showSelfSignUp, setShowSelfSignUp] = useState<boolean>(showSignUp);
const [componentBranding, setComponentBranding] = useState<Branding>();
Expand Down Expand Up @@ -104,12 +103,13 @@ const SignIn: FC<SignInProps> = (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);
});
}, []);

Expand All @@ -125,7 +125,7 @@ const SignIn: FC<SignInProps> = (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,
Expand All @@ -135,7 +135,7 @@ const SignIn: FC<SignInProps> = (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);
});

Expand Down Expand Up @@ -185,7 +185,7 @@ const SignIn: FC<SignInProps> = (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,
Expand All @@ -198,7 +198,7 @@ const SignIn: FC<SignInProps> = (props: SignInProps): ReactElement => {
setShowSelfSignUp(false);
}

authContext.setIsAuthLoading(false);
authContext?.setIsAuthLoading(false);
};

const renderLoginOptions = (authenticators: Authenticator[]): ReactElement[] => {
Expand All @@ -208,7 +208,7 @@ const SignIn: FC<SignInProps> = (props: SignInProps): ReactElement => {
const displayName: string = authenticator.idp === 'LOCAL' ? authenticator.authenticator : authenticator.idp;
LoginOptions.push(
<LoginOptionsBox
isAuthLoading={authContext.isAuthLoading}
isAuthLoading={authContext?.isAuthLoading}
socialName={authenticator.authenticator}
displayName={`${t(keys.common.multiple.options.prefix)} ${displayName}`}
handleOnClick={(): Promise<void> => handleAuthenticate(authenticator.authenticatorId)}
Expand Down Expand Up @@ -345,7 +345,7 @@ const SignIn: FC<SignInProps> = (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 (
<div className="Box-circularProgressHolder">
<CircularProgress className="circular-progress" />
Expand All @@ -364,14 +364,14 @@ const SignIn: FC<SignInProps> = (props: SignInProps): ReactElement => {
return (
<ThemeProvider theme={generateThemeSignIn(componentBranding?.preference.theme)}>
<UISignIn className="Box-asgardeoSignIn">
{showLogo && !(isLoading || isComponentLoading) && (
{showLogo && !(isLoading || authContext?.isComponentLoading) && (
<UISignIn.Image className="asgardeo-sign-in-logo" src={imgUrl} />
)}
{authContext?.authResponse?.flowStatus !== FlowStatus.SuccessCompleted && !isAuthenticated && (
<>
{renderSignIn()}

{showFooter && !(isLoading || isComponentLoading) && (
{showFooter && !(isLoading || authContext?.isComponentLoading) && (
<UISignIn.Footer
className="asgardeo-sign-in-footer"
copyrights={{children: copyrightText}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import {ScreenType, keys} from '@asgardeo/js';
import {CircularProgress, Grid, Skeleton} from '@oxygen-ui/react';
import {PropsWithChildren, ReactElement, useContext, useState} from 'react';
import {PropsWithChildren, ReactElement, useContext} from 'react';
import AsgardeoContext from '../../../contexts/asgardeo-context';
import useTranslations from '../../../hooks/use-translations';
import BasicAuthProps from '../../../models/basic-auth-props';
Expand Down
8 changes: 8 additions & 0 deletions packages/react/src/hooks/use-translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {useContext, useEffect, useState} from 'react';
import I18nContext from '../contexts/i18n-context';
import {I18n, SetTranslationsProps} from '../models/i18n';
import UseTranslations from '../models/use-translations';
import AsgardeoContext from '../contexts/asgardeo-context';

/**
* `useTranslations` is a custom hook that fetches translations.
Expand All @@ -38,15 +39,22 @@ const useTranslations = (props: SetTranslationsProps): UseTranslations => {

const [isLoading, setIsLoading] = useState<boolean>(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.
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/models/auth-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ interface AuthContext {
isAuthLoading: boolean;
isAuthenticated: boolean | undefined;
isBrandingLoading: boolean;
isComponentLoading: boolean;
isGlobalLoading: boolean;
isTextLoading: boolean;
onSignOutRef: React.MutableRefObject<Function>;
setAuthResponse: (response: AuthApiResponse) => void;
setAuthentication: () => void;
setIsAuthLoading: (value: boolean) => void;
setIsBrandingLoading: (value: boolean) => void;
setIsComponentLoading: (value: boolean) => void;
setIsTextLoading: (value: boolean) => void;
setOnSignIn: (response?: any) => void | Promise<void>;
setOnSignOut: (response?: any) => void | Promise<void>;
Expand Down
8 changes: 6 additions & 2 deletions packages/react/src/providers/AsgardeoProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ const AsgardeoProvider: FC<PropsWithChildren<AsgardeoProviderProps>> = (
const [accessToken, setAccessToken] = useState<string>('');
const [isAuthenticated, setIsAuthenticated] = useState<boolean>();
const [user, setUser] = useState<MeAPIResponse>();

const [isBrandingLoading, setIsBrandingLoading] = useState<boolean>(true);
const [isTextLoading, setIsTextLoading] = useState<boolean>(true);
const [isAuthLoading, setIsAuthLoading] = useState<boolean>(false);
const [isComponentLoading, setIsComponentLoading] = useState<boolean>(true);
const [authResponse, setAuthResponse] = useState<AuthApiResponse>();
const [username, setUsername] = useState<string>('');

Expand Down Expand Up @@ -137,13 +137,15 @@ const AsgardeoProvider: FC<PropsWithChildren<AsgardeoProviderProps>> = (
isAuthLoading,
isAuthenticated,
isBrandingLoading,
isGlobalLoading: isBrandingLoading || isTextLoading || isAuthLoading,
isComponentLoading,
isGlobalLoading: isAuthLoading || isBrandingLoading || isComponentLoading || isTextLoading,
isTextLoading,
onSignOutRef,
setAuthResponse,
setAuthentication,
setIsAuthLoading,
setIsBrandingLoading,
setIsComponentLoading,
setIsTextLoading,
setOnSignIn,
setOnSignOut,
Expand All @@ -158,9 +160,11 @@ const AsgardeoProvider: FC<PropsWithChildren<AsgardeoProviderProps>> = (
isAuthLoading,
isAuthenticated,
isBrandingLoading,
isComponentLoading,
isTextLoading,
setAuthResponse,
setAuthentication,
setIsComponentLoading,
setOnSignIn,
setOnSignOut,
setUsername,
Expand Down