RED-7200, rewrite loading service with signals, specifically call stop when needed, remove catch all stop from composite guard postcheck.

This commit is contained in:
George 2023-07-24 11:33:16 +03:00
parent 2524896f46
commit d40f839365
7 changed files with 23 additions and 39 deletions

View File

@ -3,6 +3,9 @@ module.exports = {
env: {
browser: true,
},
globals: {
NodeJS: true,
},
ignorePatterns: ['!**/*'],
overrides: [
{

View File

@ -48,7 +48,6 @@ export class ErrorService {
readonly #loadingService = inject(LoadingService);
readonly #router = inject(Router);
readonly #displayNotification$ = new Subject<string | undefined>();
// eslint-disable-next-line no-undef
#notificationTimeout: Record<string, NodeJS.Timeout | undefined> = {};
#displayedNotificationType: string | undefined;

View File

@ -17,7 +17,7 @@
[class.help-mode-active]="helpModeService?.isHelpModeActive$ | async"
[id]="'item-' + entity.id"
[ngClass]="getTableItemClasses(entity)"
(click)="initiateNavigation(entity.routerLink)"
[routerLink]="entity.routerLink | tenant"
>
<iqser-table-item
(click)="multiSelect(entity, $event)"
@ -31,7 +31,7 @@
[class.help-mode-active]="helpModeService?.isHelpModeActive$ | async"
[id]="'item-' + entity.id"
[ngClass]="getTableItemClasses(entity)"
(click)="initiateNavigation(entity.routerLink)"
[routerLink]="entity.routerLink | tenant"
>
<iqser-table-item
(click)="multiSelect(entity, $event)"

View File

@ -1,5 +1,5 @@
/* eslint-disable @angular-eslint/prefer-on-push-component-change-detection */
import { AfterViewInit, Component, forwardRef, HostListener, inject, Inject, Input, OnDestroy, Optional, ViewChild } from '@angular/core';
import { AfterViewInit, Component, forwardRef, HostListener, Inject, Input, OnDestroy, Optional, ViewChild } from '@angular/core';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { delay, tap } from 'rxjs/operators';
import { AutoUnsubscribe, trackByFactory } from '../../utils';
@ -8,8 +8,6 @@ import { ListingComponent, ListingService } from '../index';
import { BehaviorSubject } from 'rxjs';
import { HelpModeService } from '../../help-mode';
import { HasScrollbarDirective } from '../../directives';
import { TenantsService } from '../../tenants';
import { Router } from '@angular/router';
@Component({
selector: 'iqser-table-content',
@ -32,9 +30,6 @@ export class TableContentComponent<Class extends IListable<PrimaryKey>, PrimaryK
private _lastScrolledIndex = 0;
private _multiSelectActive$ = new BehaviorSubject(false);
readonly #tenantsService = inject(TenantsService);
readonly #router = inject(Router);
#navigationInProgress = false;
constructor(
@Inject(forwardRef(() => ListingComponent)) readonly listingComponent: ListingComponent<Class>,
@ -98,11 +93,4 @@ export class TableContentComponent<Class extends IListable<PrimaryKey>, PrimaryK
private _disableMultiSelect() {
this._multiSelectActive$.next(false);
}
async initiateNavigation(routerLink: string | undefined) {
if (!routerLink || this.#navigationInProgress) return;
this.#navigationInProgress = true;
await this.#router.navigateByUrl('/' + this.#tenantsService.activeTenantId + routerLink);
this.#navigationInProgress = false;
}
}

View File

@ -1,4 +1,4 @@
<ng-container *ngIf="loadingService.isLoading$ | async as config">
<ng-container *ngIf="loadingService.isLoading() as config">
<section class="full-page-section"></section>
<section class="full-page-content">
<mat-spinner *ngIf="config.type === 'spinner'" diameter="40"></mat-spinner>

View File

@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { Injectable, signal } from '@angular/core';
const MIN_LOADING_TIME = 300;
@ -12,34 +11,32 @@ export interface ILoadingConfig {
@Injectable()
export class LoadingService {
readonly #loadingEvent$ = new BehaviorSubject<ILoadingConfig | undefined>(undefined);
readonly isLoading$ = this.#loadingEvent$.asObservable();
readonly #loading = signal<ILoadingConfig | undefined>(undefined);
readonly isLoading = this.#loading.asReadonly();
#loadingStarted = 0;
#timeout?: number;
#stopTimeout: NodeJS.Timeout | undefined;
start(config: ILoadingConfig = { type: 'spinner' }): void {
if (this.#timeout) {
clearTimeout(this.#timeout);
this.#timeout = undefined;
if (this.#stopTimeout) {
clearTimeout(this.#stopTimeout);
this.#stopTimeout = undefined;
}
setTimeout(() => {
this.#loadingEvent$.next(config);
this.#loadingStarted = new Date().getTime();
});
this.#loading.set(config);
this.#loadingStarted = Date.now();
}
update(config: ILoadingConfig): void {
if (!this.#loadingEvent$.value) {
if (!this.isLoading()) {
return this.start(config);
}
this.#loadingEvent$.next(config);
this.#loading.set(config);
}
stop(): void {
const timeSinceStarted = new Date().getTime() - this.#loadingStarted;
const remainingLoadingTime = MIN_LOADING_TIME - timeSinceStarted;
return remainingLoadingTime > 0 ? this._stopAfter(remainingLoadingTime) : this._stop();
return remainingLoadingTime > 0 ? this.#stopAfter(remainingLoadingTime) : this.#stop();
}
loadWhile(func: Promise<unknown>): void {
@ -51,11 +48,11 @@ export class LoadingService {
);
}
private _stop(): void {
setTimeout(() => this.#loadingEvent$.next(undefined));
#stop(): void {
this.#loading.set(undefined);
}
private _stopAfter(timeout: number): void {
this.#timeout = window.setTimeout(() => this._stop(), timeout);
#stopAfter(clearAfter: number): void {
this.#stopTimeout = setTimeout(() => this.#stop(), clearAfter);
}
}

View File

@ -49,7 +49,6 @@ export class CompositeRouteGuard implements CanActivate {
currentRoute = currentRoute.firstChild;
skeleton = currentRoute.data['skeleton'];
}
if (skeleton) {
this._skeletonService.setType(skeleton);
} else {
@ -60,8 +59,6 @@ export class CompositeRouteGuard implements CanActivate {
#postChecks(route: ActivatedRouteSnapshot): void {
if (route.data['skeleton']) {
this._skeletonService.clear();
} else {
this._loadingService.stop();
}
}
}