Volver a la wiki

Servicio Frontend: LivePanel (descubrimiento en vivo)

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:

  1. Timeline de fases — Ping, ARP, SNMP, HTTP, Enrich con estados y hitos.
  2. Feed de dispositivos — lista scrollable que se rellena progresivamente.
  3. 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:

Parámetro:

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:

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:

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:

addDevice(dev)

Inserta un dispositivo en el feed con micro-animación de entrada.

Parámetro:

Comportamiento:

LivePanel.addDevice({
  ip: "10.0.0.5",
  vendor: "Ubiquiti",
  type: "AP",
  method: "ssh"
});

Badge de método:

El badge no es únicamente color; incluye texto que lo discrimina (accesibilidad).

reset()

Limpia el panel para iniciar un nuevo escaneo.

Acciones:

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:

Atributos especiales:

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:

Todos los colores tienen contraste ≥ 4.5:1 a 12-14px (accesibilidad WCAG AA).

Notas de implementación

Véase también

Subir