Commit graph

397 commits

Author SHA1 Message Date
20b6c77c9e 🐛 (base): Exporta PagerAlign y corrige aria-label 2026-08-10 13:19:59 +02:00
8cb5e035dc (theme): Evita referencias cíclicas de parent()
Como `Theme::parent()` se resuelve en tiempo de ejecución, una
referencia cíclica (en la que un tema acaba siendo padre de sí mismo,
directa o transitivamente) no puede descartarse en compilación. Se
detecta al registrar el tema y aborta el arranque si procede.
2026-08-09 18:45:17 +02:00
825283caa3 ♻️ (base): El resumen de Pager usa PagerVisibility
Sustituye el bool de `summary` por `PagerVisibility`, con `Auto` como
valor por defecto: se activa igual que los botones de navegación y el
formulario de salto, sólo cuando el listado se trunca.
2026-08-07 23:47:14 +02:00
ee57d6cacf (base): Añade resumen de páginas en Pager 2026-08-07 19:03:59 +02:00
12c14afbf6 🐛 (base): Correcciones de visualización de Pager
Ajusta el cálculo de la ventana de páginas cerca de los extremos,
convierte la elipsis en una celda `.page-link` real (antes texto suelto
sin borde/fondo), separa el texto visible del aria-label accesible en
los botones anterior/siguiente, añade `with_align()` y ajusta el ancho
del campo de salto al número de dígitos.
2026-08-07 15:28:58 +02:00
3b01894024 (base): Añade componente Pager
Incluye soporte HTMX vía `sort_link()`/`hx_pager` para navegación sin
recarga.
2026-08-06 22:37:28 +02:00
e8bba0803d (form): Añade nuevo componente Number 2026-08-05 17:33:27 +02:00
502c00c891 🎨 Colapsa if anidados sugeridos por clippy 2026-08-05 13:07:35 +02:00
1cab0ae9a0 (theme): Añade región Aside
Introduce `CoreRegions::Aside` como nueva región de plantilla, entre
Header y Content, y Template ahora envuelve el cuerpo en `div.wrapper`,
omitiendo el renderizado si no hay contenido.

`CoreRegion`, `ReservedRegion` y `CoreTemplate` pasan a plural
(`CoreRegions`, `ReservedRegions`, `CoreTemplates`) para no confundirlos
con otras definiciones, y se amplía la documentación del módulo theme.
2026-08-02 10:40:36 +02:00
c49bf8f56a (form): Blinda Field contra el autorrelleno
Añade nuevas variantes `Kind::StrictText` y `StrictPassword`
(`Field::strict_text()` y `strict_password()`) para forzar en el campo
`autocomplete=off`, desactivar spellcheck y autocorrect, aplicar
`readonly+onfocus`, y enmascarar las contraseñas vía CSS en vez de
`type="password"`. Replicado en pagetop-bootsier.
2026-08-02 08:43:32 +02:00
545a87fbb0 ♻️ (bootsier): Ajusta componentes base
- Añade `#[builder_fn]` a `with_width()`/`with_floating_label()`.
- `Rounded::new()` pasa a aplicar el radio por defecto
  (`Rounded::default()` queda sin redondeo).
- `Form::action` usa `Route` en lugar de `AttrValue`, y `check::Item`
  expone `value` en vez de `name` para generar casillas con `name`
  compartido valores distintos.
2026-08-01 13:41:19 +02:00
4cc72aac0e (base): Añade componente Badge
Incluye soporte específico en Bootsier (`BadgeBootsier`) para fijar el
color de fondo con contraste de texto garantizado.
2026-08-01 12:15:00 +02:00
3e83f8e35e 🐛 (locale): Preserva grafía original de "?lang="
Antes, RequestLocale sólo guardaba el LanguageIdentifier ya resuelto,
así que `Context::route()` propagaba siempre la forma canónica en los
enlaces generados ("?lang=en-US"), aunque el usuario hubiera pedido
"?lang=en". Ahora se conserva el valor original de la query junto al
idioma resuelto, y se reutiliza al construir nuevos enlaces mientras
siga siendo válido.

El idioma efectivo para renderizar la petición no cambia: sigue siendo
siempre el LanguageIdentifier canónico soportado por la aplicación.
2026-08-01 08:05:48 +02:00
fdd2dca280 ♻️ (bootsier): Reorganiza clases y tokens utilitarios 2026-08-01 07:15:13 +02:00
1a3a295f18 (htmx): Uso de Context::default() por ::new(None) 2026-07-28 19:09:44 +02:00
c91b1cd35c (seaorm): Añade flatten_txn_err()
Convierte `TransactionError<E>` a `E` para propagar el resultado de una
transacción con `?` sin distinguir el origen del error.
2026-07-28 19:02:12 +02:00
8ddc26dae1 📝 (theme): Aclara alcance de la herencia de temas 2026-07-28 09:19:50 +02:00
dc2ed27da4 ♻️ (util): Extrae non_blank() y normalize_token() 2026-07-28 01:00:14 +02:00
747e64ce34 (auth): Añade permisos tipados
Sustituye las claves de permiso `&str` sueltas por el trait `Permission`
(clave, etiqueta y grupo), y añade `require_permission()` para cortar un
handler con `ErrorPage::AccessDenied` antes de construir nada.

Para que `require_permission()` pueda fallar sin un `Context` previo,
`ErrorPage` pasa a envolver `Option<HttpRequest>`, `Context::new()`
recibe ahora `HttpRequest` sin `Option`, y se añade `Context::admin()`
para la plantilla de administración.
2026-07-27 22:46:41 +02:00
ea0dc021ce (seaorm): Añade Paginated<T> y paginate()
Centraliza la paginación genérica junto con `Paginated::map_items()`
para enriquecer los elementos de una página con datos de otra tabla sin
perder la metadata de paginación.
2026-07-26 21:30:28 +02:00
9db1d4bab0 (htmx): Añade soporte OOB a HtmxResponse
Nuevo método `oob()` para incluir fragmentos adicionales marcados con
`hx-swap-oob` en el cuerpo de la respuesta, sin necesidad de construir
el envoltorio a mano ni depender del `hx-target` de la petición.

De paso, `set_header()` usa ya las constantes de `hx::response` en vez
de literales repetidos, y se revisan comentarios.
2026-07-26 17:55:25 +02:00
74dbcde5c5 ♻️ (core): Cambia HashMap x Vec en RegionComponents 2026-07-26 13:41:32 +02:00
7e6a9f8557 ♻️ (core): Clave &'static str en RegionComponents 2026-07-26 12:50:33 +02:00
845d91d8c1 ♻️ (core): Evita doble clonado de InRegion en Child
Los prototipos registrados con `InRegion` se clonaban dos veces por
petición: una al ensamblar la región (`ComponentGlobal::as_child`) y
otra al renderizar (`Child::render`). Ahora sólo se clonan al
renderizar.
2026-07-26 12:39:01 +02:00
ce6b4d2581 ♻️ (core): Simplifica Child a Arc<dyn Component>
Elimina el `RwLock<Box<dyn Component>>` interno ya que ningún punto del
ciclo de renderizado tomaba el write-lock.

De paso, `From<Embed<C>> for Child` pasa a una coerción de puntero sin
clonar, gracias al copy-on-write que ya ofrece `Embed::get_mut()`. Los
doctests en `rust,ignore` pasan a `rust,no_run`, verificados por el
compilador.
2026-07-26 11:30:16 +02:00
65c8a788c2 (web): Añade cabeceras HTTP a TestRequest 2026-07-26 10:03:54 +02:00
39f494539e ♻️ (htmx): Expone request y response como públicos 2026-07-26 10:02:36 +02:00
b9d9cdf601 🚧 Ajustes menores en rutas y localización
- Añade `Route::try_resolve()` y `RoutePath::is_empty()` para omitir
  atributos HTML opcionales cuando la ruta resultante está vacía.
- Renombra `Locale::configured_langid()` a `try_langid()` (convención
  `try_*` para Option).
- Reordena include_locales! y otros cambios menores.
2026-07-26 09:55:27 +02:00
8573aca29e (theme): Añade componentes Region y Template
Introduce Region y Template (`base::component::layout`) para componer el
`<body>` de una página, con captura explícita vía `handle_component()`
en lugar de maquetado implícito:

- `RegionName`/`TemplateName` (`core/theme.rs`) como interfaces de
  identidad; `CoreRegion` (`Header`/`Content`/`Footer`) y `CoreTemplate`
  (`Standard`/`Admin`) como catálogo por defecto.
- `ReservedRegion` (`PageTop`/`PageBottom`, en `response/page.rs`) queda
  fuera de `CoreRegion`. `Page::render()` las renderiza siempre,
  envolviendo `Theme::render_page_body()`, con independencia de la
  plantilla o el tema activos.
- Elimina `TemplateSource` en `Context`: la plantilla pasa a ser un
  `TemplateRef` fijo, sin resolución por tema (ese mecanismo nunca llegó
  a implementarse).
- La personalización por tema es por captura (`handle_component()` +
  `downcast_ref()`), no por sustituir qué constante se resuelve.
- Corrige referencias obsoletas a `DefaultRegions` por `CoreRegion`.
- Sustituye `tests/theme_template.rs` (API anterior) por
  `tests/component_template.rs`, que cubre el patrón de captura con el
  API nuevo.
2026-07-26 09:51:27 +02:00
e7f2563967 (htmx): Añade soporte HTMX a tablas ordenables
- Nuevo `SortDir` en `pagetop::html` para representar direcciones de
  orden (asc/desc) y calcular la siguiente al pulsar una cabecera.
- `hx_table::sort_link()` construye el enlace de ordenación con los
  cuatro atributos `hx-*` fijos, reutilizable en cualquier tabla.
- `HtmxResponse` usa `RoutePath` en `location`/`push_url`/`replace_url`/
  `redirect` para preservar "lang"; `location_json()` se separa de
  `location()` para el caso de configuración JSON personalizada.
- Añade el módulo `prelude` y una batería de tests para hx, hx_table,
  request, response y extension.
2026-07-23 07:21:27 +02:00
55159f6d8f 🌐 (tests): Traduce comentarios de tests a inglés 2026-07-19 23:34:38 +02:00
af548b03c9 (core): Añade Route, RoutePath y Waypoint
`Route` resuelve URLs sensibles al `Context`/idioma en propiedades de
componentes; `RoutePath` (renombrado desde html/route.rs) es el valor
concreto de ruta + query. `Waypoint` transporta la URL de retorno entre
pantallas de listado/alta/edición vía query string.

Ajusta `Context::route()`, `Redirect` y los componentes que aceptan
rutas para integrarse con el nuevo tipo `Route`.
2026-07-19 22:16:21 +02:00
6f82da220b 🐛 (web): HttpRequest clona ahora las extensiones
Documenta el nuevo comportamiento y aprovecha para pulir varios
comentarios y restringir visibilidad de símbolos internos.
2026-07-17 00:54:35 +02:00
370bc8ee47 ♻️ (seaorm): Renombra el re-export api a sea_orm
Amplía también los tipos reexportados (Condition, DbBackend, NotSet,
Order, Set, TransactionError, Unchanged) y habilita el mismo
re-export en migration.rs.
2026-07-14 18:37:43 +02:00
e6b4661f21 (web): Añade Form, RawForm, Request y el módulo middleware
Reexporta los extractores axum::extract::{Form, RawForm, Request} y
el módulo axum::middleware (from_fn, Next) desde pagetop::web.
2026-07-14 18:37:36 +02:00
5a8267032e 📝 Retoques menores en documentación
Quita las itálicas superfluas en "handlers" en pagetop-htmx y en el
doc de módulo de web.rs.
2026-07-14 18:37:10 +02:00
f6f78fddbe 🐛 (aliner): Corrige DefaultRegions en el pie 2026-07-14 18:31:16 +02:00
7a3419415e (datetime): Reexporta chrono::Duration 2026-07-14 18:26:52 +02:00
82e64238bd 🔥 (config): Elimina la opción app.description 2026-07-14 18:20:01 +02:00
eb3157c4a4 📝 Retoques menores en documentación 2026-07-14 07:27:51 +02:00
30151b6254 ♻️ (macros): Deja main/test sin depender de Tokio
Antes delegaban directamente en `#[tokio::main]`/`#[tokio::test]`; ahora
construyen su propio runtime vía `pagetop::util::build_runtime()`, con
el mismo comportamiento (`Builder::new_multi_thread().enable_all()`).
Las extensiones que usan estas macros ya no necesitan declarar Tokio
como dependencia directa en su `Cargo.toml`.
2026-07-14 00:44:21 +02:00
24bd13414c Añade gestión de errores catastróficos
- Los errores controlados (403, 404, fatales) se renderizan con el tema
  activo; un `panic!` no controlado se intercepta con un HTML mínimo y
  autónomo, sin depender del tema ni de los componentes.
- Corrige además que `Context::template()` no seguía los cambios de tema
  hechos con `with_theme()` después de crear la página.
- Renombra `DefaultRegion(s)`/`DefaultTemplate(s)`, añade
  `Theme::admin_template()` y `Page::admin()`, y documenta la creación
  de temas e `InRegion` en `core/theme.rs`.
2026-07-13 00:38:11 +02:00
0e72d51276 📝 Quita cursivas de algunos anglicismos en docs 2026-07-10 19:33:26 +02:00
771f61bf29 ♻️ (bootsier): Mueve Container al core de PageTop
`Container` y `Kind` pasan a `pagetop::base::component` como componente
genérico reutilizable por cualquier tema. Bootsier conserva `Width` y
añade el *trait* `ContainerBootsier`, que guarda el ancho como valor
extra en `Props`.
2026-07-09 21:44:52 +02:00
654618aa68 (html): Añade declaración de estilos a PropsOp 2026-07-09 21:40:50 +02:00
87ad78778d ♻️ (bootsier): Mueve input/select/textarea a theme
Consolida los handlers de estos campos en la capa del tema. Además,
`with_floating_label()` usa un valor extra que lee en `setup()` para
forzar `multiple`/`rows` en 'select` y `textarea`.
2026-07-09 01:26:52 +02:00
bff7cf1b38 (html): Añade PropsOp::replace_classes()
Permite sustituir una o varias clases por otras nuevas en una sola
operación, preservando su posición. Adapta el tema Bootsier para usarla
en `Button` y elimina el handler duplicado sin referencias.
2026-07-09 01:12:45 +02:00
9e8cd77140 📝 Retoques de documentación en html y componentes 2026-07-09 00:08:04 +02:00
25713a8a13 ♻️ (html): Añade valores extra a Props
- Reordena campos, variantes y métodos para mayor consistencia interna.
- Añade `extra_or`, `extra_or_default` y `extra_or_else` a `Props`.
- Mejora la documentación y amplía los tests de integración.
2026-07-09 00:05:28 +02:00
a26aa4d30a 💄 (intro): Reserva espacio vertical para *badges* 2026-07-07 15:32:30 +02:00