force reload on same url navigation + refresh after websocket connect

This commit is contained in:
Patrick Haßel 2025-10-31 08:57:47 +01:00
parent 0dff76f598
commit 39a4b94ecc
5 changed files with 47 additions and 14 deletions

View File

@ -6,12 +6,15 @@
<div class="MainMenuItem MainMenuTitle"> <div class="MainMenuItem MainMenuTitle">
{{ menuService.title }} {{ menuService.title }}
</div> </div>
@if(!ws.connected){
<div class="MainMenuItem MainMenuNotConnected">NICHT VERBUNDEN</div>
}
</div> </div>
</div> </div>
<div class="MainMenuDrawer NoUserSelect" [hidden]="!showDrawer"> <div class="MainMenuDrawer NoUserSelect" [hidden]="!showDrawer">
@for (location of locationList; track location.id) { @for (location of locationList; track location.id) {
<div class="MainMenuItem" routerLink="Location/{{ location.id }}" routerLinkActive="MainMenuItemActive" (click)="showDrawer = false">{{ location.name }}</div> <div class="MainMenuItem" (click)="navigate('Location/' + location.id); showDrawer = false" routerLinkActive="MainMenuItemActive">{{ location.name }}</div>
} }
</div> </div>

View File

@ -21,6 +21,14 @@
background-color: lightskyblue; background-color: lightskyblue;
} }
.MainMenuTitle {
flex: 1;
}
.MainMenuNotConnected {
color: red;
}
} }
} }

View File

@ -1,14 +1,15 @@
import {Component, OnDestroy, OnInit} from '@angular/core'; import {Component, OnDestroy, OnInit} from '@angular/core';
import {RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router'; import {Router, RouterLinkActive, RouterOutlet} from '@angular/router';
import {FaIconComponent} from '@fortawesome/angular-fontawesome'; import {FaIconComponent} from '@fortawesome/angular-fontawesome';
import {faBars} from '@fortawesome/free-solid-svg-icons'; import {faBars} from '@fortawesome/free-solid-svg-icons';
import {MenuService} from './menu-service'; import {MenuService} from './menu-service';
import {Location} from './location/Location'; import {Location} from './location/Location';
import {LocationService} from './location/location-service'; import {LocationService} from './location/location-service';
import {WebsocketService} from './common';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
imports: [RouterOutlet, FaIconComponent, RouterLink, RouterLinkActive], imports: [RouterOutlet, FaIconComponent, RouterLinkActive],
templateUrl: './app.html', templateUrl: './app.html',
styleUrl: './app.less' styleUrl: './app.less'
}) })
@ -23,6 +24,8 @@ export class App implements OnInit, OnDestroy {
constructor( constructor(
readonly locationService: LocationService, readonly locationService: LocationService,
readonly menuService: MenuService, readonly menuService: MenuService,
readonly router: Router,
readonly ws: WebsocketService,
) { ) {
// //
} }
@ -36,4 +39,10 @@ export class App implements OnInit, OnDestroy {
this.menuService.title = ""; this.menuService.title = "";
} }
navigate(url: string): void {
this.router.navigateByUrl('/', {skipLocationChange: true}).then(() => {
this.router.navigate([url]);
})
}
} }

View File

@ -71,24 +71,28 @@ export function stompServiceFactory() {
providedIn: 'root' providedIn: 'root'
}) })
export class WebsocketService { export class WebsocketService {
private _connected: boolean = false;
get connected(): boolean {
return this._connected;
}
constructor( constructor(
readonly stompService: StompService, readonly stompService: StompService,
) { ) {
this.websocketConnected(() => this._websocketError = false); this.onChange(connected => this._connected = connected);
this.websocketDisconnected(() => this._websocketError = true);
} }
private _websocketError: boolean = false; onChange(next: Next<boolean>): Subscription {
return this.stompService.connectionState$.pipe(map(state => state === RxStompState.OPEN)).subscribe(next);
get websocketError(): boolean {
return this._websocketError;
} }
websocketConnected(next: Next<void>): Subscription { onConnect(next: Next<void>): Subscription {
return this.stompService.connectionState$.pipe(filter(state => state === RxStompState.OPEN)).subscribe(_ => next()); return this.stompService.connectionState$.pipe(filter(state => state === RxStompState.OPEN)).subscribe(_ => next());
} }
websocketDisconnected(next: Next<void>): Subscription { onDisconnect(next: Next<void>): Subscription {
return this.stompService.connectionState$.pipe(filter(state => state !== RxStompState.OPEN)).subscribe(_ => next()); return this.stompService.connectionState$.pipe(filter(state => state !== RxStompState.OPEN)).subscribe(_ => next());
} }

View File

@ -13,6 +13,7 @@ import {SeriesHistory} from './history/series-history';
import {Interval} from '../../series/Interval'; import {Interval} from '../../series/Interval';
import {MenuService} from '../../menu-service'; import {MenuService} from '../../menu-service';
import {DatePipe} from '@angular/common'; import {DatePipe} from '@angular/common';
import {WebsocketService} from '../../common';
function yesterday(now: any) { function yesterday(now: any) {
const yesterday = new Date(now.getTime()); const yesterday = new Date(now.getTime());
@ -56,19 +57,26 @@ export class LocationDetail implements OnInit, OnDestroy {
readonly seriesService: SeriesService, readonly seriesService: SeriesService,
readonly activatedRoute: ActivatedRoute, readonly activatedRoute: ActivatedRoute,
readonly menuService: MenuService, readonly menuService: MenuService,
readonly websocketService: WebsocketService,
@Inject(LOCALE_ID) readonly locale: string, @Inject(LOCALE_ID) readonly locale: string,
) { ) {
this.datePipe = new DatePipe(locale); this.datePipe = new DatePipe(locale);
} }
ngOnInit(): void { ngOnInit(): void {
this.activatedRoute.params.subscribe(params => { this.subs.push(this.websocketService.onChange((connected) => {
if (connected) {
this.seriesService.findAll(list => this.series = list);
} else {
this.location = null;
}
}));
this.subs.push(this.activatedRoute.params.subscribe(params => {
this.locationService.getById(params['id'], location => { this.locationService.getById(params['id'], location => {
this.location = location; this.location = location;
this.menuService.title = this.location.name; this.menuService.title = this.location.name;
}); });
}); }));
this.seriesService.findAll(list => this.series = list);
this.subs.push(this.seriesService.subscribe(this.updateSeries)); this.subs.push(this.seriesService.subscribe(this.updateSeries));
this.subs.push(timer(1000, 1000).subscribe(() => { this.subs.push(timer(1000, 1000).subscribe(() => {
this.now = new Date(); this.now = new Date();
@ -77,6 +85,7 @@ export class LocationDetail implements OnInit, OnDestroy {
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.location = null;
this.menuService.title = ""; this.menuService.title = "";
this.subs.forEach(sub => sub.unsubscribe()); this.subs.forEach(sub => sub.unsubscribe());
} }