]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/blob
a644300d6904831349651e06e39c129d3d3f55a3
[ceph.git] /
1 import {
2   ChangeDetectionStrategy,
3   Component,
4   inject,
5   Input,
6   ViewEncapsulation
7 } from '@angular/core';
8 import { SkeletonModule, ButtonModule, LinkModule } from 'carbon-components-angular';
9 import { ProductiveCardComponent } from '~/app/shared/components/productive-card/productive-card.component';
10 import { RouterModule } from '@angular/router';
11 import { ComponentsModule } from '~/app/shared/components/components.module';
12 import { SummaryService } from '~/app/shared/services/summary.service';
13 import { Summary } from '~/app/shared/models/summary.model';
14 import { combineLatest, Observable, of, ReplaySubject } from 'rxjs';
15 import { CommonModule } from '@angular/common';
16 import { PipesModule } from '~/app/shared/pipes/pipes.module';
17 import { UpgradeInfoInterface } from '~/app/shared/models/upgrade.interface';
18 import { UpgradeService } from '~/app/shared/api/upgrade.service';
19 import { catchError, filter, map, startWith } from 'rxjs/operators';
20
21 type OverviewHealthData = {
22   summary: Summary;
23   upgrade: UpgradeInfoInterface;
24   currentHealth: Health;
25 };
26
27 type Health = {
28   message: string;
29   title: string;
30   icon: string;
31 };
32
33 type HealthStatus = 'HEALTH_OK' | 'HEALTH_WARN' | 'HEALTH_ERR';
34 const WarnAndErrMessage = $localize`There are active alerts and unresolved health warnings.`;
35
36 const HealthMap: Record<HealthStatus, Health> = {
37   HEALTH_OK: {
38     message: $localize`All core services are running normally`,
39     icon: 'success',
40     title: $localize`Healthy`
41   },
42   HEALTH_WARN: {
43     message: WarnAndErrMessage,
44     icon: 'warningAltFilled',
45     title: $localize`Warning`
46   },
47   HEALTH_ERR: {
48     message: WarnAndErrMessage,
49     icon: 'error',
50     title: $localize`Critical`
51   }
52 };
53
54 @Component({
55   selector: 'cd-overview-health-card',
56   imports: [
57     CommonModule,
58     ProductiveCardComponent,
59     SkeletonModule,
60     ButtonModule,
61     RouterModule,
62     ComponentsModule,
63     LinkModule,
64     PipesModule
65   ],
66   standalone: true,
67   templateUrl: './overview-health-card.component.html',
68   styleUrl: './overview-health-card.component.scss',
69   encapsulation: ViewEncapsulation.None,
70   changeDetection: ChangeDetectionStrategy.OnPush
71 })
72 export class OverviewHealthCardComponent {
73   @Input() fsid!: string;
74   @Input()
75   set health(value: HealthStatus) {
76     this.health$.next(value);
77   }
78   private health$ = new ReplaySubject<HealthStatus>(1);
79
80   private readonly summaryService = inject(SummaryService);
81   private readonly upgradeService = inject(UpgradeService);
82
83   readonly data$: Observable<OverviewHealthData> = combineLatest([
84     this.summaryService.summaryData$.pipe(filter((summary): summary is Summary => !!summary)),
85
86     this.upgradeService.listCached().pipe(
87       startWith(null as UpgradeInfoInterface),
88       catchError(() => of(null))
89     ),
90     this.health$
91   ]).pipe(
92     map(([summary, upgrade, health]) => ({ summary, upgrade, currentHealth: HealthMap?.[health] }))
93   );
94 }