15610: Fixes layout issues with the collection panel file listing.
authorLucas Di Pentima <lucas@di-pentima.com.ar>
Tue, 30 Jun 2020 19:29:43 +0000 (16:29 -0300)
committerLucas Di Pentima <lucas@di-pentima.com.ar>
Tue, 30 Jun 2020 19:29:43 +0000 (16:29 -0300)
* VirtualTree now just occupies all available space.
* VirtualTree's root container expands so that it occupies the remaining
  height of the browser window.
* Reduced vertical padding on many places to show more information on screen.
* Moved file listing 'hamburger' button next to the 'upload button' to save
  vertical space.

Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas@di-pentima.com.ar>

src/components/collection-panel-files/collection-panel-files.tsx
src/components/file-tree/file-tree.tsx
src/components/tree/virtual-tree.tsx
src/views/collection-panel/collection-panel.tsx

index 4d7e938495b4934cfb02699f55e3ce337e1b34f7..c8875f7026adec10f9be7e8c39624c0614969fa1 100644 (file)
@@ -29,7 +29,8 @@ type CssRules = 'root' | 'cardSubheader' | 'nameHeader' | 'fileSizeHeader' | 'up
 
 const styles: StyleRulesCallback<CssRules> = theme => ({
     root: {
-        paddingBottom: theme.spacing.unit
+        paddingBottom: theme.spacing.unit,
+        height: '100%'
     },
     cardSubheader: {
         paddingTop: 0,
@@ -61,9 +62,10 @@ export const CollectionPanelFiles =
             <Card data-cy='collection-files-panel' className={classes.root}>
                 <CardHeader
                     title="Files"
+                    className={classes.cardSubheader}
                     classes={{ action: classes.button }}
-                    action={
-                        isWritable &&
+                    action={<>
+                        {isWritable &&
                         <Button
                             data-cy='upload-button'
                             onClick={onUploadDataClick}
@@ -72,24 +74,22 @@ export const CollectionPanelFiles =
                             size='small'>
                             <DownloadIcon className={classes.uploadIcon} />
                             Upload data
-                        </Button>
-                    } />
+                        </Button>}
+                        {!tooManyFiles &&
+                        <Tooltip title="More options" disableFocusListener>
+                            <IconButton
+                                data-cy='collection-files-panel-options-btn'
+                                onClick={(ev) => onOptionsMenuOpen(ev, isWritable)}>
+                                <CustomizeTableIcon />
+                            </IconButton>
+                        </Tooltip>}
+                    </>
+                } />
                 { tooManyFiles
                 ? <div className={classes.centeredLabel}>
                         File listing may take some time, please click to browse: <Button onClick={loadFilesFunc}><DownloadIcon/>Show files</Button>
                 </div>
                 : <>
-                    <CardHeader
-                        className={classes.cardSubheader}
-                        action={
-                            <Tooltip title="More options" disableFocusListener>
-                                <IconButton
-                                    data-cy='collection-files-panel-options-btn'
-                                    onClick={(ev) => onOptionsMenuOpen(ev, isWritable)}>
-                                    <CustomizeTableIcon />
-                                </IconButton>
-                            </Tooltip>
-                        } />
                     <Grid container justify="space-between">
                         <Typography variant="caption" className={classes.nameHeader}>
                             Name
@@ -100,7 +100,7 @@ export const CollectionPanelFiles =
                     </Grid>
                     { isLoading
                     ? <div className={classes.centeredLabel}>(loading files...)</div>
-                    : <FileTree onMenuOpen={(ev, item) => onItemMenuOpen(ev, item, isWritable)} {...treeProps} /> }
+                    : <div style={{height: 'calc(100% - 60px)'}}><FileTree onMenuOpen={(ev, item) => onItemMenuOpen(ev, item, isWritable)} {...treeProps} /></div> }
                 </>
                 }
             </Card>);
index d4b47be9ce5d5bd41368eb054f84180f6cdb3a33..b5d98c0833b35c9addc9c6f031183e956a2280c4 100644 (file)
@@ -4,7 +4,7 @@
 
 import * as React from "react";
 import { TreeItem, TreeItemStatus } from "../tree/tree";
-import { VirtualTree } from "../tree/virtual-tree";
+import { VirtualTree as Tree } from "../tree/virtual-tree";
 import { FileTreeData } from "./file-tree-data";
 import { FileTreeItem } from "./file-tree-item";
 
@@ -17,7 +17,6 @@ export interface FileTreeProps {
     currentItemUuid?: string;
 }
 
-const Tree = VirtualTree(20);
 export class FileTree extends React.Component<FileTreeProps> {
     render() {
         return <Tree
index 9330fbe50ca44af0dba4fe0a95c5d7de6d5cb99a..59fe34b12a0a46a0d334a97733631a5caa83d09a 100644 (file)
@@ -13,7 +13,6 @@ import { ArvadosTheme } from '~/common/custom-theme';
 import { TreeItem, TreeProps, TreeItemStatus } from './tree';
 import { ListItem, Radio, Checkbox, CircularProgress, ListItemIcon } from '@material-ui/core';
 import { SidePanelRightArrowIcon } from '../icon/icon';
-import { min } from 'lodash';
 
 type CssRules = 'list'
     | 'listItem'
@@ -179,20 +178,16 @@ export const VirtualList = <T, _>(height: number, width: number, items: VirtualT
         {Row(items, render, treeProps)}
     </FixedSizeList>;
 
-export const VirtualTree = (maxElements: number) => withStyles(styles)(
+export const VirtualTree = withStyles(styles)(
     class Component<T> extends React.Component<TreeProps<T> & WithStyles<CssRules>, {}> {
         render(): ReactElement<any> {
             const { items, render } = this.props;
 
-            // Virtual list viewport's maximum height
-            const itemsQty = items && items.length || 0;
-            const viewportHeight = min([itemsQty, maxElements])! * itemSize;
-
-            return <div style={{height: viewportHeight}}><AutoSizer>
+            return <AutoSizer>
                 {({ height, width }) => {
                     return VirtualList(height, width, items || [], render, this.props);
                 }}
-            </AutoSizer></div>;
+            </AutoSizer>;
         }
     }
 );
index 1cfa48de7d5d63d494108ce6b12f869bcec14a2a..ea69b0dfc868ed100950589e162dd1b0038838af 100644 (file)
@@ -31,11 +31,42 @@ import { getUserUuid } from '~/common/getuser';
 import { getProgressIndicator } from '~/store/progress-indicator/progress-indicator-reducer';
 import { COLLECTION_PANEL_LOAD_FILES, loadCollectionFiles, COLLECTION_PANEL_LOAD_FILES_THRESHOLD } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
 
-type CssRules = 'card' | 'iconHeader' | 'tag' | 'label' | 'value' | 'link' | 'centeredLabel' | 'readOnlyIcon';
+type CssRules = 'root'
+    | 'card'
+    | 'cardHeader'
+    | 'filesCard'
+    | 'cardContent'
+    | 'iconHeader'
+    | 'tag'
+    | 'label'
+    | 'value'
+    | 'link'
+    | 'centeredLabel'
+    | 'readOnlyIcon';
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+    root: {
+        display: 'flex',
+        flexFlow: 'column',
+        height: 'calc(100vh - 130px)', // (100% viewport height) - (top bar + breadcrumbs)
+    },
     card: {
-        marginBottom: theme.spacing.unit * 2
+        marginBottom: theme.spacing.unit * 2,
+    },
+    cardHeader: {
+        paddingTop: theme.spacing.unit,
+        paddingBottom: 0,
+    },
+    filesCard: {
+        marginBottom: theme.spacing.unit * 2,
+        flex: 1,
+    },
+    cardContent: {
+        paddingTop: 0,
+        paddingBottom: theme.spacing.unit,
+        '&:last-child': {
+            paddingBottom: theme.spacing.unit,
+        }
     },
     iconHeader: {
         fontSize: '1.875rem',
@@ -101,9 +132,10 @@ export const CollectionPanel = withStyles(styles)(
             render() {
                 const { classes, item, dispatch, isWritable, isLoadingFiles, tooManyFiles } = this.props;
                 return item
-                    ? <>
+                    ? <div className={classes.root}>
                         <Card data-cy='collection-info-panel' className={classes.card}>
                             <CardHeader
+                                className={classes.cardHeader}
                                 avatar={
                                     <IconButton onClick={this.openCollectionDetails}>
                                         <CollectionIcon className={classes.iconHeader} />
@@ -133,7 +165,7 @@ export const CollectionPanel = withStyles(styles)(
                                 titleTypographyProps={this.titleProps}
                                 subheader={item.description}
                                 subheaderTypographyProps={this.titleProps} />
-                            <CardContent>
+                            <CardContent className={classes.cardContent}>
                                 <Grid container direction="column">
                                     <Grid item xs={10}>
                                         <DetailsAttribute classLabel={classes.label} classValue={classes.value}
@@ -160,7 +192,7 @@ export const CollectionPanel = withStyles(styles)(
 
                         <Card data-cy='collection-properties-panel' className={classes.card}>
                             <CardHeader title="Properties" />
-                            <CardContent>
+                            <CardContent className={classes.cardContent}>
                                 <Grid container direction="column">
                                     {isWritable && <Grid item xs={12}>
                                         <CollectionTagForm />
@@ -189,7 +221,7 @@ export const CollectionPanel = withStyles(styles)(
                                 </Grid>
                             </CardContent>
                         </Card>
-                        <div className={classes.card}>
+                        <div className={classes.filesCard}>
                             <CollectionPanelFiles
                                 isWritable={isWritable}
                                 isLoading={isLoadingFiles}
@@ -200,7 +232,7 @@ export const CollectionPanel = withStyles(styles)(
                                 }
                             } />
                         </div>
-                    </>
+                    </div>
                     : null;
             }