Merge branch '19294-wb2-webdav-url' refs #19294
[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, 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 { sidePanelReducer } from './side-panel/side-panel-reducer'
78 import { bannerReducer } from './banner/banner-reducer';
79
80 declare global {
81     interface Window {
82         __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
83     }
84 }
85
86 const composeEnhancers =
87     (process.env.NODE_ENV === 'development' &&
88         window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
89     compose;
90
91 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
92
93 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
94
95 export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
96     const rootReducer = createRootReducer(services);
97
98     const projectPanelMiddleware = dataExplorerMiddleware(
99         new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
100     );
101     const favoritePanelMiddleware = dataExplorerMiddleware(
102         new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
103     );
104     const allProcessessPanelMiddleware = dataExplorerMiddleware(
105         new AllProcessesPanelMiddlewareService(services, ALL_PROCESSES_PANEL_ID)
106     );
107     const trashPanelMiddleware = dataExplorerMiddleware(
108         new TrashPanelMiddlewareService(services, TRASH_PANEL_ID)
109     );
110     const searchResultsPanelMiddleware = dataExplorerMiddleware(
111         new SearchResultsMiddlewareService(services, SEARCH_RESULTS_PANEL_ID)
112     );
113     const sharedWithMePanelMiddleware = dataExplorerMiddleware(
114         new SharedWithMeMiddlewareService(services, SHARED_WITH_ME_PANEL_ID)
115     );
116     const workflowPanelMiddleware = dataExplorerMiddleware(
117         new WorkflowMiddlewareService(services, WORKFLOW_PANEL_ID)
118     );
119     const userPanelMiddleware = dataExplorerMiddleware(
120         new UserMiddlewareService(services, USERS_PANEL_ID)
121     );
122     const userProfileGroupsMiddleware = dataExplorerMiddleware(
123         new UserProfileGroupsMiddlewareService(services, USER_PROFILE_PANEL_ID)
124     );
125     const groupsPanelMiddleware = dataExplorerMiddleware(
126         new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
127     );
128     const groupDetailsPanelMembersMiddleware = dataExplorerMiddleware(
129         new GroupDetailsPanelMembersMiddlewareService(services, GROUP_DETAILS_MEMBERS_PANEL_ID)
130     );
131     const groupDetailsPanelPermissionsMiddleware = dataExplorerMiddleware(
132         new GroupDetailsPanelPermissionsMiddlewareService(services, GROUP_DETAILS_PERMISSIONS_PANEL_ID)
133     );
134     const linkPanelMiddleware = dataExplorerMiddleware(
135         new LinkMiddlewareService(services, LINK_PANEL_ID)
136     );
137     const apiClientAuthorizationMiddlewareService = dataExplorerMiddleware(
138         new ApiClientAuthorizationMiddlewareService(services, API_CLIENT_AUTHORIZATION_PANEL_ID)
139     );
140     const publicFavoritesMiddleware = dataExplorerMiddleware(
141         new PublicFavoritesMiddlewareService(services, PUBLIC_FAVORITE_PANEL_ID)
142     );
143     const collectionsContentAddress = dataExplorerMiddleware(
144         new CollectionsWithSameContentAddressMiddlewareService(services, COLLECTIONS_CONTENT_ADDRESS_PANEL_ID)
145     );
146     const subprocessMiddleware = dataExplorerMiddleware(
147         new SubprocessMiddlewareService(services, SUBPROCESS_PANEL_ID)
148     );
149     const redirectToMiddleware = (store: any) => (next: any) => (action: any) => {
150         const state = store.getState();
151
152         if (state.auth && state.auth.apiToken) {
153             handleRedirects(state.auth.apiToken, config);
154         }
155
156         return next(action);
157     };
158
159     let middlewares: Middleware[] = [
160         routerMiddleware(history),
161         thunkMiddleware.withExtraArgument(services),
162         authMiddleware(services),
163         projectPanelMiddleware,
164         favoritePanelMiddleware,
165         allProcessessPanelMiddleware,
166         trashPanelMiddleware,
167         searchResultsPanelMiddleware,
168         sharedWithMePanelMiddleware,
169         workflowPanelMiddleware,
170         userPanelMiddleware,
171         userProfileGroupsMiddleware,
172         groupsPanelMiddleware,
173         groupDetailsPanelMembersMiddleware,
174         groupDetailsPanelPermissionsMiddleware,
175         linkPanelMiddleware,
176         apiClientAuthorizationMiddlewareService,
177         publicFavoritesMiddleware,
178         collectionsContentAddress,
179         subprocessMiddleware,
180         treePickerSearchMiddleware
181     ];
182
183     const reduceMiddlewaresFn: (a: Middleware[],
184         b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
185
186     middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
187
188     const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
189     return createStore(rootReducer, enhancer);
190 }
191
192 const createRootReducer = (services: ServiceRepository) => combineReducers({
193     auth: authReducer(services),
194     banner: bannerReducer,
195     collectionPanel: collectionPanelReducer,
196     collectionPanelFiles: collectionPanelFilesReducer,
197     contextMenu: contextMenuReducer,
198     dataExplorer: dataExplorerReducer,
199     detailsPanel: detailsPanelReducer,
200     dialog: dialogReducer,
201     favorites: favoritesReducer,
202     ownerName: ownerNameReducer,
203     publicFavorites: publicFavoritesReducer,
204     form: formReducer,
205     processLogsPanel: processLogsPanelReducer,
206     properties: propertiesReducer,
207     resources: resourcesReducer,
208     router: routerReducer,
209     snackbar: snackbarReducer,
210     treePicker: treePickerReducer,
211     treePickerSearch: treePickerSearchReducer,
212     fileUploader: fileUploaderReducer,
213     processPanel: processPanelReducer,
214     progressIndicator: progressIndicatorReducer,
215     runProcessPanel: runProcessPanelReducer,
216     appInfo: appInfoReducer,
217     searchBar: searchBarReducer,
218     virtualMachines: virtualMachinesReducer,
219     repositories: repositoriesReducer,
220     keepServices: keepServicesReducer,
221     linkAccountPanel: linkAccountPanelReducer,
222     sidePanel: sidePanelReducer
223 });