develop #70
|
|
@ -38,6 +38,7 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
{ translationKey: 'executeCommands.hardwareInventory', slug: 'hardware-inventory', disabled: false },
|
||||
{ translationKey: 'executeCommands.runScript', slug: 'run-script', disabled: false },
|
||||
{ translationKey: 'executeCommands.refresh', slug: 'refresh', disabled: false },
|
||||
{ translationKey: 'executeCommands.deleteLease', slug: 'delete-lease', disabled: false },
|
||||
];
|
||||
|
||||
client: any = {};
|
||||
|
|
@ -81,7 +82,8 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
'hardware-inventory',
|
||||
'remove-cache-image',
|
||||
'partition',
|
||||
'refresh'
|
||||
'refresh',
|
||||
'delete-lease'
|
||||
],
|
||||
'ou-minimal': [
|
||||
'power-on',
|
||||
|
|
@ -184,6 +186,10 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
if (action === 'refresh') {
|
||||
this.refreshClient();
|
||||
}
|
||||
|
||||
if (action === 'delete-lease') {
|
||||
this.deleteClientLease();
|
||||
}
|
||||
}
|
||||
|
||||
rebootClient(): void {
|
||||
|
|
@ -395,4 +401,26 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
deleteClientLease(): void {
|
||||
if (this.clientData.length === 0) {
|
||||
this.toastService.error('No hay clientes seleccionados');
|
||||
return;
|
||||
}
|
||||
|
||||
const requests = this.clientData.map((client: any) =>
|
||||
this.http.delete(`${this.baseUrl}/clients/${client.uuid}/delete-lease`).toPromise()
|
||||
);
|
||||
|
||||
Promise.allSettled(requests).then(results => {
|
||||
const errors = results.filter(r => r.status === 'rejected');
|
||||
if (errors.length === 0) {
|
||||
this.toastService.success('Lease(s) DHCP eliminada(s) correctamente');
|
||||
} else if (errors.length < results.length) {
|
||||
this.toastService.warning(`${results.length - errors.length} lease(s) eliminada(s), ${errors.length} con error`);
|
||||
} else {
|
||||
this.toastService.error('Error al eliminar las leases DHCP');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
savedFilterNames: [string, string][] = [];
|
||||
selectedTreeFilter = '';
|
||||
syncingClientIds = new Set<string>();
|
||||
isCheckingNodeStatus = false;
|
||||
private originalTreeData: TreeNode[] = [];
|
||||
arrayClients: any[] = [];
|
||||
filters: { [key: string]: string } = {};
|
||||
|
|
@ -243,6 +244,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
|
||||
private transformer = (node: TreeNode, level: number): FlatNode => ({
|
||||
id: node.id,
|
||||
uuid: node.uuid,
|
||||
name: node.name,
|
||||
type: node.type,
|
||||
level,
|
||||
|
|
@ -463,6 +465,10 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
});
|
||||
|
||||
if (this.isCheckingNodeStatus) {
|
||||
members.forEach((c: Client) => c.uuid && this.syncingClientIds.add(c.uuid));
|
||||
}
|
||||
|
||||
// Calcular estadísticas después de cargar los clientes
|
||||
this.calculateLocalStats();
|
||||
},
|
||||
|
|
@ -843,23 +849,35 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
|
||||
|
||||
getStatusForAllClientsInNode(node: any): void {
|
||||
this.http.get<any>(`${this.baseUrl}/clients?organizationalUnit.id=${node.id}&itemsPerPage=1000`).subscribe({
|
||||
next: (response: any) => {
|
||||
const clients: Client[] = response['hydra:member'];
|
||||
const validClients = clients.filter(client => client.uuid && client['@id']);
|
||||
if (validClients.length === 0) return;
|
||||
if (!node.uuid) return;
|
||||
|
||||
validClients.forEach(client => {
|
||||
this.syncingClientIds.add(client.uuid);
|
||||
this.subscriptions.add(
|
||||
this.http.post(`${this.baseUrl}${client['@id']}/agent/status`, {}).subscribe({
|
||||
next: () => this.syncingClientIds.delete(client.uuid),
|
||||
error: () => this.syncingClientIds.delete(client.uuid),
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
this.isCheckingNodeStatus = true;
|
||||
this.selectedClients.data.forEach(c => c.uuid && this.syncingClientIds.add(c.uuid));
|
||||
|
||||
this.subscriptions.add(
|
||||
this.http.post<{ results: Array<{ uuid: string; ip: string; status: string; success: boolean }> }>(
|
||||
`${this.baseUrl}/organizational-units/${node.uuid}/agent/status`,
|
||||
{}
|
||||
).subscribe({
|
||||
next: (response) => {
|
||||
this.isCheckingNodeStatus = false;
|
||||
const statusMap = new Map(response.results.map(r => [r.uuid, r.status]));
|
||||
response.results.forEach(r => this.syncingClientIds.delete(r.uuid));
|
||||
this.selectedClients.data = this.selectedClients.data.map(client => {
|
||||
const newStatus = statusMap.get(client.uuid);
|
||||
return newStatus ? { ...client, status: newStatus } : client;
|
||||
});
|
||||
this.arrayClients = this.selectedClients.data;
|
||||
this.calculateLocalStats();
|
||||
this.toastr.success('Estado del aula actualizado');
|
||||
},
|
||||
error: () => {
|
||||
this.isCheckingNodeStatus = false;
|
||||
this.selectedClients.data.forEach(c => c.uuid && this.syncingClientIds.delete(c.uuid));
|
||||
this.toastr.error('Error al comprobar el estado del aula');
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ export interface TreeNode {
|
|||
|
||||
export interface FlatNode {
|
||||
id?: string;
|
||||
uuid?: string;
|
||||
name: string;
|
||||
type: string;
|
||||
level: number;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@
|
|||
</button>
|
||||
<button mat-icon-button color="primary"
|
||||
(click)="addClientsToSubnet(subnet)"><mat-icon>computer</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="deleteSubnetLeases(subnet)"
|
||||
matTooltip="Borrar leases de la subred"><mat-icon>delete_sweep</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="toggleAction(subnet, 'delete')"><mat-icon>delete</mat-icon></button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
|
|
|||
|
|
@ -296,6 +296,26 @@ export class OgDhcpSubnetsComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
deleteSubnetLeases(subnet: Subnet) {
|
||||
const dialogRef = this.dialog.open(DeleteModalComponent, {
|
||||
width: '300px',
|
||||
data: { name: `leases de ${subnet.name}` }
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
this.http.delete(`${this.baseUrl}/og-dhcp/server/${subnet.uuid}/delete-leases`, {}).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Leases de la subred eliminadas correctamente');
|
||||
},
|
||||
error: (error) => {
|
||||
this.toastService.error(error.error?.['hydra:description'] || 'Error al eliminar leases de la subred');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addClientsToSubnet(subnet: Subnet) {
|
||||
const dialogRef = this.dialog.open(AddClientsToSubnetComponent, {
|
||||
width: '800px',
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@
|
|||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;">
|
||||
<button mat-icon-button color="primary" (click)="deleteClientLease(client)"
|
||||
matTooltip="Borrar lease del cliente">
|
||||
<mat-icon>delete_sweep</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="deleteClient(client)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -75,6 +75,26 @@ export class ShowClientsComponent implements OnInit {
|
|||
);
|
||||
}
|
||||
|
||||
deleteClientLease(client: any): void {
|
||||
const dialogRef = this.dialog.open(DeleteModalComponent, {
|
||||
width: '300px',
|
||||
data: { name: `lease de ${client.name}` }
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
this.http.delete(`${this.baseUrl}/og-dhcp/server/${this.data.subnetUuid}/delete-lease/${client.uuid}`, {}).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Lease del cliente eliminada correctamente');
|
||||
},
|
||||
error: (error) => {
|
||||
this.toastService.error(error.error?.['hydra:description'] || 'Error al eliminar lease del cliente');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
deleteClient(client: any): void {
|
||||
const dialogRef = this.dialog.open(DeleteModalComponent, {
|
||||
width: '300px',
|
||||
|
|
|
|||
|
|
@ -592,7 +592,8 @@
|
|||
"softwareInventory": "Software Inventory",
|
||||
"hardwareInventory": "Hardware Inventory",
|
||||
"runScript": "Run Script",
|
||||
"refresh": "Refresh"
|
||||
"refresh": "Refresh",
|
||||
"deleteLease": "Delete DHCP Lease"
|
||||
},
|
||||
"changeOU": "Change Organizational Unit",
|
||||
"moveClientsTooltip": "Move clients to another organizational unit",
|
||||
|
|
|
|||
|
|
@ -593,7 +593,8 @@
|
|||
"softwareInventory": "Inventario Software",
|
||||
"hardwareInventory": "Inventario Hardware",
|
||||
"runScript": "Ejecutar script",
|
||||
"refresh": "Refrescar"
|
||||
"refresh": "Refrescar",
|
||||
"deleteLease": "Borrar lease DHCP"
|
||||
},
|
||||
"changeOU": "Mover",
|
||||
"moveClientsTooltip": "Mover clientes a otra unidad organizativa",
|
||||
|
|
|
|||
Loading…
Reference in New Issue