refs #690. ogBoot status changes. Added ogLive in client

develop-jenkins
Manuel Aranda Rosales 2024-10-22 18:29:57 +02:00
parent a0deb37a35
commit 4904e40a49
5 changed files with 123 additions and 112 deletions

View File

@ -1,70 +1,83 @@
.global-selectors {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
gap: 10px;
}
.global-selectors mat-form-field {
flex: 1;
margin-right: 10px;
}
.global-selectors button {
height: 40px;
padding: 0 20px;
}
.filters-container {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 10px;
margin-bottom: 15px;
}
.filters-container mat-form-field {
flex: 1;
}
.mat-elevation-z8 {
margin-top: 15px;
}
.mat-table {
width: 100%;
}
mat-header-cell, mat-cell {
text-align: center;
font-size: 14px;
padding: 8px;
}
mat-form-field {
width: 100%;
}
.mat-paginator {
margin-top: 20px;
display: flex;
justify-content: center;
}
mat-select, mat-input {
font-size: 14px;
}
.mat-form-field-appearance-fill .mat-form-field-flex {
padding: 8px 0;
}
button.mat-flat-button {
padding: 8px 16px;
font-size: 14px;
.title {
font-size: 24px;
}
.divider {
margin: 20px 0;
}
table {
width: 100%;
margin-top: 50px;
}
.search-container {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 0 5px;
box-sizing: border-box;
}
.global-selectors {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 0 5px;
}
.selected-global {
width: 450px;
}
.search-string {
flex: 2;
padding: 5px;
}
.search-boolean {
flex: 1;
padding: 5px;
}
.save-button{
justify-self: end;
}
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.mat-elevation-z8 {
box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
}
.paginator-container {
display: flex;
justify-content: end;
margin-bottom: 30px;
}
.example-headers-align .mat-expansion-panel-header-description {
justify-content: space-between;
align-items: center;
}
.example-headers-align .mat-mdc-form-field + .mat-mdc-form-field {
margin-left: 8px;
}
.example-button-row {
display: table-cell;
max-width: 600px;
}
.example-button-row .mat-mdc-button-base {
margin: 8px 8px 8px 0;
}

View File

@ -1,21 +1,10 @@
<mat-accordion class="example-headers-align">
<mat-expansion-panel hideToggle>
<mat-expansion-panel-header>
<mat-panel-title> Sincronización ogBoot </mat-panel-title>
</mat-expansion-panel-header>
<div class="example-button-row">
<button mat-flat-button color="primary" (click)="syncOgCore()"> Sincronizar OgCore</button>
</div>
</mat-expansion-panel>
</mat-accordion>
<div class="header-container">
<h2 class="title">Administrar ficheros de arranque PXE</h2>
<h2 class="title">Netboot avanzado</h2>
</div>
<div [formGroup]="taskForm" class="filters-container">
<mat-form-field appearance="fill" class="full-width">
<div [formGroup]="taskForm" class="search-container">
<mat-form-field appearance="fill" class="search-boolean">
<mat-label>Selecciona Unidad Organizacional</mat-label>
<mat-select formControlName="organizationalUnit" (selectionChange)="onOrganizationalUnitChange()">
<mat-option *ngIf="loadingUnits" disabled>Cargando unidades...</mat-option>
@ -26,7 +15,7 @@
<mat-error *ngIf="taskForm.get('organizationalUnit')?.invalid">Este campo es obligatorio</mat-error>
</mat-form-field>
<mat-form-field appearance="fill" class="full-width">
<mat-form-field appearance="fill" class="search-boolean">
<mat-label>Selecciona aula</mat-label>
<mat-select formControlName="selectedChild" (selectionChange)="onChildChange()">
<mat-option *ngIf="selectedUnitChildren.length === 0" disabled>No hay aulas disponibles</mat-option>
@ -40,14 +29,14 @@
<mat-divider class="divider"></mat-divider>
<div class="global-selectors">
<mat-form-field appearance="fill">
<mat-label>Global ogLive</mat-label>
<mat-select [(value)]="globalOgLive">
<mat-form-field appearance="fill" class="selected-global">
<mat-label>Seleccione plantilla para aplicar a todos los clientes</mat-label>
<mat-select [(value)]="globalOgLive" (selectionChange)="applyToAll()" >
<mat-option *ngFor="let option of ogLiveOptions" [value]="option['@id']">{{ option.name }}</mat-option>
</mat-select>
</mat-form-field>
<button mat-flat-button color="primary" (click)="applyToAll()">Aplicar a todos</button>
<button mat-flat-button color="primary" [disabled]="selectedUnitChildren.length === 0" (click)="saveOgLiveTemplates()">Guardar</button>
</div>
<mat-table [dataSource]="dataSource" class="mat-elevation-z8">
@ -75,19 +64,8 @@
</mat-form-field>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<div class="save-button"
>
<button mat-flat-button color="primary" (click)="saveOgLiveTemplates()">Guardar</button>
</div>
<mat-paginator [length]="length"
[pageSize]="itemsPerPage"
[pageSizeOptions]="pageSizeOptions"
(page)="onPageChange($event)">
</mat-paginator>

View File

@ -3,6 +3,8 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { ToastrService } from 'ngx-toastr';
import { PageEvent } from '@angular/material/paginator';
import {Observable} from "rxjs";
import {ServerInfoDialogComponent} from "../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
@Component({
selector: 'app-pxe-boot-files',
@ -26,6 +28,7 @@ export class PxeBootFilesComponent implements OnInit {
filters: any = {};
displayedColumns: string[] = ['id', 'name', 'ogLive'];
constructor(
private fb: FormBuilder,
private http: HttpClient,
@ -73,14 +76,14 @@ export class PxeBootFilesComponent implements OnInit {
onOrganizationalUnitChange(): void {
const selectedUnitId = this.taskForm.get('organizationalUnit')?.value;
const selectedUnit = this.availableOrganizationalUnits.find(unit => unit['@id'] === selectedUnitId);
if (selectedUnit) {
this.selectedUnitChildren = this.getAllClassrooms(selectedUnit);
} else {
this.selectedUnitChildren = [];
}
}
getAllClassrooms(unit: any): any[] {
let classrooms: any[] = [];
if (unit.type === 'classroom') {
@ -93,7 +96,7 @@ export class PxeBootFilesComponent implements OnInit {
}
return classrooms;
}
onChildChange(): void {
const selectedChildId = this.taskForm.get('selectedChild')?.value;
@ -107,7 +110,7 @@ export class PxeBootFilesComponent implements OnInit {
this.dataSource = [];
}
}
applyToAll(): void {
this.dataSource = this.dataSource.map(client => ({
@ -152,15 +155,4 @@ export class PxeBootFilesComponent implements OnInit {
this.itemsPerPage = event.pageSize;
this.fetchPxeTemplates();
}
syncOgCore(): void {
this.http.post(`${this.baseUrl}/sync`, {}).subscribe(
() => {
this.toastService.success('Sincronización completada');
},
error => {
this.toastService.error('Error al sincronizar');
}
);
}
}

View File

@ -10,6 +10,7 @@
<div matListItemLine>{{ client.mac }}</div>
</div>
<div class="icon-container">
<button mat-icon-button color="info" (click)="showInfo(client)" i18n="@@editImage"> <mat-icon>visibility</mat-icon></button>
<button mat-icon-button color="primary" (click)="addClientToTemplate(client)" i18n="@@editImage"> <mat-icon>sync</mat-icon></button>
<button mat-icon-button color="warn" class="right-icon" (click)="deleteClient(client)">
<mat-icon>delete</mat-icon>

View File

@ -4,6 +4,10 @@ import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog
import {HttpClient} from "@angular/common/http";
import {ToastrService} from "ngx-toastr";
import {DeleteModalComponent} from "../../../../shared/delete_modal/delete-modal/delete-modal.component";
import {Observable} from "rxjs";
import {
ServerInfoDialogComponent
} from "../../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
@Component({
selector: 'app-clients',
@ -14,6 +18,7 @@ export class ClientsComponent {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
templateForm!: FormGroup;
clients: any[] = [];
alertMessage: string | null = null;
constructor(
public dialogRef: MatDialogRef<ClientsComponent>,
@ -55,6 +60,28 @@ export class ClientsComponent {
);
}
loadAlert(client: any): Observable<any> {
return this.http.post<any>(`${this.baseUrl}/clients/server/${client.uuid}/get-pxe`, {});
}
showInfo(client:any) {
this.loadAlert(client).subscribe(
response => {
this.alertMessage = response.message;
this.dialog.open(ServerInfoDialogComponent, {
width: '600px',
data: {
message: this.alertMessage
}
});
},
error => {
console.error('Error al cargar la información del alert', error);
}
);
}
deleteClient(client: any): void {
const dialogRef = this.dialog.open(DeleteModalComponent, {
width: '300px',
@ -63,7 +90,7 @@ export class ClientsComponent {
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.http.post(`${this.baseUrl}/pxe-templates/${this.data.uuid}/delete-client`, { client: client['@id'] }).subscribe({
this.http.post(`${this.baseUrl}/pxe-templates/${this.data.data.uuid}/delete-client`, { client: client['@id'] }).subscribe({
next: () => {
this.toastService.success('Cliente eliminado exitosamente');
this.dialogRef.close();