From: Stephen Smith Date: Tue, 19 Apr 2022 17:50:34 +0000 (-0400) Subject: 16068: Merge branch 'main' of git.arvados.org:arvados-workbench2 into 16068-merge... X-Git-Tag: 2.4.1~1^2~8^2~2 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/29d9fdf79b6225638877b64bab88029d18b00264?hp=406ae9a8f9851fcadb16592f245a13c2311de95a 16068: Merge branch 'main' of git.arvados.org:arvados-workbench2 into 16068-merge-process-info-details-panels Arvados-DCO-1.1-Signed-off-by: Stephen Smith --- diff --git a/src/common/custom-theme.ts b/src/common/custom-theme.ts index b0703237..fc89a4ae 100644 --- a/src/common/custom-theme.ts +++ b/src/common/custom-theme.ts @@ -31,6 +31,7 @@ interface Colors { blue500: string; grey500: string; purple: string; + orange: string; } const arvadosPurple = '#361336'; @@ -53,7 +54,8 @@ export const themeOptions: ArvadosThemeOptions = { red900: red['900'], blue500: blue['500'], grey500: grey500, - purple: arvadosPurple + purple: arvadosPurple, + orange: '#f0ad4e', } }, overrides: { diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx index 051f5d34..0363d333 100644 --- a/src/components/data-explorer/data-explorer.tsx +++ b/src/components/data-explorer/data-explorer.tsx @@ -66,6 +66,8 @@ interface DataExplorerDataProps { contextMenuColumn: boolean; dataTableDefaultView?: React.ReactNode; working?: boolean; + currentRefresh?: string; + currentRoute?: string; hideColumnSelector?: boolean; paperProps?: PaperProps; actions?: React.ReactNode; @@ -96,16 +98,55 @@ type DataExplorerProps = DataExplorerDataProps & export const DataExplorer = withStyles(styles)( class DataExplorerGeneric extends React.Component> { + state = { + showLoading: false, + prevRefresh: '', + prevRoute: '', + }; + + componentDidUpdate(prevProps: DataExplorerProps) { + 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, @@ -113,8 +154,7 @@ export const DataExplorer = withStyles(styles)( doHidePanel, doMaximizePanel, panelName, panelMaximized, elementPath } = this.props; - const dataCy = this.props["data-cy"]; - return + return
{title && {title}} @@ -156,7 +196,7 @@ export const DataExplorer = withStyles(styles)( onFiltersChange={onFiltersChange} onSortToggle={onSortToggle} extractKey={extractKey} - working={working} + working={this.state.showLoading} defaultView={dataTableDefaultView} currentItemUuid={currentItemUuid} currentRoute={paperKey} /> diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx index e8a6ce69..14dfdaca 100644 --- a/src/components/data-table/data-table.tsx +++ b/src/components/data-table/data-table.tsx @@ -86,7 +86,7 @@ type DataTableProps = DataTableDataProps & WithStyles; export const DataTable = withStyles(styles)( class Component extends React.Component> { render() { - const { items, classes } = this.props; + const { items, classes, working } = this.props; return
@@ -96,16 +96,16 @@ export const DataTable = withStyles(styles)( - { this.props.working !== undefined && !this.props.working && items.map(this.renderBodyRow) } + { !working && items.map(this.renderBodyRow) }
- { this.props.working && + { !!working &&
} - {items.length === 0 && this.props.working !== undefined && !this.props.working && this.renderNoItemsPlaceholder()} + {items.length === 0 && !working && this.renderNoItemsPlaceholder()}
; } diff --git a/src/components/refresh-button/refresh-button.test.tsx b/src/components/refresh-button/refresh-button.test.tsx index f9fa32d2..3a9292e6 100644 --- a/src/components/refresh-button/refresh-button.test.tsx +++ b/src/components/refresh-button/refresh-button.test.tsx @@ -6,7 +6,7 @@ import React from "react"; import { Button } from "@material-ui/core"; import { shallow, configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; -import { RefreshButton } from './refresh-button'; +import { LAST_REFRESH_TIMESTAMP, RefreshButton } from './refresh-button'; configure({ adapter: new Adapter() }); @@ -31,6 +31,7 @@ describe('', () => { }); it('should pass window location to router', () => { + expect(localStorage.getItem(LAST_REFRESH_TIMESTAMP)).toBeFalsy(); // setup const wrapper = shallow(); @@ -39,5 +40,6 @@ describe('', () => { // then expect(props.history.replace).toHaveBeenCalledWith('/'); + expect(localStorage.getItem(LAST_REFRESH_TIMESTAMP)).not.toBeFalsy(); }); }); diff --git a/src/components/refresh-button/refresh-button.tsx b/src/components/refresh-button/refresh-button.tsx index 9971547b..e2fe5484 100644 --- a/src/components/refresh-button/refresh-button.tsx +++ b/src/components/refresh-button/refresh-button.tsx @@ -26,12 +26,17 @@ interface RefreshButtonProps { onClick?: () => void; } +export const LAST_REFRESH_TIMESTAMP = 'lastRefreshTimestamp'; + export const RefreshButton = ({ history, classes, onClick }: RouteComponentProps & WithStyles & RefreshButtonProps) =>