Browse Source

Merge pull request #23262 from abpframework/issue-23231-v2

Refactor: Use Angular inject() for Dependency Injection Across All Modules - Issue 23231
pull/23311/head
Yağmur Çelik 1 year ago
committed by GitHub
parent
commit
5219175127
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/account.service.ts
  2. 6
      npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/profile.service.ts
  3. 6
      npm/ng-packs/packages/account-core/proxy/src/lib/proxy/account/web/areas/account/controllers/account.service.ts
  4. 13
      npm/ng-packs/packages/account-core/src/lib/auth-wrapper.service.ts
  5. 14
      npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts
  6. 16
      npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts
  7. 10
      npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts
  8. 10
      npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts
  9. 8
      npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts
  10. 18
      npm/ng-packs/packages/account/src/lib/components/register/register.component.ts
  11. 16
      npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts
  12. 35
      npm/ng-packs/packages/components/chart.js/src/chart.component.ts
  13. 6
      npm/ng-packs/packages/components/extensible/src/lib/components/abstract-actions/abstract-actions.component.ts
  14. 15
      npm/ng-packs/packages/components/extensible/src/lib/components/grid-actions/grid-actions.component.ts
  15. 12
      npm/ng-packs/packages/components/extensible/src/lib/components/page-toolbar/page-toolbar.component.ts
  16. 28
      npm/ng-packs/packages/components/extensible/src/lib/directives/prop-data.directive.ts
  17. 41
      npm/ng-packs/packages/components/page/src/page-part.directive.ts
  18. 14
      npm/ng-packs/packages/components/tree/src/lib/templates/expanded-icon-template.directive.ts
  19. 14
      npm/ng-packs/packages/components/tree/src/lib/templates/tree-node-template.directive.ts
  20. 6
      npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
  21. 12
      npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts
  22. 6
      npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts
  23. 10
      npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts
  24. 35
      npm/ng-packs/packages/core/src/lib/directives/for.directive.ts
  25. 30
      npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts
  26. 6
      npm/ng-packs/packages/core/src/lib/directives/init.directive.ts
  27. 35
      npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
  28. 35
      npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts
  29. 10
      npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts
  30. 10
      npm/ng-packs/packages/core/src/lib/handlers/routes.handler.ts
  31. 5
      npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts
  32. 5
      npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts
  33. 13
      npm/ng-packs/packages/core/src/lib/pipes/short-date-time.pipe.ts
  34. 13
      npm/ng-packs/packages/core/src/lib/pipes/short-date.pipe.ts
  35. 13
      npm/ng-packs/packages/core/src/lib/pipes/short-time.pipe.ts
  36. 5
      npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts
  37. 9
      npm/ng-packs/packages/core/src/lib/providers/locale.provider.ts
  38. 8
      npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts
  39. 8
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts
  40. 8
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts
  41. 8
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts
  42. 14
      npm/ng-packs/packages/core/src/lib/services/config-state.service.ts
  43. 5
      npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts
  44. 6
      npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts
  45. 6
      npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts
  46. 6
      npm/ng-packs/packages/core/src/lib/services/list.service.ts
  47. 17
      npm/ng-packs/packages/core/src/lib/services/localization.service.ts
  48. 16
      npm/ng-packs/packages/core/src/lib/services/multi-tenancy.service.ts
  49. 5
      npm/ng-packs/packages/core/src/lib/services/permission.service.ts
  50. 7
      npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts
  51. 15
      npm/ng-packs/packages/core/src/lib/services/rest.service.ts
  52. 8
      npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts
  53. 8
      npm/ng-packs/packages/core/src/lib/services/routes.service.ts
  54. 8
      npm/ng-packs/packages/core/src/lib/services/session-state.service.ts
  55. 402
      npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts
  56. 352
      npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts
  57. 11
      npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts
  58. 27
      npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts
  59. 6
      npm/ng-packs/packages/feature-management/proxy/src/lib/proxy/feature-management/features.service.ts
  60. 6
      npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-role.service.ts
  61. 6
      npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user-lookup.service.ts
  62. 6
      npm/ng-packs/packages/identity/proxy/src/lib/proxy/identity/identity-user.service.ts
  63. 12
      npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts
  64. 13
      npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts
  65. 6
      npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts
  66. 6
      npm/ng-packs/packages/permission-management/proxy/src/lib/proxy/permissions.service.ts
  67. 5
      npm/ng-packs/packages/schematics/src/commands/api/files-service/proxy/__namespace@dir__/__name@kebab__.service.ts.template
  68. 2
      npm/ng-packs/packages/schematics/src/utils/service.ts
  69. 10
      npm/ng-packs/packages/setting-management/config/src/lib/components/email-setting-group/email-setting-group.component.ts
  70. 6
      npm/ng-packs/packages/setting-management/config/src/lib/proxy/email-settings.service.ts
  71. 8
      npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/email-settings.service.ts
  72. 8
      npm/ng-packs/packages/setting-management/proxy/src/lib/proxy/time-zone-settings.service.ts
  73. 6
      npm/ng-packs/packages/tenant-management/proxy/src/lib/proxy/tenant.service.ts
  74. 6
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/account-layout.component.ts
  75. 28
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/auth-wrapper/auth-wrapper.component.ts
  76. 44
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.ts
  77. 6
      npm/ng-packs/packages/theme-basic/src/lib/components/logo/logo.component.ts
  78. 16
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts
  79. 10
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts
  80. 6
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/nav-items.component.ts
  81. 26
      npm/ng-packs/packages/theme-basic/src/lib/components/page-alert-container/page-alert-container.component.ts
  82. 10
      npm/ng-packs/packages/theme-basic/src/lib/handlers/lazy-style.handler.ts
  83. 12
      npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts
  84. 16
      npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb/breadcrumb.component.ts
  85. 23
      npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts
  86. 5
      npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts
  87. 16
      npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts
  88. 8
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-close.directive.ts
  89. 6
      npm/ng-packs/packages/theme-shared/src/lib/directives/disabled.directive.ts
  90. 24
      npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts
  91. 39
      npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts
  92. 10
      npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts
  93. 10
      npm/ng-packs/packages/theme-shared/src/lib/directives/visible.directive.ts
  94. 6
      npm/ng-packs/packages/theme-shared/src/lib/handlers/document-dir.handler.ts
  95. 4
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts
  96. 6
      npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts
  97. 8
      npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts

6
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) {}
}

6
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) {}
}

6
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) {}
}

13
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<boolean> {
@ -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);
}

14
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 || '';

16
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;

10
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]],
});

10
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);

8
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<FormProp>(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 || '';

18
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();

16
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');

35
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;

6
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<L>['record'];
protected constructor(injector: Injector) {
protected constructor() {
const injector = inject(Injector);
super();
this.getInjected = injector.get.bind(injector);
const extensions = injector.get(ExtensionsService);

15
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<R = any> extends AbstractActionsComponent<Enti
readonly trackByFn: TrackByFunction<EntityAction<R>> = (_, item) => item.text;
constructor(injector: Injector) {
super(injector);
constructor() {
super();
}
}

12
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<R = any>
extends AbstractActionsComponent<ToolbarActionList<R>>
implements HasCreateInjectorPipe<R>
{
readonly injector: Injector;
defaultBtnClass = 'btn btn-sm btn-primary';
getData = () => this.data;
@ -42,8 +44,12 @@ export class PageToolbarComponent<R = any>
readonly trackByFn: TrackByFunction<ToolbarComponent<R>> = (_, 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 } {

28
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<L extends PropList<any>>
extends PropData<InferredData<L>>
implements OnChanges, OnDestroy
{
private tempRef = inject<TemplateRef<any>>(TemplateRef);
private vcRef = inject(ViewContainerRef);
@Input('abpPropDataFromList') propList?: L;
@Input('abpPropDataWithRecord') record!: InferredData<L>['record'];
@ -26,11 +30,9 @@ export class PropDataDirective<L extends PropList<any>>
readonly getInjected: InferredData<L>['getInjected'];
constructor(
private tempRef: TemplateRef<any>,
private vcRef: ViewContainerRef,
injector: Injector,
) {
constructor() {
const injector = inject(Injector);
super();
this.getInjected = injector.get.bind(injector);

41
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<PageRenderStrategy>('PAGE
selector: '[abpPagePart]',
})
export class PagePartDirective implements OnInit, OnDestroy, OnChanges {
private templateRef = inject<TemplateRef<any>>(TemplateRef);
private viewContainer = inject(ViewContainerRef);
private renderLogic = inject<PageRenderStrategy>(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<any>,
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);

14
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<any>>(TemplateRef);
@Directive({
selector: '[abpTreeExpandedIconTemplate],[abp-tree-expanded-icon-template]',
})
export class ExpandedIconTemplateDirective {
constructor(public template: TemplateRef<any>) {}
}
}

14
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<any>>(TemplateRef);
@Directive({
selector: '[abpTreeNodeTemplate],[abp-tree-node-template]',
})
export class TreeNodeTemplateDirective {
constructor(public template: TemplateRef<any>) {}
}
}

6
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;

12
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<any>;
componentKey!: string;
externalComponent?: Type<any>;
constructor(
private route: ActivatedRoute,
private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService,
) {}
ngOnInit() {
this.defaultComponent = this.route.snapshot.data.replaceableComponent.defaultComponent;
this.componentKey = (

6
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);
}

10
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<Event>();
constructor(
private el: ElementRef,
private subscription: SubscriptionService,
) {}
ngOnInit(): void {
const input$ = fromEvent<InputEvent>(this.el.nativeElement, 'input').pipe(
debounceTime(this.debounce),

35
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<AbpForContext>>(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<AbpForContext>,
private vcRef: ViewContainerRef,
private differs: IterableDiffers,
) {}
private iterateOverAppliedOperations(changes: IterableChanges<any>) {
const rw: RecordView[] = [];

30
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<HTMLFormElement>>(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<HTMLFormElement>,
private cdRef: ChangeDetectorRef,
private subscription: SubscriptionService,
) {}
ngOnInit() {
this.subscription.addOne(this.formGroupDirective.ngSubmit, () => {
if (this.markAsDirtyWhenSubmit) {

6
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<ElementRef<any>>();
private elRef = inject(ElementRef);
constructor(private elRef: ElementRef) {}
@Output('abpInit') readonly init = new EventEmitter<ElementRef<any>>();
ngAfterViewInit() {
this.init.emit(this.elRef);

35
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<any>>(TemplateRef, { optional: true })!;
private vcRef = inject(ViewContainerRef);
private permissionService = inject(PermissionService);
private cdRef = inject(ChangeDetectorRef);
queue = inject<QueueManager>(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<any>,
private vcRef: ViewContainerRef,
private permissionService: PermissionService,
private cdRef: ChangeDetectorRef,
@Inject(QUEUE_MANAGER) public queue: QueueManager,
) {}
private check() {
if (this.subscription) {
this.subscription.unsubscribe();

35
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<any>>(TemplateRef);
private vcRef = inject(ViewContainerRef);
private replaceableComponents = inject(ReplaceableComponentsService);
private subscription = inject(SubscriptionService);
@Input('abpReplaceableTemplate')
data!: ReplaceableComponents.ReplaceableTemplateDirectiveInput<any, any>;
@ -40,13 +47,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
initialized = false;
constructor(
private injector: Injector,
private templateRef: TemplateRef<any>,
private vcRef: ViewContainerRef,
private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService,
) {
constructor() {
this.context = {
initTemplate: (ref: any) => {
this.resetDefaultComponent();

10
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<MouseEvent>();
private el = inject(ElementRef);
private subscription = inject(SubscriptionService);
constructor(
private el: ElementRef,
private subscription: SubscriptionService,
) {}
@Output('click.stop') readonly stopPropEvent = new EventEmitter<MouseEvent>();
ngOnInit(): void {
this.subscription.addOne(fromEvent<MouseEvent>(this.el.nativeElement, 'click'), event => {

10
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();
}

5
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();

5
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 = '',

13
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);
}

13
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);
}

13
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);
}

5
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<PipeTransform>(
'INJECTOR_PIPE_DATA_TOKEN',
@ -8,7 +8,8 @@ export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken<PipeTransform>(
name: 'toInjector',
})
export class ToInjectorPipe implements PipeTransform {
constructor(private injector: Injector) {}
private injector = inject(Injector);
transform(
value: any,
token: InjectionToken<any> = INJECTOR_PIPE_DATA_TOKEN,

9
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],
};
};

8
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) {}
}

8
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) {}
}

8
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) { }
}

8
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) {}
}

14
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<void>();
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();
}

5
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<T extends Type<any> | TemplateRef<any>>(
projectionStrategy: ProjectionStrategy<T>,

6
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<void>();
constructor(injector: Injector) {
constructor() {
const injector = inject(Injector);
this.delay = injector.get(LOADER_DELAY, 500);
}

6
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<string, HTMLScriptElement | HTMLLinkElement | null>();
private resourceWaitService = inject(ResourceWaitService);
constructor(private resourceWaitService: ResourceWaitService) {}
readonly loaded = new Map<string, HTMLScriptElement | HTMLLinkElement | null>();
load(strategy: LoadingStrategy, retryTimes?: number, retryDelay?: number): Observable<Event> {
if (this.loaded.has(strategy.path)) return of(new CustomEvent('load'));

6
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<QueryParamsType = ABP.PageQueryParams | any> 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();

17
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<string>();
@ -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();

16
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)

5
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(

7
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<ReplaceableComponents.ReplaceableComponent[]>;
get replaceableComponents$(): Observable<ReplaceableComponents.ReplaceableComponent[]> {
@ -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[]);
}

15
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<ABP.Root>(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);

8
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<RouterWaitState>({ loading: false });
private destroy$ = new Subject<void>();
private delay: number;
constructor(private routerEvents: RouterEvents, injector: Injector) {
constructor() {
const injector = inject(Injector);
this.delay = injector.get(LOADER_DELAY, 500);
this.updateLoadingStatusOnNavigationEvents();
}

8
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<T extends ABP.Nav>
extends AbstractTreeService<T>
implements OnDestroy
{
protected injector = inject(Injector);
private subscription: Subscription;
private permissionService: PermissionService;
private compareFunc;
@ -211,8 +213,10 @@ export abstract class AbstractNavTreeService<T extends ABP.Nav>
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)

8
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();
}

402
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: '<router-outlet></router-outlet>',
})
class DummyApplicationLayoutComponent {}
@Component({
selector: 'abp-layout-account',
template: '<router-outlet></router-outlet>',
})
class DummyAccountLayoutComponent {}
@Component({
selector: 'abp-layout-empty',
template: '<router-outlet></router-outlet>',
})
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<RouterOutletComponent>;
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: '<router-outlet></router-outlet>',
})
class DummyApplicationLayoutComponent {}
@Component({
selector: 'abp-layout-account',
template: '<router-outlet></router-outlet>',
})
class DummyAccountLayoutComponent {}
@Component({
selector: 'abp-layout-empty',
template: '<router-outlet></router-outlet>',
})
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<RouterOutletComponent>;
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();
});
});

352
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: ' <p>default</p> ',
exportAs: 'abpDefaultComponent',
})
class DefaultComponent {
@Input()
oneWay;
@Input()
twoWay: boolean;
@Output()
readonly twoWayChange = new EventEmitter<boolean>();
@Output()
readonly someOutput = new EventEmitter<string>();
setTwoWay(value) {
this.twoWay = value;
this.twoWayChange.emit(value);
}
}
@Component({
selector: 'abp-external-component',
template: ' <p>external</p> ',
})
class ExternalComponent {
constructor(
@Optional()
@Inject('REPLACEABLE_DATA')
public data: ReplaceableComponents.ReplaceableTemplateData<any, any>,
) {}
}
describe('ReplaceableTemplateDirective', () => {
let spectator: SpectatorDirective<ReplaceableTemplateDirective>;
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(
`
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate">
<abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component>
</div>
`,
{
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(
`
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate">
<abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component>
</div>
`,
{ 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: ' <p>default</p> ',
exportAs: 'abpDefaultComponent',
})
class DefaultComponent {
@Input()
oneWay;
@Input()
twoWay: boolean;
@Output()
readonly twoWayChange = new EventEmitter<boolean>();
@Output()
readonly someOutput = new EventEmitter<string>();
setTwoWay(value) {
this.twoWay = value;
this.twoWayChange.emit(value);
}
}
@Component({
selector: 'abp-external-component',
template: ' <p>external</p> ',
})
class ExternalComponent { data = inject<ReplaceableComponents.ReplaceableTemplateData<any, any>>('REPLACEABLE_DATA' as any, { optional: true })!;
}
describe('ReplaceableTemplateDirective', () => {
let spectator: SpectatorDirective<ReplaceableTemplateDirective>;
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(
`
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate">
<abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component>
</div>
`,
{
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(
`
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate">
<abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component>
</div>
`,
{ 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();
});
});
});

11
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();
}

27
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<ABP.Root>(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<any> {

6
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) {}
}

6
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) {}
}

6
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) {}
}

6
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) {}
}

12
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<ABP.Root>(CORE_OPTIONS);
constructor() {
this.listenToSetEnvironment();
}

13
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<any>, next: HttpHandler) {
this.httpWaitService.addRequest(request);

6
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);
}

6
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) {}
}

5
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) {}
}
}

2
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);

10
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();
}

6
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) {}
}

8
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) {}
}

8
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) {}
}

6
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) {}
}

6
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();
}

28
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) {}
}
}

44
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) {}
}
}

6
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) {}
}

16
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<CurrentUserDto> = 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();
}

10
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);
}

6
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<NavItem> = (_, element) => element.id;
readonly navItems = inject(NavItemsService);
constructor(public readonly navItems: NavItemsService) {}
trackByFn: TrackByFunction<NavItem> = (_, element) => element.id;
}

26
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) {}
}
}

10
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 {

12
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;
})

16
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<ABP.Route>[] = [];
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<ABP.Route>[] = [];
ngOnInit(): void {
this.subscription.addOne(

23
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 => {

5
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<ConfirmationIcons>(CONFIRMATION_ICONS);
confirm = Confirmation.Status.confirm;
reject = Confirmation.Status.reject;

16
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();
}

8
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');
}

6
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) {

24
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();

39
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<HTMLElement>>(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<HTMLElement>,
private vcRef: ViewContainerRef,
private cdRes: ComponentFactoryResolver,
private injector: Injector,
private renderer: Renderer2,
) {}
ngOnInit() {
if (!this.targetElement) {
const { offsetHeight, offsetWidth } = this.elRef.nativeElement;

10
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<MockDocument>(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;

10
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<unknown>>(TemplateRef);
conditionSubscription: Subscription | undefined;
isVisible: boolean | undefined;
@ -16,11 +19,6 @@ export class AbpVisibleDirective implements OnDestroy, OnInit {
}
private condition$: Observable<boolean> = of(false);
constructor(
private viewContainerRef: ViewContainerRef,
private templateRef: TemplateRef<unknown>,
) {}
ngOnInit(): void {
this.updateVisibility();
}

6
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<LocaleDirection>('ltr');
dir$ = this.dir.asObservable();
constructor(protected injector: Injector) {
constructor() {
this.listenToLanguageChanges();
}

4
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();
}

6
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.Status>;
confirmation$ = new ReplaySubject<Confirmation.DialogData | null>(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, {

8
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('-');

Loading…
Cancel
Save