Merge branch 'main' into 22155-layout-bugs
[arvados.git] / services / workbench2 / src / store / project-panel / project-panel-data-middleware-service.ts
index 98f2625cfa3c947b831e9ec2a691062ed2f02723..da6f0df23890648728b90727b5089174a70c8102 100644 (file)
@@ -10,12 +10,11 @@ import {
 } from "store/data-explorer/data-explorer-middleware-service";
 import { ProjectPanelDataColumnNames } from "views/project-panel/project-panel-data";
 import { RootState } from "store/store";
-import { DataColumns } from "components/data-table/data-table";
 import { ServiceRepository } from "services/services";
-import { SortDirection } from "components/data-table/data-column";
+import { DataColumns, SortDirection } from "components/data-table/data-column";
 import { OrderBuilder, OrderDirection } from "services/api/order-builder";
 import { FilterBuilder, joinFilters } from "services/api/filter-builder";
-import { GroupContentsResource, GroupContentsResourcePrefix } from "services/groups-service/groups-service";
+import { ContentsArguments, GroupContentsResource, GroupContentsResourcePrefix } from "services/groups-service/groups-service";
 import { updateFavorites } from "store/favorites/favorites-actions";
 import { IS_PROJECT_PANEL_TRASHED, getProjectPanelCurrentUuid } from "store/project-panel/project-panel-action";
 import { projectPanelDataActions } from "store/project-panel/project-panel-action-bind";
@@ -28,13 +27,13 @@ import { progressIndicatorActions } from "store/progress-indicator/progress-indi
 import { DataExplorer, getDataExplorer } from "store/data-explorer/data-explorer-reducer";
 import { ListResults } from "services/common-service/common-service";
 import { getSortColumn } from "store/data-explorer/data-explorer-reducer";
-import { serializeResourceTypeFilters, buildProcessStatusFilters } from "store/resource-type-filters/resource-type-filters";
+import { buildProcessStatusFilters, serializeDataResourceTypeFilters } from "store/resource-type-filters/resource-type-filters";
 import { updatePublicFavorites } from "store/public-favorites/public-favorites-actions";
 import { selectedFieldsOfGroup } from "models/group";
 import { defaultCollectionSelectedFields } from "models/collection";
 import { ContextMenuActionNames } from "views-components/context-menu/context-menu-action-set";
 import { removeDisabledButton } from "store/multiselect/multiselect-actions";
-import { dataExplorerActions } from "store/data-explorer/data-explorer-action";
+import { couldNotFetchItemsAvailable } from "store/data-explorer/data-explorer-action";
 
 export class ProjectPanelDataMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
@@ -52,8 +51,10 @@ export class ProjectPanelDataMiddlewareService extends DataExplorerMiddlewareSer
             api.dispatch(projectPanelDataExplorerIsNotSet());
         } else {
             try {
-                api.dispatch<any>(dataExplorerActions.SET_IS_NOT_FOUND({ id: this.id, isNotFound: false }));
+                api.dispatch<any>(projectPanelDataActions.SET_IS_NOT_FOUND({ isNotFound: false }));
                 if (!background) { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); }
+
+                // Get items
                 const response = await this.services.groupsService.contents(projectUuid, getParams(dataExplorer, !!isProjectTrashed));
                 const resourceUuids = [...response.items.map(item => item.uuid), projectUuid];
                 api.dispatch<any>(updateFavorites(resourceUuids));
@@ -70,7 +71,7 @@ export class ProjectPanelDataMiddlewareService extends DataExplorerMiddlewareSer
                     })
                 );
                 if (e.status === 404) {
-                    api.dispatch<any>(dataExplorerActions.SET_IS_NOT_FOUND({ id: this.id, isNotFound: true}));
+                    api.dispatch<any>(projectPanelDataActions.SET_IS_NOT_FOUND({ isNotFound: true}));
                 }
                 else {
                     api.dispatch(couldNotFetchProjectContents());
@@ -83,6 +84,25 @@ export class ProjectPanelDataMiddlewareService extends DataExplorerMiddlewareSer
             }
         }
     }
+
+    async requestCount(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
+        const state = api.getState();
+        const dataExplorer = getDataExplorer(state.dataExplorer, this.getId());
+        const projectUuid = getProjectPanelCurrentUuid(state);
+        const isProjectTrashed = getProperty<string>(IS_PROJECT_PANEL_TRASHED)(state.properties);
+
+        if (criteriaChanged && projectUuid) {
+            // Get itemsAvailable
+            return this.services.groupsService.contents(projectUuid, getCountParams(dataExplorer, !!isProjectTrashed))
+                .then((results: ListResults<GroupContentsResource>) => {
+                    if (results.itemsAvailable !== undefined) {
+                        api.dispatch<any>(projectPanelDataActions.SET_ITEMS_AVAILABLE(results.itemsAvailable));
+                    } else {
+                        couldNotFetchItemsAvailable();
+                    }
+                });
+        }
+    }
 }
 
 export const setItems = (listResults: ListResults<GroupContentsResource>) =>
@@ -91,17 +111,25 @@ export const setItems = (listResults: ListResults<GroupContentsResource>) =>
         items: listResults.items.map(resource => resource.uuid),
     });
 
-export const getParams = (dataExplorer: DataExplorer, isProjectTrashed: boolean) => ({
+export const getParams = (dataExplorer: DataExplorer, isProjectTrashed: boolean): ContentsArguments => ({
     ...dataExplorerToListParams(dataExplorer),
     order: getOrder(dataExplorer),
     filters: getFilters(dataExplorer),
     includeTrash: isProjectTrashed,
     select: selectedFieldsOfGroup.concat(defaultCollectionSelectedFields),
+    count: 'none',
+});
+
+const getCountParams = (dataExplorer: DataExplorer, isProjectTrashed: boolean): ContentsArguments => ({
+    filters: getFilters(dataExplorer),
+    includeTrash: isProjectTrashed,
+    limit: 0,
+    count: 'exact',
 });
 
 export const getFilters = (dataExplorer: DataExplorer) => {
     const columns = dataExplorer.columns as DataColumns<string, ProjectResource>;
-    const typeFilters = serializeResourceTypeFilters(getDataExplorerColumnFilters(columns, ProjectPanelDataColumnNames.TYPE));
+    const typeFilters = serializeDataResourceTypeFilters(getDataExplorerColumnFilters(columns, ProjectPanelDataColumnNames.TYPE));
     const statusColumnFilters = getDataExplorerColumnFilters(columns, "Status");
     const activeStatusFilter = Object.keys(statusColumnFilters).find(filterName => statusColumnFilters[filterName].selected);