From 87761bae6e31f52b635827b55946b8eb7db9cc80 Mon Sep 17 00:00:00 2001 From: Isaac Victor Warui Date: Sat, 29 Nov 2025 19:46:00 +0300 Subject: [PATCH] feat: replace observables logic with signals --- .../budget-table/budget-table.component.ts | 34 +++++++----- .../select-budget/select-budget.component.ts | 53 ++++++++++++------- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/libs/features/budgetting/budgets/src/lib/components/budget-table/budget-table.component.ts b/libs/features/budgetting/budgets/src/lib/components/budget-table/budget-table.component.ts index 77d8fee7..28f003c0 100644 --- a/libs/features/budgetting/budgets/src/lib/components/budget-table/budget-table.component.ts +++ b/libs/features/budgetting/budgets/src/lib/components/budget-table/budget-table.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { Component, EventEmitter, Input, inject, input, effect, ChangeDetectionStrategy, Output, ViewChild } from '@angular/core'; import { MatTable, MatTableDataSource } from '@angular/material/table'; import { MatPaginator } from '@angular/material/paginator'; import { MatDialog } from '@angular/material/dialog'; @@ -18,13 +18,15 @@ import { ChildBudgetsModalComponent } from '../../modals/child-budgets-modal/chi selector: 'app-budget-table', templateUrl: './budget-table.component.html', styleUrls: ['./budget-table.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class BudgetTableComponent { - private _sbS = new SubSink(); + // private _sbS = new SubSink(); - @Input() budgets$: Observable<{overview: BudgetRecord[], budgets: any[]}>; + // @Input() budgets$: Observable<{overview: BudgetRecord[], budgets: any[]}>; + budgets = input<{overview: BudgetRecord[], budgets: any[]}>(); @Input() canPromote = false; @Output() doPromote: EventEmitter = new EventEmitter(); @@ -38,15 +40,23 @@ export class BudgetTableComponent { overviewBudgets: BudgetRecord[] = []; - constructor(private _router$$: Router, - private _dialog: MatDialog, - ) { } - - ngOnInit(): void { - this._sbS.sink = this.budgets$.pipe(tap((o) => { - this.overviewBudgets = o.overview; - this.dataSource.data = o.budgets; - })).subscribe(); + private _router$$ = inject(Router); + private _dialog = inject(MatDialog); + // ) { } + + // ngOnInit(): void { + // this._sbS.sink = this.budgets$.pipe(tap((o) => { + // this.overviewBudgets = o.overview; + // this.dataSource.data = o.budgets; + // })).subscribe(); + // } + + ngOnInit() { + effect(() => { + const budgetData = this.budgets(); + this.overviewBudgets = budgetData.overview; + this.dataSource.data = budgetData.budgets; + }) } /** diff --git a/libs/features/budgetting/budgets/src/lib/pages/select-budget/select-budget.component.ts b/libs/features/budgetting/budgets/src/lib/pages/select-budget/select-budget.component.ts index 887a1d2e..25fdbf24 100644 --- a/libs/features/budgetting/budgets/src/lib/pages/select-budget/select-budget.component.ts +++ b/libs/features/budgetting/budgets/src/lib/pages/select-budget/select-budget.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, signal, computed, effect, ChangeDetectionStrategy } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { cloneDeep as ___cloneDeep, flatMap as __flatMap } from 'lodash'; @@ -18,37 +18,52 @@ import { CreateBudgetModalComponent } from '../../components/create-budget-modal templateUrl: './select-budget.component.html', styleUrls: ['./select-budget.component.scss', '../../components/budget-view-styles.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) /** List of all active budgets on the system. */ export class SelectBudgetPageComponent implements OnInit { /** Overview which contains all budgets of an organisation */ - overview$!: Observable; - sharedBudgets$: Observable; + private overviewsig = signal; + private sharedBudgetssig = signal; showFilter = false; // budgetsLoaded: boolean = false; - allBudgets$: Observable<{overview: BudgetRecord[], budgets: any[]}>; + // allBudgets$: Observable<{overview: BudgetRecord[], budgets: any[]}>; + allBudgets = computed(() => { + const overview = this.overviewsig(); + const budgets = this.sharedBudgetssig(); - constructor(private _orgBudgets$$: OrgBudgetsStore, - private _budgets$$: BudgetsStore, - private _dialog: MatDialog, - private _logger: Logger) - { } + if (!overview || !budgets) return { overview: [], budgets: [] }; + + const flatOverview = __flatMap(overview); + const flatBudgets = __flatMap(budgets); + + const trBudgets = flatBudgets.map((budget: any) => { + budget['endYear'] = budget.startYear + budget.duration - 1; + return budget; + }) + + return { overview: flatOverview, budgets: trBudgets }; + }) + + private _orgBudgets$$ = inject(OrgBudgetsStore); + private _budgets$$ = inject(BudgetsStore); + private _dialog = inject(MatDialog); + private _logger = inject(Logger); ngOnInit() { - this.overview$ = this._orgBudgets$$.get(); - this.sharedBudgets$ = this._budgets$$.get(); - - this.allBudgets$ = combineLatest([this.overview$, this._budgets$$.get()]) - .pipe(map(([overview, budgets]) => {return {overview: __flatMap(overview), budgets: __flatMap(budgets)}}), - map((overview) => { - const trBudgets = overview.budgets.map((budget: any) => {budget['endYear'] = budget.startYear + budget.duration - 1; return budget;}) - // this.budgetsLoaded = true; - return {overview: overview.overview, budgets: trBudgets} - })); + effect(() => { + this._orgBudgets$$.get().subscribe(overview => { + this.overviewsig.set(overview) + }) + + this._budgets$$.get().subscribe(budgets => { + this.sharedBudgetssig.set(budgets) + }) + }, {allowSignalWrites: true}) } applyFilter(event: Event) {