X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/95b86eb6b3184b787b570a906347ccaac32195c6..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 c94c3a74..5dbd3f09 100644 --- a/src/views/virtual-machine-panel/virtual-machine-panel.tsx +++ b/src/views/virtual-machine-panel/virtual-machine-panel.tsx @@ -4,20 +4,21 @@ 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, VirtualMachinesResource } 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' | 'rightAlign' | 'cardWithoutMachines' | 'icon'; +type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'rightAlign' | 'cardWithoutMachines' | 'icon' | 'moreOptionsButton' | 'moreOptions'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ button: { @@ -55,31 +56,47 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ icon: { textAlign: "right", marginTop: theme.spacing.unit - } + }, + moreOptionsButton: { + padding: 0 + }, + moreOptions: { + textAlign: 'right', + '&:last-child': { + paddingRight: 0 + } + }, }); -const mapStateToProps = ({ virtualMachines }: RootState) => { +const mapStateToProps = ({ virtualMachines, auth }: RootState) => { return { requestedDate: virtualMachines.date, + isAdmin: auth.user!.isAdmin, + logins: virtualMachines.logins, ...virtualMachines }; }; -const mapDispatchToProps = { - saveRequestedDate, - loadVirtualMachinesData -}; +const mapDispatchToProps = (dispatch: Dispatch): Pick => ({ + saveRequestedDate: () => dispatch(saveRequestedDate()), + 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; @@ -93,12 +110,12 @@ export const VirtualMachinePanel = compose( } render() { - const { virtualMachines, links } = this.props; + const { virtualMachines, links, isAdmin } = this.props; return ( - {virtualMachines.itemsAvailable === 0 && } + {!isAdmin && virtualMachines.itemsAvailable > 0 && } {virtualMachines.itemsAvailable > 0 && links.itemsAvailable > 0 && } - {} + {!isAdmin && } ); } @@ -131,53 +148,87 @@ const CardContentWithVirtualMachines = (props: VirtualMachineProps) => -
- - {props.requestedDate && - - A request for shell access was sent on {props.requestedDate} - } -
- - - - - Host name - Login name - Command line - Web shell - - - - {props.virtualMachines.items.map((it, index) => - - {it.hostname} - {getUsername(props.links, it)} - ssh {getUsername(props.links, it)}@shell.arvados - - - Log in as {getUsername(props.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: VirtualMachinesResource) => { - 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 = (props: VirtualMachineProps) =>