Deuda #274 Tanda B — puerto sin recarga, deep discovery deduplicado y un solo cargador de series en Wireless (v1.86.17)
Resumen
Segunda entrega del bloque B1 de la deuda técnica #274 (la lista abierta al cerrar la auditoría profunda del monitoraje, task #261): tres refactors medianos, los tres en JavaScript de monitorización, que sacan a un módulo compartido código que vivía copiado en varios sitios a la vez. A diferencia de [[feature—monitoring—deuda-274-tanda-a]] (backend: alertas, WebSocket, dedupe SNMP), esta tanda es casi toda limpieza de frontend — de los tres puntos, solo uno cambia lo que ve el usuario.
Qué corrige cada arreglo
- #21 — Asignar o quitar un puerto ya no recarga la página. Los 5 llamadores de
PortAssignModalhacíanwindow.location.reload()en el callback para repintar un simple badge: se perdían las pestañas abiertas, el scroll y las gráficas en vivo. AhoraPortAssignModal._assign()entrega al callback elport_connectionque devuelve el POST (_unassign()entreganull), y el nuevo módulostatic/js/utils/portCell.jsconcentra el repintado: la celda “Port” de la tabla de miembros (marcado idéntico en los 3GroupDetailde Wireless/UPS/Cartelería) y el badge del item de la barra lateral. El binding del botón “Assign” pasa a delegado en el contenedor — la celda se repinta sola, así que un listener por botón dejaría muerto el repintado de una celda nueva. - #19 — Deep Discovery: la sonda de OIDs deja de estar duplicada en los dos modales.
deep_discovery_vendor.js(494 líneas) ydeep_discovery_profile.js(430) llevaban cada uno su copia de la petición al Agente, el pintado de filas, el banner de estadísticas, la tabla de OIDs, el desplegable de categoría y la subida de MIBs. Salen aoid_probe.jsyoid_selector.js(nuevos); los ficheros originales quedan en 359 y 306 líneas. Al unificar aparecieron 3 divergencias, resueltas explícitamente: el truncado del valor sondeado (50 en Vendor vs 60 en la ficha del dispositivo, se queda en 60); un arreglo real de traducción — el banner de la ficha usaba el msgid(%(pct)s%%), y elinterpolatedel i18n de Django no desescapa%%como sí hace elformatde Python, así que el usuario veía literalmente “85.0%%” en inglés y en español; se adopta el msgid del Vendor (un solo%, ya traducido); y quién resuelve elprofile_id(el Vendor por API, la ficha desde memoria — se deja que lo pase el llamador, los dos son correctos en su contexto). - #20 — Las gráficas de Wireless cargan sus series por un solo camino.
WirelessChartPanel._loadData/._loadGroupDatayloadExpertData/loadExpertGroupDataeran cuatro copias de la misma lógica sobre los mismos tres endpoints. El nuevopages/wireless/WirelessSeriesLoader.jslas sustituye, parametrizado por un constructor de series (makeSeries) — lo único que de verdad cambiaba entre el panel y la gráfica Expert. Efecto colateral bueno: el reparto de la llamada a/vm/extras(fix A40 de [[feature—monitoring—auditoria-261-ciclo-4-cableado-observatory]], que evita N peticiones idénticas al refrescar el grid) vivía solo en el panel; ahora lo aprovechan también las gráficas Expert. YhexToRgba, copiada palabra por palabra en cinco módulos de gráficas (Monitoring, Signage, UPS, Wireless panel y Expert), pasa astatic/js/utils/color.js;ExpertChartHelpersla reexporta para no romper a quien la importaba de ahí.
Implementación
static/js/utils/portCell.js(nuevo) —portCellHtml/repaintPortCell(celda de tabla) yupdateSidebarPortBadge.static/js/services/PortAssignModal.js— ya no llama alocation.reload; entrega elport_connection(onull) al callback.static/js/pages/{monitoring,wireless,ups,signage}/*GroupDetail.jsypages/{wireless,ups,signage}.js— consumenportCell.jsen vez de recargar.static/js/network/auto_provision/oid_probe.js+oid_selector.js(nuevos) — sonda de OIDs, pintado de filas, banner de estadísticas y subida de MIBs, compartidos pordeep_discovery_vendor.jsydeep_discovery_profile.js.static/js/pages/wireless/WirelessSeriesLoader.js(nuevo) — cargador único de series paraWirelessChartPanel.jsyWirelessExpertChart.js/ExpertChartHelpers.js.static/js/utils/color.js(nuevo) —hexToRgba, reexportada desdeExpertChartHelpers.js.config/settings/base.py—APP_VERSIONa1.86.17.
Tests
3 tests de contrato nuevos en frontend/src/__tests__/static/: port_assign_no_reload.test.js (ningún callback de PortAssignModal.show puede volver a llamar a location.reload), oid_probe_shared.test.js (solo el módulo compartido habla con el endpoint del Agente, ningún msgid lleva %%, el truncado es único) y wireless_series_loader.test.js (hexToRgba se define una sola vez en todo static/js). El commit incluye además un fix de CI aparte: frontend/biome.json desactiva useLiteralKeys (chocaba con noPropertyAccessFromIndexSignature del tsconfig, dejaba el job Frontend en rojo desde v1.86.16).
Límite honesto
Sin cambio de comportamiento visible salvo el %% del banner de la sonda (arreglo real) y 1px de relleno en la tabla de OIDs (5px → 6px, escala de espaciado). JS y CSS no pasan por el CI de este proyecto: los tres puntos se cierran con click-test manual en el navegador tras el deploy, no con verificación automática end-to-end.
Commits relacionados
8af8b974(2026-08-29) — refactor(monitoring): deuda #274 B1, PR #466, v1.86.17.
Véase también
- [[feature—monitoring—deuda-274-tanda-a]]
- [[feature—wireless—deep-discovery-timestamp]]
- [[crearack-tech—architecture—wireless-monitor]]
- [[feature—network—discovery-audit-sa1]]
- [[feature—monitoring—auditoria-261-ciclo-4-cableado-observatory]]