import { Component, OnInit, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ToastrService } from 'ngx-toastr'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-create-task', templateUrl: './create-task.component.html', styleUrls: ['./create-task.component.css'] }) export class CreateTaskComponent implements OnInit { baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; taskForm: FormGroup; availableCommandGroups: any[] = []; selectedGroupCommands: any[] = []; availableIndividualCommands: any[] = []; apiUrl = `${this.baseUrl}/command-tasks`; editing: boolean = false; availableOrganizationalUnits: any[] = []; selectedUnitChildren: any[] = []; selectedClients: any[] = []; selectedClientIds: Set = new Set(); constructor( private fb: FormBuilder, private http: HttpClient, private toastr: ToastrService, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any ) { this.taskForm = this.fb.group({ commandGroup: ['', Validators.required], extraCommands: [[]], date: ['', Validators.required], time: ['', Validators.required], notes: [''], organizationalUnit: ['', Validators.required], selectedChild: [''], selectedClients: [[]] }); } ngOnInit(): void { this.loadCommandGroups(); this.loadIndividualCommands(); this.loadOrganizationalUnits(); if (this.data && this.data.task) { this.editing = true; this.loadTaskData(this.data.task); } } loadCommandGroups(): void { this.http.get(`${this.baseUrl}/command-groups`).subscribe( (data) => { this.availableCommandGroups = data['hydra:member']; }, (error) => { this.toastr.error('Error al cargar los grupos de comandos'); } ); } loadIndividualCommands(): void { this.http.get(`${this.baseUrl}/commands`).subscribe( (data) => { this.availableIndividualCommands = data['hydra:member']; }, (error) => { this.toastr.error('Error al cargar los comandos individuales'); } ); } loadOrganizationalUnits(): void { this.http.get(`${this.baseUrl}/organizational-units?page=1&itemsPerPage=30`).subscribe( (data) => { this.availableOrganizationalUnits = data['hydra:member'].filter((unit: any) => unit['type'] === 'organizational-unit'); }, (error) => { this.toastr.error('Error al cargar las unidades organizacionales'); } ); } loadTaskData(task: any): void { this.taskForm.patchValue({ commandGroup: task.commandGroup ? task.commandGroup['@id'] : '', extraCommands: task.commands ? task.commands.map((cmd: any) => cmd['@id']) : [], date: task.dateTime ? task.dateTime.split('T')[0] : '', time: task.dateTime ? task.dateTime.split('T')[1].slice(0, 5) : '', notes: task.notes || '', organizationalUnit: task.organizationalUnit ? task.organizationalUnit['@id'] : '' }); if (task.commandGroup) { this.selectedGroupCommands = task.commandGroup.commands; } } private collectClassrooms(unit: any): any[] { let classrooms = []; if (unit.type === 'classroom') { classrooms.push(unit); } if (unit.children && unit.children.length > 0) { for (let child of unit.children) { classrooms = classrooms.concat(this.collectClassrooms(child)); } } return classrooms; } onOrganizationalUnitChange(): void { const selectedUnitId = this.taskForm.get('organizationalUnit')?.value; const selectedUnit = this.availableOrganizationalUnits.find(unit => unit['@id'] === selectedUnitId); if (selectedUnit) { this.selectedUnitChildren = this.collectClassrooms(selectedUnit); } else { this.selectedUnitChildren = []; } this.taskForm.patchValue({ selectedChild: '', selectedClients: [] }); this.selectedClients = []; this.selectedClientIds.clear(); } onChildChange(): void { const selectedChildId = this.taskForm.get('selectedChild')?.value; if (!selectedChildId) { this.selectedClients = []; return; } const url = `${this.baseUrl}${selectedChildId}`.replace(/([^:]\/)\/+/g, '$1'); this.http.get(url).subscribe( (data) => { if (Array.isArray(data.clients) && data.clients.length > 0) { this.selectedClients = data.clients; } else { this.selectedClients = []; this.toastr.warning('El aula seleccionada no tiene clientes.'); } this.taskForm.patchValue({ selectedClients: [] }); this.selectedClientIds.clear(); }, (error) => { this.toastr.error('Error al cargar los detalles del aula seleccionada'); } ); } toggleSelectAll() { const allSelected = this.areAllSelected(); if (allSelected) { this.selectedClientIds.clear(); } else { this.selectedClients.forEach(client => this.selectedClientIds.add(client.uuid)); } this.taskForm.get('selectedClients')!.setValue(Array.from(this.selectedClientIds)); } areAllSelected(): boolean { return this.selectedClients.length > 0 && this.selectedClients.every(client => this.selectedClientIds.has(client.uuid)); } onCommandGroupChange(): void { const selectedGroupId = this.taskForm.get('commandGroup')?.value; this.http.get(`${this.baseUrl}/command-groups/${selectedGroupId}`).subscribe( (data) => { this.selectedGroupCommands = data.commands; }, (error) => { this.toastr.error('Error al cargar los comandos del grupo seleccionado'); } ); } saveTask(): void { if (this.taskForm.invalid) { this.toastr.error('Por favor, rellene todos los campos obligatorios'); return; } const formData = this.taskForm.value; const dateTime = this.combineDateAndTime(formData.date, formData.time); const selectedCommands = formData.extraCommands && formData.extraCommands.length > 0 ? formData.extraCommands.map((id: any) => `/commands/${id}`) : null; const payload: any = { commandGroups: formData.commandGroup ? [`/command-groups/${formData.commandGroup}`] : null, dateTime: dateTime, notes: formData.notes || '', clients: Array.from(this.selectedClientIds).map((uuid: string) => `/clients/${uuid}`), }; if (selectedCommands) { payload.commands = selectedCommands; } 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: () => { this.toastr.success('Tarea creada con éxito'); this.dialogRef.close(true); }, error: () => { this.toastr.error('Error al crear la tarea'); } }); } } combineDateAndTime(date: string, time: string): string { const dateObj = new Date(date); const [hours, minutes] = time.split(':').map(Number); dateObj.setHours(hours, minutes, 0); return dateObj.toISOString(); } close(): void { this.dialogRef.close(); } }