Merge branch '21128-toolbar-context-menu'
[arvados-workbench2.git] / src / store / all-processes-panel / all-processes-panel-middleware-service.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { DataExplorerMiddlewareService, dataExplorerToListParams, getDataExplorerColumnFilters, getOrder } from "store/data-explorer/data-explorer-middleware-service";
6 import { RootState } from "../store";
7 import { ServiceRepository } from "services/services";
8 import { FilterBuilder, joinFilters } from "services/api/filter-builder";
9 import { allProcessesPanelActions } from "./all-processes-panel-action";
10 import { Dispatch, MiddlewareAPI } from "redux";
11 import { resourcesActions } from "store/resources/resources-actions";
12 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
13 import { progressIndicatorActions } from 'store/progress-indicator/progress-indicator-actions';
14 import { getDataExplorer, DataExplorer } from "store/data-explorer/data-explorer-reducer";
15 import { loadMissingProcessesInformation } from "store/project-panel/project-panel-middleware-service";
16 import { DataColumns } from "components/data-table/data-table";
17 import {
18     ProcessStatusFilter,
19     buildProcessStatusFilters,
20     serializeOnlyProcessTypeFilters
21 } from "../resource-type-filters/resource-type-filters";
22 import { AllProcessesPanelColumnNames } from "views/all-processes-panel/all-processes-panel";
23 import { containerRequestFieldsNoMounts, ContainerRequestResource } from "models/container-request";
24
25 export class AllProcessesPanelMiddlewareService extends DataExplorerMiddlewareService {
26     constructor(private services: ServiceRepository, id: string) {
27         super(id);
28     }
29
30     async requestItems(api: MiddlewareAPI<Dispatch, RootState>, criteriaChanged?: boolean, background?: boolean) {
31         const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
32         if (!dataExplorer) {
33             api.dispatch(allProcessesPanelDataExplorerIsNotSet());
34         } else {
35             try {
36                 if (!background) { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); }
37                 const processItems = await this.services.containerRequestService.list(
38                     {
39                         ...getParams(dataExplorer),
40                         // Omit mounts when viewing all process panel
41                         select: containerRequestFieldsNoMounts,
42                     });
43
44                 if (!background) { api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId())); }
45                 api.dispatch(resourcesActions.SET_RESOURCES(processItems.items));
46                 await api.dispatch<any>(loadMissingProcessesInformation(processItems.items));
47                 api.dispatch(allProcessesPanelActions.SET_ITEMS({
48                     items: processItems.items.map((resource: any) => resource.uuid),
49                     itemsAvailable: processItems.itemsAvailable,
50                     page: Math.floor(processItems.offset / processItems.limit),
51                     rowsPerPage: processItems.limit
52                 }));
53             } catch {
54                 if (!background) { api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId())); }
55                 api.dispatch(allProcessesPanelActions.SET_ITEMS({
56                     items: [],
57                     itemsAvailable: 0,
58                     page: 0,
59                     rowsPerPage: dataExplorer.rowsPerPage
60                 }));
61                 api.dispatch(couldNotFetchAllProcessesListing());
62             }
63         }
64     }
65 }
66
67 const getParams = (dataExplorer: DataExplorer) => ({
68     ...dataExplorerToListParams(dataExplorer),
69     order: getOrder<ContainerRequestResource>(dataExplorer),
70     filters: getFilters(dataExplorer)
71 });
72
73 const getFilters = (dataExplorer: DataExplorer) => {
74     const columns = dataExplorer.columns as DataColumns<string, ContainerRequestResource>;
75     const statusColumnFilters = getDataExplorerColumnFilters(columns, 'Status');
76     const activeStatusFilter = Object.keys(statusColumnFilters).find(
77         filterName => statusColumnFilters[filterName].selected
78     ) || ProcessStatusFilter.ALL;
79
80     const nameFilter = new FilterBuilder().addILike("name", dataExplorer.searchValue).getFilters();
81     const statusFilter = buildProcessStatusFilters(new FilterBuilder(), activeStatusFilter).getFilters();
82     const typeFilters = serializeOnlyProcessTypeFilters(getDataExplorerColumnFilters(columns, AllProcessesPanelColumnNames.TYPE));
83
84     return joinFilters(
85         nameFilter,
86         statusFilter,
87         typeFilters
88     );
89 };
90
91 const allProcessesPanelDataExplorerIsNotSet = () =>
92     snackbarActions.OPEN_SNACKBAR({
93         message: 'All Processes panel is not ready.',
94         kind: SnackbarKind.ERROR
95     });
96
97 const couldNotFetchAllProcessesListing = () =>
98     snackbarActions.OPEN_SNACKBAR({
99         message: 'Could not fetch All Processes listing.',
100         kind: SnackbarKind.ERROR
101     });