Merge pull request 'New client option. Disk logs.' (#87) from develop into main
Reviewed-on: #87pull/88/head
commit
2c21cde3dc
|
|
@ -185,6 +185,7 @@ import { ScrollToTopComponent } from './shared/scroll-to-top/scroll-to-top.compo
|
|||
import { CreateTagModalComponent } from './components/repositories/show-git-images/create-tag-modal/create-tag-modal.component';
|
||||
import { CreateBranchModalComponent } from './components/repositories/show-git-images/create-branch-modal/create-branch-modal.component';
|
||||
import { ClientLogsModalComponent } from './components/groups/shared/client-logs-modal/client-logs-modal.component';
|
||||
import { ClientDiskLogsModalComponent } from './components/groups/shared/client-disk-logs-modal/client-disk-logs-modal.component';
|
||||
import { BackupRepositoryModalComponent } from './components/repositories/show-git-images/backup-repository-modal/backup-repository-modal.component';
|
||||
import { HardwareComponent } from './components/hardware/hardware.component';
|
||||
import { CreateHardwareComponent } from './components/hardware/create-hardware/create-hardware.component';
|
||||
|
|
@ -325,6 +326,7 @@ registerLocaleData(localeEs, 'es-ES');
|
|||
CreateTagModalComponent,
|
||||
CreateBranchModalComponent,
|
||||
ClientLogsModalComponent,
|
||||
ClientDiskLogsModalComponent,
|
||||
SafePipe,
|
||||
BackupRepositoryModalComponent,
|
||||
HardwareComponent,
|
||||
|
|
|
|||
|
|
@ -458,6 +458,10 @@
|
|||
<mat-icon>analytics</mat-icon>
|
||||
<span>{{ 'clientLogs' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="openClientDiskLogsModal($event, client)">
|
||||
<mat-icon>storage</mat-icon>
|
||||
<span>{{ 'diskLogs' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onDeleteClick($event, client)" *ngIf="auth.userCategory !== 'ou-minimal'">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>{{ 'buttonDelete' | translate }}</span>
|
||||
|
|
@ -653,6 +657,10 @@
|
|||
<mat-icon>analytics</mat-icon>
|
||||
<span>{{ 'clientLogs' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="openClientDiskLogsModal($event, client)">
|
||||
<mat-icon>storage</mat-icon>
|
||||
<span>{{ 'diskLogs' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onDeleteClick($event, client)" *ngIf="auth.userCategory !== 'ou-minimal'">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>{{ 'buttonDelete' | translate }}</span>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import {ChangeParentComponent} from "./shared/change-parent/change-parent.compon
|
|||
import { AuthService } from '@services/auth.service';
|
||||
import { ClientPendingTasksComponent } from '../task-logs/client-pending-tasks/client-pending-tasks.component';
|
||||
import { ClientLogsModalComponent } from './shared/client-logs-modal/client-logs-modal.component';
|
||||
import { ClientDiskLogsModalComponent } from './shared/client-disk-logs-modal/client-disk-logs-modal.component';
|
||||
import { DeleteResultsModalComponent } from './shared/delete-results-modal/delete-results-modal.component';
|
||||
|
||||
enum NodeType {
|
||||
|
|
@ -1085,6 +1086,19 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
openClientDiskLogsModal(event: MouseEvent, client: Client): void {
|
||||
event.stopPropagation();
|
||||
|
||||
this.dialog.open(ClientDiskLogsModalComponent, {
|
||||
width: '1100px',
|
||||
height: '80vh',
|
||||
data: { client },
|
||||
disableClose: false,
|
||||
hasBackdrop: true,
|
||||
backdropClass: 'non-clickable-backdrop',
|
||||
});
|
||||
}
|
||||
|
||||
openOUPendingTasks(event: MouseEvent, node: any): void {
|
||||
event.stopPropagation();
|
||||
this.loading = true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
.disk-logs-modal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 24px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 1.25rem;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
flex: 1;
|
||||
padding: 24px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.client-info {
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid #2196f3;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.client-info p {
|
||||
margin: 4px 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.client-info strong {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.log-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
background-color: #1e1e1e;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.log-loading,
|
||||
.log-error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
flex: 1;
|
||||
color: #aaa;
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.log-error {
|
||||
color: #f44336;
|
||||
}
|
||||
|
||||
.log-content {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.5;
|
||||
color: #d4d4d4;
|
||||
background-color: transparent;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
padding: 16px 24px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
padding: 12px 24px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.action-button:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<div class="disk-logs-modal">
|
||||
<div class="modal-header">
|
||||
<h2 mat-dialog-title>
|
||||
<mat-icon>storage</mat-icon>
|
||||
{{ 'diskLogs' | translate }} - {{ data.client.name }}
|
||||
</h2>
|
||||
<div class="header-actions">
|
||||
<button mat-icon-button (click)="loadLogs()" [matTooltip]="'buttonRefresh' | translate" [disabled]="loading">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-content">
|
||||
<div class="client-info">
|
||||
<p><strong>{{ 'labelClient' | translate }}</strong> {{ data.client.name }}</p>
|
||||
<p><strong>{{ 'labelIpColon' | translate }}</strong> {{ data.client.ip }}</p>
|
||||
</div>
|
||||
|
||||
<div class="log-container">
|
||||
<div *ngIf="loading" class="log-loading">
|
||||
<mat-spinner diameter="40"></mat-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="error && !loading" class="log-error">
|
||||
<mat-icon>error_outline</mat-icon>
|
||||
<span>{{ error }}</span>
|
||||
</div>
|
||||
|
||||
<pre *ngIf="!loading && !error" class="log-content">{{ content || ('noLogsAvailable' | translate) }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="action-button" (click)="closeModal()">
|
||||
{{ 'buttonClose' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import { Component, Inject, OnInit, OnDestroy } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-client-disk-logs-modal',
|
||||
templateUrl: './client-disk-logs-modal.component.html',
|
||||
styleUrls: ['./client-disk-logs-modal.component.css']
|
||||
})
|
||||
export class ClientDiskLogsModalComponent implements OnInit, OnDestroy {
|
||||
content: string = '';
|
||||
loading: boolean = false;
|
||||
error: string | null = null;
|
||||
private apiUrl: string;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<ClientDiskLogsModalComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { client: any },
|
||||
private http: HttpClient,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
this.apiUrl = this.configService.apiUrl;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadLogs();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {}
|
||||
|
||||
loadLogs(): void {
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
|
||||
this.http.get<{ content: string }>(`${this.apiUrl}/clients/${this.data.client.uuid}/disk-logs`).subscribe({
|
||||
next: (response) => {
|
||||
this.content = response.content || '';
|
||||
this.loading = false;
|
||||
},
|
||||
error: (err) => {
|
||||
this.error = err.status === 404
|
||||
? 'No se encontró el archivo de logs para este cliente.'
|
||||
: 'Error al obtener los logs de disco.';
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
closeModal(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -231,6 +231,7 @@
|
|||
"clientListExecuteScript": "Llistat de clients on s'executarà l'script seleccionat",
|
||||
"clientListPartition": "Llistat de clients on es realitzarà el particionat",
|
||||
"clientLogs": "Registres de client",
|
||||
"diskLogs": "Registres de disc",
|
||||
"clientMacOS": "Client MacOS",
|
||||
"clientOff": "Client apagat",
|
||||
"clientOgLive": "Client OGLive",
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@
|
|||
"clientListExecuteScript": "List of clients where the selected script will be executed",
|
||||
"clientListPartition": "List of clients where partitioning will be performed",
|
||||
"clientLogs": "Client Logs",
|
||||
"diskLogs": "Disk Logs",
|
||||
"clientMacOS": "MacOS client",
|
||||
"clientOff": "Client off",
|
||||
"clientOgLive": "OGLive client",
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@
|
|||
"clientListExecuteScript": "Listado de clientes donde se ejecutara el script seleccionado",
|
||||
"clientListPartition": "Listado de clientes donde se realizará el particionado",
|
||||
"clientLogs": "Logs de cliente",
|
||||
"diskLogs": "Logs de disco",
|
||||
"clientMacOS": "Cliente MacOS",
|
||||
"clientOff": "Cliente apagado",
|
||||
"clientOgLive": "Cliente OGLive",
|
||||
|
|
|
|||
Loading…
Reference in New Issue