refs #1727 Add StatusTab component to Global Status for enhanced service and disk usage display
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
parent
9f9d73644b
commit
50755bd1d5
|
@ -135,6 +135,7 @@ import { registerLocaleData } from '@angular/common';
|
|||
import localeEs from '@angular/common/locales/es';
|
||||
import { GlobalStatusComponent } from './components/global-status/global-status.component';
|
||||
import { ShowImagesComponent } from './components/repositories/show-images/show-images.component';
|
||||
import { StatusTabComponent } from './components/global-status/status-tab/status-tab.component';
|
||||
|
||||
export function HttpLoaderFactory(http: HttpClient) {
|
||||
return new TranslateHttpLoader(http, './locale/', '.json');
|
||||
|
@ -229,7 +230,8 @@ registerLocaleData(localeEs, 'es-ES');
|
|||
OperationResultDialogComponent,
|
||||
ConvertImageComponent,
|
||||
GlobalStatusComponent,
|
||||
ShowImagesComponent
|
||||
ShowImagesComponent,
|
||||
StatusTabComponent
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
imports: [BrowserModule,
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
.dashboard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.disk-usage-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.disk-usage {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.service-list {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.services-status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.services-status li {
|
||||
margin: 5px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-led {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.status-led.active {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.status-led.inactive {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.disk-title {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.service-title {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f4f4f4;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<app-loading [isLoading]="loading"></app-loading>
|
||||
<div *ngIf="!loading" class="dashboard">
|
||||
<!-- Disk Usage Section -->
|
||||
<div class="disk-usage-container">
|
||||
<h3 class="disk-title">{{ 'diskUsageTitle' | translate }}</h3>
|
||||
<div class="disk-usage" joyrideStep="diskUsageStep" text="{{ 'diskUsageDescription' | translate }}">
|
||||
<ngx-charts-pie-chart [view]="view" [scheme]="colorScheme" [results]="diskUsageChartData" [doughnut]="isDoughnut"
|
||||
[labels]="showLabels">
|
||||
</ngx-charts-pie-chart>
|
||||
<div class="disk-usage-info">
|
||||
<p>{{ 'totalLabel' | translate }}: <strong>{{ formatBytes(diskUsage.total) }}</strong>
|
||||
</p>
|
||||
<p>{{ 'usedLabel' | translate }}: <strong>{{ formatBytes(diskUsage.used) }}</strong>
|
||||
</p>
|
||||
<p>{{ 'availableLabel' | translate }}: <strong>{{ formatBytes(diskUsage.available)
|
||||
}}</strong></p>
|
||||
<p>{{ 'freeLabel' | translate }}: <strong>{{ diskUsage.percentage }}</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Services Status Section -->
|
||||
<div class="services-status" joyrideStep="servicesStatusStep" text="{{ 'servicesStatusDescription' | translate }}">
|
||||
<h3 class="service-title">{{ 'servicesTitle' | translate }}</h3>
|
||||
<ul class="service-list">
|
||||
<li *ngFor="let service of getServices()">
|
||||
<span class="status-led"
|
||||
[ngClass]="{ 'active': service.status === 'active', 'inactive': service.status !== 'active' }"></span>
|
||||
{{ service.name }}: {{ service.status | translate }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Installed OgLives Section -->
|
||||
<div class="installed-oglives" joyrideStep="oglivesStep" text="{{ 'oglivesDescription' | translate }}">
|
||||
<h3>{{ 'installedOglivesTitle' | translate }}</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'idLabel' | translate }}</th>
|
||||
<th>{{ 'kernelLabel' | translate }}</th>
|
||||
<th>{{ 'architectureLabel' | translate }}</th>
|
||||
<th>{{ 'revisionLabel' | translate }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let oglive of installedOgLives">
|
||||
<td>{{ oglive.id }}</td>
|
||||
<td>{{ oglive.kernel }}</td>
|
||||
<td>{{ oglive.architecture }}</td>
|
||||
<td>{{ oglive.revision }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,49 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { LoadingComponent } from 'src/app/shared/loading/loading.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { StatusTabComponent } from './status-tab.component';
|
||||
|
||||
describe('StatusTabComponent', () => {
|
||||
let component: StatusTabComponent;
|
||||
let fixture: ComponentFixture<StatusTabComponent>;
|
||||
|
||||
const mockConfigService = {
|
||||
apiUrl: 'http://mock-api-url'
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [StatusTabComponent, LoadingComponent],
|
||||
imports: [
|
||||
HttpClientTestingModule,
|
||||
ToastrModule.forRoot(),
|
||||
MatDialogModule,
|
||||
MatTabsModule,
|
||||
TranslateModule.forRoot(),
|
||||
NgxChartsModule,
|
||||
BrowserAnimationsModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: ConfigService, useValue: mockConfigService }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(StatusTabComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-status-tab',
|
||||
templateUrl: './status-tab.component.html',
|
||||
styleUrl: './status-tab.component.css'
|
||||
})
|
||||
export class StatusTabComponent {
|
||||
@Input() loading: boolean = false;
|
||||
@Input() diskUsage: any = {};
|
||||
@Input() servicesStatus: any = {};
|
||||
@Input() installedOgLives: any[] = [];
|
||||
@Input() diskUsageChartData: any[] = [];
|
||||
@Input() showLabels: boolean = true;
|
||||
@Input() isDoughnut: boolean = true;
|
||||
@Input() colorScheme: any = {
|
||||
domain: ['#df200d', '#26a700']
|
||||
};
|
||||
@Input() view: [number, number] = [400, 220];
|
||||
|
||||
getServices(): { name: string, status: string }[] {
|
||||
if (!this.servicesStatus) {
|
||||
return [];
|
||||
}
|
||||
const services = Object.keys(this.servicesStatus).map(key => ({
|
||||
name: key,
|
||||
status: this.servicesStatus[key]
|
||||
}))
|
||||
return services;
|
||||
}
|
||||
|
||||
formatBytes(bytes: number): string {
|
||||
if (bytes >= 1e9) {
|
||||
return (bytes / 1e9).toFixed(2) + ' GB';
|
||||
} else if (bytes >= 1e6) {
|
||||
return (bytes / 1e6).toFixed(2) + ' MB';
|
||||
} else if (bytes >= 1e3) {
|
||||
return (bytes / 1e3).toFixed(2) + ' KB';
|
||||
} else {
|
||||
return bytes + ' B';
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue