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