15088: Adds routing for link-account panel
[arvados-workbench2.git] / src / views / my-account-panel / my-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 { Field, InjectedFormProps, WrappedFieldProps } from "redux-form";
7 import { TextField } from "~/components/text-field/text-field";
8 import { NativeSelectField } from "~/components/select-field/select-field";
9 import { DetailsAttribute } from '~/components/details-attribute/details-attribute';
10 import {
11     StyleRulesCallback,
12     WithStyles,
13     withStyles,
14     Card,
15     CardContent,
16     Button,
17     Typography,
18     Grid,
19     InputLabel
20 } from '@material-ui/core';
21 import { ArvadosTheme } from '~/common/custom-theme';
22 import { User } from "~/models/user";
23 import { MY_ACCOUNT_VALIDATION } from "~/validators/validators";
24
25 type CssRules = 'root' | 'gridItem' | 'label' | 'title' | 'actions' | 'link';
26
27 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
28     root: {
29         width: '100%',
30         overflow: 'auto'
31     },
32     gridItem: {
33         height: 45,
34         marginBottom: 20
35     },
36     label: {
37         fontSize: '0.675rem'
38     },
39     title: {
40         marginBottom: theme.spacing.unit * 3,
41         color: theme.palette.grey["600"]
42     },
43     link: {
44         lineHeight:'2.1',
45         whiteSpace: 'nowrap',
46         fontSize: '1rem',
47         color: theme.palette.primary.main,
48         '&:hover': {
49             cursor: 'pointer'
50         }
51     },
52     actions: {
53         display: 'flex',
54         justifyContent: 'flex-end'
55     }
56 });
57
58 export interface MyAccountPanelRootActionProps {
59     openLinkAccount: () => void;
60  }
61
62 export interface MyAccountPanelRootDataProps {
63     isPristine: boolean;
64     isValid: boolean;
65     initialValues?: User;
66     localCluster: string;
67 }
68
69 const RoleTypes = [
70     { key: 'Bio-informatician', value: 'Bio-informatician' },
71     { key: 'Data Scientist', value: 'Data Scientist' },
72     { key: 'Analyst', value: 'Analyst' },
73     { key: 'Researcher', value: 'Researcher' },
74     { key: 'Software Developer', value: 'Software Developer' },
75     { key: 'System Administrator', value: 'System Administrator' },
76     { key: 'Other', value: 'Other' }
77 ];
78
79 type MyAccountPanelRootProps = InjectedFormProps & MyAccountPanelRootActionProps & MyAccountPanelRootDataProps & WithStyles<CssRules>;
80
81 type LocalClusterProp = { localCluster: string };
82 const renderField: React.ComponentType<WrappedFieldProps & LocalClusterProp> = ({ input, localCluster }) => (
83     <span>{localCluster === input.value.substr(0, 5) ? "" : "federated"} user {input.value}</span>
84 );
85
86 export const MyAccountPanelRoot = withStyles(styles)(
87     ({ classes, isValid, handleSubmit, reset, isPristine, invalid, submitting, localCluster, openLinkAccount}: MyAccountPanelRootProps) => {
88         return <Card className={classes.root}>
89             <CardContent>
90                 <Grid container spacing={24}>
91                     <Grid item className={classes.gridItem}>
92                         <Typography variant="title" className={classes.title}>
93                             Logged in as <Field name="uuid" component={renderField} localCluster={localCluster} />
94                         </Typography>
95                     </Grid>
96                     <Grid item className={classes.gridItem}>
97                         <span onClick={() => openLinkAccount()}>
98                             <DetailsAttribute classLabel={classes.link} label='Link account' />
99                         </span>
100                     </Grid>
101                 </Grid>
102                 <form onSubmit={handleSubmit}>
103                     <Grid container spacing={24}>
104                         <Grid item className={classes.gridItem} sm={6} xs={12}>
105                             <Field
106                                 label="First name"
107                                 name="firstName"
108                                 component={TextField}
109                                 disabled
110                             />
111                         </Grid>
112                         <Grid item className={classes.gridItem} sm={6} xs={12}>
113                             <Field
114                                 label="Last name"
115                                 name="lastName"
116                                 component={TextField}
117                                 disabled
118                             />
119                         </Grid>
120                         <Grid item className={classes.gridItem} sm={6} xs={12}>
121                             <Field
122                                 label="E-mail"
123                                 name="email"
124                                 component={TextField}
125                                 disabled
126                             />
127                         </Grid>
128                         <Grid item className={classes.gridItem} sm={6} xs={12}>
129                             <Field
130                                 label="Username"
131                                 name="username"
132                                 component={TextField}
133                                 disabled
134                             />
135                         </Grid>
136                         <Grid item className={classes.gridItem} sm={6} xs={12}>
137                             <Field
138                                 label="Organization"
139                                 name="prefs.profile.organization"
140                                 component={TextField}
141                                 validate={MY_ACCOUNT_VALIDATION}
142                                 required
143                             />
144                         </Grid>
145                         <Grid item className={classes.gridItem} sm={6} xs={12}>
146                             <Field
147                                 label="E-mail at Organization"
148                                 name="prefs.profile.organization_email"
149                                 component={TextField}
150                                 validate={MY_ACCOUNT_VALIDATION}
151                                 required
152                             />
153                         </Grid>
154                         <Grid item className={classes.gridItem} sm={6} xs={12}>
155                             <InputLabel className={classes.label} htmlFor="prefs.profile.role">Role</InputLabel>
156                             <Field
157                                 id="prefs.profile.role"
158                                 name="prefs.profile.role"
159                                 component={NativeSelectField}
160                                 items={RoleTypes}
161                             />
162                         </Grid>
163                         <Grid item className={classes.gridItem} sm={6} xs={12}>
164                             <Field
165                                 label="Website"
166                                 name="prefs.profile.website_url"
167                                 component={TextField}
168                             />
169                         </Grid>
170                         <Grid container direction="row" justify="flex-end" >
171                             <Button color="primary" onClick={reset} disabled={isPristine}>Discard changes</Button>
172                             <Button
173                                 color="primary"
174                                 variant="contained"
175                                 type="submit"
176                                 disabled={isPristine || invalid || submitting}>
177                                 Save changes
178                             </Button>
179                         </Grid>
180                     </Grid>
181                 </form >
182             </CardContent >
183         </Card >;
184     }
185 );