15088: Improves federated linking logic and UI
[arvados-workbench2.git] / src / store / link-account-panel / link-account-panel-actions.ts
index e63da1a42ac838f8d089771391ceb80dd94f8dac..7a92f4aaa990ca1bef6e6792ccd9b8d3d7ed6304 100644 (file)
@@ -18,7 +18,8 @@ import { progressIndicatorActions } from "~/store/progress-indicator/progress-in
 import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
 
 export const linkAccountPanelActions = unionize({
-    LINK_INIT: ofType<{ targetUser: UserResource | undefined }>(),
+    LINK_INIT: ofType<{
+        targetUser: UserResource | undefined }>(),
     LINK_LOAD: ofType<{
         originatingUser: OriginatingUser | undefined,
         targetUser: UserResource | undefined,
@@ -30,6 +31,8 @@ export const linkAccountPanelActions = unionize({
         targetUser: UserResource | undefined,
         userToLink: UserResource | undefined,
         error: LinkAccountPanelError }>(),
+    SET_SELECTED_CLUSTER: ofType<{
+        selectedCluster: string }>(),
     HAS_SESSION_DATA: {}
 });
 
@@ -84,19 +87,31 @@ export const linkFailed = () =>
         if (linkState.userToLink && linkState.userToLinkToken && linkState.targetUser && linkState.targetUserToken) {
             if (linkState.originatingUser === OriginatingUser.TARGET_USER) {
                 dispatch(switchUser(linkState.targetUser, linkState.targetUserToken));
-                dispatch(linkAccountPanelActions.LINK_INIT({targetUser: linkState.targetUser}));
             }
             else if ((linkState.originatingUser === OriginatingUser.USER_TO_LINK)) {
                 dispatch(switchUser(linkState.userToLink, linkState.userToLinkToken));
-                dispatch(linkAccountPanelActions.LINK_INIT({targetUser: linkState.userToLink}));
             }
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Account link failed.', kind: SnackbarKind.ERROR , hideDuration: 3000 }));
         }
         services.linkAccountService.removeAccountToLink();
+        services.linkAccountService.saveLinkOpStatus(LinkAccountStatus.FAILED);
+        location.reload();
     };
 
 export const loadLinkAccountPanel = () =>
     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+        // If there are remote hosts, set the initial selected cluster by getting the first cluster that isn't the local cluster
+        if (getState().linkAccountPanel.selectedCluster === undefined) {
+            const localCluster = getState().auth.localCluster;
+            let selectedCluster = localCluster;
+            for (const key in getState().auth.remoteHosts) {
+                if (key !== localCluster) {
+                    selectedCluster = key;
+                    break;
+                }
+            }
+            dispatch(linkAccountPanelActions.SET_SELECTED_CLUSTER({ selectedCluster }));
+        }
+
         // First check if an account link operation has completed
         dispatch(checkForLinkStatus());
 
@@ -118,7 +133,7 @@ export const loadLinkAccountPanel = () =>
                 dispatch(saveApiToken(curToken));
 
                 let params: any;
-                if (linkAccountData.type === LinkAccountType.ACCESS_OTHER_ACCOUNT) {
+                if (linkAccountData.type === LinkAccountType.ACCESS_OTHER_ACCOUNT || linkAccountData.type === LinkAccountType.ACCESS_OTHER_REMOTE_ACCOUNT) {
                     params = {
                         originatingUser: OriginatingUser.USER_TO_LINK,
                         targetUser: curUserResource,
@@ -127,7 +142,7 @@ export const loadLinkAccountPanel = () =>
                         userToLinkToken: linkAccountData.token
                     };
                 }
-                else if (linkAccountData.type === LinkAccountType.ADD_OTHER_LOGIN) {
+                else if (linkAccountData.type === LinkAccountType.ADD_OTHER_LOGIN || linkAccountData.type === LinkAccountType.ADD_LOCAL_TO_REMOTE) {
                     params = {
                         originatingUser: OriginatingUser.TARGET_USER,
                         targetUser: savedUserResource,
@@ -170,9 +185,16 @@ 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.saveAccountToLink(accountToLink);
+
         const auth = getState().auth;
+        const isLocalUser = auth.user!.uuid.substring(0,5) === auth.localCluster;
+        let homeCluster = auth.localCluster;
+        if (isLocalUser && t === LinkAccountType.ACCESS_OTHER_REMOTE_ACCOUNT) {
+            homeCluster = getState().linkAccountPanel.selectedCluster!;
+        }
+
         dispatch(logout());
-        dispatch(login(auth.localCluster, auth.homeCluster, auth.remoteHosts));
+        dispatch(login(auth.localCluster, homeCluster, auth.remoteHosts));
     };
 
 export const getAccountLinkData = () =>