246 lines
7.6 KiB
TypeScript
246 lines
7.6 KiB
TypeScript
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';
|
|
import { ConfigService } from '@services/config.service';
|
|
|
|
@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[] = [];
|
|
selectedUnitChildren: any[] = [];
|
|
selectedClients: any[] = [];
|
|
selectedClientIds: Set<string> = new Set();
|
|
|
|
constructor(
|
|
private fb: FormBuilder,
|
|
private http: HttpClient,
|
|
private configService: ConfigService,
|
|
private toastr: ToastrService,
|
|
public dialogRef: MatDialogRef<CreateTaskComponent>,
|
|
@Inject(MAT_DIALOG_DATA) public data: any
|
|
) {
|
|
this.baseUrl = this.configService.apiUrl;
|
|
this.apiUrl = `${this.baseUrl}/command-tasks`;
|
|
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<any>(`${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<any>(`${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<any>(`${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<any>(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<any>(`${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<any>(`${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<any>(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();
|
|
}
|
|
}
|