import {
Card,
CardContent,
+ CircularProgress,
Grid,
StyleRulesCallback,
Table,
withStyles
} from '@material-ui/core';
import { ArvadosTheme } from '~/common/custom-theme';
-import { Session } from "~/models/session";
+import { Session, SessionStatus } from "~/models/session";
import Button from "@material-ui/core/Button";
-import { User } from "~/models/user";
-import { compose } from "redux";
-import { Field, InjectedFormProps, reduxForm, reset } from "redux-form";
+import { compose, Dispatch } from "redux";
+import { Field, FormErrors, InjectedFormProps, reduxForm, reset, stopSubmit } from "redux-form";
import { TextField } from "~/components/text-field/text-field";
import { addSession } from "~/store/auth/auth-action-session";
import { SITE_MANAGER_REMOTE_HOST_VALIDATION } from "~/validators/validators";
-type CssRules = 'root' | 'link' | 'buttonContainer' | 'table' | 'tableRow' | 'status' | 'remoteSiteInfo' | 'buttonAdd';
+type CssRules = 'root' | 'link' | 'buttonContainer' | 'table' | 'tableRow' |
+ 'remoteSiteInfo' | 'buttonAdd' | 'buttonLoggedIn' | 'buttonLoggedOut' |
+ 'statusCell';
const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
root: {
whiteSpace: 'nowrap'
}
},
- status: {
- width: 100,
- padding: 5,
- fontWeight: 'bold',
- textAlign: 'center',
- borderRadius: 4
+ statusCell: {
+ minWidth: 160
},
remoteSiteInfo: {
marginTop: 20
buttonAdd: {
marginLeft: 10,
marginTop: theme.spacing.unit * 3
+ },
+ buttonLoggedIn: {
+ minHeight: theme.spacing.unit,
+ padding: 5,
+ color: '#fff',
+ backgroundColor: '#009966',
+ '&:hover': {
+ backgroundColor: '#008450',
+ }
+ },
+ buttonLoggedOut: {
+ minHeight: theme.spacing.unit,
+ padding: 5,
+ color: '#000',
+ backgroundColor: '#FFC414',
+ '&:hover': {
+ backgroundColor: '#eaaf14',
+ }
}
});
export interface SiteManagerPanelRootActionProps {
+ toggleSession: (session: Session) => void;
}
export interface SiteManagerPanelRootDataProps {
sessions: Session[];
- user: User;
}
type SiteManagerPanelRootProps = SiteManagerPanelRootDataProps & SiteManagerPanelRootActionProps & WithStyles<CssRules> & InjectedFormProps;
const SITE_MANAGER_FORM_NAME = 'siteManagerForm';
+const submitSession = (remoteHost: string) =>
+ (dispatch: Dispatch) => {
+ dispatch<any>(addSession(remoteHost)).then(() => {
+ dispatch(reset(SITE_MANAGER_FORM_NAME));
+ }).catch((e: any) => {
+ const errors = {
+ remoteHost: e
+ } as FormErrors;
+ dispatch(stopSubmit(SITE_MANAGER_FORM_NAME, errors));
+ });
+ };
+
export const SiteManagerPanelRoot = compose(
reduxForm<{remoteHost: string}>({
form: SITE_MANAGER_FORM_NAME,
+ touchOnBlur: false,
onSubmit: (data, dispatch) => {
- dispatch(addSession(data.remoteHost));
- dispatch(reset(SITE_MANAGER_FORM_NAME));
+ dispatch(submitSession(data.remoteHost));
}
}),
withStyles(styles))
- (({ classes, sessions, handleSubmit }: SiteManagerPanelRootProps) =>
+ (({ classes, sessions, handleSubmit, toggleSession }: SiteManagerPanelRootProps) =>
<Card className={classes.root}>
<CardContent>
<Grid container direction="row">
<Grid item xs={12}>
- <Typography variant='body1' paragraph={true} >
+ <Typography paragraph={true} >
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.
</Typography>
</Grid>
</TableRow>
</TableHead>
<TableBody>
- {sessions.map((session, index) =>
- <TableRow key={index} className={classes.tableRow}>
+ {sessions.map((session, index) => {
+ const validating = session.status === SessionStatus.BEING_VALIDATED;
+ return <TableRow key={index} className={classes.tableRow}>
<TableCell>{session.clusterId}</TableCell>
- <TableCell>{session.username}</TableCell>
- <TableCell>{session.email}</TableCell>
- <TableCell>
- <div className={classes.status} style={{
- color: session.loggedIn ? '#fff' : '#000',
- backgroundColor: session.loggedIn ? '#009966' : '#FFC414'
- }}>
- {session.loggedIn ? "Logged in" : "Logged out"}
- </div>
+ <TableCell>{validating ? <CircularProgress size={20}/> : session.username}</TableCell>
+ <TableCell>{validating ? <CircularProgress size={20}/> : session.email}</TableCell>
+ <TableCell className={classes.statusCell}>
+ <Button fullWidth
+ disabled={validating || session.status === SessionStatus.INVALIDATED || session.active}
+ className={session.loggedIn ? classes.buttonLoggedIn : classes.buttonLoggedOut}
+ onClick={() => toggleSession(session)}>
+ {validating ? "Validating" : (session.loggedIn ? "Logged in" : "Logged out")}
+ </Button>
</TableCell>
- </TableRow>)}
+ </TableRow>;
+ })}
</TableBody>
</Table>}
</Grid>
<form onSubmit={handleSubmit}>
<Grid container direction="row">
<Grid item xs={12}>
- <Typography variant='body1' paragraph={true} className={classes.remoteSiteInfo}>
+ <Typography paragraph={true} className={classes.remoteSiteInfo}>
To add a remote Arvados site, paste the remote site's host here (see "ARVADOS_API_HOST" on the "current token" page).
</Typography>
</Grid>
component={TextField}
placeholder="zzzz.arvadosapi.com"
margin="normal"
- label="New cluster"/>
+ label="New cluster"
+ autoFocus/>
</Grid>
<Grid item xs={3}>
<Button type="submit" variant="contained" color="primary"