19438: Finished adding fields
[arvados-workbench2.git] / src / views / process-panel / process-resource-card.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 {
7     StyleRulesCallback,
8     WithStyles,
9     withStyles,
10     Card,
11     CardHeader,
12     IconButton,
13     CardContent,
14     Tooltip,
15     Typography,
16     Grid,
17     CircularProgress,
18 } from '@material-ui/core';
19 import { ArvadosTheme } from 'common/custom-theme';
20 import {
21     CloseIcon,
22     MaximizeIcon,
23     UnMaximizeIcon,
24     ProcessIcon
25 } from 'components/icon/icon';
26 import { MPVPanelProps } from 'components/multi-panel-view/multi-panel-view';
27 import { connect } from 'react-redux';
28 import { Process } from 'store/processes/process';
29 import { NodeInstanceType } from 'store/process-panel/process-panel';
30 import { DefaultView } from 'components/default-view/default-view';
31 import { DetailsAttribute } from "components/details-attribute/details-attribute";
32 import { formatFileSize } from "common/formatters";
33 import { InputCollectionMount } from 'store/processes/processes-actions';
34 import { MountKind, TemporaryDirectoryMount } from 'models/mount-types';
35
36 interface ProcessResourceCardDataProps {
37     process: Process;
38     nodeInfo: NodeInstanceType | null;
39 }
40
41 type CssRules = "card" | "header" | "title" | "avatar" | "iconHeader" | "content" | "sectionH3";
42
43 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
44     card: {
45         height: '100%'
46     },
47     header: {
48         paddingBottom: "0px"
49     },
50     title: {},
51     avatar: {},
52     iconHeader: {},
53     content: {
54         paddingTop: "0px",
55         maxHeight: `calc(100% - ${theme.spacing.unit * 4.5}px)`,
56         overflow: "auto"
57     },
58     sectionH3: {
59         margin: "0.5em"
60     }
61 });
62
63 type ProcessResourceCardProps = ProcessResourceCardDataProps & WithStyles<CssRules> & MPVPanelProps;
64
65 export const ProcessResourceCard = withStyles(styles)(connect()(
66     ({ classes, nodeInfo, doHidePanel, doMaximizePanel, doUnMaximizePanel, panelMaximized, panelName, process, }: ProcessResourceCardProps) => {
67
68         const loading = false;
69
70         let diskRequest = 0;
71         if (process.container?.mounts) {
72             for (const mnt in process.container.mounts) {
73                 const mp = process.container.mounts[mnt];
74                 if (mp.kind === MountKind.TEMPORARY_DIRECTORY) {
75                     diskRequest += mp.capacity;
76                 }
77             }
78         }
79
80         return <Card className={classes.card} data-cy="process-resources-card">
81             <CardHeader
82                 className={classes.header}
83                 classes={{
84                     content: classes.title,
85                     avatar: classes.avatar,
86                 }}
87                 avatar={<ProcessIcon className={classes.iconHeader} />}
88                 title={
89                     <Typography noWrap variant='h6' color='inherit'>
90                         Resources
91                     </Typography>
92                 }
93                 action={
94                     <div>
95                         {doUnMaximizePanel && panelMaximized &&
96                             <Tooltip title={`Unmaximize ${panelName || 'panel'}`} disableFocusListener>
97                                 <IconButton onClick={doUnMaximizePanel}><UnMaximizeIcon /></IconButton>
98                             </Tooltip>}
99                         {doMaximizePanel && !panelMaximized &&
100                             <Tooltip title={`Maximize ${panelName || 'panel'}`} disableFocusListener>
101                                 <IconButton onClick={doMaximizePanel}><MaximizeIcon /></IconButton>
102                             </Tooltip>}
103                         {doHidePanel &&
104                             <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
105                                 <IconButton disabled={panelMaximized} onClick={doHidePanel}><CloseIcon /></IconButton>
106                             </Tooltip>}
107                     </div>
108                 } />
109             <CardContent className={classes.content}>
110                 <Grid container>
111                     <Grid item xs={4}>
112                         <h3 className={classes.sectionH3}>Requested resources</h3>
113                         <Grid container>
114                             <Grid item xs={12}>
115                                 <DetailsAttribute label="cores" value={process.container?.runtimeConstraints.vcpus} />
116                             </Grid>
117                             <Grid item xs={12}>
118                                 <DetailsAttribute label="RAM" value={formatFileSize(process.container?.runtimeConstraints.ram)} />
119                             </Grid>
120                             <Grid item xs={12}>
121                                 <DetailsAttribute label="Disk" value={formatFileSize(diskRequest)} />
122                             </Grid>
123                             <Grid item xs={12}>
124                                 <DetailsAttribute label="API access" value={process.container?.runtimeConstraints.API.toString()} />
125                             </Grid>
126
127                             {process.container?.runtimeConstraints.keep_cache_ram &&
128                                 process.container?.runtimeConstraints.keep_cache_ram > 0 ?
129                                 <Grid item xs={12}>
130                                     <DetailsAttribute label="Keep cache (RAM)" value={formatFileSize(process.container?.runtimeConstraints.keep_cache_ram)} />
131                                 </Grid> : null}
132
133                             {process.container?.runtimeConstraints.keep_cache_disk &&
134                                 process.container?.runtimeConstraints.keep_cache_disk > 0 ?
135                                 <Grid item xs={12}>
136                                     <DetailsAttribute label="Keep cache (disk)" value={formatFileSize(process.container?.runtimeConstraints.keep_cache_disk)} />
137                                 </Grid> : null}
138
139                             {process.container?.runtimeConstraints.cuda &&
140                                 process.container?.runtimeConstraints.cuda.device_count > 0 ?
141                                 <>
142                                     <Grid item xs={12}>
143                                         <DetailsAttribute label="CUDA devices" value={process.container?.runtimeConstraints.cuda.device_count} />
144                                     </Grid>
145                                     <Grid item xs={12}>
146                                         <DetailsAttribute label="CUDA driver version" value={process.container?.runtimeConstraints.cuda.driver_version} />
147                                     </Grid>
148                                     <Grid item xs={12}>
149                                         <DetailsAttribute label="CUDA hardware capability" value={process.container?.runtimeConstraints.cuda.hardware_capability} />
150                                     </Grid>
151                                 </> : null}
152                         </Grid>
153                     </Grid>
154
155
156                     <Grid item xs={8}>
157                         <h3 className={classes.sectionH3}>Assigned instance type</h3>
158                         {nodeInfo === null ? <Grid item xs={8}>
159                             No instance type recorded
160                         </Grid>
161                             :
162                             <Grid container>
163                                 <Grid item xs={6}>
164                                     <DetailsAttribute label="cores" value={nodeInfo.VCPUs} />
165                                 </Grid>
166
167                                 <Grid item xs={6}>
168                                     <DetailsAttribute label="Provider type" value={nodeInfo.ProviderType} />
169                                 </Grid>
170
171                                 <Grid item xs={6}>
172                                     <DetailsAttribute label="RAM" value={formatFileSize(nodeInfo.RAM)} />
173                                 </Grid>
174
175                                 <Grid item xs={6}>
176                                     <DetailsAttribute label="Price" value={"$" + nodeInfo.Price.toString()} />
177                                 </Grid>
178
179                                 <Grid item xs={6}>
180                                     <DetailsAttribute label="Included scratch disk" value={formatFileSize(nodeInfo.IncludedScratch)} />
181                                 </Grid>
182
183                                 <Grid item xs={6}>
184                                     <DetailsAttribute label="Preemptible" value={nodeInfo.Preemptible.toString()} />
185                                 </Grid>
186
187                                 <Grid item xs={6}>
188                                     <DetailsAttribute label="Added scratch disk" value={formatFileSize(nodeInfo.AddedScratch)} />
189                                 </Grid>
190
191                                 {nodeInfo.CUDA.DeviceCount > 0 &&
192                                     <>
193                                         <Grid item xs={6}>
194                                             <DetailsAttribute label="CUDA devices" value={formatFileSize(nodeInfo.CUDA.DeviceCount)} />
195                                         </Grid>
196                                         <Grid item xs={6}>
197                                             <DetailsAttribute label="CUDA driver version" value={formatFileSize(nodeInfo.CUDA.DriverVersion)} />
198                                         </Grid>
199                                         <Grid item xs={6}>
200                                             <DetailsAttribute label="CUDA hardware capability" value={formatFileSize(nodeInfo.CUDA.HardwareCapability)} />
201                                         </Grid>
202                                     </>
203                                 }
204                             </Grid>}
205                     </Grid>
206                 </Grid>
207             </CardContent>
208         </Card >;
209     }
210 ));