Merge branch 'master' into 16848-token-handling-improvements
[arvados.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
74 const composeEnhancers =
75     (process.env.NODE_ENV === 'development' &&
76         window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
77         window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, traceLimit: 25 })) ||
78     compose;
79
80 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
81
82 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
83
84 export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
85     const rootReducer = createRootReducer(services);
86
87     const projectPanelMiddleware = dataExplorerMiddleware(
88         new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
89     );
90     const favoritePanelMiddleware = dataExplorerMiddleware(
91         new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
92     );
93     const allProcessessPanelMiddleware = dataExplorerMiddleware(
94         new AllProcessesPanelMiddlewareService(services, ALL_PROCESSES_PANEL_ID)
95     );
96     const trashPanelMiddleware = dataExplorerMiddleware(
97         new TrashPanelMiddlewareService(services, TRASH_PANEL_ID)
98     );
99     const searchResultsPanelMiddleware = dataExplorerMiddleware(
100         new SearchResultsMiddlewareService(services, SEARCH_RESULTS_PANEL_ID)
101     );
102     const sharedWithMePanelMiddleware = dataExplorerMiddleware(
103         new SharedWithMeMiddlewareService(services, SHARED_WITH_ME_PANEL_ID)
104     );
105     const workflowPanelMiddleware = dataExplorerMiddleware(
106         new WorkflowMiddlewareService(services, WORKFLOW_PANEL_ID)
107     );
108     const userPanelMiddleware = dataExplorerMiddleware(
109         new UserMiddlewareService(services, USERS_PANEL_ID)
110     );
111     const groupsPanelMiddleware = dataExplorerMiddleware(
112         new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
113     );
114     const groupDetailsPanelMiddleware = dataExplorerMiddleware(
115         new GroupDetailsPanelMiddlewareService(services, GROUP_DETAILS_PANEL_ID)
116     );
117     const linkPanelMiddleware = dataExplorerMiddleware(
118         new LinkMiddlewareService(services, LINK_PANEL_ID)
119     );
120     const computeNodeMiddleware = dataExplorerMiddleware(
121         new ComputeNodeMiddlewareService(services, COMPUTE_NODE_PANEL_ID)
122     );
123     const apiClientAuthorizationMiddlewareService = dataExplorerMiddleware(
124         new ApiClientAuthorizationMiddlewareService(services, API_CLIENT_AUTHORIZATION_PANEL_ID)
125     );
126     const publicFavoritesMiddleware = dataExplorerMiddleware(
127         new PublicFavoritesMiddlewareService(services, PUBLIC_FAVORITE_PANEL_ID)
128     );
129     const collectionsContentAddress = dataExplorerMiddleware(
130         new CollectionsWithSameContentAddressMiddlewareService(services, COLLECTIONS_CONTENT_ADDRESS_PANEL_ID)
131     );
132     const subprocessMiddleware = dataExplorerMiddleware(
133         new SubprocessMiddlewareService(services, SUBPROCESS_PANEL_ID)
134     );
135     const redirectToMiddleware = (store: any) => (next: any) => (action: any) => {
136         const state = store.getState();
137
138         if (state.auth && state.auth.apiToken) {
139             handleRedirects(state.auth.apiToken, config);
140         }
141
142         return next(action);
143     };
144
145     const middlewares: Middleware[] = [
146         routerMiddleware(history),
147         thunkMiddleware.withExtraArgument(services),
148         authMiddleware(services),
149         projectPanelMiddleware,
150         favoritePanelMiddleware,
151         allProcessessPanelMiddleware,
152         trashPanelMiddleware,
153         searchResultsPanelMiddleware,
154         sharedWithMePanelMiddleware,
155         workflowPanelMiddleware,
156         userPanelMiddleware,
157         groupsPanelMiddleware,
158         groupDetailsPanelMiddleware,
159         linkPanelMiddleware,
160         computeNodeMiddleware,
161         apiClientAuthorizationMiddlewareService,
162         publicFavoritesMiddleware,
163         collectionsContentAddress,
164         subprocessMiddleware,
165     ];
166
167     const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
168     return createStore(rootReducer, enhancer);
169 }
170
171 const createRootReducer = (services: ServiceRepository) => combineReducers({
172     auth: authReducer(services),
173     collectionPanel: collectionPanelReducer,
174     collectionPanelFiles: collectionPanelFilesReducer,
175     contextMenu: contextMenuReducer,
176     dataExplorer: dataExplorerReducer,
177     detailsPanel: detailsPanelReducer,
178     dialog: dialogReducer,
179     favorites: favoritesReducer,
180     ownerName: ownerNameReducer,
181     publicFavorites: publicFavoritesReducer,
182     form: formReducer,
183     processLogsPanel: processLogsPanelReducer,
184     properties: propertiesReducer,
185     resources: resourcesReducer,
186     router: routerReducer,
187     snackbar: snackbarReducer,
188     treePicker: treePickerReducer,
189     fileUploader: fileUploaderReducer,
190     processPanel: processPanelReducer,
191     progressIndicator: progressIndicatorReducer,
192     runProcessPanel: runProcessPanelReducer,
193     appInfo: appInfoReducer,
194     searchBar: searchBarReducer,
195     virtualMachines: virtualMachinesReducer,
196     repositories: repositoriesReducer,
197     keepServices: keepServicesReducer,
198     linkAccountPanel: linkAccountPanelReducer
199 });