18128: Show [X] close button on individual panels.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Fri, 8 Oct 2021 19:11:16 +0000 (16:11 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Thu, 2 Dec 2021 23:01:56 +0000 (20:01 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

src/components/data-explorer/data-explorer.tsx
src/views/process-panel/process-information-card.tsx
src/views/process-panel/process-panel-root.tsx
src/views/subprocess-panel/subprocess-panel-root.tsx

index d272e870bf0caaa46c7918624fe091265fb5c762..940dbd0a505ecc9592ce5f5a760c38778d1b5daf 100644 (file)
@@ -11,7 +11,7 @@ import { SearchInput } from 'components/search-input/search-input';
 import { ArvadosTheme } from "common/custom-theme";
 import { createTree } from 'models/tree';
 import { DataTableFilters } from 'components/data-table-filters/data-table-filters-tree';
-import { MoreOptionsIcon } from 'components/icon/icon';
+import { CloseIcon, MoreOptionsIcon } from 'components/icon/icon';
 import { PaperProps } from '@material-ui/core/Paper';
 
 type CssRules = 'searchBox' | "toolbar" | "toolbarUnderTitle" | "footer" | "root" | 'moreOptionsButton' | 'title';
@@ -62,6 +62,7 @@ interface DataExplorerDataProps<T> {
     title?: React.ReactNode;
     paperKey?: string;
     currentItemUuid: string;
+    panelName?: string
 }
 
 interface DataExplorerActionProps<T> {
@@ -77,6 +78,7 @@ interface DataExplorerActionProps<T> {
     onChangeRowsPerPage: (rowsPerPage: number) => void;
     onLoadMore: (page: number) => void;
     extractKey?: (item: T) => React.Key;
+    doHidePanel?: () => void;
 }
 
 type DataExplorerProps<T> = DataExplorerDataProps<T> & DataExplorerActionProps<T> & WithStyles<CssRules>;
@@ -94,7 +96,7 @@ export const DataExplorer = withStyles(styles)(
                 rowsPerPage, rowsPerPageOptions, onColumnToggle, searchLabel, searchValue, onSearch,
                 items, itemsAvailable, onRowClick, onRowDoubleClick, classes,
                 dataTableDefaultView, hideColumnSelector, actions, paperProps, hideSearchInput,
-                paperKey, fetchMode, currentItemUuid, title
+                paperKey, fetchMode, currentItemUuid, title, doHidePanel, panelName
             } = this.props;
             return <Paper className={classes.root} {...paperProps} key={paperKey}>
                 {title && <div className={classes.title}>{title}</div>}
@@ -111,6 +113,10 @@ export const DataExplorer = withStyles(styles)(
                             columns={columns}
                             onColumnToggle={onColumnToggle} />}
                     </Grid>
+                    { doHidePanel &&
+                        <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
+                            <Button onClick={doHidePanel}><CloseIcon /></Button>
+                        </Tooltip> }
                 </Toolbar>}
                 <DataTable
                     columns={this.props.contextMenuColumn ? [...columns, this.contextMenuColumn] : columns}
index e70a047898d878b0a5947a0d85ac01204ae6e151..ad7673af2bc88b600671b24e9d61d56f9e2fdcc0 100644 (file)
@@ -5,10 +5,10 @@
 import React from 'react';
 import {
     StyleRulesCallback, WithStyles, withStyles, Card,
-    CardHeader, IconButton, CardContent, Grid, Chip, Typography, Tooltip
+    CardHeader, IconButton, CardContent, Grid, Chip, Typography, Tooltip, Button
 } from '@material-ui/core';
 import { ArvadosTheme } from 'common/custom-theme';
-import { MoreOptionsIcon, ProcessIcon } from 'components/icon/icon';
+import { CloseIcon, MoreOptionsIcon, ProcessIcon } from 'components/icon/icon';
 import { DetailsAttribute } from 'components/details-attribute/details-attribute';
 import { Process } from 'store/processes/process';
 import { getProcessStatus, getProcessStatusColor } from 'store/processes/process';
@@ -81,12 +81,14 @@ export interface ProcessInformationCardDataProps {
     navigateToOutput: (uuid: string) => void;
     openWorkflow: (uuid: string) => void;
     cancelProcess: (uuid: string) => void;
+    doHidePanel?: () => void;
+    panelName?: string;
 }
 
 type ProcessInformationCardProps = ProcessInformationCardDataProps & WithStyles<CssRules, true>;
 
 export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
-    ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, openWorkflow, cancelProcess }: ProcessInformationCardProps) => {
+    ({ classes, process, onContextMenu, theme, openProcessInputDialog, navigateToOutput, openWorkflow, cancelProcess, doHidePanel, panelName }: ProcessInformationCardProps) => {
         const { container } = process;
         const startedAt = container ? formatDate(container.startedAt) : 'N/A';
         const finishedAt = container ? formatDate(container.finishedAt) : 'N/A';
@@ -111,6 +113,10 @@ export const ProcessInformationCard = withStyles(styles, { withTheme: true })(
                                 <MoreOptionsIcon />
                             </IconButton>
                         </Tooltip>
+                        { doHidePanel &&
+                        <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
+                            <Button onClick={doHidePanel}><CloseIcon /></Button>
+                        </Tooltip> }
                     </div>
                 }
                 title={
index 242349b5dc79a6c7e4d015438e2cb48e4cc903ac..045e5cfa4a3fdd06bc3133e89582a0d5ecfbc00b 100644 (file)
@@ -10,7 +10,7 @@ import { ProcessIcon } from 'components/icon/icon';
 import { Process } from 'store/processes/process';
 import { SubprocessPanel } from 'views/subprocess-panel/subprocess-panel';
 import { SubprocessFilterDataProps } from 'components/subprocess-filter/subprocess-filter';
-import { MPVContainer } from 'components/multi-panel-view/multi-panel-view';
+import { MPVContainer, MPVPanelContent } from 'components/multi-panel-view/multi-panel-view';
 
 export interface ProcessPanelRootDataProps {
     process?: Process;
@@ -32,7 +32,7 @@ export type ProcessPanelRootProps = ProcessPanelRootDataProps & ProcessPanelRoot
 export const ProcessPanelRoot = ({ process, ...props }: ProcessPanelRootProps) =>
     process
         ? <MPVContainer spacing={8} panelNames={["Info", "Subprocesses"]} alignItems="stretch">
-            <Grid item sm={12} md={12}>
+            <MPVPanelContent sm={12} md={12}>
                 <ProcessInformationCard
                     process={process}
                     onContextMenu={event => props.onContextMenu(event, process)}
@@ -41,10 +41,10 @@ export const ProcessPanelRoot = ({ process, ...props }: ProcessPanelRootProps) =
                     openWorkflow={props.navigateToWorkflow}
                     cancelProcess={props.cancelProcess}
                 />
-            </Grid>
-            <Grid item sm={12} md={12}>
+            </MPVPanelContent>
+            <MPVPanelContent sm={12} md={12}>
                 <SubprocessPanel />
-            </Grid>
+            </MPVPanelContent>
         </MPVContainer>
         : <Grid container
             alignItems='center'
index b8e1b08141a3219baed3013c9b8a93cafbed1036..e35a571254d994b1064b5b7179317a9f5b7bb42e 100644 (file)
@@ -65,12 +65,14 @@ export const subprocessPanelColumns: DataColumns<string> = [
 
 export interface SubprocessPanelDataProps {
     resources: ResourcesState;
+    panelName?: string;
 }
 
 export interface SubprocessPanelActionProps {
     onItemClick: (item: string) => void;
     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: string, resources: ResourcesState) => void;
     onItemDoubleClick: (item: string) => void;
+    doHidePanel?: () => void;
 }
 
 type SubprocessPanelProps = SubprocessPanelActionProps & SubprocessPanelDataProps;
@@ -91,5 +93,7 @@ export const SubprocessPanelRoot = (props: SubprocessPanelProps) => {
             <DataTableDefaultView
                 icon={ProcessIcon}
                 messages={DEFAULT_VIEW_MESSAGES} />
-        } />;
+        }
+        doHidePanel={props.doHidePanel}
+        panelName={props.panelName} />;
 };
\ No newline at end of file