15088: Adds invalid states and UI and improves action error handling
[arvados-workbench2.git] / src / views / link-account-panel / link-account-panel-root.tsx
index ceb3ffaeb21ce0ef53ece5219c6252ea45037b6d..68f407b57044a879f175e5adbfbaa2922f342493 100644 (file)
@@ -14,8 +14,10 @@ import {
     Grid,
 } from '@material-ui/core';
 import { ArvadosTheme } from '~/common/custom-theme';
-import { User } from "~/models/user";
-import { formatDate }from "~/common/formatters";
+import { UserResource } from "~/models/user";
+import { LinkAccountType } from "~/models/link-account";
+import { formatDate } from "~/common/formatters";
+import { LinkAccountPanelStatus, LinkAccountPanelError } from "~/store/link-account-panel/link-account-panel-reducer";
 
 type CssRules = 'root';// | 'gridItem' | 'label' | 'title' | 'actions';
 
@@ -27,35 +29,88 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 });
 
 export interface LinkAccountPanelRootDataProps {
-    user?: User;
+    user?: UserResource;
+    userToLink?: UserResource;
+    status : LinkAccountPanelStatus;
+    error: LinkAccountPanelError;
 }
 
-export interface LinkAccountPanelRootActionProps { }
+export interface LinkAccountPanelRootActionProps {
+    saveAccountLinkData: (type: LinkAccountType) => void;
+    removeAccountLinkData: () => void;
+    linkAccount: () => void;
+}
+
+function displayUser(user: UserResource, showCreatedAt: boolean = false) {
+    const disp = [];
+    disp.push(<span><b>{user.email}</b> ({user.username}, {user.uuid})</span>);
+    if (showCreatedAt) {
+        disp.push(<span> created on <b>{formatDate(user.createdAt)}</b></span>);
+    }
+    return disp;
+}
 
 type LinkAccountPanelRootProps = LinkAccountPanelRootDataProps & LinkAccountPanelRootActionProps & WithStyles<CssRules>;
 
 export const LinkAccountPanelRoot = withStyles(styles) (
-    ({classes, user}: LinkAccountPanelRootProps) => {
+    ({classes, user, userToLink, status, error, saveAccountLinkData, removeAccountLinkData, linkAccount}: LinkAccountPanelRootProps) => {
         return <Card className={classes.root}>
             <CardContent>
+            { status === LinkAccountPanelStatus.INITIAL && user &&
             <Grid container spacing={24}>
-            { user && <Grid container item direction="column" spacing={24}>
-                <Grid item>
-                    You are currently logged in as <b>{user.email}</b> ({user.username}, {user.uuid}) created on <b>{formatDate(user.createdAt)}</b>
+                <Grid container item direction="column" spacing={24}>
+                    <Grid item>
+                        You are currently logged in as {displayUser(user, true)}
+                    </Grid>
+                    <Grid item>
+                        You can link Arvados accounts. After linking, either login will take you to the same account.
+                    </Grid>
                 </Grid>
-                <Grid item>
-                    You can link Arvados accounts. After linking, either login will take you to the same account.
+                <Grid container item direction="row" spacing={24}>
+                    <Grid item>
+                        <Button color="primary" variant="contained" onClick={() => saveAccountLinkData(LinkAccountType.ADD_OTHER_LOGIN)}>
+                            Add another login to this account
+                        </Button>
+                    </Grid>
+                    <Grid item>
+                        <Button color="primary" variant="contained" onClick={() => saveAccountLinkData(LinkAccountType.ACCESS_OTHER_ACCOUNT)}>
+                            Use this login to access another account
+                        </Button>
+                    </Grid>
                 </Grid>
             </Grid> }
-            <Grid container item direction="row" spacing={24}>
-                <Grid item>
-                    <Button color="primary" variant="contained">Add another login to this account</Button>
-                </Grid>
-                <Grid item>
-                    <Button color="primary" variant="contained">Use this login to access another account</Button>
+            { (status === LinkAccountPanelStatus.LINKING || status === LinkAccountPanelStatus.ERROR) && userToLink && user &&
+            <Grid container spacing={24}>
+                { status === LinkAccountPanelStatus.LINKING && <Grid container item direction="column" spacing={24}>
+                    <Grid item>
+                        Clicking 'Link accounts' will link {displayUser(user, true)} to {displayUser(userToLink, true)}.
+                    </Grid>
+                    <Grid item>
+                        After linking, logging in as {displayUser(user)} will log you into the same account as {displayUser(userToLink)}.
+                    </Grid>
+                    <Grid item>
+                       Any object owned by {displayUser(user)} will be transfered to {displayUser(userToLink)}.
+                    </Grid>
+                </Grid> }
+                { error === LinkAccountPanelError.NON_ADMIN && <Grid item>
+                    Cannot link admin account {displayUser(userToLink)} to non-admin account {displayUser(user)}.
+                </Grid> }
+                { error === LinkAccountPanelError.SAME_USER && <Grid item>
+                    Cannot link {displayUser(userToLink)} to the same account.
+                </Grid> }
+                <Grid container item direction="row" spacing={24}>
+                    <Grid item>
+                        <Button variant="contained" onClick={() => removeAccountLinkData()}>
+                            Cancel
+                        </Button>
+                    </Grid>
+                    <Grid item>
+                        <Button disabled={status === LinkAccountPanelStatus.ERROR} color="primary" variant="contained" onClick={() => linkAccount()}>
+                            Link accounts
+                        </Button>
+                    </Grid>
                 </Grid>
-            </Grid>
-            </Grid>
+            </Grid> }
             </CardContent>
-        </Card>;
+        </Card> ;
 });
\ No newline at end of file