refs #917 New client view component and partition assistant component

develop-jenkins
Alvaro Puente Mella 2024-10-15 14:33:38 +02:00
parent e0704d61ef
commit 800b73db61
8 changed files with 146 additions and 50 deletions

View File

@ -1,6 +1,6 @@
/* Header - Title and Icon */
.client-header { .client-header {
display: flex; display: flex;
align-items: center; align-items: center;
@ -12,12 +12,12 @@
} }
.client-icon { .client-icon {
flex-shrink: 0; /* Prevent shrinking of the icon */ flex-shrink: 0;
margin-right: 20px; margin-right: 20px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-width: 120px; /* Ensure the icon has enough space */ min-width: 120px;
min-height: 120px; min-height: 120px;
} }
@ -37,11 +37,45 @@
color: #666; color: #666;
} }
/* Information Section */
.client-info { .client-info {
margin: 20px 0;
}
.info-section {
margin-bottom: 30px;
}
.two-column-table {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 10px; gap: 10px;
margin-top: 15px;
}
.table-row {
display: flex;
justify-content: space-between;
padding: 10px;
border-bottom: 1px solid #e0e0e0;
}
.column.property {
font-weight: bold;
text-align: left;
width: 45%;
}
.column.value {
text-align: right;
width: 45%;
}
.mat-tab-group {
min-height: 400px;
}
.mat-tab-body-wrapper {
min-height: inherit;
} }
.info-section { .info-section {
@ -49,6 +83,7 @@
padding: 20px; padding: 20px;
border-radius: 12px; border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
height: auto;
} }
.info-section h2 { .info-section h2 {
@ -62,7 +97,6 @@
margin: 5px 0; margin: 5px 0;
} }
/* Disk Usage Section */
.disk-usage { .disk-usage {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -1,22 +1,36 @@
<div class="client-header">
<div class="client-icon">
<mat-icon class="icon-pc">computer</mat-icon>
</div>
<div class="client-title">
<h1>{{ clientData?.name }}</h1>
<p><strong>UUID:</strong> {{ clientData?.uuid }}</p>
<p><strong>IP:</strong> {{ clientData?.ip }}</p>
</div>
</div>
<div class="client-info"> <div class="client-info">
<!-- Información General --> <!-- Información General -->
<div class="info-section"> <div class="info-section">
<h2 *ngIf="isGeneralInfoVisible">Información General</h2> <mat-tab-group dynamicHeight>
<p *ngIf="isGeneralInfoVisible"><strong>MAC:</strong> {{ clientData?.mac }}</p>
<p *ngIf="isGeneralInfoVisible"><strong>Número de serie:</strong> {{ clientData?.serialNumber }}</p> <mat-tab label="Datos generales">
<h2 *ngIf="isGeneralInfoVisible">Unidad Organizativa</h2> <div class="two-column-table">
<p *ngIf="isGeneralInfoVisible">{{ clientData?.organizationalUnit?.name }}</p> <div class="table-row" *ngFor="let clientData of generalData">
<div class="column property">{{ clientData?.property }}</div>
<div class="column value">{{ clientData?.value }}</div>
</div>
</div>
</mat-tab>
<mat-tab label="Propiedades de red">
<div class="two-column-table">
<div class="table-row" *ngFor="let clientData of networkData">
<div class="column property">{{ clientData?.property }}</div>
<div class="column value">{{ clientData?.value }}</div>
</div>
</div>
</mat-tab>
<mat-tab label="Propiedades del aula">
<div class="two-column-table">
<div class="table-row" *ngFor="let clientData of classroomData">
<div class="column property">{{ clientData?.property }}</div>
<div class="column value">{{ clientData?.value }}</div>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div> </div>
<!-- Uso del Espacio en Disco --> <!-- Uso del Espacio en Disco -->
@ -40,12 +54,13 @@
<p>Usado: 75% (375GB)</p> <p>Usado: 75% (375GB)</p>
<p>Total: 500GB</p> <p>Total: 500GB</p>
</div> </div>
</div>
</div>
<div class="buttons-row"> <div class="buttons-row">
<button mat-flat-button color="primary" (click)="togglePartitionAssistant()">Asistente a particionado</button> <button mat-flat-button color="primary" (click)="togglePartitionAssistant()">Asistente a particionado</button>
<button mat-flat-button color="primary" (click)="showBootImage()">Restaurar imagen</button> <button mat-flat-button color="primary" (click)="showBootImage()">Restaurar imagen</button>
</div>
</div>
</div> </div>
<div class="assistants-container" *ngIf="isPartitionAssistantVisible"> <div class="assistants-container" *ngIf="isPartitionAssistantVisible">

View File

@ -1,5 +1,9 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
interface ClientInfo {
property: string;
value: any;
}
@Component({ @Component({
selector: 'app-client-main-view', selector: 'app-client-main-view',
@ -9,12 +13,18 @@ import { HttpClient } from '@angular/common/http';
export class ClientMainViewComponent implements OnInit { export class ClientMainViewComponent implements OnInit {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
clientUuid: string; clientUuid: string;
clientData: any; clientData: any = {};
isPartitionAssistantVisible: boolean = false; isPartitionAssistantVisible: boolean = false;
isBootImageVisible: boolean = false; isBootImageVisible: boolean = false;
isGeneralInfoVisible: boolean = true; isGeneralInfoVisible: boolean = true;
isDiskUsageVisible: boolean = true; isDiskUsageVisible: boolean = true;
displayedColumns: string[] = ['property', 'value'];
generalData: ClientInfo[] = [];
networkData: ClientInfo[] = [];
classroomData: ClientInfo[] = [];
constructor(private http: HttpClient) { constructor(private http: HttpClient) {
const url = window.location.href; const url = window.location.href;
const segments = url.split('/'); const segments = url.split('/');
@ -22,27 +32,62 @@ export class ClientMainViewComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
this.loadClientData(); this.clientData = history.state.clientData
this.updateGeneralData();
this.updateNetworkData();
this.updateClassroomData();
} }
loadClientData() { updateGeneralData() {
this.http.get(`${this.baseUrl}/clients/${this.clientUuid}`).subscribe( this.generalData = [
data => { { property: 'Nombre', value: this.clientData?.name || '' },
this.clientData = data; { property: 'Uuid', value: this.clientData?.uuid || '' },
}, { property: 'IP', value: this.clientData?.ip || '' },
error => { { property: 'MAC', value: this.clientData?.mac || '' },
console.error('Error loading client data:', error); { property: 'Nº de serie', value: this.clientData?.serialNumber || '' },
} { property: 'Netiface', value: this.clientData?.netiface || '' },
); { property: 'Perfil hardware', value: this.clientData?.hardwareProfile?.description || '' },
{ property: 'Menú', value: this.clientData?.menu?.description || '' },
{ property: 'Fecha de creación', value: this.clientData?.createdAt || '' },
{ property: 'Creado por', value: this.clientData?.createdBy || '' }
];
}
updateNetworkData() {
this.networkData = [
{ property: 'Perfil hardware', value: this.clientData?.hardwareProfile?.description || '' },
{ property: 'Subred', value: this.clientData?.subnet || '' },
{ property: 'OGlive', value: '' },
{ property: 'Autoexec', value: '' },
{ property: 'Repositorio', value: '' },
{ property: 'Validación', value: this.clientData?.organizationalUnit?.networkSettings?.validation || '' },
{ property: 'Fecha de creación', value: this.clientData?.createdAt || '' },
{ property: 'Creado por', value: this.clientData?.createdBy || '' }
];
}
updateClassroomData() {
this.classroomData = [
{ property: 'Url servidor proxy', value: this.clientData?.organizationalUnit?.networkSettings?.proxy || '' },
{ property: 'IP DNS', value: this.clientData?.organizationalUnit?.networkSettings?.dns || '' },
{ property: 'Máscara de red', value: this.clientData?.organizationalUnit?.networkSettings?.netmask || '' },
{ property: 'Router', value: this.clientData?.organizationalUnit?.networkSettings?.router || '' },
{ property: 'NTP', value: this.clientData?.organizationalUnit?.networkSettings?.ntp || '' },
{ property: 'Modo p2p', value: this.clientData?.organizationalUnit?.networkSettings?.p2pMode || '' },
{ property: 'Tiempo p2p', value: this.clientData?.organizationalUnit?.networkSettings?.p2pTime || '' },
{ property: 'IP multicast', value: this.clientData?.organizationalUnit?.networkSettings?.mcastIp || '' },
{ property: 'Modo multicast', value: this.clientData?.organizationalUnit?.networkSettings?.mcastMode || '' },
{ property: 'Puerto multicast', value: this.clientData?.organizationalUnit?.networkSettings?.mcastPort || '' },
{ property: 'Velocidad multicast', value: this.clientData?.organizationalUnit?.networkSettings?.mcastSpeed || '' },
{ property: 'Perfil hardware', value: this.clientData?.organizationalUnit?.networkSettings?.hardwareProfile?.description || '' }
];
} }
togglePartitionAssistant() { togglePartitionAssistant() {
this.isPartitionAssistantVisible = !this.isPartitionAssistantVisible; this.isPartitionAssistantVisible = !this.isPartitionAssistantVisible;
} }
showBootImage() { showBootImage() {
this.isPartitionAssistantVisible = false; this.isPartitionAssistantVisible = false;
} }
} }

View File

@ -13,8 +13,7 @@
display: flex; display: flex;
margin: 10px 0; margin: 10px 0;
height: 30px; height: 30px;
border: 1px solid #ccc; border: 1px solid #000000;
background-color: #c5c5c5;
} }
.partition-segment { .partition-segment {

View File

@ -10,7 +10,6 @@
<span class="disk-size">Tamaño: {{ totalDiskSize }} GB</span> <span class="disk-size">Tamaño: {{ totalDiskSize }} GB</span>
</div> </div>
<!-- Barra visual de particiones -->
<div class="partition-bar"> <div class="partition-bar">
<div <div
*ngFor="let partition of partitions" *ngFor="let partition of partitions"
@ -21,9 +20,8 @@
</div> </div>
</div> </div>
<button mat-button (click)="addPartition()">Añadir</button> <button mat-button (click)="addPartition()">Añadir +</button>
<!-- Tabla de particiones (simplificada) -->
<table class="partition-table"> <table class="partition-table">
<thead> <thead>
<tr> <tr>
@ -62,8 +60,7 @@
</table> </table>
<div *ngIf="errorMessage" class="error-message">{{ errorMessage }}</div> <div *ngIf="errorMessage" class="error-message">{{ errorMessage }}</div>
<!-- Solo el botón de Guardar -->
<div class="actions"> <div class="actions">
<button mat-button (click)="save()">Guardar</button> <button mat-flat-button color="primary" (click)="save()">Guardar</button>
</div> </div>
</div> </div>

View File

@ -34,7 +34,7 @@ export class PartitionAssistantComponent {
type: 'NTFS', type: 'NTFS',
sizeBytes: 0, sizeBytes: 0,
format: false, format: false,
color: '#cccccc', color: '#' + Math.floor(Math.random() * 16777215).toString(16),
percentage: 0 percentage: 0
}); });
} else { } else {

View File

@ -12,6 +12,8 @@ import {DeleteModalComponent} from "../../../../shared/delete_modal/delete-modal
import { throwError } from 'rxjs'; import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
import {ClientViewComponent} from "../../shared/client-view/client-view.component"; import {ClientViewComponent} from "../../shared/client-view/client-view.component";
import { Router } from '@angular/router';
@Component({ @Component({
selector: 'app-client-tab-view', selector: 'app-client-tab-view',
templateUrl: './client-tab-view.component.html', templateUrl: './client-tab-view.component.html',
@ -74,7 +76,8 @@ export class ClientTabViewComponent {
private dataService: DataService, private dataService: DataService,
public dialog: MatDialog, public dialog: MatDialog,
private toastService: ToastrService, private toastService: ToastrService,
private http: HttpClient private http: HttpClient,
private router: Router
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
@ -131,7 +134,10 @@ export class ClientTabViewComponent {
handleClientClick(event: MouseEvent, client: any): void { handleClientClick(event: MouseEvent, client: any): void {
event.stopPropagation(); event.stopPropagation();
const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height:'700px' }); /* const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height:'700px' }); */
this.router.navigate(['client', client.uuid], { state: { clientData: client } });
} }
resetFilters() { resetFilters() {

View File

@ -54,7 +54,7 @@ export class ClientViewComponent {
constructor( constructor(
private dialogRef: MatDialogRef<ClientViewComponent>, private dialogRef: MatDialogRef<ClientViewComponent>,
@Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode @Inject(MAT_DIALOG_DATA) public data: any
) { ) {
} }