From 5e8a5a1c42226e0dd3aceaf4825d870a3786c5d1 Mon Sep 17 00:00:00 2001 From: Daniel Kos Date: Mon, 17 Sep 2018 22:30:10 +0200 Subject: [PATCH] Change default table view to be displayed only after data fetch Feature #14186 Arvados-DCO-1.1-Signed-off-by: Daniel Kos --- .../data-explorer/data-explorer.tsx | 4 ++- src/components/data-table/data-table.tsx | 5 +-- .../data-explorer/data-explorer-reducer.ts | 1 + .../favorite-panel-middleware-service.ts | 5 ++- .../progress-indicator-actions.ts | 1 + .../progress-indicator-reducer.ts | 6 +++- .../project-panel-middleware-service.ts | 4 +++ .../trash-panel-middleware-service.ts | 4 +++ .../data-explorer/data-explorer.tsx | 4 ++- src/views/favorite-panel/favorite-panel.tsx | 29 +++++++---------- src/views/project-panel/project-panel.tsx | 32 ++++++++----------- src/views/trash-panel/trash-panel.tsx | 28 +++++++--------- 12 files changed, 65 insertions(+), 58 deletions(-) diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx index 58507fb0..66b9c35b 100644 --- a/src/components/data-explorer/data-explorer.tsx +++ b/src/components/data-explorer/data-explorer.tsx @@ -33,6 +33,7 @@ interface DataExplorerDataProps { page: number; contextMenuColumn: boolean; dataTableDefaultView?: React.ReactNode; + working?: boolean; } interface DataExplorerActionProps { @@ -60,7 +61,7 @@ export const DataExplorer = withStyles(styles)( } render() { const { - columns, onContextMenu, onFiltersChange, onSortToggle, extractKey, + columns, onContextMenu, onFiltersChange, onSortToggle, working, extractKey, rowsPerPage, rowsPerPageOptions, onColumnToggle, searchValue, onSearch, items, itemsAvailable, onRowClick, onRowDoubleClick, classes, dataTableDefaultView @@ -87,6 +88,7 @@ export const DataExplorer = withStyles(styles)( onFiltersChange={onFiltersChange} onSortToggle={onSortToggle} extractKey={extractKey} + working={working} defaultView={dataTableDefaultView} /> diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx index 65531a5b..25d81c62 100644 --- a/src/components/data-table/data-table.tsx +++ b/src/components/data-table/data-table.tsx @@ -19,6 +19,7 @@ export interface DataTableDataProps { onSortToggle: (column: DataColumn) => void; onFiltersChange: (filters: DataTableFilterItem[], column: DataColumn) => void; extractKey?: (item: T) => React.Key; + working?: boolean; defaultView?: React.ReactNode; } @@ -63,7 +64,7 @@ export const DataTable = withStyles(styles)( {items.map(this.renderBodyRow)} - {items.length === 0 && this.renderNoItemsPlaceholder()} + {items.length === 0 && this.props.working !== undefined && !this.props.working && this.renderNoItemsPlaceholder()} ; } @@ -71,7 +72,7 @@ export const DataTable = withStyles(styles)( renderNoItemsPlaceholder = () => { return this.props.defaultView ? this.props.defaultView - : ; + : ; } renderHeadCell = (column: DataColumn, index: number) => { diff --git a/src/store/data-explorer/data-explorer-reducer.ts b/src/store/data-explorer/data-explorer-reducer.ts index cc800244..d059d37a 100644 --- a/src/store/data-explorer/data-explorer-reducer.ts +++ b/src/store/data-explorer/data-explorer-reducer.ts @@ -15,6 +15,7 @@ export interface DataExplorer { rowsPerPage: number; rowsPerPageOptions: number[]; searchValue: string; + working?: boolean; } export const initialDataExplorer: DataExplorer = { diff --git a/src/store/favorite-panel/favorite-panel-middleware-service.ts b/src/store/favorite-panel/favorite-panel-middleware-service.ts index c385309f..96f66647 100644 --- a/src/store/favorite-panel/favorite-panel-middleware-service.ts +++ b/src/store/favorite-panel/favorite-panel-middleware-service.ts @@ -17,6 +17,7 @@ import { LinkResource } from "~/models/link"; import { GroupContentsResource, GroupContentsResourcePrefix } from "~/services/groups-service/groups-service"; import { resourcesActions } from "~/store/resources/resources-actions"; import { snackbarActions } from '~/store/snackbar/snackbar-actions'; +import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions.ts'; import { getDataExplorer } from "~/store/data-explorer/data-explorer-reducer"; import { loadMissingProcessesInformation } from "~/store/project-panel/project-panel-middleware-service"; @@ -30,7 +31,6 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic if (!dataExplorer) { api.dispatch(favoritesPanelDataExplorerIsNotSet()); } else { - const columns = dataExplorer.columns as DataColumns; const sortColumn = dataExplorer.columns.find(c => c.sortDirection !== SortDirection.NONE); const typeFilters = this.getColumnFilters(columns, FavoritePanelColumnNames.TYPE); @@ -50,6 +50,7 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic .addOrder(direction, "name", GroupContentsResourcePrefix.PROJECT); } try { + api.dispatch(progressIndicatorActions.START(this.getId())); const response = await this.services.favoriteService .list(this.services.authService.getUuid()!, { limit: dataExplorer.rowsPerPage, @@ -61,6 +62,7 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic .addILike("name", dataExplorer.searchValue) .getFilters() }); + api.dispatch(progressIndicatorActions.PERSIST_STOP(this.getId())); api.dispatch(resourcesActions.SET_RESOURCES(response.items)); await api.dispatch(loadMissingProcessesInformation(response.items)); api.dispatch(favoritePanelActions.SET_ITEMS({ @@ -71,6 +73,7 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic })); api.dispatch(updateFavorites(response.items.map(item => item.uuid))); } catch (e) { + api.dispatch(progressIndicatorActions.PERSIST_STOP(this.getId())); api.dispatch(favoritePanelActions.SET_ITEMS({ items: [], itemsAvailable: 0, diff --git a/src/store/progress-indicator/progress-indicator-actions.ts b/src/store/progress-indicator/progress-indicator-actions.ts index 3712e41b..144f20be 100644 --- a/src/store/progress-indicator/progress-indicator-actions.ts +++ b/src/store/progress-indicator/progress-indicator-actions.ts @@ -7,6 +7,7 @@ import { unionize, ofType, UnionOf } from "~/common/unionize"; export const progressIndicatorActions = unionize({ START: ofType(), STOP: ofType(), + PERSIST_STOP: ofType(), TOGGLE: ofType<{ id: string, working: boolean }>() }); diff --git a/src/store/progress-indicator/progress-indicator-reducer.ts b/src/store/progress-indicator/progress-indicator-reducer.ts index f6a73472..4889bace 100644 --- a/src/store/progress-indicator/progress-indicator-reducer.ts +++ b/src/store/progress-indicator/progress-indicator-reducer.ts @@ -15,11 +15,15 @@ export const progressIndicatorReducer = (state: ProgressIndicatorState = initial return progressIndicatorActions.match(action, { START: id => startWorking(id), STOP: id => stopWorking(id), + PERSIST_STOP: id => state.map(p => ({ + id, + working: p.id === id ? false : p.working + })), TOGGLE: ({ id, working }) => working ? startWorking(id) : stopWorking(id), default: () => state, }); }; export function isSystemWorking(state: ProgressIndicatorState): boolean { - return state.length > 0; + return state.length > 0 && state.reduce((working, p) => working ? true : p.working, false); } diff --git a/src/store/project-panel/project-panel-middleware-service.ts b/src/store/project-panel/project-panel-middleware-service.ts index 4b4ec269..89db436f 100644 --- a/src/store/project-panel/project-panel-middleware-service.ts +++ b/src/store/project-panel/project-panel-middleware-service.ts @@ -18,6 +18,7 @@ import { ProjectResource } from "~/models/project"; import { updateResources } from "~/store/resources/resources-actions"; import { getProperty } from "~/store/properties/properties"; import { snackbarActions } from '../snackbar/snackbar-actions'; +import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions.ts'; import { DataExplorer, getDataExplorer } from '../data-explorer/data-explorer-reducer'; import { ListResults } from '~/services/common-service/common-resource-service'; import { loadContainers } from '../processes/processes-actions'; @@ -38,12 +39,15 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService api.dispatch(projectPanelDataExplorerIsNotSet()); } else { try { + api.dispatch(progressIndicatorActions.START(this.getId())); const response = await this.services.groupsService.contents(projectUuid, getParams(dataExplorer)); + api.dispatch(progressIndicatorActions.PERSIST_STOP(this.getId())); api.dispatch(updateFavorites(response.items.map(item => item.uuid))); api.dispatch(updateResources(response.items)); await api.dispatch(loadMissingProcessesInformation(response.items)); api.dispatch(setItems(response)); } catch (e) { + api.dispatch(progressIndicatorActions.PERSIST_STOP(this.getId())); api.dispatch(couldNotFetchProjectContents()); } } diff --git a/src/store/trash-panel/trash-panel-middleware-service.ts b/src/store/trash-panel/trash-panel-middleware-service.ts index 6e8fa542..968656d9 100644 --- a/src/store/trash-panel/trash-panel-middleware-service.ts +++ b/src/store/trash-panel/trash-panel-middleware-service.ts @@ -21,6 +21,7 @@ import { ProjectPanelColumnNames } from "~/views/project-panel/project-panel"; import { updateFavorites } from "~/store/favorites/favorites-actions"; import { snackbarActions } from "~/store/snackbar/snackbar-actions"; import { updateResources } from "~/store/resources/resources-actions"; +import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions"; export class TrashPanelMiddlewareService extends DataExplorerMiddlewareService { constructor(private services: ServiceRepository, id: string) { @@ -47,6 +48,7 @@ export class TrashPanelMiddlewareService extends DataExplorerMiddlewareService { } try { + api.dispatch(progressIndicatorActions.START(this.getId())); const userUuid = this.services.authService.getUuid()!; const listResults = await this.services.groupsService .contents(userUuid, { @@ -61,6 +63,7 @@ export class TrashPanelMiddlewareService extends DataExplorerMiddlewareService { recursive: true, includeTrash: true }); + api.dispatch(progressIndicatorActions.PERSIST_STOP(this.getId())); const items = listResults.items.map(it => it.uuid); @@ -71,6 +74,7 @@ export class TrashPanelMiddlewareService extends DataExplorerMiddlewareService { api.dispatch(updateFavorites(items)); api.dispatch(updateResources(listResults.items)); } catch (e) { + api.dispatch(progressIndicatorActions.PERSIST_STOP(this.getId())); api.dispatch(couldNotFetchTrashContents()); } } diff --git a/src/views-components/data-explorer/data-explorer.tsx b/src/views-components/data-explorer/data-explorer.tsx index 16dd5993..74c3e64a 100644 --- a/src/views-components/data-explorer/data-explorer.tsx +++ b/src/views-components/data-explorer/data-explorer.tsx @@ -21,7 +21,9 @@ interface Props { } const mapStateToProps = (state: RootState, { id }: Props) => { - return getDataExplorer(state.dataExplorer, id); + const progress = state.progressIndicator.find(p => p.id === id); + const working = progress && progress.working; + return { ...getDataExplorer(state.dataExplorer, id), working }; }; const mapDispatchToProps = () => { diff --git a/src/views/favorite-panel/favorite-panel.tsx b/src/views/favorite-panel/favorite-panel.tsx index 73849562..4ba967c0 100644 --- a/src/views/favorite-panel/favorite-panel.tsx +++ b/src/views/favorite-panel/favorite-panel.tsx @@ -164,23 +164,18 @@ export const FavoritePanel = withStyles(styles)( connect(mapStateToProps, mapDispatchToProps)( class extends React.Component { render() { - return this.hasAnyFavorites() - ? } /> - : ; - } - - hasAnyFavorites = () => { - return Object - .keys(this.props.favorites) - .find(uuid => this.props.favorites[uuid]); + return + } />; } } ) diff --git a/src/views/project-panel/project-panel.tsx b/src/views/project-panel/project-panel.tsx index 2c962ef8..61f6766c 100644 --- a/src/views/project-panel/project-panel.tsx +++ b/src/views/project-panel/project-panel.tsx @@ -139,27 +139,23 @@ export const ProjectPanel = withStyles(styles)( render() { const { classes } = this.props; return
- {this.hasAnyItems() - ? } /> - : - } - + + }/>
; } - hasAnyItems = () => { - const resources = filterResources(this.isCurrentItemChild)(this.props.resources); - return resources.length > 0; - } - isCurrentItemChild = (resource: Resource) => { return resource.ownerUuid === this.props.currentItemId; } diff --git a/src/views/trash-panel/trash-panel.tsx b/src/views/trash-panel/trash-panel.tsx index db7d8f68..04c13354 100644 --- a/src/views/trash-panel/trash-panel.tsx +++ b/src/views/trash-panel/trash-panel.tsx @@ -155,23 +155,17 @@ export const TrashPanel = withStyles(styles)( }))( class extends React.Component { render() { - return this.hasAnyTrashedResources() - ? } /> - : ; - } - - hasAnyTrashedResources = () => { - // TODO: implement check if there is anything in the trash, - // without taking pagination into the account - return true; + return + } />; } handleContextMenu = (event: React.MouseEvent, resourceUuid: string) => { -- 2.30.2