Code

// 1. Importar tags de VanJS
const { div, input, button, ul, li, span, p } = van.tags;

// 2. Extraer el ID por defecto si entityData está presente en el contexto
const defaultDeviceId = entityData?.['provision.administration.identifier']?._value?._current?.value || "";

// 3. Estados reactivos de VanJS
const statusText = van.state(defaultDeviceId ? "Cargando datos..." : "Introduce un ID de dispositivo y pulsa Consultar");
const fieldsList = van.state([]);
const loadedEntity = van.state(null); // Guardará la entidad en modo flattened
const currentDeviceId = van.state(defaultDeviceId);

// 4. Estilos en línea
const styles = {
  container: "padding: 14px; font-family: system-ui, -apple-system, sans-serif; color: #1e293b; height: 100%; box-sizing: border-box; overflow-y: auto;",
  searchBox: "display: flex; gap: 8px; margin-bottom: 12px;",
  input: "flex: 1; padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 0.875rem; outline: none;",
  primaryBtn: "padding: 8px 16px; background-color: #2563eb; color: white; border: none; border-radius: 6px; font-size: 0.875rem; font-weight: 500; cursor: pointer;",
  actionsBox: "display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap;",
  actionBtn: "padding: 6px 12px; background-color: #0f766e; color: white; border: none; border-radius: 6px; font-size: 0.8125rem; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 6px;",
  secondaryActionBtn: "padding: 6px 12px; background-color: #475569; color: white; border: none; border-radius: 6px; font-size: 0.8125rem; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 6px;",
  list: "list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px;",
  item: "display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; background: #f8fafc; border-radius: 6px; border: 1px solid #e2e8f0; font-size: 0.875rem;",
  key: "color: #64748b; font-weight: 500;",
  value: "font-weight: 600; color: #0f172a; word-break: break-all;",
  status: "color: #64748b; font-size: 0.875rem; text-align: center; padding: 16px 0; margin: 0;"
};

// 5. Función asíncrona para consultar el dispositivo usando $api
async function searchDevice(id) {
  const targetId = (id || "").trim();

  if (!targetId) {
    statusText.val = "⚠️ Por favor, introduce un identificador de dispositivo válido.";
    fieldsList.val = [];
    loadedEntity.val = null;
    return;
  }

  statusText.val = `Buscando dispositivo "${targetId}"...`;
  fieldsList.val = [];
  loadedEntity.val = null;
  currentDeviceId.val = targetId;

  try {
    // Consulta en modo .flattened()
    const response = await $api.entitiesSearchBuilder()
      .filter({
        eq: {
          'provision.administration.identifier': targetId
        }
      })
      .flattened()
      .limit(1)
      .build()
      .execute();

    const entity = response?.data?.entities?.[0];

    if (!entity) {
      statusText.val = `❌ No se encontró ningún dispositivo con ID: "${targetId}"`;
      return;
    }

    // Guardar la entidad en modo flattened en el estado
    loadedEntity.val = entity;
    statusText.val = "";

    // Mapeo de campos simples a mostrar
    fieldsList.val = [
      { label: "Identificador", value: entity['provision.administration.identifier']?._value?._current?.value || targetId },
      { label: "Organización", value: entity['provision.administration.organization']?._value?._current?.value || "N/A" },
      { label: "Canal", value: entity['provision.administration.channel']?._value?._current?.value || "N/A" },
      { label: "Grupo de Servicio", value: entity['provision.administration.serviceGroup']?._value?._current?.value || "N/A" },
      { label: "Tipo Específico", value: entity['provision.device.specificType']?._value?._current?.value || "N/A" },
      { label: "Número de Serie", value: entity['provision.device.serialNumber']?._value?._current?.value || "N/A" },
      { label: "Estado Operacional", value: entity['device.operationalStatus']?._value?._current?.value || "N/A" }
    ];

  } catch (error) {
    console.error("Error al consultar el dispositivo:", error);
    statusText.val = `❌ Error en la consulta: ${error.message || error}`;
  }
}

// 6. Funciones para ejecutar las acciones sobre el dispositivo cargado
function handleOpenDeviceDetails() {
  if (!currentDeviceId.val) {
    return;
  }
  // Abrir widget deviceInfoDetails con el identificador del dispositivo
  openWidget('deviceInfoDetails', currentDeviceId.val, `Detalles: ${currentDeviceId.val}`);
}

function handleOpenEntitiesWizard() {
  if (!loadedEntity.val) {
    return;
  }
  // Abrir wizard entities pasando el objeto de la entidad en modo flattened
  openWizard('entities', loadedEntity.val, true);
}

// 7. Input de texto pre-rellenado
const textInput = input({
  type: "text",
  placeholder: "Identificador del dispositivo...",
  value: defaultDeviceId,
  style: styles.input,
  onkeydown: (e) => {
    if (e.key === "Enter") {
      searchDevice(textInput.value);
    }
  }
});

// 8. Búsqueda automática inicial si entityData contenía un ID
if (defaultDeviceId) {
  searchDevice(defaultDeviceId);
}

// 9. Retorno del componente reactivo VanJS
return div({ style: styles.container },
  // Barra de búsqueda
  div({ style: styles.searchBox },
    textInput,
    button({
      style: styles.primaryBtn,
      onclick: () => {
        searchDevice(textInput.value);
      }
    }, "Consultar")
  ),

  // Contenido reactivo: Estado o Botones de Acción + Listado
  () => {
    if (statusText.val) {
      return p({ style: styles.status }, statusText.val);
    }

    return div(
      // Barra de acciones disponibles para el dispositivo cargado
      div({ style: styles.actionsBox },
        button({
          style: styles.actionBtn,
          onclick: () => {
            handleOpenDeviceDetails();
          }
        }, "📱 Abrir 'deviceInfoDetails'"),
        button({
          style: styles.secondaryActionBtn,
          onclick: () => {
            handleOpenEntitiesWizard();
          }
        }, "🧙 Abrir Wizard 'entities'")
      ),

      // Listado de datos simples
      ul({ style: styles.list },
        fieldsList.val.map((field) => {
          return li({ style: styles.item },
            span({ style: styles.key }, field.label),
            span({ style: styles.value }, String(field.value))
          );
        })
      )
    );
  }
);