Merge branch 'develop' of ssh://ognproject.evlt.uma.es:21987/opengnsys/oggui into develop
testing/ogGui-multibranch/pipeline/head There was a failure building this commit Details

deb-pkg
Lucas Lara García 2025-02-28 11:26:23 +01:00
commit 1d78965c92
6 changed files with 128 additions and 87 deletions

View File

@ -358,7 +358,13 @@
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table> </table>
</section> </section>
<mat-paginator [pageSize]="20" [pageSizeOptions]="[5, 10, 20, 50]" showFirstLastButtons></mat-paginator> <mat-paginator
[length]="length"
[pageSize]="itemsPerPage"
[pageIndex]="page"
[pageSizeOptions]="pageSizeOptions"
(page)="onPageChange($event)">
</mat-paginator>
</div> </div>
</div> </div>

View File

@ -19,7 +19,7 @@ import { DeleteModalComponent } from '../../shared/delete_modal/delete-modal/del
import { ClassroomViewDialogComponent } from './shared/classroom-view/classroom-view-modal'; import { ClassroomViewDialogComponent } from './shared/classroom-view/classroom-view-modal';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator'; import {MatPaginator, PageEvent} from '@angular/material/paginator';
import { CreateMultipleClientComponent } from "./shared/clients/create-multiple-client/create-multiple-client.component"; import { CreateMultipleClientComponent } from "./shared/clients/create-multiple-client/create-multiple-client.component";
import { SelectionModel } from "@angular/cdk/collections"; import { SelectionModel } from "@angular/cdk/collections";
@ -41,6 +41,10 @@ export class GroupsComponent implements OnInit, OnDestroy {
organizationalUnits: UnidadOrganizativa[] = []; organizationalUnits: UnidadOrganizativa[] = [];
selectedUnidad: UnidadOrganizativa | null = null; selectedUnidad: UnidadOrganizativa | null = null;
selectedDetail: UnidadOrganizativa | null = null; selectedDetail: UnidadOrganizativa | null = null;
length: number = 0;
itemsPerPage: number = 10;
page: number = 0;
pageSizeOptions: number[] = [5, 10, 20, 40, 100];
initialLoading: boolean = true; initialLoading: boolean = true;
isLoadingClients: boolean = false; isLoadingClients: boolean = false;
searchTerm = ''; searchTerm = '';
@ -334,11 +338,12 @@ export class GroupsComponent implements OnInit, OnDestroy {
} }
public fetchClientsForNode(node: TreeNode, selectedClientsBeforeEdit: string[] = []): void { public fetchClientsForNode(node: any, selectedClientsBeforeEdit: string[] = []): void {
this.isLoadingClients = true; this.isLoadingClients = true;
this.http.get<any>(`${this.baseUrl}/clients?organizationalUnit.id=${node.id}`).subscribe({ this.http.get<any>(`${this.baseUrl}/clients?organizationalUnit.id=${node.id}&page=${this.page + 1}&itemsPerPage=${this.itemsPerPage}`).subscribe({
next: (response) => { next: (response) => {
this.selectedClients.data = response['hydra:member']; this.selectedClients.data = response['hydra:member'];
this.length = response['hydra:totalItems'];
this.arrayClients = this.selectedClients.data; this.arrayClients = this.selectedClients.data;
this.hasClients = node.hasClients ?? false; this.hasClients = node.hasClients ?? false;
this.isLoadingClients = false; this.isLoadingClients = false;
@ -732,4 +737,11 @@ export class GroupsComponent implements OnInit, OnDestroy {
inputElement.value = ''; inputElement.value = '';
this.filterClients(''); this.filterClients('');
} }
onPageChange(event: PageEvent): void {
this.page = event.pageIndex;
this.itemsPerPage = event.pageSize;
this.length = event.length;
this.fetchClientsForNode(this.selectedNode);
}
} }

View File

@ -2,10 +2,6 @@
width: 100%; width: 100%;
} }
form {
padding: 20px;
}
.spacing-container { .spacing-container {
margin-top: 20px; margin-top: 20px;
margin-bottom: 16px; margin-bottom: 16px;

View File

@ -1,38 +1,62 @@
<h2 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Añadir' }} subred</h2> <h2 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Añadir' }} subred</h2>
<mat-dialog-content> <mat-dialog-content>
<form [formGroup]="subnetForm">
<div class="spacing-container"> <div class="spacing-container">
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Nombre</mat-label> <mat-label>Nombre</mat-label>
<input matInput [(ngModel)]="name" placeholder="Nombre de la subred" required> <input matInput formControlName="name" placeholder="Nombre de la subred" required>
<mat-error *ngIf="subnetForm.controls['name'].invalid">
El nombre de la subred es obligatorio.
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Netmask</mat-label> <mat-label>Netmask</mat-label>
<input matInput [(ngModel)]="netmask" placeholder="Netmask" required> <input matInput formControlName="netmask" placeholder="Netmask" required>
<mat-error *ngIf="subnetForm.controls['netmask'].invalid">
El netmask de la subred es obligatorio.
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Dirección IP</mat-label> <mat-label>Dirección IP</mat-label>
<input matInput [(ngModel)]="ipAddress" placeholder="Dirección IP" required> <input matInput formControlName="ipAddress" placeholder="Dirección IP" required>
<mat-error *ngIf="subnetForm.controls['ipAddress'].invalid">
La ip de la subred es obligatorio.
</mat-error>
</mat-form-field> </mat-form-field>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<span class="step-title">Parámetros avanzados</span> <span class="step-title">Parámetros avanzados</span>
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Next Server</mat-label> <mat-label>Next Server</mat-label>
<input matInput [(ngModel)]="nextServer" placeholder="Next Server"> <input matInput formControlName="nextServer" placeholder="Next Server">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Boot File Name</mat-label> <mat-label>Boot File Name</mat-label>
<input matInput [(ngModel)]="bootFileName" placeholder="Boot File Name"> <input matInput formControlName="bootFileName" placeholder="Boot File Name">
</mat-form-field> </mat-form-field>
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Router</mat-label> <mat-label>Router</mat-label>
<input matInput [(ngModel)]="router" placeholder="Router"> <input matInput formControlName="router" placeholder="Router">
</mat-form-field>
<mat-form-field appearance="fill" class="full-width">
<mat-label>DNS</mat-label>
<input matInput formControlName="dns" placeholder="DNS">
<mat-error *ngIf="subnetForm.controls['dns'].invalid">
Formato inválido. Introduzca direcciones IP separadas por comas.
</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
</form>
</mat-dialog-content> </mat-dialog-content>
<mat-dialog-actions class="action-container"> <mat-dialog-actions class="action-container">
<button class="ordinary-button" (click)="onNoClick()">Cancelar</button> <button class="ordinary-button" (click)="onNoClick()">Cancelar</button>
<button class="submit-button" (click)="save()" cdkFocusInitial>Guardar</button> <button class="submit-button" (click)="save()" [disabled]="subnetForm.invalid" cdkFocusInitial>Guardar</button>
</mat-dialog-actions> </mat-dialog-actions>

View File

@ -1,8 +1,8 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Component, Inject, OnInit } from '@angular/core'; import { Component, Inject, OnInit } from '@angular/core';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ToastrService } from 'ngx-toastr'; import { ToastrService } from 'ngx-toastr';
import {DeleteModalComponent} from "../../../shared/delete_modal/delete-modal/delete-modal.component";
@Component({ @Component({
selector: 'app-create-subnet', selector: 'app-create-subnet',
@ -11,23 +11,28 @@ import {DeleteModalComponent} from "../../../shared/delete_modal/delete-modal/de
}) })
export class CreateSubnetComponent implements OnInit { export class CreateSubnetComponent implements OnInit {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
subnetId: string | null = null; subnetForm: FormGroup;
name: string = '';
netmask: string = '';
ipAddress: string = '';
nextServer: string = '';
bootFileName: string = '';
router: string = '';
serverId: number = 0;
isEditMode: boolean = false; isEditMode: boolean = false;
subnetId: string | null = null;
constructor( constructor(
private toastService: ToastrService, private toastService: ToastrService,
private http: HttpClient, private http: HttpClient,
private fb: FormBuilder,
public dialogRef: MatDialogRef<CreateSubnetComponent>, public dialogRef: MatDialogRef<CreateSubnetComponent>,
public dialog: MatDialog, public dialog: MatDialog,
@Inject(MAT_DIALOG_DATA) public data: any @Inject(MAT_DIALOG_DATA) public data: any
) { } ) {
this.subnetForm = this.fb.group({
name: ['', Validators.required],
netmask: ['', Validators.required],
ipAddress: ['', Validators.required],
router: [''],
dns: ['', Validators.pattern(/^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?),)*((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/)],
nextServer: [''],
bootFileName: ['']
});
}
ngOnInit(): void { ngOnInit(): void {
if (this.data) { if (this.data) {
@ -38,13 +43,15 @@ export class CreateSubnetComponent implements OnInit {
loadData() { loadData() {
this.subnetId = this.data.uuid; this.subnetId = this.data.uuid;
this.name = this.data.name; this.subnetForm.patchValue({
this.netmask = this.data.netmask; name: this.data.name,
this.ipAddress = this.data.ipAddress; netmask: this.data.netmask,
this.nextServer = this.data.nextServer; dns: this.data.dns,
this.bootFileName = this.data.bootFileName; ipAddress: this.data.ipAddress,
this.router = this.data.router; nextServer: this.data.nextServer,
this.serverId = this.data.serverId; bootFileName: this.data.bootFileName,
router: this.data.router
});
} }
onNoClick(): void { onNoClick(): void {
@ -52,19 +59,16 @@ export class CreateSubnetComponent implements OnInit {
} }
save(): void { save(): void {
const payload = { if (this.subnetForm.invalid) {
name: this.name, this.toastService.error('Por favor, revisa los campos del formulario');
netmask: this.netmask, return;
ipAddress: this.ipAddress, }
router: this.router || null,
nextServer: this.nextServer || null,
bootFileName: this.bootFileName || null
};
if (!this.data){ const payload = this.subnetForm.value;
this.http.post(`${this.baseUrl}/subnets`, payload)
.subscribe({ if (!this.isEditMode) {
next: (response) => { this.http.post(`${this.baseUrl}/subnets`, payload).subscribe({
next: () => {
this.toastService.success('Configuración de red añadida exitosamente'); this.toastService.success('Configuración de red añadida exitosamente');
this.dialogRef.close(); this.dialogRef.close();
}, },
@ -73,9 +77,8 @@ export class CreateSubnetComponent implements OnInit {
} }
}); });
} else { } else {
this.http.patch(`${this.baseUrl}/subnets/${this.subnetId}`, payload) this.http.patch(`${this.baseUrl}/subnets/${this.subnetId}`, payload).subscribe({
.subscribe({ next: () => {
next: (response) => {
this.toastService.success('Configuración de red actualizada exitosamente'); this.toastService.success('Configuración de red actualizada exitosamente');
this.dialogRef.close(); this.dialogRef.close();
}, },

View File

@ -66,10 +66,8 @@ export class OgDhcpSubnetsComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.loading = true; this.loading = true;
this.loadSubnets();
this.loadAlert() this.loadAlert()
this.syncSubnets() this.syncSubnets()
this.loading = false;
} }
loadSubnets() { loadSubnets() {
@ -93,7 +91,9 @@ export class OgDhcpSubnetsComponent implements OnInit {
.subscribe(response => { .subscribe(response => {
this.toastService.success('Sincronización con componente DHCP exitosa'); this.toastService.success('Sincronización con componente DHCP exitosa');
this.loadSubnets() this.loadSubnets()
this.loading = false;
}, error => { }, error => {
this.loading = false;
this.toastService.error('Error al sincronizar'); this.toastService.error('Error al sincronizar');
}); });
} }