15088: Handles browser navigation during link account ops
[arvados-workbench2.git] / src / store / link-account-panel / link-account-panel-actions.ts
index 61dc657eb21f998104a13467a4e42d819138819d..5552882449b0d376aa3c502ca74d4c66a650c87d 100644 (file)
@@ -14,6 +14,8 @@ import { UserResource } from "~/models/user";
 import { GroupResource } from "~/models/group";
 import { LinkAccountPanelError, OriginatingUser } from "./link-account-panel-reducer";
 import { login, logout } from "~/store/auth/auth-action";
+import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
+import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
 
 export const linkAccountPanelActions = unionize({
     LINK_INIT: ofType<{ targetUser: UserResource | undefined }>(),
@@ -69,13 +71,6 @@ export const checkForLinkStatus = () =>
         }
     };
 
-export const finishLinking = (status: LinkAccountStatus) =>
-    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
-        services.linkAccountService.removeFromSession();
-        services.linkAccountService.saveLinkOpStatus(status);
-        location.reload();
-    };
-
 export const switchUser = (user: UserResource, token: string) =>
     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
         dispatch(saveUser(user));
@@ -97,12 +92,11 @@ export const linkFailed = () =>
             }
             dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Account link failed.', kind: SnackbarKind.ERROR , hideDuration: 3000 }));
         }
-        dispatch(finishLinking(LinkAccountStatus.FAILED));
+        services.linkAccountService.removeAccountToLink();
     };
 
 export const loadLinkAccountPanel = () =>
     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
-
         // First check if an account link operation has completed
         dispatch(checkForLinkStatus());
 
@@ -112,20 +106,11 @@ export const loadLinkAccountPanel = () =>
         const curToken = getState().auth.apiToken;
         if (curUser && curToken) {
             const curUserResource = await services.userService.get(curUser.uuid);
-            const linkAccountData = services.linkAccountService.getFromSession();
+            const linkAccountData = services.linkAccountService.getAccountToLink();
 
             // If there is link account session data, then the user has logged in a second time
             if (linkAccountData) {
 
-                // If the window is refreshed after the second login, cancel the linking
-                if (window.performance) {
-                    if (performance.navigation.type === PerformanceNavigation.TYPE_BACK_FORWARD ||
-                        performance.navigation.type === PerformanceNavigation.TYPE_RELOAD) {
-                        dispatch(cancelLinking());
-                        return;
-                    }
-                }
-
                 // Use the token of the user we are getting data for. This avoids any admin/non-admin permissions
                 // issues since a user will always be able to query the api server for their own user data.
                 dispatch(saveApiToken(linkAccountData.token));
@@ -155,7 +140,8 @@ export const loadLinkAccountPanel = () =>
                     // This should never really happen, but just in case, switch to the user that
                     // originated the linking operation (i.e. the user saved in session data)
                     dispatch(switchUser(savedUserResource, linkAccountData.token));
-                    dispatch(finishLinking(LinkAccountStatus.FAILED));
+                    services.linkAccountService.removeAccountToLink();
+                    dispatch(linkAccountPanelActions.LINK_INIT({targetUser:savedUserResource}));
                 }
 
                 dispatch(switchUser(params.targetUser, params.targetUserToken));
@@ -183,7 +169,7 @@ export const loadLinkAccountPanel = () =>
 export const startLinking = (t: LinkAccountType) =>
     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
         const accountToLink = {type: t, userUuid: services.authService.getUuid(), token: services.authService.getApiToken()} as AccountToLink;
-        services.linkAccountService.saveToSession(accountToLink);
+        services.linkAccountService.saveAccountToLink(accountToLink);
         const auth = getState().auth;
         dispatch(logout());
         dispatch(login(auth.localCluster, auth.remoteHosts[auth.homeCluster]));
@@ -191,15 +177,16 @@ export const startLinking = (t: LinkAccountType) =>
 
 export const getAccountLinkData = () =>
     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
-        return services.linkAccountService.getFromSession();
+        return services.linkAccountService.getAccountToLink();
     };
 
 export const cancelLinking = () =>
     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
         let user: UserResource | undefined;
         try {
+            dispatch(progressIndicatorActions.START_WORKING(WORKBENCH_LOADING_SCREEN));
             // When linking is cancelled switch to the originating user (i.e. the user saved in session data)
-            const linkAccountData = services.linkAccountService.getFromSession();
+            const linkAccountData = services.linkAccountService.getAccountToLink();
             if (linkAccountData) {
                 dispatch(saveApiToken(linkAccountData.token));
                 user = await services.userService.get(linkAccountData.userUuid);
@@ -207,7 +194,9 @@ export const cancelLinking = () =>
             }
         }
         finally {
-            dispatch(finishLinking(LinkAccountStatus.CANCELLED));
+            services.linkAccountService.removeAccountToLink();
+            dispatch(linkAccountPanelActions.LINK_INIT({targetUser:user}));
+            dispatch(progressIndicatorActions.STOP_WORKING(WORKBENCH_LOADING_SCREEN));
         }
     };
 
@@ -236,6 +225,9 @@ export const linkAccount = () =>
                 dispatch(saveApiToken(linkState.userToLinkToken));
                 await services.linkAccountService.linkAccounts(linkState.targetUserToken, newGroup.uuid);
                 dispatch(switchUser(linkState.targetUser, linkState.targetUserToken));
+                services.linkAccountService.removeAccountToLink();
+                services.linkAccountService.saveLinkOpStatus(LinkAccountStatus.SUCCESS);
+                location.reload();
             }
             catch(e) {
                 // If the link operation fails, delete the previously made project
@@ -248,8 +240,5 @@ export const linkAccount = () =>
                 }
                 throw e;
             }
-            finally {
-                dispatch(finishLinking(LinkAccountStatus.SUCCESS));
-            }
         }
     };
\ No newline at end of file