/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { combineReducers, createStore, Store } from "redux"; import { ActionsUnion, createAction, DeepReadonly, FrameworkReducer, FrameworkState } from "@bentley/ui-framework"; // Valid values for SwitchIModelState.switchState export enum SwitchState { None = 0, SelectIModel = 1, SelectSnapshot = 2, OpenIModel = 3, OpenSnapshot = 4, } export interface SelectedIModel { imodelId: string; contextId: string; } // State handling for switching iModels export interface SwitchIModelState { switchState: SwitchState; selectedIModel: SelectedIModel | null; selectedSnapshot: string; } const initialState: SwitchIModelState = { switchState: SwitchState.None, selectedIModel: null, selectedSnapshot: "", }; // eslint-disable-next-line @typescript-eslint/naming-convention export const SwitchIModelActions = { selectIModel: () => createAction("App:SELECT_IMODEL", {}), selectSnapshot: () => createAction("App:SELECT_SNAPSHOT", {}), openIModel: (selectedIModel: SelectedIModel) => createAction("App:OPEN_IMODEL", selectedIModel), openSnapshot: (selectedSnapshot: string) => createAction("App:OPEN_SNAPSHOT", selectedSnapshot), }; export type SwitchIModelActionsUnion = ActionsUnion<typeof SwitchIModelActions>; // eslint-disable-next-line @typescript-eslint/naming-convention function AppReducer(state: SwitchIModelState = initialState, action: SwitchIModelActionsUnion): DeepReadonly<SwitchIModelState> { switch (action.type) { case "App:SELECT_IMODEL": return { ...state, switchState: SwitchState.SelectIModel }; case "App:SELECT_SNAPSHOT": return { ...state, switchState: SwitchState.SelectSnapshot }; case "App:OPEN_IMODEL": return { ...state, switchState: SwitchState.OpenIModel, selectedIModel: action.payload }; case "App:OPEN_SNAPSHOT": return { ...state, switchState: SwitchState.OpenSnapshot, selectedSnapshot: action.payload }; default: return { ...state, switchState: SwitchState.None }; } } // React-redux interface stuff export interface RootState { switchIModelState: SwitchIModelState; frameworkState?: FrameworkState; } export type AppStore = Store<RootState>; /** * Centralized state management class using Redux actions, reducers and store. */ export class AppState { private _store: AppStore; private _rootReducer: any; constructor() { // this is the rootReducer for the application. this._rootReducer = combineReducers<RootState>({ switchIModelState: AppReducer, frameworkState: FrameworkReducer, } as any); // create the Redux Store. this._store = createStore(this._rootReducer, (window as any).__REDUX_DEVTOOLS_EXTENSION__ && (window as any).__REDUX_DEVTOOLS_EXTENSION__()); } public get store(): Store<RootState> { return this._store; } }