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