Merge branch '17426-plug-ins' refs #17426
[arvados-workbench2.git] / src / store / store.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { createStore, applyMiddleware, compose, Middleware, combineReducers, Store, Action, Dispatch } from 'redux';
6 import { routerMiddleware, routerReducer } from "react-router-redux";
7 import thunkMiddleware from 'redux-thunk';
8 import { History } from "history";
9 import { handleRedirects } from '../common/redirect-to';
10
11 import { authReducer } from "./auth/auth-reducer";
12 import { authMiddleware } from "./auth/auth-middleware";
13 import { dataExplorerReducer } from './data-explorer/data-explorer-reducer';
14 import { detailsPanelReducer } from './details-panel/details-panel-reducer';
15 import { contextMenuReducer } from './context-menu/context-menu-reducer';
16 import { reducer as formReducer } from 'redux-form';
17 import { favoritesReducer } from './favorites/favorites-reducer';
18 import { snackbarReducer } from './snackbar/snackbar-reducer';
19 import { collectionPanelFilesReducer } from './collection-panel/collection-panel-files/collection-panel-files-reducer';
20 import { dataExplorerMiddleware } from "./data-explorer/data-explorer-middleware";
21 import { FAVORITE_PANEL_ID } from "./favorite-panel/favorite-panel-action";
22 import { PROJECT_PANEL_ID } from "./project-panel/project-panel-action";
23 import { ProjectPanelMiddlewareService } from "./project-panel/project-panel-middleware-service";
24 import { FavoritePanelMiddlewareService } from "./favorite-panel/favorite-panel-middleware-service";
25 import { AllProcessesPanelMiddlewareService } from "./all-processes-panel/all-processes-panel-middleware-service";
26 import { collectionPanelReducer } from './collection-panel/collection-panel-reducer';
27 import { dialogReducer } from './dialog/dialog-reducer';
28 import { ServiceRepository } from "~/services/services";
29 import { treePickerReducer } from './tree-picker/tree-picker-reducer';
30 import { resourcesReducer } from '~/store/resources/resources-reducer';
31 import { propertiesReducer } from './properties/properties-reducer';
32 import { fileUploaderReducer } from './file-uploader/file-uploader-reducer';
33 import { TrashPanelMiddlewareService } from "~/store/trash-panel/trash-panel-middleware-service";
34 import { TRASH_PANEL_ID } from "~/store/trash-panel/trash-panel-action";
35 import { processLogsPanelReducer } from './process-logs-panel/process-logs-panel-reducer';
36 import { processPanelReducer } from '~/store/process-panel/process-panel-reducer';
37 import { SHARED_WITH_ME_PANEL_ID } from '~/store/shared-with-me-panel/shared-with-me-panel-actions';
38 import { SharedWithMeMiddlewareService } from './shared-with-me-panel/shared-with-me-middleware-service';
39 import { progressIndicatorReducer } from './progress-indicator/progress-indicator-reducer';
40 import { runProcessPanelReducer } from '~/store/run-process-panel/run-process-panel-reducer';
41 import { WorkflowMiddlewareService } from './workflow-panel/workflow-middleware-service';
42 import { WORKFLOW_PANEL_ID } from './workflow-panel/workflow-panel-actions';
43 import { appInfoReducer } from '~/store/app-info/app-info-reducer';
44 import { searchBarReducer } from './search-bar/search-bar-reducer';
45 import { SEARCH_RESULTS_PANEL_ID } from '~/store/search-results-panel/search-results-panel-actions';
46 import { SearchResultsMiddlewareService } from './search-results-panel/search-results-middleware-service';
47 import { virtualMachinesReducer } from "~/store/virtual-machines/virtual-machines-reducer";
48 import { repositoriesReducer } from '~/store/repositories/repositories-reducer';
49 import { keepServicesReducer } from '~/store/keep-services/keep-services-reducer';
50 import { UserMiddlewareService } from '~/store/users/user-panel-middleware-service';
51 import { USERS_PANEL_ID } from '~/store/users/users-actions';
52 import { GroupsPanelMiddlewareService } from '~/store/groups-panel/groups-panel-middleware-service';
53 import { GROUPS_PANEL_ID } from '~/store/groups-panel/groups-panel-actions';
54 import { GroupDetailsPanelMiddlewareService } from '~/store/group-details-panel/group-details-panel-middleware-service';
55 import { GROUP_DETAILS_PANEL_ID } from '~/store/group-details-panel/group-details-panel-actions';
56 import { LINK_PANEL_ID } from '~/store/link-panel/link-panel-actions';
57 import { LinkMiddlewareService } from '~/store/link-panel/link-panel-middleware-service';
58 import { COMPUTE_NODE_PANEL_ID } from '~/store/compute-nodes/compute-nodes-actions';
59 import { ComputeNodeMiddlewareService } from '~/store/compute-nodes/compute-nodes-middleware-service';
60 import { API_CLIENT_AUTHORIZATION_PANEL_ID } from '~/store/api-client-authorizations/api-client-authorizations-actions';
61 import { ApiClientAuthorizationMiddlewareService } from '~/store/api-client-authorizations/api-client-authorizations-middleware-service';
62 import { PublicFavoritesMiddlewareService } from '~/store/public-favorites-panel/public-favorites-middleware-service';
63 import { PUBLIC_FAVORITE_PANEL_ID } from '~/store/public-favorites-panel/public-favorites-action';
64 import { publicFavoritesReducer } from '~/store/public-favorites/public-favorites-reducer';
65 import { linkAccountPanelReducer } from './link-account-panel/link-account-panel-reducer';
66 import { CollectionsWithSameContentAddressMiddlewareService } from '~/store/collections-content-address-panel/collections-content-address-middleware-service';
67 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from '~/store/collections-content-address-panel/collections-content-address-panel-actions';
68 import { ownerNameReducer } from '~/store/owner-name/owner-name-reducer';
69 import { SubprocessMiddlewareService } from '~/store/subprocess-panel/subprocess-panel-middleware-service';
70 import { SUBPROCESS_PANEL_ID } from '~/store/subprocess-panel/subprocess-panel-actions';
71 import { ALL_PROCESSES_PANEL_ID } from './all-processes-panel/all-processes-panel-action';
72 import { Config } from '~/common/config';
73 import { pluginConfig } from '~/plugins';
74 import { MiddlewareListReducer } from '~/common/plugintypes';
75
76 const composeEnhancers =
77     (process.env.NODE_ENV === 'development' &&
78         window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
79         window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, traceLimit: 25 })) ||
80     compose;
81
82 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
83
84 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
85
86 export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
87     const rootReducer = createRootReducer(services);
88
89     const projectPanelMiddleware = dataExplorerMiddleware(
90         new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
91     );
92     const favoritePanelMiddleware = dataExplorerMiddleware(
93         new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
94     );
95     const allProcessessPanelMiddleware = dataExplorerMiddleware(
96         new AllProcessesPanelMiddlewareService(services, ALL_PROCESSES_PANEL_ID)
97     );
98     const trashPanelMiddleware = dataExplorerMiddleware(
99         new TrashPanelMiddlewareService(services, TRASH_PANEL_ID)
100     );
101     const searchResultsPanelMiddleware = dataExplorerMiddleware(
102         new SearchResultsMiddlewareService(services, SEARCH_RESULTS_PANEL_ID)
103     );
104     const sharedWithMePanelMiddleware = dataExplorerMiddleware(
105         new SharedWithMeMiddlewareService(services, SHARED_WITH_ME_PANEL_ID)
106     );
107     const workflowPanelMiddleware = dataExplorerMiddleware(
108         new WorkflowMiddlewareService(services, WORKFLOW_PANEL_ID)
109     );
110     const userPanelMiddleware = dataExplorerMiddleware(
111         new UserMiddlewareService(services, USERS_PANEL_ID)
112     );
113     const groupsPanelMiddleware = dataExplorerMiddleware(
114         new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
115     );
116     const groupDetailsPanelMiddleware = dataExplorerMiddleware(
117         new GroupDetailsPanelMiddlewareService(services, GROUP_DETAILS_PANEL_ID)
118     );
119     const linkPanelMiddleware = dataExplorerMiddleware(
120         new LinkMiddlewareService(services, LINK_PANEL_ID)
121     );
122     const computeNodeMiddleware = dataExplorerMiddleware(
123         new ComputeNodeMiddlewareService(services, COMPUTE_NODE_PANEL_ID)
124     );
125     const apiClientAuthorizationMiddlewareService = dataExplorerMiddleware(
126         new ApiClientAuthorizationMiddlewareService(services, API_CLIENT_AUTHORIZATION_PANEL_ID)
127     );
128     const publicFavoritesMiddleware = dataExplorerMiddleware(
129         new PublicFavoritesMiddlewareService(services, PUBLIC_FAVORITE_PANEL_ID)
130     );
131     const collectionsContentAddress = dataExplorerMiddleware(
132         new CollectionsWithSameContentAddressMiddlewareService(services, COLLECTIONS_CONTENT_ADDRESS_PANEL_ID)
133     );
134     const subprocessMiddleware = dataExplorerMiddleware(
135         new SubprocessMiddlewareService(services, SUBPROCESS_PANEL_ID)
136     );
137     const redirectToMiddleware = (store: any) => (next: any) => (action: any) => {
138         const state = store.getState();
139
140         if (state.auth && state.auth.apiToken) {
141             handleRedirects(state.auth.apiToken, config);
142         }
143
144         return next(action);
145     };
146
147     let middlewares: Middleware[] = [
148         routerMiddleware(history),
149         thunkMiddleware.withExtraArgument(services),
150         authMiddleware(services),
151         projectPanelMiddleware,
152         favoritePanelMiddleware,
153         allProcessessPanelMiddleware,
154         trashPanelMiddleware,
155         searchResultsPanelMiddleware,
156         sharedWithMePanelMiddleware,
157         workflowPanelMiddleware,
158         userPanelMiddleware,
159         groupsPanelMiddleware,
160         groupDetailsPanelMiddleware,
161         linkPanelMiddleware,
162         computeNodeMiddleware,
163         apiClientAuthorizationMiddlewareService,
164         publicFavoritesMiddleware,
165         collectionsContentAddress,
166         subprocessMiddleware,
167     ];
168
169     const reduceMiddlewaresFn: (a: Middleware[],
170         b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
171
172     middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
173
174     const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
175     return createStore(rootReducer, enhancer);
176 }
177
178 const createRootReducer = (services: ServiceRepository) => combineReducers({
179     auth: authReducer(services),
180     collectionPanel: collectionPanelReducer,
181     collectionPanelFiles: collectionPanelFilesReducer,
182     contextMenu: contextMenuReducer,
183     dataExplorer: dataExplorerReducer,
184     detailsPanel: detailsPanelReducer,
185     dialog: dialogReducer,
186     favorites: favoritesReducer,
187     ownerName: ownerNameReducer,
188     publicFavorites: publicFavoritesReducer,
189     form: formReducer,
190     processLogsPanel: processLogsPanelReducer,
191     properties: propertiesReducer,
192     resources: resourcesReducer,
193     router: routerReducer,
194     snackbar: snackbarReducer,
195     treePicker: treePickerReducer,
196     fileUploader: fileUploaderReducer,
197     processPanel: processPanelReducer,
198     progressIndicator: progressIndicatorReducer,
199     runProcessPanel: runProcessPanelReducer,
200     appInfo: appInfoReducer,
201     searchBar: searchBarReducer,
202     virtualMachines: virtualMachinesReducer,
203     repositories: repositoriesReducer,
204     keepServices: keepServicesReducer,
205     linkAccountPanel: linkAccountPanelReducer
206 });