a64fdb25ae9b1c737aa4acdd3fd7ee3cfa878bf8
[arvados-workbench2.git] / src / views / site-manager-panel / site-manager-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     Card,
8     CardContent, CircularProgress,
9     Grid,
10     StyleRulesCallback,
11     Table,
12     TableBody,
13     TableCell,
14     TableHead,
15     TableRow,
16     Typography,
17     WithStyles,
18     withStyles
19 } from '@material-ui/core';
20 import { ArvadosTheme } from '~/common/custom-theme';
21 import { Session, SessionStatus } from "~/models/session";
22 import Button from "@material-ui/core/Button";
23 import { User } from "~/models/user";
24 import { compose } from "redux";
25 import { Field, FormErrors, InjectedFormProps, reduxForm, reset, stopSubmit } from "redux-form";
26 import { TextField } from "~/components/text-field/text-field";
27 import { addSession } from "~/store/auth/auth-action-session";
28 import { SITE_MANAGER_REMOTE_HOST_VALIDATION } from "~/validators/validators";
29 import {
30     RENAME_FILE_DIALOG,
31     RenameFileDialogData
32 } from "~/store/collection-panel/collection-panel-files/collection-panel-files-actions";
33
34 type CssRules = 'root' | 'link' | 'buttonContainer' | 'table' | 'tableRow' | 'status' | 'remoteSiteInfo' | 'buttonAdd';
35
36 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
37     root: {
38        width: '100%',
39        overflow: 'auto'
40     },
41     link: {
42         color: theme.palette.primary.main,
43         textDecoration: 'none',
44         margin: '0px 4px'
45     },
46     buttonContainer: {
47         textAlign: 'right'
48     },
49     table: {
50         marginTop: theme.spacing.unit
51     },
52     tableRow: {
53         '& td, th': {
54             whiteSpace: 'nowrap'
55         }
56     },
57     status: {
58         width: 100,
59         padding: 5,
60         fontWeight: 'bold',
61         textAlign: 'center',
62         borderRadius: 4
63     },
64     remoteSiteInfo: {
65         marginTop: 20
66     },
67     buttonAdd: {
68         marginLeft: 10,
69         marginTop: theme.spacing.unit * 3
70     }
71 });
72
73 export interface SiteManagerPanelRootActionProps {
74 }
75
76 export interface SiteManagerPanelRootDataProps {
77     sessions: Session[];
78     user: User;
79 }
80
81 type SiteManagerPanelRootProps = SiteManagerPanelRootDataProps & SiteManagerPanelRootActionProps & WithStyles<CssRules> & InjectedFormProps;
82 const SITE_MANAGER_FORM_NAME = 'siteManagerForm';
83
84 export const SiteManagerPanelRoot = compose(
85     reduxForm<{remoteHost: string}>({
86         form: SITE_MANAGER_FORM_NAME,
87         onSubmit: async (data, dispatch) => {
88             try {
89                 await dispatch(addSession(data.remoteHost));
90                 dispatch(reset(SITE_MANAGER_FORM_NAME));
91             } catch (e) {
92                 const errors = {
93                     remoteHost: e
94                 } as FormErrors;
95                 dispatch(stopSubmit(SITE_MANAGER_FORM_NAME, errors));
96             }
97
98         }
99     }),
100     withStyles(styles))
101     (({ classes, sessions, handleSubmit }: SiteManagerPanelRootProps) =>
102         <Card className={classes.root}>
103             <CardContent>
104                 <Grid container direction="row">
105                     <Grid item xs={12}>
106                         <Typography variant='body1' paragraph={true} >
107                             You can log in to multiple Arvados sites here, then use the multi-site search page to search collections and projects on all sites at once.
108                         </Typography>
109                     </Grid>
110                 </Grid>
111                 <Grid item xs={12}>
112                     {sessions.length > 0 && <Table className={classes.table}>
113                         <TableHead>
114                             <TableRow className={classes.tableRow}>
115                                 <TableCell>Cluster ID</TableCell>
116                                 <TableCell>Username</TableCell>
117                                 <TableCell>Email</TableCell>
118                                 <TableCell>Status</TableCell>
119                             </TableRow>
120                         </TableHead>
121                         <TableBody>
122                             {sessions.map((session, index) => {
123                                 const validating = session.status === SessionStatus.BEING_VALIDATED;
124                                 return <TableRow key={index} className={classes.tableRow}>
125                                     <TableCell>{session.clusterId}</TableCell>
126                                     <TableCell>{validating ? <CircularProgress size={20}/> : session.username}</TableCell>
127                                     <TableCell>{validating ? <CircularProgress size={20}/> : session.email}</TableCell>
128                                     <TableCell>
129                                         <div className={classes.status} style={{
130                                             color: session.loggedIn ? '#fff' : '#000',
131                                             backgroundColor: session.loggedIn ? '#009966' : '#FFC414'
132                                         }}>
133                                             {session.loggedIn ? "Logged in" : "Logged out"}
134                                         </div>
135                                     </TableCell>
136                                 </TableRow>;
137                             })}
138                         </TableBody>
139                     </Table>}
140                 </Grid>
141                 <form onSubmit={handleSubmit}>
142                     <Grid container direction="row">
143                         <Grid item xs={12}>
144                             <Typography variant='body1' paragraph={true} className={classes.remoteSiteInfo}>
145                                 To add a remote Arvados site, paste the remote site's host here (see "ARVADOS_API_HOST" on the "current token" page).
146                             </Typography>
147                         </Grid>
148                         <Grid item xs={8}>
149                             <Field
150                                 name='remoteHost'
151                                 validate={SITE_MANAGER_REMOTE_HOST_VALIDATION}
152                                 component={TextField}
153                                 placeholder="zzzz.arvadosapi.com"
154                                 margin="normal"
155                                 label="New cluster"
156                                 autoFocus/>
157                         </Grid>
158                         <Grid item xs={3}>
159                             <Button type="submit" variant="contained" color="primary"
160                                 className={classes.buttonAdd}>
161                                 {"ADD"}</Button>
162                         </Grid>
163                     </Grid>
164                 </form>
165             </CardContent>
166         </Card>
167     );