15088: Changes link account page times to local. Adds cancel snackbar.
[arvados-workbench2.git] / src / views / link-account-panel / link-account-panel-root.tsx
index 8661f6654a3be0b98f8d9623d4ff4cee0161493c..a5b1e35e053292d409a24b597a0c6c3712f8eb41 100644 (file)
@@ -11,6 +11,8 @@ import {
     CardContent,
     Button,
     Grid,
+    Select,
+    CircularProgress
 } from '@material-ui/core';
 import { ArvadosTheme } from '~/common/custom-theme';
 import { UserResource } from "~/models/user";
@@ -18,7 +20,7 @@ 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';
+type CssRules = 'root';
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     root: {
@@ -30,66 +32,128 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 export interface LinkAccountPanelRootDataProps {
     targetUser?: UserResource;
     userToLink?: UserResource;
+    remoteHosts:  { [key: string]: string };
+    hasRemoteHosts: boolean;
+    localCluster: string;
     status : LinkAccountPanelStatus;
     error: LinkAccountPanelError;
+    selectedCluster?: string;
+    isProcessing: boolean;
 }
 
 export interface LinkAccountPanelRootActionProps {
-    saveAccountLinkData: (type: LinkAccountType) => void;
+    startLinking: (type: LinkAccountType) => void;
     cancelLinking: () => void;
     linkAccount: () => void;
+    setSelectedCluster: (cluster: string) => void;
 }
 
-function displayUser(user: UserResource, showCreatedAt: boolean = false) {
+function displayUser(user: UserResource, showCreatedAt: boolean = false, showCluster: boolean = false) {
     const disp = [];
     disp.push(<span><b>{user.email}</b> ({user.username}, {user.uuid})</span>);
+    if (showCluster) {
+        const homeCluster = user.uuid.substr(0,5);
+        disp.push(<span> hosted on cluster <b>{homeCluster}</b> and </span>);
+    }
     if (showCreatedAt) {
         disp.push(<span> created on <b>{formatDate(user.createdAt)}</b></span>);
     }
     return disp;
 }
 
+function isLocalUser(uuid: string, localCluster: string) {
+    return uuid.substring(0, 5) === localCluster;
+}
+
 type LinkAccountPanelRootProps = LinkAccountPanelRootDataProps & LinkAccountPanelRootActionProps & WithStyles<CssRules>;
 
 export const LinkAccountPanelRoot = withStyles(styles) (
-    ({classes, targetUser, userToLink, status, error, saveAccountLinkData, cancelLinking, linkAccount}: LinkAccountPanelRootProps) => {
+    ({classes, targetUser, userToLink, status, isProcessing, error, startLinking, cancelLinking, linkAccount,
+      remoteHosts, hasRemoteHosts, selectedCluster, setSelectedCluster, localCluster}: LinkAccountPanelRootProps) => {
         return <Card className={classes.root}>
             <CardContent>
-            { status === LinkAccountPanelStatus.INITIAL && targetUser &&
-            <Grid container spacing={24}>
-                <Grid container item direction="column" spacing={24}>
-                    <Grid item>
-                        You are currently logged in as {displayUser(targetUser, true)}
-                    </Grid>
-                    <Grid item>
-                        You can link Arvados accounts. After linking, either login will take you to the same account.
-                    </Grid>
+            { isProcessing && <Grid container item direction="column" alignContent="center" spacing={24}>
+                <Grid item>
+                    Loading user info. Please wait.
                 </Grid>
-                <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 item style={{ alignSelf: 'center' }}>
+                    <CircularProgress/>
                 </Grid>
             </Grid> }
-            { (status === LinkAccountPanelStatus.LINKING || status === LinkAccountPanelStatus.ERROR) && userToLink && targetUser &&
+            { !isProcessing && status === LinkAccountPanelStatus.INITIAL && targetUser && <div>
+                { isLocalUser(targetUser.uuid, localCluster) ? <Grid container spacing={24}>
+                    <Grid container item direction="column" spacing={24}>
+                        <Grid item>
+                            You are currently logged in as {displayUser(targetUser, true)}
+                        </Grid>
+                        <Grid item>
+                            You can link Arvados accounts. After linking, either login will take you to the same account.
+                        </Grid >
+                    </Grid>
+                    <Grid container item direction="row" spacing={24}>
+                        <Grid item>
+                            <Button disabled={!targetUser.isActive} color="primary" variant="contained" onClick={() => startLinking(LinkAccountType.ADD_OTHER_LOGIN)}>
+                                Add another login to this account
+                            </Button>
+                        </Grid>
+                        <Grid item>
+                            <Button color="primary" variant="contained" onClick={() => startLinking(LinkAccountType.ACCESS_OTHER_ACCOUNT)}>
+                                Use this login to access another account
+                            </Button>
+                        </Grid>
+                    </Grid>
+                    { hasRemoteHosts && selectedCluster && <Grid container item direction="column" spacing={24}>
+                        <Grid item>
+                            You can also link {displayUser(targetUser, false)} with an account from a remote cluster.
+                        </Grid>
+                        <Grid item>
+                            Please select the cluster that hosts the account you want to link with:
+                                <Select id="remoteHostsDropdown" native defaultValue={selectedCluster} style={{ marginLeft: "1em" }}
+                                    onChange={(event) => setSelectedCluster(event.target.value)}>
+                                    {Object.keys(remoteHosts).map((k) => k !== localCluster ? <option key={k} value={k}>{k}</option> : null)}
+                                </Select>
+                            </Grid>
+                        <Grid item>
+                            <Button color="primary" variant="contained" onClick={() => startLinking(LinkAccountType.ACCESS_OTHER_REMOTE_ACCOUNT)}>
+                                Link with an account on&nbsp;{hasRemoteHosts ? <label>{selectedCluster} </label> : null}
+                            </Button>
+                        </Grid>
+                    </Grid> }
+                </Grid> :
+                <Grid container spacing={24}>
+                    <Grid container item direction="column" spacing={24}>
+                        <Grid item>
+                            You are currently logged in as {displayUser(targetUser, true, true)}
+                        </Grid>
+                        {targetUser.isActive ? <> <Grid item>
+                            This a remote account. You can link a local Arvados account to this one. After linking, you can access the local account's data by logging into the <b>{localCluster}</b> cluster with the <b>{targetUser.email}</b> account.
+                        </Grid >
+                        <Grid item>
+                            <Button color="primary" variant="contained" onClick={() => startLinking(LinkAccountType.ADD_LOCAL_TO_REMOTE)}>
+                                Link an account from {localCluster} to this account
+                            </Button>
+                        </Grid> </>
+                        : <Grid item>
+                          This an inactive remote account. An administrator must activate your account before you can proceed. After your accounts is activated, you can link a local Arvados account hosted by the <b>{localCluster}</b> cluster to this one.
+                        </Grid >}
+                    </Grid>
+                </Grid>}
+            </div> }
+            { !isProcessing && (status === LinkAccountPanelStatus.LINKING || status === LinkAccountPanelStatus.ERROR) && userToLink && targetUser &&
             <Grid container spacing={24}>
                 { status === LinkAccountPanelStatus.LINKING && <Grid container item direction="column" spacing={24}>
                     <Grid item>
-                        Clicking 'Link accounts' will link {displayUser(userToLink, true)} to {displayUser(targetUser, true)}.
+                        Clicking 'Link accounts' will link {displayUser(userToLink, true, !isLocalUser(targetUser.uuid, localCluster))} to {displayUser(targetUser, true, !isLocalUser(targetUser.uuid, localCluster))}.
                     </Grid>
-                    <Grid item>
+                    { (isLocalUser(targetUser.uuid, localCluster)) && <Grid item>
                         After linking, logging in as {displayUser(userToLink)} will log you into the same account as {displayUser(targetUser)}.
-                    </Grid>
+                    </Grid> }
                     <Grid item>
-                       Any object owned by {displayUser(userToLink)} will be transfered to {displayUser(targetUser)}.
+                        Any object owned by {displayUser(userToLink)} will be transfered to {displayUser(targetUser)}.
                     </Grid>
+                    { !isLocalUser(targetUser.uuid, localCluster) && <Grid item>
+                        You can access <b>{userToLink.email}</b> data by logging into <b>{localCluster}</b> with the <b>{targetUser.email}</b> account.
+                    </Grid> }
                 </Grid> }
                 { error === LinkAccountPanelError.NON_ADMIN && <Grid item>
                     Cannot link admin account {displayUser(userToLink)} to non-admin account {displayUser(targetUser)}.
@@ -98,7 +162,7 @@ export const LinkAccountPanelRoot = withStyles(styles) (
                     Cannot link {displayUser(targetUser)} to the same account.
                 </Grid> }
                 { error === LinkAccountPanelError.INACTIVE && <Grid item>
-                    Cannot link active account {displayUser(userToLink)} to inactive account {displayUser(targetUser)}.
+                    Cannot link account {displayUser(userToLink)} to inactive account {displayUser(targetUser)}.
                 </Grid> }
                 <Grid container item direction="row" spacing={24}>
                     <Grid item>
@@ -113,6 +177,6 @@ export const LinkAccountPanelRoot = withStyles(styles) (
                     </Grid>
                 </Grid>
             </Grid> }
-            </CardContent>
-        </Card> ;
+        </CardContent>
+    </Card>;
 });
\ No newline at end of file