Merge remote-tracking branch 'origin/main' 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
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         tooltipsMiddleware(services),
164         projectPanelMiddleware,
165         favoritePanelMiddleware,
166         allProcessessPanelMiddleware,
167         trashPanelMiddleware,
168         searchResultsPanelMiddleware,
169         sharedWithMePanelMiddleware,
170         workflowPanelMiddleware,
171         userPanelMiddleware,
172         userProfileGroupsMiddleware,
173         groupsPanelMiddleware,
174         groupDetailsPanelMembersMiddleware,
175         groupDetailsPanelPermissionsMiddleware,
176         linkPanelMiddleware,
177         apiClientAuthorizationMiddlewareService,
178         publicFavoritesMiddleware,
179         collectionsContentAddress,
180         subprocessMiddleware,
181         treePickerSearchMiddleware
182     ];
183
184     const reduceMiddlewaresFn: (a: Middleware[],
185         b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
186
187     middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
188
189     const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
190     return createStore(rootReducer, enhancer);
191 }
192
193 const createRootReducer = (services: ServiceRepository) => combineReducers({
194     auth: authReducer(services),
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 });