-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
846 additions
and
515 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
export interface Contact { | ||
id: string; | ||
firstName: string; | ||
lastName: string; | ||
} | ||
|
||
export interface ContactWithoutId { | ||
id?: string; | ||
firstName: string; | ||
lastName: string; | ||
} | ||
|
||
|
78 changes: 78 additions & 0 deletions
78
apps/showcase/src/components/showcase/tanstack/store/contact/contact.actions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { | ||
asyncProps, | ||
AsyncRequest, | ||
FailAsyncStoreItemEntitiesActionPayload, | ||
FromApiActionPayload, | ||
SetActionPayload, | ||
SetAsyncStoreItemEntitiesActionPayload, | ||
UpdateActionPayload, | ||
UpdateAsyncStoreItemEntitiesActionPayloadWithId | ||
} from '@o3r/core'; | ||
|
||
import {createAction, props} from '@ngrx/store'; | ||
// import {ContactModel} from './contact.state'; | ||
import {ContactStateDetails} from './contact.state'; | ||
import type { Contact } from '../../contact'; | ||
|
||
/** StateDetailsActions */ | ||
const ACTION_SET = '[Contact] set'; | ||
const ACTION_UPDATE = '[Contact] update'; | ||
const ACTION_RESET = '[Contact] reset'; | ||
const ACTION_CANCEL_REQUEST = '[Contact] cancel request'; | ||
|
||
/** Entity Actions */ | ||
const ACTION_CLEAR_ENTITIES = '[Contact] clear entities'; | ||
const ACTION_UPDATE_ENTITIES = '[Contact] update entities'; | ||
const ACTION_UPSERT_ENTITIES = '[Contact] upsert entities'; | ||
const ACTION_SET_ENTITIES = '[Contact] set entities'; | ||
const ACTION_FAIL_ENTITIES = '[Contact] fail entities'; | ||
|
||
/** Async Actions */ | ||
const ACTION_SET_ENTITIES_FROM_API = '[Contact] set entities from api'; | ||
const ACTION_UPDATE_ENTITIES_FROM_API = '[Contact] update entities from api'; | ||
const ACTION_UPSERT_ENTITIES_FROM_API = '[Contact] upsert entities from api'; | ||
|
||
/** Action to clear the StateDetails of the store and replace it */ | ||
export const setContact = createAction(ACTION_SET, props<SetActionPayload<ContactStateDetails>>()); | ||
|
||
/** Action to change a part or the whole object in the store. */ | ||
export const updateContact = createAction(ACTION_UPDATE, props<UpdateActionPayload<ContactStateDetails>>()); | ||
|
||
/** Action to reset the whole state, by returning it to initial state. */ | ||
export const resetContact = createAction(ACTION_RESET); | ||
|
||
/** Action to cancel a Request ID registered in the store. Can happen from effect based on a switchMap for instance */ | ||
export const cancelContactRequest = createAction(ACTION_CANCEL_REQUEST, props<AsyncRequest>()); | ||
|
||
/** Action to clear all contact and fill the store with the payload */ | ||
export const setContactEntities = createAction(ACTION_SET_ENTITIES, props<SetAsyncStoreItemEntitiesActionPayload<Contact>>()); | ||
|
||
/** Action to update contact with known IDs, ignore the new ones */ | ||
export const updateContactEntities = createAction(ACTION_UPDATE_ENTITIES, props<UpdateAsyncStoreItemEntitiesActionPayloadWithId<Contact>>()); | ||
|
||
/** Action to update contact with known IDs, insert the new ones */ | ||
export const upsertContactEntities = createAction(ACTION_UPSERT_ENTITIES, props<SetAsyncStoreItemEntitiesActionPayload<Contact>>()); | ||
|
||
/** Action to empty the list of entities, keeping the global state */ | ||
export const clearContactEntities = createAction(ACTION_CLEAR_ENTITIES); | ||
|
||
/** Action to update failureStatus for every ContactModel */ | ||
export const failContactEntities = createAction(ACTION_FAIL_ENTITIES, props<FailAsyncStoreItemEntitiesActionPayload<any>>()); | ||
|
||
/** | ||
* Action to put the global status of the store in a pending state. Call SET action with the list of ContactModels received, when this action resolves. | ||
* If the call fails, dispatch FAIL_ENTITIES action | ||
*/ | ||
export const setContactEntitiesFromApi = createAction(ACTION_SET_ENTITIES_FROM_API, asyncProps<FromApiActionPayload<Contact[]>>()); | ||
|
||
/** | ||
* Action to change isPending status of elements to be updated with a request. Call UPDATE action with the list of ContactModels received, when this action resolves. | ||
* If the call fails, dispatch FAIL_ENTITIES action | ||
*/ | ||
export const updateContactEntitiesFromApi = createAction(ACTION_UPDATE_ENTITIES_FROM_API, asyncProps<FromApiActionPayload<Contact[]> & { ids: string[] }>()); | ||
|
||
/** | ||
* Action to put global status of the store in a pending state. Call UPSERT action with the list of ContactModels received, when this action resolves. | ||
* If the call fails, dispatch FAIL_ENTITIES action | ||
*/ | ||
export const upsertContactEntitiesFromApi = createAction(ACTION_UPSERT_ENTITIES_FROM_API, asyncProps<FromApiActionPayload<Contact[]>>()); |
66 changes: 66 additions & 0 deletions
66
apps/showcase/src/components/showcase/tanstack/store/contact/contact.effect.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import {Injectable} from '@angular/core'; | ||
import {Actions, createEffect, ofType} from '@ngrx/effects'; | ||
import {from, of} from 'rxjs'; | ||
import {catchError, map, mergeMap} from 'rxjs/operators'; | ||
import {fromApiEffectSwitchMap} from '@o3r/core'; | ||
import { | ||
cancelContactRequest, | ||
failContactEntities, | ||
setContactEntities, setContactEntitiesFromApi, | ||
updateContactEntities, updateContactEntitiesFromApi, | ||
upsertContactEntities, upsertContactEntitiesFromApi | ||
} from './contact.actions'; | ||
|
||
/** | ||
* Service to handle async Contact actions | ||
*/ | ||
@Injectable() | ||
export class ContactEffect { | ||
|
||
/** | ||
* Set the entities with the reply content, dispatch failContactEntities if it catches a failure | ||
*/ | ||
public setEntitiesFromApi$ = createEffect(() => | ||
this.actions$.pipe( | ||
ofType(setContactEntitiesFromApi), | ||
fromApiEffectSwitchMap( | ||
(reply, action) => setContactEntities({entities: reply, requestId: action.requestId}), | ||
(error, action) => of(failContactEntities({error, requestId: action.requestId})), | ||
cancelContactRequest | ||
) | ||
) | ||
); | ||
|
||
/** | ||
* Update the entities with the reply content, dispatch failContactEntities if it catches a failure | ||
*/ | ||
public updateEntitiesFromApi$ = createEffect(() => | ||
this.actions$.pipe( | ||
ofType(updateContactEntitiesFromApi), | ||
mergeMap((payload) => | ||
from(payload.call).pipe( | ||
map((reply) => updateContactEntities({entities: reply, requestId: payload.requestId})), | ||
catchError((err) => of(failContactEntities({ids: payload.ids, error: err, requestId: payload.requestId}))) | ||
) | ||
) | ||
) | ||
); | ||
|
||
/** | ||
* Upsert the entities with the reply content, dispatch failContactEntities if it catches a failure | ||
*/ | ||
public upsertEntitiesFromApi$ = createEffect(() => | ||
this.actions$.pipe( | ||
ofType(upsertContactEntitiesFromApi), | ||
mergeMap((payload) => | ||
from(payload.call).pipe( | ||
map((reply) => upsertContactEntities({entities: reply, requestId: payload.requestId})), | ||
catchError((err) => of(failContactEntities({error: err, requestId: payload.requestId}))) | ||
) | ||
) | ||
) | ||
); | ||
|
||
constructor(protected actions$: Actions) { | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
apps/showcase/src/components/showcase/tanstack/store/contact/contact.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { InjectionToken, ModuleWithProviders, NgModule } from '@angular/core'; | ||
import { Action, ActionReducer, StoreModule } from '@ngrx/store'; | ||
|
||
import { EffectsModule } from '@ngrx/effects'; | ||
import { ContactEffect } from './contact.effect'; | ||
import { contactReducer } from './contact.reducer'; | ||
import { CONTACT_STORE_NAME, ContactState } from './contact.state'; | ||
|
||
/** Token of the Contact reducer */ | ||
export const CONTACT_REDUCER_TOKEN = new InjectionToken<ActionReducer<ContactState, Action>>('Feature Contact Reducer'); | ||
|
||
/** Provide default reducer for Contact store */ | ||
export function getDefaultContactReducer() { | ||
return contactReducer; | ||
} | ||
|
||
@NgModule({ | ||
imports: [ | ||
StoreModule.forFeature(CONTACT_STORE_NAME, CONTACT_REDUCER_TOKEN), EffectsModule.forFeature([ContactEffect]) | ||
], | ||
providers: [ | ||
{ provide: CONTACT_REDUCER_TOKEN, useFactory: getDefaultContactReducer } | ||
] | ||
}) | ||
export class ContactStoreModule { | ||
public static forRoot<T extends ContactState>(reducerFactory: () => ActionReducer<T, Action>): ModuleWithProviders<ContactStoreModule> { | ||
return { | ||
ngModule: ContactStoreModule, | ||
providers: [ | ||
{ provide: CONTACT_REDUCER_TOKEN, useFactory: reducerFactory } | ||
] | ||
}; | ||
} | ||
} |
Oops, something went wrong.