fix(plugins): sincronizacion reciproca de tiempo restante y auto-conexion mercure (v1.24.3)
oggui-debian-package/pipeline/head This commit looks good Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit Details
oggui-debian-package/pipeline/tag This commit looks good Details

main
Juan Manuel Bardallo 2026-10-30 15:09:57 +01:00
parent 8a82c37d48
commit 4788e1f7bc
4 changed files with 35 additions and 4 deletions

View File

@ -1,5 +1,14 @@
# Changelog
## [1.24.3] - 2026-10-30
### Fixed
- **Sincronización Recíproca de Metadatos y Auto-Conexión Mercure (`PluginService`, `GroupsComponent`)**:
- Solucionado el fallo de actualización del tiempo restante en vivo: `meta.remaining_minutes` (snake_case fijado en la carga inicial HTTP) bloqueaba la lectura de las actualizaciones reactivas de Mercure emitidas en camelCase (`remainingMinutes`).
- `setPluginMetadata` normaliza y actualiza recíprocamente ambas claves (`remainingMinutes` y `remaining_minutes`) en cada evento recibido.
- Auto-conexión garantizada de Mercure en `PluginService`: si la URL de Mercure se resuelve de forma asíncrona tras la carga de la configuración, se conecta de manera transparente al solicitar estados o badges.
- Implementado sondeo de seguridad en segundo plano cada 30 segundos en `GroupsComponent` para mantener siempre sincronizados los minutos y badges de plugins ante micro-cortes o reconexiones de SSE.
## [1.24.2] - 2026-10-30
### Fixed

View File

@ -1,6 +1,6 @@
{
"name": "og-webconsole",
"version": "1.24.2",
"version": "1.24.3",
"scripts": {
"ng": "ng",
"start": "ng serve",

View File

@ -9,7 +9,7 @@ import { ToastrService } from 'ngx-toastr';
import { JoyrideService } from 'ngx-joyride';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
import { Subscription } from 'rxjs';
import { Subscription, interval } from 'rxjs';
import { DataService } from './services/data.service';
import { UnidadOrganizativa, Client, TreeNode, FlatNode, Command } from './model/model';
import { ManageOrganizationalUnitComponent } from './shared/organizational-units/manage-organizational-unit/manage-organizational-unit.component';
@ -274,9 +274,17 @@ export class GroupsComponent implements OnInit, OnDestroy {
this.subscriptions.add(
this.pluginService.statusUpdates$.subscribe(() => {
this.cd.markForCheck();
this.cd.detectChanges();
})
);
// Sincronización periódica de seguridad cada 30s para refrescar tiempo restante y estado de plugins
this.subscriptions.add(
interval(30000).subscribe(() => {
this.pluginService.loadActivePluginsStatus().subscribe();
})
);
}
private updateClientStatus(clientUuid: string, status: string): void {

View File

@ -168,7 +168,17 @@ export class PluginService {
public setPluginMetadata(pluginName: string, idOrUuid: string | number, metadata: any): void {
const key = this.getStatusKey(pluginName, idOrUuid);
const existing = this.clientPluginMetadataMap.get(key) || {};
this.clientPluginMetadataMap.set(key, { ...existing, ...metadata });
const updated = { ...existing, ...metadata };
// Sincronizar recíprocamente remainingMinutes y remaining_minutes para evitar discrepancias snake/camelCase
const remMins = metadata.remainingMinutes !== undefined ? metadata.remainingMinutes
: (metadata.remaining_minutes !== undefined ? metadata.remaining_minutes : undefined);
if (remMins !== undefined) {
updated.remaining_minutes = remMins;
updated.remainingMinutes = remMins;
}
this.clientPluginMetadataMap.set(key, updated);
}
public getPluginMetadata(pluginName: string, idOrUuid: string | number): any {
@ -369,6 +379,7 @@ export class PluginService {
}
loadActivePluginsStatus(): Observable<void> {
this.initMercureSubscription();
const apiUrl = this.configService.apiUrl;
if (!apiUrl || this.activePlugins.length === 0) {
return of(undefined);
@ -660,6 +671,9 @@ export class PluginService {
}
getClientBadges(client: any): PluginBadge[] {
if (!this.mercureEventSource) {
this.initMercureSubscription();
}
const badges: PluginBadge[] = [];
if (!client || this.activePlugins.length === 0) return badges;
@ -718,7 +732,7 @@ export class PluginService {
if (meta) {
const dni = meta.dni || meta.user || meta.student;
const mins = meta.remaining_minutes !== undefined ? meta.remaining_minutes : meta.remainingMinutes;
const mins = meta.remainingMinutes !== undefined ? meta.remainingMinutes : meta.remaining_minutes;
const infoParts: string[] = [];
if (dni) {
infoParts.push(`DNI: ${dni}`);