Skip to content

Commit 5034351

Browse files
committed
feat: add loading signal for planet
1 parent 3b46b76 commit 5034351

File tree

5 files changed

+37
-45
lines changed

5 files changed

+37
-45
lines changed

examples/portal/src/app/app.component.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@
3939
</thy-nav>
4040
</thy-sidebar>
4141
</div>
42-
<div id="app-host-container" class="thy-layout" [ngClass]="{ hide: !loadingDone }">
42+
<div id="app-host-container" class="thy-layout" [ngClass]="{ hide: loading() }">
4343
<div class="portal portal-container">
4444
<router-outlet></router-outlet>
4545
</div>
4646
</div>
47-
48-
<thy-loading class="portal" *ngIf="!loadingDone" [thyDone]="loadingDone"></thy-loading>
47+
@if (loading(); as loadingState) {
48+
<thy-loading class="portal" [thyDone]="!loadingState"></thy-loading>
49+
}
4950
</thy-layout>

examples/portal/src/app/app.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export class AppComponent implements OnInit {
1919

2020
activeAppNames: string[] = [];
2121

22-
get loadingDone() {
23-
return this.planet.loadingDone;
22+
get loading() {
23+
return this.planet.loading;
2424
}
2525

2626
constructor(

packages/planet/src/application/planet-application-loader.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,11 @@ class AppStatusChangeFaker {
8787
expect(this.spy).toHaveBeenCalledTimes(fromCalledTimes + 1);
8888
expect(this.spy).toHaveBeenCalledWith({ app: expectedApp, status: ApplicationStatus.bootstrapping });
8989
expect(this.planetApplicationLoader.loadingDone).toBe(false);
90+
expect(this.planetApplicationLoader.loading()).toBe(true);
9091
appRefFaker.bootstrap();
9192
expect(this.planetApplicationLoader.loadingDone).toBe(true);
93+
expect(this.planetApplicationLoader.loading()).toBe(false);
94+
9295
expect(this.spy).toHaveBeenCalledTimes(fromCalledTimes + 3);
9396

9497
expect(this.spy).toHaveBeenCalledWith({ app: expectedApp, status: ApplicationStatus.bootstrapped });

packages/planet/src/application/planet-application-loader.ts

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, NgZone, ApplicationRef, Injector } from '@angular/core';
1+
import { Injectable, NgZone, ApplicationRef, Injector, computed, signal } from '@angular/core';
22
import { of, Observable, Subject, forkJoin, from, throwError } from 'rxjs';
33
import { AssetsLoader } from '../assets-loader';
44
import { PlanetApplication, PlanetRouterEvent, SwitchModes, PlanetOptions } from '../planet.class';
@@ -54,6 +54,8 @@ export class PlanetApplicationLoader {
5454

5555
private appsLoadingStart$ = new Subject<AppsLoadingStartEvent>();
5656

57+
private innerLoading = signal(false);
58+
5759
public get appStatusChange(): Observable<AppStatusChangeEvent> {
5860
return this.appStatusChange$.asObservable();
5961
}
@@ -62,8 +64,13 @@ export class PlanetApplicationLoader {
6264
return this.appsLoadingStart$.asObservable();
6365
}
6466

67+
/**
68+
* @deprecated please use loading signal
69+
*/
6570
public loadingDone = false;
6671

72+
public loading = this.innerLoading.asReadonly();
73+
6774
constructor(
6875
private assetsLoader: AssetsLoader,
6976
private planetApplicationService: PlanetApplicationService,
@@ -73,9 +80,7 @@ export class PlanetApplicationLoader {
7380
applicationRef: ApplicationRef
7481
) {
7582
if (getApplicationLoader()) {
76-
throw new Error(
77-
'PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed'
78-
);
83+
throw new Error('PlanetApplicationLoader has been injected in the portal, repeated injection is not allowed');
7984
}
8085

8186
this.options = {
@@ -97,9 +102,7 @@ export class PlanetApplicationLoader {
97102
this.ngZone.run(() => {
98103
const fromStatus = this.appsStatus.get(app);
99104
debug(
100-
`app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${
101-
ApplicationStatus[status]
102-
}`
105+
`app(${app.name}) status change: ${fromStatus ? ApplicationStatus[fromStatus] : 'empty'} => ${ApplicationStatus[status]}`
103106
);
104107
this.appsStatus.set(app, status);
105108
this.appStatusChange$.next({
@@ -109,10 +112,7 @@ export class PlanetApplicationLoader {
109112
});
110113
}
111114

112-
private getAppStatusChange$(
113-
app: PlanetApplication,
114-
status = ApplicationStatus.bootstrapped
115-
): Observable<PlanetApplication> {
115+
private getAppStatusChange$(app: PlanetApplication, status = ApplicationStatus.bootstrapped): Observable<PlanetApplication> {
116116
return this.appStatusChange.pipe(
117117
filter(event => {
118118
return event.app === app && event.status === status;
@@ -140,6 +140,7 @@ export class PlanetApplicationLoader {
140140
private setLoadingDone() {
141141
this.ngZone.run(() => {
142142
this.loadingDone = true;
143+
this.innerLoading.set(false);
143144
});
144145
}
145146

@@ -188,9 +189,7 @@ export class PlanetApplicationLoader {
188189
appStatus === ApplicationStatus.loadError
189190
) {
190191
debug(
191-
`app(${app.name}) status is ${
192-
ApplicationStatus[appStatus as ApplicationStatus]
193-
}, start load assets`
192+
`app(${app.name}) status is ${ApplicationStatus[appStatus as ApplicationStatus]}, start load assets`
194193
);
195194
hasAppsNeedLoadingAssets = true;
196195
return this.ngZone.runOutsideAngular(() => {
@@ -202,6 +201,7 @@ export class PlanetApplicationLoader {
202201
});
203202
if (hasAppsNeedLoadingAssets) {
204203
this.loadingDone = false;
204+
this.innerLoading.set(true);
205205
}
206206
return loadApps$.length > 0 ? forkJoin(loadApps$) : of([] as PlanetApplication[]);
207207
}),
@@ -212,19 +212,15 @@ export class PlanetApplicationLoader {
212212
switchMap(app => {
213213
const appStatus = this.appsStatus.get(app);
214214
if (appStatus === ApplicationStatus.bootstrapped) {
215-
debug(
216-
`[routeChange] app(${app.name}) status is bootstrapped, show app and active`
217-
);
215+
debug(`[routeChange] app(${app.name}) status is bootstrapped, show app and active`);
218216
this.showApp(app);
219217
const appRef = getPlanetApplicationRef(app.name);
220218
appRef?.navigateByUrl(event.url);
221219
this.setAppStatus(app, ApplicationStatus.active);
222220
this.setLoadingDone();
223221
return of(app);
224222
} else if (appStatus === ApplicationStatus.assetsLoaded) {
225-
debug(
226-
`[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`
227-
);
223+
debug(`[routeChange] app(${app.name}) status is assetsLoaded, start bootstrapping`);
228224
return this.bootstrapApp(app).pipe(
229225
map(() => {
230226
debug(`app(${app.name}) bootstrapped success, active it`);
@@ -237,9 +233,7 @@ export class PlanetApplicationLoader {
237233
debug(`[routeChange] app(${app.name}) is active, do nothings`);
238234
const appRef = getPlanetApplicationRef(app.name);
239235
// Backwards compatibility sub app use old version which has not getCurrentRouterStateUrl
240-
const currentUrl = appRef?.getCurrentRouterStateUrl
241-
? appRef.getCurrentRouterStateUrl()
242-
: '';
236+
const currentUrl = appRef?.getCurrentRouterStateUrl ? appRef.getCurrentRouterStateUrl() : '';
243237
if (currentUrl !== event.url) {
244238
appRef?.navigateByUrl(event.url);
245239
}
@@ -253,9 +247,7 @@ export class PlanetApplicationLoader {
253247
return this.getAppStatusChange$(app).pipe(
254248
take(1),
255249
map(() => {
256-
debug(
257-
`app(${app.name}) status is bootstrapped by subscribe status change, active it`
258-
);
250+
debug(`app(${app.name}) status is bootstrapped by subscribe status change, active it`);
259251
this.setAppStatus(app, ApplicationStatus.active);
260252
this.showApp(app);
261253
return app;
@@ -355,10 +347,7 @@ export class PlanetApplicationLoader {
355347
}
356348
}
357349

358-
private bootstrapApp(
359-
app: PlanetApplication,
360-
defaultStatus: 'hidden' | 'display' = 'display'
361-
): Observable<PlanetApplicationRef> {
350+
private bootstrapApp(app: PlanetApplication, defaultStatus: 'hidden' | 'display' = 'display'): Observable<PlanetApplicationRef> {
362351
debug(`app(${app.name}) start bootstrapping`);
363352
this.setAppStatus(app, ApplicationStatus.bootstrapping);
364353
const appRef = getPlanetApplicationRef(app.name);
@@ -517,11 +506,7 @@ export class PlanetApplicationLoader {
517506
return getPlanetApplicationRef(app.name);
518507
})
519508
);
520-
} else if (
521-
[ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(
522-
status
523-
)
524-
) {
509+
} else if ([ApplicationStatus.assetsLoading, ApplicationStatus.assetsLoaded, ApplicationStatus.bootstrapping].includes(status)) {
525510
debug(`preload app(${app.name}), status is ${ApplicationStatus[status]}, return until bootstrapped`);
526511
return this.getAppStatusChange$(app).pipe(
527512
take(1),

packages/planet/src/planet.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { Injectable, Inject, Optional, Injector } from '@angular/core';
22
import { NavigationEnd, RouterEvent, Router } from '@angular/router';
33
import { PlanetOptions, PlanetApplication, PLANET_APPLICATIONS } from './planet.class';
44
import { PlanetApplicationService } from './application/planet-application.service';
5-
import {
6-
PlanetApplicationLoader,
7-
AppsLoadingStartEvent,
8-
AppStatusChangeEvent
9-
} from './application/planet-application-loader';
5+
import { PlanetApplicationLoader, AppsLoadingStartEvent, AppStatusChangeEvent } from './application/planet-application-loader';
106
import { Observable, Subscription } from 'rxjs';
117
import { filter, startWith, distinctUntilChanged, map } from 'rxjs/operators';
128
import {
@@ -30,10 +26,17 @@ export class Planet {
3026
return getApplicationService();
3127
}
3228

29+
/**
30+
* @deprecated please use loading signal
31+
*/
3332
public get loadingDone() {
3433
return this.planetApplicationLoader.loadingDone;
3534
}
3635

36+
public get loading() {
37+
return this.planetApplicationLoader.loading;
38+
}
39+
3740
public get appStatusChange(): Observable<AppStatusChangeEvent> {
3841
return this.planetApplicationLoader.appStatusChange;
3942
}

0 commit comments

Comments
 (0)