Cómo migrar el JavaScript de procesos Classic a la nueva UI
Descripción general
En Etendo Classic, un Proceso definido (un proceso configurado en el Diccionario de la Aplicación, con o sin parámetros) puede llevar JavaScript escrito a mano que personaliza su diálogo: pre-rellenar campos cuando se abre, validar y transformar la entrada a medida que el usuario escribe, condicionar la ejecución a una confirmación, mostrar banners dentro del diálogo, lanzar procesos anidados o post-procesar la respuesta del servidor. En Classic este JavaScript se ejecuta dentro del entorno de ejecución de SmartClient.
La nueva Workspace UI reproduce ese comportamiento sin SmartClient. El JavaScript personalizado ya no está vinculado a un módulo de SmartClient; en su lugar se almacena como texto plano en un conjunto de columnas de metadatos del proceso y de sus parámetros. En tiempo de ejecución, la nueva UI compila ese texto y lo ejecuta contra un contexto controlado que emula las APIs de Classic que los scripts esperan. Esto hace que la capacidad sea totalmente controlada por metadatos: cualquier proceso se vuelve programable simplemente rellenando sus columnas — no se despliega código nuevo en la UI.
Esta guía explica cómo migrar el JavaScript de un Proceso definido de Classic a la nueva UI en su propio entorno. Si usted mantiene una instancia productiva con Procesos definidos personalizados cuyo JavaScript de Classic personaliza su comportamiento, esos scripts no se ejecutarán en la nueva UI hasta que se migren a las columnas de metadatos. Este documento es la referencia para esa migración.
Alcance y responsabilidades
Esta guía está dirigida a desarrolladores que deben migrar el JavaScript de procesos Classic sin acceso al código fuente de la nueva UI. La vía recomendada y con soporte es seguir esta documentación y migrar a mano. Sus herramientas son esta documentación y los pasos manuales y autogestionados que describe. Concretamente:
- Producir el código migrado siguiendo esta guía.
- Pegarlo en los campos de metadatos correctos (consulte Los campos de metadatos).
- Validar el resultado manualmente en el diálogo en ejecución.
- Si algo no funciona, notificar el problema — describir exactamente qué falla y dónde.
Antecedentes: los cinco puntos de enganche de Classic
Un Proceso definido de Classic puede asociar comportamiento en hasta cinco puntos. La nueva UI asigna cada uno a una columna de metadatos:
| # | Hook de Classic | Se dispara cuando | Ámbito |
|---|---|---|---|
| 1 | onLoad |
Se abre el diálogo del proceso | Process (OBUIAPP_Process) |
| 2 | onProcess |
El usuario pulsa el botón de ejecutar / OK | Process (OBUIAPP_Process) |
| 3 | onRefresh |
El diálogo necesita volver a obtener sus datos (p. ej. después de que se cierra un proceso anidado) | Process (OBUIAPP_Process) |
| 4 | onChange |
Se confirma el valor de un parámetro | Parameter (OBUIAPP_Parameter) |
| 5 | onGridLoad |
Un parámetro de grilla insertada termina de cargar las filas | Parameter (OBUIAPP_Parameter) |
Más allá de estos puntos de entrada, un archivo de proceso de Classic es un único módulo de JavaScript:
los puntos de entrada llaman a funciones auxiliares compartidas, constantes y estado de closure declarados
en el mismo archivo. La nueva UI reproduce esto con una columna dedicada de ámbito de módulo (consulte
em_etmeta_payscript_logic).
El objetivo de la migración es la paridad de comportamiento: un proceso migrado debe comportarse igual que su contraparte de Classic, con el JavaScript residiendo en los metadatos en lugar de en un módulo de SmartClient.
Qué puede hacer la nueva UI
Esta sección describe las capacidades disponibles para los scripts migrados — el qué, el por qué y
cómo se usan — sin entrar en cómo se implementan internamente. Si un script toca algo que la nueva UI
no implementa, lanza un error claro "<api> is not implemented yet" en lugar de fallar silenciosamente,
de modo que las carencias afloran durante la migración en lugar de en producción.
El contrato del modelo de ejecución que debe respetar
Unas pocas reglas rigen cada campo. Un cuerpo que las incumpla no se ejecutará:
- Cada hook es una expresión de arrow function simple. El valor de un campo debe ser una única arrow
function como
async (process, view) => { … }. No debe estar envuelta en una IIFE (expresión de función invocada inmediatamente, p. ej.(async () => { … })()) y no debe ser un literal de objeto. Cualquier cosa que no evalúe a una función se rechaza en tiempo de compilación. onLoad/onProcess/onChange/onGridLoadson arrow functions; el ámbito de módulo es diferente. El campo de ámbito de módulo (em_etmeta_payscript_logic) es un cuerpo de módulo — una secuencia de declaraciones que termina enreturn { … };— no una arrow function. Consulte la descripción de su campo más abajo.- Las funciones auxiliares se resuelven por su nombre simple. Todo lo devuelto por el campo de ámbito
de módulo está disponible, por su nombre simple, dentro de los cinco hooks. Los globales como
OB,callAction,confirm,messageBaryBigDecimaltambién se inyectan y pueden llamarse directamente. onChangeno se dispara durante el sembrado inicial. Igual que en Classic, elonChangede un parámetro se ejecuta solo ante un cambio genuino del usuario, nunca mientras el diálogo siembra sus valores iniciales o por defecto. Coloque el cómputo de tiempo de carga enem_etmeta_onload, no enem_etmeta_on_parameter_change.
Catálogo de capacidades
| Capacidad | Qué aporta a los scripts migrados |
|---|---|
El objeto view |
Refleja el OBStandardView de Classic. El contexto de solo lectura (view.theForm, view.messageBar, view.getContextInfo(), view.selectedRecords, view.tabId, …) está siempre disponible; los métodos de acción (view.refresh(), view.openProcess(...), view.executeProcess(), los botones del pie, el botón OK) están disponibles dentro de los hooks que los necesitan. |
Proxies form, item |
view.theForm.getItem(name) y métodos de campo: getValue() / setValue(v), show() / hide() / isVisible(), setRequired(bool) / setDisabled(bool), setTitle(text), setValueMap(map) / getValueMap(), setValueFromRecord({ id, _identifier }), y más. Los parámetros numéricos devuelven numbers reales, de modo que las comparaciones de Classic siguen funcionando. |
Proxy grid |
Para grillas insertadas (Window-Reference / Pick&Execute): selección (getSelectedRecords, selectRecord, …), lecturas de filas, valores de edición (setEditValue, getEditValues), visibilidad (show() / hide()), botones de acción por fila, y hooks de tiempo de ejecución registrados desde onGridLoad (onRecordChange, onSelectionToggle, setColumnOnChange, setColumnValidator, fireOnPause). Dentro de onGridLoad la grilla se recibe como el argumento grid; desde cualquier otro hook (onLoad, onProcess, onRefresh, el onChange de un parámetro) se accede al mismo handle mediante view.theForm.getItem(name).canvas.viewGrid. |
Ejecución en el servidor — view.executeProcess() |
El equivalente en la nueva UI del actionHandlerCall() de Classic. Construye el payload de ejecución estándar y lo envía a la clase Java configurada del proceso. Úselo en onProcess en lugar de construir un payload a mano. |
| Funciones auxiliares HTTP | callAction(handler, payload), callDatasource(entity, payload), callServlet(path, payload) — POST a handlers/datasources del backend con autenticación y CSRF gestionados automáticamente. |
| Diálogos modales | confirm / warn / say (e isc.confirm / ask / warn / say). Basados en Promesas y también aceptan la forma de callback de Classic. |
| Barra de mensajes dentro del diálogo | view.messageBar.setMessage(severity, title, text, actions?) y view.messageBar.hide(), con severidades OB.MessageBar.TYPE_* / isc.OBMessageBar.TYPE_*. Los enlaces clicables deben expresarse como un array estructurado actions, no como HTML <a onclick> en línea. |
| Procesos anidados | view.openProcess(params) (y view.standardWindow.openProcess(...)) superpone otro diálogo de proceso encima; el onRefresh del padre se dispara cuando el proceso hijo se cierra. |
El shim OB.* |
Un espacio de nombres OB compartido que refleja los globales de Classic: OB.I18N.getLabel, OB.Format.*, OB.Utilities.Number.JSToOBMasked, OB.Utilities.Action.set/execute/executeJSON, OB.PropertyStore, OB.RemoteCallManager.call (adaptador callback↔Promise), OB.Datasource.create, OB.Constants, constantes de severidad. |
Aritmética decimal — BigDecimal |
El BigDecimal de Classic se inyecta como global, de modo que los cálculos monetarios (add, subtract, multiply, divide, compareTo, setScale, …) se migran textualmente. Nunca reescriba los cálculos monetarios con Number / parseFloat, que generan deriva y rompen la paridad con el servidor. |
| Despachador de action-JSON | OB.Utilities.Action.executeJSON(actions) despacha un array responseActions del backend (barra de mensajes, toast, navegar a una solapa, refrescar grilla, descargar/visualizar informe, …). |
| Componente de UI personalizado | Cuando se establece la marca de componente personalizado del proceso, onLoad devuelve un esquema de UI y el diálogo renderiza un componente a medida en lugar del formulario de parámetros estándar. |
Qué no se admite (aún)
La nueva UI es genérica y controlada por metadatos, sin tratamientos especiales por proceso. Un conjunto de mecanismos de Classic están intencionadamente modificados o no se admiten:
- El HTML con onclick en línea en los mensajes no está permitido. El texto de los mensajes se sanea
(solo etiquetas de formato); use el array estructurado
actionspara los elementos clicables. - Las primitivas de UI de SmartClient (
isc.ClassFactory.defineClass,isc.DynamicForm,isc.OBPopup, …) no están disponibles. Sus equivalentes son los declarativosgrid.setRowActions(...)yopenDynamicForm({ fields }). - Cualquier cosa que la plataforma no implemente lanza
"<api> is not implemented yet". Si encuentra ese error durante la validación, es una carencia de capacidad que debe notificar (consulte Notificar problemas) — no algo que deba sortear en su entorno.
Los campos de metadatos (dónde va el código migrado)
Siete columnas personalizadas contienen el código migrado. Cinco pertenecen al proceso (cuatro hooks más una marca de renderizado), y dos a cada parámetro. Introduzca el JavaScript migrado en el campo correspondiente a cada columna en la ventana Process Definition (y su solapa Parameters) en el Diccionario de la Aplicación.
| Campo (columna) | Entidad | Hook | Forma del código |
|---|---|---|---|
em_etmeta_onload |
Process | onLoad |
async (process, view) => { … } |
em_etmeta_onprocess |
Process | onProcess |
async (process, view) => { … } |
em_etmeta_on_refresh |
Process | onRefresh |
(view) => { … } |
em_etmeta_payscript_logic |
Process | ámbito de módulo compartido | cuerpo de módulo que termina en return { … }; |
em_etmeta_on_parameter_change |
Parameter | onChange |
(item, view, form, grid) => { … } |
em_etmeta_on_grid_load |
Parameter | onGridLoad |
(grid, view, parameters) => { … } |
em_etmeta_custom_component |
Process | marca de renderizado | booleano (Sí/No) |
Cualquier campo puede dejarse vacío
Un proceso rara vez usa los cinco hooks. Rellene solo los campos que correspondan a los hooks que el archivo de Classic realmente implementa; deje el resto vacíos. Un campo vacío significa "sin script para este hook".
A continuación se describe el propósito, la firma y un ejemplo sencillo para cada campo.
1. em_etmeta_onload — onLoad del proceso
- Entidad: Process · Firma:
async (process, view) => { … } - Se dispara: una vez, cuando se abre el diálogo, después de que los valores por defecto hayan sido sembrados y antes de que el formulario sea interactivo.
- Propósito: sembrar o calcular valores por defecto, ocultar o requerir campos, preseleccionar filas de
grilla, condicionar la apertura a un
confirm, o (con la marca de componente personalizado) devolver un esquema de UI. - Devuelve (opcional): un mapa de pares
paramName: valuepara sembrar campos; un retorno falsy es una operación sin efecto.
async (process, view) => {
const form = view.theForm;
// Hide an advanced field unless the launching record is a sales transaction.
const ctx = view.getContextInfo();
if (ctx.inpissotrx !== 'Y') {
form.getItem('credit_to_use').hide();
}
// Seed a sensible default and make a field mandatory.
form.getItem('payment_date').setValue(ctx.inpdateordered);
form.getItem('reference_no').setRequired(true);
};
2. em_etmeta_onprocess — onProcess del proceso
- Entidad: Process · Firma:
async (process, view) => { … } - Se dispara: cuando el usuario pulsa el botón de ejecutar / OK.
- Propósito: validación del lado del cliente antes del envío, llamada al backend y post-procesamiento de la respuesta.
- Regla clave: llame a
view.executeProcess()para ejecutar la clase Java propia del proceso (el equivalente delactionHandlerCall()de Classic). Para abortar con un error, devuelva{ severity: 'error', text }.
async (process, view) => {
const form = view.theForm;
const amount = form.getItem('actual_payment').getValue(); // numeric field returns a real number
if (amount <= 0) {
const text = OB.I18N.getLabel('ETP_AmountMustBePositive');
view.messageBar.setMessage(isc.OBMessageBar.TYPE_ERROR, null, text);
return { severity: 'error', text }; // aborts; the modal stays open
}
const response = await view.executeProcess(); // equivalent to actionHandlerCall()
return response && response.message;
};
Los procesos Pick&Execute / Window-Reference se comportan de forma diferente
Para un proceso cuyo patrón es Pick&Execute, o que tiene un parámetro de grilla Window-Reference, la
plataforma envía la selección de la grilla por sí misma. En ese caso, onProcess se ejecuta como un
hook de validación previa al envío: devuelva { severity: 'error', text } para abortar, o
undefined para dejar que el envío continúe — y no llame a view.executeProcess() (provocaría
un doble envío).
3. em_etmeta_on_refresh — onRefresh del proceso
- Entidad: Process · Firma:
(view) => { … } - Se dispara: cuando el diálogo necesita volver a obtener sus datos — por ejemplo, cuando se cierra un
proceso anidado, el
onRefreshdel padre se invoca automáticamente. - Propósito: refrescar los datos de grilla/formulario después de un cambio externo.
(view) => {
// Re-pull the embedded grid after a nested process modified the data.
view.theForm.getItem('order_invoice').canvas.viewGrid.invalidateCache();
};
4. em_etmeta_payscript_logic — ámbito de módulo compartido
- Entidad: Process · Forma: un cuerpo de módulo (declaraciones y funciones auxiliares) que
termina con
return { … };— no una arrow function. - Propósito: contener todo lo que el archivo de Classic declaraba a nivel de módulo — funciones auxiliares compartidas, constantes y estado de closure — que los puntos de entrada referencian por su nombre simple. Se evalúa una vez por apertura del diálogo, y lo que devuelva queda disponible dentro de los cinco hooks.
const PAID_FULLY = 'PPM';
function remaining(form) {
const total = new BigDecimal(String(form.getItem('total').getValue()));
const paid = new BigDecimal(String(form.getItem('actual_payment').getValue()));
return total.subtract(paid);
}
return { PAID_FULLY, remaining };
Auto-registro con espacio de nombres
Si el archivo de Classic registra un espacio de nombres como OB.APRM.AddPayment = { … }, haga lo
mismo dentro de este cuerpo de módulo; el shim OB tolera escrituras OB.<Module>.<Process>.
5. em_etmeta_on_parameter_change — onChange del parámetro
- Entidad: Parameter (uno por parámetro que tenga un onChange) · Firma:
(item, view, form, grid) => { … }—itemes el campo que cambió;gridesnullpara los parámetros escalares. - Se dispara: cuando el usuario confirma el valor del parámetro (nunca durante el sembrado inicial).
- Propósito: reaccionar ante un cambio de valor — recalcular campos dependientes, alternar requerido/deshabilitado, refrescar un mapa de valores, mostrar un banner.
(item, view, form) => {
// When the document type changes, recompute the suggested amount.
const isCredit = item.getValue() === 'CR';
form.getItem('credit_amount').setDisabled(!isCredit);
if (!isCredit) {
form.getItem('credit_amount').setValue(0);
}
};
6. em_etmeta_on_grid_load — onGridLoad del parámetro
- Entidad: Parameter (el parámetro de grilla) · Firma:
(grid, view, parameters) => { … } - Se dispara: cada vez que la grilla insertada recibe un resultado de datasource entregado (incluido un resultado vacío, exactamente una vez).
- Propósito: post-procesar las filas cargadas (selección por defecto, componentes por fila, columnas derivadas), registrar hooks/validadores de edición por columna, o reaccionar ante una grilla vacía (p. ej. un banner informativo cuando ninguna fila coincide).
(grid, view) => {
if (grid.getData().getLength() === 0) {
view.messageBar.setMessage(isc.OBMessageBar.TYPE_INFO, null,
OB.I18N.getLabel('ETP_NoOutstandingDocuments'));
return;
}
// Recompute a total whenever an editable amount cell changes.
grid.onRecordChange((record, changes) => {
// …re-sum settlement amounts over the selected rows…
});
};
7. em_etmeta_custom_component — marca de componente personalizado
- Entidad: Process · Tipo: booleano (Sí/No).
- Propósito: determina cómo se renderiza el diálogo del proceso:
- No (false) — el caso normal. El diálogo renderiza el formulario estándar basado en metadatos:
los parámetros del proceso, sus metadatos y los hooks de JavaScript migrados (
onLoad,onProcess,onChange, …) descritos en esta guía. Esto es lo que se utiliza para prácticamente todas las migraciones. - Sí (true) — una UI a medida. El diálogo no renderiza el formulario de parámetros estándar.
En su lugar, la nueva UI debe contener un componente personalizado construido específicamente para
ese proceso, y
onLoaddevuelve el esquema que lo gobierna. Esto refleja el comportamiento de Classic, donde un proceso así también dispone de su propia UI construida a mano en lugar de un diálogo de parámetros genérico. Se reserva para el caso poco frecuente de un proceso cuyo diálogo no es una lista plana de campos (p. ej. un selector especializado).
- No (false) — el caso normal. El diálogo renderiza el formulario estándar basado en metadatos:
los parámetros del proceso, sus metadatos y los hooks de JavaScript migrados (
Un componente personalizado requiere la intervención del equipo de plataforma
Establecer esta marca en Sí no es una migración que usted pueda completar rellenando campos. Un componente personalizado es código real que debe añadirse a la nueva UI para ese proceso concreto, y usted no dispone de acceso al código fuente de la nueva UI. Si un proceso realmente necesita un componente personalizado, comuníquese con el equipo de plataforma para que lo construya. Para todos los demás procesos, deje esta marca en No y realice la migración utilizando los campos estándar descritos arriba.
Migrar con el "New UI Migrations" Team
Usted puede migrar todos los procesos a mano siguiendo esta guía. El "New UI Migrations" Team es una herramienta opcional que el equipo de Etendo construyó y usó internamente para acelerar el trabajo; su uso no tiene soporte. Traduce un archivo JavaScript de un Proceso definido de Classic a las columnas de metadatos descritas arriba, usando sus agentes de migración. Descárguelo desde Descargas y cargue sus archivos en su asistente de IA. Se usó con Claude Code, pero los agentes y el skill son Markdown plano que funciona con cualquier asistente de IA. Interactúe con él en español (al menos el primer mensaje), como se muestra en los pasos a continuación.
Descargas
Los agentes de migración y el skill de arquitectura y migración están disponibles como una única descarga:
Descargar los agentes de migración y el skill (.zip)
El zip contiene cuatro archivos Markdown:
faro.md— el agente coordinador, que valida la solicitud y despacha el trabajo.babel.md— el agente migrador/desarrollador, que analiza el JavaScript de Classic y genera el código migrado por columna de metadatos.sello.md— el agente de QA, que guía la validación manual contra una lista de verificación de pruebas.new-ui-js-migration-guide.md— el skill: la referencia autoritativa de arquitectura y migración. Es la fuente de verdad de cada API admitida, firma y regla de migración.
Cargue estos archivos Markdown en su asistente de IA. Internamente, el equipo de Etendo usó Claude Code, pero los archivos son agnósticos de herramienta, de modo que funcionan con cualquier asistente de IA.
El tooling de agentes no tiene soporte
El uso del "New UI Migrations" Team es opcional y no tiene soporte. No se da soporte a los problemas derivados del uso de los agentes en sí. Las carencias de capacidad de la plataforma y los errores del sustrato se siguen notificando y recibiendo soporte de la forma habitual (consulte Notificar problemas).
Migrar a mano
Los pasos 4 a 6 también se aplican a usted: sustituya sus propios cuerpos migrados por los bloques de código etiquetados del equipo, y derive su propio plan de pruebas manual en lugar de la lista de verificación del equipo.
Qué hace — y qué no hace — el equipo
El equipo hace: lee el archivo .js de Classic y los metadatos del proceso; comprueba la viabilidad
contra el skill de arquitectura y migración (consulte Descargas); genera el código migrado
para cada columna como una arrow function simple; autocomprueba que cada cuerpo compila; y entrega una
salida por columna lista para pegar, junto con una lista de verificación de pruebas manuales.
El equipo nunca: pega el código en la UI por usted (eso lo hace usted); cambia el código fuente de la aplicación; hace commit o push de nada; ni inventa soporte de plataforma que no existe. Si un proceso usa algo que la nueva UI no puede hacer, el equipo se detiene y notifica la carencia en lugar de producir código que parece migrado pero falla.
Valide antes de considerar la migración terminada
La salida del equipo es un borrador a verificar, no un resultado terminado. Puede malinterpretar un caso límite o un patrón idiomático de Classic. Ejecute siempre la lista de verificación manual antes de considerar la migración terminada, y notifique cualquier cosa que falle.
Paso 1 — Identificar las entradas
Reúna dos entradas:
- La ruta al archivo
.jsde Classic del Proceso definido (el archivo que contiene su JavaScript personalizado). - El id del proceso — el
obuiapp_process_idde 32 caracteres del Proceso definido. Puede leerlo desde el registro de la ventana Process Definition, o desde la URL/ayuda de ese registro.
Paso 2 — Activar el equipo
El agente de migración del equipo solo actúa cuando su mensaje coincide con su plantilla de activación exactamente (las comillas pueden ser simples o dobles). Envíele, en español, la ruta del archivo y el id del proceso:
Quiero migrar el javascript del proceso definido. El path del archivo original es '<path>' y el id del proceso es '<process-id>'.
Por ejemplo:
Quiero migrar el javascript del proceso definido. El path del archivo original es 'modules/com.example.payments/web/js/ob-myprocess.js' y el id del proceso es '9BED7889E1034FE68BD85D5D16857320'.
Si el mensaje no coincide con la plantilla, el equipo no actuará — simplemente reformulará la plantilla que usted debe usar.
Paso 3 — Revisar la salida del equipo
El equipo devuelve, en español para los entregables:
- Un informe de cobertura: una tabla que clasifica cada API de Classic que el archivo usa como admitida, de mejor esfuerzo o no admitida. Si algo no está admitido, el equipo se detiene aquí y explica exactamente qué le falta a la nueva UI — eso es una carencia que debe notificarse, no sortearse.
- El código migrado por columna, cada uno en su propio bloque de código, claramente etiquetado con la columna a la que va. Las columnas sin código se marcan como "LEAVE EMPTY".
- Una lista de advertencias (código muerto eliminado, notas de clonación, diferencias semánticas).
- Una lista de verificación de pruebas manuales — los pasos concretos que usted debe ejecutar para confirmar la paridad.
Lea el informe de cobertura y las advertencias antes de pegar nada. Le indican qué esperar y qué probar.
Los pasos 4 a 6 se aplican en ambos casos
Tanto si utilizó el equipo como si migró a mano, siga los pasos 4 a 6 tal como están escritos: pegue su código migrado, valídelo manualmente y notifique cualquier problema.
Paso 4 — Pegar el código en los campos
Para cada bloque etiquetado, copie el cuerpo en el campo correspondiente de la ventana Process Definition (o su solapa Parameters), siguiendo Los campos de metadatos. Pegue solo el código migrado — el que entregó el equipo o el suyo propio — exactamente como corresponda, en la columna indicada. Guarde el registro.
Haga coincidir el campo con la columna
Pegar un cuerpo onProcess en el campo onLoad (o un hook de parámetro en el parámetro equivocado)
producirá un comportamiento incorrecto difícil de diagnosticar. Compruebe dos veces la etiqueta de
cada bloque contra el campo que está editando.
Paso 5 — Validar manualmente
Abra el diálogo del proceso en la nueva UI y ejecute cada elemento de su plan de pruebas manual (la lista
de verificación del equipo, o su propio plan si migró a mano): confirme que el diálogo se abre
correctamente, que el sembrado/ocultamiento de onLoad ocurrió, que cada onChange reacciona como en
Classic, que las grillas cargan y validan como se espera, y que la ejecución devuelve el mismo resultado
que Classic. Compare lado a lado con el diálogo de Classic siempre que sea posible.
Paso 6 — Notificar problemas (no corregir)
Si una prueba falla — un hook no se dispara, un valor es incorrecto, o aparece un error
"… is not implemented yet" — notifíquelo. Describa el síntoma con precisión (qué proceso, qué hook,
qué hizo, qué esperaba, qué ocurrió) e incluya cualquier texto de error. Si activó el "New UI
Migrations" Team, dígale "el test X falló: <síntoma>" y reanalizará y reemitirá los campos corregidos
para ese proceso.
No intente parchear la nueva UI en su entorno. Las carencias de capacidad y los errores del sustrato son resueltos por el equipo de plataforma; su contribución es un informe claro y reproducible.
Notificar problemas
Como usted no tiene acceso al código fuente de la nueva UI, un buen informe es lo más valioso que puede producir cuando una migración no se comporta como Classic. Incluya:
- El proceso — nombre y
obuiapp_process_id. - El hook / campo involucrado (
onLoad,onProcess, elonChangede un parámetro específico, etc.). - Pasos para reproducir — exactamente lo que hizo en el diálogo.
- Esperado vs real — qué hace Classic frente a qué hace la nueva UI.
- Cualquier texto de error mostrado en el diálogo o en la consola del navegador (especialmente
"<api> is not implemented yet", que nombra la capacidad faltante). - El cuerpo migrado relevante que pegó, y el informe de cobertura si activó el "New UI Migrations" Team.
This work is licensed under CC BY-SA 2.5 ES by Futit Services S.L.