Add typescript paths to top level folders
[arvados-workbench2.git] / src / store / project-panel / project-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 } from "../data-explorer/data-explorer-middleware-service";
6 import { ProjectPanelColumnNames, ProjectPanelFilter } from "~/views/project-panel/project-panel";
7 import { RootState } from "../store";
8 import { DataColumns } from "~/components/data-table/data-table";
9 import { ServiceRepository } from "~/services/services";
10 import { ProjectPanelItem, resourceToDataItem } from "~/views/project-panel/project-panel-item";
11 import { SortDirection } from "~/components/data-table/data-column";
12 import { OrderBuilder } from "~/common/api/order-builder";
13 import { FilterBuilder } from "~/common/api/filter-builder";
14 import { GroupContentsResourcePrefix, GroupContentsResource } from "~/services/groups-service/groups-service";
15 import { checkPresenceInFavorites } from "../favorites/favorites-actions";
16 import { projectPanelActions } from "./project-panel-action";
17 import { Dispatch, MiddlewareAPI } from "redux";
18
19 export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService {
20     constructor(private services: ServiceRepository, id: string) {
21         super(id);
22     }
23
24     requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
25         const state = api.getState();
26         const dataExplorer = state.dataExplorer[this.getId()];
27         const columns = dataExplorer.columns as DataColumns<ProjectPanelItem, ProjectPanelFilter>;
28         const typeFilters = getColumnFilters(columns, ProjectPanelColumnNames.TYPE);
29         const statusFilters = getColumnFilters(columns, ProjectPanelColumnNames.STATUS);
30         const sortColumn = dataExplorer.columns.find(({ sortDirection }) => Boolean(sortDirection && sortDirection !== "none"));
31         const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.ASC ? SortDirection.ASC : SortDirection.DESC;
32         if (typeFilters.length > 0) {
33             this.services.groupsService
34                 .contents(state.projects.currentItemId, {
35                     limit: dataExplorer.rowsPerPage,
36                     offset: dataExplorer.page * dataExplorer.rowsPerPage,
37                     order: sortColumn
38                         ? sortColumn.name === ProjectPanelColumnNames.NAME
39                             ? getOrder("name", sortDirection)
40                             : getOrder("createdAt", sortDirection)
41                         : OrderBuilder.create(),
42                     filters: FilterBuilder
43                         .create()
44                         .concat(FilterBuilder
45                             .create()
46                             .addIsA("uuid", typeFilters.map(f => f.type)))
47                         .concat(FilterBuilder
48                             .create(GroupContentsResourcePrefix.PROCESS)
49                             .addIn("state", statusFilters.map(f => f.type)))
50                         .concat(getSearchFilter(dataExplorer.searchValue))
51                 })
52                 .then(response => {
53                     api.dispatch(projectPanelActions.SET_ITEMS({
54                         items: response.items.map(resourceToDataItem),
55                         itemsAvailable: response.itemsAvailable,
56                         page: Math.floor(response.offset / response.limit),
57                         rowsPerPage: response.limit
58                     }));
59                     api.dispatch<any>(checkPresenceInFavorites(response.items.map(item => item.uuid)));
60                 });
61         } else {
62             api.dispatch(projectPanelActions.SET_ITEMS({
63                 items: [],
64                 itemsAvailable: 0,
65                 page: 0,
66                 rowsPerPage: dataExplorer.rowsPerPage
67             }));
68         }
69     }
70 }
71
72 const getColumnFilters = (columns: DataColumns<ProjectPanelItem, ProjectPanelFilter>, columnName: string) => {
73     const column = columns.find(c => c.name === columnName);
74     return column && column.filters ? column.filters.filter(f => f.selected) : [];
75 };
76
77 const getOrder = (attribute: "name" | "createdAt", direction: SortDirection) =>
78     [
79         OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION),
80         OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS),
81         OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROJECT)
82     ].reduce((acc, b) =>
83         acc.concat(direction === SortDirection.ASC
84             ? b.addAsc(attribute)
85             : b.addDesc(attribute)), OrderBuilder.create());
86
87 const getSearchFilter = (searchValue: string) =>
88     searchValue
89         ? [
90             FilterBuilder.create(GroupContentsResourcePrefix.COLLECTION),
91             FilterBuilder.create(GroupContentsResourcePrefix.PROCESS),
92             FilterBuilder.create(GroupContentsResourcePrefix.PROJECT)]
93             .reduce((acc, b) =>
94                 acc.concat(b.addILike("name", searchValue)), FilterBuilder.create())
95         : FilterBuilder.create();