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