X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/944b7786dd97c8de8f7cb9eb7e6446fc2dda58fd..a1e2b8ba77e4a7273940a3fc542bc42e282618a7:/src/views/virtual-machine-panel/virtual-machine-panel.tsx diff --git a/src/views/virtual-machine-panel/virtual-machine-panel.tsx b/src/views/virtual-machine-panel/virtual-machine-panel.tsx index 65865370..5dbd3f09 100644 --- a/src/views/virtual-machine-panel/virtual-machine-panel.tsx +++ b/src/views/virtual-machine-panel/virtual-machine-panel.tsx @@ -4,25 +4,26 @@ import * as React from 'react'; import { connect } from 'react-redux'; -import { Grid, Typography, Button, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table, Tooltip } from '@material-ui/core'; +import { Grid, Typography, Button, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table, Tooltip, IconButton } 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, compose } from 'redux'; +import { compose, Dispatch } from 'redux'; 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'; +import { HelpIcon, MoreOptionsIcon } from '~/components/icon/icon'; +import { VirtualMachineLogins, VirtualMachinesResource } from '~/models/virtual-machines'; import { Routes } from '~/routes/routes'; +import { openVirtualMachinesContextMenu } from '~/store/context-menu/context-menu-actions'; -type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'icon'; +type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'rightAlign' | 'cardWithoutMachines' | 'icon' | 'moreOptionsButton' | 'moreOptions'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ button: { marginTop: theme.spacing.unit, - marginBottom: theme.spacing.unit * 2 + marginBottom: theme.spacing.unit }, codeSnippet: { borderRadius: theme.spacing.unit * 0.5, @@ -46,35 +47,56 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ transition: 'all 0.5s ease' } }, - icon: { + rightAlign: { textAlign: "right" - } + }, + cardWithoutMachines: { + display: 'flex' + }, + icon: { + textAlign: "right", + marginTop: theme.spacing.unit + }, + moreOptionsButton: { + padding: 0 + }, + moreOptions: { + textAlign: 'right', + '&:last-child': { + paddingRight: 0 + } + }, }); -const mapStateToProps = (state: RootState) => { +const mapStateToProps = ({ virtualMachines, auth }: RootState) => { return { - requestedDate: state.virtualMachines.date, - virtualMachines: state.virtualMachines.virtualMachines, - logins: state.virtualMachines.logins, - links: state.virtualMachines.links + requestedDate: virtualMachines.date, + isAdmin: auth.user!.isAdmin, + logins: virtualMachines.logins, + ...virtualMachines }; }; -const mapDispatchToProps = (dispatch: Dispatch) => ({ +const mapDispatchToProps = (dispatch: Dispatch): Pick => ({ saveRequestedDate: () => dispatch(saveRequestedDate()), - loadVirtualMachinesData: () => dispatch(loadVirtualMachinesData()) + loadVirtualMachinesData: () => dispatch(loadVirtualMachinesData()), + onOptionsMenuOpen: (event, virtualMachine) => { + dispatch(openVirtualMachinesContextMenu(event, virtualMachine)); + }, }); interface VirtualMachinesPanelDataProps { requestedDate: string; virtualMachines: ListResults; - logins: VirtualMachinesLoginsResource[]; + logins: VirtualMachineLogins; links: ListResults; + isAdmin: boolean; } interface VirtualMachinesPanelActionProps { saveRequestedDate: () => void; loadVirtualMachinesData: () => string; + onOptionsMenuOpen: (event: React.MouseEvent, virtualMachine: VirtualMachinesResource) => void; } type VirtualMachineProps = VirtualMachinesPanelActionProps & VirtualMachinesPanelDataProps & WithStyles; @@ -88,91 +110,136 @@ export const VirtualMachinePanel = compose( } render() { - const { classes, saveRequestedDate, requestedDate, virtualMachines, logins, links } = this.props; + const { virtualMachines, links, isAdmin } = this.props; return ( - {cardContentWithNoVirtualMachines(requestedDate, saveRequestedDate, classes)} - {virtualMachines.itemsAvailable > 0 && links.itemsAvailable > 0 && cardContentWithVirtualMachines(virtualMachines, links, classes)} - {cardSSHSection(classes)} + {!isAdmin && virtualMachines.itemsAvailable > 0 && } + {virtualMachines.itemsAvailable > 0 && links.itemsAvailable > 0 && } + {!isAdmin && } ); } } ); -const cardContentWithNoVirtualMachines = (requestedDate: string, saveRequestedDate: () => void, classes: any) => +const CardContentWithNoVirtualMachines = (props: VirtualMachineProps) => - - - 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. - - - {requestedDate && - - A request for shell access was sent on {requestedDate} - } + + + + 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. + + + + + {props.requestedDate && + + A request for shell access was sent on {props.requestedDate} + } + ; -const login = 'pawelkowalczyk'; - -const cardContentWithVirtualMachines = (virtualMachines: ListResults, links: ListResults, classes: any) => +const CardContentWithVirtualMachines = (props: VirtualMachineProps) => - - - - - Host name - Login name - Command line - Web shell - - - - {virtualMachines.items.map((it, index) => - - {it.hostname} - {getUsername(links, it)} - ssh {getUsername(links, it)}@shell.arvados - - - Log in as {getUsername(links, it)} - - - - )} - -
+ {props.isAdmin ? {adminVirtualMachinesTable(props)} + : +
+ + {props.requestedDate && + + A request for shell access was sent on {props.requestedDate} + } +
+ + {userVirtualMachinesTable(props)} +
+ }
; -const getUsername = (links: ListResults, virtualMachine: any) => { - const link = links.items.find((item: any) => item.headUuid === virtualMachine.uuid); - return link.properties.username || undefined; +const userVirtualMachinesTable = (props: VirtualMachineProps) => + + + + Host name + Login name + Command line + Web shell + + + + {props.virtualMachines.items.map((it, index) => + + {it.hostname} + {getUsername(props.links)} + ssh {getUsername(props.links)}@{it.hostname}.arvados + + + Log in as {getUsername(props.links)} + + + + )} + +
; + +const adminVirtualMachinesTable = (props: VirtualMachineProps) => + + + + Uuid + Host name + Logins + + + + + {props.logins.items.length > 0 && props.virtualMachines.items.map((it, index) => + + {it.uuid} + {it.hostname} + ["{props.logins.items[0].username}"] + + + props.onOptionsMenuOpen(event, it)} className={props.classes.moreOptionsButton}> + + + + + + )} + +
; + +const getUsername = (links: ListResults) => { + return links.items[0].properties.username; }; -const cardSSHSection = (classes: any) => +const CardSSHSection = (props: VirtualMachineProps) => - In order to access virtual machines using SSH, add an SSH key to your account and add a section like this to your SSH configuration file ( ~/.ssh/config): + In order to access virtual machines using SSH, add an SSH key to your account and add a section like this to your SSH configuration file ( ~/.ssh/config):