refs #2501. Panel logs integration
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
3270f75f15
commit
fbdcfdb3ea
|
@ -184,6 +184,21 @@ mat-dialog-content {
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
.overview-card.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.overview-card.clickable:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.overview-card.clickable:active {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.overview-icon {
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
border-radius: 50%;
|
||||
|
@ -215,6 +230,28 @@ mat-dialog-content {
|
|||
color: #6c757d;
|
||||
}
|
||||
|
||||
.click-hint {
|
||||
margin-top: 0.5rem !important;
|
||||
font-size: 0.75rem !important;
|
||||
color: #667eea !important;
|
||||
font-weight: 500;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.hint-icon {
|
||||
font-size: 0.875rem !important;
|
||||
width: 0.875rem !important;
|
||||
height: 0.875rem !important;
|
||||
}
|
||||
|
||||
.overview-card.clickable:hover .click-hint {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ===== BADGES DE ESTADO ===== */
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
|
@ -554,4 +591,296 @@ mat-dialog-content {
|
|||
margin: 0;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ===== SECCIÓN DE LOGS ===== */
|
||||
.logs-section {
|
||||
margin-top: 2rem;
|
||||
padding: 1.5rem;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.logs-header {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.logs-header h3 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.logs-header h3::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.logs-header p {
|
||||
margin: 0;
|
||||
font-size: 0.9rem;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.logs-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.ogboot-logs-iframe {
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
background: white;
|
||||
}
|
||||
|
||||
.dhcp-logs-iframe {
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* Responsive para logs */
|
||||
@media (max-width: 768px) {
|
||||
.logs-section {
|
||||
margin-top: 1.5rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.logs-container {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.ogboot-logs-iframe {
|
||||
width: 100% !important;
|
||||
height: 150px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== TARJETAS ACTIVAS ===== */
|
||||
.overview-card.clickable.active {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.overview-card.clickable.active .overview-icon {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.overview-card.clickable.active .status-badge {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.overview-card.clickable.active .click-hint {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.overview-card.clickable.active h3 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.overview-card.clickable.active p {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
/* ===== CONTENIDO DINÁMICO ===== */
|
||||
.dynamic-content {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
animation: fadeInUp 0.6s ease-out;
|
||||
}
|
||||
|
||||
.section-content {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* ===== HEADER DE SECCIÓN Y BOTÓN DE LOGS ===== */
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 2px solid #e9ecef;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.section-header h2::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.logs-button {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 25px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.logs-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
|
||||
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
|
||||
}
|
||||
|
||||
.logs-button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.logs-button mat-icon {
|
||||
font-size: 1.1rem;
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
}
|
||||
|
||||
/* Responsive para el header de sección */
|
||||
@media (max-width: 768px) {
|
||||
.section-header {
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.logs-button {
|
||||
padding: 0.5rem 1.25rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.logs-button mat-icon {
|
||||
font-size: 1rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== HEADER DE SECCIÓN Y BOTÓN DE LOGS ===== */
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 2px solid #e9ecef;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.section-header h2::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.logs-button {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 25px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.logs-button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
|
||||
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
|
||||
}
|
||||
|
||||
.logs-button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.logs-button mat-icon {
|
||||
font-size: 1.1rem;
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
}
|
||||
|
||||
/* Responsive para el header de sección */
|
||||
@media (max-width: 768px) {
|
||||
.section-header {
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.logs-button {
|
||||
padding: 0.5rem 1.25rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.logs-button mat-icon {
|
||||
font-size: 1rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
<!-- Header con bienvenida -->
|
||||
<div class="welcome-header">
|
||||
<div class="welcome-content">
|
||||
<div class="welcome-icon">
|
||||
|
@ -17,9 +16,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contenido principal -->
|
||||
<mat-dialog-content [ngClass]="{'loading': loading}">
|
||||
<!-- Spinner de carga -->
|
||||
<div class="spinner-container" *ngIf="loading">
|
||||
<div class="loading-content">
|
||||
<mat-spinner class="loading-spinner"></mat-spinner>
|
||||
|
@ -27,11 +24,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contenido principal cuando no está cargando -->
|
||||
<div *ngIf="!loading" class="main-content">
|
||||
<!-- Resumen rápido del sistema -->
|
||||
<div class="system-overview">
|
||||
<div class="overview-card">
|
||||
<div class="overview-card clickable"
|
||||
[ngClass]="{'active': selectedSection === 'repositories'}"
|
||||
(click)="selectSection('repositories')">
|
||||
<div class="overview-icon">
|
||||
<mat-icon>cloud</mat-icon>
|
||||
</div>
|
||||
|
@ -41,7 +38,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview-card">
|
||||
<div class="overview-card clickable"
|
||||
[ngClass]="{'active': selectedSection === 'ogboot'}"
|
||||
(click)="selectSection('ogboot')">
|
||||
<div class="overview-icon">
|
||||
<mat-icon>storage</mat-icon>
|
||||
</div>
|
||||
|
@ -52,7 +51,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview-card">
|
||||
<div class="overview-card clickable"
|
||||
[ngClass]="{'active': selectedSection === 'dhcp'}"
|
||||
(click)="selectSection('dhcp')">
|
||||
<div class="overview-icon">
|
||||
<mat-icon>router</mat-icon>
|
||||
</div>
|
||||
|
@ -62,11 +63,22 @@
|
|||
<p *ngIf="errorDhcp">Estado: <span class="status-badge offline">Error</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview-card clickable"
|
||||
[ngClass]="{'active': selectedSection === 'ogcore'}"
|
||||
(click)="selectSection('ogcore')">
|
||||
<div class="overview-icon">
|
||||
<mat-icon>dns</mat-icon>
|
||||
</div>
|
||||
<div class="overview-content">
|
||||
<h3>OgCore Server</h3>
|
||||
<p>Logs del servidor</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tabs principales -->
|
||||
<mat-tab-group (selectedTabChange)="onTabChange($event)" class="main-tabs">
|
||||
<mat-tab label="{{ 'repositoryLabel' | translate }}">
|
||||
<div class="dynamic-content">
|
||||
<div *ngIf="selectedSection === 'repositories'" class="section-content">
|
||||
<div class="repositories-container">
|
||||
<div *ngIf="repositories.length === 0" class="no-repositories">
|
||||
<mat-icon class="no-data-icon">cloud_off</mat-icon>
|
||||
|
@ -75,7 +87,6 @@
|
|||
</div>
|
||||
|
||||
<div *ngIf="repositories.length > 0" class="repositories-selector-container">
|
||||
<!-- Selector de repositorio -->
|
||||
<div class="repository-selector">
|
||||
<mat-form-field appearance="outline" class="repository-select-field">
|
||||
<mat-label>Seleccionar repositorio</mat-label>
|
||||
|
@ -88,11 +99,14 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Información del repositorio seleccionado -->
|
||||
<div *ngIf="selectedRepositoryUuid && !errorRepositories[selectedRepositoryUuid] && repositoryStatuses[selectedRepositoryUuid]" class="selected-repository-content">
|
||||
<div class="repository-item">
|
||||
<div class="repository-header">
|
||||
<h3>{{ getSelectedRepositoryName() }}</h3>
|
||||
<div class="section-header">
|
||||
<h2>{{ getSelectedRepositoryName() }}</h2>
|
||||
<button class="logs-button" (click)="scrollToLogs()">
|
||||
<mat-icon>article</mat-icon>
|
||||
<span>Ver logs</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="repository-content">
|
||||
|
@ -111,16 +125,30 @@
|
|||
</app-status-tab>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="repository-logs-section" id="repository-logs-section">
|
||||
<div class="logs-header">
|
||||
<h3>Datos del repositorio: {{ getSelectedRepositoryName() }}</h3>
|
||||
<p>Información específica del repositorio seleccionado</p>
|
||||
</div>
|
||||
<div class="logs-container">
|
||||
<iframe
|
||||
src="https://localhost:3030/d-solo/ogrepo-logs/ogrepo-logs?orgId=1&timezone=browser&refresh=5s&var-query0=&editIndex=0&var-hostname=ogrepository2&theme=dark&panelId=1&__feature.dashboardSceneSolo"
|
||||
width="100%"
|
||||
height="600"
|
||||
frameborder="0"
|
||||
class="repository-logs-iframe">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mensaje cuando no hay repositorio seleccionado -->
|
||||
<div *ngIf="!selectedRepositoryUuid" class="no-repository-selected">
|
||||
<mat-icon class="no-data-icon">storage</mat-icon>
|
||||
<h3>Selecciona un repositorio</h3>
|
||||
<p>Elige un repositorio de la lista para ver su estado detallado.</p>
|
||||
</div>
|
||||
|
||||
<!-- Error al cargar repositorio -->
|
||||
<div *ngIf="selectedRepositoryUuid && errorRepositories[selectedRepositoryUuid]" class="error-container">
|
||||
<div class="error-card">
|
||||
<mat-icon class="error-icon">error_outline</mat-icon>
|
||||
|
@ -134,15 +162,39 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</div>
|
||||
|
||||
<mat-tab label="OgBoot Server">
|
||||
<div *ngIf="!errorOgBoot && !loadingOgBoot" class="tab-content">
|
||||
<app-status-tab [loading]="loadingOgBoot" [diskUsage]="ogBootDiskUsage" [servicesStatus]="ogBootServicesStatus"
|
||||
[installedOgLives]="installedOgLives" [diskUsageChartData]="ogBootDiskUsageChartData" [view]="view"
|
||||
[colorScheme]="colorScheme" [isDoughnut]="isDoughnut" [showLabels]="showLabels" [isDhcp]="isDhcp"
|
||||
[isRepository]="false">
|
||||
</app-status-tab>
|
||||
<div *ngIf="selectedSection === 'ogboot'" class="section-content">
|
||||
<div *ngIf="!errorOgBoot && !loadingOgBoot" class="tab-content">
|
||||
<div class="section-header">
|
||||
<h2>OgBoot Server</h2>
|
||||
<button class="logs-button" (click)="scrollToLogs()">
|
||||
<mat-icon>article</mat-icon>
|
||||
<span>Ver logs</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<app-status-tab [loading]="loadingOgBoot" [diskUsage]="ogBootDiskUsage" [servicesStatus]="ogBootServicesStatus"
|
||||
[installedOgLives]="installedOgLives" [diskUsageChartData]="ogBootDiskUsageChartData" [view]="view"
|
||||
[colorScheme]="colorScheme" [isDoughnut]="isDoughnut" [showLabels]="showLabels" [isDhcp]="isDhcp"
|
||||
[isRepository]="false">
|
||||
</app-status-tab>
|
||||
|
||||
<div class="logs-section" id="ogboot-logs-section">
|
||||
<div class="logs-header">
|
||||
<h3>Logs de OgBoot</h3>
|
||||
<p>Logs en tiempo real del servidor OgBoot</p>
|
||||
</div>
|
||||
<div class="logs-container">
|
||||
<iframe
|
||||
src="https://localhost:3030/d-solo/ogboot-logs/ogboot-logs?orgId=1&timezone=browser&refresh=5s&theme=dark&panelId=1&__feature.dashboardSceneSolo"
|
||||
width="100%"
|
||||
height="800"
|
||||
frameborder="0"
|
||||
class="ogboot-logs-iframe">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="loadingOgBoot" class="loading-container">
|
||||
<div class="loading-content">
|
||||
|
@ -161,14 +213,38 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</div>
|
||||
|
||||
<mat-tab label="DHCP Server">
|
||||
<div *ngIf="!errorDhcp && !loadingDhcp" class="tab-content">
|
||||
<app-status-tab [loading]="loadingDhcp" [diskUsage]="dhcpDiskUsage" [servicesStatus]="dhcpServicesStatus"
|
||||
[subnets]="subnets" [diskUsageChartData]="dhcpDiskUsageChartData" [view]="view" [colorScheme]="colorScheme"
|
||||
[isDoughnut]="isDoughnut" [showLabels]="showLabels" [isDhcp]="true" [isRepository]="false">
|
||||
</app-status-tab>
|
||||
<div *ngIf="selectedSection === 'dhcp'" class="section-content">
|
||||
<div *ngIf="!errorDhcp && !loadingDhcp" class="tab-content">
|
||||
<div class="section-header">
|
||||
<h2>DHCP Server</h2>
|
||||
<button class="logs-button" (click)="scrollToLogs()">
|
||||
<mat-icon>article</mat-icon>
|
||||
<span>Ver logs</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<app-status-tab [loading]="loadingDhcp" [diskUsage]="dhcpDiskUsage" [servicesStatus]="dhcpServicesStatus"
|
||||
[subnets]="subnets" [diskUsageChartData]="dhcpDiskUsageChartData" [view]="view" [colorScheme]="colorScheme"
|
||||
[isDoughnut]="isDoughnut" [showLabels]="showLabels" [isDhcp]="true" [isRepository]="false">
|
||||
</app-status-tab>
|
||||
|
||||
<div class="logs-section" id="dhcp-logs-section">
|
||||
<div class="logs-header">
|
||||
<h3>Logs de DHCP</h3>
|
||||
<p>Logs en tiempo real del servidor DHCP</p>
|
||||
</div>
|
||||
<div class="logs-container">
|
||||
<iframe
|
||||
src="https://localhost:3030/d-solo/ogdhcp-logs/ogdhcp-logs?orgId=1&timezone=browser&refresh=5s&theme=dark&panelId=1&__feature.dashboardSceneSolo"
|
||||
width="100%"
|
||||
height="800"
|
||||
frameborder="0"
|
||||
class="dhcp-logs-iframe">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="loadingDhcp" class="loading-container">
|
||||
<div class="loading-content">
|
||||
|
@ -187,12 +263,36 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
||||
|
||||
<div *ngIf="selectedSection === 'ogcore'" class="section-content">
|
||||
<div class="tab-content">
|
||||
<div class="section-header">
|
||||
<h2>OgCore Server</h2>
|
||||
</div>
|
||||
|
||||
<div class="logs-section" id="ogcore-logs-section">
|
||||
<div class="logs-header">
|
||||
<h3>Logs de OgCore</h3>
|
||||
<p>Logs en tiempo real del servidor OgCore</p>
|
||||
</div>
|
||||
<div class="logs-container">
|
||||
<iframe
|
||||
src="https://localhost:3030/d-solo/ogcore-logs/ogcore-logs?orgId=1&tab=transformations&theme=dark&panelId=1&__feature.dashboardSceneSolo&now-5m&to=now&timezone=browser"
|
||||
width="100%"
|
||||
height="800"
|
||||
frameborder="0"
|
||||
class="ogcore-logs-iframe">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</mat-dialog-content>
|
||||
|
||||
<!-- Footer con acciones -->
|
||||
<mat-dialog-actions class="action-container">
|
||||
<div class="action-info">
|
||||
<p class="last-update">Última actualización: {{ lastUpdateTime }}</p>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { MatTabChangeEvent } from '@angular/material/tabs';
|
||||
import {ToastrService} from "ngx-toastr";
|
||||
import { ToastrService } from "ngx-toastr";
|
||||
|
||||
@Component({
|
||||
selector: 'app-global-status',
|
||||
|
@ -31,6 +30,7 @@ export class GlobalStatusComponent implements OnInit {
|
|||
repositoryStatuses: { [key: string]: any } = {};
|
||||
lastUpdateTime: string = '';
|
||||
selectedRepositoryUuid: string = '';
|
||||
selectedSection: 'repositories' | 'ogboot' | 'dhcp' | 'ogcore' = 'repositories';
|
||||
|
||||
ogBootApiUrl: string;
|
||||
ogBootDiskUsage: any = {};
|
||||
|
@ -44,7 +44,8 @@ export class GlobalStatusComponent implements OnInit {
|
|||
isDhcp: boolean = false;
|
||||
isRepository: boolean = false;
|
||||
|
||||
// Loading específicos para cada sección
|
||||
ogCoreApiUrl: string;
|
||||
|
||||
loadingOgBootOgLives: boolean = false;
|
||||
loadingOgBootServices: boolean = false;
|
||||
loadingOgBootDisk: boolean = false;
|
||||
|
@ -60,6 +61,7 @@ export class GlobalStatusComponent implements OnInit {
|
|||
this.baseUrl = this.configService.apiUrl;
|
||||
this.ogBootApiUrl = `${this.baseUrl}/og-boot/status`;
|
||||
this.dhcpApiUrl = `${this.baseUrl}/og-dhcp/status`;
|
||||
this.ogCoreApiUrl = `${this.baseUrl}`;
|
||||
this.repositoriesUrl = `${this.baseUrl}/image-repositories`;
|
||||
|
||||
this.ogBootDiskUsageChartData = [];
|
||||
|
@ -290,23 +292,9 @@ export class GlobalStatusComponent implements OnInit {
|
|||
this.loadStatus(this.dhcpApiUrl, this.dhcpDiskUsage, this.dhcpServicesStatus, this.dhcpDiskUsageChartData, this.installedOgLives, this.isDhcp, 'errorDhcp', false);
|
||||
}
|
||||
|
||||
onTabChange(event: MatTabChangeEvent): void {
|
||||
switch (event.index) {
|
||||
case 0:
|
||||
if (this.repositories.length === 0) {
|
||||
this.loadRepositories(false);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this.loadOgBootStatus();
|
||||
break;
|
||||
case 2:
|
||||
this.loadDhcpStatus();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
onRepositoryChange(repositoryUuid: string): void {
|
||||
this.selectedRepositoryUuid = repositoryUuid;
|
||||
|
@ -324,6 +312,15 @@ export class GlobalStatusComponent implements OnInit {
|
|||
return selectedRepo ? selectedRepo.name : '';
|
||||
}
|
||||
|
||||
getRepositoryIframeUrl(): string {
|
||||
const repositoryName = this.getSelectedRepositoryName();
|
||||
if (repositoryName) {
|
||||
const encodedName = encodeURIComponent(repositoryName);
|
||||
return `https://localhost:3030/d-solo/ogrepo-logs/ogrepo-logs?orgId=1&timezone=browser&refresh=5s&var-query0=&editIndex=0&var-hostname=${encodedName}&theme=dark&panelId=1&__feature.dashboardSceneSolo`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
refreshAll(): void {
|
||||
this.loading = true;
|
||||
this.updateLastUpdateTime();
|
||||
|
@ -364,4 +361,71 @@ export class GlobalStatusComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
selectSection(section: 'repositories' | 'ogboot' | 'dhcp' | 'ogcore'): void {
|
||||
this.selectedSection = section;
|
||||
|
||||
switch (section) {
|
||||
case 'repositories':
|
||||
break;
|
||||
case 'ogboot':
|
||||
if (!this.ogBootDiskUsage) {
|
||||
this.loadOgBootStatus();
|
||||
}
|
||||
break;
|
||||
case 'dhcp':
|
||||
if (!this.dhcpDiskUsage) {
|
||||
this.loadDhcpStatus();
|
||||
}
|
||||
break;
|
||||
case 'ogcore':
|
||||
// No se necesita cargar nada, solo mostrar los logs
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
scrollToLogs(): void {
|
||||
let logsSectionId: string;
|
||||
switch (this.selectedSection) {
|
||||
case 'repositories':
|
||||
logsSectionId = 'repository-logs-section';
|
||||
break;
|
||||
case 'ogboot':
|
||||
logsSectionId = 'ogboot-logs-section';
|
||||
break;
|
||||
case 'dhcp':
|
||||
logsSectionId = 'dhcp-logs-section';
|
||||
break;
|
||||
case 'ogcore':
|
||||
logsSectionId = 'ogcore-logs-section';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const checkAndScroll = () => {
|
||||
const logsSection = document.getElementById(logsSectionId);
|
||||
if (logsSection) {
|
||||
logsSection.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (checkAndScroll()) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(interval);
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<app-loading [isLoading]="loading"></app-loading>
|
||||
|
||||
<div *ngIf="!loading" class="dashboard">
|
||||
<!-- Sección de uso de recursos -->
|
||||
<div class="resources-section">
|
||||
<!-- Disk Usage Section -->
|
||||
<div class="resource-card disk-usage-container">
|
||||
<div class="resource-header">
|
||||
<div class="resource-icon">
|
||||
|
@ -32,13 +30,12 @@
|
|||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">{{ 'usedPercentageLabel' | translate }}:</span>
|
||||
<span class="info-value usage-percentage">{{ isRepository ? diskUsage.used_percentage : diskUsage.percentage }}%</span>
|
||||
<span class="info-value usage-percentage">{{ isRepository ? diskUsage.used_percentage : diskUsage.percentage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RAM Usage Section -->
|
||||
<div class="resource-card ram-usage-container" *ngIf="isRepository">
|
||||
<div class="resource-header">
|
||||
<div class="resource-icon">
|
||||
|
@ -67,13 +64,12 @@
|
|||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">{{ 'usedPercentageLabel' | translate }}:</span>
|
||||
<span class="info-value usage-percentage">{{ ramUsage.used_percentage }}%</span>
|
||||
<span class="info-value usage-percentage">{{ ramUsage.used_percentage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CPU Usage Section -->
|
||||
<div class="resource-card cpu-usage-container" *ngIf="isRepository">
|
||||
<div class="resource-header">
|
||||
<div class="resource-icon">
|
||||
|
@ -84,7 +80,7 @@
|
|||
<div class="resource-content">
|
||||
<div class="cpu-usage-display">
|
||||
<div class="cpu-circle">
|
||||
<div class="cpu-percentage">{{ cpuUsage.used_percentage }}%</div>
|
||||
<div class="cpu-percentage">{{ cpuUsage.used_percentage }}</div>
|
||||
<div class="cpu-label">Uso actual</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -92,9 +88,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sección de servicios y procesos -->
|
||||
<div class="services-section">
|
||||
<!-- Services Status Section -->
|
||||
<div class="service-card services-status" joyrideStep="servicesStatusStep" text="{{ 'servicesStatusDescription' | translate }}">
|
||||
<div class="service-header">
|
||||
<div class="service-icon">
|
||||
|
@ -116,7 +110,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Processes Status Section -->
|
||||
<div class="service-card processes-status" *ngIf="isRepository">
|
||||
<div class="service-header">
|
||||
<div class="service-icon">
|
||||
|
@ -139,9 +132,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sección de datos específicos -->
|
||||
<div class="data-section">
|
||||
<!-- Installed OgLives Section -->
|
||||
<div class="data-card" *ngIf="!isRepository && !isDhcp">
|
||||
<div class="data-header">
|
||||
<div class="data-icon">
|
||||
|
@ -171,7 +162,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Subnets Section -->
|
||||
<div class="data-card" *ngIf="isDhcp">
|
||||
<div class="data-header">
|
||||
<div class="data-icon">
|
||||
|
|
Loading…
Reference in New Issue