import { inject } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Component, Input, OnInit, OnChanges } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ClientViewComponent } from "../client-view/client-view.component"; import { CdkDragMove } from '@angular/cdk/drag-drop'; import { HttpClient } from '@angular/common/http'; import { ToastrService } from 'ngx-toastr'; import { ConfigService } from '@services/config.service'; interface GroupedClients { organizationalUnitName: string; clientRows: any[][]; } @Component({ selector: 'app-classroom-view', templateUrl: './classroom-view.component.html', styleUrls: ['./classroom-view.component.css'] }) export class ClassroomViewComponent implements OnInit, OnChanges { public translate = inject(TranslateService); baseUrl: string; @Input() clients: any[] = []; @Input() pcInTable: number = 5; groupedClients: GroupedClients[] = []; syncingUds = false; constructor(public dialog: MatDialog, private http: HttpClient, private toastService: ToastrService, private configService: ConfigService) { this.baseUrl = this.configService.apiUrl; } ngOnInit(): void { this.groupClientsByOrganizationalUnit(); this.initializeClientPositions(); } ngOnChanges(): void { this.groupClientsByOrganizationalUnit(); this.initializeClientPositions(); } groupClientsByOrganizationalUnit(): void { const grouped = this.clients.reduce((acc, client) => { const ouName = 'text'; if (!acc[ouName]) { acc[ouName] = []; } acc[ouName].push(client); return acc; }, {}); this.groupedClients = Object.keys(grouped).map(ouName => ({ organizationalUnitName: ouName, clientRows: this.chunkArray(grouped[ouName], this.pcInTable) })); } initializeClientPositions(): void { this.groupedClients.forEach(group => { group.clientRows.forEach(row => { row.forEach(client => { const position = client.position || { x: 0, y: 0 }; client.dragPosition = { x: position.x, y: position.y }; }); }); }); } chunkArray(arr: any[], chunkSize: number): any[][] { const chunks = []; for (let i = 0; i < arr.length; i += chunkSize) { chunks.push(arr.slice(i, i + chunkSize)); } return chunks; } handleClientClick(client: any): void { this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height: '700px' }); } onDragMoved(event: CdkDragMove, client: any): void { const dragPosition = event.source.getFreeDragPosition() client.position.x = dragPosition.x; client.position.y = dragPosition.y; } saveDisposition(): void { this.groupedClients.forEach(group => { group.clientRows.forEach(row => { row.forEach(client => { const url = `${this.baseUrl}/clients/${client.uuid}`; const payload = { name: client.name, position: client.position }; this.http.patch(url, payload).subscribe(response => { this.openSnackBar(false, 'Plano actualizado!'); }, error => { console.error(this.translate.instant('errorUpdatingClient1'), error); this.openSnackBar(true, error); }); }); }); }); } openSnackBar(isError: boolean, message: string) { if (isError) { this.toastService.error(this.translate.instant('errorUpdatingClient') + message, 'Error'); } else this.toastService.success(this.translate.instant('updatedClient'), 'Éxito'); } get calendarUuid(): string | null { const client = this.clients.find(c => c.organizationalUnit?.remoteCalendar?.uuid); return client?.organizationalUnit?.remoteCalendar?.uuid || null; } syncUds(): void { const uuid = this.calendarUuid; if (!uuid) { this.toastService.warning('Este aula no tiene un calendario remoto asociado'); return; } this.syncingUds = true; this.http.post(`${this.baseUrl}/remote-calendars/${uuid}/sync-uds`, {}).subscribe({ next: () => { this.toastService.success(this.translate.instant('calendarsSynchronizedCorrectly')); this.syncingUds = false; }, error: (error: any) => { this.toastService.error(error.error?.['hydra:description'] || 'Error al sincronizar con UDS'); this.syncingUds = false; } }); } isRemotePcActive(client: any): boolean { return !!client.isRemotePcActive; } }