Descripción general
LivePanel es un módulo JavaScript vanilla que gestiona la visualización en tiempo real del descubrimiento de dispositivos en el modal de Auto-Provision. Muestra:
- Timeline de fases — Ping, ARP, SNMP, HTTP, Enrich con estados y hitos.
- Feed de dispositivos — lista scrollable que se rellena progresivamente.
- Micro-animaciones — latidos, anillos expansivos, entrada de items (con respeto a
prefers-reduced-motion).
Ubicación: static/js/network/auto_provision/live_panel.js
Integración: cableado en discovery.js (métodos discoverSingleDevice() y discoverSubnet()). Se invoca por cada evento de fase/dispositivo del backend o el escaneo local.
API pública
El módulo exporta un objeto LivePanel con 5 métodos:
LivePanel.setPhaseActive(phase)
LivePanel.setPhaseDone(phase, milestone)
LivePanel.setPhaseSkipped(phase, milestone)
LivePanel.addDevice(dev)
LivePanel.reset()
setPhaseActive(phase)
Marca una fase como “activa” (en progreso). Aplica:
data-state="active"al<li class="ap-phase" data-phase="...">.- Animación de latido (pulsación azul con anillo expansivo).
- Color accent en el nombre de la fase.
Parámetro:
phase(string):"ping","arp","snmp","http","enrich".
LivePanel.setPhaseActive('snmp');
// → <li data-phase="snmp" data-state="active">...</li>
setPhaseDone(phase, milestone)
Fija una fase como completada y actualiza su hito (p.ej. “3 hosts alive”).
Parámetros:
phase(string): clave de fase.milestone(string | null): texto que aparece debajo del nombre (p.ej. “3 hosts alive · 4 ms”).
LivePanel.setPhaseDone('ping', '127 hosts alive');
// → <li data-phase="ping" data-state="done">
// <span class="ap-phase__name">Ping</span>
// <span class="ap-phase__milestone">127 hosts alive</span>
// </li>
Efecto visual:
- Check verde (✓) en el nodo.
- Borde + fondo verde.
- Hito fijado en
text-secondary(visible permanentemente).
setPhaseSkipped(phase, milestone)
Marca una fase como omitida (p.ej. HTTP sin respuesta, fase opcional saltada).
Parámetros: igual que setPhaseDone().
LivePanel.setPhaseSkipped('http', 'no web UI detected');
// → <li data-phase="http" data-state="skipped">
// <span class="ap-phase__milestone">no web UI detected</span>
// </li>
Efecto visual:
- Borde punteado (dashed).
- Opacidad reducida (opacity: 0.7).
- Hito en
text-muted(discreto).
addDevice(dev)
Inserta un dispositivo en el feed con micro-animación de entrada.
Parámetro:
dev(object):{ ip: "192.168.1.10", // string, requerido vendor: "Cisco", // string, requerido type: "Switch", // string, optional method: "snmp" // string: 'snmp' | 'ssh' | 'ping' }
Comportamiento:
- Crea un
<div class="ap-device">con la IP (monospace), vendor + tipo, y badge de método. - Lo inserta al inicio del feed (lo más reciente primero, sin obligar scroll).
- Elimina el placeholder vacío si estaba.
- Incrementa el contador
#discovery-found-count. - Aplica animación de entrada (
.34s cubic-bezier(...)).
LivePanel.addDevice({
ip: "10.0.0.5",
vendor: "Ubiquiti",
type: "AP",
method: "ssh"
});
Badge de método:
snmp→ azul claro con borde, texto “SNMP”.ssh→ verde claro, texto “SSH”.ping→ gris neutro, texto “PING”.
El badge no es únicamente color; incluye texto que lo discrimina (accesibilidad).
reset()
Limpia el panel para iniciar un nuevo escaneo.
Acciones:
- Reset
data-statede todas las fases a"pending". - Limpia hitos (
data-milestone). - Vacía el feed y muestra placeholder.
- Reset contador a 0.
- Reset barra de progreso a 0%.
LivePanel.reset();
Estructura del DOM (IDs requeridos)
El módulo asume la siguiente estructura HTML (en #discovery-progress):
<ul id="discovery-phase-list">
<li class="ap-phase" data-phase="ping" data-state="pending">
<span class="ap-phase__node" aria-hidden="true">
<svg><!-- check icon --></svg>
</span>
<span class="ap-phase__body">
<span class="ap-phase__name">Ping</span>
<span class="ap-phase__milestone" data-milestone></span>
</span>
</li>
<!-- ... (arp, snmp, http, enrich) -->
</ul>
<div id="discovery-live-feed" aria-live="polite">
<div class="ap-feed-empty" data-empty>No devices yet…</div>
</div>
<span id="discovery-found-count" aria-live="polite">
<b>0</b> found
</span>
IDs críticos:
#discovery-phase-list— UL de fases.#discovery-live-feed— contenedor scrollable de dispositivos.#discovery-found-count— contador (actualizado poraddDevice()).
Atributos especiales:
data-phaseen<li>— clave de fase (discrimina ensetPhaseActive()etc.).data-state— estado actual (pending|active|done|skipped).data-milestone— span que recibe el hito.aria-live="polite"— anuncio accesible en feed y contador.
Animaciones
Latido de fase activa
@keyframes ap-pulse { /* pulsación caja sombra */ }
@keyframes ap-ring { /* anillo expansivo */ }
Dura 1.6s, infinita. Pausa automática si prefers-reduced-motion: reduce.
Entrada de dispositivo
@keyframes ap-device-in {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
/* duración: .34s cubic-bezier(.2, .7, .3, 1) */
Suave y rápida. Deshabilitada si prefers-reduced-motion: reduce.
Integración con discovery.js
En discovery.js, los métodos discoverSingleDevice() y discoverSubnet() llaman a LivePanel.* en cada fase:
// Ejemplo pseudocódigo:
async function discoverSingleDevice(ip) {
LivePanel.reset();
LivePanel.setPhaseActive('ping');
// ... ping logic ...
LivePanel.setPhaseDone('ping', 'host alive');
LivePanel.setPhaseActive('arp');
// ... arp logic ...
LivePanel.setPhaseDone('arp', 'MAC matched');
// etc.
LivePanel.setPhaseActive('enrich');
// ... enrich logic ...
const discovered = await fetchDevicesFromBackend();
discovered.forEach(dev => LivePanel.addDevice(dev));
LivePanel.setPhaseDone('enrich', `${discovered.length} devices enriched`);
}
Estilos (CSS)
Ubicados en static/css/pages/auto_provision.css. Incluyen:
- Paleta: variables CSS de
--accent,--success,--bg-tertiary, etc. - Grid layout: columna izquierda (fases) + derecha (feed).
- Timeline: línea vertical con nodos (SVG check en
done, animaciones enactive). - Scrollbar customizado: thin, color
--border-color. - Media queries: en pantallas <720px, feed cae debajo de fases.
Todos los colores tienen contraste ≥ 4.5:1 a 12-14px (accesibilidad WCAG AA).
Notas de implementación
- Vanilla JS: sin frameworks, sin dependencias externas.
- No mutación de métodos: cada
set*es idempotente (llamar 2x la misma operación da el mismo resultado). - Accesibilidad:
aria-liveen feed y contador, textos de badge no solo color. - Performance:
.prepend()en feed evita repintado de toda la lista (inserta al inicio). - Mock funcional:
_design/autoprovision-live-panel.htmles autónomo (716 líneas), incluye lógica DEMO que permite simular el escaneo sin backend.
Véase también
- [[feature—network—autoprovision-ux-panel-assign-s115]]
- [[entity—network—endpoint—assign-types]]
- [[concept—ux—animations-and-transitions]]
- [[concept—ux—accessibility]]