mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-13 13:03:04 +00:00
show full screen loader when switching themes
This commit is contained in:
@@ -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>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { delay, map, distinctUntilChanged, filter, take } from 'rxjs/operators';
|
import { delay, distinctUntilChanged, filter, take } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
OnInit,
|
OnInit,
|
||||||
Optional,
|
Optional,
|
||||||
|
PLATFORM_ID,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { NavigationCancel, NavigationEnd, NavigationStart, Router } from '@angular/router';
|
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 { hasValue, isNotEmpty } from './shared/empty.util';
|
||||||
import { KlaroService } from './shared/cookies/klaro.service';
|
import { KlaroService } from './shared/cookies/klaro.service';
|
||||||
import { GoogleAnalyticsService } from './statistics/google-analytics.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 { ThemeService } from './shared/theme-support/theme.service';
|
||||||
import { BASE_THEME_NAME } from './shared/theme-support/theme.constants';
|
import { BASE_THEME_NAME } from './shared/theme-support/theme.constants';
|
||||||
import { DEFAULT_THEME_CONFIG } from './shared/theme-support/theme.effects';
|
import { DEFAULT_THEME_CONFIG } from './shared/theme-support/theme.effects';
|
||||||
@@ -45,7 +46,6 @@ import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, AfterViewInit {
|
export class AppComponent implements OnInit, AfterViewInit {
|
||||||
isLoading$: BehaviorSubject<boolean> = new BehaviorSubject(true);
|
|
||||||
sidebarVisible: Observable<boolean>;
|
sidebarVisible: Observable<boolean>;
|
||||||
slideSidebarOver: Observable<boolean>;
|
slideSidebarOver: Observable<boolean>;
|
||||||
collapsedSidebarWidth: Observable<string>;
|
collapsedSidebarWidth: Observable<string>;
|
||||||
@@ -57,11 +57,23 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
/**
|
/**
|
||||||
* Whether or not the authentication is currently blocking the UI
|
* 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(
|
constructor(
|
||||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
@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 themeService: ThemeService,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private store: Store<HostWindowState>,
|
private store: Store<HostWindowState>,
|
||||||
@@ -83,6 +95,10 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
this.models = models;
|
this.models = models;
|
||||||
|
|
||||||
this.themeService.getThemeName$().subscribe((themeName: string) => {
|
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)) {
|
if (hasValue(themeName)) {
|
||||||
this.setThemeCss(themeName);
|
this.setThemeCss(themeName);
|
||||||
} else if (hasValue(DEFAULT_THEME_CONFIG)) {
|
} else if (hasValue(DEFAULT_THEME_CONFIG)) {
|
||||||
@@ -118,13 +134,12 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.isNotAuthBlocking$ = this.store.pipe(select(isAuthenticationBlocking)).pipe(
|
this.isAuthBlocking$ = this.store.pipe(select(isAuthenticationBlocking)).pipe(
|
||||||
map((isBlocking: boolean) => isBlocking === false),
|
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
);
|
);
|
||||||
this.isNotAuthBlocking$
|
this.isAuthBlocking$
|
||||||
.pipe(
|
.pipe(
|
||||||
filter((notBlocking: boolean) => notBlocking),
|
filter((isBlocking: boolean) => isBlocking === false),
|
||||||
take(1)
|
take(1)
|
||||||
).subscribe(() => this.initializeKlaro());
|
).subscribe(() => this.initializeKlaro());
|
||||||
|
|
||||||
@@ -156,12 +171,12 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
delay(0)
|
delay(0)
|
||||||
).subscribe((event) => {
|
).subscribe((event) => {
|
||||||
if (event instanceof NavigationStart) {
|
if (event instanceof NavigationStart) {
|
||||||
this.isLoading$.next(true);
|
this.isRouteLoading$.next(true);
|
||||||
} else if (
|
} else if (
|
||||||
event instanceof NavigationEnd ||
|
event instanceof NavigationEnd ||
|
||||||
event instanceof NavigationCancel
|
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);
|
head.appendChild(link);
|
||||||
}
|
}
|
||||||
|
@@ -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>
|
<ds-admin-sidebar></ds-admin-sidebar>
|
||||||
<div class="inner-wrapper" [@slideSidebarPadding]="{
|
<div class="inner-wrapper" [@slideSidebarPadding]="{
|
||||||
value: (!(sidebarVisible | async) ? 'hidden' : (slideSidebarOver | async) ? 'shown' : 'expanded'),
|
value: (!(sidebarVisible | async) ? 'hidden' : (slideSidebarOver | async) ? 'shown' : 'expanded'),
|
||||||
@@ -12,10 +12,10 @@
|
|||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<ds-themed-breadcrumbs></ds-themed-breadcrumbs>
|
<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>
|
<ds-loading [showMessage]="false"></ds-loading>
|
||||||
</div>
|
</div>
|
||||||
<div [class.d-none]="isLoading">
|
<div [class.d-none]="shouldShowRouteLoader">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<ds-themed-footer></ds-themed-footer>
|
<ds-themed-footer></ds-themed-footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-template #authLoader>
|
<ng-template #fullScreenLoader>
|
||||||
<div class="ds-full-screen-loader">
|
<div class="ds-full-screen-loader">
|
||||||
<ds-loading [showMessage]="false"></ds-loading>
|
<ds-loading [showMessage]="false"></ds-loading>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -27,6 +27,7 @@ import { provideMockStore } from '@ngrx/store/testing';
|
|||||||
import { RouteService } from '../core/services/route.service';
|
import { RouteService } from '../core/services/route.service';
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { MenuServiceStub } from '../shared/testing/menu-service.stub';
|
import { MenuServiceStub } from '../shared/testing/menu-service.stub';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
describe('RootComponent', () => {
|
describe('RootComponent', () => {
|
||||||
let component: RootComponent;
|
let component: RootComponent;
|
||||||
@@ -36,6 +37,7 @@ describe('RootComponent', () => {
|
|||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
NoopAnimationsModule,
|
||||||
StoreModule.forRoot(authReducer, storeModuleConfig),
|
StoreModule.forRoot(authReducer, storeModuleConfig),
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
loader: {
|
loader: {
|
||||||
|
@@ -38,14 +38,14 @@ export class RootComponent implements OnInit {
|
|||||||
models;
|
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(
|
constructor(
|
||||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||||
|
@@ -11,14 +11,14 @@ export class ThemedRootComponent extends ThemedComponent<RootComponent> {
|
|||||||
/**
|
/**
|
||||||
* Whether or not the authentication is currently blocking the UI
|
* Whether or not the authentication is currently blocking the UI
|
||||||
*/
|
*/
|
||||||
@Input() isNotAuthBlocking: boolean;
|
@Input() shouldShowFullscreenLoader: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the the application is loading;
|
* 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 {
|
protected getComponentName(): string {
|
||||||
return 'RootComponent';
|
return 'RootComponent';
|
||||||
|
Reference in New Issue
Block a user