From 28b7c31784b0353ad33a72f2e5cd6c8e7bcf6947 Mon Sep 17 00:00:00 2001 From: Manfred Steyer Date: Sat, 28 Sep 2024 10:44:18 +0200 Subject: [PATCH] feat: add store to coupling feature --- .detective/hash | 2 +- .detective/log | 6 ++ .../features/coupling/coupling.component.html | 13 +++- .../features/coupling/coupling.component.ts | 73 +++++++------------ .../app/features/coupling/coupling.store.ts | 66 +++++++++++++++++ 5 files changed, 110 insertions(+), 50 deletions(-) create mode 100644 apps/frontend/src/app/features/coupling/coupling.store.ts diff --git a/.detective/hash b/.detective/hash index b3d1459..df57060 100644 --- a/.detective/hash +++ b/.detective/hash @@ -1 +1 @@ -b710a462a265c9bf0de882fc6886c806a46d2279, v1.1.2 \ No newline at end of file +37698fb21ae14ef200051ddf81bbee302fd731c1, v1.1.2 \ No newline at end of file diff --git a/.detective/log b/.detective/log index 5f87259..2d85790 100644 --- a/.detective/log +++ b/.detective/log @@ -1,3 +1,9 @@ +"Manfred Steyer ,Fri Sep 27 22:48:19 2024 +0200 76656b36d327a6c9f45040294c99cc83a30d84b0,refactor(frontend): remove unnecessary rendering effect in hotspot component" +1 1 .detective/hash +9 0 .detective/log +5 1 apps/frontend/src/app/features/hotspot/hotspot.component.html +26 7 apps/frontend/src/app/features/hotspot/hotspot.component.ts + "Manfred Steyer ,Fri Sep 27 22:20:25 2024 +0200 5547a7c4196a2ba80acb704250c0a76d9e1101c1,feat: add limits store to team alignment and hotspots" 1 1 .detective/hash 8 8 .detective/log diff --git a/apps/frontend/src/app/features/coupling/coupling.component.html b/apps/frontend/src/app/features/coupling/coupling.component.html index 14124ed..5bc6530 100644 --- a/apps/frontend/src/app/features/coupling/coupling.component.html +++ b/apps/frontend/src/app/features/coupling/coupling.component.html @@ -1,12 +1,21 @@
- Group by folder Min. Connections - + ('structure'); - toolTip = computed(() => - this.type() === 'structure' ? STRUCTURE_TIP : COUPLING_TIP - ); totalCommits = this.statusStore.commits; - groupByFolder = signal(false); - limits = this.limitsStore.limits; - minConnections = signal(1); - couplingResult$ = combineLatest({ + groupByFolder = this.couplingStore.filter.groupByFolder; + minConnections = this.couplingStore.filter.minConnections; + + couplingResult = this.couplingStore.couplingResult; + graph = computed(() => this.toGraph(this.couplingResult())); + + toolTip = computed(() => + this.type() === 'structure' ? STRUCTURE_TIP : COUPLING_TIP + ); + + loadOptions$ = combineLatest({ limits: toObservable(this.limits).pipe(debounceTimeSkipFirst(300)), filterChanged: this.eventService.filterChanged.pipe(startWith(null)), type: toObservable(this.type), - }).pipe(switchMap((combi) => this.loadCoupling(combi))); + }).pipe(takeUntilDestroyed()); - couplingResult = toSignal(this.couplingResult$, { - initialValue: initCouplingResult, - }); - - graph = computed(() => this.toGraph(this.couplingResult())); + constructor() { + this.couplingStore.rxLoad(this.loadOptions$); + } - private loadCoupling(combi: { - limits: Limits; - filterChanged: void | null; - type: GraphType; - }): Observable { - return this.couplingService.load(combi.type, combi.limits).pipe( - catchError((err) => { - this.showError(err); - return of(initCouplingResult); - }) - ); + updateFilter(filter: Partial) { + this.couplingStore.updateFilter(filter); } updateLimits(limits: Limits): void { @@ -105,8 +86,6 @@ export class CouplingComponent { toGraph(result: CouplingResult): Graph { result.matrix = clearSelfLinks(result.matrix); - console.log('result', result); - const groupNodes: CouplingNodeDefinition[] = this.groupByFolder() ? createGroups(result.dimensions) : []; diff --git a/apps/frontend/src/app/features/coupling/coupling.store.ts b/apps/frontend/src/app/features/coupling/coupling.store.ts new file mode 100644 index 0000000..c358a50 --- /dev/null +++ b/apps/frontend/src/app/features/coupling/coupling.store.ts @@ -0,0 +1,66 @@ +import { inject } from '@angular/core'; +import { patchState, signalStore, withMethods, withState } from '@ngrx/signals'; +import { rxMethod } from '@ngrx/signals/rxjs-interop'; +import { catchError, Observable, of, pipe, switchMap, tap } from 'rxjs'; + +import { CouplingService } from '../../data/coupling.service'; +import { + CouplingResult, + initCouplingResult, +} from '../../model/coupling-result'; +import { GraphType } from '../../model/graph-type'; +import { Limits } from '../../model/limits'; +import { injectShowError } from '../../utils/error-handler'; + +export type CouplingFilter = { + groupByFolder: boolean; + minConnections: number; +}; + +export type LoadOptions = { + type: GraphType; + limits: Limits; +}; + +export const CouplingStore = signalStore( + { providedIn: 'root' }, + withState({ + filter: { + groupByFolder: false, + minConnections: 1, + } as CouplingFilter, + couplingResult: initCouplingResult, + }), + withMethods( + ( + _store, + couplingService = inject(CouplingService), + showError = injectShowError() + ) => ({ + _loadCoupling(options: LoadOptions): Observable { + return couplingService.load(options.type, options.limits).pipe( + catchError((err) => { + showError(err); + return of(initCouplingResult); + }) + ); + }, + }) + ), + withMethods((store) => ({ + updateFilter(filter: Partial) { + patchState(store, (state) => ({ + filter: { + ...state.filter, + ...filter, + }, + })); + }, + rxLoad: rxMethod( + pipe( + switchMap((options) => store._loadCoupling(options)), + tap((couplingResult) => patchState(store, { couplingResult })) + ) + ), + })) +);