[ARVADOS-WORKBENCH2] updated: 1.3.0-237-g52f6efaa

Git user git at public.curoverse.com
Thu Dec 27 17:35:29 EST 2018


Summary of changes:
 src/components/data-explorer/data-explorer.tsx     | 18 ++++++--
 src/components/data-table/data-table.tsx           |  5 +++
 src/services/common-service/common-service.ts      |  3 +-
 src/services/groups-service/groups-service.ts      |  2 +-
 src/store/data-explorer/data-explorer-action.ts    | 11 ++++-
 src/store/data-explorer/data-explorer-reducer.ts   | 28 ++++++++++--
 src/store/search-bar/search-bar-actions.ts         | 13 ++++--
 .../search-results-middleware-service.ts           | 50 ++++++++++++++++-----
 src/store/workbench/workbench-actions.ts           | 52 +++++++++++++++-------
 .../data-explorer/data-explorer.tsx                |  4 ++
 .../compute-node-panel/compute-node-panel-root.tsx |  6 +--
 11 files changed, 148 insertions(+), 44 deletions(-)

       via  52f6efaa4834fcbcb356c3509171f95d2f1af1c7 (commit)
      from  3b7eae043b41eaebd5cd78d3a74584bcc1290ee7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 52f6efaa4834fcbcb356c3509171f95d2f1af1c7
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Thu Dec 27 23:35:21 2018 +0100

    Cluster search fixes, infinite data explorer mode
    
    Feature #14348
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx
index b6ca215d..db925236 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/components/data-explorer/data-explorer.tsx
@@ -5,7 +5,7 @@
 import * as 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 } from "~/components/data-table/data-table";
+import { DataTable, DataColumns, DataTableFetchMode } from "~/components/data-table/data-table";
 import { DataColumn, SortDirection } from "~/components/data-table/data-column";
 import { SearchInput } from '~/components/search-input/search-input';
 import { ArvadosTheme } from "~/common/custom-theme";
@@ -35,6 +35,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 });
 
 interface DataExplorerDataProps<T> {
+    fetchMode: DataTableFetchMode;
     items: T[];
     itemsAvailable: number;
     columns: DataColumns<T>;
@@ -63,6 +64,7 @@ interface DataExplorerActionProps<T> {
     onFiltersChange: (filters: DataTableFilters, column: DataColumn<T>) => void;
     onChangePage: (page: number) => void;
     onChangeRowsPerPage: (rowsPerPage: number) => void;
+    onLoadMore: (page: number) => void;
     extractKey?: (item: T) => React.Key;
 }
 
@@ -81,7 +83,7 @@ export const DataExplorer = withStyles(styles)(
                 rowsPerPage, rowsPerPageOptions, onColumnToggle, searchValue, onSearch,
                 items, itemsAvailable, onRowClick, onRowDoubleClick, classes,
                 dataTableDefaultView, hideColumnSelector, actions, paperProps, hideSearchInput,
-                paperKey
+                paperKey, fetchMode
             } = this.props;
             return <Paper className={classes.root} {...paperProps} key={paperKey}>
                 <Toolbar className={classes.toolbar}>
@@ -110,14 +112,18 @@ export const DataExplorer = withStyles(styles)(
                     defaultView={dataTableDefaultView} />
                 <Toolbar className={classes.footer}>
                     <Grid container justify="flex-end">
-                        <TablePagination
+                        {fetchMode === DataTableFetchMode.PAGINATED ? <TablePagination
                             count={itemsAvailable}
                             rowsPerPage={rowsPerPage}
                             rowsPerPageOptions={rowsPerPageOptions}
                             page={this.props.page}
                             onChangePage={this.changePage}
                             onChangeRowsPerPage={this.changeRowsPerPage}
-                            component="div" />
+                            component="div" /> : <Button
+                                variant="text"
+                                size="medium"
+                                onClick={() => this.loadMore(this.props.page)}
+                                >Load more</Button>}
                     </Grid>
                 </Toolbar>
             </Paper>;
@@ -131,6 +137,10 @@ export const DataExplorer = withStyles(styles)(
             this.props.onChangeRowsPerPage(parseInt(event.target.value, 10));
         }
 
+        loadMore = (page: number) => {
+            this.props.onLoadMore(page + 1);
+        }
+
         renderContextMenuTrigger = (item: T) =>
             <Grid container justify="center">
                 <Tooltip title="More options" disableFocusListener>
diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx
index d9157a6a..8298861b 100644
--- a/src/components/data-table/data-table.tsx
+++ b/src/components/data-table/data-table.tsx
@@ -12,6 +12,11 @@ import { countNodes } from '~/models/tree';
 
 export type DataColumns<T> = Array<DataColumn<T>>;
 
+export enum DataTableFetchMode {
+    PAGINATED,
+    INFINITE
+}
+
 export interface DataTableDataProps<T> {
     items: T[];
     columns: DataColumns<T>;
diff --git a/src/services/common-service/common-service.ts b/src/services/common-service/common-service.ts
index b301a727..07ff398a 100644
--- a/src/services/common-service/common-service.ts
+++ b/src/services/common-service/common-service.ts
@@ -23,6 +23,7 @@ export interface ListArguments {
 }
 
 export interface ListResults<T> {
+    clusterId?: string;
     kind: string;
     offset: number;
     limit: number;
@@ -128,4 +129,4 @@ export class CommonService<T> {
             this.actions
         );
     }
-}
\ No newline at end of file
+}
diff --git a/src/services/groups-service/groups-service.ts b/src/services/groups-service/groups-service.ts
index 7dfd0c13..a676557a 100644
--- a/src/services/groups-service/groups-service.ts
+++ b/src/services/groups-service/groups-service.ts
@@ -70,7 +70,7 @@ export class GroupsService<T extends GroupResource = GroupResource> extends Tras
             }
         });
         const mappedResponse = { ...TrashableResourceService.mapKeys(_.camelCase)(res) };
-        return { ...mappedResponse, items: mappedItems };
+        return { ...mappedResponse, items: mappedItems, clusterId: session && session.clusterId };
     }
 
     shared(params: SharedArguments = {}): Promise<ListResults<GroupContentsResource>> {
diff --git a/src/store/data-explorer/data-explorer-action.ts b/src/store/data-explorer/data-explorer-action.ts
index 7797ae6c..5bed4ac1 100644
--- a/src/store/data-explorer/data-explorer-action.ts
+++ b/src/store/data-explorer/data-explorer-action.ts
@@ -3,15 +3,18 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { unionize, ofType, UnionOf } from "~/common/unionize";
-import { DataColumns } from "~/components/data-table/data-table";
+import { DataColumns, DataTableFetchMode } from "~/components/data-table/data-table";
 import { DataTableFilters } from '~/components/data-table-filters/data-table-filters-tree';
 
 export const dataExplorerActions = unionize({
+    CLEAR: ofType<{ id: string }>(),
     RESET_PAGINATION: ofType<{ id: string }>(),
     REQUEST_ITEMS: ofType<{ id: string }>(),
+    SET_FETCH_MODE: ofType<({ id: string, fetchMode: DataTableFetchMode })>(),
     SET_COLUMNS: ofType<{ id: string, columns: DataColumns<any> }>(),
     SET_FILTERS: ofType<{ id: string, columnName: string, filters: DataTableFilters }>(),
     SET_ITEMS: ofType<{ id: string, items: any[], page: number, rowsPerPage: number, itemsAvailable: number }>(),
+    APPEND_ITEMS: ofType<{ id: string, items: any[], page: number, rowsPerPage: number, itemsAvailable: number }>(),
     SET_PAGE: ofType<{ id: string, page: number }>(),
     SET_ROWS_PER_PAGE: ofType<{ id: string, rowsPerPage: number }>(),
     TOGGLE_COLUMN: ofType<{ id: string, columnName: string }>(),
@@ -22,16 +25,22 @@ export const dataExplorerActions = unionize({
 export type DataExplorerAction = UnionOf<typeof dataExplorerActions>;
 
 export const bindDataExplorerActions = (id: string) => ({
+    CLEAR: () =>
+        dataExplorerActions.CLEAR({ id }),
     RESET_PAGINATION: () =>
         dataExplorerActions.RESET_PAGINATION({ id }),
     REQUEST_ITEMS: () =>
         dataExplorerActions.REQUEST_ITEMS({ id }),
+    SET_FETCH_MODE: (payload: { fetchMode: DataTableFetchMode }) =>
+        dataExplorerActions.SET_FETCH_MODE({ ...payload, id }),
     SET_COLUMNS: (payload: { columns: DataColumns<any> }) =>
         dataExplorerActions.SET_COLUMNS({ ...payload, id }),
     SET_FILTERS: (payload: { columnName: string, filters: DataTableFilters }) =>
         dataExplorerActions.SET_FILTERS({ ...payload, id }),
     SET_ITEMS: (payload: { items: any[], page: number, rowsPerPage: number, itemsAvailable: number }) =>
         dataExplorerActions.SET_ITEMS({ ...payload, id }),
+    APPEND_ITEMS: (payload: { items: any[], page: number, rowsPerPage: number, itemsAvailable: number }) =>
+        dataExplorerActions.APPEND_ITEMS({ ...payload, id }),
     SET_PAGE: (payload: { page: number }) =>
         dataExplorerActions.SET_PAGE({ ...payload, id }),
     SET_ROWS_PER_PAGE: (payload: { rowsPerPage: number }) =>
diff --git a/src/store/data-explorer/data-explorer-reducer.ts b/src/store/data-explorer/data-explorer-reducer.ts
index 613bf278..0fa32905 100644
--- a/src/store/data-explorer/data-explorer-reducer.ts
+++ b/src/store/data-explorer/data-explorer-reducer.ts
@@ -2,12 +2,18 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { DataColumn, toggleSortDirection, resetSortDirection, SortDirection } from "~/components/data-table/data-column";
-import { dataExplorerActions, DataExplorerAction } from "./data-explorer-action";
-import { DataColumns } from "~/components/data-table/data-table";
+import {
+    DataColumn,
+    resetSortDirection,
+    SortDirection,
+    toggleSortDirection
+} from "~/components/data-table/data-column";
+import { DataExplorerAction, dataExplorerActions } from "./data-explorer-action";
+import { DataColumns, DataTableFetchMode } from "~/components/data-table/data-table";
 import { DataTableFilters } from "~/components/data-table-filters/data-table-filters-tree";
 
 export interface DataExplorer {
+    fetchMode: DataTableFetchMode;
     columns: DataColumns<any>;
     items: any[];
     itemsAvailable: number;
@@ -19,6 +25,7 @@ export interface DataExplorer {
 }
 
 export const initialDataExplorer: DataExplorer = {
+    fetchMode: DataTableFetchMode.PAGINATED,
     columns: [],
     items: [],
     itemsAvailable: 0,
@@ -32,9 +39,15 @@ export type DataExplorerState = Record<string, DataExplorer>;
 
 export const dataExplorerReducer = (state: DataExplorerState = {}, action: DataExplorerAction) =>
     dataExplorerActions.match(action, {
+        CLEAR: ({ id }) =>
+            update(state, id, explorer => ({ ...explorer, page: 0, itemsAvailable: 0, items: [] })),
+
         RESET_PAGINATION: ({ id }) =>
             update(state, id, explorer => ({ ...explorer, page: 0 })),
 
+        SET_FETCH_MODE: ({ id, fetchMode }) =>
+            update(state, id, explorer => ({ ...explorer, fetchMode })),
+
         SET_COLUMNS: ({ id, columns }) =>
             update(state, id, setColumns(columns)),
 
@@ -44,6 +57,15 @@ export const dataExplorerReducer = (state: DataExplorerState = {}, action: DataE
         SET_ITEMS: ({ id, items, itemsAvailable, page, rowsPerPage }) =>
             update(state, id, explorer => ({ ...explorer, items, itemsAvailable, page, rowsPerPage })),
 
+        APPEND_ITEMS: ({ id, items, itemsAvailable, page, rowsPerPage }) =>
+            update(state, id, explorer => ({
+                ...explorer,
+                items: state[id].items.concat(items),
+                itemsAvailable: state[id].itemsAvailable + itemsAvailable,
+                page,
+                rowsPerPage
+            })),
+
         SET_PAGE: ({ id, page }) =>
             update(state, id, explorer => ({ ...explorer, page })),
 
diff --git a/src/store/search-bar/search-bar-actions.ts b/src/store/search-bar/search-bar-actions.ts
index cfa07ebc..c81cba04 100644
--- a/src/store/search-bar/search-bar-actions.ts
+++ b/src/store/search-bar/search-bar-actions.ts
@@ -21,6 +21,8 @@ import * as _ from "lodash";
 import { getModifiedKeysValues } from "~/common/objects";
 import { activateSearchBarProject } from "~/store/search-bar/search-bar-tree-actions";
 import { Session } from "~/models/session";
+import { searchResultsPanelActions } from "~/store/search-results-panel/search-results-panel-actions";
+import { ListResults } from "~/services/common-service/common-service";
 
 export const searchBarActions = unionize({
     SET_CURRENT_VIEW: ofType<string>(),
@@ -190,6 +192,7 @@ export const submitData = (event: React.FormEvent<HTMLFormElement>) =>
         dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
         dispatch(searchBarActions.SET_SEARCH_VALUE(searchValue));
         dispatch(searchBarActions.SET_SEARCH_RESULTS([]));
+        dispatch(searchResultsPanelActions.CLEAR());
         dispatch(navigateToSearchResults);
     };
 
@@ -209,15 +212,17 @@ const searchGroups = (searchValue: string, limit: number) =>
             const sq = parseSearchQuery(searchValue);
             const clusterId = getSearchQueryFirstProp(sq, 'cluster');
             const sessions = getSearchSessions(clusterId, getState().auth.sessions);
-            sessions.forEach(async session => {
+            const lists: ListResults<GroupContentsResource>[] = await Promise.all(sessions.map(session => {
                 const filters = getFilters('name', searchValue, sq);
-                const { items } = await services.groupsService.contents('', {
+                return services.groupsService.contents('', {
                     filters,
                     limit,
                     recursive: true
                 }, session);
-                dispatch(searchBarActions.SET_SEARCH_RESULTS(items));
-            });
+            }));
+
+            const items = lists.reduce((items, list) => items.concat(list.items), [] as GroupContentsResource[]);
+            dispatch(searchBarActions.SET_SEARCH_RESULTS(items));
         }
     };
 
diff --git a/src/store/search-results-panel/search-results-middleware-service.ts b/src/store/search-results-panel/search-results-middleware-service.ts
index 5e806e71..dd96a024 100644
--- a/src/store/search-results-panel/search-results-middleware-service.ts
+++ b/src/store/search-results-panel/search-results-middleware-service.ts
@@ -22,7 +22,6 @@ import {
     parseSearchQuery
 } from '~/store/search-bar/search-bar-actions';
 import { getSortColumn } from "~/store/data-explorer/data-explorer-reducer";
-import { Session } from "~/models/session";
 
 export class SearchResultsMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
@@ -37,15 +36,36 @@ export class SearchResultsMiddlewareService extends DataExplorerMiddlewareServic
         const sq = parseSearchQuery(searchValue);
         const clusterId = getSearchQueryFirstProp(sq, 'cluster');
         const sessions = getSearchSessions(clusterId, state.auth.sessions);
-        sessions.forEach(async session => {
-            try {
-                const response = await this.services.groupsService.contents(userUuid, getParams(dataExplorer, searchValue, sq), session);
-                api.dispatch(updateResources(response.items));
-                api.dispatch(setItems(response));
-            } catch {
-                api.dispatch(couldNotFetchSearchResults(session));
-            }
-        });
+
+        if (searchValue.trim() === '') {
+            return;
+        }
+
+        try {
+            const params = getParams(dataExplorer, searchValue, sq);
+            const lists: ListResults<GroupContentsResource>[] = await Promise.all(sessions.map(session =>
+                this.services.groupsService.contents('', params, session)
+            ));
+
+            const items = lists
+                .reduce((items, list) => items.concat(list.items), [] as GroupContentsResource[]);
+
+            const itemsAvailable = lists
+                .reduce((itemsAvailable, list) => itemsAvailable + list.itemsAvailable, 0);
+
+            const list: ListResults<GroupContentsResource> = {
+                ...params,
+                kind: '',
+                items,
+                itemsAvailable
+            };
+
+            api.dispatch(updateResources(list.items));
+            api.dispatch(appendItems(list));
+
+        } catch {
+            api.dispatch(couldNotFetchSearchResults());
+        }
     }
 }
 
@@ -80,8 +100,14 @@ export const setItems = (listResults: ListResults<GroupContentsResource>) =>
         items: listResults.items.map(resource => resource.uuid),
     });
 
-const couldNotFetchSearchResults = (session: Session) =>
+export const appendItems = (listResults: ListResults<GroupContentsResource>) =>
+    searchResultsPanelActions.APPEND_ITEMS({
+        ...listResultsToDataExplorerItemsMeta(listResults),
+        items: listResults.items.map(resource => resource.uuid),
+    });
+
+const couldNotFetchSearchResults = () =>
     snackbarActions.OPEN_SNACKBAR({
-        message: `Could not fetch search results for ${session.clusterId}.`,
+        message: `Could not fetch search results for some sessions.`,
         kind: SnackbarKind.ERROR
     });
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 46ab1f59..d01143db 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -5,21 +5,37 @@
 import { Dispatch } from 'redux';
 import { RootState } from "~/store/store";
 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
-import { snackbarActions } from '~/store/snackbar/snackbar-actions';
-import { loadFavoritePanel } from '~/store/favorite-panel/favorite-panel-action';
-import { openProjectPanel, projectPanelActions, setIsProjectPanelTrashed } from '~/store/project-panel/project-panel-action';
-import { activateSidePanelTreeItem, initSidePanelTree, SidePanelTreeCategory, loadSidePanelTreeProjects } from '~/store/side-panel-tree/side-panel-tree-actions';
+import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
+import { favoritePanelActions, loadFavoritePanel } from '~/store/favorite-panel/favorite-panel-action';
+import {
+    getProjectPanelCurrentUuid,
+    openProjectPanel,
+    projectPanelActions,
+    setIsProjectPanelTrashed
+} from '~/store/project-panel/project-panel-action';
+import {
+    activateSidePanelTreeItem,
+    initSidePanelTree,
+    loadSidePanelTreeProjects,
+    SidePanelTreeCategory
+} from '~/store/side-panel-tree/side-panel-tree-actions';
 import { loadResource, updateResources } from '~/store/resources/resources-actions';
-import { favoritePanelActions } from '~/store/favorite-panel/favorite-panel-action';
 import { projectPanelColumns } from '~/views/project-panel/project-panel';
 import { favoritePanelColumns } from '~/views/favorite-panel/favorite-panel';
 import { matchRootRoute } from '~/routes/routes';
-import { setSidePanelBreadcrumbs, setProcessBreadcrumbs, setSharedWithMeBreadcrumbs, setTrashBreadcrumbs, setBreadcrumbs, setGroupDetailsBreadcrumbs, setGroupsBreadcrumbs } from '~/store/breadcrumbs/breadcrumbs-actions';
+import {
+    setBreadcrumbs,
+    setGroupDetailsBreadcrumbs,
+    setGroupsBreadcrumbs,
+    setProcessBreadcrumbs,
+    setSharedWithMeBreadcrumbs,
+    setSidePanelBreadcrumbs,
+    setTrashBreadcrumbs
+} from '~/store/breadcrumbs/breadcrumbs-actions';
 import { navigateToProject } from '~/store/navigation/navigation-action';
 import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
 import { ServiceRepository } from '~/services/services';
 import { getResource } from '~/store/resources/resources';
-import { getProjectPanelCurrentUuid } from '~/store/project-panel/project-panel-action';
 import * as projectCreateActions from '~/store/projects/project-create-actions';
 import * as projectMoveActions from '~/store/projects/project-move-actions';
 import * as projectUpdateActions from '~/store/projects/project-update-actions';
@@ -35,8 +51,10 @@ import { trashPanelColumns } from "~/views/trash-panel/trash-panel";
 import { loadTrashPanel, trashPanelActions } from "~/store/trash-panel/trash-panel-action";
 import { initProcessLogsPanel } from '~/store/process-logs-panel/process-logs-panel-actions';
 import { loadProcessPanel } from '~/store/process-panel/process-panel-actions';
-import { sharedWithMePanelActions } from '~/store/shared-with-me-panel/shared-with-me-panel-actions';
-import { loadSharedWithMePanel } from '~/store/shared-with-me-panel/shared-with-me-panel-actions';
+import {
+    loadSharedWithMePanel,
+    sharedWithMePanelActions
+} from '~/store/shared-with-me-panel/shared-with-me-panel-actions';
 import { CopyFormDialogData } from '~/store/copy-dialog/copy-dialog';
 import { loadWorkflowPanel, workflowPanelActions } from '~/store/workflow-panel/workflow-panel-actions';
 import { loadSshKeysPanel } from '~/store/auth/auth-action-ssh';
@@ -45,23 +63,25 @@ import { loadSiteManagerPanel } from '~/store/auth/auth-action-session';
 import { workflowPanelColumns } from '~/views/workflow-panel/workflow-panel-view';
 import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions';
 import { getProgressIndicator } from '~/store/progress-indicator/progress-indicator-reducer';
-import { ResourceKind, extractUuidKind } from '~/models/resource';
+import { extractUuidKind, ResourceKind } from '~/models/resource';
 import { FilterBuilder } from '~/services/api/filter-builder';
 import { GroupContentsResource } from '~/services/groups-service/groups-service';
-import { unionize, ofType, UnionOf, MatchCases } from '~/common/unionize';
+import { MatchCases, ofType, unionize, UnionOf } from '~/common/unionize';
 import { loadRunProcessPanel } from '~/store/run-process-panel/run-process-panel-actions';
 import { loadCollectionFiles } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
-import { SnackbarKind } from '~/store/snackbar/snackbar-actions';
 import { collectionPanelActions } from "~/store/collection-panel/collection-panel-action";
 import { CollectionResource } from "~/models/collection";
-import { searchResultsPanelActions, loadSearchResultsPanel } from '~/store/search-results-panel/search-results-panel-actions';
+import {
+    loadSearchResultsPanel,
+    searchResultsPanelActions
+} from '~/store/search-results-panel/search-results-panel-actions';
 import { searchResultsPanelColumns } from '~/views/search-results-panel/search-results-panel-view';
 import { loadVirtualMachinesPanel } from '~/store/virtual-machines/virtual-machines-actions';
 import { loadRepositoriesPanel } from '~/store/repositories/repositories-actions';
 import { loadKeepServicesPanel } from '~/store/keep-services/keep-services-actions';
 import { loadUsersPanel, userBindedActions } from '~/store/users/users-actions';
-import { loadLinkPanel, linkPanelActions } from '~/store/link-panel/link-panel-actions';
-import { loadComputeNodesPanel, computeNodesActions } from '~/store/compute-nodes/compute-nodes-actions';
+import { linkPanelActions, loadLinkPanel } from '~/store/link-panel/link-panel-actions';
+import { computeNodesActions, loadComputeNodesPanel } from '~/store/compute-nodes/compute-nodes-actions';
 import { linkPanelColumns } from '~/views/link-panel/link-panel-root';
 import { userPanelColumns } from '~/views/user-panel/user-panel';
 import { computeNodePanelColumns } from '~/views/compute-node-panel/compute-node-panel-root';
@@ -70,6 +90,7 @@ import * as groupPanelActions from '~/store/groups-panel/groups-panel-actions';
 import { groupsPanelColumns } from '~/views/groups-panel/groups-panel';
 import * as groupDetailsPanelActions from '~/store/group-details-panel/group-details-panel-actions';
 import { groupDetailsPanelColumns } from '~/views/group-details-panel/group-details-panel';
+import { DataTableFetchMode } from "~/components/data-table/data-table";
 
 export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
 
@@ -102,6 +123,7 @@ export const loadWorkbench = () =>
                 dispatch(trashPanelActions.SET_COLUMNS({ columns: trashPanelColumns }));
                 dispatch(sharedWithMePanelActions.SET_COLUMNS({ columns: projectPanelColumns }));
                 dispatch(workflowPanelActions.SET_COLUMNS({ columns: workflowPanelColumns }));
+                dispatch(searchResultsPanelActions.SET_FETCH_MODE({ fetchMode: DataTableFetchMode.INFINITE }));
                 dispatch(searchResultsPanelActions.SET_COLUMNS({ columns: searchResultsPanelColumns }));
                 dispatch(userBindedActions.SET_COLUMNS({ columns: userPanelColumns }));
                 dispatch(groupPanelActions.GroupsPanelActions.SET_COLUMNS({ columns: groupsPanelColumns }));
diff --git a/src/views-components/data-explorer/data-explorer.tsx b/src/views-components/data-explorer/data-explorer.tsx
index 8cddf3ba..8c95355f 100644
--- a/src/views-components/data-explorer/data-explorer.tsx
+++ b/src/views-components/data-explorer/data-explorer.tsx
@@ -57,6 +57,10 @@ const mapDispatchToProps = () => {
             dispatch(dataExplorerActions.SET_ROWS_PER_PAGE({ id, rowsPerPage }));
         },
 
+        onLoadMore: (page: number) => {
+            dispatch(dataExplorerActions.SET_PAGE({ id, page }));
+        },
+
         onRowClick,
 
         onRowDoubleClick,
diff --git a/src/views/compute-node-panel/compute-node-panel-root.tsx b/src/views/compute-node-panel/compute-node-panel-root.tsx
index feaadb5e..88a0e551 100644
--- a/src/views/compute-node-panel/compute-node-panel-root.tsx
+++ b/src/views/compute-node-panel/compute-node-panel-root.tsx
@@ -7,10 +7,10 @@ import { ShareMeIcon } from '~/components/icon/icon';
 import { DataExplorer } from '~/views-components/data-explorer/data-explorer';
 import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
 import { COMPUTE_NODE_PANEL_ID } from '~/store/compute-nodes/compute-nodes-actions';
-import { DataColumns } from '~/components/data-table/data-table';
+import { DataColumns, DataTableFetchMode } from '~/components/data-table/data-table';
 import { SortDirection } from '~/components/data-table/data-column';
 import { createTree } from '~/models/tree';
-import { 
+import {
     ComputeNodeUuid, ComputeNodeInfo, ComputeNodeDomain, ComputeNodeHostname, ComputeNodeJobUuid,
     ComputeNodeFirstPingAt, ComputeNodeLastPingAt, ComputeNodeIpAddress
 } from '~/views-components/data-explorer/renderers';
@@ -115,4 +115,4 @@ export const ComputeNodePanelRoot = (props: ComputeNodePanelRootProps) => {
                 icon={ShareMeIcon}
                 messages={[DEFAULT_MESSAGE]} />
         } />;
-};
\ No newline at end of file
+};

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list