import { Component, OnInit, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog'; import { ToastrService } from 'ngx-toastr'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { ConfigService } from '@services/config.service'; import {of} from "rxjs"; import {startWith, switchMap} from "rxjs/operators"; import {CreateTaskScheduleComponent} from "../create-task-schedule/create-task-schedule.component"; @Component({ selector: 'app-create-task', templateUrl: './create-task.component.html', styleUrls: ['./create-task.component.css'] }) export class CreateTaskComponent implements OnInit { baseUrl: string; taskForm: FormGroup; availableCommandGroups: any[] = []; selectedGroupCommands: any[] = []; availableIndividualCommands: any[] = []; apiUrl: string; editing: boolean = false; availableOrganizationalUnits: any[] = []; clients: any[] = []; allOrganizationalUnits: any[] = []; loading: boolean = false; taskMode: 'create' | 'add' = 'create'; existingTasks: any[] = []; selectedExistingTask: string | null = null; executionOrder: number | null = null; constructor( private fb: FormBuilder, private http: HttpClient, private configService: ConfigService, private toastr: ToastrService, private dialog: MatDialog, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any ) { this.baseUrl = this.configService.apiUrl; this.apiUrl = `${this.baseUrl}/command-tasks`; this.taskForm = this.fb.group({ scope: [ this.data?.scope ? this.data.scope : '', Validators.required], name: ['', Validators.required], organizationalUnit: [ this.data?.organizationalUnit ? this.data.organizationalUnit : null, Validators.required], notes: [''], scheduleAfterCreate: [false] }); } ngOnInit(): void { this.loading = true; const observables = [ this.loadCommandGroups(), this.loadIndividualCommands(), this.loadOrganizationalUnits(), this.startUnitsFilter(), this.loadTasks() ]; Promise.all(observables).then(() => { if (this.data.task) { this.editing = true; this.loadData().then(() => { this.loading = false; }) } else { this.loading = false; } }).catch(() => { this.loading = false; }) } loadData(): Promise { return new Promise((resolve, reject) => { this.http.get(`${this.baseUrl}${this.data.task['@id']}`).subscribe( (data) => { this.taskForm.patchValue({ name: data.name, scope: data.scope, organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : null, notes: data.notes, }); resolve(); }, (error) => { this.toastr.error('Error al cargar los datos de la tarea'); reject(error); } ); }) } loadTasks(): Promise { return new Promise((resolve, reject) => { this.http.get(`${this.apiUrl}?page=1&itemsPerPage=100`).subscribe( (data) => { this.existingTasks = data['hydra:member']; resolve(); }, (error) => { this.toastr.error('Error al cargar las tareas existentes'); reject(error); } ); }); } onScopeChange(scope: string): void { this.filterUnits(scope).subscribe(filteredUnits => { this.availableOrganizationalUnits = filteredUnits; this.taskForm.get('organizationalUnit')?.setValue(''); }); } startUnitsFilter(): Promise { return new Promise((resolve, reject) => { this.taskForm.get('scope')?.valueChanges.pipe( startWith(this.taskForm.get('scope')?.value), switchMap((value) => this.filterUnits(value)) ).subscribe(filteredUnits => { this.availableOrganizationalUnits = filteredUnits; resolve(); }, error => { this.toastr.error('Error al filtrar las unidades organizacionales'); reject(error); }); }) } filterUnits(value: string) { const filtered = this.allOrganizationalUnits.filter(unit => unit.type === value); return of(filtered); } loadCommandGroups(): Promise { return new Promise((resolve, reject) => { this.http.get(`${this.baseUrl}/command-groups`).subscribe( (data) => { this.availableCommandGroups = data['hydra:member']; resolve(); }, (error) => { this.toastr.error('Error al cargar los grupos de comandos'); reject(error); }); }); } loadIndividualCommands(): Promise { return new Promise((resolve, reject) => { this.http.get(`${this.baseUrl}/commands`).subscribe( (data) => { this.availableIndividualCommands = data['hydra:member']; resolve(); }, (error) => { this.toastr.error('Error al cargar los comandos individuales'); reject(error); }); }); } loadOrganizationalUnits(): Promise { return new Promise((resolve, reject) => { this.http.get(`${this.baseUrl}/organizational-units?page=1&itemsPerPage=100`).subscribe( (data) => { this.allOrganizationalUnits = data['hydra:member']; this.availableOrganizationalUnits = [...this.allOrganizationalUnits]; resolve(); }, (error) => { this.toastr.error('Error al cargar las unidades organizacionales'); reject(error); } ); }); } addToExistingTask() { if (!this.selectedExistingTask) { this.toastr.error('Debes seleccionar una tarea existente.'); return; } if (this.executionOrder == null || this.executionOrder < 1) { this.toastr.error('Debes introducir un orden de ejecución válido (mayor que 0).'); return; } const data = { taskId: this.selectedExistingTask, executionOrder: this.executionOrder }; this.toastr.success('Tarea actualizada con éxito'); this.dialogRef.close(data); } saveTask(): void { if (this.taskForm.invalid) { this.toastr.error('Por favor, rellene todos los campos obligatorios'); return; } const formData = this.taskForm.value; const payload: any = { name: formData.name, scope: formData.scope, organizationalUnit: formData.organizationalUnit, notes: formData.notes || '', }; if (this.editing) { const taskId = this.data.task.uuid; this.http.patch(`${this.apiUrl}/${taskId}`, payload).subscribe({ next: () => { this.toastr.success('Tarea actualizada con éxito'); this.dialogRef.close(true); }, error: () => { this.toastr.error('Error al actualizar la tarea'); } }); } else { this.http.post(this.apiUrl, payload).subscribe({ next: response => { this.toastr.success('Tarea creada con éxito'); this.dialogRef.close(response); if (formData.scheduleAfterCreate) { const dialogRef = this.dialog.open(CreateTaskScheduleComponent, { width: '800px', data: { task: response } }); dialogRef.afterClosed().subscribe(result => { if (result) { this.toastr.success('Tarea programada correctamente'); } }); } }, error: () => { this.toastr.error('Error al crear la tarea'); } }); } } close(): void { this.dialogRef.close(false); } }