refs #1282. Adapted ogCore filter. Refactor unused and wrong code
parent
369e09ee86
commit
013536bc9e
|
@ -31,9 +31,11 @@
|
||||||
<ng-container *ngIf="column.columnDef !== 'readOnly'">
|
<ng-container *ngIf="column.columnDef !== 'readOnly'">
|
||||||
{{ column.cell(command) }}
|
{{ column.cell(command) }}
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="column.columnDef === 'readOnly'">
|
<ng-container *ngIf="column.columnDef === 'readOnly'">
|
||||||
<mat-chip *ngIf="command.readOnly" class="mat-chip-readonly-true"><mat-icon style="color:white;">check</mat-icon></mat-chip>
|
<mat-icon [color]="command[column.columnDef] ? 'primary' : 'warn'">
|
||||||
<mat-chip *ngIf="!command.readOnly" class="mat-chip-readonly-false"><mat-icon style="color:white;">close</mat-icon></mat-chip>
|
{{ command[column.columnDef] ? 'check_circle' : 'cancel' }}
|
||||||
|
</mat-icon>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -41,7 +43,6 @@
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'columnActions' | translate }}</th>
|
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'columnActions' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let command" style="text-align: center;" joyrideStep="actionsStep" text="{{ 'actionsStepText' | translate }}">
|
<td mat-cell *matCellDef="let command" style="text-align: center;" joyrideStep="actionsStep" text="{{ 'actionsStepText' | translate }}">
|
||||||
<button mat-icon-button color="info" (click)="executeCommand($event, command)"><mat-icon>play_arrow</mat-icon></button>
|
|
||||||
<button mat-icon-button color="info" (click)="viewDetails($event, command)"><mat-icon>visibility</mat-icon></button>
|
<button mat-icon-button color="info" (click)="viewDetails($event, command)"><mat-icon>visibility</mat-icon></button>
|
||||||
<button mat-icon-button color="primary" [disabled]="command.readOnly" (click)="editCommand($event, command)"><mat-icon>edit</mat-icon></button>
|
<button mat-icon-button color="primary" [disabled]="command.readOnly" (click)="editCommand($event, command)"><mat-icon>edit</mat-icon></button>
|
||||||
<button mat-icon-button color="warn" [disabled]="command.readOnly" (click)="deleteCommand($event, command)"><mat-icon>delete</mat-icon></button>
|
<button mat-icon-button color="warn" [disabled]="command.readOnly" (click)="deleteCommand($event, command)"><mat-icon>delete</mat-icon></button>
|
||||||
|
|
|
@ -114,19 +114,6 @@ export class CommandsComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
executeCommand(event: MouseEvent, command: any): void {
|
|
||||||
this.dialog.open(ExecuteCommandComponent, {
|
|
||||||
width: '50%',
|
|
||||||
data: { commandData: command }
|
|
||||||
}).afterClosed().subscribe((result) => {
|
|
||||||
if (result) {
|
|
||||||
console.log('Comando ejecutado con éxito');
|
|
||||||
} else {
|
|
||||||
console.log('Ejecución de comando cancelada');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageChange(event: any): void {
|
onPageChange(event: any): void {
|
||||||
this.page = event.pageIndex;
|
this.page = event.pageIndex;
|
||||||
this.itemsPerPage = event.pageSize;
|
this.itemsPerPage = event.pageSize;
|
||||||
|
|
|
@ -1,40 +1,10 @@
|
||||||
<h2 mat-dialog-title>{{ 'executeCommandTitle' | translate }}</h2>
|
<button mat-icon-button color="primary" [matMenuTriggerFor]="commandMenu">
|
||||||
|
<mat-icon>terminal</mat-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
<mat-dialog-content class="form-container">
|
<mat-menu #commandMenu="matMenu">
|
||||||
<form [formGroup]="form" class="command-form">
|
<button mat-menu-item [disabled]="command.disabled" *ngFor="let command of arrayCommands" (click)="onCommandSelect(command.slug)">
|
||||||
|
{{ command.name }}
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" class="full-width">
|
|
||||||
<mat-label>{{ 'organizationalUnitLabel' | translate }}</mat-label>
|
|
||||||
<mat-select formControlName="unit">
|
|
||||||
<mat-option *ngFor="let unit of units" [value]="unit.uuid">{{ unit.name }}</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field appearance="fill" class="full-width">
|
|
||||||
<mat-label>{{ 'subOrganizationalUnitLabel' | translate }}</mat-label>
|
|
||||||
<mat-select formControlName="childUnit">
|
|
||||||
<mat-option *ngFor="let child of childUnits" [value]="child.uuid">{{ child.name }}</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<div class="checkbox-group">
|
|
||||||
<label>{{ 'clientsLabel' | translate }}</label>
|
|
||||||
<div *ngIf="clients.length > 0">
|
|
||||||
<mat-checkbox *ngFor="let client of clients"
|
|
||||||
(change)="toggleClientSelection(client.uuid)"
|
|
||||||
[checked]="form.get('clientSelection')?.value.includes(client.uuid)">
|
|
||||||
{{ client.name }}
|
|
||||||
</mat-checkbox>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="clients.length === 0">
|
|
||||||
<p>{{ 'noClientsAvailable' | translate }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</mat-dialog-content>
|
|
||||||
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<button mat-button (click)="closeModal()">{{ 'buttonCancel' | translate }}</button>
|
|
||||||
<button mat-button (click)="executeCommand()" [disabled]="!form.get('clientSelection')?.value.length">{{ 'buttonExecute' | translate }}</button>
|
|
||||||
</mat-dialog-actions>
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { Component, Inject, OnInit } from '@angular/core';
|
import {Component, Inject, Input, OnInit} from '@angular/core';
|
||||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
import {ToastrService} from "ngx-toastr";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-execute-command',
|
selector: 'app-execute-command',
|
||||||
|
@ -9,92 +11,129 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
styleUrls: ['./execute-command.component.css']
|
styleUrls: ['./execute-command.component.css']
|
||||||
})
|
})
|
||||||
export class ExecuteCommandComponent implements OnInit {
|
export class ExecuteCommandComponent implements OnInit {
|
||||||
form: FormGroup;
|
@Input() clientData: any = {};
|
||||||
units: any[] = [];
|
|
||||||
childUnits: any[] = [];
|
|
||||||
clients: any[] = [];
|
|
||||||
selectedClients: any[] = [];
|
|
||||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||||
|
loading: boolean = true;
|
||||||
|
|
||||||
|
arrayCommands: any[] = [
|
||||||
|
{name: 'Enceder', slug: 'power-on', disabled: false},
|
||||||
|
{name: 'Apagar', slug: 'power-off', disabled: false},
|
||||||
|
{name: 'Reiniciar', slug: 'reboot', disabled: false},
|
||||||
|
{name: 'Iniciar Sesión', slug: 'login', disabled: true},
|
||||||
|
{name: 'Crear Image', slug: 'create-image', disabled: false},
|
||||||
|
{name: 'Deploy Image', slug: 'deploy-image', disabled: false},
|
||||||
|
{name: 'Eliminar Imagen Cache', slug: 'delete-image-cache', disabled: true},
|
||||||
|
{name: 'Particionar y Formatear', slug: 'partition', disabled: false},
|
||||||
|
{name: 'Inventario Software', slug: 'software-inventory', disabled: true},
|
||||||
|
{name: 'Inventario Hardware', slug: 'hardware-inventory', disabled: true},
|
||||||
|
{name: 'Ejecutar script', slug: 'run-script', disabled: true},
|
||||||
|
];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dialogRef: MatDialogRef<ExecuteCommandComponent>,
|
private dialog: MatDialog,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
|
||||||
private http: HttpClient,
|
private http: HttpClient,
|
||||||
private fb: FormBuilder
|
private fb: FormBuilder,
|
||||||
|
private router: Router,
|
||||||
|
private toastService: ToastrService
|
||||||
) {
|
) {
|
||||||
this.form = this.fb.group({
|
|
||||||
unit: [null],
|
|
||||||
childUnit: [null],
|
|
||||||
clientSelection: [[]]
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.loadUnits();
|
this.clientData = this.clientData || {};
|
||||||
this.form.get('unit')?.valueChanges.subscribe(value => this.onUnitChange(value));
|
this.loadClient(this.clientData)
|
||||||
this.form.get('childUnit')?.valueChanges.subscribe(value => this.onChildUnitChange(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadUnits(): void {
|
loadClient = (uuid: string) => {
|
||||||
this.http.get<any>(`${this.baseUrl}/organizational-units?page=1&itemsPerPage=30`).subscribe(
|
this.http.get<any>(`${this.baseUrl}${uuid}`).subscribe({
|
||||||
response => {
|
next: data => {
|
||||||
this.units = response['hydra:member'].filter((unit: { type: string; }) => unit.type === 'organizational-unit');
|
this.clientData = data;
|
||||||
|
this.loading = false;
|
||||||
},
|
},
|
||||||
error => console.error('Error fetching organizational units:', error)
|
error: error => {
|
||||||
);
|
console.error('Error al obtener el cliente:', error);
|
||||||
}
|
|
||||||
|
|
||||||
onUnitChange(unitId: string): void {
|
|
||||||
const unit = this.units.find(unit => unit.uuid === unitId);
|
|
||||||
this.childUnits = unit ? this.getAllChildren(unit) : [];
|
|
||||||
this.clients = [];
|
|
||||||
this.form.patchValue({ childUnit: null, clientSelection: [] });
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllChildren(unit: any): any[] {
|
|
||||||
let allChildren = [];
|
|
||||||
if (unit.children && unit.children.length > 0) {
|
|
||||||
for (const child of unit.children) {
|
|
||||||
allChildren.push(child);
|
|
||||||
allChildren = allChildren.concat(this.getAllChildren(child));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
onChildUnitChange(childUnitId: string): void {
|
|
||||||
const childUnit = this.childUnits.find(unit => unit.uuid === childUnitId);
|
|
||||||
this.clients = childUnit && childUnit.clients ? childUnit.clients : [];
|
|
||||||
this.form.patchValue({ clientSelection: [] });
|
|
||||||
}
|
|
||||||
|
|
||||||
executeCommand(): void {
|
|
||||||
const payload = {
|
|
||||||
clients: ['/clients/'+this.form.get('clientSelection')?.value]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.http.post(`${this.baseUrl}/commands/${this.data.commandData.uuid}/execute`, payload)
|
|
||||||
.subscribe({
|
|
||||||
next: () => {
|
|
||||||
console.log('Comando ejecutado con éxito');
|
|
||||||
this.dialogRef.close(true);
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
console.error('Error al ejecutar el comando:', error);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
closeModal(): void {
|
onCommandSelect(action: any): void {
|
||||||
this.dialogRef.close(false);
|
if (action === 'partition') {
|
||||||
|
this.openPartitionAssistant();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleClientSelection(clientId: string): void {
|
if (action === 'create-image') {
|
||||||
const selectedClients = this.form.get('clientSelection')?.value;
|
this.openCreateImageAssistant();
|
||||||
if (selectedClients.includes(clientId)) {
|
}
|
||||||
this.form.get('clientSelection')?.setValue(selectedClients.filter((id: string) => id !== clientId));
|
|
||||||
} else {
|
if (action === 'deploy-image') {
|
||||||
this.form.get('clientSelection')?.setValue([...selectedClients, clientId]);
|
this.openDeployImageAssistant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === 'reboot') {
|
||||||
|
this.rebootClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === 'power-off') {
|
||||||
|
this.powerOffClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === 'power-on') {
|
||||||
|
this.powerOnClient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rebootClient(): void {
|
||||||
|
this.http.post(`${this.baseUrl}/clients/server/${this.clientData.uuid}/reboot`, {}).subscribe(
|
||||||
|
response => {
|
||||||
|
this.toastService.success('Cliente actualizado correctamente');
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.toastService.error('Error de conexión con el cliente');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
powerOnClient(): void {
|
||||||
|
const payload = {
|
||||||
|
client: this.clientData['@id']
|
||||||
|
}
|
||||||
|
|
||||||
|
this.http.post(`${this.baseUrl}${this.clientData.repository['@id']}/wol`, payload).subscribe(
|
||||||
|
response => {
|
||||||
|
this.toastService.success('Cliente actualizado correctamente');
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.toastService.error('Error de conexión con el cliente');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
powerOffClient(): void {
|
||||||
|
this.http.post(`${this.baseUrl}/clients/server/${this.clientData.uuid}/power-off`, {}).subscribe(
|
||||||
|
response => {
|
||||||
|
this.toastService.success('Cliente actualizado correctamente');
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.toastService.error('Error de conexión con el cliente');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
openPartitionAssistant(): void {
|
||||||
|
this.router.navigate([`/clients/${this.clientData.uuid}/partition-assistant`]).then(r => {
|
||||||
|
console.log('navigated', r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openCreateImageAssistant(): void {
|
||||||
|
this.router.navigate([`/clients/${this.clientData.uuid}/create-image`]).then(r => {
|
||||||
|
console.log('navigated', r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openDeployImageAssistant(): void {
|
||||||
|
this.router.navigate([`/clients/${this.clientData.uuid}/deploy-image`]).then(r => {
|
||||||
|
console.log('navigated', r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,7 @@ export class ClientMainViewComponent implements OnInit {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGeneralData() {
|
updateGeneralData() {
|
||||||
this.generalData = [
|
this.generalData = [
|
||||||
{ property: 'Nombre', value: this.clientData?.name || '' },
|
{ property: 'Nombre', value: this.clientData?.name || '' },
|
||||||
|
|
|
@ -187,7 +187,6 @@ export class DeployImageComponent {
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (response) => {
|
next: (response) => {
|
||||||
this.toastService.success('Petición de despliegue enviada correctamente');
|
this.toastService.success('Petición de despliegue enviada correctamente');
|
||||||
this.router.navigate(['/commands-logs'])
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
|
|
|
@ -166,10 +166,6 @@
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<mat-menu #menu="matMenu">
|
<mat-menu #menu="matMenu">
|
||||||
<button *ngIf="selectedNode?.type === 'classroom'" mat-menu-item [matMenuTriggerFor]="commandMenu" (click)="fetchCommands()">
|
|
||||||
<mat-icon>play_arrow</mat-icon>
|
|
||||||
<span>{{ 'executeCommand' | translate }}</span>
|
|
||||||
</button>
|
|
||||||
<button mat-menu-item (click)="onShowDetailsClick($event, selectedNode)">
|
<button mat-menu-item (click)="onShowDetailsClick($event, selectedNode)">
|
||||||
<mat-icon matTooltip="{{ 'viewUnitTooltip' | translate }}" matTooltipHideDelay="0">visibility</mat-icon>
|
<mat-icon matTooltip="{{ 'viewUnitTooltip' | translate }}" matTooltipHideDelay="0">visibility</mat-icon>
|
||||||
<span>{{ 'viewUnitMenu' | translate }}</span>
|
<span>{{ 'viewUnitMenu' | translate }}</span>
|
||||||
|
@ -227,9 +223,7 @@
|
||||||
<button mat-icon-button color="primary" (click)="onShowClientDetail($event, client)">
|
<button mat-icon-button color="primary" (click)="onShowClientDetail($event, client)">
|
||||||
<mat-icon>visibility</mat-icon>
|
<mat-icon>visibility</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button color="primary">
|
<app-execute-command [clientData]="client['@id']"></app-execute-command>
|
||||||
<mat-icon>more_vert</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -245,7 +239,6 @@
|
||||||
[src]="'assets/images/ordenador_' + client.status + '.png'"
|
[src]="'assets/images/ordenador_' + client.status + '.png'"
|
||||||
alt="Client Icon"
|
alt="Client Icon"
|
||||||
class="client-image" />
|
class="client-image" />
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -299,25 +292,14 @@
|
||||||
<td mat-cell *matCellDef="let client"> {{ client.parentName }} </td>
|
<td mat-cell *matCellDef="let client"> {{ client.parentName }} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions" >
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'actions' | translate }} </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'actions' | translate }} </th>
|
||||||
<td mat-cell *matCellDef="let client">
|
<td mat-cell *matCellDef="let client">
|
||||||
<button mat-icon-button [matMenuTriggerFor]="clientMenu">
|
<button mat-icon-button [matMenuTriggerFor]="clientMenu">
|
||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
<app-execute-command [clientData]="client['@id']"></app-execute-command>
|
||||||
<mat-menu #clientMenu="matMenu">
|
<mat-menu #clientMenu="matMenu">
|
||||||
|
|
||||||
<mat-menu restoreFocus=false #commandMenu="matMenu" xPosition="before">
|
|
||||||
<button mat-menu-item *ngFor="let command of commands" (click)="executeClientCommand(command, client)">
|
|
||||||
<span>{{ command.name }}</span>
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
|
||||||
|
|
||||||
<button mat-menu-item [matMenuTriggerFor]="commandMenu" (click)="fetchCommands()">
|
|
||||||
<mat-icon>play_arrow</mat-icon>
|
|
||||||
<span>{{ 'executeCommand' | translate }}</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button mat-menu-item (click)="onEditClick($event, client.type, client.uuid)">
|
<button mat-menu-item (click)="onEditClick($event, client.type, client.uuid)">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
<span>{{ 'edit' | translate }}</span>
|
<span>{{ 'edit' | translate }}</span>
|
||||||
|
|
|
@ -135,6 +135,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private transformer = (node: TreeNode, level: number): FlatNode => ({
|
private transformer = (node: TreeNode, level: number): FlatNode => ({
|
||||||
|
id: node.id,
|
||||||
name: node.name,
|
name: node.name,
|
||||||
type: node.type,
|
type: node.type,
|
||||||
level,
|
level,
|
||||||
|
@ -268,6 +269,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
private convertToTreeData(data: UnidadOrganizativa): TreeNode[] {
|
private convertToTreeData(data: UnidadOrganizativa): TreeNode[] {
|
||||||
const processNode = (node: UnidadOrganizativa): TreeNode => ({
|
const processNode = (node: UnidadOrganizativa): TreeNode => ({
|
||||||
|
id: node.id,
|
||||||
name: node.name,
|
name: node.name,
|
||||||
type: node.type,
|
type: node.type,
|
||||||
'@id': node['@id'],
|
'@id': node['@id'],
|
||||||
|
@ -279,34 +281,22 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
|
||||||
onNodeClick(node: TreeNode): void {
|
onNodeClick(node: TreeNode): void {
|
||||||
|
console.log('Node clicked:', node);
|
||||||
this.selectedNode = node;
|
this.selectedNode = node;
|
||||||
this.fetchClientsForNode(node);
|
this.fetchClientsForNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fetchClientsForNode(node: TreeNode): void {
|
private fetchClientsForNode(node: TreeNode): void {
|
||||||
if (node.hasClients && node['@id']) {
|
console.log('Node:', node);
|
||||||
this.subscriptions.add(
|
this.http.get<any>(`${this.baseUrl}/clients?organizationalUnit.id=${node.id}`).subscribe({
|
||||||
this.http.get<{ clients: Client[] }>(`${this.baseUrl}${node['@id']}`).subscribe(
|
next: (response) => {
|
||||||
(data) => {
|
this.selectedClients.data = response['hydra:member'];
|
||||||
const clientsWithParentName = (data.clients || []).map(client => ({
|
this.loading = false;
|
||||||
...client,
|
|
||||||
parentName: node.name
|
|
||||||
}));
|
|
||||||
this.selectedClients.data = clientsWithParentName;
|
|
||||||
this.selectedClients._updateChangeSubscription();
|
|
||||||
if (this._paginator) {
|
|
||||||
this._paginator.firstPage();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
(error) => {
|
error: () => {
|
||||||
console.error('Error fetching clients:', error);
|
this.loading = false;
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.selectedClients.data = [];
|
|
||||||
this.selectedClients._updateChangeSubscription();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getNodeIcon(node: TreeNode): string {
|
getNodeIcon(node: TreeNode): string {
|
||||||
|
@ -494,10 +484,6 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
executeClientCommand(command: Command, client: Client): void {
|
|
||||||
this.toastr.success(`Ejecutando comando: ${command.name} en ${client.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
onShowClientDetail(event: MouseEvent, client: Client): void {
|
onShowClientDetail(event: MouseEvent, client: Client): void {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.router.navigate(['clients', client.uuid], { state: { clientData: client } });
|
this.router.navigate(['clients', client.uuid], { state: { clientData: client } });
|
||||||
|
@ -591,13 +577,13 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
||||||
this.toastr.success('Cliente actualizado correctamente');
|
this.toastr.success('Cliente actualizado correctamente');
|
||||||
this.syncStatus = false;
|
this.syncStatus = false;
|
||||||
this.syncingClientId = null;
|
this.syncingClientId = null;
|
||||||
this.onNodeClick(node);
|
this.search()
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.toastr.error('Error de conexión con el cliente');
|
this.toastr.error('Error de conexión con el cliente');
|
||||||
this.syncStatus = false;
|
this.syncStatus = false;
|
||||||
this.syncingClientId = null;
|
this.syncingClientId = null;
|
||||||
this.onNodeClick(node);
|
this.search()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -60,6 +60,7 @@ export interface ClientCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TreeNode {
|
export interface TreeNode {
|
||||||
|
id?: string
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
type: string;
|
||||||
'@id'?: string;
|
'@id'?: string;
|
||||||
|
@ -70,6 +71,7 @@ export interface TreeNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FlatNode {
|
export interface FlatNode {
|
||||||
|
id?: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: string;
|
type: string;
|
||||||
level: number;
|
level: number;
|
||||||
|
|
Loading…
Reference in New Issue