Skip to content

Commit

Permalink
feat(stark-core): update settings actions style
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
Due to an improvement on how actions are defined, the enum `StarkSettingsActionsTypes`
became obsolete so it has been removed.

As a result, the following actions have been changed:
- `StarkPersistPreferredLanguage(public language: string)`
  -> `StarkSettingsActions.persistPreferredLanguage({ language: string })`
- `StarkPersistPreferredLanguageSuccess()`
  -> `StarkSettingsActions.persistPreferredLanguageSuccess()`
- `StarkPersistPreferredLanguageFailure(public error: any)`
  -> `StarkSettingsActions.persistPreferredLanguageFailure({ error: any })`
- `StarkSetPreferredLanguage(public language: string)`
  -> `StarkSettingsActions.setPreferredLanguage({ language: string })`

And also the previous union type has been replaced:
`StarkSettingsActions` -> `StarkSettingsActions.Types`.

Change in effect:

```typescript
// Before
@effect({ dispatch: false })
public starkSetPreferredLanguage$(): Observable<void> {
    return this.actions$.pipe(
        ofType<StarkSetPreferredLanguage>(StarkSettingsActionsTypes.SET_PREFERRED_LANGUAGE),
        map((action: StarkSetPreferredLanguage) => {
            // some logic
        })
    );
}

// After
public starkSetPreferredLanguage$ = createEffect(
    () => this.actions$.pipe(
        ofType(StarkSettingsActions.setPreferredLanguage),
        map((action) => {
            // some logic
        })
    ),
    { dispatch: false }
);
```

Change in `action` usage:

```typescript
// Before
this.store.dispatch(new StarkSetPreferredLanguage(language));

// After
this.store.dispatch(StarkSettingsActions.StarkSetPreferredLanguage({ language: language }));
```
  • Loading branch information
SuperITMan committed May 3, 2021
1 parent 810bbc1 commit f1803a8
Show file tree
Hide file tree
Showing 14 changed files with 81 additions and 118 deletions.
1 change: 1 addition & 0 deletions packages/stark-core/src/modules/settings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./settings/actions";
export * from "./settings/constants";
export * from "./settings/effects";
export * from "./settings/entities";
export * from "./settings/reducers";
Expand Down
3 changes: 2 additions & 1 deletion packages/stark-core/src/modules/settings/actions.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./actions/settings.actions";
import * as StarkSettingsActions from "./actions/settings.actions";
export { StarkSettingsActions };
Original file line number Diff line number Diff line change
@@ -1,81 +1,43 @@
import { Action } from "@ngrx/store";

/**
* All the Settings action types
*/
export enum StarkSettingsActionTypes {
PERSIST_PREFERRED_LANGUAGE = "[StarkSettings] Persist Preferred Language",
PERSIST_PREFERRED_LANGUAGE_SUCCESS = "[StarkSettings] Persist Preferred Language Success",
PERSIST_PREFERRED_LANGUAGE_FAILURE = "[StarkSettings] Persist Preferred Language Failure",
SET_PREFERRED_LANGUAGE = "[StarkSettings] Set Preferred Language"
}
import { createAction, props, union } from "@ngrx/store";
import { starkSettingsStoreKey } from "../constants";

/**
* Action that requires to persist the given language locally so that the language remains the same when the user comes back
* @returns The created action object
*
* Parameter:
* - language - The language to persist
*/
export class StarkPersistPreferredLanguage implements Action {
/**
* The type of action
*/
public readonly type: StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE = StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE;

/**
* Class constructor
* @param language - The language to persist
*/
public constructor(public language: string) {}
}
export const persistPreferredLanguage = createAction(
`[${starkSettingsStoreKey}] Persist Preferred Language`,
props<{ language: string }>()
);

/**
* Action that notifies the application that the preferred language was successfully persisted.
* @returns The created action object
*/
export class StarkPersistPreferredLanguageSuccess implements Action {
/**
* The type of action
*/
public readonly type: StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE_SUCCESS =
StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE_SUCCESS;
}
export const persistPreferredLanguageSuccess = createAction(`[${starkSettingsStoreKey}] Persist Preferred Language Success`);

/**
* Action that notifies the application that the preferred language could not be persisted.
* @returns The created action object
*
* Parameter:
* - error - The reason why the preferred language could not be persisted
*/
export class StarkPersistPreferredLanguageFailure implements Action {
/**
* The type of action
*/
public readonly type: StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE_FAILURE =
StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE_FAILURE;

/**
* Class constructor
* @param error - The reason why the preferred language could not be persisted
*/
public constructor(public error: any) {}
}
export const persistPreferredLanguageFailure = createAction(
`[${starkSettingsStoreKey}] Persist Preferred Language Failure`,
props<{ error: any }>()
);

/**
* Action that notifies the application that the preferred language should be changed.
* @returns The created action object
*
* Parameter:
* - language - The new preferred language
*/
export class StarkSetPreferredLanguage implements Action {
/**
* The type of action
*/
public readonly type: StarkSettingsActionTypes.SET_PREFERRED_LANGUAGE = StarkSettingsActionTypes.SET_PREFERRED_LANGUAGE;

/**
* Class constructor
* @param language - The new preferred language
*/
public constructor(public language: string) {}
}
export const setPreferredLanguage = createAction(`[${starkSettingsStoreKey}] Set Preferred Language`, props<{ language: string }>());

export type StarkSettingsActions =
| StarkPersistPreferredLanguage
| StarkPersistPreferredLanguageSuccess
| StarkPersistPreferredLanguageFailure
| StarkSetPreferredLanguage;
/**
* @ignore
*/
const all = union({ persistPreferredLanguage, persistPreferredLanguageSuccess, persistPreferredLanguageFailure, setPreferredLanguage });
export type Types = typeof all;
1 change: 1 addition & 0 deletions packages/stark-core/src/modules/settings/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./constants/settings-store-key";
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Key defined to find the service in a store
*/
export const starkSettingsStoreKey = "StarkSettings";
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import SpyObj = jasmine.SpyObj;
import createSpyObj = jasmine.createSpyObj;
import { StarkSettingsEffects } from "./settings.effects";
import { StarkSetPreferredLanguage } from "../actions";
import { StarkSettingsActions } from "../actions";
import { STARK_SESSION_SERVICE } from "../../session/services";
import { MockStarkSessionService } from "@nationalbankbelgium/stark-core/testing";
import { TestBed } from "@angular/core/testing";
Expand Down Expand Up @@ -41,9 +41,9 @@ describe("Effect: StarkSettingsEffects", () => {
const subject: ReplaySubject<any> = new ReplaySubject(1);
actions = subject.asObservable();

settingsEffects.setPreferredLanguage$().subscribe(mockObserver);
settingsEffects.setPreferredLanguage$.subscribe(mockObserver);

subject.next(new StarkSetPreferredLanguage("NL"));
subject.next(StarkSettingsActions.setPreferredLanguage({ language: "NL" }));

expect(mockSessionService.setCurrentLanguage).toHaveBeenCalledWith("NL");
expect(mockObserver.next).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Inject, Injectable } from "@angular/core";
import { Actions, Effect, ofType } from "@ngrx/effects";
import { Observable } from "rxjs";
import { Actions, createEffect, ofType } from "@ngrx/effects";
import { map } from "rxjs/operators";

import { StarkSetPreferredLanguage, StarkSettingsActionTypes } from "../actions";
import { StarkSettingsActions } from "../actions";
import { STARK_SESSION_SERVICE, StarkSessionService } from "../../session/services";

/**
Expand All @@ -23,11 +22,12 @@ export class StarkSettingsEffects {
*
* `dispatch: false` => because this effect does not dispatch an action
*/
@Effect({ dispatch: false })
public setPreferredLanguage$(): Observable<void> {
return this.actions$.pipe(
ofType<StarkSetPreferredLanguage>(StarkSettingsActionTypes.SET_PREFERRED_LANGUAGE),
map((action: StarkSetPreferredLanguage) => this.sessionService.setCurrentLanguage(action.language))
);
}
public setPreferredLanguage$ = createEffect(
() =>
this.actions$.pipe(
ofType(StarkSettingsActions.setPreferredLanguage),
map((action) => this.sessionService.setCurrentLanguage(action.language))
),
{ dispatch: false }
);
}
4 changes: 2 additions & 2 deletions packages/stark-core/src/modules/settings/reducers.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./reducers/index";
export * from "./reducers/settings.reducer";
export { selectStarkSettings, starkSettingsReducers, StarkSettingsState } from "./reducers/index";
export { settingsReducer } from "./reducers/settings.reducer";
9 changes: 5 additions & 4 deletions packages/stark-core/src/modules/settings/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ActionReducerMap, createFeatureSelector, createSelector, MemoizedSelector } from "@ngrx/store";
import { ActionReducerMap, createFeatureSelector, createSelector } from "@ngrx/store";
import { StarkSettings } from "../entities";
import { StarkSettingsActions } from "../actions";
import { settingsReducer } from "./settings.reducer";
import { starkSettingsStoreKey } from "../constants";

/**
* Defines the part of the state assigned to the {@link StarkSettingsModule}
Expand All @@ -16,7 +17,7 @@ export interface StarkSettingsState {
/**
* Reducers assigned to each property of the {@link StarkSettingsModule}'s state
*/
export const starkSettingsReducers: ActionReducerMap<StarkSettingsState, StarkSettingsActions> = {
export const starkSettingsReducers: ActionReducerMap<StarkSettingsState, StarkSettingsActions.Types> = {
/**
* Reducer assigned to the state's `settings` property
*/
Expand All @@ -26,7 +27,7 @@ export const starkSettingsReducers: ActionReducerMap<StarkSettingsState, StarkSe
/**
* NGRX Selector for the {@link StarkSettingsModule}'s state
*/
export const selectStarkSettings: MemoizedSelector<object, StarkSettings> = createSelector(
createFeatureSelector<StarkSettingsState>("StarkSettings"),
export const selectStarkSettings = createSelector(
createFeatureSelector<StarkSettingsState>(starkSettingsStoreKey),
(state: StarkSettingsState) => state.settings
);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*tslint:disable:completed-docs*/
import { StarkSetPreferredLanguage } from "../actions";
import { StarkSettingsActions } from "../actions";
import { StarkSettings } from "../entities";
import { settingsReducer } from "./settings.reducer";

Expand All @@ -19,12 +19,18 @@ describe("Reducer: SettingsReducer", () => {
deepFreeze(initialState); // Enforce immutability

// Send the SET_PREFERRED_LANGUAGE action to the settingsReducer
const changedState: StarkSettings = settingsReducer(<StarkSettings>initialState, new StarkSetPreferredLanguage("NL"));
const changedState: StarkSettings = settingsReducer(
<StarkSettings>initialState,
StarkSettingsActions.setPreferredLanguage({ language: "NL" })
);
expect(changedState.preferredLanguage).toBe("NL");
});
it("should set the preferred language when state not defined", () => {
// Send the SET_PREFERRED_LANGUAGE action to the settingsReducer
const changedState: StarkSettings = settingsReducer(<any>undefined, new StarkSetPreferredLanguage("NL"));
const changedState: StarkSettings = settingsReducer(
<any>undefined,
StarkSettingsActions.setPreferredLanguage({ language: "NL" })
);
expect(changedState.preferredLanguage).toBe("NL");
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { StarkSettingsActions, StarkSettingsActionTypes } from "../actions";
import { StarkSettingsActions } from "../actions";
import { StarkSettings } from "../entities";
import { createReducer, on } from "@ngrx/store";

/**
* Key defined to find the service in a store
* Defines the initial state of the reducer
*/
export const starkSettingsStoreKey = "starkSettings";
const INITIAL_SETTINGS_STATE: StarkSettings = new StarkSettings();

/**
* Defines the initial state of the reducer
* Definition of the reducer using `createReducer` method.
*/
const INITIAL_SETTINGS_STATE: StarkSettings = new StarkSettings();
const reducer = createReducer<StarkSettings, StarkSettingsActions.Types>(
INITIAL_SETTINGS_STATE,
on(StarkSettingsActions.setPreferredLanguage, (state, action) => ({ ...state, preferredLanguage: action.language }))
);

/**
* Definition of the `settings` reducer
Expand All @@ -18,26 +22,8 @@ const INITIAL_SETTINGS_STATE: StarkSettings = new StarkSettings();
* @returns The new `StarkSettings` state
*/
export function settingsReducer(
state: Readonly<StarkSettings> = INITIAL_SETTINGS_STATE,
action: Readonly<StarkSettingsActions>
state: StarkSettings | undefined,
action: StarkSettingsActions.Types
): Readonly<StarkSettings> {
// the new state will be calculated from the data coming in the actions
switch (action.type) {
case StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE_SUCCESS:
return state;

case StarkSettingsActionTypes.PERSIST_PREFERRED_LANGUAGE_FAILURE:
return state;

// this case is ignored by the reducer as it does not result in a state change
// an effect takes care of doing what needs to be done with it
// case StarkSettingsActions.PERSIST_PREFERRED_LANGUAGE:
// return state;

case StarkSettingsActionTypes.SET_PREFERRED_LANGUAGE:
return { ...state, preferredLanguage: action.language };

default:
return state;
}
return reducer(state, action);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "../../../configuration/entities";
import { StarkCoreApplicationState } from "../../../common/store";
import { StarkSettingsServiceImpl } from "./settings.service";
import { StarkSetPreferredLanguage } from "../actions";
import { StarkSettingsActions } from "../actions";
import { StarkUser } from "../../user/entities";
import { of } from "rxjs";
import SpyObj = jasmine.SpyObj;
Expand Down Expand Up @@ -165,7 +165,7 @@ describe("Service: StarkSettingsService", () => {
settingsService.setPreferredLanguage("NL");

expect(mockStore.dispatch).toHaveBeenCalledTimes(1);
expect(mockStore.dispatch.calls.argsFor(0)[0]).toEqual(new StarkSetPreferredLanguage("NL"));
expect(mockStore.dispatch.calls.argsFor(0)[0]).toEqual(StarkSettingsActions.setPreferredLanguage({ language: "NL" }));
expect(settingsService.preferredLanguage).toEqual("NL");
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { filter } from "rxjs/operators";
import { STARK_LOGGING_SERVICE, StarkLoggingService } from "../../logging/services";
import { STARK_SESSION_SERVICE, StarkSessionService } from "../../session/services";
import { StarkSettingsService, starkSettingsServiceName } from "./settings.service.intf";
import { StarkSetPreferredLanguage } from "../actions";
import { StarkSettingsActions } from "../actions";
import {
STARK_APP_CONFIG,
STARK_APP_METADATA,
Expand Down Expand Up @@ -80,7 +80,7 @@ export class StarkSettingsServiceImpl implements StarkSettingsService {

public setPreferredLanguage(language: string): void {
this.preferredLanguage = language;
this.store.dispatch(new StarkSetPreferredLanguage(language));
this.store.dispatch(StarkSettingsActions.setPreferredLanguage({ language: language }));
}

public findMatchingSupportedLanguage(language: string): number {
Expand Down
3 changes: 2 additions & 1 deletion packages/stark-core/src/modules/settings/settings.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { ModuleWithProviders, NgModule, Optional, SkipSelf } from "@angular/core
import { StoreModule } from "@ngrx/store";
import { EffectsModule } from "@ngrx/effects";
import { starkSettingsReducers } from "./reducers";
import { starkSettingsStoreKey } from "./constants";
import { STARK_SETTINGS_SERVICE, StarkSettingsServiceImpl } from "./services";
import { StarkSettingsEffects } from "./effects";

@NgModule({
imports: [StoreModule.forFeature("StarkSettings", starkSettingsReducers), EffectsModule.forFeature([StarkSettingsEffects])]
imports: [StoreModule.forFeature(starkSettingsStoreKey, starkSettingsReducers), EffectsModule.forFeature([StarkSettingsEffects])]
})
export class StarkSettingsModule {
/**
Expand Down

0 comments on commit f1803a8

Please sign in to comment.