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