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