Skip to content

Commit

Permalink
feat: added dbxAppContextState
Browse files Browse the repository at this point in the history
- added ngrx state for dbxAppContextState
  • Loading branch information
dereekb committed Apr 19, 2022
1 parent fe572b2 commit dfc17eb
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 0 deletions.
25 changes: 25 additions & 0 deletions packages/dbx-core/src/lib/context/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

/**
* A contextual state identifier for a specific section of the app.
*
* Some examples are:
* - init: The default context that is initialized.
* - public: A public part of the app.
* - onboarding: The onboarding section of the app.
* - app: The main portion of the app.
*
* More complex apps may have more sub-sections or app portions that could each have their own context state.
*/
export type DbxAppContextState = string;

export const DBX_INIT_APP_CONTEXT_STATE = 'init';
export const DBX_PUBLIC_APP_CONTEXT_STATE = 'public';
export const DBX_ONBOARDING_APP_CONTEXT_STATE = 'onboarding';
export const DBX_APP_APP_CONTEXT_STATE = 'app';

/**
* Default AppContextStates.
*
* Your app may not use these, but this type is available for convenience.
*/
export type DbxKnownAppContextState = typeof DBX_INIT_APP_CONTEXT_STATE | typeof DBX_PUBLIC_APP_CONTEXT_STATE | typeof DBX_ONBOARDING_APP_CONTEXT_STATE | typeof DBX_APP_APP_CONTEXT_STATE;
2 changes: 2 additions & 0 deletions packages/dbx-core/src/lib/context/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './state';
export * from './context';
Empty file.
14 changes: 14 additions & 0 deletions packages/dbx-core/src/lib/context/state/action/data.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createAction, props } from '@ngrx/store';
import { DbxAppContextState } from '../../context';

/**
* Action to set the current DbxAppContextState value.
*/
export const dbxAppContextSetState = createAction('[App/Context] Set State',
props<{ state: DbxAppContextState }>()
);

/**
* Resets the app back to the init context.
*/
export const dbxAppContextResetState = createAction('[App/Context] Reset');
8 changes: 8 additions & 0 deletions packages/dbx-core/src/lib/context/state/action/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as DbxAppContextActions from './data.action';

export {
/**
* Accessor for the DbxAppContextStateData in our DbxAppContextFeatureState.
*/
DbxAppContextActions
};
52 changes: 52 additions & 0 deletions packages/dbx-core/src/lib/context/state/effect/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { OnRunEffects, Actions, EffectNotification, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { exhaustMap, filter, takeUntil } from 'rxjs/operators';
import { DbxAppContextState } from '../../context';
import { onDbxAppContext } from '../';

// MARK: Abstract Context Effects
/**
* Abstract effects class that only runs/allows effects when the DbxAppContextState in the ngrx state matches input activeState value.
*/
export abstract class AbstractOnDbxAppContextStateEffects<S> implements OnRunEffects {

constructor(
/**
* The state to activate on.
*/
private readonly activeState: DbxAppContextState,
/**
* ngrx Actions
*/
protected readonly actions$: Actions,
/**
* ngrx Store
*/
protected readonly store: Store<S>
) { }

/**
* Configures all actions of the sub-class to only activate when the DbxAppContextState in App
*
* @param resolvedEffects$
* @returns
*/
ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>): Observable<EffectNotification> {
return this.actions$.pipe(
ofType(onDbxAppContext.DbxAppContextActions.dbxAppContextSetState),
filter((x) => x.state === this.activeState),
exhaustMap(() =>
resolvedEffects$.pipe(
takeUntil(
this.actions$.pipe(
ofType(onDbxAppContext.DbxAppContextActions.dbxAppContextSetState),
filter((x) => x.state !== this.activeState),
)
)
)
)
);
}

}
13 changes: 13 additions & 0 deletions packages/dbx-core/src/lib/context/state/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as fromDbxAppContext from './reducer'; // our reduce items are exported as "fromDbxAppContext", which lets external types access those items.
import * as onDbxAppContext from './action';

export {
/**
* Accessor for the DbxAppContextFeatureState reducers.
*/
fromDbxAppContext,
/**
* Accessor for the DbxAppContextFeatureState actions.
*/
onDbxAppContext
};
27 changes: 27 additions & 0 deletions packages/dbx-core/src/lib/context/state/reducer/data.reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createReducer, on } from '@ngrx/store';
import { DbxAppContextState, DBX_INIT_APP_CONTEXT_STATE } from '../../context';
import { DbxAppContextActions } from '../action';

/**
* The feature key for these items/reducers.
*/
export const dbxAppContextStateFeatureKey = 'data';

/**
* The typings for this feature.
*/
export interface DbxAppContextStateData {
state: DbxAppContextState;
}

export const initialState: DbxAppContextStateData = {
state: DBX_INIT_APP_CONTEXT_STATE
};

export const reducer = createReducer(
initialState,
/**
* When DbxAppContextActions.dbxAppContextSetState is pushed, update the app's state to match the argument state.
*/
on(DbxAppContextActions.dbxAppContextSetState, (_, { state }) => ({ state }))
);
53 changes: 53 additions & 0 deletions packages/dbx-core/src/lib/context/state/reducer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
Action,
combineReducers,
createFeatureSelector,
createSelector,
} from '@ngrx/store';

import * as fromDbxAppContextState from './data.reducer';

/**
* Global feature key for our app.
*/
export const featureKey = 'app.context';

/**
* This is a "feature state", which in this case is a single feature (our app state), but could include keys/states within this feature.
*/
export interface DbxAppContextFeatureState {
[fromDbxAppContextState.dbxAppContextStateFeatureKey]: fromDbxAppContextState.DbxAppContextStateData;
}

/**
* Interface typing extension for the DbxAppContextFeatureState, and the typing information for how this feature extends the base state.
*/
export interface State {
[featureKey]: DbxAppContextFeatureState;
}

/**
* Reducers mapping for the DbxAppContextFeatureState
*/
export function reducers(state: DbxAppContextFeatureState | undefined, action: Action) {
return combineReducers({
[fromDbxAppContextState.dbxAppContextStateFeatureKey]: fromDbxAppContextState.reducer
})(state, action);
}

/**
* Selects the DbxAppContextFeatureState feature context.
*
* Used by createSelector() to retrieve more specific data from the DbxAppContextFeatureState.
*/
export const selectAppContextFeature = createFeatureSelector<DbxAppContextFeatureState>(
featureKey
);

/**
* Selector to retrieve the state value from our DbxAppContextStateData in our DbxAppContextFeatureState.
*/
export const selectDbxAppContextState = createSelector(
selectAppContextFeature,
(featureState: DbxAppContextFeatureState) => featureState[fromDbxAppContextState.dbxAppContextStateFeatureKey].state
);
10 changes: 10 additions & 0 deletions packages/dbx-core/src/lib/context/state/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as fromDbxContext from './reducer';

/**
* Type that contains the dbx-core contextual ngrx state information.
*
* This is the "full state" of our DbxAppContext. It is the sum of the fromDbxContext.State interface.
*
* Sub-state types that need to be aware of this typeing may extend (via union) this type.
*/
export type DbxAppContextFullState = fromDbxContext.State;
1 change: 1 addition & 0 deletions packages/dbx-core/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './action';
export * from './auth';
export * from './button';
export * from './context';
export * from './router';
export * from './pipe';
export * from './filter';
Expand Down

0 comments on commit dfc17eb

Please sign in to comment.