import { Component, Inject, OnInit, OnDestroy, ViewEncapsulation } from '@angular/core';
import { Router, RouterOutlet, NavigationEnd } from '@angular/router';
import { MatTabsModule } from '@angular/material/tabs';
import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';
import { I18nService } from '../../services/i18n.service';
import { SocketService } from '../../services/socket.service';
import { CommonService } from '../../services/common.service';
import { MonitoringDataService } from './monitoring-data.service';
import { RedisStateService } from '../../services/redis-state.service';
require('./monitoring-shell.component.scss');
@Component({
selector: 'p3xr-monitoring-shell',
standalone: true,
imports: [RouterOutlet, MatTabsModule],
template: `
`,
encapsulation: ViewEncapsulation.None,
})
export class MonitoringShellComponent implements OnInit, OnDestroy {
strings;
selectedTab = 0;
private readonly routes = ['/monitoring', '/monitoring/profiler', '/monitoring/pubsub', '/monitoring/analysis'];
private routerSub?: Subscription;
private subs: Subscription[] = [];
private servicesStarted = false;
constructor(
@Inject(I18nService) private readonly i18n: I18nService,
@Inject(Router) private readonly router: Router,
@Inject(SocketService) private readonly socket: SocketService,
@Inject(CommonService) private readonly common: CommonService,
@Inject(MonitoringDataService) private readonly data: MonitoringDataService,
@Inject(RedisStateService) private readonly state: RedisStateService,
) {
this.strings = this.i18n.strings;
}
ngOnInit(): void {
this.syncTab(this.router.url);
this.routerSub = this.router.events
.pipe(filter(e => e instanceof NavigationEnd))
.subscribe((e: NavigationEnd) => this.syncTab(e.urlAfterRedirects));
// Redirect to settings on Redis disconnect
this.subs.push(this.socket.redisDisconnected$.subscribe(() => {
this.router.navigate(['/settings']);
}));
// If connected, start immediately; otherwise wait for connection
if (this.state.connection()) {
this.initServices();
} else {
this.subs.push(this.socket.stateChanged$.subscribe(() => {
if (this.state.connection() && !this.servicesStarted) {
this.initServices();
}
}));
}
}
ngOnDestroy(): void {
this.data.stopProfiler();
this.data.stopPubSub();
this.data.destroy();
this.routerSub?.unsubscribe();
this.subs.forEach(s => s.unsubscribe());
}
private initServices(): void {
this.servicesStarted = true;
this.data.init(this.socket, () => this.i18n.currentLang());
this.startServices();
}
private async startServices(): Promise {
try {
await this.data.startProfiler();
} catch (e) {
this.common.generalHandleError(e);
}
try {
await this.data.startPubSub();
} catch (e) {
this.common.generalHandleError(e);
}
}
onTabChange(index: number): void {
if (index >= 0 && index < this.routes.length) {
this.router.navigate([this.routes[index]]);
}
}
private syncTab(url: string): void {
if (url.startsWith('/monitoring/profiler')) {
this.selectedTab = 1;
} else if (url.startsWith('/monitoring/pubsub')) {
this.selectedTab = 2;
} else if (url.startsWith('/monitoring/analysis')) {
this.selectedTab = 3;
} else {
this.selectedTab = 0;
}
}
}