17585: Project change should trigger loader
[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 { API_CLIENT_AUTHORIZATION_PANEL_ID } from 'store/api-client-authorizations/api-client-authorizations-actions';
59 import { ApiClientAuthorizationMiddlewareService } from 'store/api-client-authorizations/api-client-authorizations-middleware-service';
60 import { PublicFavoritesMiddlewareService } from 'store/public-favorites-panel/public-favorites-middleware-service';
61 import { PUBLIC_FAVORITE_PANEL_ID } from 'store/public-favorites-panel/public-favorites-action';
62 import { publicFavoritesReducer } from 'store/public-favorites/public-favorites-reducer';
63 import { linkAccountPanelReducer } from './link-account-panel/link-account-panel-reducer';
64 import { CollectionsWithSameContentAddressMiddlewareService } from 'store/collections-content-address-panel/collections-content-address-middleware-service';
65 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from 'store/collections-content-address-panel/collections-content-address-panel-actions';
66 import { ownerNameReducer } from 'store/owner-name/owner-name-reducer';
67 import { SubprocessMiddlewareService } from 'store/subprocess-panel/subprocess-panel-middleware-service';
68 import { SUBPROCESS_PANEL_ID } from 'store/subprocess-panel/subprocess-panel-actions';
69 import { ALL_PROCESSES_PANEL_ID } from './all-processes-panel/all-processes-panel-action';
70 import { Config } from 'common/config';
71 import { pluginConfig } from 'plugins';
72 import { MiddlewareListReducer } from 'common/plugintypes';
73
74 declare global {
75     interface Window {
76       __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
77     }
78 }
79
80 const composeEnhancers =
81     (process.env.NODE_ENV === 'development' &&
82         window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
83     compose;
84
85 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
86
87 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
88
89 export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
90     const rootReducer = createRootReducer(services);
91
92     const projectPanelMiddleware = dataExplorerMiddleware(
93         new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
94     );
95     const favoritePanelMiddleware = dataExplorerMiddleware(
96         new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
97     );
98     const allProcessessPanelMiddleware = dataExplorerMiddleware(
99         new AllProcessesPanelMiddlewareService(services, ALL_PROCESSES_PANEL_ID)
100     );
101     const trashPanelMiddleware = dataExplorerMiddleware(
102         new TrashPanelMiddlewareService(services, TRASH_PANEL_ID)
103     );
104     const searchResultsPanelMiddleware = dataExplorerMiddleware(
105         new SearchResultsMiddlewareService(services, SEARCH_RESULTS_PANEL_ID)
106     );
107     const sharedWithMePanelMiddleware = dataExplorerMiddleware(
108         new SharedWithMeMiddlewareService(services, SHARED_WITH_ME_PANEL_ID)
109     );
110     const workflowPanelMiddleware = dataExplorerMiddleware(
111         new WorkflowMiddlewareService(services, WORKFLOW_PANEL_ID)
112     );
113     const userPanelMiddleware = dataExplorerMiddleware(
114         new UserMiddlewareService(services, USERS_PANEL_ID)
115     );
116     const groupsPanelMiddleware = dataExplorerMiddleware(
117         new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
118     );
119     const groupDetailsPanelMiddleware = dataExplorerMiddleware(
120         new GroupDetailsPanelMiddlewareService(services, GROUP_DETAILS_PANEL_ID)
121     );
122     const linkPanelMiddleware = dataExplorerMiddleware(
123         new LinkMiddlewareService(services, LINK_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         apiClientAuthorizationMiddlewareService,
163         publicFavoritesMiddleware,
164         collectionsContentAddress,
165         subprocessMiddleware,
166     ];
167
168     const reduceMiddlewaresFn: (a: Middleware[],
169         b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
170
171     middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
172
173     const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
174     return createStore(rootReducer, enhancer);
175 }
176
177 const createRootReducer = (services: ServiceRepository) => combineReducers({
178     auth: authReducer(services),
179     collectionPanel: collectionPanelReducer,
180     collectionPanelFiles: collectionPanelFilesReducer,
181     contextMenu: contextMenuReducer,
182     dataExplorer: dataExplorerReducer,
183     detailsPanel: detailsPanelReducer,
184     dialog: dialogReducer,
185     favorites: favoritesReducer,
186     ownerName: ownerNameReducer,
187     publicFavorites: publicFavoritesReducer,
188     form: formReducer,
189     processLogsPanel: processLogsPanelReducer,
190     properties: propertiesReducer,
191     resources: resourcesReducer,
192     router: routerReducer,
193     snackbar: snackbarReducer,
194     treePicker: treePickerReducer,
195     fileUploader: fileUploaderReducer,
196     processPanel: processPanelReducer,
197     progressIndicator: progressIndicatorReducer,
198     runProcessPanel: runProcessPanelReducer,
199     appInfo: appInfoReducer,
200     searchBar: searchBarReducer,
201     virtualMachines: virtualMachinesReducer,
202     repositories: repositoriesReducer,
203     keepServices: keepServicesReducer,
204     linkAccountPanel: linkAccountPanelReducer
205 });