Browse Source

refactor : migrate core package to inject() DI

pull/23262/head
Fahri Gedik 1 year ago
parent
commit
d55ea1b132
  1. 6
      npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
  2. 12
      npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts
  3. 6
      npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts
  4. 10
      npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts
  5. 35
      npm/ng-packs/packages/core/src/lib/directives/for.directive.ts
  6. 30
      npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts
  7. 6
      npm/ng-packs/packages/core/src/lib/directives/init.directive.ts
  8. 35
      npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
  9. 35
      npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts
  10. 10
      npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts
  11. 10
      npm/ng-packs/packages/core/src/lib/handlers/routes.handler.ts
  12. 5
      npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts
  13. 5
      npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts
  14. 13
      npm/ng-packs/packages/core/src/lib/pipes/short-date-time.pipe.ts
  15. 13
      npm/ng-packs/packages/core/src/lib/pipes/short-date.pipe.ts
  16. 13
      npm/ng-packs/packages/core/src/lib/pipes/short-time.pipe.ts
  17. 5
      npm/ng-packs/packages/core/src/lib/pipes/to-injector.pipe.ts
  18. 8
      npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts
  19. 8
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts
  20. 8
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts
  21. 8
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts
  22. 14
      npm/ng-packs/packages/core/src/lib/services/config-state.service.ts
  23. 5
      npm/ng-packs/packages/core/src/lib/services/content-projection.service.ts
  24. 6
      npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts
  25. 6
      npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts
  26. 6
      npm/ng-packs/packages/core/src/lib/services/list.service.ts
  27. 17
      npm/ng-packs/packages/core/src/lib/services/localization.service.ts
  28. 16
      npm/ng-packs/packages/core/src/lib/services/multi-tenancy.service.ts
  29. 5
      npm/ng-packs/packages/core/src/lib/services/permission.service.ts
  30. 7
      npm/ng-packs/packages/core/src/lib/services/replaceable-components.service.ts
  31. 15
      npm/ng-packs/packages/core/src/lib/services/rest.service.ts
  32. 8
      npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts
  33. 8
      npm/ng-packs/packages/core/src/lib/services/routes.service.ts
  34. 8
      npm/ng-packs/packages/core/src/lib/services/session-state.service.ts
  35. 402
      npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts
  36. 352
      npm/ng-packs/packages/core/src/lib/tests/replaceable-template.directive.spec.ts
  37. 10
      npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts
  38. 24
      npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts

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 { ActivatedRoute, Router } from '@angular/router';
import { eLayoutType } from '../enums/common'; import { eLayoutType } from '../enums/common';
import { ABP } from '../models'; import { ABP } from '../models';
@ -39,7 +39,9 @@ export class DynamicLayoutComponent implements OnInit {
protected readonly routerEvents = inject(RouterEvents); protected readonly routerEvents = inject(RouterEvents);
protected readonly environment = inject(EnvironmentService); protected readonly environment = inject(EnvironmentService);
constructor(@Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent) { constructor() {
const dynamicLayoutComponent = inject(DynamicLayoutComponent, { optional: true, skipSelf: true })!;
if (dynamicLayoutComponent) { if (dynamicLayoutComponent) {
if (isDevMode()) console.warn('DynamicLayoutComponent must be used only in AppComponent.'); if (isDevMode()) console.warn('DynamicLayoutComponent must be used only in AppComponent.');
return; 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 { ActivatedRoute } from '@angular/router';
import { distinctUntilChanged } from 'rxjs/operators'; import { distinctUntilChanged } from 'rxjs/operators';
import { ReplaceableComponents } from '../models/replaceable-components'; import { ReplaceableComponents } from '../models/replaceable-components';
@ -15,18 +15,16 @@ import { CommonModule } from '@angular/common';
imports: [CommonModule], imports: [CommonModule],
}) })
export class ReplaceableRouteContainerComponent implements OnInit { export class ReplaceableRouteContainerComponent implements OnInit {
private route = inject(ActivatedRoute);
private replaceableComponents = inject(ReplaceableComponentsService);
private subscription = inject(SubscriptionService);
defaultComponent!: Type<any>; defaultComponent!: Type<any>;
componentKey!: string; componentKey!: string;
externalComponent?: Type<any>; externalComponent?: Type<any>;
constructor(
private route: ActivatedRoute,
private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService,
) {}
ngOnInit() { ngOnInit() {
this.defaultComponent = this.route.snapshot.data.replaceableComponent.defaultComponent; this.defaultComponent = this.route.snapshot.data.replaceableComponent.defaultComponent;
this.componentKey = ( 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({ @Directive({
selector: '[autofocus]', selector: '[autofocus]',
}) })
export class AutofocusDirective implements AfterViewInit { export class AutofocusDirective implements AfterViewInit {
private elRef = inject(ElementRef);
private _delay = 0; private _delay = 0;
@Input('autofocus') @Input('autofocus')
@ -15,8 +17,6 @@ export class AutofocusDirective implements AfterViewInit {
return this._delay; return this._delay;
} }
constructor(private elRef: ElementRef) {}
ngAfterViewInit(): void { ngAfterViewInit(): void {
setTimeout(() => this.elRef.nativeElement.focus(), this.delay as number); 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 { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators'; import { debounceTime } from 'rxjs/operators';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
@ -8,15 +8,13 @@ import { SubscriptionService } from '../services/subscription.service';
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class InputEventDebounceDirective implements OnInit { export class InputEventDebounceDirective implements OnInit {
private el = inject(ElementRef);
private subscription = inject(SubscriptionService);
@Input() debounce = 300; @Input() debounce = 300;
@Output('input.debounce') readonly debounceEvent = new EventEmitter<Event>(); @Output('input.debounce') readonly debounceEvent = new EventEmitter<Event>();
constructor(
private el: ElementRef,
private subscription: SubscriptionService,
) {}
ngOnInit(): void { ngOnInit(): void {
const input$ = fromEvent<InputEvent>(this.el.nativeElement, 'input').pipe( const input$ = fromEvent<InputEvent>(this.el.nativeElement, 'input').pipe(
debounceTime(this.debounce), debounceTime(this.debounce),

35
npm/ng-packs/packages/core/src/lib/directives/for.directive.ts

@ -1,15 +1,16 @@
import { import {
Directive, Directive,
EmbeddedViewRef, EmbeddedViewRef,
Input, Input,
IterableChangeRecord, IterableChangeRecord,
IterableChanges, IterableChanges,
IterableDiffer, IterableDiffer,
IterableDiffers, IterableDiffers,
OnChanges, OnChanges,
TemplateRef, TemplateRef,
TrackByFunction, TrackByFunction,
ViewContainerRef, ViewContainerRef,
inject
} from '@angular/core'; } from '@angular/core';
import clone from 'just-clone'; import clone from 'just-clone';
import compare from 'just-compare'; import compare from 'just-compare';
@ -36,6 +37,10 @@ class RecordView {
selector: '[abpFor]', selector: '[abpFor]',
}) })
export class ForDirective implements OnChanges { 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 // eslint-disable-next-line @angular-eslint/no-input-rename
@Input('abpForOf') @Input('abpForOf')
items!: any[]; items!: any[];
@ -73,12 +78,6 @@ export class ForDirective implements OnChanges {
return this.trackBy || ((index: number, item: any) => (item as any).id || index); 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>) { private iterateOverAppliedOperations(changes: IterableChanges<any>) {
const rw: RecordView[] = []; const rw: RecordView[] = [];

30
npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts

@ -1,12 +1,12 @@
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Directive, Directive,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
Input, Input,
OnInit, OnInit,
Output, Output,
Self, inject
} from '@angular/core'; } from '@angular/core';
import { FormGroupDirective, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { FormGroupDirective, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { fromEvent } from 'rxjs'; import { fromEvent } from 'rxjs';
@ -22,6 +22,11 @@ type Controls = { [key: string]: UntypedFormControl } | UntypedFormGroup[];
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class FormSubmitDirective implements OnInit { 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() @Input()
debounce = 200; debounce = 200;
@ -36,13 +41,6 @@ export class FormSubmitDirective implements OnInit {
executedNgSubmit = false; executedNgSubmit = false;
constructor(
@Self() private formGroupDirective: FormGroupDirective,
private host: ElementRef<HTMLFormElement>,
private cdRef: ChangeDetectorRef,
private subscription: SubscriptionService,
) {}
ngOnInit() { ngOnInit() {
this.subscription.addOne(this.formGroupDirective.ngSubmit, () => { this.subscription.addOne(this.formGroupDirective.ngSubmit, () => {
if (this.markAsDirtyWhenSubmit) { 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({ @Directive({
selector: '[abpInit]', selector: '[abpInit]',
}) })
export class InitDirective implements AfterViewInit { 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() { ngAfterViewInit() {
this.init.emit(this.elRef); this.init.emit(this.elRef);

35
npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts

@ -1,14 +1,13 @@
import { import {
AfterViewInit, AfterViewInit,
ChangeDetectorRef, ChangeDetectorRef,
Directive, Directive,
Inject, Input,
Input, OnChanges,
OnChanges, OnDestroy,
OnDestroy, TemplateRef,
Optional, ViewContainerRef,
TemplateRef, inject
ViewContainerRef,
} from '@angular/core'; } from '@angular/core';
import { ReplaySubject, Subscription } from 'rxjs'; import { ReplaySubject, Subscription } from 'rxjs';
import { distinctUntilChanged, take } from 'rxjs/operators'; import { distinctUntilChanged, take } from 'rxjs/operators';
@ -20,6 +19,12 @@ import { QueueManager } from '../utils/queue';
selector: '[abpPermission]', selector: '[abpPermission]',
}) })
export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit { 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('abpPermission') condition: string | undefined;
@Input('abpPermissionRunChangeDetection') runChangeDetection = true; @Input('abpPermissionRunChangeDetection') runChangeDetection = true;
@ -30,14 +35,6 @@ export class PermissionDirective implements OnDestroy, OnChanges, AfterViewInit
rendered = false; 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() { private check() {
if (this.subscription) { if (this.subscription) {
this.subscription.unsubscribe(); this.subscription.unsubscribe();

35
npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts

@ -1,13 +1,14 @@
import { import {
Directive, Directive,
Injector, Injector,
Input, Input,
OnChanges, OnChanges,
OnInit, OnInit,
SimpleChanges, SimpleChanges,
TemplateRef, TemplateRef,
Type, Type,
ViewContainerRef, ViewContainerRef,
inject
} from '@angular/core'; } from '@angular/core';
import compare from 'just-compare'; import compare from 'just-compare';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
@ -22,6 +23,12 @@ import { SubscriptionService } from '../services/subscription.service';
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class ReplaceableTemplateDirective implements OnInit, OnChanges { 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') @Input('abpReplaceableTemplate')
data!: ReplaceableComponents.ReplaceableTemplateDirectiveInput<any, any>; data!: ReplaceableComponents.ReplaceableTemplateDirectiveInput<any, any>;
@ -40,13 +47,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
initialized = false; initialized = false;
constructor( constructor() {
private injector: Injector,
private templateRef: TemplateRef<any>,
private vcRef: ViewContainerRef,
private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService,
) {
this.context = { this.context = {
initTemplate: (ref: any) => { initTemplate: (ref: any) => {
this.resetDefaultComponent(); 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 { fromEvent } from 'rxjs';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
@ -7,12 +7,10 @@ import { SubscriptionService } from '../services/subscription.service';
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class StopPropagationDirective implements OnInit { export class StopPropagationDirective implements OnInit {
@Output('click.stop') readonly stopPropEvent = new EventEmitter<MouseEvent>(); private el = inject(ElementRef);
private subscription = inject(SubscriptionService);
constructor( @Output('click.stop') readonly stopPropEvent = new EventEmitter<MouseEvent>();
private el: ElementRef,
private subscription: SubscriptionService,
) {}
ngOnInit(): void { ngOnInit(): void {
this.subscription.addOne(fromEvent<MouseEvent>(this.el.nativeElement, 'click'), event => { 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 { Route, Router } from '@angular/router';
import { ABP } from '../models'; import { ABP } from '../models';
import { RoutesService } from '../services/routes.service'; import { RoutesService } from '../services/routes.service';
@ -7,10 +7,10 @@ import { RoutesService } from '../services/routes.service';
providedIn: 'root', providedIn: 'root',
}) })
export class RoutesHandler { export class RoutesHandler {
constructor( private routes = inject(RoutesService);
private routes: RoutesService, private router = inject(Router, { optional: true })!;
@Optional() private router: Router,
) { constructor() {
this.addRoutes(); 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 { 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 { finalize } from 'rxjs/operators';
import { HttpWaitService } from '../services'; import { HttpWaitService } from '../services';
@ -7,7 +7,8 @@ import { HttpWaitService } from '../services';
providedIn: 'root', providedIn: 'root',
}) })
export class ApiInterceptor implements IApiInterceptor { export class ApiInterceptor implements IApiInterceptor {
constructor(private httpWaitService: HttpWaitService) {} private httpWaitService = inject(HttpWaitService);
getAdditionalHeaders(existingHeaders?: HttpHeaders) { getAdditionalHeaders(existingHeaders?: HttpHeaders) {
return existingHeaders || new 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 { LocalizationWithDefault } from '../models/localization';
import { LocalizationService } from '../services/localization.service'; import { LocalizationService } from '../services/localization.service';
@ -7,7 +7,8 @@ import { LocalizationService } from '../services/localization.service';
name: 'abpLocalization', name: 'abpLocalization',
}) })
export class LocalizationPipe implements PipeTransform { export class LocalizationPipe implements PipeTransform {
constructor(private localization: LocalizationService) {} private localization = inject(LocalizationService);
transform( transform(
value: string | LocalizationWithDefault = '', 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 { 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 { ConfigStateService } from '../services';
import { getShortDateShortTimeFormat } from '../utils/date-utils'; import { getShortDateShortTimeFormat } from '../utils/date-utils';
@ -8,11 +8,12 @@ import { getShortDateShortTimeFormat } from '../utils/date-utils';
pure: true, pure: true,
}) })
export class ShortDateTimePipe extends DatePipe implements PipeTransform { export class ShortDateTimePipe extends DatePipe implements PipeTransform {
constructor( private configStateService = inject(ConfigStateService);
private configStateService: ConfigStateService,
@Inject(LOCALE_ID) locale: string, constructor() {
@Inject(DATE_PIPE_DEFAULT_TIMEZONE) @Optional() defaultTimezone?: string | null, const locale = inject(LOCALE_ID);
) { const defaultTimezone = inject(DATE_PIPE_DEFAULT_TIMEZONE, { optional: true });
super(locale, defaultTimezone); 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 { 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 { ConfigStateService } from '../services';
import { getShortDateFormat } from '../utils/date-utils'; import { getShortDateFormat } from '../utils/date-utils';
@ -8,11 +8,12 @@ import { getShortDateFormat } from '../utils/date-utils';
pure: true, pure: true,
}) })
export class ShortDatePipe extends DatePipe implements PipeTransform { export class ShortDatePipe extends DatePipe implements PipeTransform {
constructor( private configStateService = inject(ConfigStateService);
private configStateService: ConfigStateService,
@Inject(LOCALE_ID) locale: string, constructor() {
@Inject(DATE_PIPE_DEFAULT_TIMEZONE) @Optional() defaultTimezone?: string | null, const locale = inject(LOCALE_ID);
) { const defaultTimezone = inject(DATE_PIPE_DEFAULT_TIMEZONE, { optional: true });
super(locale, defaultTimezone); 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 { 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 { ConfigStateService } from '../services';
import { getShortTimeFormat } from '../utils/date-utils'; import { getShortTimeFormat } from '../utils/date-utils';
@ -8,11 +8,12 @@ import { getShortTimeFormat } from '../utils/date-utils';
pure: true, pure: true,
}) })
export class ShortTimePipe extends DatePipe implements PipeTransform { export class ShortTimePipe extends DatePipe implements PipeTransform {
constructor( private configStateService = inject(ConfigStateService);
private configStateService: ConfigStateService,
@Inject(LOCALE_ID) locale: string, constructor() {
@Inject(DATE_PIPE_DEFAULT_TIMEZONE) @Optional() defaultTimezone?: string | null, const locale = inject(LOCALE_ID);
) { const defaultTimezone = inject(DATE_PIPE_DEFAULT_TIMEZONE, { optional: true });
super(locale, defaultTimezone); 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>( export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken<PipeTransform>(
'INJECTOR_PIPE_DATA_TOKEN', 'INJECTOR_PIPE_DATA_TOKEN',
@ -8,7 +8,8 @@ export const INJECTOR_PIPE_DATA_TOKEN = new InjectionToken<PipeTransform>(
name: 'toInjector', name: 'toInjector',
}) })
export class ToInjectorPipe implements PipeTransform { export class ToInjectorPipe implements PipeTransform {
constructor(private injector: Injector) {} private injector = inject(Injector);
transform( transform(
value: any, value: any,
token: InjectionToken<any> = INJECTOR_PIPE_DATA_TOKEN, token: InjectionToken<any> = INJECTOR_PIPE_DATA_TOKEN,

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 { RestService } from '../../../../services';
import { Rest } from '../../../../models'; 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'; import type { FindTenantResultDto } from '../../../volo/abp/asp-net-core/mvc/multi-tenancy/models';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AbpTenantService { export class AbpTenantService {
private restService = inject(RestService);
apiName = 'abp'; apiName = 'abp';
@ -24,6 +26,4 @@ export class AbpTenantService {
url: `/api/abp/multi-tenancy/tenants/by-name/${name}`, url: `/api/abp/multi-tenancy/tenants/by-name/${name}`,
}, },
{ apiName: this.apiName,...config }); { 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 { RestService } from '../../../../../../services';
import { Rest } from '../../../../../../models'; import { Rest } from '../../../../../../models';
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import type { ApplicationApiDescriptionModel, ApplicationApiDescriptionModelRequestDto } from '../../../http/modeling/models'; import type { ApplicationApiDescriptionModel, ApplicationApiDescriptionModelRequestDto } from '../../../http/modeling/models';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AbpApiDefinitionService { export class AbpApiDefinitionService {
private restService = inject(RestService);
apiName = 'abp'; apiName = 'abp';
@ -17,6 +19,4 @@ export class AbpApiDefinitionService {
params: { includeTypes: model.includeTypes }, params: { includeTypes: model.includeTypes },
}, },
{ apiName: this.apiName,...config }); { 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 type { ApplicationConfigurationDto, ApplicationConfigurationRequestOptions } from './models';
import { RestService } from '../../../../../../services'; import { RestService } from '../../../../../../services';
import { Rest } from '../../../../../../models'; import { Rest } from '../../../../../../models';
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AbpApplicationConfigurationService { export class AbpApplicationConfigurationService {
private restService = inject(RestService);
apiName = 'abp'; apiName = 'abp';
@ -17,6 +19,4 @@ export class AbpApplicationConfigurationService {
params: { includeLocalizationResources: options.includeLocalizationResources }, params: { includeLocalizationResources: options.includeLocalizationResources },
}, },
{ apiName: this.apiName, ...config }); { 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 type { ApplicationLocalizationDto, ApplicationLocalizationRequestDto } from './models';
import { RestService } from '../../../../../../services'; import { RestService } from '../../../../../../services';
import { Rest } from '../../../../../../models'; import { Rest } from '../../../../../../models';
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class AbpApplicationLocalizationService { export class AbpApplicationLocalizationService {
private restService = inject(RestService);
apiName = 'abp'; apiName = 'abp';
@ -17,6 +19,4 @@ export class AbpApplicationLocalizationService {
params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics }, params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics },
}, },
{ apiName: this.apiName,...config }); { 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 { Observable, Subject } from 'rxjs';
import { map, switchMap, take, tap } from 'rxjs/operators'; import { map, switchMap, take, tap } from 'rxjs/operators';
import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; 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', providedIn: 'root',
}) })
export class ConfigStateService { 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 updateSubject = new Subject<void>();
private readonly store = new InternalStore({} as ApplicationConfigurationDto); private readonly store = new InternalStore({} as ApplicationConfigurationDto);
@ -27,13 +31,7 @@ export class ConfigStateService {
get createOnUpdateStream() { get createOnUpdateStream() {
return this.store.sliceUpdate; return this.store.sliceUpdate;
} }
constructor( constructor() {
private abpConfigService: AbpApplicationConfigurationService,
private abpApplicationLocalizationService: AbpApplicationLocalizationService,
@Optional()
@Inject(INCUDE_LOCALIZATION_RESOURCES_TOKEN)
private readonly includeLocalizationResources: boolean | null,
) {
this.initUpdateStream(); 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'; import { ProjectionStrategy } from '../strategies/projection.strategy';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ContentProjectionService { export class ContentProjectionService {
constructor(private injector: Injector) {} private injector = inject(Injector);
projectContent<T extends Type<any> | TemplateRef<any>>( projectContent<T extends Type<any> | TemplateRef<any>>(
projectionStrategy: ProjectionStrategy<T>, 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 { HttpRequest } from '@angular/common/http';
import { InternalStore } from '../utils/internal-store-utils'; import { InternalStore } from '../utils/internal-store-utils';
import { getPathName } from '../utils/http-utils'; import { getPathName } from '../utils/http-utils';
@ -26,7 +26,9 @@ export class HttpWaitService {
private delay: number; private delay: number;
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
constructor(injector: Injector) { constructor() {
const injector = inject(Injector);
this.delay = injector.get(LOADER_DELAY, 500); 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 { concat, Observable, of, pipe, throwError } from 'rxjs';
import { delay, retryWhen, shareReplay, take, tap } from 'rxjs/operators'; import { delay, retryWhen, shareReplay, take, tap } from 'rxjs/operators';
import { LoadingStrategy } from '../strategies'; import { LoadingStrategy } from '../strategies';
@ -8,9 +8,9 @@ import { ResourceWaitService } from './resource-wait.service';
providedIn: 'root', providedIn: 'root',
}) })
export class LazyLoadService { 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> { load(strategy: LoadingStrategy, retryTimes?: number, retryDelay?: number): Observable<Event> {
if (this.loaded.has(strategy.path)) return of(new CustomEvent('load')); 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 { import {
EMPTY, EMPTY,
BehaviorSubject, BehaviorSubject,
@ -119,7 +119,9 @@ export class ListService<QueryParamsType = ABP.PageQueryParams | any> implements
this.next(); this.next();
}; };
constructor(injector: Injector) { constructor() {
const injector = inject(Injector);
const delay = injector.get(LIST_QUERY_DEBOUNCE_TIME, 300); const delay = injector.get(LIST_QUERY_DEBOUNCE_TIME, 300);
this.delay = delay ? debounceTime(delay) : tap(); this.delay = delay ? debounceTime(delay) : tap();
this.get(); this.get();

17
npm/ng-packs/packages/core/src/lib/services/localization.service.ts

@ -1,5 +1,5 @@
import { registerLocaleData } from '@angular/common'; 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 { BehaviorSubject, combineLatest, from, Observable, Subject } from 'rxjs';
import { filter, map, switchMap } from 'rxjs/operators'; import { filter, map, switchMap } from 'rxjs/operators';
import { ABP } from '../models/common'; import { ABP } from '../models/common';
@ -17,6 +17,10 @@ import { SessionStateService } from './session-state.service';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class LocalizationService { export class LocalizationService {
private sessionState = inject(SessionStateService);
private injector = inject(Injector);
private configState = inject(ConfigStateService);
private latestLang = this.sessionState.getLanguage(); private latestLang = this.sessionState.getLanguage();
private _languageChange$ = new Subject<string>(); private _languageChange$ = new Subject<string>();
@ -44,14 +48,9 @@ export class LocalizationService {
return this._languageChange$.asObservable(); return this._languageChange$.asObservable();
} }
constructor( constructor() {
private sessionState: SessionStateService, const otherInstance = inject(LocalizationService, { optional: true, skipSelf: true })!;
private injector: Injector,
@Optional()
@SkipSelf()
otherInstance: LocalizationService,
private configState: ConfigStateService,
) {
if (otherInstance) throw new Error('LocalizationService should have only one instance.'); if (otherInstance) throw new Error('LocalizationService should have only one instance.');
this.listenToSetLanguage(); 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 { map, switchMap } from 'rxjs/operators';
import { AbpTenantService } from '../proxy/pages/abp/multi-tenancy'; import { AbpTenantService } from '../proxy/pages/abp/multi-tenancy';
import { import {
@ -12,6 +12,12 @@ import { SessionStateService } from './session-state.service';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class MultiTenancyService { export class MultiTenancyService {
private restService = inject(RestService);
private sessionState = inject(SessionStateService);
private tenantService = inject(AbpTenantService);
private configStateService = inject(ConfigStateService);
tenantKey = inject(TENANT_KEY);
domainTenant: CurrentTenantDto | null = null; domainTenant: CurrentTenantDto | null = null;
isTenantBoxVisible = true; isTenantBoxVisible = true;
@ -23,14 +29,6 @@ export class MultiTenancyService {
return this.configStateService.refreshAppState().pipe(map(_ => tenant)); 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) { setTenantByName(tenantName: string) {
return this.tenantService return this.tenantService
.findTenantByName(tenantName) .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 { map } from 'rxjs/operators';
import { ABP } from '../models/common'; import { ABP } from '../models/common';
import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; 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' }) @Injectable({ providedIn: 'root' })
export class PermissionService { export class PermissionService {
constructor(protected configState: ConfigStateService) {} protected configState = inject(ConfigStateService);
getGrantedPolicy$(key: string) { getGrantedPolicy$(key: string) {
return this.getStream().pipe( 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 { Router } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@ -8,6 +8,9 @@ import { reloadRoute } from '../utils/route-utils';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ReplaceableComponentsService { export class ReplaceableComponentsService {
private ngZone = inject(NgZone);
private router = inject(Router);
private readonly store: InternalStore<ReplaceableComponents.ReplaceableComponent[]>; private readonly store: InternalStore<ReplaceableComponents.ReplaceableComponent[]>;
get replaceableComponents$(): Observable<ReplaceableComponents.ReplaceableComponent[]> { get replaceableComponents$(): Observable<ReplaceableComponents.ReplaceableComponent[]> {
@ -22,7 +25,7 @@ export class ReplaceableComponentsService {
return this.store.sliceUpdate(state => state); return this.store.sliceUpdate(state => state);
} }
constructor(private ngZone: NgZone, private router: Router) { constructor() {
this.store = new InternalStore([] as ReplaceableComponents.ReplaceableComponent[]); 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 { 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 { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
import { ExternalHttpClient } from '../clients/http.client'; import { ExternalHttpClient } from '../clients/http.client';
@ -14,13 +14,12 @@ import { HttpErrorReporterService } from './http-error-reporter.service';
providedIn: 'root', providedIn: 'root',
}) })
export class RestService { export class RestService {
constructor( protected options = inject<ABP.Root>(CORE_OPTIONS);
@Inject(CORE_OPTIONS) protected options: ABP.Root, protected http = inject(HttpClient);
protected http: HttpClient, protected externalHttp = inject(ExternalHttpClient);
protected externalHttp: ExternalHttpClient, protected environment = inject(EnvironmentService);
protected environment: EnvironmentService, protected httpErrorReporter = inject(HttpErrorReporterService);
protected httpErrorReporter: HttpErrorReporterService,
) { }
protected getApiFromStore(apiName: string | undefined): string { protected getApiFromStore(apiName: string | undefined): string {
return this.environment.getApiUrl(apiName); 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 { NavigationStart } from '@angular/router';
import { of, Subject, timer } from 'rxjs'; import { of, Subject, timer } from 'rxjs';
import { map, mapTo, switchMap, takeUntil, tap } from 'rxjs/operators'; import { map, mapTo, switchMap, takeUntil, tap } from 'rxjs/operators';
@ -14,10 +14,14 @@ export interface RouterWaitState {
providedIn: 'root', providedIn: 'root',
}) })
export class RouterWaitService { export class RouterWaitService {
private routerEvents = inject(RouterEvents);
private store = new InternalStore<RouterWaitState>({ loading: false }); private store = new InternalStore<RouterWaitState>({ loading: false });
private destroy$ = new Subject<void>(); private destroy$ = new Subject<void>();
private delay: number; private delay: number;
constructor(private routerEvents: RouterEvents, injector: Injector) { constructor() {
const injector = inject(Injector);
this.delay = injector.get(LOADER_DELAY, 500); this.delay = injector.get(LOADER_DELAY, 500);
this.updateLoadingStatusOnNavigationEvents(); 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 { BehaviorSubject, Observable, Subscription, map } from 'rxjs';
import { ABP } from '../models/common'; import { ABP } from '../models/common';
import { OTHERS_GROUP } from '../tokens'; import { OTHERS_GROUP } from '../tokens';
@ -201,6 +201,8 @@ export abstract class AbstractNavTreeService<T extends ABP.Nav>
extends AbstractTreeService<T> extends AbstractTreeService<T>
implements OnDestroy implements OnDestroy
{ {
protected injector = inject(Injector);
private subscription: Subscription; private subscription: Subscription;
private permissionService: PermissionService; private permissionService: PermissionService;
private compareFunc; private compareFunc;
@ -211,8 +213,10 @@ export abstract class AbstractNavTreeService<T extends ABP.Nav>
return this.compareFunc(a, b); return this.compareFunc(a, b);
}; };
constructor(protected injector: Injector) { constructor() {
super(); super();
const injector = this.injector;
const configState = this.injector.get(ConfigStateService); const configState = this.injector.get(ConfigStateService);
this.subscription = configState this.subscription = configState
.createOnUpdateStream(state => state) .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', providedIn: 'root',
}) })
export class SessionStateService { export class SessionStateService {
private configState = inject(ConfigStateService);
private localStorageService = inject(AbpLocalStorageService);
private readonly store = new InternalStore({} as Session.State); private readonly store = new InternalStore({} as Session.State);
protected readonly document = inject(DOCUMENT); protected readonly document = inject(DOCUMENT);
@ -19,10 +22,7 @@ export class SessionStateService {
this.localStorageService.setItem('abpSession', JSON.stringify(this.store.state)); this.localStorageService.setItem('abpSession', JSON.stringify(this.store.state));
}; };
constructor( constructor() {
private configState: ConfigStateService,
private localStorageService: AbpLocalStorageService,
) {
this.init(); this.init();
this.setInitialLanguage(); 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 { HttpClient } from '@angular/common/http';
import { Component, NgModule } from '@angular/core'; import { Component, NgModule, inject as inject_1 } from '@angular/core';
import { ActivatedRoute, RouterModule } from '@angular/router'; import { ActivatedRoute, RouterModule } from '@angular/router';
import { createRoutingFactory, SpectatorRouting } from '@ngneat/spectator/jest'; import { createRoutingFactory, SpectatorRouting } from '@ngneat/spectator/jest';
import { DynamicLayoutComponent, RouterOutletComponent } from '../components'; import { DynamicLayoutComponent, RouterOutletComponent } from '../components';
import { eLayoutType } from '../enums/common'; import { eLayoutType } from '../enums/common';
import { ABP } from '../models'; import { ABP } from '../models';
import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service';
import { ReplaceableComponentsService, RoutesService } from '../services'; import { ReplaceableComponentsService, RoutesService } from '../services';
import { mockRoutesService } from './routes.service.spec'; import { mockRoutesService } from './routes.service.spec';
@Component({ @Component({
selector: 'abp-layout-application', selector: 'abp-layout-application',
template: '<router-outlet></router-outlet>', template: '<router-outlet></router-outlet>',
}) })
class DummyApplicationLayoutComponent {} class DummyApplicationLayoutComponent {}
@Component({ @Component({
selector: 'abp-layout-account', selector: 'abp-layout-account',
template: '<router-outlet></router-outlet>', template: '<router-outlet></router-outlet>',
}) })
class DummyAccountLayoutComponent {} class DummyAccountLayoutComponent {}
@Component({ @Component({
selector: 'abp-layout-empty', selector: 'abp-layout-empty',
template: '<router-outlet></router-outlet>', template: '<router-outlet></router-outlet>',
}) })
class DummyEmptyLayoutComponent {} class DummyEmptyLayoutComponent {}
const LAYOUTS = [ const LAYOUTS = [
DummyApplicationLayoutComponent, DummyApplicationLayoutComponent,
DummyAccountLayoutComponent, DummyAccountLayoutComponent,
DummyEmptyLayoutComponent, DummyEmptyLayoutComponent,
]; ];
@NgModule({ @NgModule({
imports: [RouterModule], imports: [RouterModule],
declarations: [...LAYOUTS], declarations: [...LAYOUTS],
}) })
class DummyLayoutModule {} class DummyLayoutModule {}
@Component({ @Component({
selector: 'abp-dummy', selector: 'abp-dummy',
template: '{{route.snapshot.data?.name}} works!', template: '{{route.snapshot.data?.name}} works!',
}) })
class DummyComponent { class DummyComponent { route = inject_1(ActivatedRoute);
constructor(public route: ActivatedRoute) {}
} }
const routes: ABP.Route[] = [ const routes: ABP.Route[] = [
{ {
path: '', path: '',
name: 'Root', name: 'Root',
}, },
{ {
path: '/parentWithLayout', path: '/parentWithLayout',
name: 'ParentWithLayout', name: 'ParentWithLayout',
parentName: 'Root', parentName: 'Root',
layout: eLayoutType.application, layout: eLayoutType.application,
}, },
{ {
path: '/parentWithLayout/childWithoutLayout', path: '/parentWithLayout/childWithoutLayout',
name: 'ChildWithoutLayout', name: 'ChildWithoutLayout',
parentName: 'ParentWithLayout', parentName: 'ParentWithLayout',
}, },
{ {
path: '/parentWithLayout/childWithLayout', path: '/parentWithLayout/childWithLayout',
name: 'ChildWithLayout', name: 'ChildWithLayout',
parentName: 'ParentWithLayout', parentName: 'ParentWithLayout',
layout: eLayoutType.account, layout: eLayoutType.account,
}, },
{ {
path: '/withData', path: '/withData',
name: 'WithData', name: 'WithData',
layout: eLayoutType.application, layout: eLayoutType.application,
}, },
]; ];
describe('DynamicLayoutComponent', () => { describe('DynamicLayoutComponent', () => {
const createComponent = createRoutingFactory({ const createComponent = createRoutingFactory({
component: RouterOutletComponent, component: RouterOutletComponent,
stubsEnabled: false, stubsEnabled: false,
declarations: [DummyComponent, DynamicLayoutComponent], declarations: [DummyComponent, DynamicLayoutComponent],
mocks: [AbpApplicationConfigurationService, HttpClient], mocks: [AbpApplicationConfigurationService, HttpClient],
providers: [ providers: [
{ {
provide: RoutesService, provide: RoutesService,
useFactory: () => mockRoutesService(), useFactory: () => mockRoutesService(),
}, },
ReplaceableComponentsService, ReplaceableComponentsService,
], ],
imports: [RouterModule, DummyLayoutModule], imports: [RouterModule, DummyLayoutModule],
routes: [ routes: [
{ path: '', component: RouterOutletComponent }, { path: '', component: RouterOutletComponent },
{ {
path: 'parentWithLayout', path: 'parentWithLayout',
component: DynamicLayoutComponent, component: DynamicLayoutComponent,
children: [ children: [
{ {
path: 'childWithoutLayout', path: 'childWithoutLayout',
component: DummyComponent, component: DummyComponent,
data: { name: 'childWithoutLayout' }, data: { name: 'childWithoutLayout' },
}, },
{ {
path: 'childWithLayout', path: 'childWithLayout',
component: DummyComponent, component: DummyComponent,
data: { name: 'childWithLayout' }, data: { name: 'childWithLayout' },
}, },
], ],
}, },
{ {
path: 'withData', path: 'withData',
component: DynamicLayoutComponent, component: DynamicLayoutComponent,
children: [ children: [
{ {
path: '', path: '',
component: DummyComponent, component: DummyComponent,
data: { name: 'withData' }, data: { name: 'withData' },
}, },
], ],
data: { layout: eLayoutType.empty }, data: { layout: eLayoutType.empty },
}, },
{ {
path: 'withoutLayout', path: 'withoutLayout',
component: DynamicLayoutComponent, component: DynamicLayoutComponent,
children: [ children: [
{ {
path: '', path: '',
component: DummyComponent, component: DummyComponent,
data: { name: 'withoutLayout' }, data: { name: 'withoutLayout' },
}, },
], ],
data: { layout: null }, data: { layout: null },
}, },
], ],
}); });
let spectator: SpectatorRouting<RouterOutletComponent>; let spectator: SpectatorRouting<RouterOutletComponent>;
let replaceableComponents: ReplaceableComponentsService; let replaceableComponents: ReplaceableComponentsService;
beforeEach(async () => { beforeEach(async () => {
spectator = createComponent(); spectator = createComponent();
replaceableComponents = spectator.inject(ReplaceableComponentsService); replaceableComponents = spectator.inject(ReplaceableComponentsService);
const routesService = spectator.inject(RoutesService); const routesService = spectator.inject(RoutesService);
routesService.add(routes); routesService.add(routes);
replaceableComponents.add({ replaceableComponents.add({
key: 'Theme.ApplicationLayoutComponent', key: 'Theme.ApplicationLayoutComponent',
component: DummyApplicationLayoutComponent, component: DummyApplicationLayoutComponent,
}); });
replaceableComponents.add({ replaceableComponents.add({
key: 'Theme.AccountLayoutComponent', key: 'Theme.AccountLayoutComponent',
component: DummyAccountLayoutComponent, component: DummyAccountLayoutComponent,
}); });
replaceableComponents.add({ replaceableComponents.add({
key: 'Theme.EmptyLayoutComponent', key: 'Theme.EmptyLayoutComponent',
component: DummyEmptyLayoutComponent, component: DummyEmptyLayoutComponent,
}); });
}); });
it('should handle application layout from parent abp route and display it', async () => { it('should handle application layout from parent abp route and display it', async () => {
spectator.router.navigateByUrl('/parentWithLayout/childWithoutLayout'); spectator.router.navigateByUrl('/parentWithLayout/childWithoutLayout');
await spectator.fixture.whenStable(); await spectator.fixture.whenStable();
spectator.detectComponentChanges(); spectator.detectComponentChanges();
expect(spectator.query('abp-dynamic-layout')).toBeTruthy(); expect(spectator.query('abp-dynamic-layout')).toBeTruthy();
expect(spectator.query('abp-layout-application')).toBeTruthy(); expect(spectator.query('abp-layout-application')).toBeTruthy();
}); });
it('should handle account layout from own property and display it', async () => { it('should handle account layout from own property and display it', async () => {
spectator.router.navigateByUrl('/parentWithLayout/childWithLayout'); spectator.router.navigateByUrl('/parentWithLayout/childWithLayout');
await spectator.fixture.whenStable(); await spectator.fixture.whenStable();
spectator.detectComponentChanges(); spectator.detectComponentChanges();
expect(spectator.query('abp-layout-account')).toBeTruthy(); expect(spectator.query('abp-layout-account')).toBeTruthy();
}); });
it('should handle empty layout from route data and display it', async () => { it('should handle empty layout from route data and display it', async () => {
spectator.router.navigateByUrl('/withData'); spectator.router.navigateByUrl('/withData');
await spectator.fixture.whenStable(); await spectator.fixture.whenStable();
spectator.detectComponentChanges(); spectator.detectComponentChanges();
expect(spectator.query('abp-layout-empty')).toBeTruthy(); expect(spectator.query('abp-layout-empty')).toBeTruthy();
}); });
it('should display empty layout when layout is null', async () => { it('should display empty layout when layout is null', async () => {
spectator.router.navigateByUrl('/withoutLayout'); spectator.router.navigateByUrl('/withoutLayout');
await spectator.fixture.whenStable(); await spectator.fixture.whenStable();
spectator.detectComponentChanges(); spectator.detectComponentChanges();
expect(spectator.query('abp-layout-empty')).toBeTruthy(); expect(spectator.query('abp-layout-empty')).toBeTruthy();
}); });
it('should not display any layout when layouts are empty', async () => { it('should not display any layout when layouts are empty', async () => {
const spy = jest.spyOn(replaceableComponents, 'get'); const spy = jest.spyOn(replaceableComponents, 'get');
spy.mockReturnValue(null); spy.mockReturnValue(null);
spectator.detectChanges(); spectator.detectChanges();
spectator.router.navigateByUrl('/withoutLayout'); spectator.router.navigateByUrl('/withoutLayout');
await spectator.fixture.whenStable(); await spectator.fixture.whenStable();
spectator.detectComponentChanges(); spectator.detectComponentChanges();
expect(spectator.query('abp-layout-empty')).toBeFalsy(); 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 { Component, EventEmitter, Input, Output, inject } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { ReplaceableTemplateDirective } from '../directives/replaceable-template.directive'; import { ReplaceableTemplateDirective } from '../directives/replaceable-template.directive';
import { ReplaceableComponents } from '../models/replaceable-components'; import { ReplaceableComponents } from '../models/replaceable-components';
import { ReplaceableComponentsService } from '../services/replaceable-components.service'; import { ReplaceableComponentsService } from '../services/replaceable-components.service';
@Component({ @Component({
selector: 'abp-default-component', selector: 'abp-default-component',
template: ' <p>default</p> ', template: ' <p>default</p> ',
exportAs: 'abpDefaultComponent', exportAs: 'abpDefaultComponent',
}) })
class DefaultComponent { class DefaultComponent {
@Input() @Input()
oneWay; oneWay;
@Input() @Input()
twoWay: boolean; twoWay: boolean;
@Output() @Output()
readonly twoWayChange = new EventEmitter<boolean>(); readonly twoWayChange = new EventEmitter<boolean>();
@Output() @Output()
readonly someOutput = new EventEmitter<string>(); readonly someOutput = new EventEmitter<string>();
setTwoWay(value) { setTwoWay(value) {
this.twoWay = value; this.twoWay = value;
this.twoWayChange.emit(value); this.twoWayChange.emit(value);
} }
} }
@Component({ @Component({
selector: 'abp-external-component', selector: 'abp-external-component',
template: ' <p>external</p> ', template: ' <p>external</p> ',
}) })
class ExternalComponent { class ExternalComponent { data = inject<ReplaceableComponents.ReplaceableTemplateData<any, any>>('REPLACEABLE_DATA' as any, { optional: true })!;
constructor(
@Optional() }
@Inject('REPLACEABLE_DATA')
public data: ReplaceableComponents.ReplaceableTemplateData<any, any>, describe('ReplaceableTemplateDirective', () => {
) {} let spectator: SpectatorDirective<ReplaceableTemplateDirective>;
} const get$Res = new BehaviorSubject(undefined);
describe('ReplaceableTemplateDirective', () => { const createDirective = createDirectiveFactory({
let spectator: SpectatorDirective<ReplaceableTemplateDirective>; directive: ReplaceableTemplateDirective,
const get$Res = new BehaviorSubject(undefined); declarations: [DefaultComponent, ExternalComponent],
entryComponents: [ExternalComponent],
const createDirective = createDirectiveFactory({ mocks: [Router],
directive: ReplaceableTemplateDirective, providers: [{ provide: ReplaceableComponentsService, useValue: { get$: () => get$Res } }],
declarations: [DefaultComponent, ExternalComponent], });
entryComponents: [ExternalComponent],
mocks: [Router], describe('without external component', () => {
providers: [{ provide: ReplaceableComponentsService, useValue: { get$: () => get$Res } }], const twoWayChange = jest.fn(a => a);
}); const someOutput = jest.fn(a => a);
describe('without external component', () => { beforeEach(() => {
const twoWayChange = jest.fn(a => a); spectator = createDirective(
const someOutput = jest.fn(a => a); `
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate">
beforeEach(() => { <abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component>
spectator = createDirective( </div>
` `,
<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> hostProps: {
</div> oneWay: { label: 'Test' },
`, twoWay: false,
{ twoWayChange,
hostProps: { someOutput,
oneWay: { label: 'Test' }, },
twoWay: false, },
twoWayChange, );
someOutput,
}, const component = spectator.query(DefaultComponent);
}, spectator.directive.context.initTemplate(component);
); spectator.detectChanges();
});
const component = spectator.query(DefaultComponent);
spectator.directive.context.initTemplate(component); afterEach(() => twoWayChange.mockClear());
spectator.detectChanges();
}); it('should display the default template when store response is undefined', () => {
expect(spectator.query('abp-default-component')).toBeTruthy();
afterEach(() => twoWayChange.mockClear()); });
it('should display the default template when store response is undefined', () => { it('should be setted inputs and outputs', () => {
expect(spectator.query('abp-default-component')).toBeTruthy(); const component = spectator.query(DefaultComponent);
}); expect(component.oneWay).toEqual({ label: 'Test' });
expect(component.twoWay).toEqual(false);
it('should be setted inputs and outputs', () => { });
const component = spectator.query(DefaultComponent);
expect(component.oneWay).toEqual({ label: 'Test' }); it('should change the component inputs', () => {
expect(component.twoWay).toEqual(false); const component = spectator.query(DefaultComponent);
}); spectator.setHostInput({ oneWay: 'test' });
component.setTwoWay(true);
it('should change the component inputs', () => { component.someOutput.emit('someOutput emitted');
const component = spectator.query(DefaultComponent); expect(component.oneWay).toBe('test');
spectator.setHostInput({ oneWay: 'test' }); expect(twoWayChange).toHaveBeenCalledWith(true);
component.setTwoWay(true); expect(someOutput).toHaveBeenCalledWith('someOutput emitted');
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);
describe('with external component', () => { beforeEach(() => {
const twoWayChange = jest.fn(a => a); spectator = createDirective(
const someOutput = jest.fn(a => a); `
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate">
beforeEach(() => { <abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component>
spectator = createDirective( </div>
` `,
<div *abpReplaceableTemplate="{inputs: {oneWay: {value: oneWay}, twoWay: {value: twoWay, twoWay: true}}, outputs: {twoWayChange: twoWayChange, someOutput: someOutput}, componentKey: 'TestModule.TestComponent'}; let initTemplate = initTemplate"> { hostProps: { oneWay: { label: 'Test' }, twoWay: false, twoWayChange, someOutput } },
<abp-default-component #defaultComponent="abpDefaultComponent"></abp-default-component> );
</div>
`, get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' });
{ hostProps: { oneWay: { label: 'Test' }, twoWay: false, twoWayChange, someOutput } }, });
);
afterEach(() => twoWayChange.mockClear());
get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' });
}); it('should display the external component', () => {
expect(spectator.query('p')).toHaveText('external');
afterEach(() => twoWayChange.mockClear()); });
it('should display the external component', () => { it('should be injected the data object', () => {
expect(spectator.query('p')).toHaveText('external'); const externalComponent = spectator.query(ExternalComponent);
}); expect(externalComponent.data).toEqual({
componentKey: 'TestModule.TestComponent',
it('should be injected the data object', () => { inputs: { oneWay: { label: 'Test' }, twoWay: false },
const externalComponent = spectator.query(ExternalComponent); outputs: { someOutput, twoWayChange },
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;
it('should be worked all data properties', () => { externalComponent.data.outputs.someOutput('someOutput emitted');
const externalComponent = spectator.query(ExternalComponent); expect(externalComponent.data.inputs.oneWay).toBe('test');
spectator.setHostInput({ oneWay: 'test' }); expect(twoWayChange).toHaveBeenCalledWith(true);
externalComponent.data.inputs.twoWay = true; expect(someOutput).toHaveBeenCalledWith('someOutput emitted');
externalComponent.data.outputs.someOutput('someOutput emitted');
expect(externalComponent.data.inputs.oneWay).toBe('test'); spectator.setHostInput({ twoWay: 'twoWay test' });
expect(twoWayChange).toHaveBeenCalledWith(true); expect(externalComponent.data.inputs.twoWay).toBe('twoWay test');
expect(someOutput).toHaveBeenCalledWith('someOutput emitted'); });
spectator.setHostInput({ twoWay: 'twoWay test' }); it('should be worked correctly the default component when the external component has been removed from store', () => {
expect(externalComponent.data.inputs.twoWay).toBe('twoWay test'); expect(spectator.query('p')).toHaveText('external');
}); const externalComponent = spectator.query(ExternalComponent);
spectator.setHostInput({ oneWay: 'test' });
it('should be worked correctly the default component when the external component has been removed from store', () => { externalComponent.data.inputs.twoWay = true;
expect(spectator.query('p')).toHaveText('external'); get$Res.next({ component: null, key: 'TestModule.TestComponent' });
const externalComponent = spectator.query(ExternalComponent); spectator.detectChanges();
spectator.setHostInput({ oneWay: 'test' }); const component = spectator.query(DefaultComponent);
externalComponent.data.inputs.twoWay = true; spectator.directive.context.initTemplate(component);
get$Res.next({ component: null, key: 'TestModule.TestComponent' }); expect(spectator.query('abp-default-component')).toBeTruthy();
spectator.detectChanges();
const component = spectator.query(DefaultComponent); expect(component.oneWay).toEqual('test');
spectator.directive.context.initTemplate(component); expect(component.twoWay).toEqual(true);
expect(spectator.query('abp-default-component')).toBeTruthy(); });
expect(component.oneWay).toEqual('test'); it('should reset default component subscriptions', () => {
expect(component.twoWay).toEqual(true); get$Res.next({ component: null, key: 'TestModule.TestComponent' });
}); const component = spectator.query(DefaultComponent);
spectator.directive.context.initTemplate(component);
it('should reset default component subscriptions', () => { spectator.detectChanges();
get$Res.next({ component: null, key: 'TestModule.TestComponent' }); const unsubscribe = jest.fn(() => {});
const component = spectator.query(DefaultComponent); spectator.directive.defaultComponentSubscriptions.twoWayChange.unsubscribe = unsubscribe;
spectator.directive.context.initTemplate(component);
spectator.detectChanges(); get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' });
const unsubscribe = jest.fn(() => {}); expect(unsubscribe).toHaveBeenCalled();
spectator.directive.defaultComponentSubscriptions.twoWayChange.unsubscribe = unsubscribe; });
});
get$Res.next({ component: ExternalComponent, key: 'TestModule.TestComponent' }); });
expect(unsubscribe).toHaveBeenCalled();
});
});
});

10
npm/ng-packs/packages/core/testing/src/lib/services/mock-permission.service.ts

@ -1,12 +1,18 @@
import { ConfigStateService, PermissionService } from '@abp/ng.core'; import { ConfigStateService, PermissionService } from '@abp/ng.core';
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class MockPermissionService extends PermissionService { export class MockPermissionService extends PermissionService {
constructor(protected configState: ConfigStateService) { protected configState: ConfigStateService;
constructor() {
const configState = inject(ConfigStateService);
super(configState); super(configState);
this.configState = configState;
this.grantAllPolicies(); this.grantAllPolicies();
} }

24
npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts

@ -7,20 +7,30 @@ import {
RestService, RestService,
} from '@abp/ng.core'; } from '@abp/ng.core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable, throwError } from 'rxjs'; import { Observable, throwError } from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class MockRestService extends RestService { export class MockRestService extends RestService {
constructor( protected options: ABP.Root;
@Inject(CORE_OPTIONS) protected options: ABP.Root, protected http: HttpClient;
protected http: HttpClient, protected externalhttp: ExternalHttpClient;
protected externalhttp: ExternalHttpClient, protected environment: EnvironmentService;
protected environment: EnvironmentService,
) { constructor() {
const options = inject<ABP.Root>(CORE_OPTIONS);
const http = inject(HttpClient);
const externalhttp = inject(ExternalHttpClient);
const environment = inject(EnvironmentService);
super(options, http,externalhttp, environment, null as unknown as HttpErrorReporterService); super(options, http,externalhttp, environment, null as unknown as HttpErrorReporterService);
this.options = options;
this.http = http;
this.externalhttp = externalhttp;
this.environment = environment;
} }
handleError(err: any): Observable<any> { handleError(err: any): Observable<any> {

Loading…
Cancel
Save