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