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));
116 const redirectToMiddleware = (store: any) => (next: any) => (action: any) => {
117 const state = store.getState();
119 if (state.auth && state.auth.apiToken) {
120 handleRedirects(state.auth.apiToken, config);
126 let middlewares: Middleware[] = [
127 routerMiddleware(history),
128 thunkMiddleware.withExtraArgument(services),
129 authMiddleware(services),
130 tooltipsMiddleware(services),
131 projectPanelMiddleware,
132 favoritePanelMiddleware,
133 allProcessessPanelMiddleware,
134 trashPanelMiddleware,
135 searchResultsPanelMiddleware,
136 sharedWithMePanelMiddleware,
137 workflowPanelMiddleware,
139 userProfileGroupsMiddleware,
140 groupsPanelMiddleware,
141 groupDetailsPanelMembersMiddleware,
142 groupDetailsPanelPermissionsMiddleware,
144 apiClientAuthorizationMiddlewareService,
145 publicFavoritesMiddleware,
146 collectionsContentAddress,
147 subprocessMiddleware,
148 treePickerSearchMiddleware,
151 const reduceMiddlewaresFn: (a: Middleware[], b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
153 middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
155 const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
156 return createStore(rootReducer, enhancer);
159 const createRootReducer = (services: ServiceRepository) =>
161 auth: authReducer(services),
162 banner: bannerReducer,
163 collectionPanel: collectionPanelReducer,
164 collectionPanelFiles: collectionPanelFilesReducer,
165 contextMenu: contextMenuReducer,
166 dataExplorer: dataExplorerReducer,
167 detailsPanel: detailsPanelReducer,
168 dialog: dialogReducer,
169 favorites: favoritesReducer,
170 ownerName: ownerNameReducer,
171 publicFavorites: publicFavoritesReducer,
173 processLogsPanel: processLogsPanelReducer,
174 properties: propertiesReducer,
175 resources: resourcesReducer,
176 router: routerReducer,
177 snackbar: snackbarReducer,
178 treePicker: treePickerReducer,
179 treePickerSearch: treePickerSearchReducer,
180 fileUploader: fileUploaderReducer,
181 processPanel: processPanelReducer,
182 progressIndicator: progressIndicatorReducer,
183 runProcessPanel: runProcessPanelReducer,
184 appInfo: appInfoReducer,
185 searchBar: searchBarReducer,
186 virtualMachines: virtualMachinesReducer,
187 repositories: repositoriesReducer,
188 keepServices: keepServicesReducer,
189 linkAccountPanel: linkAccountPanelReducer,
190 sidePanel: sidePanelReducer,
191 multiselect: multiselectReducer,