import { bindDataExplorerActions } from '~/store/data-explorer/data-explorer-action';
import { formatDate } from "~/common/formatters";
import { unionize, ofType, UnionOf } from "~/common/unionize";
+import { VirtualMachinesLoginsResource } from '~/models/virtual-machines';
-export const virtualMachinesAction = unionize({
+export const virtualMachinesActions = unionize({
SET_REQUESTED_DATE: ofType<string>(),
+ SET_VIRTUAL_MACHINES: ofType<any>(),
+ SET_LOGINS: ofType<VirtualMachinesLoginsResource[]>()
});
-export type VirtualMachineActions = UnionOf<typeof virtualMachinesAction>;
+export type VirtualMachineActions = UnionOf<typeof virtualMachinesActions>;
export const VIRTUAL_MACHINES_PANEL = 'virtualMachinesPanel';
export const openVirtualMachines = () =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
- const virtualMachines = await services.virtualMachineService.list();
- // const logins = await services.virtualMachineService.logins(virtualMachines.items[0].uuid);
- // const getAllLogins = await services.virtualMachineService.getAllLogins();
- console.log(virtualMachines);
- // console.log(logins);
- // console.log(getAllLogins);
dispatch<any>(navigateToVirtualMachines);
};
-export const loadRequestedDate = () =>
+const loadRequestedDate = () =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
const date = services.virtualMachineService.getRequestedDate();
- dispatch(virtualMachinesAction.SET_REQUESTED_DATE(date));
+ dispatch(virtualMachinesActions.SET_REQUESTED_DATE(date));
+ };
+
+
+export const loadVirtualMachinesData = () =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ dispatch<any>(loadRequestedDate());
+ const virtualMachines = await services.virtualMachineService.list();
+ dispatch(virtualMachinesActions.SET_VIRTUAL_MACHINES(virtualMachines));
+ // const logins = await services.virtualMachineService.logins(virtualMachines.items[0].uuid);
+ // console.log(logins);
+ // const getAllLogins = await services.virtualMachineService.getAllLogins();
+ // console.log(getAllLogins);
+ // dispatch(virtualMachinesActions.SET_LOGINS(getAllLogins));
};
export const saveRequestedDate = () =>
dispatch<any>(loadRequestedDate());
};
-const virtualMachinesActions = bindDataExplorerActions(VIRTUAL_MACHINES_PANEL);
+const virtualMachinesBindedActions = bindDataExplorerActions(VIRTUAL_MACHINES_PANEL);
export const loadVirtualMachinesPanel = () =>
(dispatch: Dispatch) => {
- dispatch(virtualMachinesActions.REQUEST_ITEMS());
+ dispatch(virtualMachinesBindedActions.REQUEST_ITEMS());
};
import * as React from 'react';
import { connect } from 'react-redux';
-import { Grid, Typography, Button, Card, CardContent } from '@material-ui/core';
+import { Grid, Typography, Button, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table } from '@material-ui/core';
import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
import { ArvadosTheme } from '~/common/custom-theme';
import { DefaultCodeSnippet } from '~/components/default-code-snippet/default-code-snippet';
import { Link } from 'react-router-dom';
import { Dispatch } from 'redux';
-import { saveRequestedDate, loadRequestedDate } from '~/store/virtual-machines/virtual-machines-actions';
+import { saveRequestedDate, loadVirtualMachinesData } from '~/store/virtual-machines/virtual-machines-actions';
import { RootState } from '~/store/store';
+import { ListResults } from '~/services/common-service/common-resource-service';
+import { HelpIcon } from '~/components/icon/icon';
+import { VirtualMachinesLoginsResource } from '~/models/virtual-machines';
-type CssRules = 'button' | 'codeSnippet' | 'link';
+type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'icon';
const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
button: {
borderRadius: theme.spacing.unit * 0.5,
border: '1px solid',
borderColor: theme.palette.grey["400"],
- maxHeight: '400px'
},
link: {
textDecoration: 'none',
- color: theme.palette.primary.main
+ color: theme.palette.primary.main,
+ "&:hover": {
+ color: theme.palette.primary.dark,
+ transition: 'all 0.5s ease'
+ }
},
+ linkIcon: {
+ textDecoration: 'none',
+ color: theme.palette.grey["400"],
+ textAlign: 'right',
+ "&:hover": {
+ color: theme.palette.common.black,
+ transition: 'all 0.5s ease'
+ }
+ },
+ icon: {
+ textAlign: "right"
+ }
});
const mapStateToProps = (state: RootState) => {
return {
- requestedDate: state.virtualMachines.date
+ requestedDate: state.virtualMachines.date,
+ virtualMachines: state.virtualMachines.virtualMachines,
+ logins: state.virtualMachines.logins
};
};
const mapDispatchToProps = (dispatch: Dispatch) => ({
saveRequestedDate: () => dispatch<any>(saveRequestedDate()),
- loadRequestedDate: () => dispatch<any>(loadRequestedDate())
+ loadVirtualMachinesData: () => dispatch<any>(loadVirtualMachinesData())
});
interface VirtualMachinesPanelDataProps {
requestedDate: string;
+ virtualMachines: ListResults<any>;
+ logins: VirtualMachinesLoginsResource[];
}
interface VirtualMachinesPanelActionProps {
saveRequestedDate: () => void;
- loadRequestedDate: () => string;
+ loadVirtualMachinesData: () => string;
}
type VirtualMachineProps = VirtualMachinesPanelActionProps & VirtualMachinesPanelDataProps & WithStyles<CssRules>;
export const VirtualMachinePanel = withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(
class extends React.Component<VirtualMachineProps> {
componentDidMount() {
- this.props.loadRequestedDate();
+ this.props.loadVirtualMachinesData();
}
render() {
- const { classes, saveRequestedDate, requestedDate } = this.props;
+ const { classes, saveRequestedDate, requestedDate, virtualMachines, logins } = this.props;
return (
<Grid container spacing={16}>
<Grid item xs={12}>
<Card>
<CardContent>
- <Typography variant="body2">
- You do not have access to any virtual machines. Some Arvados features require using the command line. You may request access to a hosted virtual machine with the command line shell.
- </Typography>
- <Button variant="contained" color="primary" className={classes.button} onClick={saveRequestedDate}>
- SEND REQUEST FOR SHELL ACCESS
- </Button>
- {requestedDate &&
- <Typography variant="body1">
- A request for shell access was sent on {requestedDate}
- </Typography>}
+ {virtualMachines.itemsAvailable === 0
+ ? cardContentWithNoVirtualMachines(requestedDate, saveRequestedDate, classes)
+ : cardContentWithVirtualMachines(virtualMachines, classes)}
</CardContent>
</Card>
</Grid>
<Grid item xs={12}>
- <Card>
- <CardContent>
- <Typography variant="body2">
- In order to access virtual machines using SSH, <Link to='' className={classes.link}>add an SSH key to your account</Link> and add a section like this to your SSH configuration file ( ~/.ssh/config):
- </Typography>
- <DefaultCodeSnippet
- className={classes.codeSnippet}
- lines={[textSSH]} />
- </CardContent>
- </Card>
+ {cardSSHSection(classes)}
</Grid>
</Grid >
);
}
- }));
+ })
+);
+
+const cardContentWithNoVirtualMachines = (requestedDate: string, saveRequestedDate: () => void, classes: any) =>
+ <span>
+ <Typography variant="body2">
+ You do not have access to any virtual machines. Some Arvados features require using the command line. You may request access to a hosted virtual machine with the command line shell.
+ </Typography>
+ <Button variant="contained" color="primary" className={classes.button} onClick={saveRequestedDate}>
+ SEND REQUEST FOR SHELL ACCESS
+ </Button>
+ {requestedDate &&
+ <Typography variant="body1">
+ A request for shell access was sent on {requestedDate}
+ </Typography>}
+ </span>;
+
+const login = 'pawelkowalczyk';
+const cardContentWithVirtualMachines = (virtualMachines: ListResults<any>, classes: any) =>
+ <span>
+ <div className={classes.icon}>
+ <a href="https://doc.arvados.org/user/getting_started/vm-login-with-webshell.html" target="_blank" className={classes.linkIcon}>
+ <HelpIcon />
+ </a>
+ </div>
+ <Table>
+ <TableHead>
+ <TableRow>
+ <TableCell>Host name</TableCell>
+ <TableCell>Login name</TableCell>
+ <TableCell>Command line</TableCell>
+ <TableCell>Web shell</TableCell>
+ </TableRow>
+ </TableHead>
+ <TableBody>
+ {virtualMachines.items.map((it, index) =>
+ <TableRow key={index}>
+ <TableCell>{it.hostname}</TableCell>
+ <TableCell>{login}</TableCell>
+ <TableCell>ssh {login}@shell.arvados</TableCell>
+ <TableCell>
+ <a href={`https://workbench.c97qk.arvadosapi.com${it.href}/webshell/${login}`} target="_blank" className={classes.link}>
+ Log in as {login}
+ </a>
+ </TableCell>
+ </TableRow>
+ )}
+ </TableBody>
+ </Table>
+ </span >;
+// dodac link do ssh panelu jak juz bedzie
+const cardSSHSection = (classes: any) =>
+ <Card>
+ <CardContent>
+ <Typography variant="body2">
+ In order to access virtual machines using SSH, <Link to='' className={classes.link}>add an SSH key to your account</Link> and add a section like this to your SSH configuration file ( ~/.ssh/config):
+ </Typography>
+ <DefaultCodeSnippet
+ className={classes.codeSnippet}
+ lines={[textSSH]} />
+ </CardContent>
+ </Card>;
const textSSH = `Host *.arvados
TCPKeepAlive yes