Merge branch '22318-ansible-test-node'
[arvados.git] / services / workbench2 / src / store / public-favorites-panel / public-favorites-middleware-service.ts
index 48d27be5413214c5a64f91fdec10f200261496b9..d10b01d7a2a15f43ce6cfa73da0a7baee385308c 100644 (file)
@@ -4,89 +4,93 @@
 
 import { ServiceRepository } from 'services/services';
 import { MiddlewareAPI, Dispatch } from 'redux';
-import { DataExplorerMiddlewareService, getDataExplorerColumnFilters } from 'store/data-explorer/data-explorer-middleware-service';
+import { DataExplorerMiddlewareService, dataExplorerToListParams, getDataExplorerColumnFilters, listResultsToDataExplorerItemsMeta } from 'store/data-explorer/data-explorer-middleware-service';
 import { RootState } from 'store/store';
 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
-import { getDataExplorer } from 'store/data-explorer/data-explorer-reducer';
+import { DataExplorer, getDataExplorer } from 'store/data-explorer/data-explorer-reducer';
 import { resourcesActions } from 'store/resources/resources-actions';
 import { FilterBuilder } from 'services/api/filter-builder';
 import { FavoritePanelColumnNames } from 'views/favorite-panel/favorite-panel';
 import { publicFavoritePanelActions } from 'store/public-favorites-panel/public-favorites-action';
-import { DataColumns } from 'components/data-table/data-table';
+import { DataColumns } from 'components/data-table/data-column';
 import { serializeSimpleObjectTypeFilters } from '../resource-type-filters/resource-type-filters';
-import { LinkClass } from 'models/link';
+import { LinkClass, LinkResource } from 'models/link';
 import { progressIndicatorActions } from 'store/progress-indicator/progress-indicator-actions';
 import { updatePublicFavorites } from 'store/public-favorites/public-favorites-actions';
 import { GroupContentsResource } from 'services/groups-service/groups-service';
+import { ListArguments, ListResults } from 'services/common-service/common-service';
+import { couldNotFetchItemsAvailable } from 'store/data-explorer/data-explorer-action';
 
 export class PublicFavoritesMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
         super(id);
     }
 
-    async requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
+    getTypeFilters(dataExplorer: DataExplorer) {
+        const columns = dataExplorer.columns as DataColumns<GroupContentsResource>;
+        return serializeSimpleObjectTypeFilters(getDataExplorerColumnFilters(columns, FavoritePanelColumnNames.TYPE));
+    }
+
+    getLinkFilters(dataExplorer: DataExplorer, publicProjectUuid: string): string {
+        return new FilterBuilder()
+            .addEqual('link_class', LinkClass.STAR)
+            .addEqual('owner_uuid', publicProjectUuid)
+            .addIsA("head_uuid", this.getTypeFilters(dataExplorer))
+            .getFilters();
+    }
+
+    getResourceFilters(dataExplorer: DataExplorer, uuids: string[]): string {
+        return new FilterBuilder()
+            .addIn("uuid", uuids)
+            .addILike("name", dataExplorer.searchValue)
+            .addIsA("uuid", this.getTypeFilters(dataExplorer))
+            .getFilters();
+    }
+
+    getLinkParams(dataExplorer: DataExplorer, publicProjectUuid: string): ListArguments {
+        return {
+            ...dataExplorerToListParams(dataExplorer),
+            filters: this.getLinkFilters(dataExplorer, publicProjectUuid),
+            count: "none",
+        };
+    }
+
+    getCountParams(dataExplorer: DataExplorer, publicProjectUuid: string): ListArguments {
+        return {
+            filters: this.getLinkFilters(dataExplorer, publicProjectUuid),
+            limit: 0,
+            count: "exact",
+        };
+    }
+
+    async requestItems(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
         const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
         if (!dataExplorer) {
             api.dispatch(favoritesPanelDataExplorerIsNotSet());
         } else {
-            const columns = dataExplorer.columns as DataColumns<string, GroupContentsResource>;
-            const typeFilters = serializeSimpleObjectTypeFilters(getDataExplorerColumnFilters(columns, FavoritePanelColumnNames.TYPE));
-
             try {
-                api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
+                if (!background) { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); }
+
                 const uuidPrefix = api.getState().auth.config.uuidPrefix;
                 const publicProjectUuid = `${uuidPrefix}-j7d0g-publicfavorites`;
-                const responseLinks = await this.services.linkService.list({
-                    limit: dataExplorer.rowsPerPage,
-                    offset: dataExplorer.page * dataExplorer.rowsPerPage,
-                    filters: new FilterBuilder()
-                        .addEqual('link_class', LinkClass.STAR)
-                        .addEqual('owner_uuid', publicProjectUuid)
-                        .addIsA("head_uuid", typeFilters)
-                        .getFilters()
-                });
+
+                // Get items
+                const responseLinks = await this.services.linkService.list(this.getLinkParams(dataExplorer, publicProjectUuid));
                 const uuids = responseLinks.items.map(it => it.headUuid);
-                const groupItems: any = await this.services.groupsService.list({
-                    filters: new FilterBuilder()
-                        .addIn("uuid", uuids)
-                        .addILike("name", dataExplorer.searchValue)
-                        .addIsA("uuid", typeFilters)
-                        .getFilters()
-                });
-                const collectionItems: any = await this.services.collectionService.list({
-                    filters: new FilterBuilder()
-                        .addIn("uuid", uuids)
-                        .addILike("name", dataExplorer.searchValue)
-                        .addIsA("uuid", typeFilters)
-                        .getFilters()
-                });
-                const processItems: any = await this.services.containerRequestService.list({
-                    filters: new FilterBuilder()
-                        .addIn("uuid", uuids)
-                        .addILike("name", dataExplorer.searchValue)
-                        .addIsA("uuid", typeFilters)
-                        .getFilters()
-                });
-                const response = groupItems;
-                collectionItems.items.forEach((it: any) => {
-                    response.itemsAvailable++;
-                    response.items.push(it);
-                });
-                processItems.items.forEach((it: any) => {
-                    response.itemsAvailable++;
-                    response.items.push(it);
+
+                const orderedItems = await this.services.groupsService.contents("", {
+                    filters: this.getResourceFilters(dataExplorer, uuids),
+                    include: ["owner_uuid", "container_uuid"],
                 });
-                api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
-                api.dispatch(resourcesActions.SET_RESOURCES(response.items));
+
+                api.dispatch(resourcesActions.SET_RESOURCES(orderedItems.items));
+                api.dispatch(resourcesActions.SET_RESOURCES(orderedItems.included));
                 api.dispatch(publicFavoritePanelActions.SET_ITEMS({
-                    items: response.items.map((resource: any) => resource.uuid),
-                    itemsAvailable: response.itemsAvailable,
-                    page: Math.floor(response.offset / response.limit),
-                    rowsPerPage: response.limit
+                    ...listResultsToDataExplorerItemsMeta(responseLinks),
+                    items: orderedItems.items.map(resource => resource.uuid),
                 }));
-                api.dispatch<any>(updatePublicFavorites(response.items.map((item: any) => item.uuid)));
+                api.dispatch<any>(updatePublicFavorites(uuids));
             } catch (e) {
-                api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(publicFavoritePanelActions.SET_ITEMS({
                     items: [],
                     itemsAvailable: 0,
@@ -94,9 +98,30 @@ export class PublicFavoritesMiddlewareService extends DataExplorerMiddlewareServ
                     rowsPerPage: dataExplorer.rowsPerPage
                 }));
                 api.dispatch(couldNotFetchPublicFavorites());
+            } finally {
+                api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
             }
         }
     }
+
+    async requestCount(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
+        const state = api.getState();
+        const dataExplorer = getDataExplorer(state.dataExplorer, this.getId());
+        const uuidPrefix = api.getState().auth.config.uuidPrefix;
+        const publicProjectUuid = `${uuidPrefix}-j7d0g-publicfavorites`;
+
+        if (criteriaChanged) {
+            // Get itemsAvailable
+            return this.services.linkService.list(this.getCountParams(dataExplorer, publicProjectUuid))
+                .then((results: ListResults<LinkResource>) => {
+                    if (results.itemsAvailable !== undefined) {
+                        api.dispatch<any>(publicFavoritePanelActions.SET_ITEMS_AVAILABLE(results.itemsAvailable));
+                    } else {
+                        couldNotFetchItemsAvailable();
+                    }
+                });
+        }
+    }
 }
 
 const favoritesPanelDataExplorerIsNotSet = () =>