1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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';
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, treePickerSearchReducer } from './tree-picker/tree-picker-reducer';
30 import { treePickerSearchMiddleware } from './tree-picker/tree-picker-middleware';
31 import { resourcesReducer } from 'store/resources/resources-reducer';
32 import { propertiesReducer } from './properties/properties-reducer';
33 import { fileUploaderReducer } from './file-uploader/file-uploader-reducer';
34 import { TrashPanelMiddlewareService } from 'store/trash-panel/trash-panel-middleware-service';
35 import { TRASH_PANEL_ID } from 'store/trash-panel/trash-panel-action';
36 import { processLogsPanelReducer } from './process-logs-panel/process-logs-panel-reducer';
37 import { processPanelReducer } from 'store/process-panel/process-panel-reducer';
38 import { SHARED_WITH_ME_PANEL_ID } from 'store/shared-with-me-panel/shared-with-me-panel-actions';
39 import { SharedWithMeMiddlewareService } from './shared-with-me-panel/shared-with-me-middleware-service';
40 import { progressIndicatorReducer } from './progress-indicator/progress-indicator-reducer';
41 import { runProcessPanelReducer } from 'store/run-process-panel/run-process-panel-reducer';
42 import { WorkflowMiddlewareService } from './workflow-panel/workflow-middleware-service';
43 import { WORKFLOW_PANEL_ID } from './workflow-panel/workflow-panel-actions';
44 import { appInfoReducer } from 'store/app-info/app-info-reducer';
45 import { searchBarReducer } from './search-bar/search-bar-reducer';
46 import { SEARCH_RESULTS_PANEL_ID } from 'store/search-results-panel/search-results-panel-actions';
47 import { SearchResultsMiddlewareService } from './search-results-panel/search-results-middleware-service';
48 import { virtualMachinesReducer } from 'store/virtual-machines/virtual-machines-reducer';
49 import { repositoriesReducer } from 'store/repositories/repositories-reducer';
50 import { keepServicesReducer } from 'store/keep-services/keep-services-reducer';
51 import { UserMiddlewareService } from 'store/users/user-panel-middleware-service';
52 import { USERS_PANEL_ID } from 'store/users/users-actions';
53 import { UserProfileGroupsMiddlewareService } from 'store/user-profile/user-profile-groups-middleware-service';
54 import { USER_PROFILE_PANEL_ID } from 'store/user-profile/user-profile-actions';
55 import { GroupsPanelMiddlewareService } from 'store/groups-panel/groups-panel-middleware-service';
56 import { GROUPS_PANEL_ID } from 'store/groups-panel/groups-panel-actions';
57 import { GroupDetailsPanelMembersMiddlewareService } from 'store/group-details-panel/group-details-panel-members-middleware-service';
58 import { GroupDetailsPanelPermissionsMiddlewareService } from 'store/group-details-panel/group-details-panel-permissions-middleware-service';
59 import { GROUP_DETAILS_MEMBERS_PANEL_ID, GROUP_DETAILS_PERMISSIONS_PANEL_ID } from 'store/group-details-panel/group-details-panel-actions';
60 import { LINK_PANEL_ID } from 'store/link-panel/link-panel-actions';
61 import { LinkMiddlewareService } from 'store/link-panel/link-panel-middleware-service';
62 import { API_CLIENT_AUTHORIZATION_PANEL_ID } from 'store/api-client-authorizations/api-client-authorizations-actions';
63 import { ApiClientAuthorizationMiddlewareService } from 'store/api-client-authorizations/api-client-authorizations-middleware-service';
64 import { PublicFavoritesMiddlewareService } from 'store/public-favorites-panel/public-favorites-middleware-service';
65 import { PUBLIC_FAVORITE_PANEL_ID } from 'store/public-favorites-panel/public-favorites-action';
66 import { publicFavoritesReducer } from 'store/public-favorites/public-favorites-reducer';
67 import { linkAccountPanelReducer } from './link-account-panel/link-account-panel-reducer';
68 import { CollectionsWithSameContentAddressMiddlewareService } from 'store/collections-content-address-panel/collections-content-address-middleware-service';
69 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from 'store/collections-content-address-panel/collections-content-address-panel-actions';
70 import { ownerNameReducer } from 'store/owner-name/owner-name-reducer';
71 import { SubprocessMiddlewareService } from 'store/subprocess-panel/subprocess-panel-middleware-service';
72 import { SUBPROCESS_PANEL_ID } from 'store/subprocess-panel/subprocess-panel-actions';
73 import { ALL_PROCESSES_PANEL_ID } from './all-processes-panel/all-processes-panel-action';
74 import { Config } from 'common/config';
75 import { pluginConfig } from 'plugins';
76 import { MiddlewareListReducer } from 'common/plugintypes';
77 import { tooltipsMiddleware } from './tooltips/tooltips-middleware';
78 import { sidePanelReducer } from './side-panel/side-panel-reducer';
79 import { bannerReducer } from './banner/banner-reducer';
80 import { multiselectReducer } from './multiselect/multiselect-reducer';
84 __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
88 const composeEnhancers = (process.env.NODE_ENV === 'development' && window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
90 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
92 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
94 export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
95 const rootReducer = createRootReducer(services);
97 const projectPanelMiddleware = dataExplorerMiddleware(new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID));
98 const favoritePanelMiddleware = dataExplorerMiddleware(new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID));
99 const allProcessessPanelMiddleware = dataExplorerMiddleware(new AllProcessesPanelMiddlewareService(services, ALL_PROCESSES_PANEL_ID));
100 const trashPanelMiddleware = dataExplorerMiddleware(new TrashPanelMiddlewareService(services, TRASH_PANEL_ID));
101 const searchResultsPanelMiddleware = dataExplorerMiddleware(new SearchResultsMiddlewareService(services, SEARCH_RESULTS_PANEL_ID));
102 const sharedWithMePanelMiddleware = dataExplorerMiddleware(new SharedWithMeMiddlewareService(services, SHARED_WITH_ME_PANEL_ID));
103 const workflowPanelMiddleware = dataExplorerMiddleware(new WorkflowMiddlewareService(services, WORKFLOW_PANEL_ID));
104 const userPanelMiddleware = dataExplorerMiddleware(new UserMiddlewareService(services, USERS_PANEL_ID));
105 const userProfileGroupsMiddleware = dataExplorerMiddleware(new UserProfileGroupsMiddlewareService(services, USER_PROFILE_PANEL_ID));
106 const groupsPanelMiddleware = dataExplorerMiddleware(new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID));
107 const groupDetailsPanelMembersMiddleware = dataExplorerMiddleware(new GroupDetailsPanelMembersMiddlewareService(services, GROUP_DETAILS_MEMBERS_PANEL_ID));
108 const groupDetailsPanelPermissionsMiddleware = dataExplorerMiddleware(
109 new GroupDetailsPanelPermissionsMiddlewareService(services, GROUP_DETAILS_PERMISSIONS_PANEL_ID)
111 const linkPanelMiddleware = dataExplorerMiddleware(new LinkMiddlewareService(services, LINK_PANEL_ID));
112 const apiClientAuthorizationMiddlewareService = dataExplorerMiddleware(new ApiClientAuthorizationMiddlewareService(services, API_CLIENT_AUTHORIZATION_PANEL_ID));
113 const publicFavoritesMiddleware = dataExplorerMiddleware(new PublicFavoritesMiddlewareService(services, PUBLIC_FAVORITE_PANEL_ID));
114 const collectionsContentAddress = dataExplorerMiddleware(new CollectionsWithSameContentAddressMiddlewareService(services, COLLECTIONS_CONTENT_ADDRESS_PANEL_ID));
115 const subprocessMiddleware = dataExplorerMiddleware(new SubprocessMiddlewareService(services, SUBPROCESS_PANEL_ID));
117 const redirectToMiddleware = (store: any) => (next: any) => (action: any) => {
118 const state = store.getState();
120 if (state.auth && state.auth.apiToken) {
121 handleRedirects(state.auth.apiToken, config);
127 let middlewares: Middleware[] = [
128 routerMiddleware(history),
129 thunkMiddleware.withExtraArgument(services),
130 authMiddleware(services),
131 tooltipsMiddleware(services),
132 projectPanelMiddleware,
133 favoritePanelMiddleware,
134 allProcessessPanelMiddleware,
135 trashPanelMiddleware,
136 searchResultsPanelMiddleware,
137 sharedWithMePanelMiddleware,
138 workflowPanelMiddleware,
140 userProfileGroupsMiddleware,
141 groupsPanelMiddleware,
142 groupDetailsPanelMembersMiddleware,
143 groupDetailsPanelPermissionsMiddleware,
145 apiClientAuthorizationMiddlewareService,
146 publicFavoritesMiddleware,
147 collectionsContentAddress,
148 subprocessMiddleware,
149 treePickerSearchMiddleware,
152 const reduceMiddlewaresFn: (a: Middleware[], b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
154 middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
156 const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
157 return createStore(rootReducer, enhancer);
160 const createRootReducer = (services: ServiceRepository) =>
162 auth: authReducer(services),
163 banner: bannerReducer,
164 collectionPanel: collectionPanelReducer,
165 collectionPanelFiles: collectionPanelFilesReducer,
166 contextMenu: contextMenuReducer,
167 dataExplorer: dataExplorerReducer,
168 detailsPanel: detailsPanelReducer,
169 dialog: dialogReducer,
170 favorites: favoritesReducer,
171 ownerName: ownerNameReducer,
172 publicFavorites: publicFavoritesReducer,
174 processLogsPanel: processLogsPanelReducer,
175 properties: propertiesReducer,
176 resources: resourcesReducer,
177 router: routerReducer,
178 snackbar: snackbarReducer,
179 treePicker: treePickerReducer,
180 treePickerSearch: treePickerSearchReducer,
181 fileUploader: fileUploaderReducer,
182 processPanel: processPanelReducer,
183 progressIndicator: progressIndicatorReducer,
184 runProcessPanel: runProcessPanelReducer,
185 appInfo: appInfoReducer,
186 searchBar: searchBarReducer,
187 virtualMachines: virtualMachinesReducer,
188 repositories: repositoriesReducer,
189 keepServices: keepServicesReducer,
190 linkAccountPanel: linkAccountPanelReducer,
191 sidePanel: sidePanelReducer,
192 multiselect: multiselectReducer,