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