diff --git a/src/app/loans/create-loans-account/create-loans-account.component.ts b/src/app/loans/create-loans-account/create-loans-account.component.ts index c9b4b39372..b53d78c4e9 100644 --- a/src/app/loans/create-loans-account/create-loans-account.component.ts +++ b/src/app/loans/create-loans-account/create-loans-account.component.ts @@ -12,11 +12,13 @@ import { AfterViewInit, ChangeDetectorRef, Component, + DestroyRef, QueryList, ViewChild, ViewChildren, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; /** Custom Services */ @@ -62,6 +64,7 @@ import { Dates } from 'app/core/utils/dates'; changeDetection: ChangeDetectionStrategy.OnPush }) export class CreateLoansAccountComponent extends LoanProductBaseComponent implements AfterViewInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansService = inject(LoansService); private settingsService = inject(SettingsService); @@ -110,12 +113,12 @@ export class CreateLoansAccountComponent extends LoanProductBaseComponent implem constructor() { super(); this.loanProductsBasicDetails = []; - this.route.data.subscribe( - (data: { loansAccountTemplate: any; loanProductsBasicDetails: LoanProductBasicDetails[] }) => { + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loansAccountTemplate: any; loanProductsBasicDetails: LoanProductBasicDetails[] }) => { this.loanProductsBasicDetails = data.loanProductsBasicDetails; this.loansAccountTemplate = data.loansAccountTemplate; - } - ); + }); } ngAfterViewInit() { diff --git a/src/app/loans/custom-dialog/loans-account-add-collateral-dialog/loans-account-add-collateral-dialog.component.ts b/src/app/loans/custom-dialog/loans-account-add-collateral-dialog/loans-account-add-collateral-dialog.component.ts index 03c3317319..915090283b 100644 --- a/src/app/loans/custom-dialog/loans-account-add-collateral-dialog/loans-account-add-collateral-dialog.component.ts +++ b/src/app/loans/custom-dialog/loans-account-add-collateral-dialog/loans-account-add-collateral-dialog.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialogRef, MAT_DIALOG_DATA, @@ -15,7 +16,7 @@ import { MatDialogActions, MatDialogClose } from '@angular/material/dialog'; -import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; +import { UntypedFormGroup, UntypedFormBuilder, Validators } from '@angular/forms'; import { CdkScrollable } from '@angular/cdk/scrolling'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -34,6 +35,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class LoansAccountAddCollateralDialogComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); dialogRef = inject>(MatDialogRef); data = inject(MAT_DIALOG_DATA); private formBuilder = inject(UntypedFormBuilder); @@ -81,16 +83,28 @@ export class LoansAccountAddCollateralDialogComponent implements OnInit { * Subscribe to Form controls value changes */ buildDependencies() { - this.addCollateralForm.controls.collateral.valueChanges.subscribe((collateral: any) => { - this.collateralData = collateral; - this.maxQuantity = collateral.quantity; - }); + this.addCollateralForm.controls.collateral.valueChanges + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((collateral: any) => { + this.collateralData = collateral; + this.maxQuantity = collateral.quantity; + }); - this.addCollateralForm.controls.quantity.valueChanges.subscribe((quantity: any) => { - this.addCollateralForm.patchValue({ - totalValue: this.collateralData.basePrice * quantity, - totalCollateralValue: (this.collateralData.basePrice * this.collateralData.pctToBase * quantity) / 100 + this.addCollateralForm.controls.quantity.valueChanges + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((quantity: any) => { + if (!this.collateralData || quantity === null || quantity === '') { + this.addCollateralForm.patchValue({ totalValue: '', totalCollateralValue: '' }, { emitEvent: false }); + return; + } + + const basePrice = Number(this.collateralData.basePrice) || 0; + const pctToBase = Number(this.collateralData.pctToBase) || 0; + const qty = Number(quantity) || 0; + this.addCollateralForm.patchValue({ + totalValue: basePrice * qty, + totalCollateralValue: (basePrice * pctToBase * qty) / 100 + }); }); - }); } } diff --git a/src/app/loans/edit-loans-account/edit-loans-account.component.ts b/src/app/loans/edit-loans-account/edit-loans-account.component.ts index 4486f855a5..b416830dcd 100644 --- a/src/app/loans/edit-loans-account/edit-loans-account.component.ts +++ b/src/app/loans/edit-loans-account/edit-loans-account.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, ViewChild, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, ViewChild, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { LoansService } from '../loans.service'; import { LoansAccountDetailsStepComponent } from '../loans-account-stepper/loans-account-details-step/loans-account-details-step.component'; @@ -47,6 +48,7 @@ import { LoanProductBaseComponent } from 'app/products/loan-products/common/loan changeDetection: ChangeDetectionStrategy.OnPush }) export class EditLoansAccountComponent extends LoanProductBaseComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private dateUtils = inject(Dates); private loansService = inject(LoansService); @@ -79,8 +81,9 @@ export class EditLoansAccountComponent extends LoanProductBaseComponent { this.loanProductService.initialize(LoanProductBaseComponent.resolveProductTypeDefault(this.route, 'loan')); this.loanId = this.route.snapshot.params['loanId']; - this.route.data.subscribe( - (data: { loansAccountAndTemplate: any; loanProductsBasicDetails: LoanProductBasicDetails[] }) => { + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loansAccountAndTemplate: any; loanProductsBasicDetails: LoanProductBasicDetails[] }) => { this.loansAccountAndTemplate = data.loansAccountAndTemplate; if (this.loanProductService.isLoanProduct) { this.loansAccountProductTemplate = data.loansAccountAndTemplate; @@ -92,8 +95,7 @@ export class EditLoansAccountComponent extends LoanProductBaseComponent { ); } this.loanProductsBasicDetails = data.loanProductsBasicDetails; - } - ); + }); } /** diff --git a/src/app/loans/glim-account/create-glim-account/create-glim-account.component.ts b/src/app/loans/glim-account/create-glim-account/create-glim-account.component.ts index 588fa08260..517e8f115b 100644 --- a/src/app/loans/glim-account/create-glim-account/create-glim-account.component.ts +++ b/src/app/loans/glim-account/create-glim-account/create-glim-account.component.ts @@ -7,7 +7,16 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, QueryList, ViewChild, ViewChildren, inject } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + DestroyRef, + QueryList, + ViewChild, + ViewChildren, + inject +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { I18nService } from 'app/core/i18n/i18n.service'; import { ActivatedRoute, Router } from '@angular/router'; @@ -51,6 +60,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class CreateGlimAccountComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private router = inject(Router); private loansService = inject(LoansService); @@ -97,10 +107,12 @@ export class CreateGlimAccountComponent { * @param {ClientsService} clientService Client Service */ constructor() { - this.route.data.subscribe((data: { loansAccountTemplate: any; groupsData: any }) => { - this.loansAccountTemplate = data.loansAccountTemplate; - this.dataSource = data.groupsData.activeClientMembers; - }); + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loansAccountTemplate: any; groupsData: any }) => { + this.loansAccountTemplate = data.loansAccountTemplate; + this.dataSource = data.groupsData.activeClientMembers; + }); } /** diff --git a/src/app/loans/glim-account/glim-account.component.ts b/src/app/loans/glim-account/glim-account.component.ts index 19cba9276d..de7d706c48 100644 --- a/src/app/loans/glim-account/glim-account.component.ts +++ b/src/app/loans/glim-account/glim-account.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, ViewChild, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, ViewChild, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { @@ -53,6 +54,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class GlimAccountComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); dialog = inject(MatDialog); @@ -81,7 +83,7 @@ export class GlimAccountComponent implements OnInit { * @param {MatDialog} dialog Dialog reference. */ constructor() { - this.route.data.subscribe((data: { glimData: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { glimData: any }) => { this.glimOverviewData = data.glimData; }); } diff --git a/src/app/loans/loans-account-stepper/loans-account-details-step/loans-account-details-step.component.ts b/src/app/loans/loans-account-stepper/loans-account-details-step/loans-account-details-step.component.ts index 406667acdc..69ac2f9617 100644 --- a/src/app/loans/loans-account-stepper/loans-account-details-step/loans-account-details-step.component.ts +++ b/src/app/loans/loans-account-stepper/loans-account-details-step/loans-account-details-step.component.ts @@ -11,13 +11,14 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + DestroyRef, OnInit, Input, Output, EventEmitter, - OnDestroy, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { SettingsService } from 'app/settings/settings.service'; @@ -26,8 +27,7 @@ import { TranslateService } from '@ngx-translate/core'; /** Custom Services */ import { LoansService } from '../../loans.service'; import { Commons } from 'app/core/utils/commons'; -import { takeUntil } from 'rxjs/operators'; -import { ReplaySubject, Subject } from 'rxjs'; +import { ReplaySubject } from 'rxjs'; import { MatTooltip } from '@angular/material/tooltip'; import { NgxMatSelectSearchModule } from 'ngx-mat-select-search'; import { AsyncPipe } from '@angular/common'; @@ -62,7 +62,8 @@ import { LoanProductBaseComponent } from 'app/products/loan-products/common/loan ], changeDetection: ChangeDetectionStrategy.OnPush }) -export class LoansAccountDetailsStepComponent extends LoanProductBaseComponent implements OnInit, OnDestroy { +export class LoansAccountDetailsStepComponent extends LoanProductBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private loansService = inject(LoansService); private route = inject(ActivatedRoute); @@ -106,8 +107,6 @@ export class LoansAccountDetailsStepComponent extends LoanProductBaseComponent i protected productData: ReplaySubject = new ReplaySubject(1); /** control for the filter select */ protected filterFormCtrl: UntypedFormControl = new UntypedFormControl(''); - /** Subject that emits when the component has been destroyed. */ - protected _onDestroy = new Subject(); productSelected: LoanProductBasicDetails | null = null; @@ -167,17 +166,12 @@ export class LoansAccountDetailsStepComponent extends LoanProductBaseComponent i this.getProductTemplate(false); } } - this.filterFormCtrl.valueChanges.pipe(takeUntil(this._onDestroy)).subscribe(() => { + this.filterFormCtrl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { this.searchItem(); }); this.productData.next(this.productList.slice()); } - ngOnDestroy(): void { - this._onDestroy.next(); - this._onDestroy.complete(); - } - searchItem(): void { if (this.productList) { const search: string = this.filterFormCtrl.value.toLowerCase(); diff --git a/src/app/loans/loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component.ts b/src/app/loans/loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component.ts index 1f4ec9ac63..427c161a64 100644 --- a/src/app/loans/loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component.ts +++ b/src/app/loans/loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component.ts @@ -11,12 +11,14 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + DestroyRef, OnInit, Input, OnChanges, SimpleChanges, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; @@ -99,6 +101,7 @@ interface DisbursementData { changeDetection: ChangeDetectionStrategy.OnPush }) export class LoansAccountTermsStepComponent extends LoanProductBaseComponent implements OnInit, OnChanges { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private settingsService = inject(SettingsService); private route = inject(ActivatedRoute); @@ -515,42 +518,57 @@ export class LoansAccountTermsStepComponent extends LoanProductBaseComponent imp const repaymentFrequencyNthDayType = this.loansAccountTermsForm.get('repaymentFrequencyNthDayType'); const repaymentFrequencyDayOfWeekType = this.loansAccountTermsForm.get('repaymentFrequencyDayOfWeekType'); - this.loansAccountTermsForm.get('repaymentFrequencyType')?.valueChanges.subscribe((repaymentFrequencyType) => { - repaymentFrequencyNthDayType?.setValidators(null); - repaymentFrequencyDayOfWeekType?.setValidators(null); + this.loansAccountTermsForm + .get('repaymentFrequencyType') + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((repaymentFrequencyType) => { + repaymentFrequencyNthDayType?.setValidators(null); + repaymentFrequencyDayOfWeekType?.setValidators(null); - setTimeout(() => { - repaymentFrequencyNthDayType?.updateValueAndValidity(); - repaymentFrequencyDayOfWeekType?.updateValueAndValidity(); + setTimeout(() => { + repaymentFrequencyNthDayType?.updateValueAndValidity(); + repaymentFrequencyDayOfWeekType?.updateValueAndValidity(); + }); }); - }); } /** Custom Listeners for the form to calculate Loan Term */ setLoanTermListener() { - this.loansAccountTermsForm.get('numberOfRepayments')?.valueChanges.subscribe((numberOfRepayments) => { - const repaymentEvery: number = this.loansAccountTermsForm.value.repaymentEvery; - this.calculateLoanTerm(numberOfRepayments, repaymentEvery); - }); + this.loansAccountTermsForm + .get('numberOfRepayments') + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((numberOfRepayments) => { + const repaymentEvery: number = this.loansAccountTermsForm.value.repaymentEvery; + this.calculateLoanTerm(numberOfRepayments, repaymentEvery); + }); - this.loansAccountTermsForm.get('repaymentEvery')?.valueChanges.subscribe((repaymentEvery) => { - const numberOfRepayments: number = this.loansAccountTermsForm.value.numberOfRepayments; - this.calculateLoanTerm(numberOfRepayments, repaymentEvery); - }); + this.loansAccountTermsForm + .get('repaymentEvery') + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((repaymentEvery) => { + const numberOfRepayments: number = this.loansAccountTermsForm.value.numberOfRepayments; + this.calculateLoanTerm(numberOfRepayments, repaymentEvery); + }); - this.loansAccountTermsForm.get('loanTermFrequencyType')?.valueChanges.subscribe((loanTermFrequencyType) => { - this.loansAccountTermsForm.patchValue({ repaymentFrequencyType: loanTermFrequencyType }); - }); + this.loansAccountTermsForm + .get('loanTermFrequencyType') + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((loanTermFrequencyType) => { + this.loansAccountTermsForm.patchValue({ repaymentFrequencyType: loanTermFrequencyType }); + }); - this.loansAccountTermsForm.get('amortizationType')?.valueChanges.subscribe((amortizationType) => { - if (amortizationType === 0) { - // Equal Principal Payments - this.loansAccountTermsForm.addControl('fixedPrincipalPercentagePerInstallment', new UntypedFormControl('')); - } else { - // Equal Installments - this.loansAccountTermsForm.removeControl('fixedPrincipalPercentagePerInstallment'); - } - }); + this.loansAccountTermsForm + .get('amortizationType') + ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((amortizationType) => { + if (amortizationType === 0) { + // Equal Principal Payments + this.loansAccountTermsForm.addControl('fixedPrincipalPercentagePerInstallment', new UntypedFormControl('')); + } else { + // Equal Installments + this.loansAccountTermsForm.removeControl('fixedPrincipalPercentagePerInstallment'); + } + }); } /** Prevent negative values in numeric fields */ @@ -568,7 +586,7 @@ export class LoansAccountTermsStepComponent extends LoanProductBaseComponent imp numericFieldsWithMinZero.forEach((fieldName) => { const control = this.loansAccountTermsForm.get(fieldName); if (control) { - control.valueChanges.subscribe((value) => { + control.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => { if (typeof value === 'number' && value < 0) { control.setValue(0, { emitEvent: false }); } @@ -577,7 +595,7 @@ export class LoansAccountTermsStepComponent extends LoanProductBaseComponent imp }); const interestRateControl = this.loansAccountTermsForm.get('interestRatePerPeriod'); if (interestRateControl) { - interestRateControl.valueChanges.subscribe((value) => { + interestRateControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => { if (typeof value === 'number' && value < 0.01) { interestRateControl.setValue(0.01, { emitEvent: false }); } diff --git a/src/app/loans/loans-view/account-details/account-details.component.ts b/src/app/loans/loans-view/account-details/account-details.component.ts index a53b58cbd0..be05057167 100644 --- a/src/app/loans/loans-view/account-details/account-details.component.ts +++ b/src/app/loans/loans-view/account-details/account-details.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { DateFormatPipe } from '../../../pipes/date-format.pipe'; import { FormatNumberPipe } from '../../../pipes/format-number.pipe'; @@ -29,6 +30,7 @@ import { BreachDisplayComponent } from 'app/shared/loan/breach-display/breach-di changeDetection: ChangeDetectionStrategy.OnPush }) export class AccountDetailsComponent extends LoanProductBaseComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); loanDetails: any; @@ -40,7 +42,7 @@ export class AccountDetailsComponent extends LoanProductBaseComponent { constructor() { super(); this.loanProductService.initialize(LoanProductBaseComponent.resolveProductTypeDefault(this.route, 'loan')); - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanDetails = data.loanDetailsData; }); } diff --git a/src/app/loans/loans-view/charges-tab/charges-tab.component.ts b/src/app/loans/loans-view/charges-tab/charges-tab.component.ts index 387930029d..d3bf227966 100644 --- a/src/app/loans/loans-view/charges-tab/charges-tab.component.ts +++ b/src/app/loans/loans-view/charges-tab/charges-tab.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, ViewChild, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, ViewChild, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; @@ -78,6 +79,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class ChargesTabComponent extends LoanAccountTabBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private loansService = inject(LoansService); private route = inject(ActivatedRoute); private dateUtils = inject(Dates); @@ -122,7 +124,7 @@ export class ChargesTabComponent extends LoanAccountTabBaseComponent implements */ constructor() { super(); - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanDetails = data.loanDetailsData; }); } diff --git a/src/app/loans/loans-view/datatable-tab/datatable-tab.component.ts b/src/app/loans/loans-view/datatable-tab/datatable-tab.component.ts index a644466bca..c30c9284ba 100644 --- a/src/app/loans/loans-view/datatable-tab/datatable-tab.component.ts +++ b/src/app/loans/loans-view/datatable-tab/datatable-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { EntityDatatableTabComponent } from '../../../shared/tabs/entity-datatable-tab/entity-datatable-tab.component'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -22,6 +23,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class DatatableTabComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); entityId: string; @@ -37,14 +39,14 @@ export class DatatableTabComponent implements OnInit { constructor() { this.entityId = this.route.parent.parent.snapshot.paramMap.get('loanId'); this.entityDatatable = null; - this.route.data.subscribe((data: { loanDatatable: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDatatable: any }) => { this.entityDatatable = data.loanDatatable; this.multiRowDatatableFlag = this.entityDatatable.columnHeaders[0].columnName === 'id' ? true : false; }); } ngOnInit() { - this.route.parent.parent.params.subscribe((params) => { + this.route.parent.parent.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { this.entityId = params['loanId']; }); } diff --git a/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts index 0152315adf..d0ff36dc5b 100644 --- a/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts +++ b/src/app/loans/loans-view/external-asset-owner-tab/external-asset-owner-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { ExternalAssetOwner } from 'app/loans/services/external-asset-owner'; @@ -60,6 +61,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class ExternalAssetOwnerTabComponent extends LoanAccountTabBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private dialog = inject(MatDialog); private externalAssetOwner = inject(ExternalAssetOwner); @@ -83,11 +85,13 @@ export class ExternalAssetOwnerTabComponent extends LoanAccountTabBaseComponent constructor() { super(); - this.route.data.subscribe((data: { loanTransfersData: any; activeTransferData: any }) => { - this.loanTransfersData = data.loanTransfersData.empty ? [] : data.loanTransfersData.content; - this.activeTransferData = data.activeTransferData || null; - this.existActiveTransfer = data.activeTransferData && data.activeTransferData.transferId != null; - }); + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanTransfersData: any; activeTransferData: any }) => { + this.loanTransfersData = data.loanTransfersData.empty ? [] : data.loanTransfersData.content; + this.activeTransferData = data.activeTransferData || null; + this.existActiveTransfer = data.activeTransferData && data.activeTransferData.transferId != null; + }); } ngOnInit(): void { diff --git a/src/app/loans/loans-view/floating-interest-rates/floating-interest-rates.component.ts b/src/app/loans/loans-view/floating-interest-rates/floating-interest-rates.component.ts index 0c761d89f7..6fdeb1797f 100644 --- a/src/app/loans/loans-view/floating-interest-rates/floating-interest-rates.component.ts +++ b/src/app/loans/loans-view/floating-interest-rates/floating-interest-rates.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { MatTable, @@ -44,6 +45,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class FloatingInterestRatesComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); /** Loan Details */ @@ -61,7 +63,7 @@ export class FloatingInterestRatesComponent implements OnInit { * @param {ActivatedRoute} route Activated Route. */ constructor() { - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanDetails = data.loanDetailsData; }); } diff --git a/src/app/loans/loans-view/general-tab/general-tab.component.ts b/src/app/loans/loans-view/general-tab/general-tab.component.ts index 7e0b1db124..dfd973137c 100644 --- a/src/app/loans/loans-view/general-tab/general-tab.component.ts +++ b/src/app/loans/loans-view/general-tab/general-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { MatTableDataSource, @@ -47,6 +48,7 @@ import { LoanSummaryBalanceComponentComponent } from './loan-summary-balance-com changeDetection: ChangeDetectionStrategy.OnPush }) export class GeneralTabComponent extends LoanProductBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); /** Currency Code */ @@ -70,7 +72,7 @@ export class GeneralTabComponent extends LoanProductBaseComponent implements OnI if (productType) { this.loanProductService.initialize(productType); } - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanDetails = data.loanDetailsData; this.currencyCode = this.loanDetails.currency.code; if (this.loanDetails.transactions) { diff --git a/src/app/loans/loans-view/loan-account-actions/add-loan-charge/add-loan-charge.component.ts b/src/app/loans/loans-view/loan-account-actions/add-loan-charge/add-loan-charge.component.ts index a388e52f6e..855c953bc5 100644 --- a/src/app/loans/loans-view/loan-account-actions/add-loan-charge/add-loan-charge.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/add-loan-charge/add-loan-charge.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; /** Custom Services */ @@ -28,6 +29,7 @@ import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.co changeDetection: ChangeDetectionStrategy.OnPush }) export class AddLoanChargeComponent extends LoanAccountActionsBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private dateUtils = inject(Dates); @@ -61,7 +63,7 @@ export class AddLoanChargeComponent extends LoanAccountActionsBaseComponent impl */ constructor() { super(); - this.route.data.subscribe((data: { actionButtonData: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { actionButtonData: any }) => { this.loanChargeOptions = data.actionButtonData.chargeOptions; }); this.loanId = this.route.snapshot.params['loanId']; @@ -73,21 +75,23 @@ export class AddLoanChargeComponent extends LoanAccountActionsBaseComponent impl ngOnInit() { this.maxDate = this.settingsService.maxFutureDate; this.createLoanChargeForm(); - this.loanChargeForm.controls.chargeId.valueChanges.subscribe((chargeId) => { - const chargeDetails = this.loanChargeOptions.find((option) => { - return option.id === chargeId; + this.loanChargeForm.controls.chargeId.valueChanges + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((chargeId) => { + const chargeDetails = this.loanChargeOptions.find((option) => { + return option.id === chargeId; + }); + if (chargeDetails.chargeTimeType.id === 2) { + this.loanChargeForm.addControl('dueDate', new UntypedFormControl('', Validators.required)); + } else { + this.loanChargeForm.removeControl('dueDate'); + } + this.loanChargeForm.patchValue({ + amount: chargeDetails.amount, + chargeCalculation: chargeDetails.chargeCalculationType.value, + chargeTime: chargeDetails.chargeTimeType.value + }); }); - if (chargeDetails.chargeTimeType.id === 2) { - this.loanChargeForm.addControl('dueDate', new UntypedFormControl('', Validators.required)); - } else { - this.loanChargeForm.removeControl('dueDate'); - } - this.loanChargeForm.patchValue({ - amount: chargeDetails.amount, - chargeCalculation: chargeDetails.chargeCalculationType.value, - chargeTime: chargeDetails.chargeTimeType.value - }); - }); } /** diff --git a/src/app/loans/loans-view/loan-account-actions/adjust-loan-charge/adjust-loan-charge.component.ts b/src/app/loans/loans-view/loan-account-actions/adjust-loan-charge/adjust-loan-charge.component.ts index 78acce9771..6c30bbac86 100644 --- a/src/app/loans/loans-view/loan-account-actions/adjust-loan-charge/adjust-loan-charge.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/adjust-loan-charge/adjust-loan-charge.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { OrganizationService } from 'app/organization/organization.service'; import { MatSlideToggle } from '@angular/material/slide-toggle'; @@ -28,6 +29,7 @@ import { InputAmountComponent } from 'app/shared/input-amount/input-amount.compo changeDetection: ChangeDetectionStrategy.OnPush }) export class AdjustLoanChargeComponent extends LoanAccountActionsBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private organizationService = inject(OrganizationService); @@ -55,10 +57,12 @@ export class AdjustLoanChargeComponent extends LoanAccountActionsBaseComponent i constructor() { super(); this.chargeId = this.route.snapshot.params['id']; - this.route.data.subscribe((data: { loansAccountCharge: any; loanDetailsData: any }) => { - this.chargeData = data.loansAccountCharge; - this.loanDetailsData = data.loanDetailsData; - }); + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loansAccountCharge: any; loanDetailsData: any }) => { + this.chargeData = data.loansAccountCharge; + this.loanDetailsData = data.loanDetailsData; + }); } /** diff --git a/src/app/loans/loans-view/loan-account-actions/approve-loan/approve-loan.component.ts b/src/app/loans/loans-view/loan-account-actions/approve-loan/approve-loan.component.ts index fac05a8049..fac43762c2 100644 --- a/src/app/loans/loans-view/loan-account-actions/approve-loan/approve-loan.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/approve-loan/approve-loan.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; import { Dates } from 'app/core/utils/dates'; @@ -35,6 +36,7 @@ import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.co changeDetection: ChangeDetectionStrategy.OnPush }) export class ApproveLoanComponent extends LoanAccountActionsBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private dateUtils = inject(Dates); @@ -54,7 +56,7 @@ export class ApproveLoanComponent extends LoanAccountActionsBaseComponent implem constructor() { super(); this.maxDate = this.settingsService.maxFutureDate; - this.route.data.subscribe((data: { actionButtonData: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { actionButtonData: any }) => { this.loanData = data.actionButtonData; this.currency = data.actionButtonData.currency; }); diff --git a/src/app/loans/loans-view/loan-account-actions/create-guarantor/create-guarantor.component.ts b/src/app/loans/loans-view/loan-account-actions/create-guarantor/create-guarantor.component.ts index 49c25d5d65..b241375516 100644 --- a/src/app/loans/loans-view/loan-account-actions/create-guarantor/create-guarantor.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/create-guarantor/create-guarantor.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, AfterViewInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, AfterViewInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; /** Custom Services */ @@ -34,6 +35,7 @@ import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.co changeDetection: ChangeDetectionStrategy.OnPush }) export class CreateGuarantorComponent extends LoanAccountActionsBaseComponent implements OnInit, AfterViewInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private dateUtils = inject(Dates); private clientsService = inject(ClientsService); @@ -97,36 +99,39 @@ export class CreateGuarantorComponent extends LoanAccountActionsBaseComponent im * Add guarantor detail fields to the UI. */ buildDependencies() { - this.newGuarantorForm.get('existingClient').valueChanges.subscribe(() => { - this.showClientDetailsForm = !this.showClientDetailsForm; - if (this.showClientDetailsForm) { - this.newGuarantorForm.addControl('firstname', new UntypedFormControl('')); - this.newGuarantorForm.addControl('lastname', new UntypedFormControl('')); - this.newGuarantorForm.addControl('dob', new UntypedFormControl('')); - this.newGuarantorForm.addControl('addressLine1', new UntypedFormControl('')); - this.newGuarantorForm.addControl('addressLine2', new UntypedFormControl('')); - this.newGuarantorForm.addControl('city', new UntypedFormControl('')); - this.newGuarantorForm.addControl('zip', new UntypedFormControl('')); - this.newGuarantorForm.addControl('mobileNumber', new UntypedFormControl('')); - this.newGuarantorForm.addControl('housePhoneNumber', new UntypedFormControl('')); - this.newGuarantorForm.removeControl('name'); - this.newGuarantorForm.removeControl('savingsId'); - this.newGuarantorForm.removeControl('amount'); - } else { - this.newGuarantorForm.addControl('name', new UntypedFormControl('')); - this.newGuarantorForm.addControl('savingsId', new UntypedFormControl('')); - this.newGuarantorForm.addControl('amount', new UntypedFormControl('')); - this.newGuarantorForm.removeControl('firstname'); - this.newGuarantorForm.removeControl('lastname'); - this.newGuarantorForm.removeControl('dob'); - this.newGuarantorForm.removeControl('addressLine1'); - this.newGuarantorForm.removeControl('addressLine2'); - this.newGuarantorForm.removeControl('city'); - this.newGuarantorForm.removeControl('zip'); - this.newGuarantorForm.removeControl('mobileNumber'); - this.newGuarantorForm.removeControl('housePhoneNumber'); - } - }); + this.newGuarantorForm + .get('existingClient') + .valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => { + this.showClientDetailsForm = !this.showClientDetailsForm; + if (this.showClientDetailsForm) { + this.newGuarantorForm.addControl('firstname', new UntypedFormControl('')); + this.newGuarantorForm.addControl('lastname', new UntypedFormControl('')); + this.newGuarantorForm.addControl('dob', new UntypedFormControl('')); + this.newGuarantorForm.addControl('addressLine1', new UntypedFormControl('')); + this.newGuarantorForm.addControl('addressLine2', new UntypedFormControl('')); + this.newGuarantorForm.addControl('city', new UntypedFormControl('')); + this.newGuarantorForm.addControl('zip', new UntypedFormControl('')); + this.newGuarantorForm.addControl('mobileNumber', new UntypedFormControl('')); + this.newGuarantorForm.addControl('housePhoneNumber', new UntypedFormControl('')); + this.newGuarantorForm.removeControl('name'); + this.newGuarantorForm.removeControl('savingsId'); + this.newGuarantorForm.removeControl('amount'); + } else { + this.newGuarantorForm.addControl('name', new UntypedFormControl('')); + this.newGuarantorForm.addControl('savingsId', new UntypedFormControl('')); + this.newGuarantorForm.addControl('amount', new UntypedFormControl('')); + this.newGuarantorForm.removeControl('firstname'); + this.newGuarantorForm.removeControl('lastname'); + this.newGuarantorForm.removeControl('dob'); + this.newGuarantorForm.removeControl('addressLine1'); + this.newGuarantorForm.removeControl('addressLine2'); + this.newGuarantorForm.removeControl('city'); + this.newGuarantorForm.removeControl('zip'); + this.newGuarantorForm.removeControl('mobileNumber'); + this.newGuarantorForm.removeControl('housePhoneNumber'); + } + }); } /** @@ -134,13 +139,16 @@ export class CreateGuarantorComponent extends LoanAccountActionsBaseComponent im */ ngAfterViewInit() { if (this.newGuarantorForm.value.existingClient) { - this.newGuarantorForm.get('name').valueChanges.subscribe((value: string) => { - if (value.length >= 2) { - this.clientsService.getFilteredClients('displayName', 'ASC', true, value).subscribe((data: any) => { - this.clientsData = data.pageItems; - }); - } - }); + this.newGuarantorForm + .get('name') + .valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((value: string) => { + if (value.length >= 2) { + this.clientsService.getFilteredClients('displayName', 'ASC', true, value).subscribe((data: any) => { + this.clientsData = data.pageItems; + }); + } + }); } } diff --git a/src/app/loans/loans-view/loan-account-actions/foreclosure/foreclosure.component.ts b/src/app/loans/loans-view/loan-account-actions/foreclosure/foreclosure.component.ts index 6b55ffb4de..1218f57e8f 100644 --- a/src/app/loans/loans-view/loan-account-actions/foreclosure/foreclosure.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/foreclosure/foreclosure.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; /** Custom Services */ @@ -26,6 +27,7 @@ import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.co changeDetection: ChangeDetectionStrategy.OnPush }) export class ForeclosureComponent extends LoanAccountActionsBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private dateUtils = inject(Dates); @@ -65,9 +67,12 @@ export class ForeclosureComponent extends LoanAccountActionsBaseComponent implem } onChanges(): void { - this.foreclosureForm.get('transactionDate').valueChanges.subscribe((val) => { - this.retrieveLoanForeclosureTemplate(val); - }); + this.foreclosureForm + .get('transactionDate') + .valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((val) => { + this.retrieveLoanForeclosureTemplate(val); + }); } retrieveLoanForeclosureTemplate(val: any) { diff --git a/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts b/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts index 2ecf36bb4e..23cf066caf 100644 --- a/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports. */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute, Router } from '@angular/router'; import { LoansAccountCloseComponent } from './loans-account-close/loans-account-close.component'; import { UndoApprovalComponent } from './undo-approval/undo-approval.component'; @@ -89,6 +90,7 @@ import { UpdateDiscountComponent } from './update-discount/update-discount.compo changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanAccountActionsComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private router = inject(Router); @@ -193,11 +195,11 @@ export class LoanAccountActionsComponent { // Safely access data with optional chaining this.navigationData = currentNavigation?.extras?.state?.data; - this.route.data.subscribe((data: { actionButtonData: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { actionButtonData: any }) => { this.actionButtonData = data.actionButtonData ? data.actionButtonData : {}; }); - this.route.params.subscribe((params) => { + this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { this.actionName = params['action']; if (this.actionName === 'Change Loan Officer') { this.actionName = 'Assign Loan Officer'; diff --git a/src/app/loans/loans-view/loan-account-actions/make-repayment/make-repayment.component.ts b/src/app/loans/loans-view/loan-account-actions/make-repayment/make-repayment.component.ts index 5e45d55219..309ec6d1ac 100644 --- a/src/app/loans/loans-view/loan-account-actions/make-repayment/make-repayment.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/make-repayment/make-repayment.component.ts @@ -18,8 +18,6 @@ import { PenaltyManagementService } from 'app/loans/services/penalty-management. import { AlertService } from 'app/core/alert/alert.service'; import { InputAmountComponent } from '../../../../shared/input-amount/input-amount.component'; import { MatSlideToggle } from '@angular/material/slide-toggle'; -import { MatCheckbox } from '@angular/material/checkbox'; -import { CdkTextareaAutosize } from '@angular/cdk/text-field'; import { FormatNumberPipe } from '../../../../pipes/format-number.pipe'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.component'; @@ -35,8 +33,6 @@ import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.co ...STANDALONE_SHARED_IMPORTS, InputAmountComponent, MatSlideToggle, - MatCheckbox, - CdkTextareaAutosize, FormatNumberPipe ], changeDetection: ChangeDetectionStrategy.OnPush @@ -372,7 +368,6 @@ export class MakeRepaymentComponent extends LoanAccountActionsBaseComponent impl if (payload['paymentTypeId'] === null) { delete payload['paymentTypeId']; } else { - console.log(payload); if ('paymentDetails' in payload) { payload['paymentDetails']['paymentTypeId'] = payload['paymentTypeId']; } else { @@ -424,7 +419,6 @@ export class MakeRepaymentComponent extends LoanAccountActionsBaseComponent impl } }); } else { - console.log(payload); this.loanService .applyWorkingCapitalLoanActionCommand(this.loanId, payload, this.command) .pipe(takeUntilDestroyed(this.destroyRef)) diff --git a/src/app/loans/loans-view/loan-account-actions/prepay-loan/prepay-loan.component.ts b/src/app/loans/loans-view/loan-account-actions/prepay-loan/prepay-loan.component.ts index 39506ed541..201a17681f 100644 --- a/src/app/loans/loans-view/loan-account-actions/prepay-loan/prepay-loan.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/prepay-loan/prepay-loan.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; /** Custom Services */ @@ -37,6 +38,7 @@ import { LoanAccountActionsBaseComponent } from '../loan-account-actions-base.co changeDetection: ChangeDetectionStrategy.OnPush }) export class PrepayLoanComponent extends LoanAccountActionsBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private dateUtils = inject(Dates); @@ -121,16 +123,19 @@ export class PrepayLoanComponent extends LoanAccountActionsBaseComponent impleme this.prepayLoanForm.patchValue({ transactionAmount: this.dataObject.amount }); - this.prepayLoanForm.get('transactionDate').valueChanges.subscribe((transactionDate: string) => { - const prepayDate = this.dateUtils.formatDate(transactionDate, this.settingsService.dateFormat); + this.prepayLoanForm + .get('transactionDate') + .valueChanges.pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((transactionDate: string) => { + const prepayDate = this.dateUtils.formatDate(transactionDate, this.settingsService.dateFormat); - this.loanService.getLoanPrepayLoanActionTemplate(this.loanId, prepayDate).subscribe((response: any) => { - this.prepayData = response; - this.prepayLoanForm.patchValue({ - transactionAmount: this.prepayData.amount + this.loanService.getLoanPrepayLoanActionTemplate(this.loanId, prepayDate).subscribe((response: any) => { + this.prepayData = response; + this.prepayLoanForm.patchValue({ + transactionAmount: this.prepayData.amount + }); }); }); - }); } /** diff --git a/src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts b/src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts index 55c0a8c68e..f04abf5a34 100644 --- a/src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts +++ b/src/app/loans/loans-view/loan-account-dashboard/loan-account-dashboard.component.ts @@ -9,16 +9,17 @@ import { ChangeDetectionStrategy, Component, + DestroyRef, OnInit, AfterViewInit, + OnDestroy, ViewChild, ElementRef, - inject, - OnDestroy + inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { Subscription } from 'rxjs'; import { MatCard, MatCardHeader, MatCardContent, MatCardTitle } from '@angular/material/card'; import { Chart, registerables } from 'chart.js'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; @@ -44,10 +45,9 @@ Chart.register(...registerables); changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanAccountDashboardComponent implements OnInit, AfterViewInit, OnDestroy { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private translate = inject(TranslateService); - private langChangeSubscription?: Subscription; - private routeDataSubscription?: Subscription; @ViewChild('statusChart', { static: false }) statusChartCanvas!: ElementRef; @ViewChild('paymentsChart', { static: false }) paymentsChartCanvas!: ElementRef; @@ -71,7 +71,7 @@ export class LoanAccountDashboardComponent implements OnInit, AfterViewInit, OnD ngOnInit(): void { this.loanId = this.route.parent?.snapshot.paramMap.get('loanId') || ''; - this.routeDataSubscription = this.route.parent!.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent?.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { if (data.loanDetailsData) { this.loanData = data.loanDetailsData; this.calculateMetrics(); @@ -82,7 +82,7 @@ export class LoanAccountDashboardComponent implements OnInit, AfterViewInit, OnD } }); - this.langChangeSubscription = this.translate.onLangChange.subscribe(() => { + this.translate.onLangChange.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { if (this.statusChart) { this.createStatusChart(); } @@ -332,12 +332,6 @@ export class LoanAccountDashboardComponent implements OnInit, AfterViewInit, OnD clearTimeout(this.initTimeout); this.initTimeout = null; } - if (this.routeDataSubscription) { - this.routeDataSubscription.unsubscribe(); - } - if (this.langChangeSubscription) { - this.langChangeSubscription.unsubscribe(); - } if (this.statusChart) { this.statusChart.destroy(); } diff --git a/src/app/loans/loans-view/loan-collateral-tab/loan-collateral-tab.component.ts b/src/app/loans/loans-view/loan-collateral-tab/loan-collateral-tab.component.ts index bf1285d049..2409e108a8 100644 --- a/src/app/loans/loans-view/loan-collateral-tab/loan-collateral-tab.component.ts +++ b/src/app/loans/loans-view/loan-collateral-tab/loan-collateral-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute, RouterLink } from '@angular/router'; import { MatTable, @@ -44,6 +45,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanCollateralTabComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); /** Loan Collateral Details */ @@ -63,7 +65,7 @@ export class LoanCollateralTabComponent implements OnInit { * @param {ActivatedRoute} route Activated Route. */ constructor() { - this.route.data.subscribe((data: { loanCollaterals: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanCollaterals: any }) => { this.loanCollaterals = data.loanCollaterals; }); } diff --git a/src/app/loans/loans-view/loan-deferred-income-tab/loan-deferred-income-tab.component.ts b/src/app/loans/loans-view/loan-deferred-income-tab/loan-deferred-income-tab.component.ts index d27d8eb5c0..8b9d9a4bb6 100644 --- a/src/app/loans/loans-view/loan-deferred-income-tab/loan-deferred-income-tab.component.ts +++ b/src/app/loans/loans-view/loan-deferred-income-tab/loan-deferred-income-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatCell, MatCellDef, @@ -45,6 +46,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanDeferredIncomeTabComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); capitalizedIncomeData: LoanCapitalizedIncomeData[] = []; @@ -62,15 +64,17 @@ export class LoanDeferredIncomeTabComponent { this.loanId = this.route.parent.parent.snapshot.params['loanId']; this.capitalizedIncomeData = []; - this.route.parent.data.subscribe((data: { loanDeferredIncomeData: LoanDeferredIncomeData }) => { - data.loanDeferredIncomeData.capitalizedIncomeData.forEach((item: LoanCapitalizedIncomeData) => { - this.capitalizedIncomeData.push({ - amount: item.amount, - amortizedAmount: item.amortizedAmount ?? 0, - unrecognizedAmount: item.unrecognizedAmount ?? 0, - amountAdjustment: item.amountAdjustment ?? 0 + this.route.parent.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanDeferredIncomeData: LoanDeferredIncomeData }) => { + data.loanDeferredIncomeData.capitalizedIncomeData.forEach((item: LoanCapitalizedIncomeData) => { + this.capitalizedIncomeData.push({ + amount: item.amount, + amortizedAmount: item.amortizedAmount ?? 0, + unrecognizedAmount: item.unrecognizedAmount ?? 0, + amountAdjustment: item.amountAdjustment ?? 0 + }); }); }); - }); } } diff --git a/src/app/loans/loans-view/loan-delinquency-tags-tab/loan-delinquency-tags-tab.component.ts b/src/app/loans/loans-view/loan-delinquency-tags-tab/loan-delinquency-tags-tab.component.ts index 742d2a6c1b..2c0bbb2a1f 100644 --- a/src/app/loans/loans-view/loan-delinquency-tags-tab/loan-delinquency-tags-tab.component.ts +++ b/src/app/loans/loans-view/loan-delinquency-tags-tab/loan-delinquency-tags-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -74,6 +75,7 @@ import { ProductsService } from 'app/products/products.service'; changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanDelinquencyTagsTabComponent extends LoanProductBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansServices = inject(LoansService); private productsServices = inject(ProductsService); @@ -128,28 +130,30 @@ export class LoanDelinquencyTagsTabComponent extends LoanProductBaseComponent im this.loanId = this.route.parent.parent.snapshot.params['loanId']; this.businessDate = this.settingsService.businessDate; - this.route.parent.data.subscribe( - (data: { - loanDelinquencyTagsData: LoanDelinquencyTags[]; - loanDelinquencyData: any; - loanDelinquencyActions: LoanDelinquencyAction[]; - wcLoanDelinquencyRangeSchedule: DelinquencyRangeSchedule[]; - }) => { - this.loanDelinquencyTags = data.loanDelinquencyTagsData; - this.setLoanDelinquencyAction(data.loanDelinquencyActions || []); - const loanDelinquencyDataResponse = data.loanDelinquencyData ?? null; - const loanDelinquencyData: DelinquentData | null = loanDelinquencyDataResponse?.delinquent || null; - this.currency = loanDelinquencyDataResponse?.currency; - this.installmentLevelDelinquency = []; - if (loanDelinquencyData != null) { - this.installmentLevelDelinquency = loanDelinquencyData.installmentLevelDelinquency || []; - } - if (loanDelinquencyDataResponse?.product) { - this.loanProductId = loanDelinquencyDataResponse.product.id; + this.route.parent.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe( + (data: { + loanDelinquencyTagsData: LoanDelinquencyTags[]; + loanDelinquencyData: any; + loanDelinquencyActions: LoanDelinquencyAction[]; + wcLoanDelinquencyRangeSchedule: DelinquencyRangeSchedule[]; + }) => { + this.loanDelinquencyTags = data.loanDelinquencyTagsData; + this.setLoanDelinquencyAction(data.loanDelinquencyActions || []); + const loanDelinquencyDataResponse = data.loanDelinquencyData ?? null; + const loanDelinquencyData: DelinquentData | null = loanDelinquencyDataResponse?.delinquent || null; + this.currency = loanDelinquencyDataResponse?.currency; + this.installmentLevelDelinquency = []; + if (loanDelinquencyData != null) { + this.installmentLevelDelinquency = loanDelinquencyData.installmentLevelDelinquency || []; + } + if (loanDelinquencyDataResponse?.product) { + this.loanProductId = loanDelinquencyDataResponse.product.id; + } + this.wcLoanDelinquencyRangeSchedule = data.wcLoanDelinquencyRangeSchedule; } - this.wcLoanDelinquencyRangeSchedule = data.wcLoanDelinquencyRangeSchedule; - } - ); + ); } ngOnInit(): void { diff --git a/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts b/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts index 963aea442b..c788d4f127 100644 --- a/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts +++ b/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; /** Custom Services */ @@ -31,6 +32,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanDocumentsTabComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansService = inject(LoansService); private settingsService = inject(SettingsService); @@ -48,13 +50,13 @@ export class LoanDocumentsTabComponent implements OnInit { constructor() { this.entityId = this.route.parent.snapshot.params['loanId']; - this.route.data.subscribe((data: { loanDocuments: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDocuments: any }) => { this.getLoanDocumentsData(data.loanDocuments); }); } ngOnInit(): void { - this.route.parent.params.subscribe((params) => { + this.route.parent.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { this.entityId = params['loanId']; }); } diff --git a/src/app/loans/loans-view/loan-originators-tab/loan-originators-tab.component.ts b/src/app/loans/loans-view/loan-originators-tab/loan-originators-tab.component.ts index 94f891e9c6..5d88d3b7ac 100644 --- a/src/app/loans/loans-view/loan-originators-tab/loan-originators-tab.component.ts +++ b/src/app/loans/loans-view/loan-originators-tab/loan-originators-tab.component.ts @@ -5,7 +5,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatIconButton } from '@angular/material/button'; import { MatDialog } from '@angular/material/dialog'; import { @@ -52,6 +53,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanOriginatorsTabComponent extends LoanAccountTabBaseComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansService = inject(LoansService); private translateService = inject(TranslateService); @@ -77,10 +79,12 @@ export class LoanOriginatorsTabComponent extends LoanAccountTabBaseComponent { super(); this.clientId = this.route.parent.parent.snapshot.paramMap.get('clientId'); this.loanId = this.route.parent?.parent?.snapshot.paramMap.get('loanId'); - this.route.parent.parent.data.subscribe((data: { loanDetailsData: any }) => { - this.loanStatus = data.loanDetailsData.status; - }); - this.route.parent.data.subscribe((data: { loanOriginatorsData: any }) => { + this.route.parent.parent.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanDetailsData: any }) => { + this.loanStatus = data.loanDetailsData.status; + }); + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanOriginatorsData: any }) => { this.loanOriginatorsData = data.loanOriginatorsData.originators; }); } diff --git a/src/app/loans/loans-view/loan-term-variations-tab/loan-term-variations-tab.component.ts b/src/app/loans/loans-view/loan-term-variations-tab/loan-term-variations-tab.component.ts index 88a818c5ee..e79bb17d51 100644 --- a/src/app/loans/loans-view/loan-term-variations-tab/loan-term-variations-tab.component.ts +++ b/src/app/loans/loans-view/loan-term-variations-tab/loan-term-variations-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { Dates } from 'app/core/utils/dates'; @@ -61,6 +62,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanTermVariationsTabComponent extends LoanAccountTabBaseComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private dates = inject(Dates); private settingsService = inject(SettingsService); @@ -98,7 +100,7 @@ export class LoanTermVariationsTabComponent extends LoanAccountTabBaseComponent this.interestPausesData = []; this.clientId = this.route.parent.parent.snapshot.paramMap.get('clientId'); - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanId = data.loanDetailsData.id; this.loanTermVariationsData = []; data.loanDetailsData.loanTermVariations?.forEach((item: any) => { diff --git a/src/app/loans/loans-view/loan-tranche-details/loan-tranche-details.component.ts b/src/app/loans/loans-view/loan-tranche-details/loan-tranche-details.component.ts index ed3fff3033..4990a706cf 100644 --- a/src/app/loans/loans-view/loan-tranche-details/loan-tranche-details.component.ts +++ b/src/app/loans/loans-view/loan-tranche-details/loan-tranche-details.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { Dates } from 'app/core/utils/dates'; @@ -65,6 +66,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class LoanTrancheDetailsComponent extends LoanAccountTabBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private dialog = inject(MatDialog); private loanServices = inject(LoansService); @@ -101,7 +103,7 @@ export class LoanTrancheDetailsComponent extends LoanAccountTabBaseComponent imp */ constructor() { super(); - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanId = data.loanDetailsData.id; this.loanDetails = data.loanDetailsData; this.disallowExpectedDisbursements = this.loanDetails.disallowExpectedDisbursements || false; diff --git a/src/app/loans/loans-view/loans-view.component.ts b/src/app/loans/loans-view/loans-view.component.ts index 6cc81dda8a..c55d82afa2 100644 --- a/src/app/loans/loans-view/loans-view.component.ts +++ b/src/app/loans/loans-view/loans-view.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute, NavigationExtras, RouterLinkActive, RouterOutlet } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; @@ -75,6 +76,7 @@ import { LoanProductBaseComponent } from 'app/products/loan-products/common/loan changeDetection: ChangeDetectionStrategy.OnPush }) export class LoansViewComponent extends LoanProductBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); loansService = inject(LoansService); private translateService = inject(TranslateService); @@ -114,8 +116,9 @@ export class LoansViewComponent extends LoanProductBaseComponent implements OnIn const loansService = this.loansService; this.loanProductService.initialize(LoanProductBaseComponent.resolveProductTypeDefault(this.route, 'loan')); - this.route.data.subscribe( - (data: { loanDetailsData: any; loanDatatables: any; loanArrearsDelinquencyConfig: any }) => { + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanDetailsData: any; loanDatatables: any; loanArrearsDelinquencyConfig: any }) => { this.loanDetailsData = data.loanDetailsData; if (!this.loanDetailsData.loanProductName) { this.loanDetailsData.loanProductName = this.loanDetailsData.product.name; @@ -142,13 +145,12 @@ export class LoansViewComponent extends LoanProductBaseComponent implements OnIn this.filterDatatablesByProduct(); } this.setConditionalButtons(); - } - ); + }); this.loanId = this.route.snapshot.params['loanId']; } ngOnInit() { - this.route.params.subscribe((params) => { + this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { if (this.loanId != params['loanId']) { this.loanId = params['loanId']; this.reload(); diff --git a/src/app/loans/loans-view/notes-tab/notes-tab.component.ts b/src/app/loans/loans-view/notes-tab/notes-tab.component.ts index 0216885641..284c689dad 100644 --- a/src/app/loans/loans-view/notes-tab/notes-tab.component.ts +++ b/src/app/loans/loans-view/notes-tab/notes-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; /** Custom Components */ @@ -28,6 +29,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class NotesTabComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansService = inject(LoansService); private authenticationService = inject(AuthenticationService); @@ -40,13 +42,13 @@ export class NotesTabComponent implements OnInit { const savedCredentials = this.authenticationService.getCredentials(); this.username = savedCredentials.username; this.entityId = this.route.parent.snapshot.params['loanId']; - this.route.data.subscribe((data: { loanNotes: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanNotes: any }) => { this.entityNotes = data.loanNotes; }); } ngOnInit(): void { - this.route.parent.params.subscribe((params) => { + this.route.parent.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { this.entityId = params['loanId']; }); } diff --git a/src/app/loans/loans-view/original-schedule-tab/original-schedule-tab.component.ts b/src/app/loans/loans-view/original-schedule-tab/original-schedule-tab.component.ts index ed2c1fa926..070ad33482 100644 --- a/src/app/loans/loans-view/original-schedule-tab/original-schedule-tab.component.ts +++ b/src/app/loans/loans-view/original-schedule-tab/original-schedule-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { Currency } from 'app/shared/models/general.model'; import { @@ -59,6 +60,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class OriginalScheduleTabComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); /** Loan Details Data */ @@ -82,7 +84,7 @@ export class OriginalScheduleTabComponent { * @param {ActivatedRoute} route Activated Route. */ constructor() { - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.currency = data.loanDetailsData.currency; this.originalScheduleDetails = data.loanDetailsData.originalSchedule; }); diff --git a/src/app/loans/loans-view/overdue-charges-tab/overdue-charges-tab.component.ts b/src/app/loans/loans-view/overdue-charges-tab/overdue-charges-tab.component.ts index 66961ce584..622cfa2dc9 100644 --- a/src/app/loans/loans-view/overdue-charges-tab/overdue-charges-tab.component.ts +++ b/src/app/loans/loans-view/overdue-charges-tab/overdue-charges-tab.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, ViewChild, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, ViewChild, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort, MatSortHeader } from '@angular/material/sort'; import { @@ -54,6 +55,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class OverdueChargesTabComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); /** Stores the resolved loan data */ @@ -81,7 +83,7 @@ export class OverdueChargesTabComponent implements OnInit { * @param {ActivatedRoute} route Activated Route. */ constructor() { - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanDetails = data.loanDetailsData; }); } diff --git a/src/app/loans/loans-view/reschedule-loan-tab/reschedule-loan-tab.component.ts b/src/app/loans/loans-view/reschedule-loan-tab/reschedule-loan-tab.component.ts index ad13f6dd75..97ef7e0763 100644 --- a/src/app/loans/loans-view/reschedule-loan-tab/reschedule-loan-tab.component.ts +++ b/src/app/loans/loans-view/reschedule-loan-tab/reschedule-loan-tab.component.ts @@ -6,7 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { ChangeDetectionStrategy, Component, Input, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, Input, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -60,6 +61,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class RescheduleLoanTabComponent extends LoanAccountTabBaseComponent { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansServices = inject(LoansService); private settingsService = inject(SettingsService); @@ -82,7 +84,7 @@ export class RescheduleLoanTabComponent extends LoanAccountTabBaseComponent { constructor() { super(); this.clientId = this.route.parent.parent.snapshot.paramMap.get('clientId'); - this.route.parent.data.subscribe((data: { loanRescheduleData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanRescheduleData: any }) => { this.loanRescheduleData = data.loanRescheduleData; }); } diff --git a/src/app/loans/loans-view/standing-instructions-tab/standing-instructions-tab.component.ts b/src/app/loans/loans-view/standing-instructions-tab/standing-instructions-tab.component.ts index 8cc274b508..23962f4651 100644 --- a/src/app/loans/loans-view/standing-instructions-tab/standing-instructions-tab.component.ts +++ b/src/app/loans/loans-view/standing-instructions-tab/standing-instructions-tab.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, ViewChild, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, ViewChild, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatDialog } from '@angular/material/dialog'; import { MatTableDataSource, @@ -60,6 +61,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class StandingInstructionsTabComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private loansService = inject(LoansService); private dialog = inject(MatDialog); @@ -92,7 +94,7 @@ export class StandingInstructionsTabComponent implements OnInit { * @param {SettingsService} settingsService Settings Service */ constructor() { - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { + this.route.parent.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loanDetailsData: any }) => { this.loanDetailsData = data.loanDetailsData; }); } diff --git a/src/app/loans/loans-view/transactions/edit-transaction/edit-transaction.component.ts b/src/app/loans/loans-view/transactions/edit-transaction/edit-transaction.component.ts index bd53e8beeb..25ebaf0d34 100644 --- a/src/app/loans/loans-view/transactions/edit-transaction/edit-transaction.component.ts +++ b/src/app/loans/loans-view/transactions/edit-transaction/edit-transaction.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms'; import { Dates } from 'app/core/utils/dates'; @@ -34,6 +35,7 @@ import { LoanAccountActionsBaseComponent } from '../../loan-account-actions/loan changeDetection: ChangeDetectionStrategy.OnPush }) export class EditTransactionComponent extends LoanAccountActionsBaseComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private formBuilder = inject(UntypedFormBuilder); private dateUtils = inject(Dates); private loansService = inject(LoansService); @@ -71,13 +73,15 @@ export class EditTransactionComponent extends LoanAccountActionsBaseComponent im */ constructor() { super(); - this.route.data.subscribe((data: { loansAccountTransactionTemplate: any }) => { - this.transactionTemplateData = data.loansAccountTransactionTemplate; - if (data.loansAccountTransactionTemplate.currency) { - this.currency = data.loansAccountTransactionTemplate.currency; - } - this.paymentTypeOptions = this.transactionTemplateData.paymentTypeOptions; - }); + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loansAccountTransactionTemplate: any }) => { + this.transactionTemplateData = data.loansAccountTransactionTemplate; + if (data.loansAccountTransactionTemplate.currency) { + this.currency = data.loansAccountTransactionTemplate.currency; + } + this.paymentTypeOptions = this.transactionTemplateData.paymentTypeOptions; + }); this.loanAccountId = this.route.snapshot.params['loanId']; } diff --git a/src/app/loans/loans-view/transactions/export-transactions/export-transactions.component.ts b/src/app/loans/loans-view/transactions/export-transactions/export-transactions.component.ts index 3d5acf7625..4f8d73797d 100644 --- a/src/app/loans/loans-view/transactions/export-transactions/export-transactions.component.ts +++ b/src/app/loans/loans-view/transactions/export-transactions/export-transactions.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { DomSanitizer } from '@angular/platform-browser'; import { UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, RouterLink } from '@angular/router'; @@ -33,6 +34,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class ExportTransactionsComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private sanitizer = inject(DomSanitizer); private reportsService = inject(ReportsService); private formBuilder = inject(UntypedFormBuilder); @@ -63,9 +65,11 @@ export class ExportTransactionsComponent implements OnInit { * @param {SettingsService} settingsService Settings Service */ constructor() { - this.route.parent.parent.data.subscribe((data: { loanDetailsData: any }) => { - this.loansAccountId = data.loanDetailsData.accountNo; - }); + this.route.parent.parent.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanDetailsData: any }) => { + this.loansAccountId = data.loanDetailsData.accountNo; + }); } ngOnInit() { diff --git a/src/app/loans/loans-view/transactions/view-reciept/view-reciept.component.ts b/src/app/loans/loans-view/transactions/view-reciept/view-reciept.component.ts index 98332789d4..828ac16d5b 100644 --- a/src/app/loans/loans-view/transactions/view-reciept/view-reciept.component.ts +++ b/src/app/loans/loans-view/transactions/view-reciept/view-reciept.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { DomSanitizer } from '@angular/platform-browser'; import { ActivatedRoute, RouterLink } from '@angular/router'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; @@ -27,6 +28,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; changeDetection: ChangeDetectionStrategy.OnPush }) export class ViewRecieptComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private sanitizer = inject(DomSanitizer); private route = inject(ActivatedRoute); @@ -41,7 +43,7 @@ export class ViewRecieptComponent implements OnInit { * @param {ActivatedRoute} route Activated Route */ constructor() { - this.route.data.subscribe((data: { loansTransactionReciept: any }) => { + this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { loansTransactionReciept: any }) => { this.transactionRecieptData = data.loansTransactionReciept; }); } diff --git a/src/app/loans/loans-view/view-charge/view-charge.component.ts b/src/app/loans/loans-view/view-charge/view-charge.component.ts index bd6243b29d..d797fffe63 100644 --- a/src/app/loans/loans-view/view-charge/view-charge.component.ts +++ b/src/app/loans/loans-view/view-charge/view-charge.component.ts @@ -7,7 +7,8 @@ */ /** Angular Imports */ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, DestroyRef, inject } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ActivatedRoute } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; @@ -50,6 +51,7 @@ import { LoanAccountTabBaseComponent } from '../loan-account-tab-base.component' changeDetection: ChangeDetectionStrategy.OnPush }) export class ViewChargeComponent extends LoanAccountTabBaseComponent { + private readonly destroyRef = inject(DestroyRef); private loansService = inject(LoansService); private route = inject(ActivatedRoute); private dateUtils = inject(Dates); @@ -75,12 +77,14 @@ export class ViewChargeComponent extends LoanAccountTabBaseComponent { */ constructor() { super(); - this.route.data.subscribe((data: { loansAccountCharge: any; loanDetailsData: any }) => { - this.chargeData = data.loansAccountCharge; - this.allowPayCharge = this.chargeData.chargePayable && !this.chargeData.paid; - this.allowWaive = !this.chargeData.chargeTimeType.waived; - this.loansAccountData = data.loanDetailsData; - }); + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loansAccountCharge: any; loanDetailsData: any }) => { + this.chargeData = data.loansAccountCharge; + this.allowPayCharge = this.chargeData.chargePayable && !this.chargeData.paid; + this.allowWaive = !this.chargeData.chargeTimeType.waived; + this.loansAccountData = data.loanDetailsData; + }); } /** diff --git a/src/app/loans/loans-view/working-capital/loan-period-payment-rates/loan-period-payment-rates.component.ts b/src/app/loans/loans-view/working-capital/loan-period-payment-rates/loan-period-payment-rates.component.ts index a5ad247d69..4e1682fd4b 100644 --- a/src/app/loans/loans-view/working-capital/loan-period-payment-rates/loan-period-payment-rates.component.ts +++ b/src/app/loans/loans-view/working-capital/loan-period-payment-rates/loan-period-payment-rates.component.ts @@ -5,7 +5,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Component, inject, OnInit } from '@angular/core'; +import { Component, DestroyRef, inject, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; import { MatTable, @@ -50,6 +51,7 @@ import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base'; ] }) export class LoanPeriodPaymentRatesComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); private route = inject(ActivatedRoute); private dialog = inject(MatDialog); private translateService = inject(TranslateService); @@ -73,9 +75,11 @@ export class LoanPeriodPaymentRatesComponent implements OnInit { ngOnInit(): void { this.loanId = this.route.parent.snapshot.params['loanId']; - this.route.data.subscribe((data: { loanPaymentRatesData: PeriodPaymentRateChange[] }) => { - this.loanPaymentRatesData = data.loanPaymentRatesData; - }); + this.route.data + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((data: { loanPaymentRatesData: PeriodPaymentRateChange[] }) => { + this.loanPaymentRatesData = data.loanPaymentRatesData; + }); } addPaymentRate(): void { diff --git a/src/app/loans/models/loan-form.model.ts b/src/app/loans/models/loan-form.model.ts new file mode 100644 index 0000000000..784c1ddb57 --- /dev/null +++ b/src/app/loans/models/loan-form.model.ts @@ -0,0 +1,24 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { FormControl } from '@angular/forms'; + +export interface RepaymentForm { + transactionDate: FormControl; + externalId: FormControl; + paymentTypeId: FormControl; + note: FormControl; + skipInterestRefund: FormControl; + transactionAmount: FormControl; + classificationId?: FormControl; + accountNumber?: FormControl; + checkNumber?: FormControl; + routingCode?: FormControl; + receiptNumber?: FormControl; + bankNumber?: FormControl; +}