From 43e9cd2977b037de6cd3180ca120a8ee288ae520 Mon Sep 17 00:00:00 2001 From: mehmet-erim Date: Mon, 4 May 2020 03:12:26 +0300 Subject: [PATCH] fix: circular dependency warnings --- .../src/lib/services/localization.service.ts | 12 +++- .../core/src/lib/states/config.state.ts | 56 +++++++++++-------- .../core/src/lib/states/session.state.ts | 29 ++++------ .../confirmation/confirmation.component.html | 4 +- .../confirmation/confirmation.component.ts | 16 ++++-- .../toast-container.component.ts | 10 ++-- .../src/lib/services/confirmation.service.ts | 17 +++--- .../src/lib/services/toaster.service.ts | 2 +- .../src/lib/theme-shared.module.ts | 8 ++- 9 files changed, 86 insertions(+), 68 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts index b12b517156..0e89732e56 100644 --- a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts @@ -1,10 +1,11 @@ import { Injectable, NgZone, Optional, SkipSelf } from '@angular/core'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; -import { Store } from '@ngxs/store'; +import { Store, Actions, ofActionSuccessful } from '@ngxs/store'; import { noop, Observable } from 'rxjs'; import { ConfigState } from '../states/config.state'; import { registerLocale } from '../utils/initial-utils'; import { Config } from '../models/config'; +import { SetLanguage } from '../actions/session.actions'; type ShouldReuseRoute = (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) => boolean; @@ -18,6 +19,7 @@ export class LocalizationService { } constructor( + private actions: Actions, private store: Store, private router: Router, private ngZone: NgZone, @@ -26,6 +28,14 @@ export class LocalizationService { otherInstance: LocalizationService, ) { if (otherInstance) throw new Error('LocalizationService should have only one instance.'); + + this.listenToSetLanguage(); + } + + private listenToSetLanguage() { + this.actions + .pipe(ofActionSuccessful(SetLanguage)) + .subscribe(({ payload }) => this.registerLocale(payload)); } setRouteReuse(reuse: ShouldReuseRoute) { diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index 01a181229f..af706586bb 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -1,7 +1,8 @@ +import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Action, createSelector, Selector, State, StateContext, Store } from '@ngxs/store'; -import { of } from 'rxjs'; -import { switchMap, tap } from 'rxjs/operators'; +import { of, throwError } from 'rxjs'; +import { catchError, switchMap, tap } from 'rxjs/operators'; import snq from 'snq'; import { AddRoute, @@ -9,10 +10,11 @@ import { PatchRouteByName, SetEnvironment, } from '../actions/config.actions'; +import { RestOccurError } from '../actions/rest.actions'; import { SetLanguage } from '../actions/session.actions'; +import { ApplicationConfiguration } from '../models/application-configuration'; import { ABP } from '../models/common'; import { Config } from '../models/config'; -import { ApplicationConfigurationService } from '../services/application-configuration.service'; import { organizeRoutes } from '../utils/route-utils'; import { SessionState } from './session.state'; @@ -195,31 +197,37 @@ export class ConfigState { return selector; } - constructor( - private appConfigurationService: ApplicationConfigurationService, - private store: Store, - ) {} + constructor(private http: HttpClient, private store: Store) {} @Action(GetAppConfiguration) addData({ patchState, dispatch }: StateContext) { - return this.appConfigurationService.getConfiguration().pipe( - tap(configuration => - patchState({ - ...configuration, + const apiName = this.store.selectSnapshot(ConfigState.getDeep('environment.application.name')); + const api = this.store.selectSnapshot(ConfigState.getApiUrl(apiName)); + return this.http + .get(`${api}/api/abp/application-configuration`) + .pipe( + tap(configuration => + patchState({ + ...configuration, + }), + ), + switchMap(configuration => { + let defaultLang: string = + configuration.setting.values['Abp.Localization.DefaultLanguage']; + + if (defaultLang.includes(';')) { + defaultLang = defaultLang.split(';')[0]; + } + + return this.store.selectSnapshot(SessionState.getLanguage) + ? of(null) + : dispatch(new SetLanguage(defaultLang)); }), - ), - switchMap(configuration => { - let defaultLang: string = configuration.setting.values['Abp.Localization.DefaultLanguage']; - - if (defaultLang.includes(';')) { - defaultLang = defaultLang.split(';')[0]; - } - - return this.store.selectSnapshot(SessionState.getLanguage) - ? of(null) - : dispatch(new SetLanguage(defaultLang)); - }), - ); + catchError(err => { + dispatch(new RestOccurError(new HttpErrorResponse({ status: 0, error: err }))); + return throwError(err); + }), + ); } @Action(PatchRouteByName) diff --git a/npm/ng-packs/packages/core/src/lib/states/session.state.ts b/npm/ng-packs/packages/core/src/lib/states/session.state.ts index 9342bacd62..6acbf1d60d 100644 --- a/npm/ng-packs/packages/core/src/lib/states/session.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/session.state.ts @@ -1,26 +1,24 @@ +import { Injectable } from '@angular/core'; import { Action, + Actions, + ofActionSuccessful, Selector, State, StateContext, Store, - NgxsOnInit, - Actions, - ofActionSuccessful, } from '@ngxs/store'; -import { from, fromEvent } from 'rxjs'; -import { switchMap, take } from 'rxjs/operators'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { fromEvent } from 'rxjs'; +import { take } from 'rxjs/operators'; import { GetAppConfiguration } from '../actions/config.actions'; import { - SetLanguage, - SetTenant, ModifyOpenedTabCount, + SetLanguage, SetRemember, + SetTenant, } from '../actions/session.actions'; import { ABP, Session } from '../models'; -import { LocalizationService } from '../services/localization.service'; -import { OAuthService } from 'angular-oauth2-oidc'; -import { Injectable } from '@angular/core'; @State({ name: 'SessionState', @@ -43,12 +41,7 @@ export class SessionState { return sessionDetail; } - constructor( - private localizationService: LocalizationService, - private oAuthService: OAuthService, - private store: Store, - private actions: Actions, - ) { + constructor(private oAuthService: OAuthService, private store: Store, private actions: Actions) { actions .pipe(ofActionSuccessful(GetAppConfiguration)) .pipe(take(1)) @@ -81,9 +74,7 @@ export class SessionState { language: payload, }); - return dispatch(new GetAppConfiguration()).pipe( - switchMap(() => from(this.localizationService.registerLocale(payload))), - ); + return dispatch(new GetAppConfiguration()); } @Action(SetTenant) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.html index a40d72adf4..8b0d8591c4 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.html +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.html @@ -20,14 +20,14 @@ diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts index a73382678a..a68789044c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts @@ -1,13 +1,13 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { ReplaySubject } from 'rxjs'; import { Confirmation } from '../../models/confirmation'; -import { ConfirmationService } from '../../services/confirmation.service'; @Component({ selector: 'abp-confirmation', templateUrl: './confirmation.component.html', styleUrls: ['./confirmation.component.scss'], }) -export class ConfirmationComponent { +export class ConfirmationComponent implements OnInit { confirm = Confirmation.Status.confirm; reject = Confirmation.Status.reject; dismiss = Confirmation.Status.dismiss; @@ -16,6 +16,10 @@ export class ConfirmationComponent { data: Confirmation.DialogData; + confirmation$: ReplaySubject; + + clear: (status: Confirmation.Status) => void; + get iconClass(): string { switch (this.data.severity) { case 'info': @@ -31,14 +35,14 @@ export class ConfirmationComponent { } } - constructor(private confirmationService: ConfirmationService) { - this.confirmationService.confirmation$.subscribe(confirmation => { + ngOnInit() { + this.confirmation$.subscribe(confirmation => { this.data = confirmation; this.visible = !!confirmation; }); } close(status: Confirmation.Status) { - this.confirmationService.clear(status); + this.clear(status); } } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.ts index 124dcc5185..28d66123a9 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.ts @@ -1,7 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; -import { Toaster } from '../../models/toaster'; import { toastInOut } from '../../animations/toast.animations'; -import { ToasterService } from '../../services/toaster.service'; +import { Toaster } from '../../models/toaster'; +import { ReplaySubject } from 'rxjs'; @Component({ selector: 'abp-toast-container', @@ -10,6 +10,8 @@ import { ToasterService } from '../../services/toaster.service'; animations: [toastInOut], }) export class ToastContainerComponent implements OnInit { + toasts$: ReplaySubject; + toasts = [] as Toaster.Toast[]; @Input() @@ -27,10 +29,8 @@ export class ToastContainerComponent implements OnInit { @Input() toastKey: string; - constructor(private toastService: ToasterService) {} - ngOnInit() { - this.toastService.toasts$.subscribe(toasts => { + this.toasts$.subscribe(toasts => { this.toasts = this.toastKey ? toasts.filter(t => { return t.options && t.options.containerKey !== this.toastKey; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts index bfd5b32230..d254449894 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts @@ -15,13 +15,14 @@ export class ConfirmationService { constructor(private contentProjectionService: ContentProjectionService) {} private setContainer() { - setTimeout(() => { - this.containerComponentRef = this.contentProjectionService.projectContent( - PROJECTION_STRATEGY.AppendComponentToBody(ConfirmationComponent), - ); + this.containerComponentRef = this.contentProjectionService.projectContent( + PROJECTION_STRATEGY.AppendComponentToBody(ConfirmationComponent, { + confirmation$: this.confirmation$, + clear: this.clear, + }), + ); - this.containerComponentRef.changeDetectorRef.detectChanges(); - }, 0); + this.containerComponentRef.changeDetectorRef.detectChanges(); } info( @@ -75,10 +76,10 @@ export class ConfirmationService { return this.status$; } - clear(status: Confirmation.Status = Confirmation.Status.dismiss) { + clear = (status: Confirmation.Status = Confirmation.Status.dismiss) => { this.confirmation$.next(); this.status$.next(status); - } + }; private listenToEscape() { fromEvent(document, 'keyup') diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts index 4d178c0ad2..295647309d 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts @@ -21,7 +21,7 @@ export class ToasterService { private setContainer() { this.containerComponentRef = this.contentProjectionService.projectContent( - PROJECTION_STRATEGY.AppendComponentToBody(ToastContainerComponent), + PROJECTION_STRATEGY.AppendComponentToBody(ToastContainerComponent, { toasts$: this.toasts$ }), ); this.containerComponentRef.changeDetectorRef.detectChanges(); 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 5d53ed2124..8134a44be4 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 @@ -92,8 +92,6 @@ export function appendScript(injector: Injector) { ], }) export class ThemeSharedModule { - constructor(private errorHandler: ErrorHandler) {} - static forRoot(options = {} as RootParams): ModuleWithProviders { return { ngModule: ThemeSharedModule, @@ -104,6 +102,12 @@ export class ThemeSharedModule { deps: [THEME_SHARED_APPEND_CONTENT], useFactory: noop, }, + { + provide: APP_INITIALIZER, + multi: true, + deps: [ErrorHandler], + useFactory: noop, + }, { provide: HTTP_ERROR_CONFIG, useValue: options.httpErrorConfig }, { provide: 'HTTP_ERROR_CONFIG',