15768: cleaned up toolbar types Arvados-DCO-1.1-Signed-off-by: Lisa Knox <lisa.knox...
[arvados-workbench2.git] / src / components / data-explorer / data-explorer.tsx
index fcee0c54deedcefaf5f9ed3282bfa757ccaadd4b..0446ee6f3565169eef18cce0d669a7b8dfde29b4 100644 (file)
@@ -4,24 +4,19 @@
 
 import React from 'react';
 import { Grid, Paper, Toolbar, StyleRulesCallback, withStyles, WithStyles, TablePagination, IconButton, Tooltip, Button } from '@material-ui/core';
-import { ColumnSelector } from "components/column-selector/column-selector";
-import { DataTable, DataColumns, DataTableFetchMode } from "components/data-table/data-table";
-import { DataColumn } from "components/data-table/data-column";
+import { ColumnSelector } from 'components/column-selector/column-selector';
+import { DataTable, DataColumns, DataTableFetchMode } from 'components/data-table/data-table';
+import { DataColumn } from 'components/data-table/data-column';
 import { SearchInput } from 'components/search-input/search-input';
-import { ArvadosTheme } from "common/custom-theme";
+import { ArvadosTheme } from 'common/custom-theme';
 import { createTree } from 'models/tree';
 import { DataTableFilters } from 'components/data-table-filters/data-table-filters-tree';
-import {
-    CloseIcon,
-    IconType,
-    MaximizeIcon,
-    UnMaximizeIcon,
-    MoreOptionsIcon
-} from 'components/icon/icon';
+import { CloseIcon, IconType, MaximizeIcon, UnMaximizeIcon, MoreOptionsIcon } from 'components/icon/icon';
 import { PaperProps } from '@material-ui/core/Paper';
 import { MPVPanelProps } from 'components/multi-panel-view/multi-panel-view';
+import { MultiselectToolbar, defaultActions } from 'components/multiselectToolbar/MultiselectToolbar';
 
-type CssRules = 'searchBox' | 'headerMenu' | "toolbar" | "footer" | "root" | 'moreOptionsButton' | 'title' | 'dataTable' | 'container';
+type CssRules = 'searchBox' | 'headerMenu' | 'toolbar' | 'footer' | 'root' | 'moreOptionsButton' | 'title' | 'dataTable' | 'container';
 
 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     searchBox: {
@@ -32,19 +27,19 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         paddingRight: theme.spacing.unit,
     },
     footer: {
-        overflow: 'auto'
+        overflow: 'auto',
     },
     root: {
         height: '100%',
     },
     moreOptionsButton: {
-        padding: 0
+        padding: 0,
     },
     title: {
         display: 'inline-block',
         paddingLeft: theme.spacing.unit * 2,
         paddingTop: theme.spacing.unit * 2,
-        fontSize: '18px'
+        fontSize: '18px',
     },
     dataTable: {
         height: '100%',
@@ -54,9 +49,12 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         height: '100%',
     },
     headerMenu: {
+        width: '100%',
         float: 'right',
-        display: 'inline-block',
-    }
+        display: 'flex',
+        flexDirection: 'row-reverse',
+        justifyContent: 'space-between',
+    },
 });
 
 interface DataExplorerDataProps<T> {
@@ -83,6 +81,7 @@ interface DataExplorerDataProps<T> {
     paperKey?: string;
     currentItemUuid: string;
     elementPath?: string;
+    isMSToolbarVisible: boolean;
 }
 
 interface DataExplorerActionProps<T> {
@@ -98,10 +97,10 @@ interface DataExplorerActionProps<T> {
     onChangeRowsPerPage: (rowsPerPage: number) => void;
     onLoadMore: (page: number) => void;
     extractKey?: (item: T) => React.Key;
+    toggleMSToolbar: (isVisible: boolean) => void;
 }
 
-type DataExplorerProps<T> = DataExplorerDataProps<T> &
-    DataExplorerActionProps<T> & WithStyles<CssRules> & MPVPanelProps;
+type DataExplorerProps<T> = DataExplorerDataProps<T> & DataExplorerActionProps<T> & WithStyles<CssRules> & MPVPanelProps;
 
 export const DataExplorer = withStyles(styles)(
     class DataExplorerGeneric<T> extends React.Component<DataExplorerProps<T>> {
@@ -153,120 +152,166 @@ export const DataExplorer = withStyles(styles)(
 
         render() {
             const {
-                columns, onContextMenu, onFiltersChange, onSortToggle, extractKey,
-                rowsPerPage, rowsPerPageOptions, onColumnToggle, searchLabel, searchValue, onSearch,
-                items, itemsAvailable, onRowClick, onRowDoubleClick, classes,
-                defaultViewIcon, defaultViewMessages, hideColumnSelector, actions, paperProps, hideSearchInput,
-                paperKey, fetchMode, currentItemUuid, title,
-                doHidePanel, doMaximizePanel, doUnMaximizePanel, panelName, panelMaximized, elementPath
+                columns,
+                onContextMenu,
+                onFiltersChange,
+                onSortToggle,
+                extractKey,
+                rowsPerPage,
+                rowsPerPageOptions,
+                onColumnToggle,
+                searchLabel,
+                searchValue,
+                onSearch,
+                items,
+                itemsAvailable,
+                onRowClick,
+                onRowDoubleClick,
+                classes,
+                defaultViewIcon,
+                defaultViewMessages,
+                hideColumnSelector,
+                actions,
+                paperProps,
+                hideSearchInput,
+                paperKey,
+                fetchMode,
+                currentItemUuid,
+                title,
+                doHidePanel,
+                doMaximizePanel,
+                doUnMaximizePanel,
+                panelName,
+                panelMaximized,
+                elementPath,
+                isMSToolbarVisible,
+                toggleMSToolbar,
             } = this.props;
-            return <Paper className={classes.root} {...paperProps} key={paperKey} data-cy={this.props["data-cy"]}>
-                <Grid container direction="column" wrap="nowrap" className={classes.container}>
-                    <div>
-                        {title && <Grid item xs className={classes.title}>{title}</Grid>}
-                        {
-                            (!hideColumnSelector || !hideSearchInput || !!actions) &&
-                            <Grid className={classes.headerMenu} item xs>
-                                <Toolbar className={classes.toolbar}>
-                                    {!hideSearchInput && <div className={classes.searchBox}>
-                                        {!hideSearchInput && <SearchInput
-                                            label={searchLabel}
-                                            value={searchValue}
-                                            selfClearProp={''}
-                                            onSearch={onSearch} />}
-                                    </div>}
-                                    {actions}
-                                    {!hideColumnSelector && <ColumnSelector
-                                        columns={columns}
-                                        onColumnToggle={onColumnToggle} />}
-                                    { doUnMaximizePanel && panelMaximized &&
-                                    <Tooltip title={`Unmaximize ${panelName || 'panel'}`} disableFocusListener>
-                                        <IconButton onClick={doUnMaximizePanel}><UnMaximizeIcon /></IconButton>
-                                    </Tooltip> }
-                                    { doMaximizePanel && !panelMaximized &&
-                                        <Tooltip title={`Maximize ${panelName || 'panel'}`} disableFocusListener>
-                                            <IconButton onClick={doMaximizePanel}><MaximizeIcon /></IconButton>
-                                        </Tooltip> }
-                                    { doHidePanel &&
-                                        <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
-                                            <IconButton disabled={panelMaximized} onClick={doHidePanel}><CloseIcon /></IconButton>
-                                        </Tooltip> }
-                                </Toolbar>
-                            </Grid>
-                        }
-                    </div>
-                <Grid item xs="auto" className={classes.dataTable}><DataTable
-                    columns={this.props.contextMenuColumn ? [...columns, this.contextMenuColumn] : columns}
-                    items={items}
-                    onRowClick={(_, item: T) => onRowClick(item)}
-                    onContextMenu={onContextMenu}
-                    onRowDoubleClick={(_, item: T) => onRowDoubleClick(item)}
-                    onFiltersChange={onFiltersChange}
-                    onSortToggle={onSortToggle}
-                    extractKey={extractKey}
-                    working={this.state.showLoading}
-                    defaultViewIcon={defaultViewIcon}
-                    defaultViewMessages={defaultViewMessages}
-                    currentItemUuid={currentItemUuid}
-                    currentRoute={paperKey} /></Grid>
-                <Grid item xs><Toolbar className={classes.footer}>
-                    {
-                        elementPath &&
-                        <Grid container>
-                            <span data-cy="element-path">
-                                {elementPath}
-                            </span>
+            return (
+                <Paper className={classes.root} {...paperProps} key={paperKey} data-cy={this.props['data-cy']}>
+                    <Grid container direction='column' wrap='nowrap' className={classes.container}>
+                        <div>
+                            {title && (
+                                <Grid item xs className={classes.title}>
+                                    {title}
+                                </Grid>
+                            )}
+                            {(!hideColumnSelector || !hideSearchInput || !!actions) && (
+                                <Grid className={classes.headerMenu} item xs>
+                                    <Toolbar className={classes.toolbar}>
+                                        {!hideSearchInput && (
+                                            <div className={classes.searchBox}>
+                                                {!hideSearchInput && <SearchInput label={searchLabel} value={searchValue} selfClearProp={''} onSearch={onSearch} />}
+                                            </div>
+                                        )}
+                                        {actions}
+                                        {!hideColumnSelector && <ColumnSelector columns={columns} onColumnToggle={onColumnToggle} />}
+                                        {doUnMaximizePanel && panelMaximized && (
+                                            <Tooltip title={`Unmaximize ${panelName || 'panel'}`} disableFocusListener>
+                                                <IconButton onClick={doUnMaximizePanel}>
+                                                    <UnMaximizeIcon />
+                                                </IconButton>
+                                            </Tooltip>
+                                        )}
+                                        {doMaximizePanel && !panelMaximized && (
+                                            <Tooltip title={`Maximize ${panelName || 'panel'}`} disableFocusListener>
+                                                <IconButton onClick={doMaximizePanel}>
+                                                    <MaximizeIcon />
+                                                </IconButton>
+                                            </Tooltip>
+                                        )}
+                                        {doHidePanel && (
+                                            <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
+                                                <IconButton disabled={panelMaximized} onClick={doHidePanel}>
+                                                    <CloseIcon />
+                                                </IconButton>
+                                            </Tooltip>
+                                        )}
+                                    </Toolbar>
+                                    {isMSToolbarVisible && <MultiselectToolbar buttons={defaultActions} />}
+                                </Grid>
+                            )}
+                        </div>
+                        <Grid item xs='auto' className={classes.dataTable}>
+                            <DataTable
+                                columns={this.props.contextMenuColumn ? [...columns, this.contextMenuColumn] : columns}
+                                items={items}
+                                onRowClick={(_, item: T) => onRowClick(item)}
+                                onContextMenu={onContextMenu}
+                                onRowDoubleClick={(_, item: T) => onRowDoubleClick(item)}
+                                onFiltersChange={onFiltersChange}
+                                onSortToggle={onSortToggle}
+                                extractKey={extractKey}
+                                working={this.state.showLoading}
+                                defaultViewIcon={defaultViewIcon}
+                                defaultViewMessages={defaultViewMessages}
+                                currentItemUuid={currentItemUuid}
+                                currentRoute={paperKey}
+                                toggleMSToolbar={toggleMSToolbar}
+                            />
+                        </Grid>
+                        <Grid item xs>
+                            <Toolbar className={classes.footer}>
+                                {elementPath && (
+                                    <Grid container>
+                                        <span data-cy='element-path'>{elementPath}</span>
+                                    </Grid>
+                                )}
+                                <Grid container={!elementPath} justify='flex-end'>
+                                    {fetchMode === DataTableFetchMode.PAGINATED ? (
+                                        <TablePagination
+                                            count={itemsAvailable}
+                                            rowsPerPage={rowsPerPage}
+                                            rowsPerPageOptions={rowsPerPageOptions}
+                                            page={this.props.page}
+                                            onChangePage={this.changePage}
+                                            onChangeRowsPerPage={this.changeRowsPerPage}
+                                            // Disable next button on empty lists since that's not default behavior
+                                            nextIconButtonProps={itemsAvailable > 0 ? {} : { disabled: true }}
+                                            component='div'
+                                        />
+                                    ) : (
+                                        <Button variant='text' size='medium' onClick={this.loadMore}>
+                                            Load more
+                                        </Button>
+                                    )}
+                                </Grid>
+                            </Toolbar>
                         </Grid>
-                    }
-                    <Grid container={!elementPath} justify="flex-end">
-                        {fetchMode === DataTableFetchMode.PAGINATED ? <TablePagination
-                            count={itemsAvailable}
-                            rowsPerPage={rowsPerPage}
-                            rowsPerPageOptions={rowsPerPageOptions}
-                            page={this.props.page}
-                            onChangePage={this.changePage}
-                            onChangeRowsPerPage={this.changeRowsPerPage}
-                            // Disable next button on empty lists since that's not default behavior
-                            nextIconButtonProps={(itemsAvailable > 0) ? {} : {disabled: true}}
-                            component="div" /> : <Button
-                                variant="text"
-                                size="medium"
-                                onClick={this.loadMore}
-                            >Load more</Button>}
                     </Grid>
-                </Toolbar></Grid>
-                </Grid>
-            </Paper>;
+                </Paper>
+            );
         }
 
         changePage = (event: React.MouseEvent<HTMLButtonElement>, page: number) => {
             this.props.onChangePage(page);
-        }
+        };
 
         changeRowsPerPage: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement> = (event) => {
             this.props.onChangeRowsPerPage(parseInt(event.target.value, 10));
-        }
+        };
 
         loadMore = () => {
             this.props.onLoadMore(this.props.page + 1);
-        }
+        };
 
-        renderContextMenuTrigger = (item: T) =>
-            <Grid container justify="center">
-                <Tooltip title="More options" disableFocusListener>
-                    <IconButton className={this.props.classes.moreOptionsButton} onClick={event => this.props.onContextMenu(event, item)}>
+        renderContextMenuTrigger = (item: T) => (
+            <Grid container justify='center'>
+                <Tooltip title='More options' disableFocusListener>
+                    <IconButton className={this.props.classes.moreOptionsButton} onClick={(event) => this.props.onContextMenu(event, item)}>
                         <MoreOptionsIcon />
                     </IconButton>
                 </Tooltip>
             </Grid>
+        );
 
         contextMenuColumn: DataColumn<any, any> = {
-            name: "Actions",
+            name: 'Actions',
             selected: true,
             configurable: false,
             filters: createTree(),
-            key: "context-actions",
-            render: this.renderContextMenuTrigger
+            key: 'context-actions',
+            render: this.renderContextMenuTrigger,
         };
     }
 );