frontend-plus-react 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +5 -2
- package/dist/index.cjs +1153 -967
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +14 -4
- package/dist/index.css.map +1 -1
- package/dist/index.js +1060 -874
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -70,6 +70,7 @@ Son las de `dmencu` (que aplican a todo proyecto compartido de esta carpeta), es
|
|
|
70
70
|
- F4 con la tecla apretada: las pulsaciones que caen en la celda antes de que el editor nuevo tenga el foco se le pasan por `registrarEditor`, o quedan en cola hasta que haya uno. F4 usa el valor que acaba de copiar si la fila de arriba todavía no se redibujó.
|
|
71
71
|
|
|
72
72
|
### Detalles desplegados (como `backend-plus`)
|
|
73
|
+
- **El botón del detalle**: Ctrl+clic o la ruedita lo abren en otra pestaña. La ruedita llega como `auxclick`, y en Windows el navegador empieza el desplazamiento automático al apretarla y no lo manda: el botón cancela el `mousedown` del botón del medio. El botón se centra sobre toda la celda (`position: absolute; inset: 0`): la columna mide 30 px y la grilla le deja 8 px de margen a cada lado, así que centrarlo dentro del margen lo corría a la derecha de su sigla.
|
|
73
74
|
- Un detalle es una fila especial (`FilaDetalle`, marcada con un `Symbol`) que se intercala debajo de su fila y ocupa todas las columnas; adentro hay otra `GenericDataGrid` (recursiva). Ctrl+click o botón del medio lo abre en otra pestaña.
|
|
74
75
|
- Alturas: **de arriba hacia abajo**. La grilla principal toma lo que queda de la ventana; cada detalle recibe `altoDisponible` y no puede pasar de ahí, así su pie queda visible. No calcular el tope con el alto medido de la grilla padre: una grilla de pocas filas es baja y aplasta a su detalle.
|
|
75
76
|
- Un detalle con muchas filas muestra `firstDisplayCount` (20) cuando supera `firstDisplayOverLimit` (30), los mismos umbrales de `backend-plus`, y **virtualiza** sus filas; los chicos crecen según su contenido. La grilla principal siempre virtualiza.
|
|
@@ -118,7 +119,7 @@ Son las de `dmencu` (que aplican a todo proyecto compartido de esta carpeta), es
|
|
|
118
119
|
- Íconos grises; el ítem seleccionado y el grupo abierto toman el color de su tipo. Una wScreen se considera implementada si está en `myWScreens` **o** si el puente está encendido (se pide a backend-plus); el triángulo de advertencia es solo para «no implementada». Las pantallas del puente viven en `/bp/menu#w=<pantalla>`: así se detecta cuál está seleccionada.
|
|
119
120
|
|
|
120
121
|
### Estilo alineado con el skin `modern` de backend-skins
|
|
121
|
-
- Para que lo que entra por el puente se parezca: bordes `#e0e0e0`, encabezado `#eceff1` con letra de peso 500, hover y selección con el color primario translúcido (variables `--rdg-*` de `.rdg-light` en `GenericDataGrid.css`; usan `--primary-rgb` del skin si está cargado). Los íconos de acciones de la grilla son grises sin borde (toman su color al pasar el mouse), como `.table-button`. Sigue distinto: la barra azul del título de cada grilla y los íconos (acá son los de MUI).
|
|
122
|
+
- Para que lo que entra por el puente se parezca: bordes `#e0e0e0`, encabezado `#eceff1` con letra de peso 500, hover y selección con el color primario translúcido (variables `--rdg-*` de `.rdg-light` en `GenericDataGrid.css`; usan `--primary-rgb` del skin si está cargado). Los íconos de acciones de la grilla son grises sin borde (toman su color al pasar el mouse), como `.table-button`. Al scrollear, detrás de las filas hay un patrón de filas vacías (`background-image` de `.rdg-light`, 30 px) para que no se vea blanco mientras React dibuja las filas virtualizadas, y `content-visibility: visible` (react-data-grid lo pone en `auto`). Por eso los colores de hover y selección tienen que ser **opacos** (`color-mix` con blanco): uno translúcido deja ver el patrón como una raya en la fila. Sigue distinto: la barra azul del título de cada grilla y los íconos (acá son los de MUI).
|
|
122
123
|
|
|
123
124
|
### Cambiar contraseña y recuperar clave
|
|
124
125
|
- **Cambiar contraseña** (`/chpass`, `CambiarClavePage`; ícono de llave junto a «Salir»): `POST /chpass` con `oldPassword`, `newPassword` y `repPassword`, como el formulario de backend-plus. El servidor contesta con una redirección: al login si cambió (y **cierra la sesión**) o de vuelta a `/chpass` con el motivo en la página (`.error-message`, `resultadoDeCambioDeClave`; depende del HTML de `chpass.jade`).
|
|
@@ -143,11 +144,13 @@ Para no perder lo que la grilla de `backend-plus` ya hace y que acá todavía no
|
|
|
143
144
|
- Tres cosas que el cliente de `backend-plus` necesita y que el puente hace: un `<base href>` en la base-url (arma sus direcciones relativas a la página), el global `my` igual a `myOwn`, y llamar a `myOwn.autoSetup()` a mano (él lo hace al evento `load`, que ya pasó).
|
|
144
145
|
- Una wScreen de `backend-plus` puede ser una función, un objeto con `mainFunction`, o un objeto con `parameters` y `mainAction` (como `abrir_encuesta` de dmencu: muestra el formulario de parámetros). `resolverPantallaBP` reproduce el `showPage` de my-menu.js para las tres.
|
|
145
146
|
- **Las pantallas de `backend-plus` viven en una sola ruta, `/bp/menu#w=<pantalla>&...`** (`PaginaBP`; `/wScreens-fallback/:nombre` redirige ahí). Se parece a `<base-url>/menu` **a propósito**: BP y las aplicaciones arman direcciones a partir de la ubicación (`location.origin + location.pathname + '/../menu#w=...'` en un `history.replaceState` + `location.reload()`, como el «Cerrar» de una encuesta de dmencu; `location.pathname + '#w=...'` para abrir en otra pestaña) y así caen en esta misma ruta, que lee los parámetros del hash (o de la query) como BP. Con otra ruta, esas direcciones salen de `/react`. En producción, el servidor tiene que devolver el `index.html` también para `/react/bp/menu`.
|
|
146
|
-
- **Lo que BP manda a páginas del backend se resuelve adentro** (`capturaDeNavegacion.ts`, montado una sola vez por `CapturaBP` mientras el puente está encendido, **no** solo mientras hay una pantalla de BP: su cliente sigue vivo después de salir de ella y sus avisos quedan en el `body`; por ejemplo el de «Iniciar sesión» de `my-inform-net-status.js`, un `<a href="login">` que sin la captura llevaba a `<base-url>/login` y, con la sesión abierta, a `<base-url>/menu`, el BP nativo): clics en `<a>` (a nivel documento, también en diálogos) y, donde existe la Navigation API, cualquier `location.href = ...`. `rutaDeEnlaceBP` traduce `<base-url>/menu#w=...` a `/bp/menu#w=...`, y `login`/`logout` a los de la aplicación. El clic se corta con `stopPropagation`: el botón «proceder» de BP tiene además un `onclick` propio (`history.pushState` a `<base-url>/menu#...` y `showPage`) que dejaría la URL fuera de la aplicación y daría un error de BP. También se traduce `history.replaceState`: al editar un parámetro de una pantalla (`myOwn.replaceAddrParams`) BP reescribe la dirección a `menu#...` y, con el `<base>`, la aplicación quedaba en `<base-url>/menu` (un F5 y se salía de `/react`); `replaceState` no pasa por la Navigation API. Los enlaces `menu#i=...` (ítems del menú de BP, sin `w`) no se traducen. Los parámetros se leen con `myOwn.UriSearchToObject`, no con `URLSearchParams`: `up`, `ff` y `detailing` tienen su propio formato y llegan como objetos.
|
|
147
|
+
- **Lo que BP manda a páginas del backend se resuelve adentro** (`capturaDeNavegacion.ts`, montado una sola vez por `CapturaBP` mientras el puente está encendido, **no** solo mientras hay una pantalla de BP: su cliente sigue vivo después de salir de ella y sus avisos quedan en el `body`; por ejemplo el de «Iniciar sesión» de `my-inform-net-status.js`, un `<a href="login">` que sin la captura llevaba a `<base-url>/login` y, con la sesión abierta, a `<base-url>/menu`, el BP nativo): clics en `<a>` (a nivel documento, también en diálogos) y, donde existe la Navigation API, cualquier `location.href = ...`. `rutaDeEnlaceBP` traduce `<base-url>/menu#w=...` a `/bp/menu#w=...`, y `login`/`logout` a los de la aplicación. El clic se corta con `stopPropagation`: el botón «proceder» de BP tiene además un `onclick` propio (`history.pushState` a `<base-url>/menu#...` y `showPage`) que dejaría la URL fuera de la aplicación y daría un error de BP. También se traduce `history.replaceState`: al editar un parámetro de una pantalla (`myOwn.replaceAddrParams`) BP reescribe la dirección a `menu#...` y, con el `<base>`, la aplicación quedaba en `<base-url>/menu` (un F5 y se salía de `/react`); `replaceState` no pasa por la Navigation API. También se traduce `window.open`: el código de las aplicaciones arma la dirección de otra pestaña como `location.origin + location.pathname + '#w=...'` (`my.menuSeparator` es `'#'`; los botones «abrir» de dmencu: `abrir_encuesta`). En BP el `pathname` siempre es `<base-url>/menu`, acá es la ruta actual (una grilla, que ignora el hash): `rutaDeHashDeBP` lleva cualquier dirección de la aplicación con `#w=` a `/bp/menu#w=...`. Lo que el hash no cubre: `location.href = pathname + '#w=...'` en la misma pestaña (solo cambia el hash, no navega). Los enlaces `menu#i=...` (ítems del menú de BP, sin `w`) no se traducen. Los parámetros se leen con `myOwn.UriSearchToObject`, no con `URLSearchParams`: `up`, `ff` y `detailing` tienen su propio formato y llegan como objetos.
|
|
147
148
|
- **Los scripts de `backend-plus` se inyectan recién cuando la ventana terminó de cargar** (`esperarCargaDeVentana`): su `load` ejecuta `showPage`, que acá falla (no hay `#total-layout`). Y su manejador de errores (`myOwn.log`) deja el mensaje como primer hijo del `body` cuando no hay un `#mini-console`, lo que **corre toda la aplicación hacia abajo** durante 30 s. Era el «espacio entre el menú y el contenido» que aparecía con F5 y a veces no.
|
|
148
149
|
- **La aplicación no está atada a la ruta `/react`.** `my-menu.js` escucha `popstate` y, si la dirección no termina en `/react`, ejecuta `showPage()` (falla igual que el `load`); lo marca como `//TODO: desacoplar de BP`. El puente lo evita sin tocar `backend-plus`: mientras inyecta los scripts, `sinEscuchasDeVentana(['popstate'], ...)` ignora que registren ese evento (la navegación es del router). Si backend-plus agrega otro enganche así, se ve como un error en `ConsolaBP`. Sin el puente (`puenteBP` apagado) no se carga nada de `backend-plus` y la base-url de la aplicación es la que quiera. **Sin probar en navegador** (se probó el filtro en Vitest; falta atrás/adelante contra un backend real).
|
|
149
150
|
- **`ConsolaBP`** ofrece ese `#mini-console` (dentro de `PantallaBP` y `GrillaBP`): los mensajes y errores de `backend-plus` se ven como avisos flotantes arriba a la derecha, debajo de la AppBar, sin ocupar lugar. BP registra algunos errores **dos veces** (el de una llamada ajax lo registra `my-ajax.js` y el `catch` de «proceder», en `my-menu.js`, lo repite; pasa también en BP nativo): si llega un aviso igual a uno que llegó hace menos de 1 s, se descarta (`descartarRepetidos`). Sin contador: el error se ve una vez. Las hojas de estilo del backend y de las aplicaciones también estilizan `#mini-console` (por id, con `top`, `width: 100%`, `max-height`...): por eso `ConsolaBP` usa `&#mini-console` y repone esos valores.
|
|
150
151
|
- Las wScreens de `backend-plus` dibujan en `#main_layout`: `PantallaBP` le da ese contenedor y le pasa lo que declara su ítem de menú más la query string. Mientras está montada no puede haber otro elemento con ese id.
|
|
152
|
+
- **clientSides de las grillas.** Se reproducen los de `myOwn.clientSides` de backend-plus que no dependen de su DOM: `displayUrl` (un enlace) y `newPass`. `newPass` no tiene componente: es una celda común con el mismo editor y las mismas teclas, y al terminar de editar corre `guardadosPropios.newPass` (`admin_chpass`) en lugar de `table_record_save` (`InputRenderer`); la fila no cambia, no se ve lo escrito. Un campo clientSide **no es editable** (`campoEditableEnCelda`) salvo que tenga guardado propio: antes la columna era editable (`editable !== false`) y Enter abría el editor, que guardaba `clave_nueva` con `table_record_save` («no existe la columna clave_nueva en la relación usuarios»). `$lock` usa la base local del modo offline y no está. Si una tabla tiene un clientSide de campo que se dibuja y no está registrado, o uno de **tabla** (`TableDefinition.clientSide`, que acá no se reproduce), y el puente está encendido, `GenericDataGrid` muestra la grilla de backend-plus (`GrillaBP`) en lugar de la propia (`clientSidesSinImplementar`); la grilla de BP va dentro de un contenedor con su propio scroll y 8 px de margen: el panel de `GenericDataGridPage` tiene alto fijo y `overflow: hidden` (las grillas de esta librería se miden solas) y recortaba la de BP, que crece con su contenido. Sin puente queda el `FallbackClientSideRenderer` de siempre. Lo que registra la aplicación con `extendClientSides` evita el cambio. Sin probar en navegador.
|
|
153
|
+
- **Las hojas de estilo de backend-plus son globales** (`body { font-family: arial; font-size: 93.75%; margin: 0 }` de `my-menu` y `my-things`, los skins...) y cargadas con un `<link>` cambiaban la fuente y el aspecto de toda la aplicación (el menú incluido), antes y después de abrir una pantalla de BP. Ahora `cargarClienteBP` las baja como texto y `acotarEstilos` (`estilosBP.ts`) prefija cada selector con `.fpr-bp`, la clase del contenedor de `PantallaBP` y `GrillaBP`; `html`, `body` y `:root` pasan a ser el contenedor (sin su `overflow`, alto ni `position`: `body { height: 100%; overflow: hidden }` le cortaría el contenido y la grilla no scrollearía). Las reglas de los skins empiezan con `[my-skin=default] ...` y `my-skin` es un atributo del `body` (`lib/my-skin.js`): se aplican al contenedor, que lo recibe con `copiarSkinAlContenedor`; sin eso se pierde todo el skin. `@font-face` y `@keyframes` no se tocan y las `url()` relativas se resuelven contra la hoja. Lo que BP agrega fuera del contenedor (diálogos que cuelgan del `body`) queda sin sus estilos. Sin probar en navegador.
|
|
151
154
|
- `rutaBase` (`src/rutaBase.ts`) toma el `base` del bundler: es el `basename` del router y el prefijo de las pestañas nuevas (Ctrl+click en un detalle `wScreen`).
|
|
152
155
|
- **No hay un entorno de prueba automático para esto**: jsdom no carga los scripts de `backend-plus`. Los tests cubren la extracción de recursos y la elección de pantalla; el resto se prueba en el navegador contra un backend real (headless: Chrome con `--screenshot` y un proxy chico que inyecte la cookie de sesión).
|
|
153
156
|
- Probado contra ggs (con Chrome controlado por el protocolo de depuración, sin escribir en la base): grilla `usuarios`, la wScreen `ayuda` y `abrir_encuesta` hasta ver el formulario de la encuesta de dmencu dentro de `mi-frontend`. Sin probar: edición, detalles anidados, exportar y la convivencia del CSS global de `backend-plus` con MUI.
|