Merge remote-tracking branch 'origin/main' into 18207-Workbench2-is-not-clearing...
[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 } from './tree-picker/tree-picker-reducer';
30 import { resourcesReducer } from 'store/resources/resources-reducer';
31 import { propertiesReducer } from './properties/properties-reducer';
32 import { fileUploaderReducer } from './file-uploader/file-uploader-reducer';
33 import { TrashPanelMiddlewareService } from "store/trash-panel/trash-panel-middleware-service";
34 import { TRASH_PANEL_ID } from "store/trash-panel/trash-panel-action";
35 import { processLogsPanelReducer } from './process-logs-panel/process-logs-panel-reducer';
36 import { processPanelReducer } from 'store/process-panel/process-panel-reducer';
37 import { SHARED_WITH_ME_PANEL_ID } from 'store/shared-with-me-panel/shared-with-me-panel-actions';
38 import { SharedWithMeMiddlewareService } from './shared-with-me-panel/shared-with-me-middleware-service';
39 import { progressIndicatorReducer } from './progress-indicator/progress-indicator-reducer';
40 import { runProcessPanelReducer } from 'store/run-process-panel/run-process-panel-reducer';
41 import { WorkflowMiddlewareService } from './workflow-panel/workflow-middleware-service';
42 import { WORKFLOW_PANEL_ID } from './workflow-panel/workflow-panel-actions';
43 import { appInfoReducer } from 'store/app-info/app-info-reducer';
44 import { searchBarReducer } from './search-bar/search-bar-reducer';
45 import { SEARCH_RESULTS_PANEL_ID } from 'store/search-results-panel/search-results-panel-actions';
46 import { SearchResultsMiddlewareService } from './search-results-panel/search-results-middleware-service';
47 import { virtualMachinesReducer } from "store/virtual-machines/virtual-machines-reducer";
48 import { repositoriesReducer } from 'store/repositories/repositories-reducer';
49 import { keepServicesReducer } from 'store/keep-services/keep-services-reducer';
50 import { UserMiddlewareService } from 'store/users/user-panel-middleware-service';
51 import { USERS_PANEL_ID } from 'store/users/users-actions';
52 import { GroupsPanelMiddlewareService } from 'store/groups-panel/groups-panel-middleware-service';
53 import { GROUPS_PANEL_ID } from 'store/groups-panel/groups-panel-actions';
54 import { GroupDetailsPanelMembersMiddlewareService } from 'store/group-details-panel/group-details-panel-members-middleware-service';
55 import { GroupDetailsPanelPermissionsMiddlewareService } from 'store/group-details-panel/group-details-panel-permissions-middleware-service';
56 import { GROUP_DETAILS_MEMBERS_PANEL_ID, GROUP_DETAILS_PERMISSIONS_PANEL_ID } from 'store/group-details-panel/group-details-panel-actions';
57 import { LINK_PANEL_ID } from 'store/link-panel/link-panel-actions';
58 import { LinkMiddlewareService } from 'store/link-panel/link-panel-middleware-service';
59 import { API_CLIENT_AUTHORIZATION_PANEL_ID } from 'store/api-client-authorizations/api-client-authorizations-actions';
60 import { ApiClientAuthorizationMiddlewareService } from 'store/api-client-authorizations/api-client-authorizations-middleware-service';
61 import { PublicFavoritesMiddlewareService } from 'store/public-favorites-panel/public-favorites-middleware-service';
62 import { PUBLIC_FAVORITE_PANEL_ID } from 'store/public-favorites-panel/public-favorites-action';
63 import { publicFavoritesReducer } from 'store/public-favorites/public-favorites-reducer';
64 import { linkAccountPanelReducer } from './link-account-panel/link-account-panel-reducer';
65 import { CollectionsWithSameContentAddressMiddlewareService } from 'store/collections-content-address-panel/collections-content-address-middleware-service';
66 import { COLLECTIONS_CONTENT_ADDRESS_PANEL_ID } from 'store/collections-content-address-panel/collections-content-address-panel-actions';
67 import { ownerNameReducer } from 'store/owner-name/owner-name-reducer';
68 import { SubprocessMiddlewareService } from 'store/subprocess-panel/subprocess-panel-middleware-service';
69 import { SUBPROCESS_PANEL_ID } from 'store/subprocess-panel/subprocess-panel-actions';
70 import { ALL_PROCESSES_PANEL_ID } from './all-processes-panel/all-processes-panel-action';
71 import { Config } from 'common/config';
72 import { pluginConfig } from 'plugins';
73 import { MiddlewareListReducer } from 'common/plugintypes';
74
75 declare global {
76     interface Window {
77       __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
78     }
79 }
80
81 const composeEnhancers =
82     (process.env.NODE_ENV === 'development' &&
83         window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
84     compose;
85
86 export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
87
88 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
89
90 export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
91     const rootReducer = createRootReducer(services);
92
93     const projectPanelMiddleware = dataExplorerMiddleware(
94         new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
95     );
96     const favoritePanelMiddleware = dataExplorerMiddleware(
97         new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
98     );
99     const allProcessessPanelMiddleware = dataExplorerMiddleware(
100         new AllProcessesPanelMiddlewareService(services, ALL_PROCESSES_PANEL_ID)
101     );
102     const trashPanelMiddleware = dataExplorerMiddleware(
103         new TrashPanelMiddlewareService(services, TRASH_PANEL_ID)
104     );
105     const searchResultsPanelMiddleware = dataExplorerMiddleware(
106         new SearchResultsMiddlewareService(services, SEARCH_RESULTS_PANEL_ID)
107     );
108     const sharedWithMePanelMiddleware = dataExplorerMiddleware(
109         new SharedWithMeMiddlewareService(services, SHARED_WITH_ME_PANEL_ID)
110     );
111     const workflowPanelMiddleware = dataExplorerMiddleware(
112         new WorkflowMiddlewareService(services, WORKFLOW_PANEL_ID)
113     );
114     const userPanelMiddleware = dataExplorerMiddleware(
115         new UserMiddlewareService(services, USERS_PANEL_ID)
116     );
117     const groupsPanelMiddleware = dataExplorerMiddleware(
118         new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
119     );
120     const groupDetailsPanelMembersMiddleware = dataExplorerMiddleware(
121         new GroupDetailsPanelMembersMiddlewareService(services, GROUP_DETAILS_MEMBERS_PANEL_ID)
122     );
123     const groupDetailsPanelPermissionsMiddleware = dataExplorerMiddleware(
124         new GroupDetailsPanelPermissionsMiddlewareService(services, GROUP_DETAILS_PERMISSIONS_PANEL_ID)
125     );
126     const linkPanelMiddleware = dataExplorerMiddleware(
127         new LinkMiddlewareService(services, LINK_PANEL_ID)
128     );
129     const apiClientAuthorizationMiddlewareService = dataExplorerMiddleware(
130         new ApiClientAuthorizationMiddlewareService(services, API_CLIENT_AUTHORIZATION_PANEL_ID)
131     );
132     const publicFavoritesMiddleware = dataExplorerMiddleware(
133         new PublicFavoritesMiddlewareService(services, PUBLIC_FAVORITE_PANEL_ID)
134     );
135     const collectionsContentAddress = dataExplorerMiddleware(
136         new CollectionsWithSameContentAddressMiddlewareService(services, COLLECTIONS_CONTENT_ADDRESS_PANEL_ID)
137     );
138     const subprocessMiddleware = dataExplorerMiddleware(
139         new SubprocessMiddlewareService(services, SUBPROCESS_PANEL_ID)
140     );
141     const redirectToMiddleware = (store: any) => (next: any) => (action: any) => {
142         const state = store.getState();
143
144         if (state.auth && state.auth.apiToken) {
145             handleRedirects(state.auth.apiToken, config);
146         }
147
148         return next(action);
149     };
150
151     let middlewares: Middleware[] = [
152         routerMiddleware(history),
153         thunkMiddleware.withExtraArgument(services),
154         authMiddleware(services),
155         projectPanelMiddleware,
156         favoritePanelMiddleware,
157         allProcessessPanelMiddleware,
158         trashPanelMiddleware,
159         searchResultsPanelMiddleware,
160         sharedWithMePanelMiddleware,
161         workflowPanelMiddleware,
162         userPanelMiddleware,
163         groupsPanelMiddleware,
164         groupDetailsPanelMembersMiddleware,
165         groupDetailsPanelPermissionsMiddleware,
166         linkPanelMiddleware,
167         apiClientAuthorizationMiddlewareService,
168         publicFavoritesMiddleware,
169         collectionsContentAddress,
170         subprocessMiddleware,
171     ];
172
173     const reduceMiddlewaresFn: (a: Middleware[],
174         b: MiddlewareListReducer) => Middleware[] = (a, b) => b(a, services);
175
176     middlewares = pluginConfig.middlewares.reduce(reduceMiddlewaresFn, middlewares);
177
178     const enhancer = composeEnhancers(applyMiddleware(redirectToMiddleware, ...middlewares));
179     return createStore(rootReducer, enhancer);
180 }
181
182 const createRootReducer = (services: ServiceRepository) => combineReducers({
183     auth: authReducer(services),
184     collectionPanel: collectionPanelReducer,
185     collectionPanelFiles: collectionPanelFilesReducer,
186     contextMenu: contextMenuReducer,
187     dataExplorer: dataExplorerReducer,
188     detailsPanel: detailsPanelReducer,
189     dialog: dialogReducer,
190     favorites: favoritesReducer,
191     ownerName: ownerNameReducer,
192     publicFavorites: publicFavoritesReducer,
193     form: formReducer,
194     processLogsPanel: processLogsPanelReducer,
195     properties: propertiesReducer,
196     resources: resourcesReducer,
197     router: routerReducer,
198     snackbar: snackbarReducer,
199     treePicker: treePickerReducer,
200     fileUploader: fileUploaderReducer,
201     processPanel: processPanelReducer,
202     progressIndicator: progressIndicatorReducer,
203     runProcessPanel: runProcessPanelReducer,
204     appInfo: appInfoReducer,
205     searchBar: searchBarReducer,
206     virtualMachines: virtualMachinesReducer,
207     repositories: repositoriesReducer,
208     keepServices: keepServicesReducer,
209     linkAccountPanel: linkAccountPanelReducer
210 });