1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { ServiceRepository } from 'services/services';
6 import { MiddlewareAPI, Dispatch } from 'redux';
7 import { DataExplorerMiddlewareService, dataExplorerToListParams, getDataExplorerColumnFilters, listResultsToDataExplorerItemsMeta } from 'store/data-explorer/data-explorer-middleware-service';
8 import { RootState } from 'store/store';
9 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
10 import { DataExplorer, getDataExplorer } from 'store/data-explorer/data-explorer-reducer';
11 import { resourcesActions } from 'store/resources/resources-actions';
12 import { FilterBuilder } from 'services/api/filter-builder';
13 import { FavoritePanelColumnNames } from 'views/favorite-panel/favorite-panel';
14 import { publicFavoritePanelActions } from 'store/public-favorites-panel/public-favorites-action';
15 import { DataColumns } from 'components/data-table/data-column';
16 import { serializeSimpleObjectTypeFilters } from '../resource-type-filters/resource-type-filters';
17 import { LinkClass, LinkResource } from 'models/link';
18 import { progressIndicatorActions } from 'store/progress-indicator/progress-indicator-actions';
19 import { updatePublicFavorites } from 'store/public-favorites/public-favorites-actions';
20 import { GroupContentsResource } from 'services/groups-service/groups-service';
21 import { ListArguments, ListResults } from 'services/common-service/common-service';
22 import { couldNotFetchItemsAvailable } from 'store/data-explorer/data-explorer-action';
24 export class PublicFavoritesMiddlewareService extends DataExplorerMiddlewareService {
25 constructor(private services: ServiceRepository, id: string) {
29 getTypeFilters(dataExplorer: DataExplorer) {
30 const columns = dataExplorer.columns as DataColumns<string, GroupContentsResource>;
31 return serializeSimpleObjectTypeFilters(getDataExplorerColumnFilters(columns, FavoritePanelColumnNames.TYPE));
34 getLinkFilters(dataExplorer: DataExplorer, publicProjectUuid: string): string {
35 return new FilterBuilder()
36 .addEqual('link_class', LinkClass.STAR)
37 .addEqual('owner_uuid', publicProjectUuid)
38 .addIsA("head_uuid", this.getTypeFilters(dataExplorer))
42 getResourceFilters(dataExplorer: DataExplorer, uuids: string[]): string {
43 return new FilterBuilder()
45 .addILike("name", dataExplorer.searchValue)
46 .addIsA("uuid", this.getTypeFilters(dataExplorer))
50 getLinkParams(dataExplorer: DataExplorer, publicProjectUuid: string): ListArguments {
52 ...dataExplorerToListParams(dataExplorer),
53 filters: this.getLinkFilters(dataExplorer, publicProjectUuid),
58 getCountParams(dataExplorer: DataExplorer, publicProjectUuid: string): ListArguments {
60 filters: this.getLinkFilters(dataExplorer, publicProjectUuid),
66 async requestItems(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
67 const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
69 api.dispatch(favoritesPanelDataExplorerIsNotSet());
72 if (!background) { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); }
74 const uuidPrefix = api.getState().auth.config.uuidPrefix;
75 const publicProjectUuid = `${uuidPrefix}-j7d0g-publicfavorites`;
78 const responseLinks = await this.services.linkService.list(this.getLinkParams(dataExplorer, publicProjectUuid));
79 const uuids = responseLinks.items.map(it => it.headUuid);
81 const orderedItems = await this.services.groupsService.contents("", {
82 filters: this.getResourceFilters(dataExplorer, uuids),
83 include: ["owner_uuid", "container_uuid"],
86 api.dispatch(resourcesActions.SET_RESOURCES(orderedItems.items));
87 api.dispatch(resourcesActions.SET_RESOURCES(orderedItems.included));
88 api.dispatch(publicFavoritePanelActions.SET_ITEMS({
89 ...listResultsToDataExplorerItemsMeta(responseLinks),
90 items: orderedItems.items.map((resource: any) => resource.uuid),
92 api.dispatch<any>(updatePublicFavorites(uuids));
94 api.dispatch(publicFavoritePanelActions.SET_ITEMS({
98 rowsPerPage: dataExplorer.rowsPerPage
100 api.dispatch(couldNotFetchPublicFavorites());
102 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
107 async requestCount(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
108 const state = api.getState();
109 const dataExplorer = getDataExplorer(state.dataExplorer, this.getId());
110 const uuidPrefix = api.getState().auth.config.uuidPrefix;
111 const publicProjectUuid = `${uuidPrefix}-j7d0g-publicfavorites`;
113 if (criteriaChanged) {
114 // Get itemsAvailable
115 return this.services.linkService.list(this.getCountParams(dataExplorer, publicProjectUuid))
116 .then((results: ListResults<LinkResource>) => {
117 if (results.itemsAvailable !== undefined) {
118 api.dispatch<any>(publicFavoritePanelActions.SET_ITEMS_AVAILABLE(results.itemsAvailable));
120 couldNotFetchItemsAvailable();
127 const favoritesPanelDataExplorerIsNotSet = () =>
128 snackbarActions.OPEN_SNACKBAR({
129 message: 'Favorites panel is not ready.',
130 kind: SnackbarKind.ERROR
133 const couldNotFetchPublicFavorites = () =>
134 snackbarActions.OPEN_SNACKBAR({
135 message: 'Could not fetch public favorites contents.',
136 kind: SnackbarKind.ERROR