show full screen loader when switching themes

This commit is contained in:
Art Lowel
2021-05-27 13:26:40 +02:00
parent 772ac12329
commit 899b30213e
6 changed files with 44 additions and 23 deletions

View File

@@ -1 +1,3 @@
<ds-themed-root [isNotAuthBlocking]="isNotAuthBlocking$ | async" [isLoading]="isLoading$ | async"></ds-themed-root>
<ds-themed-root
[shouldShowFullscreenLoader]="(isAuthBlocking$ | async) || (isThemeLoading$ | async)"
[shouldShowRouteLoader]="isRouteLoading$ | async"></ds-themed-root>

View File

@@ -1,4 +1,4 @@
import { delay, map, distinctUntilChanged, filter, take } from 'rxjs/operators';
import { delay, distinctUntilChanged, filter, take } from 'rxjs/operators';
import {
AfterViewInit,
ChangeDetectionStrategy,
@@ -7,6 +7,7 @@ import {
Inject,
OnInit,
Optional,
PLATFORM_ID,
} from '@angular/core';
import { NavigationCancel, NavigationEnd, NavigationStart, Router } from '@angular/router';
@@ -32,7 +33,7 @@ import { LocaleService } from './core/locale/locale.service';
import { hasValue, isNotEmpty } from './shared/empty.util';
import { KlaroService } from './shared/cookies/klaro.service';
import { GoogleAnalyticsService } from './statistics/google-analytics.service';
import { DOCUMENT } from '@angular/common';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
import { ThemeService } from './shared/theme-support/theme.service';
import { BASE_THEME_NAME } from './shared/theme-support/theme.constants';
import { DEFAULT_THEME_CONFIG } from './shared/theme-support/theme.effects';
@@ -45,7 +46,6 @@ import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent implements OnInit, AfterViewInit {
isLoading$: BehaviorSubject<boolean> = new BehaviorSubject(true);
sidebarVisible: Observable<boolean>;
slideSidebarOver: Observable<boolean>;
collapsedSidebarWidth: Observable<string>;
@@ -57,11 +57,23 @@ export class AppComponent implements OnInit, AfterViewInit {
/**
* Whether or not the authentication is currently blocking the UI
*/
isNotAuthBlocking$: Observable<boolean>;
isAuthBlocking$: Observable<boolean>;
/**
* Whether or not the app is in the process of rerouting
*/
isRouteLoading$: BehaviorSubject<boolean> = new BehaviorSubject(true);
/**
* Whether or not the theme is in the process of being swapped
*/
isThemeLoading$: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(
@Inject(NativeWindowService) private _window: NativeWindowRef,
@Inject(DOCUMENT) private document: any,
@Inject(DOCUMENT) private document: any,
@Inject(PLATFORM_ID) private platformId: any,
private themeService: ThemeService,
private translate: TranslateService,
private store: Store<HostWindowState>,
@@ -83,6 +95,10 @@ export class AppComponent implements OnInit, AfterViewInit {
this.models = models;
this.themeService.getThemeName$().subscribe((themeName: string) => {
if (isPlatformBrowser(this.platformId)) {
// the theme css will never download server side, so this should only happen on the browser
this.isThemeLoading$.next(true);
}
if (hasValue(themeName)) {
this.setThemeCss(themeName);
} else if (hasValue(DEFAULT_THEME_CONFIG)) {
@@ -118,13 +134,12 @@ export class AppComponent implements OnInit, AfterViewInit {
}
ngOnInit() {
this.isNotAuthBlocking$ = this.store.pipe(select(isAuthenticationBlocking)).pipe(
map((isBlocking: boolean) => isBlocking === false),
this.isAuthBlocking$ = this.store.pipe(select(isAuthenticationBlocking)).pipe(
distinctUntilChanged()
);
this.isNotAuthBlocking$
this.isAuthBlocking$
.pipe(
filter((notBlocking: boolean) => notBlocking),
filter((isBlocking: boolean) => isBlocking === false),
take(1)
).subscribe(() => this.initializeKlaro());
@@ -156,12 +171,12 @@ export class AppComponent implements OnInit, AfterViewInit {
delay(0)
).subscribe((event) => {
if (event instanceof NavigationStart) {
this.isLoading$.next(true);
this.isRouteLoading$.next(true);
} else if (
event instanceof NavigationEnd ||
event instanceof NavigationCancel
) {
this.isLoading$.next(false);
this.isRouteLoading$.next(false);
}
});
}
@@ -209,6 +224,8 @@ export class AppComponent implements OnInit, AfterViewInit {
}
});
}
// the fact that this callback is used, proves we're on the browser.
this.isThemeLoading$.next(false);
};
head.appendChild(link);
}

View File

@@ -1,4 +1,4 @@
<div class="outer-wrapper" *ngIf="isNotAuthBlocking; else authLoader">
<div class="outer-wrapper" *ngIf="!shouldShowFullscreenLoader; else fullScreenLoader">
<ds-admin-sidebar></ds-admin-sidebar>
<div class="inner-wrapper" [@slideSidebarPadding]="{
value: (!(sidebarVisible | async) ? 'hidden' : (slideSidebarOver | async) ? 'shown' : 'expanded'),
@@ -12,10 +12,10 @@
<main class="main-content">
<ds-themed-breadcrumbs></ds-themed-breadcrumbs>
<div class="container d-flex justify-content-center align-items-center h-100" *ngIf="isLoading">
<div class="container d-flex justify-content-center align-items-center h-100" *ngIf="shouldShowRouteLoader">
<ds-loading [showMessage]="false"></ds-loading>
</div>
<div [class.d-none]="isLoading">
<div [class.d-none]="shouldShowRouteLoader">
<router-outlet></router-outlet>
</div>
</main>
@@ -23,7 +23,7 @@
<ds-themed-footer></ds-themed-footer>
</div>
</div>
<ng-template #authLoader>
<ng-template #fullScreenLoader>
<div class="ds-full-screen-loader">
<ds-loading [showMessage]="false"></ds-loading>
</div>

View File

@@ -27,6 +27,7 @@ import { provideMockStore } from '@ngrx/store/testing';
import { RouteService } from '../core/services/route.service';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { MenuServiceStub } from '../shared/testing/menu-service.stub';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
describe('RootComponent', () => {
let component: RootComponent;
@@ -36,6 +37,7 @@ describe('RootComponent', () => {
await TestBed.configureTestingModule({
imports: [
CommonModule,
NoopAnimationsModule,
StoreModule.forRoot(authReducer, storeModuleConfig),
TranslateModule.forRoot({
loader: {

View File

@@ -38,14 +38,14 @@ export class RootComponent implements OnInit {
models;
/**
* Whether or not the authentication is currently blocking the UI
* Whether or not to show a full screen loader
*/
@Input() isNotAuthBlocking: boolean;
@Input() shouldShowFullscreenLoader: boolean;
/**
* Whether or not the the application is loading;
* Whether or not to show a loader across the router outlet
*/
@Input() isLoading: boolean;
@Input() shouldShowRouteLoader: boolean;
constructor(
@Inject(NativeWindowService) private _window: NativeWindowRef,

View File

@@ -11,14 +11,14 @@ export class ThemedRootComponent extends ThemedComponent<RootComponent> {
/**
* Whether or not the authentication is currently blocking the UI
*/
@Input() isNotAuthBlocking: boolean;
@Input() shouldShowFullscreenLoader: boolean;
/**
* Whether or not the the application is loading;
*/
@Input() isLoading: boolean;
@Input() shouldShowRouteLoader: boolean;
protected inAndOutputNames: (keyof RootComponent & keyof this)[] = ['isLoading', 'isNotAuthBlocking'];
protected inAndOutputNames: (keyof RootComponent & keyof this)[] = ['shouldShowRouteLoader', 'shouldShowFullscreenLoader'];
protected getComponentName(): string {
return 'RootComponent';