[arvados] created: 2.7.0-6275-g3a7e0c1b7d

git repository hosting git at public.arvados.org
Tue Apr 2 20:33:23 UTC 2024


        at  3a7e0c1b7de023461f90d41a1878ec43c3d187a9 (commit)


commit 3a7e0c1b7de023461f90d41a1878ec43c3d187a9
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 16:32:47 2024 -0400

    21508: Fix process io cypress tests, remove image preview test
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/cypress/e2e/process.cy.js b/services/workbench2/cypress/e2e/process.cy.js
index 2a5a62927f..33f820c50e 100644
--- a/services/workbench2/cypress/e2e/process.cy.js
+++ b/services/workbench2/cypress/e2e/process.cy.js
@@ -1279,6 +1279,7 @@ describe("Process tests", function () {
                 .contains(name)
                 .parents("tr")
                 .within($mainRow => {
+                    cy.get($mainRow).scrollIntoView();
                     label && cy.contains(label);
 
                     if (multipleRows) {
@@ -1444,11 +1445,11 @@ describe("Process tests", function () {
                     .parents("[data-cy=process-io-card]")
                     .within(ctx => {
                         cy.get(ctx).scrollIntoView();
-                        cy.get('[data-cy="io-preview-image-toggle"]').click({ waitForAnimations: false });
                         const outPdh = testOutputCollection.portable_data_hash;
 
                         verifyIOParameter("output_file", null, "Label Description", "cat.png", `${outPdh}`);
-                        verifyIOParameterImage("output_file", `/c=${outPdh}/cat.png`);
+                        // Disabled until image preview returns
+                        // verifyIOParameterImage("output_file", `/c=${outPdh}/cat.png`);
                         verifyIOParameter("output_file_with_secondary", null, "Doc Description", "main.dat", `${outPdh}`);
                         verifyIOParameter("output_file_with_secondary", null, "Doc Description", "secondary.dat", undefined, true);
                         verifyIOParameter("output_file_with_secondary", null, "Doc Description", "secondary2.dat", undefined, true);
diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index b0badd05cd..25bcb19e78 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -555,9 +555,11 @@ const ProcessIOPreview = memo(
         const showLabel = data.some((param: ProcessIOParameter) => param.label);
 
         const hasMoreValues = (index: number) => (
-            data[index+1] && !(data[index+1].id || data[index+1].label)
+            data[index+1] && !isMainRow(data[index+1])
         );
 
+        const isMainRow = (param: ProcessIOParameter) => (param && (param.id || param.label && !param.value.secondary));
+
         const RenderRow = ({index, style}) => {
             const param = data[index];
 
@@ -565,7 +567,10 @@ const ProcessIOPreview = memo(
                 [classes.noBorderRow]: hasMoreValues(index),
             };
 
-            return <TableRow style={style} className={classNames(rowClasses)}>
+            return <TableRow
+                style={style}
+                className={classNames(rowClasses)}
+                data-cy={isMainRow(param) ? "process-io-param" : ""}>
                 <TableCell>
                     <Tooltip title={param.id}>
                         <Typography className={classes.paramTableCellText}>

commit 648b0db5d0fedc67206c08625bfb42511b4ee23b
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 15:51:42 2024 -0400

    21508: Tweak io panel name column width
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index c485d2d9d9..b0badd05cd 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -159,6 +159,9 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
                 overflow: "hidden",
             },
             // Column width overrides
+            "& th:nth-of-type(1), & td:nth-of-type(1)": {
+                flexGrow: 0.7,
+            },
             "& th:nth-last-of-type(1), & td:nth-last-of-type(1)": {
                 flexGrow: 2,
             },

commit 5b15b2571f4ace6074ba30cee2195a616d196d97
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 15:28:34 2024 -0400

    21508: Add tooltip to external http/s files
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 31354bcce6..c485d2d9d9 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -69,6 +69,7 @@ import { DefaultCodeSnippet } from "components/default-code-snippet/default-code
 import { KEEP_URL_REGEX } from "models/resource";
 import { FixedSizeList } from 'react-window';
 import AutoSizer from "react-virtualized-auto-sizer";
+import { LinkProps } from "@material-ui/core/Link";
 
 type CssRules =
     | "card"
@@ -86,7 +87,8 @@ type CssRules =
     | "secondaryVal"
     | "emptyValue"
     | "noBorderRow"
-    | "symmetricTabs";
+    | "symmetricTabs"
+    | "wrapTooltip";
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     card: {
@@ -237,6 +239,10 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             flexBasis: "0",
         },
     },
+    wrapTooltip: {
+        maxWidth: "600px",
+        wordWrap: "break-word",
+    },
 });
 
 export enum ProcessIOCardType {
@@ -842,7 +848,7 @@ const KeepUrlBase = withStyles(styles)(({ auth, res, pdh, classes }: KeepUrlProp
     // Passing a pdh always returns a relative wb2 collection url
     const pdhWbPath = getNavUrl(pdhUrl, auth);
     return pdhUrl && pdhWbPath ? (
-        <Tooltip title={"View collection in Workbench"}>
+        <Tooltip title={<>View collection in Workbench<br />{pdhUrl}</>}>
             <RouterLink
                 to={pdhWbPath}
                 className={classes.keepLink}
@@ -862,7 +868,7 @@ const KeepUrlPath = withStyles(styles)(({ auth, res, pdh, classes }: KeepUrlProp
 
     const keepUrlPathNav = getKeepNavUrl(auth, res, pdh);
     return keepUrlPathNav ? (
-        <Tooltip title={"View in keep-web"}>
+        <Tooltip classes={{tooltip: classes.wrapTooltip}} title={<>View in keep-web<br />{keepUrlPath || "/"}</>}>
             <a
                 className={classes.keepLink}
                 href={keepUrlPathNav}
@@ -936,6 +942,16 @@ const directoryToProcessIOValue = (directory: Directory, auth: AuthState, pdh?:
     };
 };
 
+type MuiLinkWithTooltipProps = WithStyles<CssRules> & React.PropsWithChildren<LinkProps>;
+
+const MuiLinkWithTooltip = withStyles(styles)((props: MuiLinkWithTooltipProps) => (
+    <Tooltip title={props.title} classes={{tooltip: props.classes.wrapTooltip}}>
+        <MuiLink {...props}>
+            {props.children}
+        </MuiLink>
+    </Tooltip>
+));
+
 const fileToProcessIOValue = (file: File, secondary: boolean, auth: AuthState, pdh: string | undefined, mainFilePdh: string): ProcessIOValue => {
     if (isExternalValue(file)) {
         return { display: <UnsupportedValue /> };
@@ -944,13 +960,14 @@ const fileToProcessIOValue = (file: File, secondary: boolean, auth: AuthState, p
     if (isFileUrl(file.location)) {
         return {
             display: (
-                <MuiLink
+                <MuiLinkWithTooltip
                     href={file.location}
                     target="_blank"
                     rel="noopener"
+                    title={file.location}
                 >
                     {file.location}
-                </MuiLink>
+                </MuiLinkWithTooltip>
             ),
             secondary,
         };

commit 039f78f18f488844fa653038189ace482c3b52f6
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 13:54:44 2024 -0400

    21508: Add tooltip helpers for primitive & primitive array display
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
    
    21508: add guard
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index c53c4e37ba..31354bcce6 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -694,7 +694,7 @@ export const getIOParamDisplayValue = (auth: AuthState, input: CommandInputParam
         case isPrimitiveOfType(input, CWLType.BOOLEAN):
             const boolValue = (input as BooleanCommandInputParameter).value;
             return boolValue !== undefined && !(Array.isArray(boolValue) && boolValue.length === 0)
-                ? [{ display: renderPrimitiveValue(boolValue, false) }]
+                ? [{ display: <PrimitiveTooltip data={boolValue}>{renderPrimitiveValue(boolValue, false)}</PrimitiveTooltip> }]
                 : [{ display: <EmptyValue /> }];
 
         case isPrimitiveOfType(input, CWLType.INT):
@@ -703,20 +703,20 @@ export const getIOParamDisplayValue = (auth: AuthState, input: CommandInputParam
             return intValue !== undefined &&
                 // Missing values are empty array
                 !(Array.isArray(intValue) && intValue.length === 0)
-                ? [{ display: renderPrimitiveValue(intValue, false) }]
+                ? [{ display: <PrimitiveTooltip data={intValue}>{renderPrimitiveValue(intValue, false)}</PrimitiveTooltip> }]
                 : [{ display: <EmptyValue /> }];
 
         case isPrimitiveOfType(input, CWLType.FLOAT):
         case isPrimitiveOfType(input, CWLType.DOUBLE):
             const floatValue = (input as FloatCommandInputParameter).value;
             return floatValue !== undefined && !(Array.isArray(floatValue) && floatValue.length === 0)
-                ? [{ display: renderPrimitiveValue(floatValue, false) }]
+                ? [{ display: <PrimitiveTooltip data={floatValue}>{renderPrimitiveValue(floatValue, false)}</PrimitiveTooltip> }]
                 : [{ display: <EmptyValue /> }];
 
         case isPrimitiveOfType(input, CWLType.STRING):
             const stringValue = (input as StringCommandInputParameter).value || undefined;
             return stringValue !== undefined && !(Array.isArray(stringValue) && stringValue.length === 0)
-                ? [{ display: renderPrimitiveValue(stringValue, false) }]
+                ? [{ display: <PrimitiveTooltip data={stringValue}>{renderPrimitiveValue(stringValue, false)}</PrimitiveTooltip> }]
                 : [{ display: <EmptyValue /> }];
 
         case isPrimitiveOfType(input, CWLType.FILE):
@@ -737,21 +737,21 @@ export const getIOParamDisplayValue = (auth: AuthState, input: CommandInputParam
 
         case getEnumType(input) !== null:
             const enumValue = (input as EnumCommandInputParameter).value;
-            return enumValue !== undefined && enumValue ? [{ display: <pre>{enumValue}</pre> }] : [{ display: <EmptyValue /> }];
+            return enumValue !== undefined && enumValue ? [{ display: <PrimitiveTooltip data={enumValue}>{enumValue}</PrimitiveTooltip> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.STRING):
             const strArray = (input as StringArrayCommandInputParameter).value || [];
-            return strArray.length ? [{ display: <span>{strArray.map(val => renderPrimitiveValue(val, true))}</span> }] : [{ display: <EmptyValue /> }];
+            return strArray.length ? [{ display: <PrimitiveArrayTooltip data={strArray}>{strArray.map(val => renderPrimitiveValue(val, true))}</PrimitiveArrayTooltip> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.INT):
         case isArrayOfType(input, CWLType.LONG):
             const intArray = (input as IntArrayCommandInputParameter).value || [];
-            return intArray.length ? [{ display: <span>{intArray.map(val => renderPrimitiveValue(val, true))}</span> }] : [{ display: <EmptyValue /> }];
+            return intArray.length ? [{ display: <PrimitiveArrayTooltip data={intArray}>{intArray.map(val => renderPrimitiveValue(val, true))}</PrimitiveArrayTooltip> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.FLOAT):
         case isArrayOfType(input, CWLType.DOUBLE):
             const floatArray = (input as FloatArrayCommandInputParameter).value || [];
-            return floatArray.length ? [{ display: <span>{floatArray.map(val => renderPrimitiveValue(val, true))}</span> }] : [{ display: <EmptyValue /> }];
+            return floatArray.length ? [{ display: <PrimitiveArrayTooltip data={floatArray}>{floatArray.map(val => renderPrimitiveValue(val, true))}</PrimitiveArrayTooltip> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.FILE):
             const fileArrayMainFiles = (input as FileArrayCommandInputParameter).value || [];
@@ -779,6 +779,27 @@ export const getIOParamDisplayValue = (auth: AuthState, input: CommandInputParam
     }
 };
 
+interface PrimitiveTooltipProps {
+    data: boolean | number | string;
+}
+
+const PrimitiveTooltip = (props: React.PropsWithChildren<PrimitiveTooltipProps>) => (
+    <Tooltip title={typeof props.data !== 'object' ? String(props.data) : ""}>
+        <pre>{props.children}</pre>
+    </Tooltip>
+);
+
+interface PrimitiveArrayTooltipProps {
+    data: string[];
+}
+
+const PrimitiveArrayTooltip = (props: React.PropsWithChildren<PrimitiveArrayTooltipProps>) => (
+    <Tooltip title={props.data.join(', ')}>
+        <span>{props.children}</span>
+    </Tooltip>
+);
+
+
 const renderPrimitiveValue = (value: any, asChip: boolean) => {
     const isObject = typeof value === "object";
     if (!isObject) {
@@ -789,7 +810,7 @@ const renderPrimitiveValue = (value: any, asChip: boolean) => {
                 style={{marginRight: "10px"}}
             />
         ) : (
-            <pre key={value}>{String(value)}</pre>
+            <>{String(value)}</>
         );
     } else {
         return asChip ? <UnsupportedValueChip /> : <UnsupportedValue />;

commit b4a2c4b4767a76a6e2f3bf85e544e670a5de6e2f
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 11:53:03 2024 -0400

    21508: Fix panel container sizing and json tab scrollbars
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 8c8121062b..c53c4e37ba 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -106,7 +106,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     },
     // Card content
     content: {
-        height: `calc(100% - ${theme.spacing.unit * 7}px - ${theme.spacing.unit * 1.5}px)`,
+        height: `calc(100% - ${theme.spacing.unit * 6}px)`,
         padding: theme.spacing.unit * 1.0,
         paddingTop: 0,
         "&:last-child": {
@@ -123,7 +123,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     // Applies to each tab's content
     tableWrapper: {
         height: "auto",
-        maxHeight: `calc(100% - ${theme.spacing.unit * 3}px)`,
+        maxHeight: `calc(100% - ${theme.spacing.unit * 6}px)`,
         overflow: "auto",
         // Use flexbox to keep scrolling at the virtual list level
         display: "flex",
@@ -636,7 +636,7 @@ interface ProcessIORawDataProps {
 }
 
 const ProcessIORaw = withStyles(styles)(({ data }: ProcessIORawDataProps) => (
-    <Paper elevation={0} style={{width: "100%"}}>
+    <Paper elevation={0} style={{minWidth: "100%"}}>
         <DefaultCodeSnippet
             lines={[JSON.stringify(data, null, 2)]}
             linked

commit 2ac122244af90c2c85ab289a5ca807b954b00294
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 10:52:49 2024 -0400

    21508: Add wrappers to chips and move ellipsis styles to fix tooltip alignment
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 46e9cb8254..8c8121062b 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -172,20 +172,24 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
                 flexDirection: "row",
                 alignItems: "center",
                 whiteSpace: "nowrap",
-                '& pre': {
-                    margin: 0,
-                    overflow: "hidden",
-                    textOverflow: "ellipsis",
-                },
             },
         },
     },
     // Param value cell typography styles
     paramTableCellText: {
-        maxWidth: "100%",
-        whiteSpace: "nowrap",
         overflow: "hidden",
-        textOverflow: "ellipsis",
+        display: "flex",
+        // Every cell contents requires a wrapper for the ellipsis
+        // since adding ellipses to an anchor element parent results in misaligned tooltip
+        "& a, & span": {
+            overflow: "hidden",
+            textOverflow: "ellipsis",
+        },
+        '& pre': {
+            margin: 0,
+            overflow: "hidden",
+            textOverflow: "ellipsis",
+        },
     },
     mountsTableRoot: {
         width: "100%",
@@ -554,14 +558,22 @@ const ProcessIOPreview = memo(
 
             return <TableRow style={style} className={classNames(rowClasses)}>
                 <TableCell>
-                    <Typography className={classes.paramTableCellText}>
-                        {param.id}
-                    </Typography>
+                    <Tooltip title={param.id}>
+                        <Typography className={classes.paramTableCellText}>
+                            <span>
+                                {param.id}
+                            </span>
+                        </Typography>
+                    </Tooltip>
                 </TableCell>
                 {showLabel && <TableCell>
-                    <Typography className={classes.paramTableCellText}>
-                        {param.label}
-                    </Typography>
+                    <Tooltip title={param.label}>
+                        <Typography className={classes.paramTableCellText}>
+                            <span>
+                                {param.label}
+                            </span>
+                        </Typography>
+                    </Tooltip>
                 </TableCell>}
                 <TableCell>
                     <ProcessValuePreview
@@ -570,6 +582,7 @@ const ProcessIOPreview = memo(
                 </TableCell>
                 <TableCell>
                     <Typography className={classes.paramTableCellText}>
+                        {/** Collection is an anchor so doesn't require wrapper element */}
                         {param.value.collection}
                     </Typography>
                 </TableCell>
@@ -728,17 +741,17 @@ export const getIOParamDisplayValue = (auth: AuthState, input: CommandInputParam
 
         case isArrayOfType(input, CWLType.STRING):
             const strArray = (input as StringArrayCommandInputParameter).value || [];
-            return strArray.length ? [{ display: <>{strArray.map(val => renderPrimitiveValue(val, true))}</> }] : [{ display: <EmptyValue /> }];
+            return strArray.length ? [{ display: <span>{strArray.map(val => renderPrimitiveValue(val, true))}</span> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.INT):
         case isArrayOfType(input, CWLType.LONG):
             const intArray = (input as IntArrayCommandInputParameter).value || [];
-            return intArray.length ? [{ display: <>{intArray.map(val => renderPrimitiveValue(val, true))}</> }] : [{ display: <EmptyValue /> }];
+            return intArray.length ? [{ display: <span>{intArray.map(val => renderPrimitiveValue(val, true))}</span> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.FLOAT):
         case isArrayOfType(input, CWLType.DOUBLE):
             const floatArray = (input as FloatArrayCommandInputParameter).value || [];
-            return floatArray.length ? [{ display: <>{floatArray.map(val => renderPrimitiveValue(val, true))}</> }] : [{ display: <EmptyValue /> }];
+            return floatArray.length ? [{ display: <span>{floatArray.map(val => renderPrimitiveValue(val, true))}</span> }] : [{ display: <EmptyValue /> }];
 
         case isArrayOfType(input, CWLType.FILE):
             const fileArrayMainFiles = (input as FileArrayCommandInputParameter).value || [];

commit d190ac273c87a28ab270b460a1bbfd1898b4e5a7
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 09:56:19 2024 -0400

    21508: Rename class for clarity
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index a6086c6c57..46e9cb8254 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -79,8 +79,8 @@ type CssRules =
     | "iconHeader"
     | "tableWrapper"
     | "paramTableRoot"
+    | "paramTableCellText"
     | "mountsTableRoot"
-    | "value"
     | "keepLink"
     | "collectionLink"
     | "secondaryVal"
@@ -180,6 +180,13 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             },
         },
     },
+    // Param value cell typography styles
+    paramTableCellText: {
+        maxWidth: "100%",
+        whiteSpace: "nowrap",
+        overflow: "hidden",
+        textOverflow: "ellipsis",
+    },
     mountsTableRoot: {
         width: "100%",
         "& thead th": {
@@ -190,13 +197,6 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             paddingRight: "25px",
         },
     },
-    // Cell typography styles
-    value: {
-        maxWidth: "100%",
-        whiteSpace: "nowrap",
-        overflow: "hidden",
-        textOverflow: "ellipsis",
-    },
     keepLink: {
         color: theme.palette.primary.main,
         textDecoration: "none",
@@ -554,12 +554,12 @@ const ProcessIOPreview = memo(
 
             return <TableRow style={style} className={classNames(rowClasses)}>
                 <TableCell>
-                    <Typography className={classes.value}>
+                    <Typography className={classes.paramTableCellText}>
                         {param.id}
                     </Typography>
                 </TableCell>
                 {showLabel && <TableCell>
-                    <Typography className={classes.value}>
+                    <Typography className={classes.paramTableCellText}>
                         {param.label}
                     </Typography>
                 </TableCell>}
@@ -569,7 +569,7 @@ const ProcessIOPreview = memo(
                     />
                 </TableCell>
                 <TableCell>
-                    <Typography className={classes.value}>
+                    <Typography className={classes.paramTableCellText}>
                         {param.value.collection}
                     </Typography>
                 </TableCell>
@@ -613,7 +613,7 @@ interface ProcessValuePreviewProps {
 }
 
 const ProcessValuePreview = withStyles(styles)(({ value, classes }: ProcessValuePreviewProps & WithStyles<CssRules>) => (
-    <Typography className={classNames(classes.value, value.secondary && classes.secondaryVal)}>
+    <Typography className={classNames(classes.paramTableCellText, value.secondary && classes.secondaryVal)}>
         {value.display}
     </Typography>
 ));

commit 1f8dc0fa14b8095203638f27d36d548c8568152b
Author: Stephen Smith <stephen at curii.com>
Date:   Tue Apr 2 09:15:04 2024 -0400

    21508: Remove remaining io panel image preview code
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index a0f6c2e948..a6086c6c57 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -289,8 +289,6 @@ export const ProcessIOCard = withStyles(styles)(
                 setSubProcTabState(value);
             };
 
-            const [showImagePreview, setShowImagePreview] = useState(false);
-
             const PanelIcon = label === ProcessIOCardType.INPUT ? InputIcon : OutputIcon;
             const mainProcess = !(process && process!.containerRequest.requestingContainerUuid);
             const showParamTable = mainProcess || forceShowParams;
@@ -331,21 +329,6 @@ export const ProcessIOCard = withStyles(styles)(
                         }
                         action={
                             <div>
-                                {mainProcess && (
-                                    <Tooltip
-                                        title={"Toggle Image Preview"}
-                                        disableFocusListener
-                                    >
-                                        <IconButton
-                                            data-cy="io-preview-image-toggle"
-                                            onClick={() => {
-                                                setShowImagePreview(!showImagePreview);
-                                            }}
-                                        >
-                                            {showImagePreview ? <ImageIcon /> : <ImageOffIcon />}
-                                        </IconButton>
-                                    </Tooltip>
-                                )}
                                 {doUnMaximizePanel && panelMaximized && (
                                     <Tooltip
                                         title={`Unmaximize ${panelName || "panel"}`}
@@ -417,7 +400,6 @@ export const ProcessIOCard = withStyles(styles)(
                                             <div className={classes.tableWrapper}>
                                                 <ProcessIOPreview
                                                     data={params}
-                                                    showImagePreview={showImagePreview}
                                                     valueLabel={forceShowParams ? "Default value" : "Value"}
                                                 />
                                             </div>
@@ -550,14 +532,13 @@ export type ProcessIOParameter = {
 
 interface ProcessIOPreviewDataProps {
     data: ProcessIOParameter[];
-    showImagePreview: boolean;
     valueLabel: string;
 }
 
 type ProcessIOPreviewProps = ProcessIOPreviewDataProps & WithStyles<CssRules>;
 
 const ProcessIOPreview = memo(
-    withStyles(styles)(({ classes, data, showImagePreview, valueLabel }: ProcessIOPreviewProps) => {
+    withStyles(styles)(({ classes, data, valueLabel }: ProcessIOPreviewProps) => {
         const showLabel = data.some((param: ProcessIOParameter) => param.label);
 
         const hasMoreValues = (index: number) => (
@@ -585,7 +566,6 @@ const ProcessIOPreview = memo(
                 <TableCell>
                     <ProcessValuePreview
                         value={param.value}
-                        showImagePreview={showImagePreview}
                     />
                 </TableCell>
                 <TableCell>
@@ -630,10 +610,9 @@ const ProcessIOPreview = memo(
 
 interface ProcessValuePreviewProps {
     value: ProcessIOValue;
-    showImagePreview: boolean;
 }
 
-const ProcessValuePreview = withStyles(styles)(({ value, showImagePreview, classes }: ProcessValuePreviewProps & WithStyles<CssRules>) => (
+const ProcessValuePreview = withStyles(styles)(({ value, classes }: ProcessValuePreviewProps & WithStyles<CssRules>) => (
     <Typography className={classNames(classes.value, value.secondary && classes.secondaryVal)}>
         {value.display}
     </Typography>

commit 807876d53b4bc86fd78e3c1183a42ed317cb835d
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Apr 1 22:31:14 2024 -0400

    21508: Condense io panel css and remove redundant wrappers/rules
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 52da53fdc9..a0f6c2e948 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -80,8 +80,6 @@ type CssRules =
     | "tableWrapper"
     | "paramTableRoot"
     | "mountsTableRoot"
-    | "rowStyles"
-    | "valueWrapper"
     | "value"
     | "keepLink"
     | "collectionLink"
@@ -132,11 +130,12 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         flexDirection: "column",
         alignItems: "start", // Prevents scroll bars at different levels in json tab
     },
+
+    // Param table virtual list styles
     paramTableRoot: {
         display: "flex",
         flexDirection: "column",
         overflow: "hidden",
-
         // Flex header
         "& thead tr": {
             alignItems: "end",
@@ -162,14 +161,23 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
                 flexGrow: 2,
             },
         },
-        // Flex body cells
-        "& > tbody tr td": {
-            padding: "4px 25px 4px",
-            overflow: "auto hidden",
-            display: "flex",
-            flexDirection: "row",
-            alignItems: "center",
-            whiteSpace: "nowrap",
+        // Flex body rows
+        "& tbody tr": {
+            height: "40px",
+            // Flex body cells
+            "& td": {
+                padding: "2px 25px 2px",
+                overflow: "hidden",
+                display: "flex",
+                flexDirection: "row",
+                alignItems: "center",
+                whiteSpace: "nowrap",
+                '& pre': {
+                    margin: 0,
+                    overflow: "hidden",
+                    textOverflow: "ellipsis",
+                },
+            },
         },
     },
     mountsTableRoot: {
@@ -182,39 +190,12 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             paddingRight: "25px",
         },
     },
-    // Virtual list row styles
-    rowStyles: {
-        height: "40px",
-        "& td": {
-            paddingTop: "2px",
-            paddingBottom: "2px",
-        },
-    },
-    // Cell typography
-    valueWrapper: {
-        display: "flex",
-        alignItems: "center",
-        flexDirection: "row",
-        height: "100%",
-        overflow: "hidden",
-        '& pre': {
-            margin: 0,
-        },
-    },
+    // Cell typography styles
     value: {
-        display: "flex",
-        gap: "10px",
-        flexWrap: "wrap",
         maxWidth: "100%",
-        maxHeight: "100%",
         whiteSpace: "nowrap",
-        "& span": {
-            display: "inline",
-        },
-        "& a, & pre": {
-            overflow: "hidden",
-            textOverflow: "ellipsis",
-        },
+        overflow: "hidden",
+        textOverflow: "ellipsis",
     },
     keepLink: {
         color: theme.palette.primary.main,
@@ -588,12 +569,19 @@ const ProcessIOPreview = memo(
 
             const rowClasses = {
                 [classes.noBorderRow]: hasMoreValues(index),
-                [classes.rowStyles]: true,
             };
 
             return <TableRow style={style} className={classNames(rowClasses)}>
-                <TableCell>{param.id}</TableCell>
-                {showLabel && <TableCell>{param.label}</TableCell>}
+                <TableCell>
+                    <Typography className={classes.value}>
+                        {param.id}
+                    </Typography>
+                </TableCell>
+                {showLabel && <TableCell>
+                    <Typography className={classes.value}>
+                        {param.label}
+                    </Typography>
+                </TableCell>}
                 <TableCell>
                     <ProcessValuePreview
                         value={param.value}
@@ -601,10 +589,8 @@ const ProcessIOPreview = memo(
                     />
                 </TableCell>
                 <TableCell>
-                    <Typography className={classes.valueWrapper}>
-                        <span className={classes.value}>
-                            {param.value.collection}
-                        </span>
+                    <Typography className={classes.value}>
+                        {param.value.collection}
                     </Typography>
                 </TableCell>
             </TableRow>;
@@ -648,8 +634,8 @@ interface ProcessValuePreviewProps {
 }
 
 const ProcessValuePreview = withStyles(styles)(({ value, showImagePreview, classes }: ProcessValuePreviewProps & WithStyles<CssRules>) => (
-    <Typography className={classes.valueWrapper}>
-        <span className={classNames(classes.value, value.secondary && classes.secondaryVal)}>{value.display}</span>
+    <Typography className={classNames(classes.value, value.secondary && classes.secondaryVal)}>
+        {value.display}
     </Typography>
 ));
 
@@ -808,6 +794,7 @@ const renderPrimitiveValue = (value: any, asChip: boolean) => {
             <Chip
                 key={value}
                 label={String(value)}
+                style={{marginRight: "10px"}}
             />
         ) : (
             <pre key={value}>{String(value)}</pre>

commit 6886f23ec69c0baf38e91e8ea0038c4f581eee06
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Apr 1 21:08:07 2024 -0400

    21508: Fix io panel json content width
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index db950bffe0..52da53fdc9 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -658,7 +658,7 @@ interface ProcessIORawDataProps {
 }
 
 const ProcessIORaw = withStyles(styles)(({ data }: ProcessIORawDataProps) => (
-    <Paper elevation={0}>
+    <Paper elevation={0} style={{width: "100%"}}>
         <DefaultCodeSnippet
             lines={[JSON.stringify(data, null, 2)]}
             linked

commit 623a3a3e8309f5e5045359fbf891e9a690a9dfc7
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Apr 1 21:07:35 2024 -0400

    21508: Add helpful comments to styles
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index a12d9918da..db950bffe0 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -106,6 +106,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         alignSelf: "flex-start",
         paddingTop: theme.spacing.unit * 0.5,
     },
+    // Card content
     content: {
         height: `calc(100% - ${theme.spacing.unit * 7}px - ${theme.spacing.unit * 1.5}px)`,
         padding: theme.spacing.unit * 1.0,
@@ -114,12 +115,14 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             paddingBottom: theme.spacing.unit * 1,
         },
     },
+    // Card title
     title: {
         overflow: "hidden",
         paddingTop: theme.spacing.unit * 0.5,
         color: theme.customs.colors.greyD,
         fontSize: "1.875rem",
     },
+    // Applies to each tab's content
     tableWrapper: {
         height: "auto",
         maxHeight: `calc(100% - ${theme.spacing.unit * 3}px)`,
@@ -134,6 +137,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         flexDirection: "column",
         overflow: "hidden",
 
+        // Flex header
         "& thead tr": {
             alignItems: "end",
             "& th": {
@@ -143,18 +147,22 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         "& tbody": {
             height: "100vh", // Must be constrained by panel maxHeight
         },
+        // Flex header/body rows
         "& thead tr, & > tbody tr": {
             display: "flex",
+            // Flex header/body cells
             "& th, & td": {
                 flexGrow: 1,
                 flexShrink: 1,
                 flexBasis: 0,
                 overflow: "hidden",
             },
+            // Column width overrides
             "& th:nth-last-of-type(1), & td:nth-last-of-type(1)": {
                 flexGrow: 2,
             },
         },
+        // Flex body cells
         "& > tbody tr td": {
             padding: "4px 25px 4px",
             overflow: "auto hidden",
@@ -174,6 +182,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             paddingRight: "25px",
         },
     },
+    // Virtual list row styles
     rowStyles: {
         height: "40px",
         "& td": {
@@ -181,6 +190,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             paddingBottom: "2px",
         },
     },
+    // Cell typography
     valueWrapper: {
         display: "flex",
         alignItems: "center",
@@ -213,6 +223,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         overflowWrap: "break-word",
         cursor: "pointer",
     },
+    // Output collection tab link
     collectionLink: {
         margin: "10px",
         "& a": {

commit 561e80264b0a9df86f5ce1e1a5a388bb53d11bc6
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Apr 1 21:06:33 2024 -0400

    21508: Add virtual list to io panel and styles to make sizing behave
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 7a39af6fe1..a12d9918da 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -67,6 +67,8 @@ import { navigateTo } from "store/navigation/navigation-action";
 import classNames from "classnames";
 import { DefaultCodeSnippet } from "components/default-code-snippet/default-code-snippet";
 import { KEEP_URL_REGEX } from "models/resource";
+import { FixedSizeList } from 'react-window';
+import AutoSizer from "react-virtualized-auto-sizer";
 
 type CssRules =
     | "card"
@@ -76,22 +78,17 @@ type CssRules =
     | "avatar"
     | "iconHeader"
     | "tableWrapper"
-    | "paramValue"
     | "paramTableRoot"
     | "mountsTableRoot"
+    | "rowStyles"
+    | "valueWrapper"
+    | "value"
     | "keepLink"
     | "collectionLink"
-    | "imagePreview"
-    | "valArray"
     | "secondaryVal"
-    | "secondaryRow"
     | "emptyValue"
     | "noBorderRow"
-    | "symmetricTabs"
-    | "imagePlaceholder"
-    | "rowWithPreview"
-    | "labelColumn"
-    | "primaryRow";
+    | "symmetricTabs";
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     card: {
@@ -127,15 +124,44 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         height: "auto",
         maxHeight: `calc(100% - ${theme.spacing.unit * 3}px)`,
         overflow: "auto",
+        // Use flexbox to keep scrolling at the virtual list level
+        display: "flex",
+        flexDirection: "column",
+        alignItems: "start", // Prevents scroll bars at different levels in json tab
     },
     paramTableRoot: {
-        width: "100%",
-        "& thead th": {
-            verticalAlign: "bottom",
-            paddingBottom: "10px",
+        display: "flex",
+        flexDirection: "column",
+        overflow: "hidden",
+
+        "& thead tr": {
+            alignItems: "end",
+            "& th": {
+                padding: "4px 25px 10px",
+            },
         },
-        "& td, & th": {
-            paddingRight: "25px",
+        "& tbody": {
+            height: "100vh", // Must be constrained by panel maxHeight
+        },
+        "& thead tr, & > tbody tr": {
+            display: "flex",
+            "& th, & td": {
+                flexGrow: 1,
+                flexShrink: 1,
+                flexBasis: 0,
+                overflow: "hidden",
+            },
+            "& th:nth-last-of-type(1), & td:nth-last-of-type(1)": {
+                flexGrow: 2,
+            },
+        },
+        "& > tbody tr td": {
+            padding: "4px 25px 4px",
+            overflow: "auto hidden",
+            display: "flex",
+            flexDirection: "row",
+            alignItems: "center",
+            whiteSpace: "nowrap",
         },
     },
     mountsTableRoot: {
@@ -148,17 +174,42 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             paddingRight: "25px",
         },
     },
-    paramValue: {
+    rowStyles: {
+        height: "40px",
+        "& td": {
+            paddingTop: "2px",
+            paddingBottom: "2px",
+        },
+    },
+    valueWrapper: {
         display: "flex",
-        alignItems: "flex-start",
-        flexDirection: "column",
+        alignItems: "center",
+        flexDirection: "row",
+        height: "100%",
+        overflow: "hidden",
         '& pre': {
             margin: 0,
         },
     },
+    value: {
+        display: "flex",
+        gap: "10px",
+        flexWrap: "wrap",
+        maxWidth: "100%",
+        maxHeight: "100%",
+        whiteSpace: "nowrap",
+        "& span": {
+            display: "inline",
+        },
+        "& a, & pre": {
+            overflow: "hidden",
+            textOverflow: "ellipsis",
+        },
+    },
     keepLink: {
         color: theme.palette.primary.main,
         textDecoration: "none",
+        // Overflow wrap for mounts table
         overflowWrap: "break-word",
         cursor: "pointer",
     },
@@ -171,28 +222,9 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             cursor: "pointer",
         },
     },
-    imagePreview: {
-        maxHeight: "15em",
-        maxWidth: "15em",
-        marginBottom: theme.spacing.unit,
-    },
-    valArray: {
-        display: "flex",
-        gap: "10px",
-        flexWrap: "wrap",
-        "& span": {
-            display: "inline",
-        },
-    },
     secondaryVal: {
         paddingLeft: "20px",
     },
-    secondaryRow: {
-        height: "24px",
-        verticalAlign: "top",
-        position: "relative",
-        top: "-4px",
-    },
     emptyValue: {
         color: theme.customs.colors.grey700,
     },
@@ -209,28 +241,6 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
             flexBasis: "0",
         },
     },
-    imagePlaceholder: {
-        width: "60px",
-        height: "60px",
-        display: "flex",
-        alignItems: "center",
-        justifyContent: "center",
-        backgroundColor: "#cecece",
-        borderRadius: "10px",
-    },
-    rowWithPreview: {
-        verticalAlign: "bottom",
-    },
-    labelColumn: {
-        minWidth: "120px",
-    },
-    primaryRow: {
-        height: "26px",
-        "& td": {
-            paddingTop: "2px",
-            paddingBottom: "2px",
-        },
-    },
 });
 
 export enum ProcessIOCardType {
@@ -557,6 +567,38 @@ type ProcessIOPreviewProps = ProcessIOPreviewDataProps & WithStyles<CssRules>;
 const ProcessIOPreview = memo(
     withStyles(styles)(({ classes, data, showImagePreview, valueLabel }: ProcessIOPreviewProps) => {
         const showLabel = data.some((param: ProcessIOParameter) => param.label);
+
+        const hasMoreValues = (index: number) => (
+            data[index+1] && !(data[index+1].id || data[index+1].label)
+        );
+
+        const RenderRow = ({index, style}) => {
+            const param = data[index];
+
+            const rowClasses = {
+                [classes.noBorderRow]: hasMoreValues(index),
+                [classes.rowStyles]: true,
+            };
+
+            return <TableRow style={style} className={classNames(rowClasses)}>
+                <TableCell>{param.id}</TableCell>
+                {showLabel && <TableCell>{param.label}</TableCell>}
+                <TableCell>
+                    <ProcessValuePreview
+                        value={param.value}
+                        showImagePreview={showImagePreview}
+                    />
+                </TableCell>
+                <TableCell>
+                    <Typography className={classes.valueWrapper}>
+                        <span className={classes.value}>
+                            {param.value.collection}
+                        </span>
+                    </Typography>
+                </TableCell>
+            </TableRow>;
+        };
+
         return (
             <Table
                 className={classes.paramTableRoot}
@@ -565,12 +607,24 @@ const ProcessIOPreview = memo(
                 <TableHead>
                     <TableRow>
                         <TableCell>Name</TableCell>
-                        {showLabel && <TableCell className={classes.labelColumn}>Label</TableCell>}
+                        {showLabel && <TableCell>Label</TableCell>}
                         <TableCell>{valueLabel}</TableCell>
                         <TableCell>Collection</TableCell>
                     </TableRow>
                 </TableHead>
                 <TableBody>
+                    <AutoSizer>
+                        {({ height, width }) =>
+                            <FixedSizeList
+                                height={height}
+                                itemCount={data.length}
+                                itemSize={40}
+                                width={width}
+                            >
+                                {RenderRow}
+                            </FixedSizeList>
+                        }
+                    </AutoSizer>
                 </TableBody>
             </Table>
         );
@@ -583,8 +637,8 @@ interface ProcessValuePreviewProps {
 }
 
 const ProcessValuePreview = withStyles(styles)(({ value, showImagePreview, classes }: ProcessValuePreviewProps & WithStyles<CssRules>) => (
-    <Typography className={classes.paramValue}>
-        <span className={classNames(classes.valArray, value.secondary && classes.secondaryVal)}>{value.display}</span>
+    <Typography className={classes.valueWrapper}>
+        <span className={classNames(classes.value, value.secondary && classes.secondaryVal)}>{value.display}</span>
     </Typography>
 ));
 

commit cbf5da01288da63a4f83282384fa7cdebbb2c5e0
Author: Stephen Smith <stephen at curii.com>
Date:   Sun Apr 7 15:48:00 2024 -0400

    21508: Split mounts and param table styles
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index fcc6d6493b..7a39af6fe1 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -76,8 +76,9 @@ type CssRules =
     | "avatar"
     | "iconHeader"
     | "tableWrapper"
-    | "tableRoot"
     | "paramValue"
+    | "paramTableRoot"
+    | "mountsTableRoot"
     | "keepLink"
     | "collectionLink"
     | "imagePreview"
@@ -127,7 +128,17 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         maxHeight: `calc(100% - ${theme.spacing.unit * 3}px)`,
         overflow: "auto",
     },
-    tableRoot: {
+    paramTableRoot: {
+        width: "100%",
+        "& thead th": {
+            verticalAlign: "bottom",
+            paddingBottom: "10px",
+        },
+        "& td, & th": {
+            paddingRight: "25px",
+        },
+    },
+    mountsTableRoot: {
         width: "100%",
         "& thead th": {
             verticalAlign: "bottom",
@@ -548,7 +559,7 @@ const ProcessIOPreview = memo(
         const showLabel = data.some((param: ProcessIOParameter) => param.label);
         return (
             <Table
-                className={classes.tableRoot}
+                className={classes.paramTableRoot}
                 aria-label="Process IO Preview"
             >
                 <TableHead>
@@ -601,7 +612,7 @@ const ProcessInputMounts = withStyles(styles)(
         auth: state.auth,
     }))(({ mounts, classes, auth }: ProcessInputMountsProps & { auth: AuthState }) => (
         <Table
-            className={classes.tableRoot}
+            className={classes.mountsTableRoot}
             aria-label="Process Input Mounts"
         >
             <TableHead>

commit 08eb10445bdda427d52ccc9d070a989b3fd4aa59
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Apr 1 10:41:35 2024 -0400

    21508: Remove image preview from io panel
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index e7eb43c24c..fcc6d6493b 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -573,17 +573,6 @@ interface ProcessValuePreviewProps {
 
 const ProcessValuePreview = withStyles(styles)(({ value, showImagePreview, classes }: ProcessValuePreviewProps & WithStyles<CssRules>) => (
     <Typography className={classes.paramValue}>
-        {value.imageUrl && showImagePreview ? (
-            <img
-                className={classes.imagePreview}
-                src={value.imageUrl}
-                crossOrigin="anonymous"
-                alt="Inline Preview"
-            />
-        ) : (
-            ""
-        )}
-        {value.imageUrl && !showImagePreview ? <ImagePlaceholder /> : ""}
         <span className={classNames(classes.valArray, value.secondary && classes.secondaryVal)}>{value.display}</span>
     </Typography>
 ));
@@ -927,9 +916,3 @@ const UnsupportedValueChip = withStyles(styles)(({ classes }: WithStyles<CssRule
         label={"Cannot display value"}
     />
 ));
-
-const ImagePlaceholder = withStyles(styles)(({ classes }: WithStyles<CssRules>) => (
-    <span className={classes.imagePlaceholder}>
-        <ImageIcon />
-    </span>
-));

commit 9c5068adca5044058518667e981000c3913673b8
Author: Stephen Smith <stephen at curii.com>
Date:   Fri Mar 29 19:34:05 2024 -0400

    21508: Expand secondary param values into separate parameters
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/store/process-panel/process-panel-actions.ts b/services/workbench2/src/store/process-panel/process-panel-actions.ts
index 82c267c7a0..60a477dd05 100644
--- a/services/workbench2/src/store/process-panel/process-panel-actions.ts
+++ b/services/workbench2/src/store/process-panel/process-panel-actions.ts
@@ -189,12 +189,13 @@ export const initProcessPanelFilters = processPanelActions.SET_PROCESS_PANEL_FIL
 ]);
 
 export const formatInputData = (inputs: CommandInputParameter[], auth: AuthState): ProcessIOParameter[] => {
-    return inputs.map(input => {
-        return {
-            id: getIOParamId(input),
-            label: input.label || "",
-            value: getIOParamDisplayValue(auth, input),
-        };
+    return inputs.flatMap((input): ProcessIOParameter[] => {
+        const processValues = getIOParamDisplayValue(auth, input);
+        return processValues.map((thisValue, i) => ({
+            id: i === 0 ? getIOParamId(input) : "",
+            label: i === 0 ? input.label || "" : "",
+            value: thisValue,
+        }));
     });
 };
 
@@ -204,11 +205,12 @@ export const formatOutputData = (
     pdh: string | undefined,
     auth: AuthState
 ): ProcessIOParameter[] => {
-    return definitions.map(output => {
-        return {
-            id: getIOParamId(output),
-            label: output.label || "",
-            value: getIOParamDisplayValue(auth, Object.assign(output, { value: values[getIOParamId(output)] || [] }), pdh),
-        };
+    return definitions.flatMap((output): ProcessIOParameter[] => {
+        const processValues = getIOParamDisplayValue(auth, Object.assign(output, { value: values[getIOParamId(output)] || [] }), pdh);
+        return processValues.map((thisValue, i) => ({
+            id: i === 0 ? getIOParamId(output) : "",
+            label: i === 0 ? output.label || "" : "",
+            value: thisValue,
+        }));
     });
 };
diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index bed879dc2f..e7eb43c24c 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -384,9 +384,9 @@ export const ProcessIOCard = withStyles(styles)(
                                     </Grid>
                                 )}
                                 {/* Once loaded, either raw or params may still be empty
-				  *   Raw when all params are empty
-				  *   Params when raw is provided by containerRequest properties but workflow mount is absent for preview
-				  */}
+                                  *   Raw when all params are empty
+                                  *   Params when raw is provided by containerRequest properties but workflow mount is absent for preview
+                                  */}
                                 {!loading && (hasRaw || hasParams) && (
                                     <>
                                         <Tabs
@@ -532,7 +532,7 @@ export type ProcessIOValue = {
 export type ProcessIOParameter = {
     id: string;
     label: string;
-    value: ProcessIOValue[];
+    value: ProcessIOValue;
 };
 
 interface ProcessIOPreviewDataProps {
@@ -560,62 +560,6 @@ const ProcessIOPreview = memo(
                     </TableRow>
                 </TableHead>
                 <TableBody>
-                    {data.map((param: ProcessIOParameter) => {
-                        const firstVal = param.value.length > 0 ? param.value[0] : undefined;
-                        const rest = param.value.slice(1);
-                        const mainRowClasses = {
-                            [classes.noBorderRow]: rest.length > 0,
-                            [classes.primaryRow]: true
-                        };
-
-                        return (
-                            <React.Fragment key={param.id}>
-                                <TableRow
-                                    className={classNames(mainRowClasses)}
-                                    data-cy="process-io-param"
-                                >
-                                    <TableCell>{param.id}</TableCell>
-                                    {showLabel && <TableCell>{param.label}</TableCell>}
-                                    <TableCell>
-                                        {firstVal && (
-                                            <ProcessValuePreview
-                                                value={firstVal}
-                                                showImagePreview={showImagePreview}
-                                            />
-                                        )}
-                                    </TableCell>
-                                    <TableCell className={firstVal?.imageUrl ? classes.rowWithPreview : undefined}>
-                                        <Typography className={classes.paramValue}>{firstVal?.collection}</Typography>
-                                    </TableCell>
-                                </TableRow>
-                                {rest.map((val, i) => {
-                                    const rowClasses = {
-                                        [classes.noBorderRow]: i < rest.length - 1,
-                                        [classes.secondaryRow]: val.secondary,
-                                        [classes.primaryRow]: !val.secondary,
-                                    };
-                                    return (
-                                        <TableRow
-                                            className={classNames(rowClasses)}
-                                            key={i}
-                                        >
-                                            <TableCell />
-                                            {showLabel && <TableCell />}
-                                            <TableCell>
-                                                <ProcessValuePreview
-                                                    value={val}
-                                                    showImagePreview={showImagePreview}
-                                                />
-                                            </TableCell>
-                                            <TableCell className={firstVal?.imageUrl ? classes.rowWithPreview : undefined}>
-                                                <Typography className={classes.paramValue}>{val.collection}</Typography>
-                                            </TableCell>
-                                        </TableRow>
-                                    );
-                                })}
-                            </React.Fragment>
-                        );
-                    })}
                 </TableBody>
             </Table>
         );

commit 60d2f52bdde24a7173275b18c74d3e7703282a8f
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Mar 25 11:47:19 2024 -0400

    21508: Fix cross origin io parameter image previews
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 3861e565f1..bed879dc2f 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -633,6 +633,7 @@ const ProcessValuePreview = withStyles(styles)(({ value, showImagePreview, class
             <img
                 className={classes.imagePreview}
                 src={value.imageUrl}
+                crossOrigin="anonymous"
                 alt="Inline Preview"
             />
         ) : (

commit f8f3297dd2e6e37c9fd2387edb2873db83bec3ab
Author: Stephen Smith <stephen at curii.com>
Date:   Mon Mar 25 11:46:52 2024 -0400

    21508: Normalize io panel row height
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx
index 5716340edc..3861e565f1 100644
--- a/services/workbench2/src/views/process-panel/process-io-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-io-card.tsx
@@ -141,6 +141,9 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         display: "flex",
         alignItems: "flex-start",
         flexDirection: "column",
+        '& pre': {
+            margin: 0,
+        },
     },
     keepLink: {
         color: theme.palette.primary.main,
@@ -211,7 +214,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         minWidth: "120px",
     },
     primaryRow: {
-        height: "24px",
+        height: "26px",
         "& td": {
             paddingTop: "2px",
             paddingBottom: "2px",

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list