1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
6 import { connect } from 'react-redux';
7 import { Grid, Card, CardContent, TableBody, TableCell, TableHead, TableRow, Table, Tooltip, IconButton } from '@material-ui/core';
8 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
9 import { ArvadosTheme } from 'common/custom-theme';
10 import { compose, Dispatch } from 'redux';
11 import { loadVirtualMachinesAdminData } from 'store/virtual-machines/virtual-machines-actions';
12 import { RootState } from 'store/store';
13 import { ListResults } from 'services/common-service/common-service';
14 import { MoreOptionsIcon } from 'components/icon/icon';
15 import { VirtualMachineLogins, VirtualMachinesResource } from 'models/virtual-machines';
16 import { openVirtualMachinesContextMenu } from 'store/context-menu/context-menu-actions';
18 type CssRules = 'moreOptionsButton' | 'moreOptions';
20 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
32 const mapStateToProps = (state: RootState) => {
34 userUuid: state.auth.user!.uuid,
35 ...state.virtualMachines
39 const mapDispatchToProps = (dispatch: Dispatch): Pick<VirtualMachinesPanelActionProps, 'loadVirtualMachinesData' | 'onOptionsMenuOpen'> => ({
40 loadVirtualMachinesData: () => dispatch<any>(loadVirtualMachinesAdminData()),
41 onOptionsMenuOpen: (event, virtualMachine) => {
42 dispatch<any>(openVirtualMachinesContextMenu(event, virtualMachine));
46 interface VirtualMachinesPanelDataProps {
47 virtualMachines: ListResults<any>;
48 logins: VirtualMachineLogins;
52 interface VirtualMachinesPanelActionProps {
53 loadVirtualMachinesData: () => string;
54 onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, virtualMachine: VirtualMachinesResource) => void;
57 type VirtualMachineProps = VirtualMachinesPanelActionProps & VirtualMachinesPanelDataProps & WithStyles<CssRules>;
59 export const VirtualMachineAdminPanel = compose(
61 connect(mapStateToProps, mapDispatchToProps))(
62 class extends React.Component<VirtualMachineProps> {
64 this.props.loadVirtualMachinesData();
68 const { virtualMachines } = this.props;
70 <Grid container spacing={16}>
71 {virtualMachines.itemsAvailable > 0 && <CardContentWithVirtualMachines {...this.props} />}
78 const CardContentWithVirtualMachines = (props: VirtualMachineProps) =>
82 {virtualMachinesTable(props)}
87 const virtualMachinesTable = (props: VirtualMachineProps) =>
91 <TableCell>Uuid</TableCell>
92 <TableCell>Host name</TableCell>
93 <TableCell>Logins</TableCell>
98 {props.logins.items.length > 0 && props.virtualMachines.items.map((it, index) =>
99 <TableRow key={index}>
100 <TableCell>{it.uuid}</TableCell>
101 <TableCell>{it.hostname}</TableCell>
102 <TableCell>["{props.logins.items.map(it => it.userUuid === props.userUuid ? it.username : '')}"]</TableCell>
103 <TableCell className={props.classes.moreOptions}>
104 <Tooltip title="More options" disableFocusListener>
105 <IconButton onClick={event => props.onOptionsMenuOpen(event, it)} className={props.classes.moreOptionsButton}>