Servicio agent_onboarding — Onboarding guiado de descarga del Local Agent
Descripción
Módulo JavaScript (static/js/modules/agent_onboarding.js, 114 LOC) que proporciona una interfaz de usuario guiada para descargar el CreaRack Local Agent cuando no está instalado en la máquina del usuario.
Se carga en base.html con atributo defer, tras agent_lna_notice.js y antes de auth.js.
API pública
El módulo expone un objeto global window.CreaRackAgentOnboarding con los siguientes métodos:
offer(context)
Parámetros:
context(string, opcional): tipo de flujo que necesita el Agent. Valores típicos:'discovery','manual'. Si no se proporciona, por defecto'manual'.
Comportamiento:
- Si ya hay un banner de instalación en pantalla, no crea uno nuevo.
- Si el aviso de permiso (
#lna-noticedeagent_lna_notice.js) está activo, lo remueve (el caso “no hay Agent” tiene prioridad). - Muestra un banner flotante con intro dinámico según
context:'discovery': “Network discovery needs the CreaRack Local Agent, and it is not running on this computer.”- Otros: “To scan and manage your network devices, CreaRack needs the Local Agent installed on this computer.”
- Introduce el banner con animación suave (inherita
lnaOutfade-out).
downloadAgent()
Parámetros: ninguno.
Comportamiento:
- Crea un
<a>temporal conhrefawindow.AGENT_DOWNLOAD_URL(default:/downloads/CreaRackAgent.exe). - Establece
downloadpara forzar descarga (no navegación). - Simula click y lo remueve del DOM.
- Nota: El navegador no puede ejecutar el
.exe; el usuario debe hacer doble click en el archivo descargado.
agentRunning()
Parámetros: ninguno.
Retorna: Promise<boolean> — true si el Agent responde a GET /info con 200 en <1.5s, false en caso contrario.
Implementación:
async function agentRunning() {
try {
const ctrl = new AbortController();
const to = setTimeout(() => ctrl.abort(), 1500);
const r = await fetch(`${AGENT_URL}/info`, {
signal: ctrl.signal,
mode: 'cors'
});
clearTimeout(to);
return r.ok;
} catch {
return false;
}
}
Comportamiento detallado
Flujo principal: offer() → banner → polling
-
Validar que no hay banner existente: Si
#agent-install-noticeya existe, salir. -
Priorizar Agent no instalado: Si
#lna-notice(permiso) está visible, removerlo. -
Crear y renderizar banner:
- ID:
agent-install-notice - Clase:
lna-notice agent-install-notice(reutiliza estilos de aviso). - HTML:
<div class="lna-notice-body"> <strong class="lna-notice-title">Install the Local Agent</strong> <p>[intro dinámico] Download it and run the installer...</p> </div> <div class="agent-install-actions"> <button id="agent-install-download" class="btn btn-action btn-sm"> Download Local Agent </button> <button id="agent-install-dismiss" class="btn btn-neutral btn-sm"> Not now </button> </div> - Role:
status(para lectura de pantalla). - Se añade al final del
<body>.
- ID:
-
Event listeners:
- Download:
- Llama a
downloadAgent(). - Cambia el texto del párrafo a “Downloading… run the installer when it finishes. This will close once the Agent connects.”
- Deshabilita el botón Download (
disabled = true). - Inicia polling con
startConnectPolling(el).
- Llama a
- Not now: Llama a
removeNotice(el)para cerrar el banner.
- Download:
startConnectPolling(el)
- Inicia un intervalo que cada 2.5s llama a
agentRunning(). - Al detectar
true(Agent conectó):- Limpia el intervalo.
- Llama a
removeNotice(el)para cerrar el banner con fade-out. - Si
window.showToastexiste, muestra un toast verde:"Local Agent connected".
removeNotice(el)
- Aplica animación CSS:
el.style.animation = 'lnaOut 0.25s ease-out forwards'. - Después de 250ms, remueve el elemento del DOM.
- La clase
lnaOutdebe estar definida en CSS (inherita deagent_lna_notice.js).
Configuración
Variables globales esperadas
window.AGENT_URL(string, optional): URL base del Agent local. Default:'http://127.0.0.1:5050'.window.AGENT_DOWNLOAD_URL(string, optional): URL del instalador.exe. Default:'/downloads/CreaRackAgent.exe'.
Funciones globales esperadas
window.showToast(message, type)(function, optional): Función para mostrar notificaciones. Si no existe, el toast de éxito no se muestra (no es error).t(message)(function, required): Función de traducción i18n (asumida global en CreaRack).
Integración en flujos existentes
discovery.js (~línea 255)
catch (e) {
// En vez de un error seco: ofrecer la descarga guiada del Agente (tarea #182).
if (window.CreaRackAgentOnboarding) window.CreaRackAgentOnboarding.offer('discovery');
throw new Error(t('Local Agent not available. Please start CreaRackAgent.exe'));
}
agent_probe.js (~línea 27)
catch (e) {
// En vez de un error seco: ofrecer la descarga guiada del Agente (tarea #182).
if (window.CreaRackAgentOnboarding) window.CreaRackAgentOnboarding.offer('discovery');
throw new Error(t('Local Agent not available. Please start CreaRackAgent.exe'));
}
Ambos flujos llaman a offer('discovery') si window.CreaRackAgentOnboarding existe (defensive programming).
Estilos CSS asociados
components.css (~línea 1010)
/* Banner "Install the Local Agent" (agent_onboarding.js, tarea #182):
fila de acciones horizontal en vez de botones apilados. */
.agent-install-actions {
display: flex;
gap: 10px;
justify-content: center;
}
.agent-install-notice .agent-install-actions .btn {
align-self: auto;
min-width: 130px;
}
Clases reutilizadas:
.lna-notice— estilos del aviso flotante (color, padding, etc.), definido enagent_lna_notice.js..lna-notice-body,.lna-notice-title— estructura heredada del aviso de permiso..btn,.btn-action,.btn-neutral,.btn-sm— sistema de botones existente en CreaRack.
IIFE y scope
El módulo es una IIFE (Immediately Invoked Function Expression) para encapsular variables locales y evitar contaminación del scope global:
(function () {
'use strict';
const AGENT_URL = window.AGENT_URL || 'http://127.0.0.1:5050';
let pollTimer = null;
// Funciones privadas...
window.CreaRackAgentOnboarding = { ... }; // Única exposición global
})();
Variables privadas:
AGENT_URL— URL del Agent (lectura de config global o default).pollTimer— ID del intervalo de polling (evita múltiples polls concurrentes).
Modelo “just-in-time”
No hay auto-disparo al cargar la app. Razones:
- Hay usuarios sin Agent local: El Sentinel 24/7 (Agent Primary) entrega monitorización central. Usuarios que solo leen datos del Sentinel no necesitan Agent local.
- Contexto importa: El banner solo se muestra cuando el usuario intenta una acción que necesita el Agent (e.g., auto-discovery de red).
- Menos ruido: Evita avisos intrusivos si el usuario no planea usar discovery.
Deuda técnica
- Traducción ES: Los strings nuevos usan
t()para i18n, pero la traducción al español sigue en ciclo F4 (futuro). - Ejecución del .exe: El navegador no puede ejecutar el instalador (seguridad). El usuario debe hacer doble click en el archivo descargado una vez finalizada la descarga.
Véase también
- [[feature—network—agent-onboarding-descarga-guiada]]
- [[feature—core—aviso-lna]]
- [[concept—terminal—local-agent]]
- [[concept—general—como-detecta-el-frontend-si-el-local-agent-esta-co]]
- [[entity—static—service—agent-lna-notice]]