19675: Add instance types info box with panel description.
authorStephen Smith <stephen@curii.com>
Tue, 19 Dec 2023 20:29:58 +0000 (15:29 -0500)
committerStephen Smith <stephen@curii.com>
Tue, 19 Dec 2023 20:29:58 +0000 (15:29 -0500)
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen@curii.com>

services/workbench2/src/components/code-snippet/code-snippet.tsx
services/workbench2/src/views/instance-types-panel/instance-types-panel.tsx

index 5a5a7041d88a630717512e562060f3decaac1c2d..209dbc44b5d37d6221cc6a507fee1401f406dab9 100644 (file)
@@ -12,17 +12,24 @@ import { FederationConfig, getNavUrl } from 'routes/routes';
 import { Dispatch } from 'redux';
 import { navigationNotAvailable } from 'store/navigation/navigation-action';
 
-type CssRules = 'root' | 'space';
+type CssRules = 'root' | 'inlineRoot' | 'space' | 'inline';
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     root: {
         boxSizing: 'border-box',
         overflow: 'auto',
-        padding: theme.spacing.unit
+        padding: theme.spacing.unit,
+    },
+    inlineRoot: {
+        padding: "3px",
+        display: "inline",
     },
     space: {
-        marginLeft: '15px'
-    }
+        marginLeft: '15px',
+    },
+    inline: {
+        display: 'inline',
+    },
 });
 
 export interface CodeSnippetDataProps {
@@ -31,6 +38,7 @@ export interface CodeSnippetDataProps {
     apiResponse?: boolean;
     linked?: boolean;
     children?: JSX.Element;
+    inline?: boolean;
 }
 
 interface CodeSnippetAuthProps {
@@ -44,11 +52,11 @@ const mapStateToProps = (state: RootState): CodeSnippetAuthProps => ({
 });
 
 export const CodeSnippet = withStyles(styles)(connect(mapStateToProps)(
-    ({ classes, lines, linked, className, apiResponse, dispatch, auth, children }: CodeSnippetProps & CodeSnippetAuthProps & DispatchProp) =>
+    ({ classes, lines, linked, className, apiResponse, dispatch, auth, children, inline }: CodeSnippetProps & CodeSnippetAuthProps & DispatchProp) =>
         <Typography
         component="div"
-        className={classNames(classes.root, className)}>
-            <Typography className={apiResponse ? classes.space : className} component="pre">
+        className={classNames([classes.root, className, inline ? classes.inlineRoot: undefined])}>
+            <Typography className={apiResponse ? classes.space : classNames([className, inline ? classes.inline : undefined])} component="pre">
                 {children}
                 {linked ?
                     lines.map((line, index) => <React.Fragment key={index}>{renderLinks(auth, dispatch)(line)}{`\n`}</React.Fragment>) :
index 5afdd6296e64908b4e7e5792bfb2f046b5f20dfd..22617d8c8621b3de0f4f1954671a4d14e11b2d18 100644 (file)
@@ -12,14 +12,19 @@ import { ClusterConfigJSON } from 'common/config';
 import { NotFoundView } from 'views/not-found-panel/not-found-panel';
 import { formatCWLResourceSize, formatCost, formatFileSize } from 'common/formatters';
 import { DetailsAttribute } from 'components/details-attribute/details-attribute';
+import { DefaultCodeSnippet } from 'components/default-code-snippet/default-code-snippet';
 
-type CssRules = 'root' | 'instanceType';
+type CssRules = 'root' | 'infoBox' | 'instanceType';
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     root: {
-       width: '100%',
+       width: "calc(100% + 20px)",
+       margin: "0 -10px",
        overflow: 'auto'
     },
+    infoBox: {
+        padding: "0 10px 10px",
+    },
     instanceType: {
         padding: "10px",
     },
@@ -38,72 +43,89 @@ export const InstanceTypesPanel = withStyles(styles)(connect(mapStateToProps)(
 
         const instances = config.InstanceTypes || {};
 
-        return <Card className={classes.root}>
-            <CardContent>
-                <Grid container direction="row">
-                    {Object.keys(instances).length > 0 ?
-                        Object.keys(instances).sort((a, b) => {
-                            const typeA = instances[a];
-                            const typeB = instances[b];
+        return <Grid className={classes.root} container direction="row">
+            <Grid className={classes.infoBox} item xs={12}>
+                <Card>
+                    <CardContent>
+                        <Typography variant="body2">
+                            These are the cloud compute instance types
+                            configured for this cluster. The core count and
+                            maximum RAM request correspond to the greatest
+                            values you can put in the CWL Workflow
+                            ResourceRequest{" "}
+                            <DefaultCodeSnippet
+                                inline
+                                lines={["minCores"]}
+                            />{" "}
+                            and{" "}
+                            <DefaultCodeSnippet inline lines={["minRAM"]} />{" "}
+                            and still be scheduled on that instance type.
+                        </Typography>
+                    </CardContent>
+                </Card>
+            </Grid>
+            {Object.keys(instances).length > 0 ?
+                Object.keys(instances)
+                    .sort((a, b) => {
+                        const typeA = instances[a];
+                        const typeB = instances[b];
 
-                            if (typeA.Price !== typeB.Price) {
-                                return typeA.Price - typeB.Price;
-                            } else {
-                                return typeA.ProviderType.localeCompare(typeB.ProviderType);
-                            }
-                        }).map((instanceKey) => {
-                            const instanceType = instances[instanceKey];
-                            const diskRequest = instanceType.IncludedScratch;
-                            const ramRequest = instanceType.RAM - config.Containers.ReserveExtraRAM;
+                        if (typeA.Price !== typeB.Price) {
+                            return typeA.Price - typeB.Price;
+                        } else {
+                            return typeA.ProviderType.localeCompare(typeB.ProviderType);
+                        }
+                    }).map((instanceKey) => {
+                        const instanceType = instances[instanceKey];
+                        const diskRequest = instanceType.IncludedScratch;
+                        const ramRequest = instanceType.RAM - config.Containers.ReserveExtraRAM;
 
-                            return <Grid data-cy={instanceKey} className={classes.instanceType} item sm={6} xs={12} key={instanceKey}>
-                                <Card>
-                                    <CardContent>
-                                        <Typography variant="h6">
-                                            {instanceKey}
-                                        </Typography>
-                                        <Grid item xs={12}>
-                                            <DetailsAttribute label="Provider type" value={instanceType.ProviderType} />
-                                        </Grid>
-                                        <Grid item xs={12}>
-                                            <DetailsAttribute label="Price" value={instanceType.Price} />
-                                        </Grid>
-                                        <Grid item xs={12}>
-                                            <DetailsAttribute label="Cores" value={instanceType.VCPUs} />
-                                        </Grid>
-                                        <Grid item xs={12}>
-                                            <DetailsAttribute label="Max RAM request" value={`${formatCWLResourceSize(ramRequest)} (${formatFileSize(ramRequest)})`} />
-                                        </Grid>
-                                        <Grid item xs={12}>
-                                            <DetailsAttribute label="Max disk request" value={`${formatCWLResourceSize(diskRequest)} (${formatFileSize(diskRequest)})`} />
-                                        </Grid>
-                                        <Grid item xs={12}>
-                                            <DetailsAttribute label="Preemptible" value={instanceType.Preemptible.toString()} />
-                                        </Grid>
-                                        {instanceType.CUDA && instanceType.CUDA.DeviceCount > 0 ?
-                                            <>
-                                                <Grid item xs={12}>
-                                                    <DetailsAttribute label="CUDA GPUs" value={instanceType.CUDA.DeviceCount} />
-                                                </Grid>
-                                                <Grid item xs={12}>
-                                                    <DetailsAttribute label="Hardware capability" value={instanceType.CUDA.HardwareCapability} />
-                                                </Grid>
-                                                <Grid item xs={12}>
-                                                    <DetailsAttribute label="Driver version" value={instanceType.CUDA.DriverVersion} />
-                                                </Grid>
-                                            </> : <></>
-                                        }
-                                    </CardContent>
-                                </Card>
-                            </Grid>
-                        }) :
-                        <NotFoundView
-                            icon={ResourceIcon}
-                            messages={["No instances found"]}
-                        />
-                    }
-                </Grid>
-            </CardContent>
-        </Card>
+                        return <Grid data-cy={instanceKey} className={classes.instanceType} item sm={6} xs={12} key={instanceKey}>
+                            <Card>
+                                <CardContent>
+                                    <Typography variant="h6">
+                                        {instanceKey}
+                                    </Typography>
+                                    <Grid item xs={12}>
+                                        <DetailsAttribute label="Provider type" value={instanceType.ProviderType} />
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <DetailsAttribute label="Price" value={instanceType.Price} />
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <DetailsAttribute label="Cores" value={instanceType.VCPUs} />
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <DetailsAttribute label="Max RAM request" value={`${formatCWLResourceSize(ramRequest)} (${formatFileSize(ramRequest)})`} />
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <DetailsAttribute label="Max disk request" value={`${formatCWLResourceSize(diskRequest)} (${formatFileSize(diskRequest)})`} />
+                                    </Grid>
+                                    <Grid item xs={12}>
+                                        <DetailsAttribute label="Preemptible" value={instanceType.Preemptible.toString()} />
+                                    </Grid>
+                                    {instanceType.CUDA && instanceType.CUDA.DeviceCount > 0 ?
+                                        <>
+                                            <Grid item xs={12}>
+                                                <DetailsAttribute label="CUDA GPUs" value={instanceType.CUDA.DeviceCount} />
+                                            </Grid>
+                                            <Grid item xs={12}>
+                                                <DetailsAttribute label="Hardware capability" value={instanceType.CUDA.HardwareCapability} />
+                                            </Grid>
+                                            <Grid item xs={12}>
+                                                <DetailsAttribute label="Driver version" value={instanceType.CUDA.DriverVersion} />
+                                            </Grid>
+                                        </> : <></>
+                                    }
+                                </CardContent>
+                            </Card>
+                        </Grid>;
+                    }) :
+                <NotFoundView
+                    icon={ResourceIcon}
+                    messages={["No instances found"]}
+                />
+            }
+        </Grid>;
     }
 ));