import { ArvadosTheme } from "common/custom-theme";
import { createTree } from 'models/tree';
import { DataTableFilters } from 'components/data-table-filters/data-table-filters-tree';
-import { CloseIcon, MaximizeIcon, 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';
rowsPerPageOptions: number[];
page: number;
contextMenuColumn: boolean;
- dataTableDefaultView?: React.ReactNode;
+ defaultViewIcon?: IconType;
+ defaultViewMessages?: string[];
working?: boolean;
+ currentRefresh?: string;
+ currentRoute?: string;
hideColumnSelector?: boolean;
paperProps?: PaperProps;
actions?: React.ReactNode;
export const DataExplorer = withStyles(styles)(
class DataExplorerGeneric<T> extends React.Component<DataExplorerProps<T>> {
+ state = {
+ showLoading: false,
+ prevRefresh: '',
+ prevRoute: '',
+ };
+
+ componentDidUpdate(prevProps: DataExplorerProps<T>) {
+ const currentRefresh = this.props.currentRefresh || '';
+ const currentRoute = this.props.currentRoute || '';
+
+ if (currentRoute !== this.state.prevRoute) {
+ // Component already mounted, but the user comes from a route change,
+ // like browsing through a project hierarchy.
+ this.setState({
+ showLoading: this.props.working,
+ prevRoute: currentRoute,
+ });
+ }
+
+ if (currentRefresh !== this.state.prevRefresh) {
+ // Component already mounted, but the user just clicked the
+ // refresh button.
+ this.setState({
+ showLoading: this.props.working,
+ prevRefresh: currentRefresh,
+ });
+ }
+ if (this.state.showLoading && !this.props.working) {
+ this.setState({
+ showLoading: false,
+ });
+ }
+ }
componentDidMount() {
if (this.props.onSetColumns) {
this.props.onSetColumns(this.props.columns);
}
+ // Component just mounted, so we need to show the loading indicator.
+ this.setState({
+ showLoading: this.props.working,
+ prevRefresh: this.props.currentRefresh || '',
+ prevRoute: this.props.currentRoute || '',
+ });
}
render() {
const {
- columns, onContextMenu, onFiltersChange, onSortToggle, working, extractKey,
+ columns, onContextMenu, onFiltersChange, onSortToggle, extractKey,
rowsPerPage, rowsPerPageOptions, onColumnToggle, searchLabel, searchValue, onSearch,
items, itemsAvailable, onRowClick, onRowDoubleClick, classes,
- dataTableDefaultView, hideColumnSelector, actions, paperProps, hideSearchInput,
+ defaultViewIcon, defaultViewMessages, hideColumnSelector, actions, paperProps, hideSearchInput,
paperKey, fetchMode, currentItemUuid, title,
- doHidePanel, doMaximizePanel, panelName, panelMaximized, elementPath
+ doHidePanel, doMaximizePanel, doUnMaximizePanel, panelName, panelMaximized, elementPath
} = this.props;
- const dataCy = this.props["data-cy"];
- return <Paper className={classes.root} {...paperProps} key={paperKey} data-cy={dataCy}>
+ 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>}
columns={columns}
onColumnToggle={onColumnToggle} />}
</Grid>
+ { 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>
onFiltersChange={onFiltersChange}
onSortToggle={onSortToggle}
extractKey={extractKey}
- working={working}
- defaultView={dataTableDefaultView}
+ working={this.state.showLoading}
+ defaultViewIcon={defaultViewIcon}
+ defaultViewMessages={defaultViewMessages}
currentItemUuid={currentItemUuid}
currentRoute={paperKey} /></Grid>
<Grid item xs><Toolbar className={classes.footer}>