diff --git a/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/account.service.ts b/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/account.service.ts index adeb2ee5c9..ad584495c6 100644 --- a/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/account.service.ts +++ b/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/account.service.ts @@ -1,12 +1,14 @@ import type { RegisterDto, ResetPasswordDto, SendPasswordResetCodeDto } from './models'; import { RestService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import type { IdentityUserDto } from '../identity/models'; @Injectable({ providedIn: 'root', }) export class AccountService { + private restService = inject(RestService); + apiName = 'AbpAccount'; register = (input: RegisterDto) => @@ -32,6 +34,4 @@ export class AccountService { body: input, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/profile.service.ts b/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/profile.service.ts index 0cea6b8cfb..a14c6cedfd 100644 --- a/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/profile.service.ts +++ b/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/profile.service.ts @@ -1,11 +1,13 @@ import type { ChangePasswordInput, ProfileDto, UpdateProfileDto } from './models'; import { RestService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class ProfileService { + private restService = inject(RestService); + apiName = 'AbpAccount'; changePassword = (input: ChangePasswordInput) => @@ -30,6 +32,4 @@ export class ProfileService { body: input, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/web/areas/account/controllers/account.service.ts b/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/web/areas/account/controllers/account.service.ts index 8adf5385b0..52c779655b 100644 --- a/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/web/areas/account/controllers/account.service.ts +++ b/npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/web/areas/account/controllers/account.service.ts @@ -1,11 +1,13 @@ import type { AbpLoginResult, UserLoginInfo } from './models/models'; import { RestService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class AccountService { + private restService = inject(RestService); + apiName = 'AbpAccount'; checkPasswordByLogin = (login: UserLoginInfo) => @@ -30,6 +32,4 @@ export class AccountService { url: '/api/account/logout', }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/account-core/src/lib/auth-wrapper.service.ts b/npm/ng-packs/packages/account-core/src/lib/auth-wrapper.service.ts index 7bad8ef96a..10ca25380b 100644 --- a/npm/ng-packs/packages/account-core/src/lib/auth-wrapper.service.ts +++ b/npm/ng-packs/packages/account-core/src/lib/auth-wrapper.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable, Injector, inject } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { ActivatedRoute } from '@angular/router'; @@ -6,6 +6,9 @@ import { ConfigStateService, MultiTenancyService } from '@abp/ng.core'; @Injectable() export class AuthWrapperService { + readonly multiTenancy = inject(MultiTenancyService); + private configState = inject(ConfigStateService); + isMultiTenancyEnabled$ = this.configState.getDeep$('multiTenancy.isEnabled'); get enableLocalLogin$(): Observable { @@ -25,11 +28,9 @@ export class AuthWrapperService { return this.isTenantBoxVisibleForCurrentRoute && this.multiTenancy.isTenantBoxVisible; } - constructor( - public readonly multiTenancy: MultiTenancyService, - private configState: ConfigStateService, - injector: Injector, - ) { + constructor() { + const injector = inject(Injector); + this.route = injector.get(ActivatedRoute); } diff --git a/npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts b/npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts index bcb37c3d48..2890d90776 100644 --- a/npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts +++ b/npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts @@ -5,11 +5,16 @@ import { SessionStateService, } from '@abp/ng.core'; import { ToasterService } from '@abp/ng.theme.shared'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { finalize } from 'rxjs/operators'; @Injectable() export class TenantBoxService { + private toasterService = inject(ToasterService); + private tenantService = inject(AbpTenantService); + private sessionState = inject(SessionStateService); + private configState = inject(ConfigStateService); + currentTenant$ = this.sessionState.getTenant$(); name?: string; @@ -18,13 +23,6 @@ export class TenantBoxService { modalBusy!: boolean; - constructor( - private toasterService: ToasterService, - private tenantService: AbpTenantService, - private sessionState: SessionStateService, - private configState: ConfigStateService, - ) {} - onSwitch() { const tenant = this.sessionState.getTenant(); this.name = tenant?.name || ''; diff --git a/npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts b/npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts index 9e1ae788f0..ad5db820ac 100644 --- a/npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts @@ -1,6 +1,6 @@ import { ProfileService } from '@abp/ng.account.core/proxy'; import { ButtonComponent, getPasswordValidators, ToasterService } from '@abp/ng.theme.shared'; -import { Component, Injector, OnInit } from '@angular/core'; +import { Component, Injector, OnInit, inject } from '@angular/core'; import { ReactiveFormsModule, UntypedFormBuilder, @@ -32,6 +32,12 @@ const PASSWORD_FIELDS = ['newPassword', 'repeatNewPassword']; export class ChangePasswordComponent implements OnInit, Account.ChangePasswordComponentInputs, Account.ChangePasswordComponentOutputs { + private fb = inject(UntypedFormBuilder); + private injector = inject(Injector); + private toasterService = inject(ToasterService); + private profileService = inject(ProfileService); + private manageProfileState = inject(ManageProfileStateService); + form!: UntypedFormGroup; inProgress?: boolean; @@ -44,14 +50,6 @@ export class ChangePasswordComponent return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch')); }; - constructor( - private fb: UntypedFormBuilder, - private injector: Injector, - private toasterService: ToasterService, - private profileService: ProfileService, - private manageProfileState: ManageProfileStateService, - ) {} - ngOnInit(): void { this.hideCurrentPassword = !this.manageProfileState.getProfile()?.hasPassword; diff --git a/npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts b/npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts index 815c95d71c..873d45c243 100644 --- a/npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts @@ -1,5 +1,5 @@ import { AccountService } from '@abp/ng.account.core/proxy'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { ReactiveFormsModule, UntypedFormBuilder, @@ -24,16 +24,16 @@ import { NgxValidateCoreModule } from '@ngx-validate/core'; ], }) export class ForgotPasswordComponent { + private fb = inject(UntypedFormBuilder); + private accountService = inject(AccountService); + form: UntypedFormGroup; inProgress?: boolean; isEmailSent = false; - constructor( - private fb: UntypedFormBuilder, - private accountService: AccountService, - ) { + constructor() { this.form = this.fb.group({ email: ['', [Validators.required, Validators.email]], }); diff --git a/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts b/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts index 797bb9f492..d7e8c8b98d 100644 --- a/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts @@ -1,7 +1,7 @@ import { ProfileService } from '@abp/ng.account.core/proxy'; import { fadeIn, LoadingDirective } from '@abp/ng.theme.shared'; import { transition, trigger, useAnimation } from '@angular/animations'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { eAccountComponents } from '../../enums/components'; import { ManageProfileStateService } from '../../services/manage-profile.state.service'; import { CommonModule } from '@angular/common'; @@ -33,6 +33,9 @@ import { ChangePasswordComponent } from '../change-password/change-password.comp ], }) export class ManageProfileComponent implements OnInit { + protected profileService = inject(ProfileService); + protected manageProfileState = inject(ManageProfileStateService); + selectedTab = 0; changePasswordKey = eAccountComponents.ChangePassword; @@ -43,11 +46,6 @@ export class ManageProfileComponent implements OnInit { hideChangePasswordTab?: boolean; - constructor( - protected profileService: ProfileService, - protected manageProfileState: ManageProfileStateService, - ) {} - ngOnInit() { this.profileService.get().subscribe(profile => { this.manageProfileState.setProfile(profile); diff --git a/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts b/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts index ac99a51c23..be6287e954 100644 --- a/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { EXTENSIONS_FORM_PROP, FormProp, @@ -24,12 +24,16 @@ import { LocalizationPipe } from '@abp/ng.core'; imports: [ReactiveFormsModule, LocalizationPipe], }) export class PersonalSettingsHalfRowComponent { + private propData = inject(EXTENSIONS_FORM_PROP); + public displayName: string; public name: string; public id: string; public formGroup!: UntypedFormGroup; - constructor(@Inject(EXTENSIONS_FORM_PROP) private propData: FormProp) { + constructor() { + const propData = this.propData; + this.displayName = propData.displayName; this.name = propData.name; this.id = propData.id || ''; diff --git a/npm/ng-packs/packages/account/src/lib/components/register/register.component.ts b/npm/ng-packs/packages/account/src/lib/components/register/register.component.ts index 18b4935c92..93bbfe26f4 100644 --- a/npm/ng-packs/packages/account/src/lib/components/register/register.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/register/register.component.ts @@ -6,7 +6,7 @@ import { LocalizationPipe, } from '@abp/ng.core'; import { ButtonComponent, getPasswordValidators, ToasterService } from '@abp/ng.theme.shared'; -import { Component, Injector, OnInit } from '@angular/core'; +import { Component, Injector, OnInit, inject } from '@angular/core'; import { ReactiveFormsModule, UntypedFormBuilder, @@ -35,6 +35,13 @@ const { maxLength, required, email } = Validators; ], }) export class RegisterComponent implements OnInit { + protected fb = inject(UntypedFormBuilder); + protected accountService = inject(AccountService); + protected configState = inject(ConfigStateService); + protected toasterService = inject(ToasterService); + protected authService = inject(AuthService); + protected injector = inject(Injector); + form!: UntypedFormGroup; inProgress?: boolean; @@ -43,15 +50,6 @@ export class RegisterComponent implements OnInit { authWrapperKey = eAccountComponents.AuthWrapper; - constructor( - protected fb: UntypedFormBuilder, - protected accountService: AccountService, - protected configState: ConfigStateService, - protected toasterService: ToasterService, - protected authService: AuthService, - protected injector: Injector, - ) {} - ngOnInit() { this.init(); this.buildForm(); diff --git a/npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts b/npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts index d04a99ae98..1e8d043000 100644 --- a/npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts @@ -1,6 +1,6 @@ import { AccountService } from '@abp/ng.account.core/proxy'; import { ButtonComponent, getPasswordValidators } from '@abp/ng.theme.shared'; -import { Component, Injector, OnInit } from '@angular/core'; +import { Component, Injector, OnInit, inject } from '@angular/core'; import { ReactiveFormsModule, UntypedFormBuilder, @@ -26,6 +26,12 @@ const PASSWORD_FIELDS = ['password', 'confirmPassword']; ], }) export class ResetPasswordComponent implements OnInit { + private fb = inject(UntypedFormBuilder); + private accountService = inject(AccountService); + private route = inject(ActivatedRoute); + private router = inject(Router); + private injector = inject(Injector); + form!: UntypedFormGroup; inProgress = false; @@ -38,14 +44,6 @@ export class ResetPasswordComponent implements OnInit { return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch')); }; - constructor( - private fb: UntypedFormBuilder, - private accountService: AccountService, - private route: ActivatedRoute, - private router: Router, - private injector: Injector, - ) {} - ngOnInit(): void { this.route.queryParams.subscribe(({ userId, resetToken }) => { if (!userId || !resetToken) this.router.navigateByUrl('/account/login'); diff --git a/npm/ng-packs/packages/components/chart.js/src/chart.component.ts b/npm/ng-packs/packages/components/chart.js/src/chart.component.ts index c700a0bce8..9ab84aedcd 100644 --- a/npm/ng-packs/packages/components/chart.js/src/chart.component.ts +++ b/npm/ng-packs/packages/components/chart.js/src/chart.component.ts @@ -1,16 +1,17 @@ -import { - AfterViewInit, - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - ElementRef, - EventEmitter, - Input, - OnChanges, - OnDestroy, - Output, - SimpleChanges, - ViewChild, +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + EventEmitter, + Input, + OnChanges, + OnDestroy, + Output, + SimpleChanges, + ViewChild, + inject } from '@angular/core'; let Chart: any; @@ -35,6 +36,9 @@ let Chart: any; exportAs: 'abpChart', }) export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges { + el = inject(ElementRef); + private cdr = inject(ChangeDetectorRef); + @Input() type!: string; @Input() data: any = {}; @@ -57,11 +61,6 @@ export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges { chart: any; - constructor( - public el: ElementRef, - private cdr: ChangeDetectorRef, - ) {} - ngAfterViewInit() { import('chart.js/auto').then(module => { Chart = module.default; diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/abstract-actions/abstract-actions.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/abstract-actions/abstract-actions.component.ts index 394e125798..465a18b813 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/abstract-actions/abstract-actions.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/abstract-actions/abstract-actions.component.ts @@ -1,4 +1,4 @@ -import { Directive, Injector, Input } from '@angular/core'; +import { Directive, Injector, Input, inject } from '@angular/core'; import { ActionData, ActionList, InferredAction } from '../../models/actions'; import { ExtensionsService } from '../../services/extensions.service'; import { EXTENSIONS_ACTION_TYPE, EXTENSIONS_IDENTIFIER } from '../../tokens/extensions.token'; @@ -16,7 +16,9 @@ export abstract class AbstractActionsComponent< @Input() record!: InferredData['record']; - protected constructor(injector: Injector) { + protected constructor() { + const injector = inject(Injector); + super(); this.getInjected = injector.get.bind(injector); const extensions = injector.get(ExtensionsService); diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts index 5307a4a671..0e3d25f26c 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts @@ -1,9 +1,8 @@ -import { - ChangeDetectionStrategy, - Component, - Injector, - Input, - TrackByFunction, +import { + ChangeDetectionStrategy, + Component, + Input, + TrackByFunction, } from '@angular/core'; import { EntityAction, EntityActionList } from '../../models/entity-actions'; import { EXTENSIONS_ACTION_TYPE } from '../../tokens/extensions.token'; @@ -43,7 +42,7 @@ export class GridActionsComponent extends AbstractActionsComponent> = (_, item) => item.text; - constructor(injector: Injector) { - super(injector); + constructor() { + super(); } } diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts index 7492b6f94e..36b195f933 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Injector, TrackByFunction } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Injector, TrackByFunction, inject } from '@angular/core'; import { HasCreateInjectorPipe, ToolbarAction, @@ -35,6 +35,8 @@ export class PageToolbarComponent extends AbstractActionsComponent> implements HasCreateInjectorPipe { + readonly injector: Injector; + defaultBtnClass = 'btn btn-sm btn-primary'; getData = () => this.data; @@ -42,8 +44,12 @@ export class PageToolbarComponent readonly trackByFn: TrackByFunction> = (_, item) => item.action || item.component; - constructor(public readonly injector: Injector) { - super(injector); + constructor() { + const injector = inject(Injector); + + super(); + + this.injector = injector; } asToolbarAction(value: ToolbarActionDefault): { value: ToolbarAction } { diff --git a/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts b/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts index 2bba45ff70..b7a05d314b 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts @@ -1,12 +1,13 @@ /* eslint-disable @angular-eslint/no-input-rename */ -import { - Directive, - Injector, - Input, - OnChanges, - OnDestroy, - TemplateRef, - ViewContainerRef, +import { + Directive, + Injector, + Input, + OnChanges, + OnDestroy, + TemplateRef, + ViewContainerRef, + inject } from '@angular/core'; import { PropData, PropList } from '../models/props'; @@ -18,6 +19,9 @@ export class PropDataDirective> extends PropData> implements OnChanges, OnDestroy { + private tempRef = inject>(TemplateRef); + private vcRef = inject(ViewContainerRef); + @Input('abpPropDataFromList') propList?: L; @Input('abpPropDataWithRecord') record!: InferredData['record']; @@ -26,11 +30,9 @@ export class PropDataDirective> readonly getInjected: InferredData['getInjected']; - constructor( - private tempRef: TemplateRef, - private vcRef: ViewContainerRef, - injector: Injector, - ) { + constructor() { + const injector = inject(Injector); + super(); this.getInjected = injector.get.bind(injector); diff --git a/npm/ng-packs/packages/components/page/src/page-part.directive.ts b/npm/ng-packs/packages/components/page/src/page-part.directive.ts index a89302916b..bfaf1e60b6 100644 --- a/npm/ng-packs/packages/components/page/src/page-part.directive.ts +++ b/npm/ng-packs/packages/components/page/src/page-part.directive.ts @@ -1,18 +1,17 @@ -import { - Directive, - TemplateRef, - ViewContainerRef, - Input, - InjectionToken, - Optional, - Inject, - OnInit, - OnDestroy, - Injector, - OnChanges, - SimpleChanges, - SimpleChange, -} from '@angular/core'; +import { + Directive, + TemplateRef, + ViewContainerRef, + Input, + InjectionToken, + OnInit, + OnDestroy, + Injector, + OnChanges, + SimpleChanges, + SimpleChange, + inject + } from '@angular/core'; import { Observable, Subscription, of } from 'rxjs'; export interface PageRenderStrategy { @@ -28,6 +27,11 @@ export const PAGE_RENDER_STRATEGY = new InjectionToken('PAGE selector: '[abpPagePart]', }) export class PagePartDirective implements OnInit, OnDestroy, OnChanges { + private templateRef = inject>(TemplateRef); + private viewContainer = inject(ViewContainerRef); + private renderLogic = inject(PAGE_RENDER_STRATEGY, { optional: true })!; + private injector = inject(Injector); + hasRendered = false; type!: string; subscription!: Subscription; @@ -48,13 +52,6 @@ export class PagePartDirective implements OnInit, OnDestroy, OnChanges { } }; - constructor( - private templateRef: TemplateRef, - private viewContainer: ViewContainerRef, - @Optional() @Inject(PAGE_RENDER_STRATEGY) private renderLogic: PageRenderStrategy, - private injector: Injector, - ) {} - ngOnChanges({ context }: SimpleChanges): void { if (this.renderLogic?.onContextUpdate) { this.renderLogic.onContextUpdate(context); diff --git a/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts b/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts index 35706bd25f..e7f1bdb913 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts +++ b/npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts @@ -1,8 +1,8 @@ -import { Directive, TemplateRef } from '@angular/core'; +import { Directive, TemplateRef, inject } from '@angular/core'; + +@Directive({ + selector: '[abpTreeExpandedIconTemplate],[abp-tree-expanded-icon-template]', +}) +export class ExpandedIconTemplateDirective { template = inject>(TemplateRef); -@Directive({ - selector: '[abpTreeExpandedIconTemplate],[abp-tree-expanded-icon-template]', -}) -export class ExpandedIconTemplateDirective { - constructor(public template: TemplateRef) {} -} +} diff --git a/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts b/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts index 56c66af04b..70cf228021 100644 --- a/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts +++ b/npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts @@ -1,8 +1,8 @@ -import { Directive, TemplateRef } from '@angular/core'; +import { Directive, TemplateRef, inject } from '@angular/core'; + +@Directive({ + selector: '[abpTreeNodeTemplate],[abp-tree-node-template]', +}) +export class TreeNodeTemplateDirective { template = inject>(TemplateRef); -@Directive({ - selector: '[abpTreeNodeTemplate],[abp-tree-node-template]', -}) -export class TreeNodeTemplateDirective { - constructor(public template: TemplateRef) {} -} +} diff --git a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts index 549702a1ad..a1961aef4d 100644 --- a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts @@ -1,4 +1,4 @@ -import { Component, inject, isDevMode, OnInit, Optional, SkipSelf, Type } from '@angular/core'; +import { Component, inject, isDevMode, OnInit, Type } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { eLayoutType } from '../enums/common'; import { ABP } from '../models'; @@ -39,7 +39,9 @@ export class DynamicLayoutComponent implements OnInit { protected readonly routerEvents = inject(RouterEvents); protected readonly environment = inject(EnvironmentService); - constructor(@Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent) { + constructor() { + const dynamicLayoutComponent = inject(DynamicLayoutComponent, { optional: true, skipSelf: true })!; + if (dynamicLayoutComponent) { if (isDevMode()) console.warn('DynamicLayoutComponent must be used only in AppComponent.'); return; diff --git a/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts b/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts index 680c7919a8..9ddc294c2b 100644 --- a/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Type } from '@angular/core'; +import { Component, OnInit, Type, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { distinctUntilChanged } from 'rxjs/operators'; import { ReplaceableComponents } from '../models/replaceable-components'; @@ -15,18 +15,16 @@ import { CommonModule } from '@angular/common'; imports: [CommonModule], }) export class ReplaceableRouteContainerComponent implements OnInit { + private route = inject(ActivatedRoute); + private replaceableComponents = inject(ReplaceableComponentsService); + private subscription = inject(SubscriptionService); + defaultComponent!: Type; componentKey!: string; externalComponent?: Type; - constructor( - private route: ActivatedRoute, - private replaceableComponents: ReplaceableComponentsService, - private subscription: SubscriptionService, - ) {} - ngOnInit() { this.defaultComponent = this.route.snapshot.data.replaceableComponent.defaultComponent; this.componentKey = ( diff --git a/npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts index f34d187939..398eaef9cc 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts @@ -1,9 +1,11 @@ -import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core'; +import { AfterViewInit, Directive, ElementRef, Input, inject } from '@angular/core'; @Directive({ selector: '[autofocus]', }) export class AutofocusDirective implements AfterViewInit { + private elRef = inject(ElementRef); + private _delay = 0; @Input('autofocus') @@ -15,8 +17,6 @@ export class AutofocusDirective implements AfterViewInit { return this._delay; } - constructor(private elRef: ElementRef) {} - ngAfterViewInit(): void { setTimeout(() => this.elRef.nativeElement.focus(), this.delay as number); } diff --git a/npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts index 204db6b418..239aed688d 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts @@ -1,4 +1,4 @@ -import { Directive, ElementRef, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Directive, ElementRef, EventEmitter, Input, OnInit, Output, inject } from '@angular/core'; import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { SubscriptionService } from '../services/subscription.service'; @@ -8,15 +8,13 @@ import { SubscriptionService } from '../services/subscription.service'; providers: [SubscriptionService], }) export class InputEventDebounceDirective implements OnInit { + private el = inject(ElementRef); + private subscription = inject(SubscriptionService); + @Input() debounce = 300; @Output('input.debounce') readonly debounceEvent = new EventEmitter(); - constructor( - private el: ElementRef, - private subscription: SubscriptionService, - ) {} - ngOnInit(): void { const input$ = fromEvent(this.el.nativeElement, 'input').pipe( debounceTime(this.debounce), diff --git a/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts index 1e37e1c908..7b3bd0319b 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts @@ -1,15 +1,16 @@ -import { - Directive, - EmbeddedViewRef, - Input, - IterableChangeRecord, - IterableChanges, - IterableDiffer, - IterableDiffers, - OnChanges, - TemplateRef, - TrackByFunction, - ViewContainerRef, +import { + Directive, + EmbeddedViewRef, + Input, + IterableChangeRecord, + IterableChanges, + IterableDiffer, + IterableDiffers, + OnChanges, + TemplateRef, + TrackByFunction, + ViewContainerRef, + inject } from '@angular/core'; import clone from 'just-clone'; import compare from 'just-compare'; @@ -36,6 +37,10 @@ class RecordView { selector: '[abpFor]', }) export class ForDirective implements OnChanges { + private tempRef = inject>(TemplateRef); + private vcRef = inject(ViewContainerRef); + private differs = inject(IterableDiffers); + // eslint-disable-next-line @angular-eslint/no-input-rename @Input('abpForOf') items!: any[]; @@ -73,12 +78,6 @@ export class ForDirective implements OnChanges { return this.trackBy || ((index: number, item: any) => (item as any).id || index); } - constructor( - private tempRef: TemplateRef, - private vcRef: ViewContainerRef, - private differs: IterableDiffers, - ) {} - private iterateOverAppliedOperations(changes: IterableChanges) { const rw: RecordView[] = []; diff --git a/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts index 25972ccb71..879fbdf780 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts @@ -1,12 +1,12 @@ -import { - ChangeDetectorRef, - Directive, - ElementRef, - EventEmitter, - Input, - OnInit, - Output, - Self, +import { + ChangeDetectorRef, + Directive, + ElementRef, + EventEmitter, + Input, + OnInit, + Output, + inject } from '@angular/core'; import { FormGroupDirective, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { fromEvent } from 'rxjs'; @@ -22,6 +22,11 @@ type Controls = { [key: string]: UntypedFormControl } | UntypedFormGroup[]; providers: [SubscriptionService], }) export class FormSubmitDirective implements OnInit { + private formGroupDirective = inject(FormGroupDirective, { self: true }); + private host = inject>(ElementRef); + private cdRef = inject(ChangeDetectorRef); + private subscription = inject(SubscriptionService); + @Input() debounce = 200; @@ -36,13 +41,6 @@ export class FormSubmitDirective implements OnInit { executedNgSubmit = false; - constructor( - @Self() private formGroupDirective: FormGroupDirective, - private host: ElementRef, - private cdRef: ChangeDetectorRef, - private subscription: SubscriptionService, - ) {} - ngOnInit() { this.subscription.addOne(this.formGroupDirective.ngSubmit, () => { if (this.markAsDirtyWhenSubmit) { diff --git a/npm/ng-packs/packages/core/src/lib/directives/init.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/init.directive.ts index 293384e4e1..1271f031ba 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/init.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/init.directive.ts @@ -1,12 +1,12 @@ -import { Directive, Output, EventEmitter, ElementRef, AfterViewInit } from '@angular/core'; +import { Directive, Output, EventEmitter, ElementRef, AfterViewInit, inject } from '@angular/core'; @Directive({ selector: '[abpInit]', }) export class InitDirective implements AfterViewInit { - @Output('abpInit') readonly init = new EventEmitter>(); + private elRef = inject(ElementRef); - constructor(private elRef: ElementRef) {} + @Output('abpInit') readonly init = new EventEmitter>(); ngAfterViewInit() { this.init.emit(this.elRef); diff --git a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts index f277bf50ee..50b805dba4 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts @@ -1,14 +1,13 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Directive, - Inject, - Input, - OnChanges, - OnDestroy, - Optional, - TemplateRef, - ViewContainerRef, +import { + AfterViewInit, + ChangeDetectorRef, + Directive, + Input, + OnChanges, + OnDestroy, + TemplateRef, + ViewContainerRef, + inject } from '@angular/core'; import { ReplaySubject, Subscription } from 'rxjs'; import { distinctUntilChanged, take } from 'rxjs/operators'; @@ -20,6 +19,12 @@ import { QueueManager } from '../utils/queue'; selector: '[abpPermission]', }) export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit { + private templateRef = inject>(TemplateRef, { optional: true })!; + private vcRef = inject(ViewContainerRef); + private permissionService = inject(PermissionService); + private cdRef = inject(ChangeDetectorRef); + queue = inject(QUEUE_MANAGER); + @Input('abpPermission') condition: string | undefined; @Input('abpPermissionRunChangeDetection') runChangeDetection = true; @@ -30,14 +35,6 @@ export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit rendered = false; - constructor( - @Optional() private templateRef: TemplateRef, - private vcRef: ViewContainerRef, - private permissionService: PermissionService, - private cdRef: ChangeDetectorRef, - @Inject(QUEUE_MANAGER) public queue: QueueManager, - ) {} - private check() { if (this.subscription) { this.subscription.unsubscribe(); diff --git a/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts index 9a1bedcd71..7e948cc20f 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts @@ -1,13 +1,14 @@ -import { - Directive, - Injector, - Input, - OnChanges, - OnInit, - SimpleChanges, - TemplateRef, - Type, - ViewContainerRef, +import { + Directive, + Injector, + Input, + OnChanges, + OnInit, + SimpleChanges, + TemplateRef, + Type, + ViewContainerRef, + inject } from '@angular/core'; import compare from 'just-compare'; import { Subscription } from 'rxjs'; @@ -22,6 +23,12 @@ import { SubscriptionService } from '../services/subscription.service'; providers: [SubscriptionService], }) export class ReplaceableTemplateDirective implements OnInit, OnChanges { + private injector = inject(Injector); + private templateRef = inject>(TemplateRef); + private vcRef = inject(ViewContainerRef); + private replaceableComponents = inject(ReplaceableComponentsService); + private subscription = inject(SubscriptionService); + @Input('abpReplaceableTemplate') data!: ReplaceableComponents.ReplaceableTemplateDirectiveInput; @@ -40,13 +47,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges { initialized = false; - constructor( - private injector: Injector, - private templateRef: TemplateRef, - private vcRef: ViewContainerRef, - private replaceableComponents: ReplaceableComponentsService, - private subscription: SubscriptionService, - ) { + constructor() { this.context = { initTemplate: (ref: any) => { this.resetDefaultComponent(); diff --git a/npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts index ddc92cb56b..a1af9bf07e 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts @@ -1,4 +1,4 @@ -import { Directive, ElementRef, EventEmitter, OnInit, Output } from '@angular/core'; +import { Directive, ElementRef, EventEmitter, OnInit, Output, inject } from '@angular/core'; import { fromEvent } from 'rxjs'; import { SubscriptionService } from '../services/subscription.service'; @@ -7,12 +7,10 @@ import { SubscriptionService } from '../services/subscription.service'; providers: [SubscriptionService], }) export class StopPropagationDirective implements OnInit { - @Output('click.stop') readonly stopPropEvent = new EventEmitter(); + private el = inject(ElementRef); + private subscription = inject(SubscriptionService); - constructor( - private el: ElementRef, - private subscription: SubscriptionService, - ) {} + @Output('click.stop') readonly stopPropEvent = new EventEmitter(); ngOnInit(): void { this.subscription.addOne(fromEvent(this.el.nativeElement, 'click'), event => { diff --git a/npm/ng-packs/packages/core/src/lib/handlers/routes.handler.ts b/npm/ng-packs/packages/core/src/lib/handlers/routes.handler.ts index 76dc66b3ae..d8880b4fbf 100644 --- a/npm/ng-packs/packages/core/src/lib/handlers/routes.handler.ts +++ b/npm/ng-packs/packages/core/src/lib/handlers/routes.handler.ts @@ -1,4 +1,4 @@ -import { Injectable, Optional } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { Route, Router } from '@angular/router'; import { ABP } from '../models'; import { RoutesService } from '../services/routes.service'; @@ -7,10 +7,10 @@ import { RoutesService } from '../services/routes.service'; providedIn: 'root', }) export class RoutesHandler { - constructor( - private routes: RoutesService, - @Optional() private router: Router, - ) { + private routes = inject(RoutesService); + private router = inject(Router, { optional: true })!; + + constructor() { this.addRoutes(); } diff --git a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts b/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts index 9321521159..04be80638e 100644 --- a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts +++ b/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts @@ -1,5 +1,5 @@ import { HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { finalize } from 'rxjs/operators'; import { HttpWaitService } from '../services'; @@ -7,7 +7,8 @@ import { HttpWaitService } from '../services'; providedIn: 'root', }) export class ApiInterceptor implements IApiInterceptor { - constructor(private httpWaitService: HttpWaitService) {} + private httpWaitService = inject(HttpWaitService); + getAdditionalHeaders(existingHeaders?: HttpHeaders) { return existingHeaders || new HttpHeaders(); diff --git a/npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts index 2dbac68eb7..bbb2a71752 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts @@ -1,4 +1,4 @@ -import { Injectable, Pipe, PipeTransform } from '@angular/core'; +import { Injectable, Pipe, PipeTransform, inject } from '@angular/core'; import { LocalizationWithDefault } from '../models/localization'; import { LocalizationService } from '../services/localization.service'; @@ -7,7 +7,8 @@ import { LocalizationService } from '../services/localization.service'; name: 'abpLocalization', }) export class LocalizationPipe implements PipeTransform { - constructor(private localization: LocalizationService) {} + private localization = inject(LocalizationService); + transform( value: string | LocalizationWithDefault = '', diff --git a/npm/ng-packs/packages/core/src/lib/pipes/short-date-time.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/short-date-time.pipe.ts index b72ca45dde..8ed6dc55b4 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/short-date-time.pipe.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/short-date-time.pipe.ts @@ -1,5 +1,5 @@ import { DatePipe, DATE_PIPE_DEFAULT_TIMEZONE } from '@angular/common'; -import { Inject, LOCALE_ID, Optional, Pipe, PipeTransform } from '@angular/core'; +import { LOCALE_ID, Pipe, PipeTransform, inject } from '@angular/core'; import { ConfigStateService } from '../services'; import { getShortDateShortTimeFormat } from '../utils/date-utils'; @@ -8,11 +8,12 @@ import { getShortDateShortTimeFormat } from '../utils/date-utils'; pure: true, }) export class ShortDateTimePipe extends DatePipe implements PipeTransform { - constructor( - private configStateService: ConfigStateService, - @Inject(LOCALE_ID) locale: string, - @Inject(DATE_PIPE_DEFAULT_TIMEZONE) @Optional() defaultTimezone?: string | null, - ) { + private configStateService = inject(ConfigStateService); + + constructor() { + const locale = inject(LOCALE_ID); + const defaultTimezone = inject(DATE_PIPE_DEFAULT_TIMEZONE, { optional: true }); + super(locale, defaultTimezone); } diff --git a/npm/ng-packs/packages/core/src/lib/pipes/short-date.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/short-date.pipe.ts index 26a7e1552f..9968009e49 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/short-date.pipe.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/short-date.pipe.ts @@ -1,5 +1,5 @@ import { DatePipe, DATE_PIPE_DEFAULT_TIMEZONE } from '@angular/common'; -import { Inject, LOCALE_ID, Optional, Pipe, PipeTransform } from '@angular/core'; +import { LOCALE_ID, Pipe, PipeTransform, inject } from '@angular/core'; import { ConfigStateService } from '../services'; import { getShortDateFormat } from '../utils/date-utils'; @@ -8,11 +8,12 @@ import { getShortDateFormat } from '../utils/date-utils'; pure: true, }) export class ShortDatePipe extends DatePipe implements PipeTransform { - constructor( - private configStateService: ConfigStateService, - @Inject(LOCALE_ID) locale: string, - @Inject(DATE_PIPE_DEFAULT_TIMEZONE) @Optional() defaultTimezone?: string | null, - ) { + private configStateService = inject(ConfigStateService); + + constructor() { + const locale = inject(LOCALE_ID); + const defaultTimezone = inject(DATE_PIPE_DEFAULT_TIMEZONE, { optional: true }); + super(locale, defaultTimezone); } diff --git a/npm/ng-packs/packages/core/src/lib/pipes/short-time.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/short-time.pipe.ts index 54e70802f8..fac722af5e 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/short-time.pipe.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/short-time.pipe.ts @@ -1,5 +1,5 @@ import { DatePipe, DATE_PIPE_DEFAULT_TIMEZONE } from '@angular/common'; -import { Inject, LOCALE_ID, Optional, Pipe, PipeTransform } from '@angular/core'; +import { LOCALE_ID, Pipe, PipeTransform, inject } from '@angular/core'; import { ConfigStateService } from '../services'; import { getShortTimeFormat } from '../utils/date-utils'; @@ -8,11 +8,12 @@ import { getShortTimeFormat } from '../utils/date-utils'; pure: true, }) export class ShortTimePipe extends DatePipe implements PipeTransform { - constructor( - private configStateService: ConfigStateService, - @Inject(LOCALE_ID) locale: string, - @Inject(DATE_PIPE_DEFAULT_TIMEZONE) @Optional() defaultTimezone?: string | null, - ) { + private configStateService = inject(ConfigStateService); + + constructor() { + const locale = inject(LOCALE_ID); + const defaultTimezone = inject(DATE_PIPE_DEFAULT_TIMEZONE, { optional: true }); + super(locale, defaultTimezone); } diff --git a/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts b/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts index 5a1ac4df29..77663a1262 100644 --- a/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts +++ b/npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts @@ -1,4 +1,4 @@ -import { InjectionToken, Injector, Pipe, PipeTransform } from '@angular/core'; +import { InjectionToken, Injector, Pipe, PipeTransform, inject } from '@angular/core'; export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken( 'INJECTOR_PIPE_DATA_TOKEN', @@ -8,7 +8,8 @@ export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken( name: 'toInjector', }) export class ToInjectorPipe implements PipeTransform { - constructor(private injector: Injector) {} + private injector = inject(Injector); + transform( value: any, token: InjectionToken = INJECTOR_PIPE_DATA_TOKEN, diff --git a/npm/ng-packs/packages/core/src/lib/providers/locale.provider.ts b/npm/ng-packs/packages/core/src/lib/providers/locale.provider.ts index ca90c4bc33..9d34802da1 100644 --- a/npm/ng-packs/packages/core/src/lib/providers/locale.provider.ts +++ b/npm/ng-packs/packages/core/src/lib/providers/locale.provider.ts @@ -1,10 +1,12 @@ -import { LOCALE_ID, Provider } from '@angular/core'; +import { LOCALE_ID, Provider, inject } from '@angular/core'; import { differentLocales } from '../constants/different-locales'; import { LocalizationService } from '../services/localization.service'; import { checkHasProp } from '../utils/common-utils'; export class LocaleId extends String { - constructor(private localizationService: LocalizationService) { + private localizationService = inject(LocalizationService); + + constructor() { super(); } @@ -24,5 +26,4 @@ export class LocaleId extends String { export const LocaleProvider: Provider = { provide: LOCALE_ID, useClass: LocaleId, - deps: [LocalizationService], -}; +}; \ No newline at end of file diff --git a/npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts b/npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts index 039ddc707e..d778e0a279 100644 --- a/npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts +++ b/npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts @@ -1,12 +1,14 @@ import { RestService } from '../../../../services'; import { Rest } from '../../../../models'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import type { FindTenantResultDto } from '../../../volo/abp/asp-net-core/mvc/multi-tenancy/models'; @Injectable({ providedIn: 'root', }) -export class AbpTenantService { +export class AbpTenantService { + private restService = inject(RestService); + apiName = 'abp'; @@ -24,6 +26,4 @@ export class AbpTenantService { url: `/api/abp/multi-tenancy/tenants/by-name/${name}`, }, { apiName: this.apiName,...config }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts index a331106214..770faca476 100644 --- a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts +++ b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts @@ -1,12 +1,14 @@ import { RestService } from '../../../../../../services'; import { Rest } from '../../../../../../models'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import type { ApplicationApiDescriptionModel, ApplicationApiDescriptionModelRequestDto } from '../../../http/modeling/models'; @Injectable({ providedIn: 'root', }) -export class AbpApiDefinitionService { +export class AbpApiDefinitionService { + private restService = inject(RestService); + apiName = 'abp'; @@ -17,6 +19,4 @@ export class AbpApiDefinitionService { params: { includeTypes: model.includeTypes }, }, { apiName: this.apiName,...config }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts index 3c04af51fc..9dc35fa7b6 100644 --- a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts +++ b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts @@ -1,12 +1,14 @@ import type { ApplicationConfigurationDto, ApplicationConfigurationRequestOptions } from './models'; import { RestService } from '../../../../../../services'; import { Rest } from '../../../../../../models'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) -export class AbpApplicationConfigurationService { +export class AbpApplicationConfigurationService { + private restService = inject(RestService); + apiName = 'abp'; @@ -17,6 +19,4 @@ export class AbpApplicationConfigurationService { params: { includeLocalizationResources: options.includeLocalizationResources }, }, { apiName: this.apiName, ...config }); - - constructor(private restService: RestService) { } } diff --git a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts index 3b9fd80584..aa3f495b53 100644 --- a/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts +++ b/npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts @@ -1,12 +1,14 @@ import type { ApplicationLocalizationDto, ApplicationLocalizationRequestDto } from './models'; import { RestService } from '../../../../../../services'; import { Rest } from '../../../../../../models'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) -export class AbpApplicationLocalizationService { +export class AbpApplicationLocalizationService { + private restService = inject(RestService); + apiName = 'abp'; @@ -17,6 +19,4 @@ export class AbpApplicationLocalizationService { params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics }, }, { apiName: this.apiName,...config }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts index 475f6d76f3..1243e8b2ba 100644 --- a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable, Optional } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { map, switchMap, take, tap } from 'rxjs/operators'; import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; @@ -15,6 +15,10 @@ import { InternalStore } from '../utils/internal-store-utils'; providedIn: 'root', }) export class ConfigStateService { + private abpConfigService = inject(AbpApplicationConfigurationService); + private abpApplicationLocalizationService = inject(AbpApplicationLocalizationService); + private readonly includeLocalizationResources = inject(INCUDE_LOCALIZATION_RESOURCES_TOKEN, { optional: true }); + private updateSubject = new Subject(); private readonly store = new InternalStore({} as ApplicationConfigurationDto); @@ -27,13 +31,7 @@ export class ConfigStateService { get createOnUpdateStream() { return this.store.sliceUpdate; } - constructor( - private abpConfigService: AbpApplicationConfigurationService, - private abpApplicationLocalizationService: AbpApplicationLocalizationService, - @Optional() - @Inject(INCUDE_LOCALIZATION_RESOURCES_TOKEN) - private readonly includeLocalizationResources: boolean | null, - ) { + constructor() { this.initUpdateStream(); } diff --git a/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts b/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts index dfcdea330a..d9aac2bd48 100644 --- a/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts @@ -1,9 +1,10 @@ -import { Injectable, Injector, TemplateRef, Type } from '@angular/core'; +import { Injectable, Injector, TemplateRef, Type, inject } from '@angular/core'; import { ProjectionStrategy } from '../strategies/projection.strategy'; @Injectable({ providedIn: 'root' }) export class ContentProjectionService { - constructor(private injector: Injector) {} + private injector = inject(Injector); + projectContent | TemplateRef>( projectionStrategy: ProjectionStrategy, diff --git a/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts b/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts index d80599fc25..d8073d8760 100644 --- a/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable, Injector, inject } from '@angular/core'; import { HttpRequest } from '@angular/common/http'; import { InternalStore } from '../utils/internal-store-utils'; import { getPathName } from '../utils/http-utils'; @@ -26,7 +26,9 @@ export class HttpWaitService { private delay: number; private destroy$ = new Subject(); - constructor(injector: Injector) { + constructor() { + const injector = inject(Injector); + this.delay = injector.get(LOADER_DELAY, 500); } diff --git a/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts b/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts index f50102e15a..8358570db9 100644 --- a/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { concat, Observable, of, pipe, throwError } from 'rxjs'; import { delay, retryWhen, shareReplay, take, tap } from 'rxjs/operators'; import { LoadingStrategy } from '../strategies'; @@ -8,9 +8,9 @@ import { ResourceWaitService } from './resource-wait.service'; providedIn: 'root', }) export class LazyLoadService { - readonly loaded = new Map(); + private resourceWaitService = inject(ResourceWaitService); - constructor(private resourceWaitService: ResourceWaitService) {} + readonly loaded = new Map(); load(strategy: LoadingStrategy, retryTimes?: number, retryDelay?: number): Observable { if (this.loaded.has(strategy.path)) return of(new CustomEvent('load')); diff --git a/npm/ng-packs/packages/core/src/lib/services/list.service.ts b/npm/ng-packs/packages/core/src/lib/services/list.service.ts index 204833a66d..3cfc0ecac9 100644 --- a/npm/ng-packs/packages/core/src/lib/services/list.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/list.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector, OnDestroy } from '@angular/core'; +import { Injectable, Injector, OnDestroy, inject } from '@angular/core'; import { EMPTY, BehaviorSubject, @@ -119,7 +119,9 @@ export class ListService implements this.next(); }; - constructor(injector: Injector) { + constructor() { + const injector = inject(Injector); + const delay = injector.get(LIST_QUERY_DEBOUNCE_TIME, 300); this.delay = delay ? debounceTime(delay) : tap(); this.get(); diff --git a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts index 7b474e7881..dd6def0c24 100644 --- a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts @@ -1,5 +1,5 @@ import { registerLocaleData } from '@angular/common'; -import { Injectable, Injector, isDevMode, Optional, SkipSelf } from '@angular/core'; +import { Injectable, Injector, isDevMode, inject } from '@angular/core'; import { BehaviorSubject, combineLatest, from, Observable, Subject } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; import { ABP } from '../models/common'; @@ -17,6 +17,10 @@ import { SessionStateService } from './session-state.service'; @Injectable({ providedIn: 'root' }) export class LocalizationService { + private sessionState = inject(SessionStateService); + private injector = inject(Injector); + private configState = inject(ConfigStateService); + private latestLang = this.sessionState.getLanguage(); private _languageChange$ = new Subject(); @@ -44,14 +48,9 @@ export class LocalizationService { return this._languageChange$.asObservable(); } - constructor( - private sessionState: SessionStateService, - private injector: Injector, - @Optional() - @SkipSelf() - otherInstance: LocalizationService, - private configState: ConfigStateService, - ) { + constructor() { + const otherInstance = inject(LocalizationService, { optional: true, skipSelf: true })!; + if (otherInstance) throw new Error('LocalizationService should have only one instance.'); this.listenToSetLanguage(); diff --git a/npm/ng-packs/packages/core/src/lib/services/multi-tenancy.service.ts b/npm/ng-packs/packages/core/src/lib/services/multi-tenancy.service.ts index 8fbde5cc8e..a88cba1c3d 100644 --- a/npm/ng-packs/packages/core/src/lib/services/multi-tenancy.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/multi-tenancy.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { map, switchMap } from 'rxjs/operators'; import { AbpTenantService } from '../proxy/pages/abp/multi-tenancy'; import { @@ -7,11 +7,15 @@ import { } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models'; import { TENANT_KEY } from '../tokens/tenant-key.token'; import { ConfigStateService } from './config-state.service'; -import { RestService } from './rest.service'; import { SessionStateService } from './session-state.service'; @Injectable({ providedIn: 'root' }) export class MultiTenancyService { + private sessionState = inject(SessionStateService); + private tenantService = inject(AbpTenantService); + private configStateService = inject(ConfigStateService); + tenantKey = inject(TENANT_KEY); + domainTenant: CurrentTenantDto | null = null; isTenantBoxVisible = true; @@ -23,14 +27,6 @@ export class MultiTenancyService { return this.configStateService.refreshAppState().pipe(map(_ => tenant)); }; - constructor( - private restService: RestService, - private sessionState: SessionStateService, - private tenantService: AbpTenantService, - private configStateService: ConfigStateService, - @Inject(TENANT_KEY) public tenantKey: string, - ) { } - setTenantByName(tenantName: string) { return this.tenantService .findTenantByName(tenantName) diff --git a/npm/ng-packs/packages/core/src/lib/services/permission.service.ts b/npm/ng-packs/packages/core/src/lib/services/permission.service.ts index 70724ac814..b45b2a36f5 100644 --- a/npm/ng-packs/packages/core/src/lib/services/permission.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/permission.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { map } from 'rxjs/operators'; import { ABP } from '../models/common'; import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; @@ -6,7 +6,8 @@ import { ConfigStateService } from './config-state.service'; @Injectable({ providedIn: 'root' }) export class PermissionService { - constructor(protected configState: ConfigStateService) {} + protected configState = inject(ConfigStateService); + getGrantedPolicy$(key: string) { return this.getStream().pipe( diff --git a/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts b/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts index 1f02daa389..c156a237aa 100644 --- a/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts @@ -1,4 +1,4 @@ -import { Injectable, NgZone } from '@angular/core'; +import { Injectable, NgZone, inject } from '@angular/core'; import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -8,6 +8,9 @@ import { reloadRoute } from '../utils/route-utils'; @Injectable({ providedIn: 'root' }) export class ReplaceableComponentsService { + private ngZone = inject(NgZone); + private router = inject(Router); + private readonly store: InternalStore; get replaceableComponents$(): Observable { @@ -22,7 +25,7 @@ export class ReplaceableComponentsService { return this.store.sliceUpdate(state => state); } - constructor(private ngZone: NgZone, private router: Router) { + constructor() { this.store = new InternalStore([] as ReplaceableComponents.ReplaceableComponent[]); } diff --git a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts index 83f91777ca..a331b6c742 100644 --- a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts @@ -1,5 +1,5 @@ import { HttpClient, HttpParameterCodec, HttpParams, HttpRequest } from '@angular/common/http'; -import { Inject, Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { ExternalHttpClient } from '../clients/http.client'; @@ -14,13 +14,12 @@ import { HttpErrorReporterService } from './http-error-reporter.service'; providedIn: 'root', }) export class RestService { - constructor( - @Inject(CORE_OPTIONS) protected options: ABP.Root, - protected http: HttpClient, - protected externalHttp: ExternalHttpClient, - protected environment: EnvironmentService, - protected httpErrorReporter: HttpErrorReporterService, - ) { } + protected options = inject(CORE_OPTIONS); + protected http = inject(HttpClient); + protected externalHttp = inject(ExternalHttpClient); + protected environment = inject(EnvironmentService); + protected httpErrorReporter = inject(HttpErrorReporterService); + protected getApiFromStore(apiName: string | undefined): string { return this.environment.getApiUrl(apiName); diff --git a/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts b/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts index 96e66a00e3..f68f6d065a 100644 --- a/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable, Injector, inject } from '@angular/core'; import { NavigationStart } from '@angular/router'; import { of, Subject, timer } from 'rxjs'; import { map, mapTo, switchMap, takeUntil, tap } from 'rxjs/operators'; @@ -14,10 +14,14 @@ export interface RouterWaitState { providedIn: 'root', }) export class RouterWaitService { + private routerEvents = inject(RouterEvents); + private store = new InternalStore({ loading: false }); private destroy$ = new Subject(); private delay: number; - constructor(private routerEvents: RouterEvents, injector: Injector) { + constructor() { + const injector = inject(Injector); + this.delay = injector.get(LOADER_DELAY, 500); this.updateLoadingStatusOnNavigationEvents(); } diff --git a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts index 393c724423..175bf76446 100644 --- a/npm/ng-packs/packages/core/src/lib/services/routes.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/routes.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector, OnDestroy } from '@angular/core'; +import { Injectable, Injector, OnDestroy, inject } from '@angular/core'; import { BehaviorSubject, Observable, Subscription, map } from 'rxjs'; import { ABP } from '../models/common'; import { OTHERS_GROUP } from '../tokens'; @@ -201,6 +201,8 @@ export abstract class AbstractNavTreeService extends AbstractTreeService implements OnDestroy { + protected injector = inject(Injector); + private subscription: Subscription; private permissionService: PermissionService; private compareFunc; @@ -211,8 +213,10 @@ export abstract class AbstractNavTreeService return this.compareFunc(a, b); }; - constructor(protected injector: Injector) { + constructor() { super(); + const injector = this.injector; + const configState = this.injector.get(ConfigStateService); this.subscription = configState .createOnUpdateStream(state => state) diff --git a/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts index d6f423983c..7e519dc742 100644 --- a/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts @@ -12,6 +12,9 @@ import { AbpLocalStorageService } from './local-storage.service'; providedIn: 'root', }) export class SessionStateService { + private configState = inject(ConfigStateService); + private localStorageService = inject(AbpLocalStorageService); + private readonly store = new InternalStore({} as Session.State); protected readonly document = inject(DOCUMENT); @@ -19,10 +22,7 @@ export class SessionStateService { this.localStorageService.setItem('abpSession', JSON.stringify(this.store.state)); }; - constructor( - private configState: ConfigStateService, - private localStorageService: AbpLocalStorageService, - ) { + constructor() { this.init(); this.setInitialLanguage(); } diff --git a/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts index 411a9e8041..aac6c41fcd 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts @@ -1,201 +1,201 @@ -import { HttpClient } from '@angular/common/http'; -import { Component, NgModule } from '@angular/core'; -import { ActivatedRoute, RouterModule } from '@angular/router'; -import { createRoutingFactory, SpectatorRouting } from '@ngneat/spectator/jest'; -import { DynamicLayoutComponent, RouterOutletComponent } from '../components'; -import { eLayoutType } from '../enums/common'; -import { ABP } from '../models'; -import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; -import { ReplaceableComponentsService, RoutesService } from '../services'; -import { mockRoutesService } from './routes.service.spec'; - -@Component({ - selector: 'abp-layout-application', - template: '', -}) -class DummyApplicationLayoutComponent {} - -@Component({ - selector: 'abp-layout-account', - template: '', -}) -class DummyAccountLayoutComponent {} - -@Component({ - selector: 'abp-layout-empty', - template: '', -}) -class DummyEmptyLayoutComponent {} - -const LAYOUTS = [ - DummyApplicationLayoutComponent, - DummyAccountLayoutComponent, - DummyEmptyLayoutComponent, -]; - -@NgModule({ - imports: [RouterModule], - declarations: [...LAYOUTS], -}) -class DummyLayoutModule {} - -@Component({ - selector: 'abp-dummy', - template: '{{route.snapshot.data?.name}} works!', -}) -class DummyComponent { - constructor(public route: ActivatedRoute) {} -} - -const routes: ABP.Route[] = [ - { - path: '', - name: 'Root', - }, - { - path: '/parentWithLayout', - name: 'ParentWithLayout', - parentName: 'Root', - layout: eLayoutType.application, - }, - { - path: '/parentWithLayout/childWithoutLayout', - name: 'ChildWithoutLayout', - parentName: 'ParentWithLayout', - }, - { - path: '/parentWithLayout/childWithLayout', - name: 'ChildWithLayout', - parentName: 'ParentWithLayout', - layout: eLayoutType.account, - }, - { - path: '/withData', - name: 'WithData', - layout: eLayoutType.application, - }, -]; - -describe('DynamicLayoutComponent', () => { - const createComponent = createRoutingFactory({ - component: RouterOutletComponent, - stubsEnabled: false, - declarations: [DummyComponent, DynamicLayoutComponent], - mocks: [AbpApplicationConfigurationService, HttpClient], - providers: [ - { - provide: RoutesService, - useFactory: () => mockRoutesService(), - }, - ReplaceableComponentsService, - ], - imports: [RouterModule, DummyLayoutModule], - routes: [ - { path: '', component: RouterOutletComponent }, - { - path: 'parentWithLayout', - component: DynamicLayoutComponent, - children: [ - { - path: 'childWithoutLayout', - component: DummyComponent, - data: { name: 'childWithoutLayout' }, - }, - { - path: 'childWithLayout', - component: DummyComponent, - data: { name: 'childWithLayout' }, - }, - ], - }, - { - path: 'withData', - component: DynamicLayoutComponent, - children: [ - { - path: '', - component: DummyComponent, - data: { name: 'withData' }, - }, - ], - data: { layout: eLayoutType.empty }, - }, - { - path: 'withoutLayout', - component: DynamicLayoutComponent, - children: [ - { - path: '', - component: DummyComponent, - data: { name: 'withoutLayout' }, - }, - ], - data: { layout: null }, - }, - ], - }); - - let spectator: SpectatorRouting; - let replaceableComponents: ReplaceableComponentsService; - - beforeEach(async () => { - spectator = createComponent(); - replaceableComponents = spectator.inject(ReplaceableComponentsService); - const routesService = spectator.inject(RoutesService); - routesService.add(routes); - - replaceableComponents.add({ - key: 'Theme.ApplicationLayoutComponent', - component: DummyApplicationLayoutComponent, - }); - replaceableComponents.add({ - key: 'Theme.AccountLayoutComponent', - component: DummyAccountLayoutComponent, - }); - replaceableComponents.add({ - key: 'Theme.EmptyLayoutComponent', - component: DummyEmptyLayoutComponent, - }); - }); - - it('should handle application layout from parent abp route and display it', async () => { - spectator.router.navigateByUrl('/parentWithLayout/childWithoutLayout'); - await spectator.fixture.whenStable(); - spectator.detectComponentChanges(); - expect(spectator.query('abp-dynamic-layout')).toBeTruthy(); - expect(spectator.query('abp-layout-application')).toBeTruthy(); - }); - - it('should handle account layout from own property and display it', async () => { - spectator.router.navigateByUrl('/parentWithLayout/childWithLayout'); - await spectator.fixture.whenStable(); - spectator.detectComponentChanges(); - expect(spectator.query('abp-layout-account')).toBeTruthy(); - }); - - it('should handle empty layout from route data and display it', async () => { - spectator.router.navigateByUrl('/withData'); - await spectator.fixture.whenStable(); - spectator.detectComponentChanges(); - expect(spectator.query('abp-layout-empty')).toBeTruthy(); - }); - - it('should display empty layout when layout is null', async () => { - spectator.router.navigateByUrl('/withoutLayout'); - await spectator.fixture.whenStable(); - spectator.detectComponentChanges(); - expect(spectator.query('abp-layout-empty')).toBeTruthy(); - }); - - it('should not display any layout when layouts are empty', async () => { - const spy = jest.spyOn(replaceableComponents, 'get'); - spy.mockReturnValue(null); - spectator.detectChanges(); - - spectator.router.navigateByUrl('/withoutLayout'); - await spectator.fixture.whenStable(); - spectator.detectComponentChanges(); - - expect(spectator.query('abp-layout-empty')).toBeFalsy(); - }); -}); +import { HttpClient } from '@angular/common/http'; +import { Component, NgModule, inject as inject_1 } from '@angular/core'; +import { ActivatedRoute, RouterModule } from '@angular/router'; +import { createRoutingFactory, SpectatorRouting } from '@ngneat/spectator/jest'; +import { DynamicLayoutComponent, RouterOutletComponent } from '../components'; +import { eLayoutType } from '../enums/common'; +import { ABP } from '../models'; +import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; +import { ReplaceableComponentsService, RoutesService } from '../services'; +import { mockRoutesService } from './routes.service.spec'; + +@Component({ + selector: 'abp-layout-application', + template: '', +}) +class DummyApplicationLayoutComponent {} + +@Component({ + selector: 'abp-layout-account', + template: '', +}) +class DummyAccountLayoutComponent {} + +@Component({ + selector: 'abp-layout-empty', + template: '', +}) +class DummyEmptyLayoutComponent {} + +const LAYOUTS = [ + DummyApplicationLayoutComponent, + DummyAccountLayoutComponent, + DummyEmptyLayoutComponent, +]; + +@NgModule({ + imports: [RouterModule], + declarations: [...LAYOUTS], +}) +class DummyLayoutModule {} + +@Component({ + selector: 'abp-dummy', + template: '{{route.snapshot.data?.name}} works!', +}) +class DummyComponent { route = inject_1(ActivatedRoute); + +} + +const routes: ABP.Route[] = [ + { + path: '', + name: 'Root', + }, + { + path: '/parentWithLayout', + name: 'ParentWithLayout', + parentName: 'Root', + layout: eLayoutType.application, + }, + { + path: '/parentWithLayout/childWithoutLayout', + name: 'ChildWithoutLayout', + parentName: 'ParentWithLayout', + }, + { + path: '/parentWithLayout/childWithLayout', + name: 'ChildWithLayout', + parentName: 'ParentWithLayout', + layout: eLayoutType.account, + }, + { + path: '/withData', + name: 'WithData', + layout: eLayoutType.application, + }, +]; + +describe('DynamicLayoutComponent', () => { + const createComponent = createRoutingFactory({ + component: RouterOutletComponent, + stubsEnabled: false, + declarations: [DummyComponent, DynamicLayoutComponent], + mocks: [AbpApplicationConfigurationService, HttpClient], + providers: [ + { + provide: RoutesService, + useFactory: () => mockRoutesService(), + }, + ReplaceableComponentsService, + ], + imports: [RouterModule, DummyLayoutModule], + routes: [ + { path: '', component: RouterOutletComponent }, + { + path: 'parentWithLayout', + component: DynamicLayoutComponent, + children: [ + { + path: 'childWithoutLayout', + component: DummyComponent, + data: { name: 'childWithoutLayout' }, + }, + { + path: 'childWithLayout', + component: DummyComponent, + data: { name: 'childWithLayout' }, + }, + ], + }, + { + path: 'withData', + component: DynamicLayoutComponent, + children: [ + { + path: '', + component: DummyComponent, + data: { name: 'withData' }, + }, + ], + data: { layout: eLayoutType.empty }, + }, + { + path: 'withoutLayout', + component: DynamicLayoutComponent, + children: [ + { + path: '', + component: DummyComponent, + data: { name: 'withoutLayout' }, + }, + ], + data: { layout: null }, + }, + ], + }); + + let spectator: SpectatorRouting; + let replaceableComponents: ReplaceableComponentsService; + + beforeEach(async () => { + spectator = createComponent(); + replaceableComponents = spectator.inject(ReplaceableComponentsService); + const routesService = spectator.inject(RoutesService); + routesService.add(routes); + + replaceableComponents.add({ + key: 'Theme.ApplicationLayoutComponent', + component: DummyApplicationLayoutComponent, + }); + replaceableComponents.add({ + key: 'Theme.AccountLayoutComponent', + component: DummyAccountLayoutComponent, + }); + replaceableComponents.add({ + key: 'Theme.EmptyLayoutComponent', + component: DummyEmptyLayoutComponent, + }); + }); + + it('should handle application layout from parent abp route and display it', async () => { + spectator.router.navigateByUrl('/parentWithLayout/childWithoutLayout'); + await spectator.fixture.whenStable(); + spectator.detectComponentChanges(); + expect(spectator.query('abp-dynamic-layout')).toBeTruthy(); + expect(spectator.query('abp-layout-application')).toBeTruthy(); + }); + + it('should handle account layout from own property and display it', async () => { + spectator.router.navigateByUrl('/parentWithLayout/childWithLayout'); + await spectator.fixture.whenStable(); + spectator.detectComponentChanges(); + expect(spectator.query('abp-layout-account')).toBeTruthy(); + }); + + it('should handle empty layout from route data and display it', async () => { + spectator.router.navigateByUrl('/withData'); + await spectator.fixture.whenStable(); + spectator.detectComponentChanges(); + expect(spectator.query('abp-layout-empty')).toBeTruthy(); + }); + + it('should display empty layout when layout is null', async () => { + spectator.router.navigateByUrl('/withoutLayout'); + await spectator.fixture.whenStable(); + spectator.detectComponentChanges(); + expect(spectator.query('abp-layout-empty')).toBeTruthy(); + }); + + it('should not display any layout when layouts are empty', async () => { + const spy = jest.spyOn(replaceableComponents, 'get'); + spy.mockReturnValue(null); + spectator.detectChanges(); + + spectator.router.navigateByUrl('/withoutLayout'); + await spectator.fixture.whenStable(); + spectator.detectComponentChanges(); + + expect(spectator.query('abp-layout-empty')).toBeFalsy(); + }); +}); diff --git a/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts index 10e59c86f6..94fdf8a527 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts @@ -1,178 +1,174 @@ -import { Component, EventEmitter, Inject, Input, Optional, Output } from '@angular/core'; -import { Router } from '@angular/router'; -import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; -import { BehaviorSubject } from 'rxjs'; -import { ReplaceableTemplateDirective } from '../directives/replaceable-template.directive'; -import { ReplaceableComponents } from '../models/replaceable-components'; -import { ReplaceableComponentsService } from '../services/replaceable-components.service'; - -@Component({ - selector: 'abp-default-component', - template: '

default

', - exportAs: 'abpDefaultComponent', -}) -class DefaultComponent { - @Input() - oneWay; - - @Input() - twoWay: boolean; - - @Output() - readonly twoWayChange = new EventEmitter(); - - @Output() - readonly someOutput = new EventEmitter(); - - setTwoWay(value) { - this.twoWay = value; - this.twoWayChange.emit(value); - } -} - -@Component({ - selector: 'abp-external-component', - template: '

external

', -}) -class ExternalComponent { - constructor( - @Optional() - @Inject('REPLACEABLE_DATA') - public data: ReplaceableComponents.ReplaceableTemplateData, - ) {} -} - -describe('ReplaceableTemplateDirective', () => { - let spectator: SpectatorDirective; - const get$Res = new BehaviorSubject(undefined); - - const createDirective = createDirectiveFactory({ - directive: ReplaceableTemplateDirective, - declarations: [DefaultComponent, ExternalComponent], - entryComponents: [ExternalComponent], - mocks: [Router], - providers: [{ provide: ReplaceableComponentsService, useValue: { get$: () => get$Res } }], - }); - - describe('without external component', () => { - const twoWayChange = jest.fn(a => a); - const someOutput = jest.fn(a => a); - - beforeEach(() => { - spectator = createDirective( - ` -
- -
- `, - { - hostProps: { - oneWay: { label: 'Test' }, - twoWay: false, - twoWayChange, - someOutput, - }, - }, - ); - - const component = spectator.query(DefaultComponent); - spectator.directive.context.initTemplate(component); - spectator.detectChanges(); - }); - - afterEach(() => twoWayChange.mockClear()); - - it('should display the default template when store response is undefined', () => { - expect(spectator.query('abp-default-component')).toBeTruthy(); - }); - - it('should be setted inputs and outputs', () => { - const component = spectator.query(DefaultComponent); - expect(component.oneWay).toEqual({ label: 'Test' }); - expect(component.twoWay).toEqual(false); - }); - - it('should change the component inputs', () => { - const component = spectator.query(DefaultComponent); - spectator.setHostInput({ oneWay: 'test' }); - component.setTwoWay(true); - component.someOutput.emit('someOutput emitted'); - expect(component.oneWay).toBe('test'); - expect(twoWayChange).toHaveBeenCalledWith(true); - expect(someOutput).toHaveBeenCalledWith('someOutput emitted'); - }); - }); - - describe('with external component', () => { - const twoWayChange = jest.fn(a => a); - const someOutput = jest.fn(a => a); - - beforeEach(() => { - spectator = createDirective( - ` -
- -
- `, - { hostProps: { oneWay: { label: 'Test' }, twoWay: false, twoWayChange, someOutput } }, - ); - - get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); - }); - - afterEach(() => twoWayChange.mockClear()); - - it('should display the external component', () => { - expect(spectator.query('p')).toHaveText('external'); - }); - - it('should be injected the data object', () => { - const externalComponent = spectator.query(ExternalComponent); - expect(externalComponent.data).toEqual({ - componentKey: 'TestModule.TestComponent', - inputs: { oneWay: { label: 'Test' }, twoWay: false }, - outputs: { someOutput, twoWayChange }, - }); - }); - - it('should be worked all data properties', () => { - const externalComponent = spectator.query(ExternalComponent); - spectator.setHostInput({ oneWay: 'test' }); - externalComponent.data.inputs.twoWay = true; - externalComponent.data.outputs.someOutput('someOutput emitted'); - expect(externalComponent.data.inputs.oneWay).toBe('test'); - expect(twoWayChange).toHaveBeenCalledWith(true); - expect(someOutput).toHaveBeenCalledWith('someOutput emitted'); - - spectator.setHostInput({ twoWay: 'twoWay test' }); - expect(externalComponent.data.inputs.twoWay).toBe('twoWay test'); - }); - - it('should be worked correctly the default component when the external component has been removed from store', () => { - expect(spectator.query('p')).toHaveText('external'); - const externalComponent = spectator.query(ExternalComponent); - spectator.setHostInput({ oneWay: 'test' }); - externalComponent.data.inputs.twoWay = true; - get$Res.next({ component: null, key: 'TestModule.TestComponent' }); - spectator.detectChanges(); - const component = spectator.query(DefaultComponent); - spectator.directive.context.initTemplate(component); - expect(spectator.query('abp-default-component')).toBeTruthy(); - - expect(component.oneWay).toEqual('test'); - expect(component.twoWay).toEqual(true); - }); - - it('should reset default component subscriptions', () => { - get$Res.next({ component: null, key: 'TestModule.TestComponent' }); - const component = spectator.query(DefaultComponent); - spectator.directive.context.initTemplate(component); - spectator.detectChanges(); - const unsubscribe = jest.fn(() => {}); - spectator.directive.defaultComponentSubscriptions.twoWayChange.unsubscribe = unsubscribe; - - get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); - expect(unsubscribe).toHaveBeenCalled(); - }); - }); -}); +import { Component, EventEmitter, Input, Output, inject } from '@angular/core'; +import { Router } from '@angular/router'; +import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; +import { BehaviorSubject } from 'rxjs'; +import { ReplaceableTemplateDirective } from '../directives/replaceable-template.directive'; +import { ReplaceableComponents } from '../models/replaceable-components'; +import { ReplaceableComponentsService } from '../services/replaceable-components.service'; + +@Component({ + selector: 'abp-default-component', + template: '

default

', + exportAs: 'abpDefaultComponent', +}) +class DefaultComponent { + @Input() + oneWay; + + @Input() + twoWay: boolean; + + @Output() + readonly twoWayChange = new EventEmitter(); + + @Output() + readonly someOutput = new EventEmitter(); + + setTwoWay(value) { + this.twoWay = value; + this.twoWayChange.emit(value); + } +} + +@Component({ + selector: 'abp-external-component', + template: '

external

', +}) +class ExternalComponent { data = inject>('REPLACEABLE_DATA' as any, { optional: true })!; + +} + +describe('ReplaceableTemplateDirective', () => { + let spectator: SpectatorDirective; + const get$Res = new BehaviorSubject(undefined); + + const createDirective = createDirectiveFactory({ + directive: ReplaceableTemplateDirective, + declarations: [DefaultComponent, ExternalComponent], + entryComponents: [ExternalComponent], + mocks: [Router], + providers: [{ provide: ReplaceableComponentsService, useValue: { get$: () => get$Res } }], + }); + + describe('without external component', () => { + const twoWayChange = jest.fn(a => a); + const someOutput = jest.fn(a => a); + + beforeEach(() => { + spectator = createDirective( + ` +
+ +
+ `, + { + hostProps: { + oneWay: { label: 'Test' }, + twoWay: false, + twoWayChange, + someOutput, + }, + }, + ); + + const component = spectator.query(DefaultComponent); + spectator.directive.context.initTemplate(component); + spectator.detectChanges(); + }); + + afterEach(() => twoWayChange.mockClear()); + + it('should display the default template when store response is undefined', () => { + expect(spectator.query('abp-default-component')).toBeTruthy(); + }); + + it('should be setted inputs and outputs', () => { + const component = spectator.query(DefaultComponent); + expect(component.oneWay).toEqual({ label: 'Test' }); + expect(component.twoWay).toEqual(false); + }); + + it('should change the component inputs', () => { + const component = spectator.query(DefaultComponent); + spectator.setHostInput({ oneWay: 'test' }); + component.setTwoWay(true); + component.someOutput.emit('someOutput emitted'); + expect(component.oneWay).toBe('test'); + expect(twoWayChange).toHaveBeenCalledWith(true); + expect(someOutput).toHaveBeenCalledWith('someOutput emitted'); + }); + }); + + describe('with external component', () => { + const twoWayChange = jest.fn(a => a); + const someOutput = jest.fn(a => a); + + beforeEach(() => { + spectator = createDirective( + ` +
+ +
+ `, + { hostProps: { oneWay: { label: 'Test' }, twoWay: false, twoWayChange, someOutput } }, + ); + + get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); + }); + + afterEach(() => twoWayChange.mockClear()); + + it('should display the external component', () => { + expect(spectator.query('p')).toHaveText('external'); + }); + + it('should be injected the data object', () => { + const externalComponent = spectator.query(ExternalComponent); + expect(externalComponent.data).toEqual({ + componentKey: 'TestModule.TestComponent', + inputs: { oneWay: { label: 'Test' }, twoWay: false }, + outputs: { someOutput, twoWayChange }, + }); + }); + + it('should be worked all data properties', () => { + const externalComponent = spectator.query(ExternalComponent); + spectator.setHostInput({ oneWay: 'test' }); + externalComponent.data.inputs.twoWay = true; + externalComponent.data.outputs.someOutput('someOutput emitted'); + expect(externalComponent.data.inputs.oneWay).toBe('test'); + expect(twoWayChange).toHaveBeenCalledWith(true); + expect(someOutput).toHaveBeenCalledWith('someOutput emitted'); + + spectator.setHostInput({ twoWay: 'twoWay test' }); + expect(externalComponent.data.inputs.twoWay).toBe('twoWay test'); + }); + + it('should be worked correctly the default component when the external component has been removed from store', () => { + expect(spectator.query('p')).toHaveText('external'); + const externalComponent = spectator.query(ExternalComponent); + spectator.setHostInput({ oneWay: 'test' }); + externalComponent.data.inputs.twoWay = true; + get$Res.next({ component: null, key: 'TestModule.TestComponent' }); + spectator.detectChanges(); + const component = spectator.query(DefaultComponent); + spectator.directive.context.initTemplate(component); + expect(spectator.query('abp-default-component')).toBeTruthy(); + + expect(component.oneWay).toEqual('test'); + expect(component.twoWay).toEqual(true); + }); + + it('should reset default component subscriptions', () => { + get$Res.next({ component: null, key: 'TestModule.TestComponent' }); + const component = spectator.query(DefaultComponent); + spectator.directive.context.initTemplate(component); + spectator.detectChanges(); + const unsubscribe = jest.fn(() => {}); + spectator.directive.defaultComponentSubscriptions.twoWayChange.unsubscribe = unsubscribe; + + get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); + expect(unsubscribe).toHaveBeenCalled(); + }); + }); +}); diff --git a/npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts b/npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts index b4d180b17a..e7f03cdf48 100644 --- a/npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts +++ b/npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts @@ -1,12 +1,17 @@ import { ConfigStateService, PermissionService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class MockPermissionService extends PermissionService { - constructor(protected configState: ConfigStateService) { - super(configState); + protected configState: ConfigStateService; + + constructor() { + const configState = inject(ConfigStateService); + super(); + this.configState = configState; + this.grantAllPolicies(); } diff --git a/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts b/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts index 7fd171c1d4..57d326ac4f 100644 --- a/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts +++ b/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts @@ -3,24 +3,33 @@ import { CORE_OPTIONS, EnvironmentService, ExternalHttpClient, - HttpErrorReporterService, RestService, } from '@abp/ng.core'; import { HttpClient } from '@angular/common/http'; -import { Inject, Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { Observable, throwError } from 'rxjs'; @Injectable({ providedIn: 'root', }) export class MockRestService extends RestService { - constructor( - @Inject(CORE_OPTIONS) protected options: ABP.Root, - protected http: HttpClient, - protected externalhttp: ExternalHttpClient, - protected environment: EnvironmentService, - ) { - super(options, http,externalhttp, environment, null as unknown as HttpErrorReporterService); + protected options: ABP.Root; + protected http: HttpClient; + protected externalhttp: ExternalHttpClient; + protected environment: EnvironmentService; + + constructor() { + const options = inject(CORE_OPTIONS); + const http = inject(HttpClient); + const externalhttp = inject(ExternalHttpClient); + const environment = inject(EnvironmentService); + + super(); + + this.options = options; + this.http = http; + this.externalhttp = externalhttp; + this.environment = environment; } handleError(err: any): Observable { diff --git a/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts b/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts index 189076428d..67616fd4d1 100644 --- a/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts +++ b/npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts @@ -1,11 +1,13 @@ import type { GetFeatureListResultDto, UpdateFeaturesDto } from './models'; import { RestService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class FeaturesService { + private restService = inject(RestService); + apiName = 'AbpFeatureManagement'; delete = (providerName: string, providerKey: string) => @@ -38,6 +40,4 @@ export class FeaturesService { }, { apiName: this.apiName }, ); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-role.service.ts b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-role.service.ts index 6e296c171b..c1aabf7091 100644 --- a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-role.service.ts +++ b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-role.service.ts @@ -1,12 +1,14 @@ import type { GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleDto, IdentityRoleUpdateDto } from './models'; import { RestService } from '@abp/ng.core'; import type { ListResultDto, PagedResultDto } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class IdentityRoleService { + private restService = inject(RestService); + apiName = 'AbpIdentity'; create = (input: IdentityRoleCreateDto) => @@ -53,6 +55,4 @@ export class IdentityRoleService { body: input, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user-lookup.service.ts b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user-lookup.service.ts index af4583aa28..cf8d01e81f 100644 --- a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user-lookup.service.ts +++ b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user-lookup.service.ts @@ -1,13 +1,15 @@ import type { UserLookupCountInputDto, UserLookupSearchInputDto } from './models'; import { RestService } from '@abp/ng.core'; import type { ListResultDto } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import type { UserData } from '../users/models'; @Injectable({ providedIn: 'root', }) export class IdentityUserLookupService { + private restService = inject(RestService); + apiName = 'AbpIdentity'; findById = (id: string) => @@ -39,6 +41,4 @@ export class IdentityUserLookupService { params: { filter: input.filter, sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount }, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts index c3b6f203f2..a538a07feb 100644 --- a/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts +++ b/npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts @@ -1,12 +1,14 @@ import type { GetIdentityUsersInput, IdentityRoleDto, IdentityUserCreateDto, IdentityUserDto, IdentityUserUpdateDto, IdentityUserUpdateRolesDto } from './models'; import { RestService } from '@abp/ng.core'; import type { ListResultDto, PagedResultDto } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class IdentityUserService { + private restService = inject(RestService); + apiName = 'AbpIdentity'; create = (input: IdentityUserCreateDto) => @@ -84,6 +86,4 @@ export class IdentityUserService { body: input, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts b/npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts index a2a9228b78..42ddb89c90 100644 --- a/npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts +++ b/npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { AuthConfig, OAuthService } from "angular-oauth2-oidc"; import compare from 'just-compare'; import { filter, map } from 'rxjs/operators'; @@ -8,11 +8,11 @@ import { ABP, EnvironmentService, CORE_OPTIONS } from '@abp/ng.core'; providedIn: 'root', }) export class OAuthConfigurationHandler { - constructor( - private oAuthService: OAuthService, - private environmentService: EnvironmentService, - @Inject(CORE_OPTIONS) private options: ABP.Root, - ) { + private oAuthService = inject(OAuthService); + private environmentService = inject(EnvironmentService); + private options = inject(CORE_OPTIONS); + + constructor() { this.listenToSetEnvironment(); } diff --git a/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts b/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts index e7ee208c47..e6921d5961 100644 --- a/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts +++ b/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts @@ -1,5 +1,5 @@ import { HttpHandler, HttpHeaders, HttpRequest } from '@angular/common/http'; -import { Inject, Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { finalize } from 'rxjs/operators'; import { @@ -14,12 +14,11 @@ import { providedIn: 'root', }) export class OAuthApiInterceptor implements IApiInterceptor { - constructor( - private oAuthService: OAuthService, - private sessionState: SessionStateService, - private httpWaitService: HttpWaitService, - @Inject(TENANT_KEY) private tenantKey: string, - ) {} + private oAuthService = inject(OAuthService); + private sessionState = inject(SessionStateService); + private httpWaitService = inject(HttpWaitService); + private tenantKey = inject(TENANT_KEY); + intercept(request: HttpRequest, next: HttpHandler) { this.httpWaitService.addRequest(request); diff --git a/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts index a490f92dd2..51c97a8101 100644 --- a/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts +++ b/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable, Injector, inject } from '@angular/core'; import { Params } from '@angular/router'; import { from, Observable, lastValueFrom, EMPTY } from 'rxjs'; import { filter, map, switchMap, take, tap } from 'rxjs/operators'; @@ -13,6 +13,8 @@ import { HttpHeaders } from '@angular/common/http'; providedIn: 'root', }) export class AbpOAuthService implements IAuthService { + protected injector = inject(Injector); + private strategy!: AuthFlowStrategy; private readonly oAuthService: OAuthService; @@ -28,7 +30,7 @@ export class AbpOAuthService implements IAuthService { return this.strategy.isInternalAuth; } - constructor(protected injector: Injector) { + constructor() { this.oAuthService = this.injector.get(OAuthService); } diff --git a/npm/ng-packs/packages/permission-management/proxy/src/lib/proxy/permissions.service.ts b/npm/ng-packs/packages/permission-management/proxy/src/lib/proxy/permissions.service.ts index 45ac0b40e1..dbd13ca778 100644 --- a/npm/ng-packs/packages/permission-management/proxy/src/lib/proxy/permissions.service.ts +++ b/npm/ng-packs/packages/permission-management/proxy/src/lib/proxy/permissions.service.ts @@ -1,11 +1,13 @@ import type { GetPermissionListResultDto, UpdatePermissionsDto } from './models'; import { RestService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class PermissionsService { + private restService = inject(RestService); + apiName = 'AbpPermissionManagement'; get = (providerName: string, providerKey: string) => @@ -24,6 +26,4 @@ export class PermissionsService { body: input, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template index aae3b43471..8b0c343173 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template +++ b/npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template @@ -5,6 +5,7 @@ providedIn: 'root', }) export class <%= name %>Service { + private restService = inject(RestService); apiName = '<%= apiName %>';<% for (let {body, signature} of methods) { %> <% @@ -26,6 +27,4 @@ export class <%= name %>Service { body: <%= body.body %>,<% } %> }, { apiName: this.apiName,...config });<% } %> - - constructor(private restService: RestService) {} -} +} \ No newline at end of file diff --git a/npm/ng-packs/packages/schematics/src/utils/service.ts b/npm/ng-packs/packages/schematics/src/utils/service.ts index 8f48ed3693..1280aa3aef 100644 --- a/npm/ng-packs/packages/schematics/src/utils/service.ts +++ b/npm/ng-packs/packages/schematics/src/utils/service.ts @@ -46,7 +46,7 @@ export function createControllerToServiceMapper({ [], ); imports.push(new Import({ path: '@abp/ng.core', specifiers: ['RestService', 'Rest'] })); - imports.push(new Import({ path: '@angular/core', specifiers: ['Injectable'] })); + imports.push(new Import({ path: '@angular/core', specifiers: ['Injectable', 'inject'] })); sortImports(imports); const methods = actions.map(mapActionToMethod); sortMethods(methods); diff --git a/npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.ts b/npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.ts index f61c158e0e..8745e0ffd4 100644 --- a/npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.ts +++ b/npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.ts @@ -45,6 +45,10 @@ const { required, email } = Validators; ], }) export class EmailSettingGroupComponent implements OnInit { + private emailSettingsService = inject(EmailSettingsService); + private fb = inject(UntypedFormBuilder); + private toasterService = inject(ToasterService); + protected readonly localizationService = inject(LocalizationService); protected readonly configStateSevice = inject(ConfigStateService); protected readonly currentUserEmail = toSignal( @@ -58,12 +62,6 @@ export class EmailSettingGroupComponent implements OnInit { isEmailTestModalOpen = false; modalSize: NgbModalOptions = { size: 'lg' }; - constructor( - private emailSettingsService: EmailSettingsService, - private fb: UntypedFormBuilder, - private toasterService: ToasterService, - ) {} - ngOnInit() { this.getData(); } diff --git a/npm/ng-packs/packages/setting-management/config/src/lib/proxy/email-settings.service.ts b/npm/ng-packs/packages/setting-management/config/src/lib/proxy/email-settings.service.ts index 0252b18c12..a1835e1a38 100644 --- a/npm/ng-packs/packages/setting-management/config/src/lib/proxy/email-settings.service.ts +++ b/npm/ng-packs/packages/setting-management/config/src/lib/proxy/email-settings.service.ts @@ -1,6 +1,6 @@ import type { EmailSettingsDto, SendTestEmailInput, UpdateEmailSettingsDto } from './models'; import { RestService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; /** @deprecated This method is deprecated, use it from @abp/ng.setting-management/proxy @@ -9,6 +9,8 @@ import { Injectable } from '@angular/core'; providedIn: 'root', }) export class EmailSettingsService { + private restService = inject(RestService); + apiName = 'SettingManagement'; get = () => @@ -33,6 +35,4 @@ export class EmailSettingsService { body: input, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/email-settings.service.ts b/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/email-settings.service.ts index a05cfc27a7..af6a2f5843 100644 --- a/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/email-settings.service.ts +++ b/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/email-settings.service.ts @@ -1,11 +1,13 @@ import type { EmailSettingsDto, SendTestEmailInput, UpdateEmailSettingsDto } from './models'; import { RestService, Rest } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) -export class EmailSettingsService { +export class EmailSettingsService { + private restService = inject(RestService); + apiName = 'SettingManagement'; @@ -33,6 +35,4 @@ export class EmailSettingsService { body: input, }, { apiName: this.apiName,...config }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/time-zone-settings.service.ts b/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/time-zone-settings.service.ts index 7141bce27d..1a20916673 100644 --- a/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/time-zone-settings.service.ts +++ b/npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/time-zone-settings.service.ts @@ -1,11 +1,13 @@ import type { NameValue } from './volo/abp/models'; import { RestService, Rest } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) -export class TimeZoneSettingsService { +export class TimeZoneSettingsService { + private restService = inject(RestService); + apiName = 'SettingManagement'; @@ -33,6 +35,4 @@ export class TimeZoneSettingsService { params: { timezone }, }, { apiName: this.apiName,...config }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/tenant-management/proxy/src/lib/proxy/tenant.service.ts b/npm/ng-packs/packages/tenant-management/proxy/src/lib/proxy/tenant.service.ts index 61d1667be4..28174f8ad8 100644 --- a/npm/ng-packs/packages/tenant-management/proxy/src/lib/proxy/tenant.service.ts +++ b/npm/ng-packs/packages/tenant-management/proxy/src/lib/proxy/tenant.service.ts @@ -1,12 +1,14 @@ import type { GetTenantsInput, TenantCreateDto, TenantDto, TenantUpdateDto } from './models'; import { RestService } from '@abp/ng.core'; import type { PagedResultDto } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class TenantService { + private restService = inject(RestService); + apiName = 'AbpTenantManagement'; create = (input: TenantCreateDto) => @@ -69,6 +71,4 @@ export class TenantService { params: { defaultConnectionString }, }, { apiName: this.apiName }); - - constructor(private restService: RestService) {} } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.ts index e5b68e8901..4a19cc7212 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component } from '@angular/core'; +import { AfterViewInit, Component, inject } from '@angular/core'; import { eLayoutType, ReplaceableTemplateDirective, SubscriptionService } from '@abp/ng.core'; import { LayoutService } from '../../services/layout.service'; import { CommonModule } from '@angular/common'; @@ -25,13 +25,13 @@ import { RouterModule } from '@angular/router'; ], }) export class AccountLayoutComponent implements AfterViewInit { + service = inject(LayoutService); + // required for dynamic component static type = eLayoutType.account; authWrapperKey = 'Account.AuthWrapperComponent'; - constructor(public service: LayoutService) {} - ngAfterViewInit() { this.service.subscribeWindowSize(); } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.ts index 5094551ed2..3c2db0a33b 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.ts @@ -1,15 +1,15 @@ -import { AuthWrapperService } from '@abp/ng.account.core'; -import { Component } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { LocalizationPipe, ReplaceableTemplateDirective } from '@abp/ng.core'; -import { TenantBoxComponent } from '../tenant-box/tenant-box.component'; +import { AuthWrapperService } from '@abp/ng.account.core'; +import { Component, inject } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { LocalizationPipe, ReplaceableTemplateDirective } from '@abp/ng.core'; +import { TenantBoxComponent } from '../tenant-box/tenant-box.component'; + +@Component({ + selector: 'abp-auth-wrapper', + templateUrl: './auth-wrapper.component.html', + providers: [AuthWrapperService], + imports: [CommonModule, TenantBoxComponent, ReplaceableTemplateDirective, LocalizationPipe], +}) +export class AuthWrapperComponent { service = inject(AuthWrapperService); -@Component({ - selector: 'abp-auth-wrapper', - templateUrl: './auth-wrapper.component.html', - providers: [AuthWrapperService], - imports: [CommonModule, TenantBoxComponent, ReplaceableTemplateDirective, LocalizationPipe], -}) -export class AuthWrapperComponent { - constructor(public service: AuthWrapperService) {} -} +} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.ts index 4aadd1effb..af4807d2bb 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.ts @@ -1,23 +1,23 @@ -import { TenantBoxService } from '@abp/ng.account.core'; -import { Component } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { LocalizationPipe } from '@abp/ng.core'; -import { ButtonComponent, ModalCloseDirective, ModalComponent } from '@abp/ng.theme.shared'; -import { FormsModule } from '@angular/forms'; +import { TenantBoxService } from '@abp/ng.account.core'; +import { Component, inject } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { LocalizationPipe } from '@abp/ng.core'; +import { ButtonComponent, ModalCloseDirective, ModalComponent } from '@abp/ng.theme.shared'; +import { FormsModule } from '@angular/forms'; + +@Component({ + selector: 'abp-tenant-box', + templateUrl: './tenant-box.component.html', + providers: [TenantBoxService], + imports: [ + CommonModule, + FormsModule, + ModalComponent, + LocalizationPipe, + ButtonComponent, + ModalCloseDirective, + ], +}) +export class TenantBoxComponent { service = inject(TenantBoxService); -@Component({ - selector: 'abp-tenant-box', - templateUrl: './tenant-box.component.html', - providers: [TenantBoxService], - imports: [ - CommonModule, - FormsModule, - ModalComponent, - LocalizationPipe, - ButtonComponent, - ModalCloseDirective, - ], -}) -export class TenantBoxComponent { - constructor(public service: TenantBoxService) {} -} +} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts index fcaeacdf1a..b3047d72ed 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts @@ -1,5 +1,5 @@ import { ApplicationInfo, EnvironmentService } from '@abp/ng.core'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; @Component({ @@ -16,9 +16,9 @@ import { CommonModule } from '@angular/common'; imports: [CommonModule], }) export class LogoComponent { + private environment = inject(EnvironmentService); + get appInfo(): ApplicationInfo { return this.environment.getEnvironment().application; } - - constructor(private environment: EnvironmentService) {} } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts index 40f2d4a342..de9ef1f3f0 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts @@ -9,7 +9,7 @@ import { ToInjectorPipe, } from '@abp/ng.core'; import { AbpVisibleDirective, UserMenu, UserMenuService } from '@abp/ng.theme.shared'; -import { Component, Inject, TrackByFunction } from '@angular/core'; +import { Component, TrackByFunction, inject } from '@angular/core'; import { Observable } from 'rxjs'; import { CommonModule } from '@angular/common'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; @@ -27,6 +27,12 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; ], }) export class CurrentUserComponent { + readonly navigateToManageProfile = inject(NAVIGATE_TO_MANAGE_PROFILE); + readonly userMenu = inject(UserMenuService); + private authService = inject(AuthService); + private configState = inject(ConfigStateService); + private sessionState = inject(SessionStateService); + currentUser$: Observable = this.configState.getOne$('currentUser'); selectedTenant$ = this.sessionState.getTenant$(); @@ -36,14 +42,6 @@ export class CurrentUserComponent { return window.innerWidth < 992; } - constructor( - @Inject(NAVIGATE_TO_MANAGE_PROFILE) public readonly navigateToManageProfile: () => void, - public readonly userMenu: UserMenuService, - private authService: AuthService, - private configState: ConfigStateService, - private sessionState: SessionStateService, - ) {} - navigateToLogin() { this.authService.navigateToLogin(); } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts index 67d09d300b..0a7b3e8190 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts @@ -1,5 +1,5 @@ import { ConfigStateService, LanguageInfo, SessionStateService } from '@abp/ng.core'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { CommonModule } from '@angular/common'; @@ -42,6 +42,9 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; imports: [CommonModule, NgbDropdownModule], }) export class LanguagesComponent { + private sessionState = inject(SessionStateService); + private configState = inject(ConfigStateService); + get smallScreen(): boolean { return window.innerWidth < 992; } @@ -69,11 +72,6 @@ export class LanguagesComponent { return this.sessionState.getLanguage(); } - constructor( - private sessionState: SessionStateService, - private configState: ConfigStateService, - ) {} - onChangeLang(cultureName: string) { this.sessionState.setLanguage(cultureName); } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.ts index d2e4a516b4..15b359f929 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.ts @@ -1,5 +1,5 @@ import { AbpVisibleDirective, NavItem, NavItemsService } from '@abp/ng.theme.shared'; -import { Component, TrackByFunction } from '@angular/core'; +import { Component, TrackByFunction, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PermissionDirective, ToInjectorPipe } from '@abp/ng.core'; @@ -9,7 +9,7 @@ import { PermissionDirective, ToInjectorPipe } from '@abp/ng.core'; imports: [CommonModule, AbpVisibleDirective, PermissionDirective, ToInjectorPipe], }) export class NavItemsComponent { - trackByFn: TrackByFunction = (_, element) => element.id; + readonly navItems = inject(NavItemsService); - constructor(public readonly navItems: NavItemsService) {} + trackByFn: TrackByFunction = (_, element) => element.id; } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.ts index b28cd6c81b..9347850b53 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.ts @@ -1,14 +1,14 @@ -import { Component, ViewEncapsulation } from '@angular/core'; -import { PageAlertService } from '@abp/ng.theme.shared'; -import { CommonModule } from '@angular/common'; -import { LocalizationPipe, SafeHtmlPipe } from '@abp/ng.core'; +import { Component, ViewEncapsulation, inject } from '@angular/core'; +import { PageAlertService } from '@abp/ng.theme.shared'; +import { CommonModule } from '@angular/common'; +import { LocalizationPipe, SafeHtmlPipe } from '@abp/ng.core'; + +@Component({ + selector: 'abp-page-alert-container', + templateUrl: './page-alert-container.component.html', + encapsulation: ViewEncapsulation.None, + imports: [CommonModule, LocalizationPipe, SafeHtmlPipe], +}) +export class PageAlertContainerComponent { service = inject(PageAlertService); -@Component({ - selector: 'abp-page-alert-container', - templateUrl: './page-alert-container.component.html', - encapsulation: ViewEncapsulation.None, - imports: [CommonModule, LocalizationPipe, SafeHtmlPipe], -}) -export class PageAlertContainerComponent { - constructor(public service: PageAlertService) {} -} +} diff --git a/npm/ng-packs/packages/theme-basic/src/lib/handlers/lazy-style.handler.ts b/npm/ng-packs/packages/theme-basic/src/lib/handlers/lazy-style.handler.ts index 02d9f69817..1064a143fb 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/handlers/lazy-style.handler.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/handlers/lazy-style.handler.ts @@ -1,6 +1,6 @@ import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; import { DocumentDirHandlerService, LocaleDirection } from '@abp/ng.theme.shared'; -import { Injectable, Injector } from '@angular/core'; +import { Injectable, Injector, inject } from '@angular/core'; import { LAZY_STYLES } from '../tokens/lazy-styles.token'; export const BOOTSTRAP = 'bootstrap-{{dir}}.min.css'; @@ -23,7 +23,9 @@ export class LazyStyleHandler { return this._dir; } - constructor(injector: Injector) { + constructor() { + const injector = inject(Injector); + this.setStyles(injector); this.setLazyLoad(injector); this.listenToDirectionChanges(injector); @@ -88,8 +90,8 @@ export function createLazyStyleHref(style: string, dir: string): string { return style.replace(/{{\s*dir\s*}}/g, dir); } -export function initLazyStyleHandler(injector: Injector) { - return () => new LazyStyleHandler(injector); +export function initLazyStyleHandler() { + return () => new LazyStyleHandler(); } interface LoadedStyle { diff --git a/npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts b/npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts index a990173218..0f8a535fe5 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts @@ -1,11 +1,14 @@ import {RouterEvents, SubscriptionService} from '@abp/ng.core'; -import { ChangeDetectorRef, Injectable } from '@angular/core'; +import { ChangeDetectorRef, Injectable, inject } from '@angular/core'; import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { eThemeBasicComponents } from '../enums'; @Injectable() export class LayoutService { + private subscription = inject(SubscriptionService); + private cdRef = inject(ChangeDetectorRef); + isCollapsed = true; smallScreen!: boolean; // do not set true or false @@ -16,9 +19,10 @@ export class LayoutService { navItemsComponentKey = eThemeBasicComponents.NavItems; - constructor(private subscription: SubscriptionService, - private cdRef: ChangeDetectorRef, - routerEvents:RouterEvents) { + constructor() { + const subscription = this.subscription; + const routerEvents = inject(RouterEvents); + subscription.addOne(routerEvents.getNavigationEvents("End"),() => { this.isCollapsed = true; }) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts index 4c7bd3cf30..f269be8d1e 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts @@ -6,7 +6,7 @@ import { SubscriptionService, TreeNode, } from '@abp/ng.core'; -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, inject } from '@angular/core'; import { Router } from '@angular/router'; import { map, startWith } from 'rxjs/operators'; import { eThemeSharedRouteNames } from '../../enums/route-names'; @@ -20,15 +20,13 @@ import { BreadcrumbItemsComponent } from '../breadcrumb-items/breadcrumb-items.c imports: [BreadcrumbItemsComponent], }) export class BreadcrumbComponent implements OnInit { - segments: Partial[] = []; + readonly cdRef = inject(ChangeDetectorRef); + private router = inject(Router); + private routes = inject(RoutesService); + private subscription = inject(SubscriptionService); + private routerEvents = inject(RouterEvents); - constructor( - public readonly cdRef: ChangeDetectorRef, - private router: Router, - private routes: RoutesService, - private subscription: SubscriptionService, - private routerEvents: RouterEvents, - ) {} + segments: Partial[] = []; ngOnInit(): void { this.subscription.addOne( diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts index fdebb542a7..4c89b9ac10 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts @@ -1,13 +1,14 @@ /* eslint-disable @angular-eslint/no-output-native */ -import { - Component, - ElementRef, - EventEmitter, - Input, - OnInit, - Output, - Renderer2, - ViewChild, +import { + Component, + ElementRef, + EventEmitter, + Input, + OnInit, + Output, + Renderer2, + ViewChild, + inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ABP } from '@abp/ng.core'; @@ -32,6 +33,8 @@ import { ABP } from '@abp/ng.core'; imports: [CommonModule], }) export class ButtonComponent implements OnInit { + private renderer = inject(Renderer2); + @Input() buttonId = ''; @@ -75,8 +78,6 @@ export class ButtonComponent implements OnInit { return `${this.loading ? 'fa fa-spinner fa-spin' : this.iconClass || 'd-none'}`; } - constructor(private renderer: Renderer2) {} - ngOnInit() { if (this.attributes) { Object.keys(this.attributes).forEach(key => { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts index f211b758e3..dcf7d4c952 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ReplaySubject } from 'rxjs'; import { Confirmation } from '../../models/confirmation'; @@ -12,7 +12,8 @@ import { LocalizationPipe } from '@abp/ng.core'; imports: [CommonModule, LocalizationPipe], }) export class ConfirmationComponent { - constructor(@Inject(CONFIRMATION_ICONS) private icons: ConfirmationIcons) {} + private icons = inject(CONFIRMATION_ICONS); + confirm = Confirmation.Status.confirm; reject = Confirmation.Status.reject; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts index 501fbbb82a..d611bc5f3d 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts @@ -1,5 +1,4 @@ -import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { combineLatest, Subscription, timer } from 'rxjs'; import { HttpWaitService, RouterWaitService, SubscriptionService } from '@abp/ng.core'; @@ -24,6 +23,11 @@ import { HttpWaitService, RouterWaitService, SubscriptionService } from '@abp/ng imports: [CommonModule], }) export class LoaderBarComponent implements OnDestroy, OnInit { + private cdRef = inject(ChangeDetectorRef); + private subscription = inject(SubscriptionService); + private httpWaitService = inject(HttpWaitService); + private routerWaitService = inject(RouterWaitService); + protected _isLoading!: boolean; @Input() @@ -73,14 +77,6 @@ export class LoaderBarComponent implements OnDestroy, OnInit { return `0 0 10px rgba(${this.color}, 0.5)`; } - constructor( - private router: Router, - private cdRef: ChangeDetectorRef, - private subscription: SubscriptionService, - private httpWaitService: HttpWaitService, - private routerWaitService: RouterWaitService, - ) {} - ngOnInit() { this.subscribeLoading(); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-close.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-close.directive.ts index 96455d1151..e15422d31b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-close.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-close.directive.ts @@ -1,11 +1,15 @@ -import { Directive, HostListener, Optional } from '@angular/core'; +import { Directive, HostListener, inject } from '@angular/core'; import { ModalComponent } from './modal.component'; @Directive({ selector: '[abpClose]', }) export class ModalCloseDirective { - constructor(@Optional() private modal: ModalComponent) { + private modal = inject(ModalComponent, { optional: true })!; + + constructor() { + const modal = this.modal; + if (!modal) { console.error('Please use abpClose within an abp-modal'); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/disabled.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/disabled.directive.ts index c0a1a74995..e00d827ba7 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/disabled.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/disabled.directive.ts @@ -1,15 +1,15 @@ -import { Directive, Host, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { Directive, Input, OnChanges, SimpleChanges, inject } from '@angular/core'; import { NgControl } from '@angular/forms'; @Directive({ selector: '[abpDisabled]', }) export class DisabledDirective implements OnChanges { + private ngControl = inject(NgControl, { host: true }); + @Input() abpDisabled = false; - constructor(@Host() private ngControl: NgControl) {} - // Related issue: https://github.com/angular/angular/issues/35330 ngOnChanges({ abpDisabled }: SimpleChanges) { if (this.ngControl.control && abpDisabled) { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts index 94d963ce2e..b26be01a34 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts @@ -1,17 +1,20 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Directive, - ElementRef, - HostBinding, - Input, - NgModule, +import { + AfterViewInit, + ChangeDetectorRef, + Directive, + ElementRef, + HostBinding, + Input, + inject } from '@angular/core'; @Directive({ selector: '[abpEllipsis]', }) export class EllipsisDirective implements AfterViewInit { + private cdRef = inject(ChangeDetectorRef); + private elRef = inject(ElementRef); + @Input('abpEllipsis') width?: string; @@ -37,11 +40,6 @@ export class EllipsisDirective implements AfterViewInit { return this.enabled && this.width ? this.width || '170px' : undefined; } - constructor( - private cdRef: ChangeDetectorRef, - private elRef: ElementRef, - ) {} - ngAfterViewInit() { this.title = this.title || (this.elRef.nativeElement as HTMLElement).innerText; this.cdRef.detectChanges(); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts index 9de000e15f..c117262583 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts @@ -1,16 +1,16 @@ -import { - ComponentFactoryResolver, - ComponentRef, - Directive, - ElementRef, - EmbeddedViewRef, - HostBinding, - Injector, - Input, - OnDestroy, - OnInit, - Renderer2, - ViewContainerRef, +import { + ComponentFactoryResolver, + ComponentRef, + Directive, + ElementRef, + EmbeddedViewRef, + HostBinding, + Injector, + Input, + OnDestroy, + OnInit, + Renderer2, + inject } from '@angular/core'; import { Subscription, timer } from 'rxjs'; import { take } from 'rxjs/operators'; @@ -20,6 +20,11 @@ import { LoadingComponent } from '../components'; selector: '[abpLoading]', }) export class LoadingDirective implements OnInit, OnDestroy { + private elRef = inject>(ElementRef); + private cdRes = inject(ComponentFactoryResolver); + private injector = inject(Injector); + private renderer = inject(Renderer2); + private _loading!: boolean; @HostBinding('style.position') @@ -77,14 +82,6 @@ export class LoadingDirective implements OnInit, OnDestroy { rootNode: HTMLDivElement | null = null; timerSubscription: Subscription | null = null; - constructor( - private elRef: ElementRef, - private vcRef: ViewContainerRef, - private cdRes: ComponentFactoryResolver, - private injector: Injector, - private renderer: Renderer2, - ) {} - ngOnInit() { if (!this.targetElement) { const { offsetHeight, offsetWidth } = this.elRef.nativeElement; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts index c7dc96f3c9..23ae8736f8 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts @@ -1,5 +1,5 @@ import { DOCUMENT } from '@angular/common'; -import { AfterViewInit, Directive, HostBinding, Inject, Input, OnDestroy } from '@angular/core'; +import { AfterViewInit, Directive, HostBinding, Input, OnDestroy, inject } from '@angular/core'; import { ColumnMode, DatatableComponent, ScrollerComponent } from '@swimlane/ngx-datatable'; import { fromEvent, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; @@ -10,6 +10,9 @@ import { debounceTime } from 'rxjs/operators'; exportAs: 'ngxDatatableDefault', }) export class NgxDatatableDefaultDirective implements AfterViewInit, OnDestroy { + private table = inject(DatatableComponent); + private document = inject(DOCUMENT); + private subscription = new Subscription(); private resizeDiff = 0; @@ -20,10 +23,7 @@ export class NgxDatatableDefaultDirective implements AfterViewInit, OnDestroy { return `ngx-datatable ${this.class}`; } - constructor( - private table: DatatableComponent, - @Inject(DOCUMENT) private document: MockDocument, - ) { + constructor() { this.table.columnMode = ColumnMode.force; this.table.footerHeight = 50; this.table.headerHeight = 50; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts index 9613779472..7532041462 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts @@ -1,10 +1,13 @@ -import { OnInit, Directive, OnDestroy, Input, ViewContainerRef, TemplateRef } from '@angular/core'; +import { OnInit, Directive, OnDestroy, Input, ViewContainerRef, TemplateRef, inject } from '@angular/core'; import { EMPTY, from, Observable, of, Subscription } from 'rxjs'; @Directive({ selector: '[abpVisible]', }) export class AbpVisibleDirective implements OnDestroy, OnInit { + private viewContainerRef = inject(ViewContainerRef); + private templateRef = inject>(TemplateRef); + conditionSubscription: Subscription | undefined; isVisible: boolean | undefined; @@ -16,11 +19,6 @@ export class AbpVisibleDirective implements OnDestroy, OnInit { } private condition$: Observable = of(false); - - constructor( - private viewContainerRef: ViewContainerRef, - private templateRef: TemplateRef, - ) {} ngOnInit(): void { this.updateVisibility(); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/document-dir.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/document-dir.handler.ts index 8260a39c27..7ca9426076 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/document-dir.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/document-dir.handler.ts @@ -1,14 +1,16 @@ import { getLocaleDirection, LocalizationService } from '@abp/ng.core'; -import { Injectable, Injector } from '@angular/core'; +import { Injectable, Injector, inject } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { map } from 'rxjs/operators'; import { LocaleDirection } from '../models/common'; @Injectable() export class DocumentDirHandlerService { + protected injector = inject(Injector); + private dir = new BehaviorSubject('ltr'); dir$ = this.dir.asObservable(); - constructor(protected injector: Injector) { + constructor() { this.listenToLanguageChanges(); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 07c5721625..f4a799ba1b 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -17,6 +17,8 @@ import { RouterErrorHandlerService } from '../services/router-error-handler.serv @Injectable({ providedIn: 'root' }) export class ErrorHandler { + protected injector = inject(Injector); + protected readonly httpErrorReporter = inject(HttpErrorReporterService); protected readonly confirmationService = inject(ConfirmationService); protected readonly routerErrorHandlerService = inject(RouterErrorHandlerService); @@ -24,7 +26,7 @@ export class ErrorHandler { protected readonly customErrorHandlers = inject(CUSTOM_ERROR_HANDLERS); protected readonly httpErrorHandler = inject(HTTP_ERROR_HANDLER, { optional: true }); - constructor(protected injector: Injector) { + constructor() { this.listenToRestError(); this.listenToRouterError(); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts index 5eeadb0ab6..ead1f0c91a 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts @@ -1,5 +1,5 @@ import { ContentProjectionService, LocalizationParam, PROJECTION_STRATEGY } from '@abp/ng.core'; -import { ComponentRef, Injectable } from '@angular/core'; +import { ComponentRef, Injectable, inject } from '@angular/core'; import { fromEvent, Observable, ReplaySubject, Subject } from 'rxjs'; import { debounceTime, filter, takeUntil } from 'rxjs/operators'; import { ConfirmationComponent } from '../components/confirmation/confirmation.component'; @@ -7,6 +7,8 @@ import { Confirmation } from '../models/confirmation'; @Injectable({ providedIn: 'root' }) export class ConfirmationService { + private contentProjectionService = inject(ContentProjectionService); + status$!: Subject; confirmation$ = new ReplaySubject(1); @@ -17,8 +19,6 @@ export class ConfirmationService { this.status$.next(status); }; - constructor(private contentProjectionService: ContentProjectionService) {} - private setContainer() { this.containerComponentRef = this.contentProjectionService.projectContent( PROJECTION_STRATEGY.AppendComponentToBody(ConfirmationComponent, { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts index 4a85a4dab6..40a99d98da 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts @@ -1,6 +1,6 @@ import { ApplicationLocalizationConfigurationDto, ConfigStateService } from '@abp/ng.core'; import { formatDate } from '@angular/common'; -import { Inject, Injectable, LOCALE_ID } from '@angular/core'; +import { Injectable, LOCALE_ID, inject } from '@angular/core'; import { NgbDateParserFormatter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; function isNumber(value: any): boolean { @@ -13,10 +13,14 @@ function toInteger(value: any): number { @Injectable() export class DateParserFormatter extends NgbDateParserFormatter { - constructor(private configState: ConfigStateService, @Inject(LOCALE_ID) private locale: string) { + private configState = inject(ConfigStateService); + private locale = inject(LOCALE_ID); + + constructor() { super(); } + parse(value: string): NgbDateStruct | null { if (value) { const dateParts = value.trim().split('-');