Skip to content
Snippets Groups Projects
Commit 59b51aee authored by John Sparger's avatar John Sparger
Browse files

Fix loading in UserProvider, don't render UserProvider children before user...

Fix loading in UserProvider, don't render UserProvider children before user initialized, be more careful with when loading flag is set in useAsync and useQueuedResponse, start with loading=true when using call=true in useAsync
parent b5cea4cf
No related branches found
No related tags found
5 merge requests!270Merging develop branch to master in order to create RC,!222Fixing missing time interval parameter for logs,!202Merging develop to master,!194Unify deployment and command logs (Job Log) ICSHWI-9610,!188Detect when users should log in and redirect them to an optional login page ICSHWI-9267
...@@ -43,6 +43,7 @@ export function UserProvider({ children }) { ...@@ -43,6 +43,7 @@ export function UserProvider({ children }) {
const [loginError, setLoginError] = useState(); const [loginError, setLoginError] = useState();
const [loginResponse, loginFcn, /*reset*/, loginLoading] = useLogin(onLoginError); const [loginResponse, loginFcn, /*reset*/, loginLoading] = useLogin(onLoginError);
const [logoutFcn, logoutLoading] = useLogout(); const [logoutFcn, logoutLoading] = useLogout();
const [initialized, setInitialized] = useState(false);
const resetLoginError = useCallback(() => setLoginError(null), [setLoginError]); const resetLoginError = useCallback(() => setLoginError(null), [setLoginError]);
...@@ -68,13 +69,19 @@ export function UserProvider({ children }) { ...@@ -68,13 +69,19 @@ export function UserProvider({ children }) {
const [value, setValue] = useState(createValue()); const [value, setValue] = useState(createValue());
useEffect(() => {
if (!loading) {
setInitialized(true);
}
}, [loading, ])
useEffect(() => { useEffect(() => {
if (!loading) { if (!loading) {
setValue(createValue()) setValue(createValue())
} }
}, [loading, setValue, createValue]) }, [loading, setValue, createValue])
return ( return ( initialized &&
<userContext.Provider value={value}> <userContext.Provider value={value}>
{children} {children}
</userContext.Provider> </userContext.Provider>
...@@ -120,11 +127,11 @@ export function useAPIErrorHandler(onError) { ...@@ -120,11 +127,11 @@ export function useAPIErrorHandler(onError) {
return useCallback(errorHandler, [logout]); return useCallback(errorHandler, [logout]);
} }
export function useQueuedResponse({ init = null, onError = null }) { export function useQueuedResponse({ init = null, onError = null, initLoading = false}) {
const queueRef = useRef([]); const queueRef = useRef([]);
const busyRef = useRef(false); const busyRef = useRef(false);
const [response, setResponse] = useState(init); const [response, setResponse] = useState(init);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(initLoading);
const errorHandler = useAPIErrorHandler(onError); const errorHandler = useAPIErrorHandler(onError);
const MAX_QUEUE_LENGTH = 10; const MAX_QUEUE_LENGTH = 10;
...@@ -144,16 +151,17 @@ export function useQueuedResponse({ init = null, onError = null }) { ...@@ -144,16 +151,17 @@ export function useQueuedResponse({ init = null, onError = null }) {
} }
queueRef.current = [] queueRef.current = []
setLoading(false);
busyRef.current = false; busyRef.current = false;
const { status, value, reason } = responses.pop(); const { status, value, reason } = responses.pop();
if (status === "rejected") { if (status === "rejected") {
setLoading(false);
errorHandler(reason); errorHandler(reason);
return; return;
} }
setResponse(value); setResponse(value);
setLoading(false);
}, [errorHandler]) }, [errorHandler])
const enqueue = useCallback((promise) => { const enqueue = useCallback((promise) => {
...@@ -168,7 +176,7 @@ export function useQueuedResponse({ init = null, onError = null }) { ...@@ -168,7 +176,7 @@ export function useQueuedResponse({ init = null, onError = null }) {
} }
export function useAsync({ fcn, call = true, init = null, onError = null }) { export function useAsync({ fcn, call = true, init = null, onError = null }) {
const { response, setResponse, loading, enqueue } = useQueuedResponse({ init, onError }); const { response, setResponse, loading, enqueue } = useQueuedResponse({ init, onError, call });
const reset = useCallback(() => setResponse(init), [setResponse, init]); const reset = useCallback(() => setResponse(init), [setResponse, init]);
...@@ -571,29 +579,33 @@ export function useUser() { ...@@ -571,29 +579,33 @@ export function useUser() {
const [userInfo, getUserInfo, resetUserInfo, userInfoLoading] = useUserInfo(onError); const [userInfo, getUserInfo, resetUserInfo, userInfoLoading] = useUserInfo(onError);
const [userRoles, getUserRoles, resetUserRoles, userRolesLoading] = useUserRoles(onError); const [userRoles, getUserRoles, resetUserRoles, userRolesLoading] = useUserRoles(onError);
const [user, setUser] = useState(); const [user, setUser] = useState();
const [loading, setLoading] = useState(true);
const dataLoading = userInfoLoading || userRolesLoading;
useEffect(() => { useEffect(() => {
// userInfo and user Roles should: // userInfo and user Roles should:
// - both be defined when logged in // - both be defined when logged in
// - both be undefined when logged out // - both be undefined when logged out
const loginStateConsistent = Boolean(userInfo) === Boolean(userRoles); const loginStateConsistent = Boolean(userInfo) === Boolean(userRoles);
if (loginStateConsistent) { if (loginStateConsistent && !dataLoading) {
setUser({ userInfo, userRoles }); setUser({ userInfo, userRoles });
setLoading(false);
} }
}, [userInfo, userRoles]) }, [dataLoading, userInfo, userRoles])
const getUser = useCallback(() => { const getUser = useCallback(() => {
setLoading(true);
getUserInfo(); getUserInfo();
getUserRoles(); getUserRoles();
}, [getUserInfo, getUserRoles]); }, [getUserInfo, getUserRoles]);
const resetUser = useCallback(() => { const resetUser = useCallback(() => {
setLoading(true);
resetUserInfo(); resetUserInfo();
resetUserRoles(); resetUserRoles();
}, [resetUserInfo, resetUserRoles]); }, [resetUserInfo, resetUserRoles]);
const loading = userInfoLoading || userRolesLoading;
return [user, getUser, resetUser, loading] return [user, getUser, resetUser, loading]
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment