diff --git a/alfa-client/libs/admin-settings/src/lib/postfach/postfach-resource.service.ts b/alfa-client/libs/admin-settings/src/lib/postfach/postfach-resource.service.ts index 456685a75a08e35669939e597bf3d83232a17e07..34010640ec7db7066270d0c9ee34133a93679773 100644 --- a/alfa-client/libs/admin-settings/src/lib/postfach/postfach-resource.service.ts +++ b/alfa-client/libs/admin-settings/src/lib/postfach/postfach-resource.service.ts @@ -1,13 +1,13 @@ import { ApiResourceService, + ApiSingleResourceReducer, ResourceRepository, ResourceServiceConfig, - SingleResourceReducer, StateService, - createSingleResourceActions, + createApiSingleResourceActions, } from '@alfa-client/tech-shared'; import { Action, ActionReducerMap } from '@ngrx/store'; -import { SingleResourceState } from 'libs/tech-shared/src/lib/ngrx/state.model'; +import { ApiSingleResourceState } from 'libs/tech-shared/src/lib/ngrx/state.model'; import { SettingsService } from '../admin-settings.service'; import { PostfachLinkRel } from './postfach.linkrel'; import { PostfachResource } from './postfach.model'; @@ -38,9 +38,9 @@ function buildConfig(settingService: SettingsService): ResourceServiceConfig<Pos }; } -export function postfachResourceReducer(state: SingleResourceState, action: Action) { - const resourceReducer: SingleResourceReducer = new SingleResourceReducer( - createSingleResourceActions({ name: POSTFACH_FEATURE_KEY, path: POSTFACH_PATH }), +export function postfachResourceReducer(state: ApiSingleResourceState, action: Action) { + const resourceReducer: ApiSingleResourceReducer = new ApiSingleResourceReducer( + createApiSingleResourceActions({ name: POSTFACH_FEATURE_KEY, path: POSTFACH_PATH }), ); return resourceReducer.reducer(state, action); } diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/actions.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/actions.ts index 331f65845f7cbcd5fae4f014cdd7aca56c7ae665..f80762e6ea0224180bf30f42c06fa6510762cd04 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/actions.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/actions.ts @@ -24,7 +24,7 @@ import { Action, ActionCreator, createAction, props } from '@ngrx/store'; import { TypedAction } from '@ngrx/store/src/models'; import { Resource, ResourceUri } from '@ngxp/rest'; -import { StateInfo } from '../resource/resource.model'; +import { SaveResourceData, StateInfo } from '../resource/resource.model'; import { ApiError, HttpError } from '../tech.model'; export const EMPTY_ACTION: Action = {} as Action; @@ -42,6 +42,7 @@ export interface ResourceUriProps { resourceUri: ResourceUri; } +//TODO rename ResourceSuccessProps export interface LoadResourceSuccessProps { resource: Resource; } @@ -60,6 +61,50 @@ export interface SingleResourceLoadActions extends ResourceActions { loadSuccessAction: TypedActionCreatorWithProps<LoadResourceSuccessProps>; } +export interface SaveProps { + saveResourceData: SaveResourceData; +} +export interface ApiSingleResourceActions extends SingleResourceLoadActions { + saveAction: TypedActionCreatorWithProps<SaveProps>; + saveSuccessAction: TypedActionCreatorWithProps<LoadResourceSuccessProps>; + saveFailureAction: TypedActionCreatorWithProps<LoadResourceFailureProps>; +} + +export function createApiSingleResourceActions(stateInfo: StateInfo): ApiSingleResourceActions { + const actions: SingleResourceLoadActions = createSingleResourceActions(stateInfo); + return { + ...actions, + saveAction: createSaveAction(stateInfo), + saveSuccessAction: createSaveSuccessAction(stateInfo), + saveFailureAction: createSaveFailureAction(stateInfo), + }; +} + +function createSaveAction(stateInfo: StateInfo): TypedActionCreatorWithProps<SaveProps> { + return createAction( + createActionType(stateInfo.name, `Save ${stateInfo.path}`), + props<SaveProps>(), + ); +} + +function createSaveSuccessAction( + stateInfo: StateInfo, +): TypedActionCreatorWithProps<LoadResourceSuccessProps> { + return createAction( + createActionType(stateInfo.name, `Save ${stateInfo.path} Success`), + props<LoadResourceSuccessProps>(), + ); +} + +function createSaveFailureAction( + stateInfo: StateInfo, +): TypedActionCreatorWithProps<LoadResourceFailureProps> { + return createAction( + createActionType(stateInfo.name, `Save ${stateInfo.path} Failure`), + props<LoadResourceFailureProps>(), + ); +} + export function createSingleResourceActions(stateInfo: StateInfo): SingleResourceLoadActions { const actions: ResourceActions = createResourceActions( stateInfo.name, diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/effects.service.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/effects.service.ts index cba87ff7d15b3897c545f50e2dac2b9f6f8eea60..c7838628cfba4661c7adea114af91e7770b2e0b3 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/effects.service.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/effects.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; import { Actions, EffectSources } from '@ngrx/effects'; import { ResourceRepository } from '../resource/resource.repository'; -import { SingleResourceLoadActions } from './actions'; -import { ResourceEffects } from './resource.effects'; +import { ApiSingleResourceActions, SingleResourceLoadActions } from './actions'; +import { ApiResourceEffects, ResourceEffects } from './resource.effects'; @Injectable() export class EffectService { @@ -17,4 +17,10 @@ export class EffectService { ...new ResourceEffects(this.actions$, this.repository, resourceActions), }); } + + public addApiSingleResourceEffects(resourceActions: ApiSingleResourceActions): void { + this.effectSources.addEffects({ + ...new ApiResourceEffects(this.actions$, this.repository, resourceActions), + }); + } } diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.effects.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.effects.ts index ca5100d16f7fce7054fb5c607f2aa32230c95088..abeac902d9a1ef44d7114b061ba8c2e12f8a95e1 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.effects.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.effects.ts @@ -3,13 +3,18 @@ import { Resource } from '@ngxp/rest'; import { of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; import { ResourceRepository } from '../resource/resource.repository'; -import { ResourceUriProps, SingleResourceLoadActions } from './actions'; +import { + ApiSingleResourceActions, + ResourceUriProps, + SaveProps, + SingleResourceLoadActions, +} from './actions'; export class ResourceEffects<T extends Resource> { constructor( - private actions$: Actions, - private repository: ResourceRepository, - private resourceActions: SingleResourceLoadActions, + protected actions$: Actions, + protected repository: ResourceRepository, + protected resourceActions: SingleResourceLoadActions, ) {} loadByUri$ = createEffect(() => @@ -24,3 +29,25 @@ export class ResourceEffects<T extends Resource> { ), ); } + +export class ApiResourceEffects<T extends Resource> extends ResourceEffects<T> { + constructor( + protected actions$: Actions, + protected repository: ResourceRepository, + protected resourceActions: ApiSingleResourceActions, + ) { + super(actions$, repository, resourceActions); + } + + save$ = createEffect(() => + this.actions$.pipe( + ofType(this.resourceActions.saveAction), + switchMap((props: SaveProps) => { + return this.repository.save<T>(props.saveResourceData).pipe( + map((resource: T) => this.resourceActions.saveSuccessAction({ resource })), + catchError((error) => of(this.resourceActions.saveFailureAction({ error }))), + ); + }), + ), + ); +} diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.reducer.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.reducer.ts index 96ed418280bd62c755cba690d74f286e731a8df2..7b5cc4b571df02ec96fcd5cacf04af3eeedee357 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.reducer.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.reducer.ts @@ -1,61 +1,151 @@ -import { Action, ActionReducer, createReducer, on } from '@ngrx/store'; +import { ActionReducer, ReducerTypes, createReducer, on } from '@ngrx/store'; import { createEmptyStateResource, createErrorStateResource, createStateResource, } from '../resource/resource.util'; import { + ApiSingleResourceActions, LoadResourceFailureProps, LoadResourceSuccessProps, SingleResourceLoadActions, } from './actions'; -import { SingleResourceState, initialResourceState } from './state.model'; +import { + ApiSingleResourceState, + SingleResourceState, + initialApiResourceState, + initialResourceState, +} from './state.model'; export class SingleResourceReducer { - public reducer: ActionReducer<SingleResourceState, Action>; + public reducer: ActionReducer<SingleResourceState>; + + protected loadActionReducerType: ReducerTypes<SingleResourceState, any>; + protected loadSuccessActionReducerType: ReducerTypes<SingleResourceState, any>; + protected loadFailureActionReducerType: ReducerTypes<SingleResourceState, any>; + protected clearActionReducerType: ReducerTypes<SingleResourceState, any>; + protected reloadActionReducerType: ReducerTypes<SingleResourceState, any>; - constructor(private actions: SingleResourceLoadActions) { + constructor(protected actions: SingleResourceLoadActions) { + this.initReducerTypes(); this.initReducer(); } - initReducer(): void { + initReducerTypes() { + this.loadActionReducerType = this.createLoadActionReducerType(); + this.loadSuccessActionReducerType = this.createLoadSuccessActionReducerType(); + this.loadFailureActionReducerType = this.createLoadFailureActionReducerType(); + this.clearActionReducerType = this.createClearActionReducerType(); + this.reloadActionReducerType = this.createReloadActionReducerType(); + } + + protected initReducer(): void { this.reducer = createReducer( initialResourceState, - on(this.actions.loadAction, (state: SingleResourceState): SingleResourceState => { + this.loadActionReducerType, + this.loadSuccessActionReducerType, + this.loadFailureActionReducerType, + this.clearActionReducerType, + this.reloadActionReducerType, + ); + } + + createLoadActionReducerType(): ReducerTypes<SingleResourceState, any> { + return on(this.actions.loadAction, (state: SingleResourceState): SingleResourceState => { + return { + ...state, + resource: { ...state.resource, loading: true }, + }; + }); + } + + createLoadSuccessActionReducerType(): ReducerTypes<SingleResourceState, any> { + return on( + this.actions.loadSuccessAction, + (state: SingleResourceState, props: LoadResourceSuccessProps): SingleResourceState => { return { ...state, - resource: { ...state.resource, loading: true }, + resource: createStateResource(props.resource), + }; + }, + ); + } + + createLoadFailureActionReducerType(): ReducerTypes<SingleResourceState, any> { + return on( + this.actions.loadFailureAction, + (state: SingleResourceState, props: LoadResourceFailureProps): SingleResourceState => ({ + ...state, + resource: createErrorStateResource(props.error), + }), + ); + } + + createClearActionReducerType(): ReducerTypes<SingleResourceState, any> { + return on( + this.actions.clearAction, + (state: SingleResourceState): SingleResourceState => ({ + ...state, + resource: createEmptyStateResource(), + }), + ); + } + + createReloadActionReducerType(): ReducerTypes<SingleResourceState, any> { + return on( + this.actions.reloadAction, + (state: SingleResourceState): SingleResourceState => ({ + ...state, + resource: { ...state.resource, reload: true }, + }), + ); + } +} + +export class ApiSingleResourceReducer extends SingleResourceReducer { + public reducer: ActionReducer<ApiSingleResourceState>; + + constructor(protected actions: ApiSingleResourceActions) { + super(actions); + } + + initReducer(): void { + this.reducer = createReducer( + initialApiResourceState, + this.loadActionReducerType, + this.loadSuccessActionReducerType, + this.loadFailureActionReducerType, + this.clearActionReducerType, + this.reloadActionReducerType, + on(this.actions.saveAction, (state: ApiSingleResourceState): ApiSingleResourceState => { + return { + ...state, + saveResource: createEmptyStateResource(true), }; }), on( - this.actions.loadSuccessAction, - (state: SingleResourceState, props: LoadResourceSuccessProps): SingleResourceState => { + this.actions.saveSuccessAction, + ( + state: ApiSingleResourceState, + props: LoadResourceSuccessProps, + ): ApiSingleResourceState => { return { ...state, - resource: createStateResource(props.resource), + saveResource: createStateResource(props.resource), }; }, ), on( - this.actions.loadFailureAction, - (state: SingleResourceState, props: LoadResourceFailureProps): SingleResourceState => ({ - ...state, - resource: createErrorStateResource(props.error), - }), - ), - on( - this.actions.clearAction, - (state: SingleResourceState): SingleResourceState => ({ - ...state, - resource: createEmptyStateResource(), - }), - ), - on( - this.actions.reloadAction, - (state: SingleResourceState): SingleResourceState => ({ - ...state, - resource: { ...state.resource, reload: true }, - }), + this.actions.saveFailureAction, + ( + state: ApiSingleResourceState, + props: LoadResourceFailureProps, + ): ApiSingleResourceState => { + return { + ...state, + saveResource: createErrorStateResource(props.error), + }; + }, ), ); } diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/selector.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/selector.ts index c7c2c27cacef25486909ed0dfcfb01a348daded0..562179270c1e4a939ea30b11b9543adc4f1c4a49 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/selector.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/selector.ts @@ -1,7 +1,8 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; import { StateInfo } from '../resource/resource.model'; -import { SingleResourceState } from './state.model'; +import { ApiSingleResourceState, SingleResourceState } from './state.model'; +//Single Resource State export const selectResource = <T>(stateInfo: StateInfo) => createSelector( createFeatureSelector<SingleResourceState>(stateInfo.name), @@ -16,6 +17,20 @@ export const existResource = <T>(stateInfo: StateInfo) => <T>getFeatureState<SingleResourceState>(stateInfo, state).resource.loaded, ); +//Api Single Resource State +export const selectSaveResource = <T>(stateInfo: StateInfo) => + createSelector( + createFeatureSelector<ApiSingleResourceState>(stateInfo.name), + (state: ApiSingleResourceState) => { + const featureState: ApiSingleResourceState = <ApiSingleResourceState>( + getFeatureState<ApiSingleResourceState>(stateInfo, state) + ); + console.info('SELECT SaveResource: ', featureState.saveResource); + console.info('SELECT Resource: ', featureState.resource); + return <T>getFeatureState<ApiSingleResourceState>(stateInfo, state).saveResource; + }, + ); + function getFeatureState<T>(stateInfo: StateInfo, state: any): T { return <T>state.hasOwnProperty(stateInfo.path) ? state[stateInfo.path] : state; } diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/state.model.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/state.model.ts index b9c0728a3d795a2da96dfdf14af240fbea23189e..6c896aedd5c81b1834f352814896a2df541db6f6 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/state.model.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/state.model.ts @@ -8,3 +8,13 @@ export interface SingleResourceState { export const initialResourceState: SingleResourceState = { resource: createEmptyStateResource<Resource>(), }; + +export interface ApiSingleResourceState { + resource: StateResource<Resource>; + saveResource: StateResource<Resource>; +} + +export const initialApiResourceState: ApiSingleResourceState = { + resource: createEmptyStateResource<Resource>(), + saveResource: createEmptyStateResource<Resource>(), +}; diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/state.service.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/state.service.ts index 9ac8339252c62390a61910e0d7d63d681496b51f..335a02cb176f9d2ec1c312d984cd2bfe9a63c433 100644 --- a/alfa-client/libs/tech-shared/src/lib/ngrx/state.service.ts +++ b/alfa-client/libs/tech-shared/src/lib/ngrx/state.service.ts @@ -1,12 +1,21 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { ResourceUri } from '@ngxp/rest'; +import { Resource, ResourceUri } from '@ngxp/rest'; import { Observable } from 'rxjs'; -import { StateInfo } from '../resource/resource.model'; +import { ResourceServiceConfig } from '../resource/resource.model'; import { StateResource } from '../resource/resource.util'; -import { ResourceActions, SingleResourceLoadActions, createSingleResourceActions } from './actions'; +import { + ApiSingleResourceActions, + ResourceActions, + SaveProps, + SingleResourceLoadActions, + createApiSingleResourceActions, + createSingleResourceActions, +} from './actions'; import { EffectService } from './effects.service'; +import { TypedAction } from '@ngrx/store/src/models'; +import { ApiStateServiceExecuter } from './api-state-service.executer'; import * as ResourceSelectors from './selector'; @Injectable() @@ -16,16 +25,24 @@ export class StateService { private effectService: EffectService, ) {} - public createSingleResourceService<T>(stateInfo: StateInfo): SingleResourceStateService<T> { - return new SingleResourceStateService(stateInfo, this.store, this.effectService); + public createSingleResourceService<B extends Resource, T extends Resource>( + config: ResourceServiceConfig<B>, + ): SingleResourceStateService<B, T> { + return new SingleResourceStateService<B, T>(config, this.store, this.effectService); + } + + public createApiSingleResourceService<B extends Resource, T extends Resource>( + config: ResourceServiceConfig<B>, + ): ApiSingleResourceStateService<B, T> { + return new ApiSingleResourceStateService<B, T>(config, this.store, this.effectService); } } -export abstract class ResourceStateService<T> { +export abstract class ResourceStateService<B extends Resource, T extends Resource> { actions: ResourceActions; constructor( - protected stateInfo: StateInfo, + protected config: ResourceServiceConfig<B>, protected store: Store, protected effectService: EffectService, ) { @@ -56,19 +73,22 @@ export abstract class ResourceStateService<T> { public abstract selectResource(): Observable<StateResource<T>>; } -export class SingleResourceStateService<T> extends ResourceStateService<T> { +export class SingleResourceStateService< + B extends Resource, + T extends Resource, +> extends ResourceStateService<B, T> { actions: SingleResourceLoadActions; constructor( - protected stateInfo: StateInfo, + protected config: ResourceServiceConfig<B>, protected store: Store, protected effectService: EffectService, ) { - super(stateInfo, store, effectService); + super(config, store, effectService); } protected initActions(): void { - this.actions = createSingleResourceActions(this.stateInfo); + this.actions = createSingleResourceActions(this.config.stateInfo); } protected initEffects(): void { @@ -76,10 +96,58 @@ export class SingleResourceStateService<T> extends ResourceStateService<T> { } public selectResource(): Observable<StateResource<T>> { - return this.store.select(ResourceSelectors.selectResource(this.stateInfo)); + return this.store.select(ResourceSelectors.selectResource(this.config.stateInfo)); } public existsResource(): Observable<boolean> { - return this.store.select(ResourceSelectors.existResource(this.stateInfo)); + return this.store.select(ResourceSelectors.existResource(this.config.stateInfo)); + } +} + +export class ApiSingleResourceStateService< + B extends Resource, + T extends Resource, +> extends SingleResourceStateService<B, T> { + actions: ApiSingleResourceActions; + + constructor( + protected config: ResourceServiceConfig<B>, + protected store: Store, + protected effectService: EffectService, + ) { + super(config, store, effectService); + } + + protected initActions(): void { + this.actions = createApiSingleResourceActions(this.config.stateInfo); + } + + protected initEffects(): void { + this.effectService.addApiSingleResourceEffects(this.actions); + } + + public save(toSave: unknown): Observable<StateResource<T>> { + return this.dispatchAction(this.selectSaveResource(), (resource: T) => + this.createSaveAction(resource, toSave), + ); + } + + private createSaveAction(resource: Resource, toSave: unknown): SaveProps & TypedAction<string> { + return this.actions.saveAction({ + saveResourceData: { toSave, resource, linkRel: this.config.edit.linkRel }, + }); + } + + private dispatchAction( + baseResource: Observable<StateResource<T>>, + runnable: (resource: T) => TypedAction<string>, + ): Observable<StateResource<T>> { + return ApiStateServiceExecuter.init<B, T>(this) + .withBaseResource(baseResource) + .execute((resource: T) => this.store.dispatch(runnable(resource))); + } + + private selectSaveResource(): Observable<StateResource<T>> { + return this.store.select(ResourceSelectors.selectSaveResource(this.config.stateInfo)); } } diff --git a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts index a5232c272a4bdd2a8450029159bd6e047d71e1ce..a80310f4f97bc3b408dd4c10f27d5457004041a4 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts @@ -1,23 +1,21 @@ -import { HttpErrorResponse } from '@angular/common/http'; import { Resource } from '@ngxp/rest'; -import { Observable, catchError, map, of, startWith, switchMap, tap, throwError } from 'rxjs'; -import { isUnprocessableEntity } from '../http.util'; -import { StateService } from '../ngrx/state.service'; -import { HttpError } from '../tech.model'; +import { Observable } from 'rxjs'; +import { + ApiSingleResourceStateService, + SingleResourceStateService, + StateService, +} from '../ngrx/state.service'; import { ResourceServiceConfig } from './resource.model'; import { ResourceRepository } from './resource.repository'; import { ResourceService } from './resource.service'; -import { - StateResource, - createEmptyStateResource, - createErrorStateResource, - createStateResource, -} from './resource.util'; +import { StateResource } from './resource.util'; export class ApiResourceService<B extends Resource, T extends Resource> extends ResourceService< B, T > { + protected apiResourceStateService: ApiSingleResourceStateService<B, T>; + constructor( protected config: ResourceServiceConfig<B>, protected stateService: StateService, @@ -26,31 +24,17 @@ export class ApiResourceService<B extends Resource, T extends Resource> extends super(config, stateService); } - public save(toSave: unknown): Observable<StateResource<T | HttpError>> { - return this.selectResource().pipe( - switchMap((stateResource: StateResource<T>) => - this.doSave(stateResource.resource, toSave).pipe( - tap(() => this.reloadResource()), - map((value: T) => createStateResource<T>(value)), - catchError((errorResponse: HttpErrorResponse) => this.handleError(errorResponse)), - ), - ), - startWith(createEmptyStateResource<T | HttpError>(true)), + protected initStateService(): void { + this.apiResourceStateService = this.stateService.createApiSingleResourceService<B, T>( + this.config, ); } - doSave(resource: T, toSave: unknown): Observable<T> { - return this.repository.save<T>({ - resource, - linkRel: this.config.edit.linkRel, - toSave, - }); + protected getResourceStateService(): SingleResourceStateService<B, T> { + return this.apiResourceStateService; } - handleError(errorResponse: HttpErrorResponse): Observable<StateResource<HttpError>> { - if (isUnprocessableEntity(errorResponse.status)) { - return of(createErrorStateResource((<any>errorResponse) as HttpError)); - } - return throwError(() => errorResponse); + public save(toSave: unknown): Observable<StateResource<T>> { + return this.apiResourceStateService.save(toSave); } } diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.model.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.model.ts index f08c137d763e1557b6596bc91c0e49c92e214f8f..185115b7cfe24f40fc07bd27230aeccd3d983499 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/resource.model.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.model.ts @@ -24,8 +24,8 @@ export interface CreateResourceData<T> { toCreate: any; } -export interface SaveResourceData<T> { - resource: T; +export interface SaveResourceData { + resource?: Resource; linkRel: string; toSave: any; } diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts index 2328613ee2ab9f1d74b2fcb1e42ba5a527b2f5c8..48c5f45838503c043e62dcd222cc415ca6f760b4 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts @@ -30,7 +30,7 @@ export class ResourceRepository { return this.resourceFactory.fromId(uri).get(); } - public save<T>(saveResourceData: SaveResourceData<Resource>): Observable<T> { + public save<T>(saveResourceData: SaveResourceData): Observable<T> { return this.resourceFactory .from(saveResourceData.resource) .put(saveResourceData.linkRel, saveResourceData.toSave); diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts index 8e57b59cc664167c27cc07b0d5f10600c904ad16..8d5b3291a67ffe740c74ad4f81832faa05a3fa31 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts @@ -10,7 +10,7 @@ import { StateResource } from './resource.util'; * T = Type of the resource which is working on */ export abstract class ResourceService<B extends Resource, T extends Resource> { - resourceStateService: SingleResourceStateService<T>; + resourceStateService: SingleResourceStateService<B, T>; resourceLoader: ResourceLoader<B, T>; constructor( @@ -21,14 +21,12 @@ export abstract class ResourceService<B extends Resource, T extends Resource> { this.initResourceLoader(); } - private initStateService(): void { - this.resourceStateService = this.stateService.createSingleResourceService( - this.config.stateInfo, - ); + protected initStateService(): void { + this.resourceStateService = this.stateService.createSingleResourceService<B, T>(this.config); } private initResourceLoader(): void { - this.resourceLoader = new ResourceLoader<B, T>(this.config, this.resourceStateService); + this.resourceLoader = new ResourceLoader<B, T>(this.config, this.getResourceStateService()); } public get(): Observable<StateResource<T>> { @@ -36,22 +34,26 @@ export abstract class ResourceService<B extends Resource, T extends Resource> { } public reloadResource(): void { - this.resourceStateService.reloadResource(); + this.getResourceStateService().reloadResource(); } public existResource(): Observable<boolean> { - return this.resourceStateService.existsResource(); + return this.getResourceStateService().existsResource(); } public selectResource(): Observable<StateResource<T>> { - return this.resourceStateService.selectResource(); + return this.getResourceStateService().selectResource(); } public loadByResourceUri(resourceUri: ResourceUri): void { - this.resourceStateService.loadResource(resourceUri); + this.getResourceStateService().loadResource(resourceUri); } public clearResource(): void { - this.resourceStateService.clearResource(); + this.getResourceStateService().clearResource(); + } + + protected getResourceStateService(): SingleResourceStateService<B, T> { + return this.resourceStateService; } }