17782: Additional imports and typing fixes.
[arvados-workbench2.git] / src / views / virtual-machine-panel / virtual-machine-admin-panel.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
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';
17
18 type CssRules = 'moreOptionsButton' | 'moreOptions';
19
20 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
21     moreOptionsButton: {
22         padding: 0
23     },
24     moreOptions: {
25         textAlign: 'right',
26         '&:last-child': {
27             paddingRight: 0
28         }
29     },
30 });
31
32 const mapStateToProps = (state: RootState) => {
33     return {
34         userUuid: state.auth.user!.uuid,
35         ...state.virtualMachines
36     };
37 };
38
39 const mapDispatchToProps = (dispatch: Dispatch): Pick<VirtualMachinesPanelActionProps, 'loadVirtualMachinesData' | 'onOptionsMenuOpen'> => ({
40     loadVirtualMachinesData: () => dispatch<any>(loadVirtualMachinesAdminData()),
41     onOptionsMenuOpen: (event, virtualMachine) => {
42         dispatch<any>(openVirtualMachinesContextMenu(event, virtualMachine));
43     },
44 });
45
46 interface VirtualMachinesPanelDataProps {
47     virtualMachines: ListResults<any>;
48     logins: VirtualMachineLogins;
49     userUuid: string;
50 }
51
52 interface VirtualMachinesPanelActionProps {
53     loadVirtualMachinesData: () => string;
54     onOptionsMenuOpen: (event: React.MouseEvent<HTMLElement>, virtualMachine: VirtualMachinesResource) => void;
55 }
56
57 type VirtualMachineProps = VirtualMachinesPanelActionProps & VirtualMachinesPanelDataProps & WithStyles<CssRules>;
58
59 export const VirtualMachineAdminPanel = compose(
60     withStyles(styles),
61     connect(mapStateToProps, mapDispatchToProps))(
62         class extends React.Component<VirtualMachineProps> {
63             componentDidMount() {
64                 this.props.loadVirtualMachinesData();
65             }
66
67             render() {
68                 const { virtualMachines } = this.props;
69                 return (
70                     <Grid container spacing={16}>
71                         {virtualMachines.itemsAvailable > 0 && <CardContentWithVirtualMachines {...this.props} />}
72                     </Grid>
73                 );
74             }
75         }
76     );
77
78 const CardContentWithVirtualMachines = (props: VirtualMachineProps) =>
79     <Grid item xs={12}>
80         <Card>
81             <CardContent>
82                 {virtualMachinesTable(props)}
83             </CardContent>
84         </Card>
85     </Grid>;
86
87 const virtualMachinesTable = (props: VirtualMachineProps) =>
88     <Table>
89         <TableHead>
90             <TableRow>
91                 <TableCell>Uuid</TableCell>
92                 <TableCell>Host name</TableCell>
93                 <TableCell>Logins</TableCell>
94                 <TableCell />
95             </TableRow>
96         </TableHead>
97         <TableBody>
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}>
106                                 <MoreOptionsIcon />
107                             </IconButton>
108                         </Tooltip>
109                     </TableCell>
110                 </TableRow>
111             )}
112         </TableBody>
113     </Table>;