From 65a4727cd0e39fec20f5b8749c0289c59cb78111 Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Fri, 24 May 2024 20:20:21 +0200
Subject: [PATCH] OZG-5012 extract store handling; reduce config; cleanup PoC

---
 .../src/lib/admin-settings.module.ts          |  9 ++-
 .../configuration-resource.service.ts         | 24 ++-----
 .../lib/postfach/postfach-resource.service.ts | 23 ++----
 .../src/lib/bescheid.service.ts               | 23 ++----
 .../src/lib/command-resource.service.ts       |  8 +--
 alfa-client/libs/tech-shared/src/index.ts     |  2 +-
 ...ucer.service.ts => del.reducer.service.ts} |  2 +-
 ...rce.reducer.ts => del.resource.reducer.ts} |  0
 .../src/lib/ngrx/resource.selector.ts         | 36 +---------
 .../src/lib/ngrx/resource.state.service.ts    | 71 +++++++++++++++++++
 .../src/lib/resource/api-resource.service.ts  |  8 +--
 .../src/lib/resource/resource.model.ts        |  5 +-
 .../src/lib/resource/resource.service.ts      | 59 +++------------
 .../tech-shared/src/lib/tech-shared.module.ts |  2 +
 14 files changed, 116 insertions(+), 156 deletions(-)
 rename alfa-client/libs/tech-shared/src/lib/ngrx/{reducer.service.ts => del.reducer.service.ts} (98%)
 rename alfa-client/libs/tech-shared/src/lib/ngrx/{resource.reducer.ts => del.resource.reducer.ts} (100%)
 create mode 100644 alfa-client/libs/tech-shared/src/lib/ngrx/resource.state.service.ts

diff --git a/alfa-client/libs/admin-settings/src/lib/admin-settings.module.ts b/alfa-client/libs/admin-settings/src/lib/admin-settings.module.ts
index f74bece4f9..5a004145d5 100644
--- a/alfa-client/libs/admin-settings/src/lib/admin-settings.module.ts
+++ b/alfa-client/libs/admin-settings/src/lib/admin-settings.module.ts
@@ -6,9 +6,8 @@ import { NgModule } from '@angular/core';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterModule } from '@angular/router';
 import KcAdminClient from '@keycloak/keycloak-admin-client';
-import { Store, StoreModule } from '@ngrx/store';
-import { EffectService } from 'libs/tech-shared/src/lib/ngrx/effects.service';
-import { ReducerService } from 'libs/tech-shared/src/lib/ngrx/reducer.service';
+import { StoreModule } from '@ngrx/store';
+import { StateService } from 'libs/tech-shared/src/lib/ngrx/resource.state.service';
 import {
   createSettingListResourceService,
   SettingListResourceService,
@@ -92,7 +91,7 @@ import { TextFieldComponent } from './shared/text-field/text-field.component';
     {
       provide: ConfigurationResourceService,
       useFactory: createConfigurationResourceService,
-      deps: [ResourceRepository, ApiRootService, Store, ReducerService, EffectService],
+      deps: [ResourceRepository, ApiRootService, StateService],
     },
     {
       provide: SettingListResourceService,
@@ -102,7 +101,7 @@ import { TextFieldComponent } from './shared/text-field/text-field.component';
     {
       provide: PostfachResourceService,
       useFactory: createPostfachResourceService,
-      deps: [ResourceRepository, SettingsService, Store, ReducerService, EffectService],
+      deps: [ResourceRepository, SettingsService, StateService],
     },
   ],
 })
diff --git a/alfa-client/libs/admin-settings/src/lib/configuration/configuration-resource.service.ts b/alfa-client/libs/admin-settings/src/lib/configuration/configuration-resource.service.ts
index bd2cc74a1b..6a90a9b2cf 100644
--- a/alfa-client/libs/admin-settings/src/lib/configuration/configuration-resource.service.ts
+++ b/alfa-client/libs/admin-settings/src/lib/configuration/configuration-resource.service.ts
@@ -7,9 +7,8 @@ import {
   ResourceState,
   createResourceAction,
 } from '@alfa-client/tech-shared';
-import { Action, ActionReducerMap, Store } from '@ngrx/store';
-import { EffectService } from 'libs/tech-shared/src/lib/ngrx/effects.service';
-import { ReducerService } from 'libs/tech-shared/src/lib/ngrx/reducer.service';
+import { Action, ActionReducerMap } from '@ngrx/store';
+import { StateService } from 'libs/tech-shared/src/lib/ngrx/resource.state.service';
 import { ConfigurationResource } from './configuration.model';
 
 export const CONFIGURATION_FEATURE_KEY = 'ConfigurationState';
@@ -24,27 +23,16 @@ export class ConfigurationResourceService extends ApiResourceService<
 export function createConfigurationResourceService(
   repository: ResourceRepository,
   apiRootService: ApiRootService,
-  store: Store,
-  reducerService: ReducerService,
-  effectService: EffectService,
+  stateService: StateService,
 ) {
-  return new ApiResourceService(
-    buildConfig(apiRootService, store),
-    repository,
-    reducerService,
-    effectService,
-  );
+  return new ApiResourceService(buildConfig(apiRootService), stateService, repository);
 }
 
-function buildConfig(
-  apiRootService: ApiRootService,
-  store: Store,
-): ResourceServiceConfig<ApiRootResource> {
+function buildConfig(apiRootService: ApiRootService): ResourceServiceConfig<ApiRootResource> {
   return {
     stateInfo: {
-      store,
       name: CONFIGURATION_FEATURE_KEY,
-      resourcePath: CONFIGURATION_PATH,
+      featureName: CONFIGURATION_PATH,
     },
     resource: apiRootService.getApiRoot(),
     getLinkRel: ApiRootLinkRel.CONFIGURATION,
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 9fe53d9cc5..c7e1a5203f 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
@@ -6,9 +6,8 @@ import {
   ResourceState,
   createResourceAction,
 } from '@alfa-client/tech-shared';
-import { Action, ActionReducerMap, Store } from '@ngrx/store';
-import { EffectService } from 'libs/tech-shared/src/lib/ngrx/effects.service';
-import { ReducerService } from 'libs/tech-shared/src/lib/ngrx/reducer.service';
+import { Action, ActionReducerMap } from '@ngrx/store';
+import { StateService } from 'libs/tech-shared/src/lib/ngrx/resource.state.service';
 import { SettingsService } from '../admin-settings.service';
 import { PostfachLinkRel } from './postfach.linkrel';
 import { PostfachResource } from './postfach.model';
@@ -25,24 +24,14 @@ export class PostfachResourceService extends ApiResourceService<
 export function createPostfachResourceService(
   repository: ResourceRepository,
   settingService: SettingsService,
-  store: Store,
-  reducerService: ReducerService,
-  effectService: EffectService,
+  stateService: StateService,
 ) {
-  return new ApiResourceService(
-    buildConfig(settingService, store),
-    repository,
-    reducerService,
-    effectService,
-  );
+  return new ApiResourceService(buildConfig(settingService), stateService, repository);
 }
 
-function buildConfig(
-  settingService: SettingsService,
-  store: Store,
-): ResourceServiceConfig<PostfachResource> {
+function buildConfig(settingService: SettingsService): ResourceServiceConfig<PostfachResource> {
   return {
-    stateInfo: { store, name: POSTFACH_FEATURE_KEY, resourcePath: POSTFACH_PATH },
+    stateInfo: { name: POSTFACH_FEATURE_KEY, featureName: POSTFACH_PATH },
     resource: settingService.getPostfach(),
     getLinkRel: PostfachLinkRel.SELF,
     edit: { linkRel: PostfachLinkRel.SELF },
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
index f74441d8fb..17b847e574 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
@@ -32,10 +32,8 @@ import {
 } from '@alfa-client/vorgang-shared';
 import { getEmpfaenger } from '@alfa-client/vorgang-shared-ui';
 import { Injectable } from '@angular/core';
-import { Store } from '@ngrx/store';
 import { ResourceUri, getUrl, hasLink } from '@ngxp/rest';
-import { EffectService } from 'libs/tech-shared/src/lib/ngrx/effects.service';
-import { ReducerService } from 'libs/tech-shared/src/lib/ngrx/reducer.service';
+import { StateService } from 'libs/tech-shared/src/lib/ngrx/resource.state.service';
 import {
   BehaviorSubject,
   Observable,
@@ -53,7 +51,7 @@ import {
 } from '../../../tech-shared/src/lib/resource/resource.model';
 import { ResourceRepository } from '../../../tech-shared/src/lib/resource/resource.repository';
 import { BescheidFacade } from './+state/bescheid.facade';
-import { BESCHEID_DRAFT_PATH, BESCHEID_FEATURE_KEY, reducer } from './+state/bescheid.reducer';
+import { BESCHEID_DRAFT_PATH, BESCHEID_FEATURE_KEY } from './+state/bescheid.reducer';
 import { BescheidLinkRel, BescheidListLinkRel } from './bescheid.linkrel';
 import {
   Bescheid,
@@ -109,14 +107,11 @@ export class BescheidService {
     private readonly vorgangCommandService: VorgangCommandService,
     private readonly binaryFileService: BinaryFileService,
     private readonly repository: ResourceRepository,
-    private readonly effectService: EffectService,
-    private readonly store: Store,
-    private readonly reducerService: ReducerService,
+    private readonly stateService: StateService,
   ) {
     this.bescheidDraftService = new CommandResourceService(
       this.buildBescheidDraftServiceConfig(),
-      this.reducerService,
-      this.effectService,
+      this.stateService,
       this.commandService,
     );
     this.bescheidListService = new ResourceListService(
@@ -128,10 +123,8 @@ export class BescheidService {
   buildBescheidDraftServiceConfig(): ResourceServiceConfig<VorgangWithEingangResource> {
     return {
       stateInfo: {
-        store: this.store,
         name: BESCHEID_FEATURE_KEY,
-        resourcePath: BESCHEID_DRAFT_PATH,
-        additionalReducer: [reducer],
+        featureName: BESCHEID_DRAFT_PATH,
       },
       resource: this.vorgangService.getVorgangWithEingang(),
       getLinkRel: VorgangWithEingangLinkRel.BESCHEID_DRAFT,
@@ -149,12 +142,6 @@ export class BescheidService {
   }
 
   public init(): void {
-    // this.bescheidDraftService = new CommandResourceService(
-    //   this.buildBescheidDraftServiceConfig(),
-    //   this.reducerService,
-    //   this.effectService,
-    //   this.commandService,
-    // );
     this.bescheidDocumentFile$.next(createEmptyStateResource());
     this.bescheidDocumentUri$.next(null);
   }
diff --git a/alfa-client/libs/command-shared/src/lib/command-resource.service.ts b/alfa-client/libs/command-shared/src/lib/command-resource.service.ts
index c9546c10bc..2916c3b28a 100644
--- a/alfa-client/libs/command-shared/src/lib/command-resource.service.ts
+++ b/alfa-client/libs/command-shared/src/lib/command-resource.service.ts
@@ -7,8 +7,7 @@ import {
   isStateResoureStable,
 } from '@alfa-client/tech-shared';
 import { Resource } from '@ngxp/rest';
-import { EffectService } from 'libs/tech-shared/src/lib/ngrx/effects.service';
-import { ReducerService } from 'libs/tech-shared/src/lib/ngrx/reducer.service';
+import { StateService } from 'libs/tech-shared/src/lib/ngrx/resource.state.service';
 import { Observable, filter, startWith, switchMap } from 'rxjs';
 import { CommandResource, CreateCommandProps } from './command.model';
 import { tapOnCommandSuccessfullyDone } from './command.rxjs.operator';
@@ -20,11 +19,10 @@ export class CommandResourceService<B extends Resource, T extends Resource> exte
 > {
   constructor(
     protected config: ResourceServiceConfig<B>,
-    protected reducerService: ReducerService,
-    protected effectService: EffectService,
+    protected stateService: StateService,
     private commandService: CommandService,
   ) {
-    super(config, reducerService, effectService);
+    super(config, stateService);
   }
 
   public delete(): Observable<StateResource<CommandResource>> {
diff --git a/alfa-client/libs/tech-shared/src/index.ts b/alfa-client/libs/tech-shared/src/index.ts
index 42a4680e0a..2742a9d0d8 100644
--- a/alfa-client/libs/tech-shared/src/index.ts
+++ b/alfa-client/libs/tech-shared/src/index.ts
@@ -31,7 +31,7 @@ export * from './lib/form.util';
 export * from './lib/http.util';
 export * from './lib/message-code';
 export * from './lib/ngrx/actions';
-export * from './lib/ngrx/resource.reducer';
+export * from './lib/ngrx/del.resource.reducer';
 export * from './lib/ngrx/resource.state';
 export * from './lib/pipe/convert-for-data-test.pipe';
 export * from './lib/pipe/convert-to-boolean.pipe';
diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/reducer.service.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/del.reducer.service.ts
similarity index 98%
rename from alfa-client/libs/tech-shared/src/lib/ngrx/reducer.service.ts
rename to alfa-client/libs/tech-shared/src/lib/ngrx/del.reducer.service.ts
index 1922c286d8..6163f7e96c 100644
--- a/alfa-client/libs/tech-shared/src/lib/ngrx/reducer.service.ts
+++ b/alfa-client/libs/tech-shared/src/lib/ngrx/del.reducer.service.ts
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
 import { Action, ActionReducer, ActionReducerMap, ReducerManager } from '@ngrx/store';
 import { StateInfo } from '../resource/resource.model';
 import { ResourceActions } from './actions';
-import { ResourceReducer } from './resource.reducer';
+import { ResourceReducer } from './del.resource.reducer';
 import { ResourceState } from './resource.state';
 
 @Injectable({
diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.reducer.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/del.resource.reducer.ts
similarity index 100%
rename from alfa-client/libs/tech-shared/src/lib/ngrx/resource.reducer.ts
rename to alfa-client/libs/tech-shared/src/lib/ngrx/del.resource.reducer.ts
diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.selector.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.selector.ts
index 71fd1d8e32..d510a104ef 100644
--- a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.selector.ts
+++ b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.selector.ts
@@ -4,10 +4,9 @@ import { StateInfo } from '../resource/resource.model';
 import { ResourceState } from './resource.state';
 
 function getState<T>(stateInfo: StateInfo, state: any): ResourceState {
-  console.info(stateInfo.name + ' - GetState Selector: ', state);
   return (
-    isUndefined(stateInfo.resourcePath) ? state
-    : state.hasOwnProperty(stateInfo.resourcePath) ? state[stateInfo.resourcePath]
+    isUndefined(stateInfo.featureName) ? state
+    : state.hasOwnProperty(stateInfo.featureName) ? state[stateInfo.featureName]
     : state
   );
 }
@@ -23,34 +22,3 @@ export const existResource = <T>(stateInfo: StateInfo) =>
     createFeatureSelector<ResourceState>(stateInfo.name),
     (state: ResourceState) => <T>(<any>getState(stateInfo, state).resource)?.loaded,
   );
-
-// export class ResourceSelector {
-//   public featureSelector;
-//   public resourceSelector;
-//   public existResourceSelector;
-//   private stateData: StateInfo;
-//   constructor(stateData: StateInfo) {
-//     this.stateData = stateData;
-//     this.featureSelector = createFeatureSelector(this.stateData.name);
-//     this.resourceSelector = this.createResourceSelector();
-//     this.existResourceSelector = this.createExistResourceSelector();
-//   }
-//   private createResourceSelector() {
-//     return <T>(stateInfo: StateInfo) =>
-//       createSelector(
-//         this.featureSelector,
-//         (state: ResourceState | ResourceSubState) => <T>this.getState(stateInfo, state).resource,
-//       );
-//   }
-//   private createExistResourceSelector() {
-//     return <T>(stateInfo: StateInfo) =>
-//       createSelector(
-//         this.featureSelector,
-//         (state: ResourceState | ResourceSubState) =>
-//           <T>this.getState(stateInfo, state).resource.loaded,
-//       );
-//   }
-//   private getState<T>(stateInfo: StateInfo, state: any): ResourceState<T> {
-//     return isUndefined(stateInfo.resourcePath) ? state : state[stateInfo.resourcePath];
-//   }
-// }
diff --git a/alfa-client/libs/tech-shared/src/lib/ngrx/resource.state.service.ts b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.state.service.ts
new file mode 100644
index 0000000000..450a98e2d8
--- /dev/null
+++ b/alfa-client/libs/tech-shared/src/lib/ngrx/resource.state.service.ts
@@ -0,0 +1,71 @@
+import { Injectable } from '@angular/core';
+import { Store } from '@ngrx/store';
+import { ResourceUri } from '@ngxp/rest';
+import { Observable } from 'rxjs';
+import { StateInfo } from '../resource/resource.model';
+import { StateResource } from '../resource/resource.util';
+import { ResourceActions, createResourceAction } from './actions';
+import { EffectService } from './effects.service';
+
+import * as ResourceSelectors from '../ngrx/resource.selector';
+
+@Injectable()
+export class StateService {
+  constructor(
+    private store: Store,
+    private effectService: EffectService,
+  ) {}
+
+  public createInstance(): ResourceStateService {
+    return new ResourceStateService(this.store, this.effectService);
+  }
+}
+
+export class ResourceStateService {
+  stateInfo: StateInfo;
+  actions: ResourceActions;
+
+  constructor(
+    private store: Store,
+    private effectService: EffectService,
+  ) {}
+
+  public init(stateInfo: StateInfo) {
+    this.stateInfo = stateInfo;
+    this.createActions(stateInfo.name);
+    this.initEffects();
+    return this;
+  }
+
+  private createActions(featureName: string): void {
+    this.actions = createResourceAction(featureName);
+  }
+
+  private initEffects(): void {
+    this.effectService.addEffects(this.actions);
+  }
+
+  getActions(): ResourceActions {
+    return this.actions;
+  }
+
+  clear(): void {
+    this.store.dispatch(this.actions.clearAction());
+  }
+
+  load(resourceUri: ResourceUri): void {
+    this.store.dispatch(this.actions.loadAction({ resourceUri }));
+  }
+
+  reload(): void {
+    this.store.dispatch(this.actions.reloadAction());
+  }
+
+  getResource<T>(): Observable<StateResource<T>> {
+    return this.store.select(ResourceSelectors.selectResource(this.stateInfo));
+  }
+
+  existsResource(): Observable<boolean> {
+    return this.store.select(ResourceSelectors.existResource(this.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 9828e168fe..87c58ca194 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,8 +1,7 @@
 import { HttpErrorResponse } from '@angular/common/http';
 import { Resource } from '@ngxp/rest';
 import { Observable, catchError, map, startWith, switchMap, tap } from 'rxjs';
-import { EffectService } from '../ngrx/effects.service';
-import { ReducerService } from '../ngrx/reducer.service';
+import { StateService } from '../ngrx/resource.state.service';
 import { HttpError } from '../tech.model';
 import { ResourceServiceConfig } from './resource.model';
 import { ResourceRepository } from './resource.repository';
@@ -15,11 +14,10 @@ export class ApiResourceService<B extends Resource, T extends Resource> extends
 > {
   constructor(
     protected config: ResourceServiceConfig<B>,
+    protected stateService: StateService,
     protected repository: ResourceRepository,
-    protected reducerService: ReducerService,
-    protected effectService: EffectService,
   ) {
-    super(config, reducerService, effectService);
+    super(config, stateService);
   }
 
   public save(toSave: unknown): Observable<StateResource<T | HttpError>> {
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 b0fbf7528b..79afc9e0b9 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
@@ -1,4 +1,3 @@
-import { Action, ActionReducer, Store } from '@ngrx/store';
 import { Resource } from '@ngxp/rest';
 import { Observable } from 'rxjs';
 import { StateResource } from './resource.util';
@@ -28,9 +27,7 @@ export declare type LinkRelationName = string;
 
 export interface StateInfo {
   name: string;
-  store?: Store;
-  resourcePath?: string;
-  additionalReducer?: ActionReducer<any, Action>[];
+  featureName: string;
 }
 
 export interface ResourceServiceConfig<B> {
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 692f810cfc..3323096ec1 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
@@ -1,12 +1,9 @@
 import { HttpErrorResponse } from '@angular/common/http';
-import { Store } from '@ngrx/store';
 import { Resource, ResourceUri, getUrl, hasLink } from '@ngxp/rest';
 import { isEqual, isNull } from 'lodash-es';
 import { Observable, combineLatest, filter, of, startWith, tap, throwError } from 'rxjs';
 import { isUnprocessableEntity } from '../http.util';
-import { ResourceActions, createResourceAction } from '../ngrx/actions';
-import { EffectService } from '../ngrx/effects.service';
-import { ReducerService } from '../ngrx/reducer.service';
+import { ResourceStateService, StateService } from '../ngrx/resource.state.service';
 import { HttpError } from '../tech.model';
 import { isNotNull } from '../tech.util';
 import { ResourceServiceConfig } from './resource.model';
@@ -20,8 +17,6 @@ import {
   isStateResoureStable,
 } from './resource.util';
 
-import * as ResourceSelectors from '../ngrx/resource.selector';
-
 /**
  * B = Type of baseresource
  * T = Type of the resource which is working on
@@ -29,30 +24,17 @@ import * as ResourceSelectors from '../ngrx/resource.selector';
 export abstract class ResourceService<B extends Resource, T extends Resource> {
   configResource: B = null;
 
-  resourceActions: ResourceActions;
+  resourceStateService: ResourceStateService;
 
   constructor(
     protected config: ResourceServiceConfig<B>,
-    protected reducerService: ReducerService,
-    protected effectService: EffectService,
+    protected stateService: StateService,
   ) {
-    this.initActions();
-    this.initReducer();
-    this.addEffect();
-  }
-
-  initActions() {
-    this.resourceActions = createResourceAction(this.config.stateInfo.name);
-  }
-
-  private addEffect(): void {
-    console.info('add effects for: ', this.config.stateInfo.name);
-    this.effectService.addEffects(this.resourceActions);
+    this.createStateService();
   }
 
-  private initReducer(): void {
-    console.info('add reducer for: ', this.config.stateInfo.name);
-    this.reducerService.addFeatureReducer(this.config.stateInfo, this.resourceActions);
+  createStateService(): void {
+    this.resourceStateService = this.stateService.createInstance().init(this.config.stateInfo);
   }
 
   public get(): Observable<StateResource<T>> {
@@ -95,7 +77,7 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
   }
 
   clearStateResource(): void {
-    this.store.dispatch(this.resourceActions.clearAction());
+    this.resourceStateService.clear();
   }
   //
 
@@ -136,22 +118,11 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
   }
 
   doLoadResource(resourceUri: ResourceUri): void {
-    // const action = Actions.loadResource({
-    //   resourceUri,
-    //   resourcePath: this.config.stateInfo.resourcePath,
-    // });
-    this.store.dispatch(
-      this.resourceActions.loadAction({
-        resourceUri,
-        resourcePath: this.config.stateInfo.resourcePath,
-      }),
-      // Actions.loadResource({ resourceUri, resourcePath: this.config.stateInfo.resourcePath }),
-    );
+    this.resourceStateService.load(resourceUri);
   }
 
   getResource(): Observable<StateResource<T>> {
-    // return this.store.select(this.selector.resourceSelector);
-    return this.store.select(ResourceSelectors.selectResource(this.config.stateInfo));
+    return this.resourceStateService.getResource();
   }
 
   handleError(errorResponse: HttpErrorResponse): Observable<StateResource<HttpError>> {
@@ -161,19 +132,11 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
     return throwError(() => errorResponse);
   }
 
-  // abstract doSave(resource: T, toSave: unknown): Observable<StateResource<T>>;
-
   public refresh(): void {
-    this.store.dispatch(this.resourceActions.reloadAction());
-    // this.store.dispatch(ResourceActions.reloadResource());
+    this.resourceStateService.reload();
   }
 
   public exists(): Observable<boolean> {
-    // return this.store.select(this.selector.existResourceSelector);
-    return this.store.select(ResourceSelectors.existResource(this.config.stateInfo));
-  }
-
-  private get store(): Store {
-    return this.config.stateInfo.store;
+    return this.resourceStateService.existsResource();
   }
 }
diff --git a/alfa-client/libs/tech-shared/src/lib/tech-shared.module.ts b/alfa-client/libs/tech-shared/src/lib/tech-shared.module.ts
index 6d81cbece9..f8992bb61a 100644
--- a/alfa-client/libs/tech-shared/src/lib/tech-shared.module.ts
+++ b/alfa-client/libs/tech-shared/src/lib/tech-shared.module.ts
@@ -27,6 +27,7 @@ import { Injector, NgModule } from '@angular/core';
 import { HttpBinaryFileInterceptor } from './interceptor/http-binary-file.interceptor';
 import { HttpXsrfInterceptor } from './interceptor/http-xsrf.interceptor';
 import { XhrInterceptor } from './interceptor/xhr.interceptor';
+import { StateService } from './ngrx/resource.state.service';
 import { ConvertForDataTestPipe } from './pipe/convert-for-data-test.pipe';
 import { ConvertToBooleanPipe } from './pipe/convert-to-boolean.pipe';
 import { EnumToLabelPipe } from './pipe/enum-to-label.pipe';
@@ -86,6 +87,7 @@ import { ToTrafficLightPipe } from './pipe/to-traffic-light.pipe';
     ConvertToBooleanPipe,
   ],
   providers: [
+    StateService,
     {
       provide: HTTP_INTERCEPTORS,
       useClass: XhrInterceptor,
-- 
GitLab