diff --git a/examples/portal/src/app/app.component.html b/examples/portal/src/app/app.component.html
index 25cb271..2736465 100644
--- a/examples/portal/src/app/app.component.html
+++ b/examples/portal/src/app/app.component.html
@@ -39,11 +39,12 @@
-
+
-
-
+ @if (loading(); as loadingState) {
+
+ }
diff --git a/examples/portal/src/app/app.component.ts b/examples/portal/src/app/app.component.ts
index 743c362..533028b 100644
--- a/examples/portal/src/app/app.component.ts
+++ b/examples/portal/src/app/app.component.ts
@@ -19,8 +19,8 @@ export class AppComponent implements OnInit {
activeAppNames: string[] = [];
- get loadingDone() {
- return this.planet.loadingDone;
+ get loading() {
+ return this.planet.loading;
}
constructor(
diff --git a/packages/planet/src/application/planet-application-loader.spec.ts b/packages/planet/src/application/planet-application-loader.spec.ts
index 2c6d6dc..e2c1ba5 100644
--- a/packages/planet/src/application/planet-application-loader.spec.ts
+++ b/packages/planet/src/application/planet-application-loader.spec.ts
@@ -87,8 +87,11 @@ class AppStatusChangeFaker {
expect(this.spy).toHaveBeenCalledTimes(fromCalledTimes + 1);
expect(this.spy).toHaveBeenCalledWith({ app: expectedApp, status: ApplicationStatus.bootstrapping });
expect(this.planetApplicationLoader.loadingDone).toBe(false);
+ expect(this.planetApplicationLoader.loading()).toBe(true);
appRefFaker.bootstrap();
expect(this.planetApplicationLoader.loadingDone).toBe(true);
+ expect(this.planetApplicationLoader.loading()).toBe(false);
+
expect(this.spy).toHaveBeenCalledTimes(fromCalledTimes + 3);
expect(this.spy).toHaveBeenCalledWith({ app: expectedApp, status: ApplicationStatus.bootstrapped });
diff --git a/packages/planet/src/application/planet-application-loader.ts b/packages/planet/src/application/planet-application-loader.ts
index df4322f..aa557f7 100644
--- a/packages/planet/src/application/planet-application-loader.ts
+++ b/packages/planet/src/application/planet-application-loader.ts
@@ -1,4 +1,4 @@
-import { Injectable, NgZone, ApplicationRef, Injector } from '@angular/core';
+import { Injectable, NgZone, ApplicationRef, Injector, computed, signal } from '@angular/core';
import { of, Observable, Subject, forkJoin, from, throwError } from 'rxjs';
import { AssetsLoader } from '../assets-loader';
import { PlanetApplication, PlanetRouterEvent, SwitchModes, PlanetOptions } from '../planet.class';
@@ -54,6 +54,8 @@ export class PlanetApplicationLoader {
private appsLoadingStart$ = new Subject
();
+ private innerLoading = signal(false);
+
public get appStatusChange(): Observable {
return this.appStatusChange$.asObservable();
}
@@ -62,8 +64,13 @@ export class PlanetApplicationLoader {
return this.appsLoadingStart$.asObservable();
}
+ /**
+ * @deprecated please use loading signal
+ */
public loadingDone = false;
+ public loading = this.innerLoading.asReadonly();
+
constructor(
private assetsLoader: AssetsLoader,
private planetApplicationService: PlanetApplicationService,
@@ -73,9 +80,7 @@ export class PlanetApplicationLoader {
applicationRef: ApplicationRef
) {
if (getApplicationLoader()) {
- throw new Error(
- 'PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed'
- );
+ throw new Error('PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed');
}
this.options = {
@@ -97,9 +102,7 @@ export class PlanetApplicationLoader {
this.ngZone.run(() => {
const fromStatus = this.appsStatus.get(app);
debug(
- `app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${
- ApplicationStatus[status]
- }`
+ `app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${ApplicationStatus[status]}`
);
this.appsStatus.set(app, status);
this.appStatusChange$.next({
@@ -109,10 +112,7 @@ export class PlanetApplicationLoader {
});
}
- private getAppStatusChange$(
- app: PlanetApplication,
- status = ApplicationStatus.bootstrapped
- ): Observable {
+ private getAppStatusChange$(app: PlanetApplication, status = ApplicationStatus.bootstrapped): Observable {
return this.appStatusChange.pipe(
filter(event => {
return event.app === app && event.status === status;
@@ -140,6 +140,7 @@ export class PlanetApplicationLoader {
private setLoadingDone() {
this.ngZone.run(() => {
this.loadingDone = true;
+ this.innerLoading.set(false);
});
}
@@ -188,9 +189,7 @@ export class PlanetApplicationLoader {
appStatus === ApplicationStatus.loadError
) {
debug(
- `app(${app.name}) status is ${
- ApplicationStatus[appStatus as ApplicationStatus]
- }, start load assets`
+ `app(${app.name}) status is ${ApplicationStatus[appStatus as ApplicationStatus]}, start load assets`
);
hasAppsNeedLoadingAssets = true;
return this.ngZone.runOutsideAngular(() => {
@@ -202,6 +201,7 @@ export class PlanetApplicationLoader {
});
if (hasAppsNeedLoadingAssets) {
this.loadingDone = false;
+ this.innerLoading.set(true);
}
return loadApps$.length > 0 ? forkJoin(loadApps$) : of([] as PlanetApplication[]);
}),
@@ -212,9 +212,7 @@ export class PlanetApplicationLoader {
switchMap(app => {
const appStatus = this.appsStatus.get(app);
if (appStatus === ApplicationStatus.bootstrapped) {
- debug(
- `[routeChange] app(${app.name}) status is bootstrapped, show app and active`
- );
+ debug(`[routeChange] app(${app.name}) status is bootstrapped, show app and active`);
this.showApp(app);
const appRef = getPlanetApplicationRef(app.name);
appRef?.navigateByUrl(event.url);
@@ -222,9 +220,7 @@ export class PlanetApplicationLoader {
this.setLoadingDone();
return of(app);
} else if (appStatus === ApplicationStatus.assetsLoaded) {
- debug(
- `[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`
- );
+ debug(`[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`);
return this.bootstrapApp(app).pipe(
map(() => {
debug(`app(${app.name}) bootstrapped success, active it`);
@@ -237,9 +233,7 @@ export class PlanetApplicationLoader {
debug(`[routeChange] app(${app.name}) is active, do nothings`);
const appRef = getPlanetApplicationRef(app.name);
// Backwards compatibility sub app use old version which has not getCurrentRouterStateUrl
- const currentUrl = appRef?.getCurrentRouterStateUrl
- ? appRef.getCurrentRouterStateUrl()
- : '';
+ const currentUrl = appRef?.getCurrentRouterStateUrl ? appRef.getCurrentRouterStateUrl() : '';
if (currentUrl !== event.url) {
appRef?.navigateByUrl(event.url);
}
@@ -253,9 +247,7 @@ export class PlanetApplicationLoader {
return this.getAppStatusChange$(app).pipe(
take(1),
map(() => {
- debug(
- `app(${app.name}) status is bootstrapped by subscribe status change, active it`
- );
+ debug(`app(${app.name}) status is bootstrapped by subscribe status change, active it`);
this.setAppStatus(app, ApplicationStatus.active);
this.showApp(app);
return app;
@@ -355,10 +347,7 @@ export class PlanetApplicationLoader {
}
}
- private bootstrapApp(
- app: PlanetApplication,
- defaultStatus: 'hidden' | 'display' = 'display'
- ): Observable {
+ private bootstrapApp(app: PlanetApplication, defaultStatus: 'hidden' | 'display' = 'display'): Observable {
debug(`app(${app.name}) start bootstrapping`);
this.setAppStatus(app, ApplicationStatus.bootstrapping);
const appRef = getPlanetApplicationRef(app.name);
@@ -517,11 +506,7 @@ export class PlanetApplicationLoader {
return getPlanetApplicationRef(app.name);
})
);
- } else if (
- [ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(
- status
- )
- ) {
+ } else if ([ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(status)) {
debug(`preload app(${app.name}), status is ${ApplicationStatus[status]}, return until bootstrapped`);
return this.getAppStatusChange$(app).pipe(
take(1),
diff --git a/packages/planet/src/planet.ts b/packages/planet/src/planet.ts
index f38c946..8f32f20 100644
--- a/packages/planet/src/planet.ts
+++ b/packages/planet/src/planet.ts
@@ -2,11 +2,7 @@ import { Injectable, Inject, Optional, Injector } from '@angular/core';
import { NavigationEnd, RouterEvent, Router } from '@angular/router';
import { PlanetOptions, PlanetApplication, PLANET_APPLICATIONS } from './planet.class';
import { PlanetApplicationService } from './application/planet-application.service';
-import {
- PlanetApplicationLoader,
- AppsLoadingStartEvent,
- AppStatusChangeEvent
-} from './application/planet-application-loader';
+import { PlanetApplicationLoader, AppsLoadingStartEvent, AppStatusChangeEvent } from './application/planet-application-loader';
import { Observable, Subscription } from 'rxjs';
import { filter, startWith, distinctUntilChanged, map } from 'rxjs/operators';
import {
@@ -30,10 +26,17 @@ export class Planet {
return getApplicationService();
}
+ /**
+ * @deprecated please use loading signal
+ */
public get loadingDone() {
return this.planetApplicationLoader.loadingDone;
}
+ public get loading() {
+ return this.planetApplicationLoader.loading;
+ }
+
public get appStatusChange(): Observable {
return this.planetApplicationLoader.appStatusChange;
}