15088: Adds support for inactive account linking
[arvados.git] / src / views / link-account-panel / link-account-panel-root.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import {
7     StyleRulesCallback,
8     WithStyles,
9     withStyles,
10     Card,
11     CardContent,
12     Button,
13     Grid,
14 } from '@material-ui/core';
15 import { ArvadosTheme } from '~/common/custom-theme';
16 import { UserResource } from "~/models/user";
17 import { LinkAccountType } from "~/models/link-account";
18 import { formatDate } from "~/common/formatters";
19 import { LinkAccountPanelStatus, LinkAccountPanelError } from "~/store/link-account-panel/link-account-panel-reducer";
20
21 type CssRules = 'root';// | 'gridItem' | 'label' | 'title' | 'actions';
22
23 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
24     root: {
25         width: '100%',
26         overflow: 'auto'
27     }
28 });
29
30 export interface LinkAccountPanelRootDataProps {
31     targetUser?: UserResource;
32     userToLink?: UserResource;
33     status : LinkAccountPanelStatus;
34     error: LinkAccountPanelError;
35 }
36
37 export interface LinkAccountPanelRootActionProps {
38     saveAccountLinkData: (type: LinkAccountType) => void;
39     cancelLinking: () => void;
40     linkAccount: () => void;
41 }
42
43 function displayUser(user: UserResource, showCreatedAt: boolean = false) {
44     const disp = [];
45     disp.push(<span><b>{user.email}</b> ({user.username}, {user.uuid})</span>);
46     if (showCreatedAt) {
47         disp.push(<span> created on <b>{formatDate(user.createdAt)}</b></span>);
48     }
49     return disp;
50 }
51
52 type LinkAccountPanelRootProps = LinkAccountPanelRootDataProps & LinkAccountPanelRootActionProps & WithStyles<CssRules>;
53
54 export const LinkAccountPanelRoot = withStyles(styles) (
55     ({classes, targetUser, userToLink, status, error, saveAccountLinkData, cancelLinking, linkAccount}: LinkAccountPanelRootProps) => {
56         return <Card className={classes.root}>
57             <CardContent>
58             { status === LinkAccountPanelStatus.INITIAL && targetUser &&
59             <Grid container spacing={24}>
60                 <Grid container item direction="column" spacing={24}>
61                     <Grid item>
62                         You are currently logged in as {displayUser(targetUser, true)}
63                     </Grid>
64                     <Grid item>
65                         You can link Arvados accounts. After linking, either login will take you to the same account.
66                     </Grid>
67                 </Grid>
68                 <Grid container item direction="row" spacing={24}>
69                     <Grid item>
70                         <Button color="primary" variant="contained" onClick={() => saveAccountLinkData(LinkAccountType.ADD_OTHER_LOGIN)}>
71                             Add another login to this account
72                         </Button>
73                     </Grid>
74                     <Grid item>
75                         <Button color="primary" variant="contained" onClick={() => saveAccountLinkData(LinkAccountType.ACCESS_OTHER_ACCOUNT)}>
76                             Use this login to access another account
77                         </Button>
78                     </Grid>
79                 </Grid>
80             </Grid> }
81             { (status === LinkAccountPanelStatus.LINKING || status === LinkAccountPanelStatus.ERROR) && userToLink && targetUser &&
82             <Grid container spacing={24}>
83                 { status === LinkAccountPanelStatus.LINKING && <Grid container item direction="column" spacing={24}>
84                     <Grid item>
85                         Clicking 'Link accounts' will link {displayUser(userToLink, true)} to {displayUser(targetUser, true)}.
86                     </Grid>
87                     <Grid item>
88                         After linking, logging in as {displayUser(userToLink)} will log you into the same account as {displayUser(targetUser)}.
89                     </Grid>
90                     <Grid item>
91                        Any object owned by {displayUser(userToLink)} will be transfered to {displayUser(targetUser)}.
92                     </Grid>
93                 </Grid> }
94                 { error === LinkAccountPanelError.NON_ADMIN && <Grid item>
95                     Cannot link admin account {displayUser(userToLink)} to non-admin account {displayUser(targetUser)}.
96                 </Grid> }
97                 { error === LinkAccountPanelError.SAME_USER && <Grid item>
98                     Cannot link {displayUser(targetUser)} to the same account.
99                 </Grid> }
100                 { error === LinkAccountPanelError.INACTIVE && <Grid item>
101                     Cannot link active account {displayUser(userToLink)} to inactive account {displayUser(targetUser)}.
102                 </Grid> }
103                 <Grid container item direction="row" spacing={24}>
104                     <Grid item>
105                         <Button variant="contained" onClick={() => cancelLinking()}>
106                             Cancel
107                         </Button>
108                     </Grid>
109                     <Grid item>
110                         <Button disabled={status === LinkAccountPanelStatus.ERROR} color="primary" variant="contained" onClick={() => linkAccount()}>
111                             Link accounts
112                         </Button>
113                     </Grid>
114                 </Grid>
115             </Grid> }
116             </CardContent>
117         </Card> ;
118 });