1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { Dispatch } from 'redux';
6 import { RootState } from 'store/store';
7 import { ServiceRepository } from 'services/services';
8 import { Middleware } from 'redux';
11 bindDataExplorerActions,
12 DataTableRequestState,
13 couldNotFetchItemsAvailable,
14 } from './data-explorer-action';
15 import { getDataExplorer } from './data-explorer-reducer';
16 import { DataExplorerMiddlewareService } from './data-explorer-middleware-service';
18 export const dataExplorerMiddleware =
19 (service: DataExplorerMiddlewareService): Middleware =>
22 const actions = bindDataExplorerActions(service.getId());
26 <T extends { id: string }>(handler: (data: T) => void) =>
29 if (data.id === service.getId()) {
33 dataExplorerActions.match(action, {
34 SET_PAGE: handleAction(() => {
35 api.dispatch(actions.REQUEST_ITEMS(false));
37 SET_ROWS_PER_PAGE: handleAction(() => {
38 api.dispatch(actions.REQUEST_ITEMS(true));
40 SET_FILTERS: handleAction(() => {
41 api.dispatch(actions.RESET_PAGINATION());
42 api.dispatch(actions.SET_LOADING_ITEMS_AVAILABLE(true));
43 api.dispatch(actions.REQUEST_ITEMS(true));
45 TOGGLE_SORT: handleAction(() => {
46 api.dispatch(actions.REQUEST_ITEMS(true));
48 SET_EXPLORER_SEARCH_VALUE: handleAction(() => {
49 api.dispatch(actions.RESET_PAGINATION());
50 api.dispatch(actions.SET_LOADING_ITEMS_AVAILABLE(true));
51 api.dispatch(actions.REQUEST_ITEMS(true));
53 REQUEST_ITEMS: handleAction(({ criteriaChanged = true, background }) => {
54 api.dispatch<any>(async (
56 getState: () => RootState,
57 services: ServiceRepository
60 let de = getDataExplorer(
61 getState().dataExplorer,
64 switch (de.requestState) {
65 case DataTableRequestState.IDLE:
66 // Start a new request.
69 actions.SET_REQUEST_STATE({
70 requestState: DataTableRequestState.PENDING,
75 const result = service.requestItems(api, criteriaChanged, background);
77 // If criteria changed, fire off a count request
78 if (criteriaChanged) {
79 dispatch(actions.REQUEST_COUNT(criteriaChanged, background));
87 actions.SET_REQUEST_STATE({
88 requestState: DataTableRequestState.NEED_REFRESH,
92 // Now check if the state is still PENDING, if it moved to NEED_REFRESH
93 // then we need to reissue requestItems
95 getState().dataExplorer,
99 de.requestState === DataTableRequestState.PENDING;
101 actions.SET_REQUEST_STATE({
102 requestState: DataTableRequestState.IDLE,
109 case DataTableRequestState.PENDING:
110 // State is PENDING, move it to NEED_REFRESH so that when the current request finishes it starts a new one.
112 actions.SET_REQUEST_STATE({
113 requestState: DataTableRequestState.NEED_REFRESH,
117 case DataTableRequestState.NEED_REFRESH:
118 // Nothing to do right now.
124 REQUEST_COUNT: handleAction(({ criteriaChanged = true, background }) => {
125 api.dispatch<any>(async (
127 getState: () => RootState,
128 services: ServiceRepository
131 let de = getDataExplorer(
132 getState().dataExplorer,
135 switch (de.countRequestState) {
136 case DataTableRequestState.IDLE:
137 // Start new count request
139 actions.SET_COUNT_REQUEST_STATE({
140 countRequestState: DataTableRequestState.PENDING,
144 // Enable loading indicator on non-background fetches
147 dataExplorerActions.SET_LOADING_ITEMS_AVAILABLE({
149 loadingItemsAvailable: true
155 await service.requestCount(api, criteriaChanged, background)
157 // Show error toast if count fetch failed
158 couldNotFetchItemsAvailable();
161 // Turn off itemsAvailable loading indicator when done
163 dataExplorerActions.SET_LOADING_ITEMS_AVAILABLE({
165 loadingItemsAvailable: false
170 // Now check if the state is still PENDING, if it moved to NEED_REFRESH
171 // then we need to reissue requestCount
172 de = getDataExplorer(
173 getState().dataExplorer,
177 de.countRequestState === DataTableRequestState.PENDING;
179 actions.SET_COUNT_REQUEST_STATE({
180 countRequestState: DataTableRequestState.IDLE,
187 case DataTableRequestState.PENDING:
188 // State is PENDING, move it to NEED_REFRESH so that when the current request finishes it starts a new one.
190 actions.SET_COUNT_REQUEST_STATE({
191 countRequestState: DataTableRequestState.NEED_REFRESH,
195 case DataTableRequestState.NEED_REFRESH:
196 // Nothing to do right now.
202 default: () => next(action),