15088: Updates state to account for both types of linking and adds UI
[arvados-workbench2.git] / src / store / link-account-panel / link-account-panel-actions.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Dispatch } from "redux";
6 import { RootState } from "~/store/store";
7 import { ServiceRepository } from "~/services/services";
8 import { setBreadcrumbs } from "~/store/breadcrumbs/breadcrumbs-actions";
9 import { LinkAccountType, AccountToLink } from "~/models/link-account";
10 import { logout, saveApiToken, saveUser } from "~/store/auth/auth-action";
11 import { unionize, ofType, UnionOf } from '~/common/unionize';
12 import { UserResource } from "~/models/user";
13 import { navigateToRootProject } from "~/store/navigation/navigation-action";
14
15 export const linkAccountPanelActions = unionize({
16     LOAD_LINKING: ofType<{ user: UserResource | undefined, userToLink: UserResource | undefined }>(),
17     REMOVE_LINKING: {}
18 });
19
20 export type LinkAccountPanelAction = UnionOf<typeof linkAccountPanelActions>;
21
22 export const loadLinkAccountPanel = () =>
23     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
24         dispatch(setBreadcrumbs([{ label: 'Link account'}]));
25
26         const curUser = getState().auth.user;
27         if (curUser) {
28             services.userService.get(curUser.uuid).then(curUserResource => {
29                 const linkAccountData = services.linkAccountService.getLinkAccount();
30                 if (linkAccountData) {
31                     services.userService.get(linkAccountData.userUuid).then(savedUserResource => {
32                         if (linkAccountData.type === LinkAccountType.ADD_OTHER_LOGIN) {
33                             dispatch<any>(linkAccountPanelActions.LOAD_LINKING({ userToLink: curUserResource, user: savedUserResource }));
34                         }
35                         else if (linkAccountData.type === LinkAccountType.ACCESS_OTHER_ACCOUNT) {
36                             dispatch<any>(linkAccountPanelActions.LOAD_LINKING({ userToLink: savedUserResource, user: curUserResource }));
37                         }
38                         else {
39                             throw new Error('Invalid link account type.');
40                         }
41                     });
42                 }
43                 else {
44                     dispatch<any>(linkAccountPanelActions.LOAD_LINKING({ userToLink: undefined, user: curUserResource }));
45                 }
46             });
47         }
48     };
49
50 export const saveAccountLinkData = (t: LinkAccountType) =>
51     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
52         const accountToLink = {type: t, userUuid: services.authService.getUuid(), token: services.authService.getApiToken()} as AccountToLink;
53         services.linkAccountService.saveLinkAccount(accountToLink);
54         dispatch(logout());
55     };
56
57 export const getAccountLinkData = () =>
58     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
59         return services.linkAccountService.getLinkAccount();
60     };
61
62 export const removeAccountLinkData = () =>
63     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
64         const linkAccountData = services.linkAccountService.getLinkAccount();
65         services.linkAccountService.removeLinkAccount();
66         dispatch(linkAccountPanelActions.REMOVE_LINKING());
67         if (linkAccountData) {
68             services.userService.get(linkAccountData.userUuid).then(savedUser => {
69                 dispatch(setBreadcrumbs([{ label: ''}]));
70                 dispatch<any>(saveUser(savedUser));
71                 dispatch<any>(saveApiToken(linkAccountData.token));
72                 dispatch<any>(navigateToRootProject);
73             });
74         }
75     };
76
77 export const linkAccount = () =>
78     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
79     };