refs #1071 Add execute command on single commands
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
parent
3f895df458
commit
8152d310f8
|
@ -118,6 +118,7 @@ import { AddClientsToPxeComponent } from './components/ogboot/pxe/add-clients-to
|
|||
import { ClientsComponent } from './components/ogboot/pxe/clients/clients.component';
|
||||
import { RepositoriesComponent } from './components/repositories/repositories.component';
|
||||
import { CreateRepositoryComponent } from './components/repositories/create-repository/create-repository.component';
|
||||
import { ExecuteCommandComponent } from './components/commands/main-commands/execute-command/execute-command.component';
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
|
@ -193,6 +194,7 @@ import { CreateRepositoryComponent } from './components/repositories/create-repo
|
|||
ClientsComponent,
|
||||
RepositoriesComponent,
|
||||
CreateRepositoryComponent,
|
||||
ExecuteCommandComponent,
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
imports: [BrowserModule,
|
||||
|
|
|
@ -36,10 +36,11 @@
|
|||
|
||||
<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="info" (click)="viewDetails($event, client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" [disabled]="client.readOnly" (click)="editCommand($event, client)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" [disabled]="client.readOnly" (click)="deleteCommand($event, client)"><mat-icon i18n="@@deleteElementTooltip">delete</mat-icon></button>
|
||||
<td mat-cell *matCellDef="let command" style="text-align: center;">
|
||||
<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 i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" [disabled]="command.readOnly" (click)="editCommand($event, command)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" [disabled]="command.readOnly" (click)="deleteCommand($event, command)"><mat-icon i18n="@@deleteElementTooltip">delete</mat-icon></button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { CreateCommandComponent } from './create-command/create-command.componen
|
|||
import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { ExecuteCommandComponent } from './execute-command/execute-command.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-commands',
|
||||
|
@ -91,7 +92,6 @@ export class CommandsComponent implements OnInit {
|
|||
}).afterClosed().subscribe(() => this.search());
|
||||
}
|
||||
|
||||
|
||||
deleteCommand(event: MouseEvent, command: any): void {
|
||||
event.stopPropagation();
|
||||
this.dialog.open(DeleteModalComponent, {
|
||||
|
@ -112,6 +112,19 @@ 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 {
|
||||
this.page = event.pageIndex;
|
||||
this.itemsPerPage = event.pageSize;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
.form-container {
|
||||
padding: 20px 24px;
|
||||
width: 100%; /* Asegura que el formulario ocupe el ancho completo */
|
||||
}
|
||||
|
||||
.command-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 15px 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.mat-dialog-content {
|
||||
padding: 24px;
|
||||
width: 100%; /* Ocupar el ancho completo del modal */
|
||||
}
|
||||
|
||||
.mat-dialog-actions {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<h2 mat-dialog-title>Ejecutar Comando</h2>
|
||||
|
||||
<mat-dialog-content class="form-container">
|
||||
<form [formGroup]="form" class="command-form">
|
||||
|
||||
<!-- Selector de Unidad Organizativa -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Unidad Organizativa</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>
|
||||
|
||||
<!-- Selector de Subunidad Organizativa -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Subunidad Organizativa</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>
|
||||
|
||||
<!-- Selector de Cliente (PC) con checkboxes -->
|
||||
<div class="checkbox-group">
|
||||
<label>Clientes (PC)</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>No hay clientes disponibles</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button (click)="closeModal()">Cancelar</button>
|
||||
<button mat-button (click)="executeCommand()" [disabled]="!form.get('clientSelection')?.value.length">Ejecutar</button>
|
||||
</mat-dialog-actions>
|
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ExecuteCommandComponent } from './execute-command.component';
|
||||
|
||||
describe('ExecuteCommandComponent', () => {
|
||||
let component: ExecuteCommandComponent;
|
||||
let fixture: ComponentFixture<ExecuteCommandComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ExecuteCommandComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ExecuteCommandComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,100 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-execute-command',
|
||||
templateUrl: './execute-command.component.html',
|
||||
styleUrls: ['./execute-command.component.css']
|
||||
})
|
||||
export class ExecuteCommandComponent implements OnInit {
|
||||
form: FormGroup;
|
||||
units: any[] = [];
|
||||
childUnits: any[] = [];
|
||||
clients: any[] = [];
|
||||
selectedClients: any[] = [];
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<ExecuteCommandComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private http: HttpClient,
|
||||
private fb: FormBuilder
|
||||
) {
|
||||
this.form = this.fb.group({
|
||||
unit: [null],
|
||||
childUnit: [null],
|
||||
clientSelection: [[]]
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadUnits();
|
||||
this.form.get('unit')?.valueChanges.subscribe(value => this.onUnitChange(value));
|
||||
this.form.get('childUnit')?.valueChanges.subscribe(value => this.onChildUnitChange(value));
|
||||
}
|
||||
|
||||
loadUnits(): void {
|
||||
this.http.get<any>(`${this.baseUrl}/organizational-units?page=1&itemsPerPage=30`).subscribe(
|
||||
response => {
|
||||
this.units = response['hydra:member'].filter((unit: { type: string; }) => unit.type === 'organizational-unit');
|
||||
},
|
||||
error => console.error('Error fetching organizational units:', 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 {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
toggleClientSelection(clientId: string): void {
|
||||
const selectedClients = this.form.get('clientSelection')?.value;
|
||||
if (selectedClients.includes(clientId)) {
|
||||
this.form.get('clientSelection')?.setValue(selectedClients.filter((id: string) => id !== clientId));
|
||||
} else {
|
||||
this.form.get('clientSelection')?.setValue([...selectedClients, clientId]);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue