From 281357e670c0044d20e7fb97c103d410eab69001 Mon Sep 17 00:00:00 2001 From: nicolasarana <90768149+nicolasarana@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:49:48 -0300 Subject: [PATCH] MPI - Mejorar performance de auditoria de pacientes --- .../component/auditoria-listado.component.ts | 2 +- .../component/auditoria-listado.html | 10 +- .../component/reporte-errores.component.ts | 103 ++++++++++++++---- .../auditoria/component/reporte-errores.html | 16 +-- .../auditoria/component/reporte-errores.scss | 38 +++++++ 5 files changed, 131 insertions(+), 38 deletions(-) create mode 100644 src/app/modules/auditoria/component/reporte-errores.scss diff --git a/src/app/modules/auditoria/component/auditoria-listado.component.ts b/src/app/modules/auditoria/component/auditoria-listado.component.ts index 6a709d1812..b40a5ba0bd 100644 --- a/src/app/modules/auditoria/component/auditoria-listado.component.ts +++ b/src/app/modules/auditoria/component/auditoria-listado.component.ts @@ -16,7 +16,7 @@ export class ListadoAuditoriaComponent { // Indica si se esta listando desde la seccion de reporte de errores, ya que tiene atributos de interés distintos @Input() errorTab = false; // Reportes de errores traidos de LogPaciente, ordenados por id de paciente - @Input() registroReportes = []; + @Input() registroReportes: any; // Evento que se emite al seleccionar un paciente de la lista @Output() selected: EventEmitter = new EventEmitter(); diff --git a/src/app/modules/auditoria/component/auditoria-listado.html b/src/app/modules/auditoria/component/auditoria-listado.html index 4e709c7f35..cfe2f556e3 100644 --- a/src/app/modules/auditoria/component/auditoria-listado.html +++ b/src/app/modules/auditoria/component/auditoria-listado.html @@ -1,4 +1,4 @@ - + Paciente Edad @@ -41,16 +41,16 @@ - + Corregido - + {{ registroReportes[paciente.id][0]?.createdAt | fecha:'utc'}} diff --git a/src/app/modules/auditoria/component/reporte-errores.component.ts b/src/app/modules/auditoria/component/reporte-errores.component.ts index c5bda41290..6efac7c5b3 100644 --- a/src/app/modules/auditoria/component/reporte-errores.component.ts +++ b/src/app/modules/auditoria/component/reporte-errores.component.ts @@ -1,7 +1,6 @@ import { Auth } from '@andes/auth'; import { Plex } from '@andes/plex'; import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'; -import { forkJoin } from 'rxjs'; import { IPaciente } from 'src/app/core/mpi/interfaces/IPaciente'; import { PacienteService } from 'src/app/core/mpi/services/paciente.service'; import { LogPacienteService } from 'src/app/services/logPaciente.service'; @@ -9,7 +8,8 @@ import { ModalCorreccionPacienteComponent } from './modal-correccion-paciente.co @Component({ selector: 'reporte-errores', - templateUrl: 'reporte-errores.html' + templateUrl: 'reporte-errores.html', + styleUrls: ['reporte-errores.scss'] }) export class ReporteErroresComponent implements OnInit { @@ -21,13 +21,19 @@ export class ReporteErroresComponent implements OnInit { filtroPaciente: string; pacientesReportados = []; corregirPaciente: Number; - showReporteError = false; // se muestra en el sidebar datos del error reportado + showReporteError = false; permisoEdicion: Boolean; permisoVincular: Boolean; pacienteSelected: IPaciente; - reportes = []; + reportes = {}; pacientes = []; + // paginación infinite scroll + loading = false; + scrollEnd = false; + skip = 0; + readonly limit = 20; + constructor( public auth: Auth, private plex: Plex, @@ -37,23 +43,77 @@ export class ReporteErroresComponent implements OnInit { ngOnInit() { this.permisoEdicion = this.auth.check('auditoriaPacientes:edicion'); this.permisoVincular = this.auth.check('auditoriaPacientes:vincular'); + this.cargar(); + } - forkJoin([ - this.pacienteService.get({ reportarError: true, activo: true }), // pacientes - this.logPacienteService.get({ operacion: 'error:reportar' }) // registros de errores reportados - ]).subscribe(respuesta => { - if (respuesta?.length) { - this.pacientesReportados = respuesta[0]; - this.corregirPaciente = null; - const erroresReportados = respuesta[1]; - this.pacientesReportados.forEach(pac => { - this.reportes[pac.id] = erroresReportados.filter((reg: any) => reg.paciente.id === pac.id); - }); + /** + * Carga una página de pacientes con errores reportados y sus logs asociados. + * @param reset si es true reinicia la lista (nueva búsqueda), si es false concatena (scroll) + */ + cargar(reset = true) { + if (this.loading || (this.scrollEnd && !reset)) { return; } + + if (reset) { + this.pacientesReportados = []; + this.pacientes = []; + this.reportes = {}; + this.skip = 0; + this.scrollEnd = false; + } + + this.loading = true; + const params: any = { + reportarError: true, + activo: true, + skip: this.skip, + limit: this.limit + }; + if (this.filtroPaciente) { + params.search = this.filtroPaciente; + } + + this.pacienteService.get(params).subscribe((pacientesBatch: any[]) => { + if (!pacientesBatch || !pacientesBatch.length) { + this.scrollEnd = true; + this.loading = false; + return; } - this.pacientes = this.pacientesReportados; + + // Si vienen menos registros que el límite, ya llegamos al final + if (pacientesBatch.length < this.limit) { + this.scrollEnd = true; + } + + const ids = pacientesBatch.map(p => p.id).join(','); + + // Pedimos los logs sólo de los pacientes de esta página + this.logPacienteService.get({ ids, operacion: 'error:reportar' }).subscribe((logs: any[]) => { + pacientesBatch.forEach(pac => { + this.reportes[pac.id] = (logs || []).filter((reg: any) => reg.paciente?.id === pac.id); + }); + + this.pacientesReportados = this.pacientesReportados.concat(pacientesBatch); + this.skip = this.pacientesReportados.length; + this.pacientes = this.pacientesReportados; + this.loading = false; + }, () => { + // Si falla la carga de logs igual mostramos los pacientes + this.pacientesReportados = this.pacientesReportados.concat(pacientesBatch); + this.skip = this.pacientesReportados.length; + this.pacientes = this.pacientesReportados; + this.loading = false; + }); + }, () => { + this.loading = false; }); } + onScroll() { + if (!this.scrollEnd) { + this.cargar(false); + } + } + onSelect(paciente: IPaciente) { if (paciente) { this.pacienteSelected = paciente; @@ -71,14 +131,7 @@ export class ReporteErroresComponent implements OnInit { } filtrarPaciente() { - const resultados = this.pacientesReportados.filter((paciente: IPaciente) => { - const data = (paciente.nombre + paciente.apellido + paciente.documento).toLowerCase(); - const filtros = (this.filtroPaciente || '').toLowerCase().split(' '); - - return filtros.every(item => data.includes(item)); - }); - - this.pacientes = this.filtroPaciente && this.filtroPaciente.length ? resultados : this.pacientesReportados; + this.cargar(true); } savePatient(paciente: IPaciente) { @@ -98,6 +151,8 @@ export class ReporteErroresComponent implements OnInit { } else { this.pacienteSelected = respSave; this.plex.toast('success', 'Los datos se actualizaron correctamente!'); + // recargamos la lista para reflejar el cambio + this.cargar(); } } else { diff --git a/src/app/modules/auditoria/component/reporte-errores.html b/src/app/modules/auditoria/component/reporte-errores.html index 8aa55c1aa5..df9d3cdd9d 100644 --- a/src/app/modules/auditoria/component/reporte-errores.html +++ b/src/app/modules/auditoria/component/reporte-errores.html @@ -1,15 +1,15 @@ - - - + -
+
+ (selected)="onSelect($event)" (scrolled)="onScroll()"> -
-
+
+ +
+
+
No se encontraron pacientes con datos reportados.
diff --git a/src/app/modules/auditoria/component/reporte-errores.scss b/src/app/modules/auditoria/component/reporte-errores.scss new file mode 100644 index 0000000000..eb363b1199 --- /dev/null +++ b/src/app/modules/auditoria/component/reporte-errores.scss @@ -0,0 +1,38 @@ +:host { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; +} + +.flex-grow-1 { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + overflow: hidden; + position: relative; +} + +auditoria-listado { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + overflow: hidden; + + ::ng-deep { + plex-list { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; + } + + .striped.md.size-lg { + flex: 1; + min-height: 0; + overflow-y: auto !important; + } + } +} \ No newline at end of file