19690: tidy up
[arvados-workbench2.git] / src / store / data-explorer / data-explorer-middleware.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Dispatch } from 'redux';
6 import { RootState } from 'store/store';
7 import { ServiceRepository } from 'services/services';
8 import { Middleware } from 'redux';
9 import {
10   dataExplorerActions,
11   bindDataExplorerActions,
12   DataTableRequestState,
13 } from './data-explorer-action';
14 import { getDataExplorer } from './data-explorer-reducer';
15 import { DataExplorerMiddlewareService } from './data-explorer-middleware-service';
16
17 export const dataExplorerMiddleware =
18   (service: DataExplorerMiddlewareService): Middleware =>
19   (api) =>
20   (next) => {
21     const actions = bindDataExplorerActions(service.getId());
22
23     return (action) => {
24       const handleAction =
25         <T extends { id: string }>(handler: (data: T) => void) =>
26         (data: T) => {
27           next(action);
28           if (data.id === service.getId()) {
29             handler(data);
30           }
31         };
32       dataExplorerActions.match(action, {
33         SET_PAGE: handleAction(() => {
34           api.dispatch(actions.REQUEST_ITEMS(false));
35         }),
36         SET_ROWS_PER_PAGE: handleAction(() => {
37           api.dispatch(actions.REQUEST_ITEMS(true));
38         }),
39         SET_FILTERS: handleAction(() => {
40           api.dispatch(actions.RESET_PAGINATION());
41           api.dispatch(actions.REQUEST_ITEMS(true));
42         }),
43         TOGGLE_SORT: handleAction(() => {
44           api.dispatch(actions.REQUEST_ITEMS(true));
45         }),
46         SET_EXPLORER_SEARCH_VALUE: handleAction(() => {
47           api.dispatch(actions.RESET_PAGINATION());
48           api.dispatch(actions.REQUEST_ITEMS(true));
49         }),
50         REQUEST_ITEMS: handleAction(({ criteriaChanged }) => {
51           api.dispatch<any>(
52             async (
53               dispatch: Dispatch,
54               getState: () => RootState,
55               services: ServiceRepository
56             ) => {
57               while (true) {
58                 let de = getDataExplorer(
59                   getState().dataExplorer,
60                   service.getId()
61                 );
62                 switch (de.requestState) {
63                   case DataTableRequestState.IDLE:
64                     // Start a new request.
65                     try {
66                       dispatch(
67                         actions.SET_REQUEST_STATE({
68                           requestState: DataTableRequestState.PENDING,
69                         })
70                       );
71                       await service.requestItems(api, criteriaChanged);
72                     } catch {
73                       dispatch(
74                         actions.SET_REQUEST_STATE({
75                           requestState: DataTableRequestState.NEED_REFRESH,
76                         })
77                       );
78                     }
79                     // Now check if the state is still PENDING, if it moved to NEED_REFRESH
80                     // then we need to reissue requestItems
81                     de = getDataExplorer(
82                       getState().dataExplorer,
83                       service.getId()
84                     );
85                     const complete =
86                       de.requestState === DataTableRequestState.PENDING;
87                     dispatch(
88                       actions.SET_REQUEST_STATE({
89                         requestState: DataTableRequestState.IDLE,
90                       })
91                     );
92                     if (complete) {
93                       return;
94                     }
95                     break;
96                   case DataTableRequestState.PENDING:
97                     // State is PENDING, move it to NEED_REFRESH so that when the current request finishes it starts a new one.
98                     dispatch(
99                       actions.SET_REQUEST_STATE({
100                         requestState: DataTableRequestState.NEED_REFRESH,
101                       })
102                     );
103                     return;
104                   case DataTableRequestState.NEED_REFRESH:
105                     // Nothing to do right now.
106                     return;
107                 }
108               }
109             }
110           );
111         }),
112         default: () => next(action),
113       });
114     };
115   };