1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { DataExplorerMiddlewareService, dataExplorerToListParams, listResultsToDataExplorerItemsMeta } from "store/data-explorer/data-explorer-middleware-service";
6 import { FavoritePanelColumnNames } from "views/favorite-panel/favorite-panel";
7 import { RootState } from "../store";
8 import { getUserUuid } from "common/getuser";
9 import { DataColumns } from "components/data-table/data-table";
10 import { ServiceRepository } from "services/services";
11 import { FilterBuilder } from "services/api/filter-builder";
12 import { updateFavorites } from "../favorites/favorites-actions";
13 import { favoritePanelActions } from "./favorite-panel-action";
14 import { Dispatch, MiddlewareAPI } from "redux";
15 import { resourcesActions } from "store/resources/resources-actions";
16 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
17 import { progressIndicatorActions } from 'store/progress-indicator/progress-indicator-actions';
18 import { DataExplorer, getDataExplorer } from "store/data-explorer/data-explorer-reducer";
19 import { getDataExplorerColumnFilters } from 'store/data-explorer/data-explorer-middleware-service';
20 import { serializeSimpleObjectTypeFilters } from '../resource-type-filters/resource-type-filters';
21 import { ResourceKind } from "models/resource";
22 import { LinkClass, LinkResource } from "models/link";
23 import { GroupContentsResource } from "services/groups-service/groups-service";
24 import { ListArguments, ListResults } from "services/common-service/common-service";
25 import { couldNotFetchItemsAvailable } from "store/data-explorer/data-explorer-action";
27 export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareService {
28 constructor(private services: ServiceRepository, id: string) {
32 getTypeFilters(dataExplorer: DataExplorer) {
33 const columns = dataExplorer.columns as DataColumns<string, GroupContentsResource>;
34 return serializeSimpleObjectTypeFilters(getDataExplorerColumnFilters(columns, FavoritePanelColumnNames.TYPE));
37 getLinkFilters(dataExplorer: DataExplorer, uuid: string): string {
38 return new FilterBuilder()
39 .addEqual("link_class", LinkClass.STAR)
40 .addEqual('tail_uuid', uuid)
41 .addEqual('tail_kind', ResourceKind.USER)
42 .addIsA("head_uuid", this.getTypeFilters(dataExplorer))
46 getResourceFilters(dataExplorer: DataExplorer, uuids: string[]): string {
47 return new FilterBuilder()
49 .addILike("name", dataExplorer.searchValue)
50 .addIsA("uuid", this.getTypeFilters(dataExplorer))
54 getLinkParams(dataExplorer: DataExplorer, uuid: string): ListArguments {
56 ...dataExplorerToListParams(dataExplorer),
57 filters: this.getLinkFilters(dataExplorer, uuid),
62 getCountParams(dataExplorer: DataExplorer, uuid: string): ListArguments {
64 filters: this.getLinkFilters(dataExplorer, uuid),
70 async requestItems(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
71 const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
72 const uuid = getUserUuid(api.getState());
74 api.dispatch(favoritesPanelDataExplorerIsNotSet());
75 } else if (!uuid || !uuid.length) {
79 if (!background) { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); }
82 const responseLinks = await this.services.linkService.list(this.getLinkParams(dataExplorer, uuid));
83 const uuids = responseLinks.items.map(it => it.headUuid);
85 const orderedItems = await this.services.groupsService.contents("", {
86 filters: this.getResourceFilters(dataExplorer, uuids),
87 include: ["owner_uuid", "container_uuid"],
90 api.dispatch(resourcesActions.SET_RESOURCES(orderedItems.items));
91 api.dispatch(resourcesActions.SET_RESOURCES(orderedItems.included));
92 api.dispatch(favoritePanelActions.SET_ITEMS({
93 ...listResultsToDataExplorerItemsMeta(responseLinks),
94 items: orderedItems.items.map((resource: any) => resource.uuid),
96 api.dispatch<any>(updateFavorites(uuids));
98 api.dispatch(favoritePanelActions.SET_ITEMS({
102 rowsPerPage: dataExplorer.rowsPerPage
104 api.dispatch(couldNotFetchFavoritesContents());
106 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
111 async requestCount(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
112 const state = api.getState();
113 const dataExplorer = getDataExplorer(state.dataExplorer, this.getId());
114 const uuid = getUserUuid(api.getState());
116 if (criteriaChanged && uuid && uuid.length) {
117 // Get itemsAvailable
118 return this.services.linkService.list(this.getCountParams(dataExplorer, uuid))
119 .then((results: ListResults<LinkResource>) => {
120 if (results.itemsAvailable !== undefined) {
121 api.dispatch<any>(favoritePanelActions.SET_ITEMS_AVAILABLE(results.itemsAvailable));
123 couldNotFetchItemsAvailable();
130 const favoritesPanelDataExplorerIsNotSet = () =>
131 snackbarActions.OPEN_SNACKBAR({
132 message: 'Favorites panel is not ready.',
133 kind: SnackbarKind.ERROR
136 const couldNotFetchFavoritesContents = () =>
137 snackbarActions.OPEN_SNACKBAR({
138 message: 'Could not fetch favorites contents.',
139 kind: SnackbarKind.ERROR
142 const userNotAvailable = () =>
143 snackbarActions.OPEN_SNACKBAR({
144 message: 'User favorites not available.',
145 kind: SnackbarKind.ERROR