refs #917 New client view component and partition assistant component
parent
e0704d61ef
commit
800b73db61
|
@ -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;
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue