From e646718fbe60a372893b94e88c9e142dd5a3fb60 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 11:03:37 +0300 Subject: [PATCH 01/20] - add wait services - remove ngxs from api interceptor and loader-bar component - remove filter input from loader bar component --- .../src/lib/interceptors/api.interceptor.ts | 10 ++-- .../src/lib/services/http-wait.service.ts | 44 +++++++++++++++ .../packages/core/src/lib/services/index.ts | 2 + .../src/lib/services/lazy-load.service.ts | 10 +++- .../src/lib/services/resource-wait.service.ts | 41 ++++++++++++++ .../src/lib/services/router-wait.service.ts | 53 +++++++++++++++++++ .../loader-bar/loader-bar.component.ts | 51 ++++++------------ 7 files changed, 168 insertions(+), 43 deletions(-) create mode 100644 npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts create mode 100644 npm/ng-packs/packages/core/src/lib/services/resource-wait.service.ts create mode 100644 npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts diff --git a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts b/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts index a2b08c07db..ad60178a98 100644 --- a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts +++ b/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts @@ -1,10 +1,9 @@ import { HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Store } from '@ngxs/store'; import { OAuthService } from 'angular-oauth2-oidc'; import { finalize } from 'rxjs/operators'; -import { StartLoader, StopLoader } from '../actions/loader.actions'; import { SessionStateService } from '../services/session-state.service'; +import { HttpWaitService } from '../services/http-wait.service'; @Injectable({ providedIn: 'root', @@ -12,20 +11,19 @@ import { SessionStateService } from '../services/session-state.service'; export class ApiInterceptor implements HttpInterceptor { constructor( private oAuthService: OAuthService, - private store: Store, private sessionState: SessionStateService, + private httpWaitService: HttpWaitService, ) {} intercept(request: HttpRequest, next: HttpHandler) { - this.store.dispatch(new StartLoader(request)); - + this.httpWaitService.addRequest(request); return next .handle( request.clone({ setHeaders: this.getAdditionalHeaders(request.headers), }), ) - .pipe(finalize(() => this.store.dispatch(new StopLoader(request)))); + .pipe(finalize(() => this.httpWaitService.deleteRequest(request))); } getAdditionalHeaders(existingHeaders?: HttpHeaders) { diff --git a/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts b/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts new file mode 100644 index 0000000000..96427594ae --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/http-wait.service.ts @@ -0,0 +1,44 @@ +import { Injectable } from '@angular/core'; +import { HttpRequest } from '@angular/common/http'; +import { InternalStore } from '../utils/internal-store-utils'; + +export interface HttpWaitState { + requests: Set>; +} + +@Injectable({ + providedIn: 'root', +}) +export class HttpWaitService { + protected store = new InternalStore({ requests: new Set() }); + + getLoading() { + return !!this.store.state.requests.size; + } + + getLoading$() { + return this.store.sliceState(({ requests }) => !!requests.size); + } + + updateLoading$() { + return this.store.sliceUpdate(({ requests }) => !!requests.size); + } + + clearLoading() { + this.store.patch({ requests: new Set() }); + } + + addRequest(request: HttpRequest) { + const requests = this.store.state.requests; + requests.add(request); + this.store.patch({ requests }); + } + + deleteRequest(request: HttpRequest) { + const requests = this.store.state.requests; + requests.delete(request); + this.store.patch({ requests }); + } + + // TODO: Add filter function +} diff --git a/npm/ng-packs/packages/core/src/lib/services/index.ts b/npm/ng-packs/packages/core/src/lib/services/index.ts index 5b294c4905..47b146ea9f 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -4,6 +4,7 @@ export * from './config-state.service'; export * from './content-projection.service'; export * from './dom-insertion.service'; export * from './environment.service'; +export * from './http-wait.service'; export * from './lazy-load.service'; export * from './list.service'; export * from './localization.service'; @@ -13,6 +14,7 @@ export * from './profile-state.service'; export * from './profile.service'; export * from './replaceable-components.service'; export * from './rest.service'; +export * from './router-wait.service'; export * from './routes.service'; export * from './session-state.service'; export * from './subscription.service'; diff --git a/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts b/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts index 5d44bb0879..0aca94c94a 100644 --- a/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'; import { concat, Observable, of, throwError } from 'rxjs'; import { delay, retryWhen, shareReplay, take, tap } from 'rxjs/operators'; import { LoadingStrategy } from '../strategies'; +import { ResourceWaitService } from './resource-wait.service'; @Injectable({ providedIn: 'root', @@ -9,9 +10,11 @@ import { LoadingStrategy } from '../strategies'; export class LazyLoadService { readonly loaded = new Map(); + constructor(private resourceWaitService: ResourceWaitService) {} + load(strategy: LoadingStrategy, retryTimes?: number, retryDelay?: number): Observable { if (this.loaded.has(strategy.path)) return of(new CustomEvent('load')); - + this.resourceWaitService.addResource(strategy.path); return strategy.createStream().pipe( retryWhen(error$ => concat( @@ -19,7 +22,10 @@ export class LazyLoadService { throwError(new CustomEvent('error')), ), ), - tap(() => this.loaded.set(strategy.path, strategy.element)), + tap(() => { + this.loaded.set(strategy.path, strategy.element); + this.resourceWaitService.deleteResource(strategy.path); + }), delay(100), shareReplay({ bufferSize: 1, refCount: true }), ); diff --git a/npm/ng-packs/packages/core/src/lib/services/resource-wait.service.ts b/npm/ng-packs/packages/core/src/lib/services/resource-wait.service.ts new file mode 100644 index 0000000000..16351837a2 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/resource-wait.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@angular/core'; +import { InternalStore } from '../utils/internal-store-utils'; + +export interface ResourceWaitState { + resources: Set; +} + +@Injectable({ + providedIn: 'root', +}) +export class ResourceWaitService { + private store = new InternalStore({ resources: new Set() }); + + getLoading() { + return !!this.store.state.resources.size; + } + + getLoading$() { + return this.store.sliceState(({ resources }) => !!resources.size); + } + + updateLoading$() { + return this.store.sliceUpdate(({ resources }) => !!resources.size); + } + + clearLoading() { + this.store.patch({ resources: new Set() }); + } + + addResource(resource: string) { + const resources = this.store.state.resources; + resources.add(resource); + this.store.patch({ resources }); + } + + deleteResource(resource: string) { + const resources = this.store.state.resources; + resources.delete(resource); + this.store.patch({ resources }); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts b/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts new file mode 100644 index 0000000000..d1306e63c9 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/router-wait.service.ts @@ -0,0 +1,53 @@ +import { Injectable } from '@angular/core'; +import { + NavigationCancel, + NavigationEnd, + NavigationError, + NavigationStart, + Router, +} from '@angular/router'; +import { filter } from 'rxjs/operators'; +import { InternalStore } from '../utils/internal-store-utils'; + +export interface RouterWaitState { + loading: boolean; +} + +@Injectable({ + providedIn: 'root', +}) +export class RouterWaitService { + private store = new InternalStore({ loading: false }); + constructor(private router: Router) { + this.router.events + .pipe( + filter( + event => + event instanceof NavigationStart || + event instanceof NavigationEnd || + event instanceof NavigationError || + event instanceof NavigationCancel, + ), + ) + .subscribe(event => { + if (event instanceof NavigationStart) this.setLoading(true); + else this.setLoading(false); + }); + } + + getLoading() { + return this.store.state.loading; + } + + getLoading$() { + return this.store.sliceState(({ loading }) => loading); + } + + updateLoading$() { + return this.store.sliceUpdate(({ loading }) => loading); + } + + setLoading(loading: boolean) { + this.store.patch({ loading }); + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts index f94b6b3656..729a844440 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts @@ -1,9 +1,9 @@ -import { StartLoader, StopLoader, SubscriptionService } from '@abp/ng.core'; +import { SubscriptionService } from '@abp/ng.core'; import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router'; -import { Actions, ofActionSuccessful } from '@ngxs/store'; -import { Subscription, timer } from 'rxjs'; -import { filter } from 'rxjs/operators'; +import { Router } from '@angular/router'; +import { combineLatest, Subscription, timer } from 'rxjs'; +import { RouterWaitService } from '../../../../../core/src/lib/services/router-wait.service'; +import { HttpWaitService } from '../../../../../core/src/lib/services/http-wait.service'; @Component({ selector: 'abp-loader-bar', @@ -51,10 +51,6 @@ export class LoaderBarComponent implements OnDestroy, OnInit { stopDelay = 800; - @Input() - filter = (action: StartLoader | StopLoader) => - action.payload.url.indexOf('openid-configuration') < 0; - private readonly clearProgress = () => { this.progressLevel = 0; this.cdRef.detectChanges(); @@ -78,44 +74,27 @@ export class LoaderBarComponent implements OnDestroy, OnInit { } constructor( - private actions: Actions, private router: Router, private cdRef: ChangeDetectorRef, private subscription: SubscriptionService, + private httpWaitService: HttpWaitService, + private routerWaiterService: RouterWaitService, ) {} - private subscribeToLoadActions() { - this.subscription.addOne( - this.actions.pipe(ofActionSuccessful(StartLoader, StopLoader), filter(this.filter)), - action => { - if (action instanceof StartLoader) this.startLoading(); - else this.stopLoading(); - }, - ); + ngOnInit() { + this.subscribeLoading(); } - private subscribeToRouterEvents() { + subscribeLoading() { this.subscription.addOne( - this.router.events.pipe( - filter( - event => - event instanceof NavigationStart || - event instanceof NavigationEnd || - event instanceof NavigationError, - ), - ), - event => { - if (event instanceof NavigationStart) this.startLoading(); + combineLatest([this.httpWaitService.getLoading$(), this.routerWaiterService.getLoading$()]), + ([httpLoading, routerLoading]) => { + if (httpLoading || routerLoading) this.startLoading(); else this.stopLoading(); }, ); } - ngOnInit() { - this.subscribeToLoadActions(); - this.subscribeToRouterEvents(); - } - ngOnDestroy() { if (this.interval) this.interval.unsubscribe(); } @@ -124,8 +103,10 @@ export class LoaderBarComponent implements OnDestroy, OnInit { if (this.isLoading || (this.interval && !this.interval.closed)) return; this.isLoading = true; - + this.progressLevel = 0; this.interval = timer(0, this.intervalPeriod).subscribe(this.reportProgress); + this.timer.unsubscribe(); + this.cdRef.detectChanges(); } stopLoading() { From 57f5205228c597708b13e77f5f9800944eef5fb4 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 11:05:54 +0300 Subject: [PATCH 02/20] - add resource-waiter service to index --- npm/ng-packs/packages/core/src/lib/services/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/npm/ng-packs/packages/core/src/lib/services/index.ts b/npm/ng-packs/packages/core/src/lib/services/index.ts index 47b146ea9f..37bc78d606 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -13,6 +13,7 @@ export * from './permission.service'; export * from './profile-state.service'; export * from './profile.service'; export * from './replaceable-components.service'; +export * from './resource-wait.service'; export * from './rest.service'; export * from './router-wait.service'; export * from './routes.service'; From e30f08e6d521966fda6bab0c04457b85f2986825 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 11:08:45 +0300 Subject: [PATCH 03/20] - remove detect changes --- .../src/lib/components/loader-bar/loader-bar.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts index 729a844440..a3afd9fba0 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts @@ -106,7 +106,6 @@ export class LoaderBarComponent implements OnDestroy, OnInit { this.progressLevel = 0; this.interval = timer(0, this.intervalPeriod).subscribe(this.reportProgress); this.timer.unsubscribe(); - this.cdRef.detectChanges(); } stopLoading() { From b4bcc2519a0a3602495f9d937af07b8c4a698e00 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 11:23:03 +0300 Subject: [PATCH 04/20] - service import fix --- .../src/lib/components/loader-bar/loader-bar.component.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts index a3afd9fba0..62f3c077b6 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts @@ -1,9 +1,7 @@ -import { SubscriptionService } from '@abp/ng.core'; +import { SubscriptionService, HttpWaitService, RouterWaitService } from '@abp/ng.core'; import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { combineLatest, Subscription, timer } from 'rxjs'; -import { RouterWaitService } from '../../../../../core/src/lib/services/router-wait.service'; -import { HttpWaitService } from '../../../../../core/src/lib/services/http-wait.service'; @Component({ selector: 'abp-loader-bar', From a0a1a1c8c9d38f08b0fdbe97731aa3d945b68e02 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 11:23:44 +0300 Subject: [PATCH 05/20] - fix import order --- .../src/lib/components/loader-bar/loader-bar.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts index 62f3c077b6..b0d626cf71 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts @@ -1,4 +1,4 @@ -import { SubscriptionService, HttpWaitService, RouterWaitService } from '@abp/ng.core'; +import { HttpWaitService, RouterWaitService, SubscriptionService } from '@abp/ng.core'; import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { combineLatest, Subscription, timer } from 'rxjs'; From a5cc3375f527d8e26656f465da116b8bfcc21c65 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Thu, 24 Dec 2020 12:29:22 +0300 Subject: [PATCH 06/20] Fix databaseProvider parameter of thanks page url --- .../src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index 75d2651cbc..b76d4de5b5 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -208,6 +208,7 @@ namespace Volo.Abp.Cli.Commands private void OpenThanksPage(UiFramework uiFramework, DatabaseProvider databaseProvider, bool tiered, bool commercial) { uiFramework = uiFramework == UiFramework.NotSpecified || uiFramework == UiFramework.None ? UiFramework.Mvc : uiFramework; + databaseProvider = databaseProvider == DatabaseProvider.NotSpecified ? DatabaseProvider.EntityFrameworkCore : databaseProvider; var urlPrefix = commercial ? "commercial" : "www"; var tieredYesNo = tiered ? "yes" : "no"; From cba06c2afb8e855a699617c0c86e82f29eb86669 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 14:54:18 +0300 Subject: [PATCH 07/20] - fix tests --- .../src/lib/tests/api.interceptor.spec.ts | 19 ++++++++------- .../src/lib/tests/lazy-load.service.spec.ts | 7 ++++-- .../lib/tests/loader-bar.component.spec.ts | 23 ++++++++----------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/tests/api.interceptor.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/api.interceptor.spec.ts index ed42194755..ab289ddd9a 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/api.interceptor.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/api.interceptor.spec.ts @@ -1,31 +1,29 @@ import { HttpRequest } from '@angular/common/http'; import { SpyObject } from '@ngneat/spectator'; import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest'; -import { Store } from '@ngxs/store'; import { OAuthService } from 'angular-oauth2-oidc'; import { Subject, timer } from 'rxjs'; -import { StartLoader, StopLoader } from '../actions'; import { ApiInterceptor } from '../interceptors'; -import { SessionStateService } from '../services'; +import { HttpWaitService, SessionStateService } from '../services'; describe('ApiInterceptor', () => { let spectator: SpectatorService; let interceptor: ApiInterceptor; - let store: SpyObject; let oauthService: SpyObject; let sessionState: SpyObject; + let httpWaitService: SpyObject; const createService = createServiceFactory({ service: ApiInterceptor, - mocks: [OAuthService, Store, SessionStateService], + mocks: [OAuthService, SessionStateService], }); beforeEach(() => { spectator = createService(); interceptor = spectator.service; - store = spectator.inject(Store); sessionState = spectator.inject(SessionStateService); oauthService = spectator.inject(OAuthService); + httpWaitService = spectator.inject(HttpWaitService); }); it('should add headers to http request', done => { @@ -52,8 +50,9 @@ describe('ApiInterceptor', () => { handleRes$.complete(); }); - it('should dispatch the loader', done => { - const spy = jest.spyOn(store, 'dispatch'); + it('should call http wait services add request and delete request', done => { + const spyAddRequest = jest.spyOn(httpWaitService, 'addRequest'); + const spyDeleteRequest = jest.spyOn(httpWaitService, 'deleteRequest'); const request = new HttpRequest('GET', 'https://abp.io'); const handleRes$ = new Subject(); @@ -70,8 +69,8 @@ describe('ApiInterceptor', () => { handleRes$.complete(); timer(0).subscribe(() => { - expect(spy.mock.calls[0][0] instanceof StartLoader).toBeTruthy(); - expect(spy.mock.calls[1][0] instanceof StopLoader).toBeTruthy(); + expect(spyAddRequest).toHaveBeenCalled(); + expect(spyDeleteRequest).toHaveBeenCalled(); done(); }); }); diff --git a/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts index dc4d937f17..eb347be80a 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/lazy-load.service.spec.ts @@ -2,10 +2,12 @@ import { of, throwError } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { LazyLoadService } from '../services/lazy-load.service'; import { ScriptLoadingStrategy } from '../strategies'; +import { ResourceWaitService } from '../services'; describe('LazyLoadService', () => { describe('#load', () => { - const service = new LazyLoadService(); + const resourceWaitService = new ResourceWaitService(); + const service = new LazyLoadService(resourceWaitService); const strategy = new ScriptLoadingStrategy('http://example.com/'); afterEach(() => { @@ -58,7 +60,8 @@ describe('LazyLoadService', () => { }); describe('#remove', () => { - const service = new LazyLoadService(); + const resourceWaitService = new ResourceWaitService(); + const service = new LazyLoadService(resourceWaitService); it('should remove an already lazy loaded element and return true', () => { const script = document.createElement('script'); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts index 894b5f60d1..00a823f860 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts @@ -1,16 +1,10 @@ -import { - Router, - RouteReuseStrategy, - NavigationStart, - NavigationEnd, - NavigationError, -} from '@angular/router'; +import { NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router'; import { createHostFactory, SpectatorHost, SpyObject } from '@ngneat/spectator/jest'; -import { Actions, NgxsModule, Store } from '@ngxs/store'; -import { Subject, Subscription, Observable, Subscriber, timer } from 'rxjs'; +import { Subject, Subscription, timer } from 'rxjs'; import { LoaderBarComponent } from '../components/loader-bar/loader-bar.component'; -import { StartLoader, StopLoader, SubscriptionService } from '@abp/ng.core'; +import { SubscriptionService } from '@abp/ng.core'; import { HttpRequest } from '@angular/common/http'; +import { HttpWaitService } from '../../../../core/src/lib/services'; describe('LoaderBarComponent', () => { let spectator: SpectatorHost; @@ -20,7 +14,6 @@ describe('LoaderBarComponent', () => { const createHost = createHostFactory({ component: LoaderBarComponent, mocks: [Router], - imports: [NgxsModule.forRoot()], detectChanges: false, providers: [SubscriptionService], }); @@ -41,7 +34,8 @@ describe('LoaderBarComponent', () => { it('should increase the progressLevel', done => { spectator.detectChanges(); - spectator.inject(Store).dispatch(new StartLoader(new HttpRequest('GET', 'test'))); + const httpWaitService = spectator.inject(HttpWaitService); + httpWaitService.addRequest(new HttpRequest('GET', 'test')); spectator.detectChanges(); setTimeout(() => { expect(spectator.component.progressLevel > 0).toBeTruthy(); @@ -51,7 +45,8 @@ describe('LoaderBarComponent', () => { test.skip('should be interval unsubscribed', done => { spectator.detectChanges(); - spectator.inject(Store).dispatch(new StartLoader(new HttpRequest('GET', 'test'))); + const httpWaitService = spectator.inject(HttpWaitService); + httpWaitService.addRequest(new HttpRequest('GET', 'test')); expect(spectator.component.interval.closed).toBe(false); timer(400).subscribe(() => { @@ -80,7 +75,7 @@ describe('LoaderBarComponent', () => { (router as any).events.next(new NavigationStart(1, 'test')); expect(spectator.component.interval.closed).toBe(false); - spectator.inject(Store).dispatch(new StopLoader(new HttpRequest('GET', 'test'))); + (router as any).events.next(new NavigationEnd(1, 'testend', 'testend')); expect(spectator.component.progressLevel).toBe(100); timer(2).subscribe(() => { From 245f59b5a7dcf5d93643efe5f75048f1fa1edf9b Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Thu, 24 Dec 2020 15:42:22 +0300 Subject: [PATCH 08/20] - fix tests --- .../loader-bar/loader-bar.component.ts | 12 +++---- .../lib/tests/loader-bar.component.spec.ts | 32 ++++++++----------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts index b0d626cf71..1700efafe2 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts @@ -41,9 +41,9 @@ export class LoaderBarComponent implements OnDestroy, OnInit { progressLevel = 0; - interval: Subscription; + interval = new Subscription(); - timer: Subscription; + timer = new Subscription(); intervalPeriod = 350; @@ -94,11 +94,11 @@ export class LoaderBarComponent implements OnDestroy, OnInit { } ngOnDestroy() { - if (this.interval) this.interval.unsubscribe(); + this.interval.unsubscribe(); } startLoading() { - if (this.isLoading || (this.interval && !this.interval.closed)) return; + if (this.isLoading || !this.interval.closed) return; this.isLoading = true; this.progressLevel = 0; @@ -107,12 +107,12 @@ export class LoaderBarComponent implements OnDestroy, OnInit { } stopLoading() { - if (this.interval) this.interval.unsubscribe(); + this.interval.unsubscribe(); this.progressLevel = 100; this.isLoading = false; - if (this.timer && !this.timer.closed) return; + if (!this.timer.closed) return; this.timer = timer(this.stopDelay).subscribe(this.clearProgress); } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts index 00a823f860..6d1ab85a46 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/loader-bar.component.spec.ts @@ -1,33 +1,29 @@ import { NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router'; -import { createHostFactory, SpectatorHost, SpyObject } from '@ngneat/spectator/jest'; -import { Subject, Subscription, timer } from 'rxjs'; +import { createComponentFactory, Spectator, SpyObject } from '@ngneat/spectator/jest'; +import { Subject, timer } from 'rxjs'; import { LoaderBarComponent } from '../components/loader-bar/loader-bar.component'; -import { SubscriptionService } from '@abp/ng.core'; +import { HttpWaitService, SubscriptionService } from '@abp/ng.core'; import { HttpRequest } from '@angular/common/http'; -import { HttpWaitService } from '../../../../core/src/lib/services'; describe('LoaderBarComponent', () => { - let spectator: SpectatorHost; + let spectator: Spectator; let router: SpyObject; const events$ = new Subject(); - const createHost = createHostFactory({ + const createComponent = createComponentFactory({ component: LoaderBarComponent, - mocks: [Router], detectChanges: false, - providers: [SubscriptionService], + providers: [SubscriptionService, { provide: Router, useValue: { events: events$ } }], }); beforeEach(() => { - spectator = createHost(''); + spectator = createComponent({}); spectator.component.intervalPeriod = 1; spectator.component.stopDelay = 1; router = spectator.inject(Router); - (router as any).events = events$; }); it('should initial variable values are correct', () => { - spectator.component.interval = new Subscription(); expect(spectator.component.containerClass).toBe('abp-loader-bar'); expect(spectator.component.color).toBe('#77b6ff'); }); @@ -57,11 +53,11 @@ describe('LoaderBarComponent', () => { it('should start and stop the loading with navigation', done => { spectator.detectChanges(); - (router as any).events.next(new NavigationStart(1, 'test')); + events$.next(new NavigationStart(1, 'test')); expect(spectator.component.interval.closed).toBe(false); - (router as any).events.next(new NavigationEnd(1, 'test', 'test')); - (router as any).events.next(new NavigationError(1, 'test', 'test')); + events$.next(new NavigationEnd(1, 'test', 'test')); + events$.next(new NavigationError(1, 'test', 'test')); expect(spectator.component.progressLevel).toBe(100); timer(2).subscribe(() => { @@ -72,10 +68,10 @@ describe('LoaderBarComponent', () => { it('should stop the loading with navigation', done => { spectator.detectChanges(); - (router as any).events.next(new NavigationStart(1, 'test')); + events$.next(new NavigationStart(1, 'test')); expect(spectator.component.interval.closed).toBe(false); - (router as any).events.next(new NavigationEnd(1, 'testend', 'testend')); + events$.next(new NavigationEnd(1, 'testend', 'testend')); expect(spectator.component.progressLevel).toBe(100); timer(2).subscribe(() => { @@ -87,8 +83,8 @@ describe('LoaderBarComponent', () => { describe('#startLoading', () => { it('should return when isLoading is true', done => { spectator.detectChanges(); - (router as any).events.next(new NavigationStart(1, 'test')); - (router as any).events.next(new NavigationStart(1, 'test')); + events$.next(new NavigationStart(1, 'test')); + events$.next(new NavigationStart(1, 'test')); done(); }); }); From fbbd40e3cdacc3ba59a88ea7aad3a78d31a79566 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 16:41:44 +0300 Subject: [PATCH 09/20] fix: use string as baseHref type in ABP.Test interface --- npm/ng-packs/packages/core/src/lib/models/common.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/models/common.ts b/npm/ng-packs/packages/core/src/lib/models/common.ts index 88bd75c027..7e828c9d2a 100644 --- a/npm/ng-packs/packages/core/src/lib/models/common.ts +++ b/npm/ng-packs/packages/core/src/lib/models/common.ts @@ -1,5 +1,5 @@ import { EventEmitter, Type } from '@angular/core'; -import { Router, Routes } from '@angular/router'; +import { Routes } from '@angular/router'; import { Subject } from 'rxjs'; import { eLayoutType } from '../enums/common'; import { Environment } from './environment'; @@ -13,7 +13,7 @@ export namespace ABP { } export interface Test extends Partial { - baseHref?: Router; + baseHref?: string; routes?: Routes; } From 02e0ec5989cc363822e95448afb891ef4c26c368 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 16:44:19 +0300 Subject: [PATCH 10/20] use withConfig instead of forTest in CoreTestingModule --- .../packages/core/testing/src/lib/core-testing.module.ts | 2 +- .../theme-shared/src/lib/tests/confirmation.service.spec.ts | 4 ++-- .../packages/theme-shared/src/lib/tests/error.handler.spec.ts | 2 +- .../theme-shared/src/lib/tests/toaster.service.spec.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts b/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts index 5a43aa9a4c..224992ed23 100644 --- a/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts +++ b/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts @@ -21,7 +21,7 @@ import { MockLocalizationPipe } from './pipes/mock-localization.pipe'; declarations: [MockLocalizationPipe], }) export class CoreTestingModule { - static forTest( + static withConfig( { baseHref = '/', routes = [], ...options } = {} as ABP.Test, ): ModuleWithProviders { return { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/confirmation.service.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/confirmation.service.spec.ts index 88813c44de..ab63cb3cb5 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/confirmation.service.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/confirmation.service.spec.ts @@ -13,7 +13,7 @@ import { ConfirmationService } from '../services'; exports: [ConfirmationComponent], entryComponents: [ConfirmationComponent], declarations: [ConfirmationComponent], - imports: [CoreTestingModule.forTest()], + imports: [CoreTestingModule.withConfig()], }) export class MockModule {} @@ -22,7 +22,7 @@ describe('ConfirmationService', () => { let service: ConfirmationService; const createService = createServiceFactory({ service: ConfirmationService, - imports: [NgxsModule.forRoot(), CoreTestingModule.forTest(), MockModule], + imports: [NgxsModule.forRoot(), CoreTestingModule.withConfig(), MockModule], }); beforeEach(() => { diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts index 939f87e5ee..a6908e03bf 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/error.handler.spec.ts @@ -31,7 +31,7 @@ const CONFIRMATION_BUTTONS = { describe('ErrorHandler', () => { const createService = createServiceFactory({ service: ErrorHandler, - imports: [NgxsModule.forRoot([]), CoreTestingModule.forTest(), MockModule], + imports: [NgxsModule.forRoot([]), CoreTestingModule.withConfig(), MockModule], mocks: [OAuthService], providers: [ { provide: APP_BASE_HREF, useValue: '/' }, diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts index fa6e0e578c..ab885726de 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/toaster.service.spec.ts @@ -11,7 +11,7 @@ import { ToasterService } from '../services/toaster.service'; exports: [ToastContainerComponent], entryComponents: [ToastContainerComponent], declarations: [ToastContainerComponent, ToastComponent], - imports: [CoreTestingModule.forTest()], + imports: [CoreTestingModule.withConfig()], }) export class MockModule {} const toastClassPrefix = 'abp-toast'; @@ -21,7 +21,7 @@ describe('ToasterService', () => { let service: ToasterService; const createService = createServiceFactory({ service: ToasterService, - imports: [NgxsModule.forRoot(), CoreTestingModule.forTest(), MockModule], + imports: [NgxsModule.forRoot(), CoreTestingModule.withConfig(), MockModule], }); beforeEach(() => { From 0a98cb6ee1819a924ec488e32fd53c23c8cccff3 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 16:45:27 +0300 Subject: [PATCH 11/20] create a BaseThemeSharedModule --- .../src/lib/theme-shared.module.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index c4647cbcd1..4bafe28925 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -27,7 +27,7 @@ import { initLazyStyleHandler } from './handlers/lazy-style.handler'; import { RootParams } from './models/common'; import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; -import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token'; +import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token'; import { DateParserFormatter } from './utils/date-parser-formatter'; const declarationsWithExports = [ @@ -48,17 +48,11 @@ const declarationsWithExports = [ LoadingDirective, TableSortDirective, ]; + @NgModule({ imports: [CoreModule, NgxDatatableModule, NgxValidateCoreModule, NgbPaginationModule], - declarations: [ - ...declarationsWithExports, - HttpErrorWrapperComponent, - ModalContainerComponent, - ], - exports: [ - NgxDatatableModule, - ...declarationsWithExports, - ], + declarations: [...declarationsWithExports, HttpErrorWrapperComponent, ModalContainerComponent], + exports: [NgxDatatableModule, ...declarationsWithExports], providers: [DatePipe], entryComponents: [ HttpErrorWrapperComponent, @@ -68,6 +62,12 @@ const declarationsWithExports = [ ConfirmationComponent, ], }) +export class BaseThemeSharedModule {} + +@NgModule({ + imports: [BaseThemeSharedModule], + exports: [BaseThemeSharedModule], +}) export class ThemeSharedModule { constructor(private errorHandler: ErrorHandler) {} From 37954a8c99927833c163e14dea14bd6048b84b39 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 16:46:08 +0300 Subject: [PATCH 12/20] add an entry point for theme shared testing --- npm/ng-packs/packages/theme-shared/testing/ng-package.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 npm/ng-packs/packages/theme-shared/testing/ng-package.json diff --git a/npm/ng-packs/packages/theme-shared/testing/ng-package.json b/npm/ng-packs/packages/theme-shared/testing/ng-package.json new file mode 100644 index 0000000000..7fc8d6067d --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/testing/ng-package.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../dist/theme-shared/testing", + "lib": { + "entryFile": "src/public-api.ts" + } +} From 394692d8a486cc56202fca35a516973af5847ebc Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 16:46:50 +0300 Subject: [PATCH 13/20] add ThemeSharedTestingModule --- .../src/lib/theme-shared-testing.module.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 npm/ng-packs/packages/theme-shared/testing/src/lib/theme-shared-testing.module.ts diff --git a/npm/ng-packs/packages/theme-shared/testing/src/lib/theme-shared-testing.module.ts b/npm/ng-packs/packages/theme-shared/testing/src/lib/theme-shared-testing.module.ts new file mode 100644 index 0000000000..323281046a --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/testing/src/lib/theme-shared-testing.module.ts @@ -0,0 +1,27 @@ +import { + BaseThemeSharedModule, + DateParserFormatter, + THEME_SHARED_ROUTE_PROVIDERS, +} from '@abp/ng.theme.shared'; +import { ModuleWithProviders, NgModule } from '@angular/core'; +import { RouterTestingModule } from '@angular/router/testing'; +import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap'; + +/** + * ThemeSharedTestingModule is the module that will be used in tests + */ +@NgModule({ + exports: [RouterTestingModule, BaseThemeSharedModule], + imports: [RouterTestingModule, BaseThemeSharedModule], +}) +export class ThemeSharedTestingModule { + static withConfig(): ModuleWithProviders { + return { + ngModule: ThemeSharedTestingModule, + providers: [ + THEME_SHARED_ROUTE_PROVIDERS, + { provide: NgbDateParserFormatter, useClass: DateParserFormatter }, + ], + }; + } +} From 98cd7b001bcbb2c97a8975feaefe3a459a1c8776 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 16:46:58 +0300 Subject: [PATCH 14/20] make ThemeSharedTestingModule public --- npm/ng-packs/packages/theme-shared/testing/src/public-api.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 npm/ng-packs/packages/theme-shared/testing/src/public-api.ts diff --git a/npm/ng-packs/packages/theme-shared/testing/src/public-api.ts b/npm/ng-packs/packages/theme-shared/testing/src/public-api.ts new file mode 100644 index 0000000000..14355a8a28 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/testing/src/public-api.ts @@ -0,0 +1 @@ +export * from './lib/theme-shared-testing.module'; From 78980ed2731345450fb22cfb4f43a677e267020c Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 17:52:10 +0300 Subject: [PATCH 15/20] update yarn lock --- npm/ng-packs/yarn.lock | 106 ++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/npm/ng-packs/yarn.lock b/npm/ng-packs/yarn.lock index 4ef0c07ef8..a3f300d1c8 100644 --- a/npm/ng-packs/yarn.lock +++ b/npm/ng-packs/yarn.lock @@ -2,12 +2,12 @@ # yarn lockfile v1 -"@abp/ng.core@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-4.1.0-rc.1.tgz#efbd35e8df0731e75b2195149269b0228ec4ae42" - integrity sha512-WhXHMlDSbYled+mW8faMW8qHUGVErh/E/3eOgfvhx4N2tGGs5w+A4EfjNVBBROcoLDwiX2q1L88WeNnrK1+OIQ== +"@abp/ng.core@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.core/-/ng.core-4.1.0-rc.2.tgz#5fe53658965af66fae655dfce4bf6a7ad7105032" + integrity sha512-NcjOn1HYIdLTdHPbWTiLywPp1jQ+zmoeknnb0q/JfUUDn5r5kPrCf85xiZBUo8e+2ViB5vXvkM5lOOD5RfES6A== dependencies: - "@abp/utils" "^4.0.1" + "@abp/utils" "^4.1.0-rc.1" "@angular/localize" "~10.0.10" "@ngxs/store" "^3.7.0" angular-oauth2-oidc "^10.0.0" @@ -17,35 +17,35 @@ ts-toolbelt "6.15.4" tslib "^2.0.0" -"@abp/ng.feature-management@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-4.1.0-rc.1.tgz#5237db2e5a0ea5a6511941864fa721a303b5612c" - integrity sha512-/9GP6ze127uMkHB2QxWJC2MXiEMTLtBhM0DXYlPZKI+Y+FrVOBoUTI3gNz+AqWFwbBAA4PqfVuThhoja5b29Sg== +"@abp/ng.feature-management@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.feature-management/-/ng.feature-management-4.1.0-rc.2.tgz#02e760bfa913276e694dbff545e39210a69b21bd" + integrity sha512-vf//thBD3ve8tkmAIan2FqQeHrO/sP8NVV83noGVMTpqKIAWIu7PBuSL3YqcNVOVxHLsO6EIwr63OAJytlvH6A== dependencies: - "@abp/ng.theme.shared" "~4.1.0-rc.1" + "@abp/ng.theme.shared" "~4.1.0-rc.2" tslib "^2.0.0" -"@abp/ng.identity@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-4.1.0-rc.1.tgz#932fd10482e82400a87927d200c2d3c850cccef4" - integrity sha512-uh7Fy+X2qGiNZ58g2c1GkmJL9VnMPLsKzg9EugNV2VxbGYg4/sNmVvAeIV66x2hpDXETHCjm+7lYuZsqI/5Vew== +"@abp/ng.identity@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.identity/-/ng.identity-4.1.0-rc.2.tgz#381d956cebe2f3c272c59567ff424d3729adb6aa" + integrity sha512-4Wnx/iXAOgdexDYuNTV+DBdnjyfhcgca1ZiUSuEnSVDKePq0xvpGeKvpXzhhm9T3uXNsqYwqNq/X5jK3jd6mZg== dependencies: - "@abp/ng.permission-management" "~4.1.0-rc.1" - "@abp/ng.theme.shared" "~4.1.0-rc.1" + "@abp/ng.permission-management" "~4.1.0-rc.2" + "@abp/ng.theme.shared" "~4.1.0-rc.2" tslib "^2.0.0" -"@abp/ng.permission-management@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-4.1.0-rc.1.tgz#de810f1d50f901cffb15f59756127e83109e79f7" - integrity sha512-AgPpmBKDYnMKmMXoiU9ewGKtn5hH9frO5tV0wjz46BjmO9kIwyap3BBeCFcZjhgVLxZnXi8D0WuzZW7mgQARIQ== +"@abp/ng.permission-management@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.permission-management/-/ng.permission-management-4.1.0-rc.2.tgz#b74402241886e156a0e72baddfbc0ebebb7576aa" + integrity sha512-6/Z/8KGKkAflfk6CoXk92StEELuP0xkwj2dvvFvnGpr2od9ELGWWqtiJ5Pjz6i5FQvrLdqcHqPh8x/vgr7QV9w== dependencies: - "@abp/ng.theme.shared" "~4.1.0-rc.1" + "@abp/ng.theme.shared" "~4.1.0-rc.2" tslib "^2.0.0" -"@abp/ng.schematics@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.schematics/-/ng.schematics-4.1.0-rc.1.tgz#42173b847cfc2f293245a96fe4732a9049b8ab7c" - integrity sha512-FU5Mat3ki6ARDmOK5WC4/AMXJC+61EknuH44SE9Y9PraXAYkJk+2Ha+1qAg+VLBQcEEVWLxIqMp+2Soc6d6oow== +"@abp/ng.schematics@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.schematics/-/ng.schematics-4.1.0-rc.2.tgz#31dada6fc1f69d0198f4fb3801b6009d6a0a0c09" + integrity sha512-yVi/C1IbwcOQfXUAe8FSlekdNfoqi/UQvTBQ19h/HGBBDxhqbv6QKjhkaVs/+EOAW8WHWCufyVtQ2/y/jrCeog== dependencies: "@angular-devkit/core" "~11.0.2" "@angular-devkit/schematics" "~11.0.2" @@ -53,37 +53,37 @@ jsonc-parser "^2.3.0" typescript "~3.9.2" -"@abp/ng.setting-management@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-4.1.0-rc.1.tgz#d35083c211089683c4fb07f88523c01e3e5d8ce0" - integrity sha512-qKLV2IWkHbK5ohHMxbdzPqE1pvPPatmV0EidE79Rk4j5+WZXOXtNz5GEA2vLmF3CsuVjX90cJQdtY1bdZpvdVQ== +"@abp/ng.setting-management@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.setting-management/-/ng.setting-management-4.1.0-rc.2.tgz#4b61bff63fa9d68be5f1c7b8c47049cc1bd8b5a8" + integrity sha512-Df2QS0bsytytUSkQ0KrI/m4pVTpQS708fwl8t3KcpeQ4hlgdg6LtTmhUaY/j6k8M1RJHaKvjPE9Jg6R2daLNGg== dependencies: - "@abp/ng.theme.shared" "~4.1.0-rc.1" + "@abp/ng.theme.shared" "~4.1.0-rc.2" tslib "^2.0.0" -"@abp/ng.tenant-management@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-4.1.0-rc.1.tgz#be6740c8a7ac844c7100a46fb88bc96ce386e17d" - integrity sha512-OymGkg5BzHiraUC0FcWPm6JN84FgYNZ3YuLTAZd/iHmqQVoj51ymTK8dBOn7sw49vWlAj/WvGN4Z9tT/JS40zg== +"@abp/ng.tenant-management@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.tenant-management/-/ng.tenant-management-4.1.0-rc.2.tgz#b75b60db124e5246476821da2bfeebd5e5da09b6" + integrity sha512-AnDiMa/M4xSwiSXjyIsBY13BNxm+JMhWiIEb9WAPlk8IUaNDJZH9zHJH/HQSUHdy6dFCmutl5Ezi6U1J9ZHpPQ== dependencies: - "@abp/ng.feature-management" "~4.1.0-rc.1" - "@abp/ng.theme.shared" "~4.1.0-rc.1" + "@abp/ng.feature-management" "~4.1.0-rc.2" + "@abp/ng.theme.shared" "~4.1.0-rc.2" tslib "^2.0.0" -"@abp/ng.theme.basic@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-4.1.0-rc.1.tgz#311e1ee4490803d43b1b1286620f1efa0fe3f459" - integrity sha512-nTf9UaupTxT0UgBx/SwaVuhtutUXFqGGq2dBKI0JNxltgfykLhDXUOTlUnymLlsyu09DJv8OIZbCX6PJAMV1GA== +"@abp/ng.theme.basic@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.basic/-/ng.theme.basic-4.1.0-rc.2.tgz#4c0ccb5386a09cf7d89efaee59c8920265032361" + integrity sha512-2NjHymzE/sgbZ8e+CJ4iMemB+mD6e/VSKA2EkCaekPpXDlp0Z3f2yyhm0jwYqCQPsmCjykdtTpR266yLQOs7ug== dependencies: - "@abp/ng.theme.shared" "~4.1.0-rc.1" + "@abp/ng.theme.shared" "~4.1.0-rc.2" tslib "^2.0.0" -"@abp/ng.theme.shared@~4.1.0-rc.1": - version "4.1.0-rc.1" - resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-4.1.0-rc.1.tgz#08c051cafd1364563943f7f8b6d067955227cc7e" - integrity sha512-oNPGXI6gyesDnzHq/x7QuXKr0ISwgz9YaKg2bvzZOCvyZ0usL2P4h/4sQvV9ThCYjDdkVKN+cdW+KNvalJ415w== +"@abp/ng.theme.shared@~4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/ng.theme.shared/-/ng.theme.shared-4.1.0-rc.2.tgz#eaf524ef26f5433ec7ea01d402ba071c42ce1aa6" + integrity sha512-d6dVhV2wer7eeHoT8Y91Bqf7m2r3FVexUp7R+/f93564swuceZGZWSsgntwpHkNdDJaxhLUJ8tG5XMe2deEGTQ== dependencies: - "@abp/ng.core" "~4.1.0-rc.1" + "@abp/ng.core" "~4.1.0-rc.2" "@fortawesome/fontawesome-free" "^5.14.0" "@ng-bootstrap/ng-bootstrap" "^7.0.0" "@ngx-validate/core" "^0.0.13" @@ -92,13 +92,6 @@ chart.js "^2.9.3" tslib "^2.0.0" -"@abp/utils@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.0.1.tgz#9a4cb420266c49d8084776bd31c86681d4d4d125" - integrity sha512-nI2ZyaNpvohr75p8jeMPWze+hX+mV47EHI+Zloa4GgGmJqrULdG71kYh45R+jGmMTbQL6huaXGnpz4gNF9TGyQ== - dependencies: - just-compare "^1.3.0" - "@abp/utils@^4.1.0-rc.1": version "4.1.0-rc.1" resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.1.0-rc.1.tgz#2863867985db9d178a5ce4347309f060f1ce6142" @@ -106,6 +99,13 @@ dependencies: just-compare "^1.3.0" +"@abp/utils@^4.1.0-rc.2": + version "4.1.0-rc.2" + resolved "https://registry.yarnpkg.com/@abp/utils/-/utils-4.1.0-rc.2.tgz#eb6dbf0ee493d0f050b37347d2d6d283098aedae" + integrity sha512-V2k5I89lVBoeGIKgg4p2H9GlMAcDWbctwKZPVwBEMVEVm1uTR2xQAWdTdSFd5Q8I8Xsf/aIG8ELM7l5j2h7/zQ== + dependencies: + just-compare "^1.3.0" + "@angular-builders/jest@^10.0.0": version "10.0.1" resolved "https://registry.yarnpkg.com/@angular-builders/jest/-/jest-10.0.1.tgz#a1a6fb5d11b5d54c051bdaa2012b5f046371560c" From ca96318427be3b734637fc46d2cca90c376e4bd1 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 17:52:44 +0300 Subject: [PATCH 16/20] inject ApplicationRef at runtime in ErrorHandler --- .../theme-shared/src/lib/handlers/error.handler.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 46652f8b25..97f9533cf7 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -74,7 +74,6 @@ export class ErrorHandler { private actions: Actions, private router: Router, private confirmationService: ConfirmationService, - private appRef: ApplicationRef, private cfRes: ComponentFactoryResolver, private rendererFactory: RendererFactory2, private injector: Injector, @@ -281,14 +280,16 @@ export class ErrorHandler { } this.componentRef.instance.hideCloseIcon = this.httpErrorConfig.errorScreen.hideCloseIcon; + const appRef = this.injector.get(ApplicationRef); + if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) { this.componentRef.instance.cfRes = this.cfRes; - this.componentRef.instance.appRef = this.appRef; + this.componentRef.instance.appRef = appRef; this.componentRef.instance.injector = this.injector; this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen.component; } - this.appRef.attachView(this.componentRef.hostView); + appRef.attachView(this.componentRef.hostView); renderer.appendChild(host, (this.componentRef.hostView as EmbeddedViewRef).rootNodes[0]); const destroy$ = new Subject(); From 0897bd30f9aeb99605e72e15971660fa567a75bd Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 17:53:15 +0300 Subject: [PATCH 17/20] use APP_INITIALIZER to instantiate ErrorHandler --- .../packages/theme-shared/src/lib/theme-shared.module.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts index 4bafe28925..6775c15e5a 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts @@ -69,12 +69,16 @@ export class BaseThemeSharedModule {} exports: [BaseThemeSharedModule], }) export class ThemeSharedModule { - constructor(private errorHandler: ErrorHandler) {} - static forRoot(options = {} as RootParams): ModuleWithProviders { return { ngModule: ThemeSharedModule, providers: [ + { + provide: APP_INITIALIZER, + multi: true, + deps: [ErrorHandler], + useFactory: noop, + }, THEME_SHARED_ROUTE_PROVIDERS, { provide: APP_INITIALIZER, From f37b52480a2b4aaf7a52424e21bcf454176e3492 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 18:46:33 +0300 Subject: [PATCH 18/20] change private props and methods to protected in RestService --- .../packages/core/src/lib/services/rest.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts index 204118aa56..d880c94e5a 100644 --- a/npm/ng-packs/packages/core/src/lib/services/rest.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/rest.service.ts @@ -15,13 +15,13 @@ import { EnvironmentService } from './environment.service'; }) export class RestService { constructor( - @Inject(CORE_OPTIONS) private options: ABP.Root, - private http: HttpClient, - private store: Store, - private environment: EnvironmentService, + @Inject(CORE_OPTIONS) protected options: ABP.Root, + protected http: HttpClient, + protected environment: EnvironmentService, + protected store: Store, ) {} - private getApiFromStore(apiName: string): string { + protected getApiFromStore(apiName: string): string { return this.environment.getApiUrl(apiName); } From ab0116cca7d19841e3973e11c068de4a84e8583d Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 18:47:07 +0300 Subject: [PATCH 19/20] create a mock rest service which doesn't report errors --- .../core/testing/src/lib/services/index.ts | 1 + .../src/lib/services/mock-rest.service.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 npm/ng-packs/packages/core/testing/src/lib/services/index.ts create mode 100644 npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts diff --git a/npm/ng-packs/packages/core/testing/src/lib/services/index.ts b/npm/ng-packs/packages/core/testing/src/lib/services/index.ts new file mode 100644 index 0000000000..24206d7c5d --- /dev/null +++ b/npm/ng-packs/packages/core/testing/src/lib/services/index.ts @@ -0,0 +1 @@ +export * from './mock-rest.service'; diff --git a/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts b/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts new file mode 100644 index 0000000000..b7b4066a4c --- /dev/null +++ b/npm/ng-packs/packages/core/testing/src/lib/services/mock-rest.service.ts @@ -0,0 +1,21 @@ +import { ABP, CORE_OPTIONS, EnvironmentService, RestService } from '@abp/ng.core'; +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable } 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 environment: EnvironmentService, + ) { + super(options, http, environment, null); + } + + handleError(err: any): Observable { + return throwError(err); + } +} From 4fc4172b514f2fcd6950874fd02a3e5c334a6312 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 24 Dec 2020 18:47:23 +0300 Subject: [PATCH 20/20] provide mock rest service in CoreTestingModule --- .../packages/core/testing/src/lib/core-testing.module.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts b/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts index 224992ed23..9a7fc3eec0 100644 --- a/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts +++ b/npm/ng-packs/packages/core/testing/src/lib/core-testing.module.ts @@ -4,12 +4,14 @@ import { coreOptionsFactory, CORE_OPTIONS, LocalizationPipe, + RestService, } from '@abp/ng.core'; import { APP_BASE_HREF } from '@angular/common'; import { ModuleWithProviders, NgModule } from '@angular/core'; import { provideRoutes } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { MockLocalizationPipe } from './pipes/mock-localization.pipe'; +import { MockRestService } from './services/mock-rest.service'; /** * CoreTestingModule is the module that will be used in tests @@ -41,6 +43,10 @@ export class CoreTestingModule { provide: LocalizationPipe, useClass: MockLocalizationPipe, }, + { + provide: RestService, + useClass: MockRestService, + }, provideRoutes(routes), ], };