Merge pull request #12416 from maxunbearable/fix/2073-empty-notifications

Fixed empty notifications on slow WS connection
This commit is contained in:
Igor Kulikov 2025-01-10 19:13:13 +02:00 committed by GitHub
commit bfc8b878a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 29 deletions

View File

@ -18,13 +18,13 @@
<section class="flex flex-row items-center justify-between" style="margin: 0 10px 4px; min-height: 36px"> <section class="flex flex-row items-center justify-between" style="margin: 0 10px 4px; min-height: 36px">
<div style="font-weight: 500; letter-spacing: .25px" translate>notification.notification</div> <div style="font-weight: 500; letter-spacing: .25px" translate>notification.notification</div>
<button mat-button color="primary" <button mat-button color="primary"
*ngIf="(notifications$ | async).length" *ngIf="(notifications$ | async)?.length"
(click)="markAsAllRead($event)"> (click)="markAsAllRead($event)">
{{ 'notification.mark-all-as-read' | translate }} {{ 'notification.mark-all-as-read' | translate }}
</button> </button>
</section> </section>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<ng-container *ngIf="loadNotification; else loadingNotification"> <ng-container *ngIf="notifications$ | async; else loadingNotification">
<div *ngIf="(notifications$ | async).length; else emptyNotification" style="overflow: auto"> <div *ngIf="(notifications$ | async).length; else emptyNotification" style="overflow: auto">
<section style="min-height: 100px; overflow: auto; padding: 6px 0;"> <section style="min-height: 100px; overflow: auto; padding: 6px 0;">
<div *ngFor="let notification of (notifications$ | async); let last = last; trackBy: trackById"> <div *ngFor="let notification of (notifications$ | async); let last = last; trackBy: trackById">

View File

@ -14,24 +14,25 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { ChangeDetectorRef, Component, Input, NgZone, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectorRef, Component, Input, NgZone, OnDestroy } from '@angular/core';
import { PageComponent } from '@shared/components/page.component'; import { PageComponent } from '@shared/components/page.component';
import { TbPopoverComponent } from '@shared/components/popover.component'; import { TbPopoverComponent } from '@shared/components/popover.component';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { Notification, NotificationRequest } from '@shared/models/notification.models'; import { Notification, NotificationRequest } from '@shared/models/notification.models';
import { NotificationWebsocketService } from '@core/ws/notification-websocket.service'; import { NotificationWebsocketService } from '@core/ws/notification-websocket.service';
import { BehaviorSubject, Observable, ReplaySubject, Subscription } from 'rxjs'; import { BehaviorSubject, Observable, shareReplay } from 'rxjs';
import { map, share, skip, tap } from 'rxjs/operators'; import { filter, skip, tap } from 'rxjs/operators';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { NotificationSubscriber } from '@shared/models/telemetry/telemetry.models'; import { NotificationSubscriber } from '@shared/models/telemetry/telemetry.models';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({ @Component({
selector: 'tb-show-notification-popover', selector: 'tb-show-notification-popover',
templateUrl: './show-notification-popover.component.html', templateUrl: './show-notification-popover.component.html',
styleUrls: ['show-notification-popover.component.scss'] styleUrls: ['show-notification-popover.component.scss']
}) })
export class ShowNotificationPopoverComponent extends PageComponent implements OnDestroy, OnInit { export class ShowNotificationPopoverComponent extends PageComponent implements OnDestroy {
@Input() @Input()
onClose: () => void; onClose: () => void;
@ -42,11 +43,13 @@ export class ShowNotificationPopoverComponent extends PageComponent implements O
@Input() @Input()
popoverComponent: TbPopoverComponent; popoverComponent: TbPopoverComponent;
private notificationSubscriber: NotificationSubscriber; private notificationSubscriber = NotificationSubscriber.createNotificationsSubscription(this.notificationWsService, this.zone, 6);
private notificationCountSubscriber: Subscription;
notifications$: Observable<Notification[]>; notifications$: Observable<Notification[]> = this.notificationSubscriber.notifications$.pipe(
loadNotification = false; filter(value => Array.isArray(value)),
shareReplay(1),
tap(() => setTimeout(() => this.cd.markForCheck()))
);
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
private notificationWsService: NotificationWebsocketService, private notificationWsService: NotificationWebsocketService,
@ -54,32 +57,15 @@ export class ShowNotificationPopoverComponent extends PageComponent implements O
private cd: ChangeDetectorRef, private cd: ChangeDetectorRef,
private router: Router) { private router: Router) {
super(store); super(store);
} this.notificationSubscriber.notificationCount$.pipe(
ngOnInit() {
this.notificationSubscriber = NotificationSubscriber.createNotificationsSubscription(this.notificationWsService, this.zone, 6);
this.notifications$ = this.notificationSubscriber.notifications$.pipe(
map(value => {
if (Array.isArray(value)) {
this.loadNotification = true;
return value;
}
return [];
}),
share({
connector: () => new ReplaySubject(1)
}),
tap(() => setTimeout(() => this.cd.markForCheck()))
);
this.notificationCountSubscriber = this.notificationSubscriber.notificationCount$.pipe(
skip(1), skip(1),
takeUntilDestroyed()
).subscribe(value => this.counter.next(value)); ).subscribe(value => this.counter.next(value));
this.notificationSubscriber.subscribe(); this.notificationSubscriber.subscribe();
} }
ngOnDestroy() { ngOnDestroy() {
super.ngOnDestroy(); super.ngOnDestroy();
this.notificationCountSubscriber.unsubscribe();
this.notificationSubscriber.unsubscribe(); this.notificationSubscriber.unsubscribe();
this.onClose(); this.onClose();
} }