♻️ Migra #[builder_fn] a #[builder_impl]

Sustituye las ~400 anotaciones `#[builder_fn]` método a método por un
único `#[builder_impl]` por `impl`/`trait`, en 74 ficheros de pagetop y
sus extensiones (admin, bootsier, menu, user).
This commit is contained in:
Manuel Cillero 2026-08-29 19:25:58 +02:00
parent c34dc02357
commit 1be3d88888
74 changed files with 104 additions and 394 deletions

View file

@ -68,16 +68,15 @@ impl Component for AdminFrame {
}
}
#[builder_impl]
impl AdminFrame {
/// Establece el título de la página.
#[builder_fn]
pub fn with_title(mut self, title: Lc) -> Self {
self.title = title;
self
}
/// Añade un componente hijo al contenido de la página.
#[builder_fn]
pub fn with_child(mut self, op: impl Into<ChildOp>) -> Self {
self.children.alter_child(op.into());
self

View file

@ -201,8 +201,10 @@ impl Component for ConfigForm {
}
}
#[builder_impl]
impl ConfigForm {
/// Crea el componente con el [`SettingsSchema`] dado.
#[builder_skip]
pub fn with_schema(schema: SettingsSchema) -> Self {
ConfigForm {
schema: Some(schema),
@ -210,7 +212,6 @@ impl ConfigForm {
}
}
#[builder_fn]
pub fn with_action_path(mut self, v: impl Into<Option<Route>>) -> Self {
if let Some(v) = v.into() {
self.action_path = Some(v);
@ -218,6 +219,7 @@ impl ConfigForm {
self
}
#[builder_skip]
pub(crate) fn with_saved(mut self, saved: bool, error: bool) -> Self {
self.saved = saved;
self.error = error;

View file

@ -3,7 +3,7 @@
//! Proporciona una API async para leer y escribir valores JSON en la tabla `settings`.
use pagetop::datetime::Utc;
use pagetop::{Getters, builder_fn};
use pagetop::{Getters, builder_impl};
use pagetop_seaorm::db::{
ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, QueryFilter, dbconn,
};
@ -128,6 +128,7 @@ pub struct SettingField {
default_value: Option<String>,
}
#[builder_impl]
impl SettingField {
/// Crea un campo de texto con nombre y etiqueta.
pub fn text(name: impl Into<String>, label: impl Into<String>) -> Self {
@ -185,21 +186,18 @@ impl SettingField {
}
/// Establece si el campo es obligatorio.
#[builder_fn]
pub fn with_required(mut self, required: bool) -> Self {
self.required = required;
self
}
/// Añade texto de ayuda bajo el campo.
#[builder_fn]
pub fn with_help(mut self, text: impl Into<String>) -> Self {
self.help_text = Some(text.into());
self
}
/// Establece el valor por defecto (como valor JSON serializado).
#[builder_fn]
pub fn with_default<T: Serialize>(mut self, value: &T) -> Self {
self.default_value = serde_json::to_string(value).ok();
self
@ -215,6 +213,7 @@ pub struct SettingsSchema {
fields: Vec<SettingField>,
}
#[builder_impl]
impl SettingsSchema {
/// Crea un nuevo esquema vacío para el `scope` dado.
pub fn new(scope: impl Into<String>) -> Self {
@ -225,7 +224,6 @@ impl SettingsSchema {
}
/// Añade un campo al esquema.
#[builder_fn]
pub fn with_field(mut self, field: SettingField) -> Self {
self.fields.push(field);
self

View file

@ -18,15 +18,15 @@ const EXTRA_COLOR: &str = "bootsier.badge.color";
///
/// let badge = bs::Badge::labeled(Lc::n("Beta")).with_color(BootsierColors::Dark);
/// ```
#[builder_impl]
pub trait BadgeBootsier {
/// Fuerza un color de la paleta de Bootsier, ignorando el que le correspondería a la `Intent`
/// del badge. `None` restablece el comportamiento por defecto (color derivado de la `Intent`).
#[builder_fn]
fn with_color(self, color: impl Into<Option<BootsierColors>>) -> Self;
}
#[builder_impl]
impl BadgeBootsier for Badge {
#[builder_fn]
fn with_color(mut self, color: impl Into<Option<BootsierColors>>) -> Self {
match color.into() {
Some(color) => self.alter_prop(PropsOp::set_extra(EXTRA_COLOR, color)),

View file

@ -33,36 +33,32 @@ const EXTRA_COLOR: &str = "bootsier.button.color";
/// .with_style(button::Style::Solid(Intent::Neutral))
/// .with_color(BootsierColors::Light);
/// ```
#[builder_impl]
pub trait ButtonBootsier {
/// Marca el botón como activo (`.active`, `aria-pressed="true"`).
#[builder_fn]
fn with_active(self, active: bool) -> Self;
/// Expande el botón al ancho completo de su contenedor (`w-100`).
#[builder_fn]
fn with_full_width(self, full_width: bool) -> Self;
/// Fuerza un color de la paleta de Bootsier, ignorando el que le correspondería a la `Intent`
/// del botón. `None` restablece el comportamiento por defecto (color derivado de la `Intent`).
/// Sin efecto si el estilo del botón es [`Style::Link`] o [`Style::None`].
#[builder_fn]
fn with_color(self, color: impl Into<Option<BootsierColors>>) -> Self;
}
#[builder_impl]
impl ButtonBootsier for Button {
#[builder_fn]
fn with_active(mut self, active: bool) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_ACTIVE, active));
self
}
#[builder_fn]
fn with_full_width(mut self, full_width: bool) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_FULL_WIDTH, full_width));
self
}
#[builder_fn]
fn with_color(mut self, color: impl Into<Option<BootsierColors>>) -> Self {
match color.into() {
Some(color) => self.alter_prop(PropsOp::set_extra(EXTRA_COLOR, color)),

View file

@ -32,18 +32,18 @@ const EXTRA_WIDTH: &str = "bootsier.container.width";
/// .with_prop(PropsOp::add_classes(class::Border::with(ScaleSize::One)))
/// .with_prop(PropsOp::add_classes(class::Rounded::new()));
/// ```
#[builder_impl]
pub trait ContainerBootsier {
/// Establece el comportamiento del ancho para el contenedor.
///
/// Determina si el contenedor aplica los anchos máximos predefinidos para cada punto de
/// ruptura, o si ocupa siempre el 100% del ancho disponible, o lo hace hasta un ancho máximo
/// explícito. Ver [`Width`] para las variantes disponibles.
#[builder_fn]
fn with_width(self, width: Width) -> Self;
}
#[builder_impl]
impl ContainerBootsier for Container {
#[builder_fn]
fn with_width(mut self, width: Width) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_WIDTH, width));
self

View file

@ -44,54 +44,46 @@ const EXTRA_MENU_POSITION: &str = "bootsier.dropdown.menu_position";
/// .with_item(bs::dropdown::Item::header(Lc::n("User session")))
/// .with_item(bs::dropdown::Item::button(Lc::n("Sign out")));
/// ```
#[builder_impl]
pub trait DropdownBootsier {
/// Indica si el botón del menú está integrado en un grupo de botones.
#[builder_fn]
fn with_button_grouped(self, grouped: bool) -> Self;
/// Establece la política de cierre automático del menú desplegable.
#[builder_fn]
fn with_auto_close(self, auto_close: AutoClose) -> Self;
/// Establece la dirección de despliegue del menú.
#[builder_fn]
fn with_direction(self, direction: Direction) -> Self;
/// Configura la alineación horizontal (con posible comportamiento *responsive* adicional).
#[builder_fn]
fn with_menu_align(self, align: MenuAlign) -> Self;
/// Configura la posición del menú.
#[builder_fn]
fn with_menu_position(self, position: MenuPosition) -> Self;
}
#[builder_impl]
impl DropdownBootsier for Dropdown {
#[builder_fn]
fn with_button_grouped(mut self, grouped: bool) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_BUTTON_GROUPED, grouped));
self
}
#[builder_fn]
fn with_auto_close(mut self, auto_close: AutoClose) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_AUTO_CLOSE, auto_close));
self
}
#[builder_fn]
fn with_direction(mut self, direction: Direction) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_DIRECTION, direction));
self
}
#[builder_fn]
fn with_menu_align(mut self, align: MenuAlign) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_MENU_ALIGN, align));
self
}
#[builder_fn]
fn with_menu_position(mut self, position: MenuPosition) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_MENU_POSITION, position));
self

View file

@ -22,18 +22,18 @@ const EXTRA_FLOATING_LABEL: &str = "bootsier.form.input.floating_label";
/// .with_placeholder(Lc::n("Enter your name"))
/// .with_floating_label(true);
/// ```
#[builder_impl]
pub trait InputBootsier {
/// Establece si la etiqueta se muestra flotante sobre el campo.
///
/// Cuando está activo, la etiqueta se superpone al campo y asciende al enfocarlo o cuando tiene
/// contenido. Requiere que el campo tenga un atributo `placeholder` definido; si no se
/// especifica, se fuerza `placeholder=""` antes del renderizado.
#[builder_fn]
fn with_floating_label(self, floating: bool) -> Self;
}
#[builder_impl]
impl InputBootsier for Field {
#[builder_fn]
fn with_floating_label(mut self, floating: bool) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_FLOATING_LABEL, floating));
self

View file

@ -24,6 +24,7 @@ const EXTRA_FLOATING_LABEL: &str = "bootsier.form.select.floating_label";
/// .with_item(bs::form::select::Item::new("es", Lc::n("Spanish")))
/// .with_item(bs::form::select::Item::new("en", Lc::n("English")));
/// ```
#[builder_impl]
pub trait SelectBootsier {
/// Establece si la etiqueta se muestra flotante sobre el campo.
///
@ -33,12 +34,11 @@ pub trait SelectBootsier {
/// Si se usa la etiqueta flotante, se anulan los valores establecidos con
/// [`with_multiple()`](form::select::Field::with_multiple) y
/// [`with_rows()`](form::select::Field::with_rows) antes del renderizado.
#[builder_fn]
fn with_floating_label(self, floating: bool) -> Self;
}
#[builder_impl]
impl SelectBootsier for Field {
#[builder_fn]
fn with_floating_label(mut self, floating: bool) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_FLOATING_LABEL, floating));
self

View file

@ -22,6 +22,7 @@ const EXTRA_FLOATING_LABEL: &str = "bootsier.form.textarea.floating_label";
/// .with_placeholder(Lc::n("Write here..."))
/// .with_floating_label(true);
/// ```
#[builder_impl]
pub trait TextareaBootsier {
/// Establece si la etiqueta se muestra flotante sobre el campo.
///
@ -31,12 +32,11 @@ pub trait TextareaBootsier {
///
/// Si se usa la etiqueta flotante, se anula el valor establecido con
/// [`with_rows()`](form::Textarea::with_rows) antes del renderizado.
#[builder_fn]
fn with_floating_label(self, floating: bool) -> Self;
}
#[builder_impl]
impl TextareaBootsier for Textarea {
#[builder_fn]
fn with_floating_label(mut self, floating: bool) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_FLOATING_LABEL, floating));
self

View file

@ -78,6 +78,7 @@ impl Component for Icon {
}
}
#[builder_impl]
impl Icon {
pub fn font() -> Self {
Self::default().with_icon_kind(IconKind::Font(FontSize::default()))
@ -104,26 +105,22 @@ impl Icon {
// **< Icon BUILDER >***************************************************************************
/// Establece el identificador único del componente; igual a `with_prop(PropsOp::set_id(id))`.
#[builder_fn]
pub fn with_id(mut self, id: impl Into<CowStr>) -> Self {
self.props.alter_id(id);
self
}
/// Modifica identificador, clases CSS, atributos HTML o valores extra del componente.
#[builder_fn]
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
#[builder_fn]
pub fn with_icon_kind(mut self, icon_kind: IconKind) -> Self {
self.icon_kind = icon_kind;
self
}
#[builder_fn]
pub fn with_aria_label(mut self, label: Lc) -> Self {
self.aria_label.alter_value(label);
self

View file

@ -46,14 +46,14 @@ pub(crate) const EXTRA_IN_NAVBAR: &str = "bootsier.nav.in_navbar";
/// ))
/// .with_item(bs::nav::Item::link_disabled(Lc::n("Disabled"), "#"));
/// ```
#[builder_impl]
pub trait NavBootsier {
/// Cambia el estilo del menú (*Tabs*, *Pills*, *Underline* o *Default*).
#[builder_fn]
fn with_kind(self, kind: Kind) -> Self;
}
#[builder_impl]
impl NavBootsier for Nav {
#[builder_fn]
fn with_kind(mut self, kind: Kind) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_KIND, kind));
self

View file

@ -140,6 +140,7 @@ const EXTRA_EXPAND: &str = "bootsier.navbar.expand";
/// .with_item(bs::nav::Item::link(Lc::n("Stock"), "/stock"))
/// ));
/// ```
#[builder_impl]
pub trait NavbarBootsier {
/// Crea una barra de navegación cuyo contenido se muestra en un **offcanvas**.
fn offcanvas(oc: bs::Offcanvas) -> Self;
@ -151,14 +152,13 @@ pub trait NavbarBootsier {
fn offcanvas_brand_right(brand: Brand, oc: bs::Offcanvas) -> Self;
/// Define a partir de qué punto de ruptura la barra de navegación deja de colapsar.
#[builder_fn]
fn with_expand(self, bp: BreakPoint) -> Self;
/// Define dónde se mostrará la barra de navegación dentro del documento.
#[builder_fn]
fn with_position(self, position: bs::navbar::Position) -> Self;
}
#[builder_impl]
impl NavbarBootsier for Navbar {
fn offcanvas(oc: bs::Offcanvas) -> Self {
let mut navbar = Self::new();
@ -187,13 +187,11 @@ impl NavbarBootsier for Navbar {
navbar
}
#[builder_fn]
fn with_expand(mut self, bp: BreakPoint) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_EXPAND, bp));
self
}
#[builder_fn]
fn with_position(mut self, position: bs::navbar::Position) -> Self {
self.alter_prop(PropsOp::set_extra(EXTRA_POSITION, position));
self

View file

@ -90,25 +90,23 @@ impl Component for Offcanvas {
}
}
#[builder_impl]
impl Offcanvas {
// **< Offcanvas BUILDER >**********************************************************************
/// Establece el identificador único del componente; igual a `with_prop(PropsOp::set_id(id))`.
#[builder_fn]
pub fn with_id(mut self, id: impl Into<CowStr>) -> Self {
self.props.alter_id(id);
self
}
/// Modifica identificador, clases CSS, atributos HTML o valores extra del componente.
#[builder_fn]
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
/// Establece el título del encabezado.
#[builder_fn]
pub fn with_title(mut self, title: Lc) -> Self {
self.title = title;
self
@ -123,7 +121,6 @@ impl Offcanvas {
/// Por ejemplo, con `BreakPoint::Lg`, será *offcanvas* en móviles y tabletas, y visible
/// directamente en pantallas grandes. Por defecto usa `BreakPoint::None` para que sea
/// *offcanvas* siempre.
#[builder_fn]
pub fn with_breakpoint(mut self, bp: BreakPoint) -> Self {
self.breakpoint = bp;
self
@ -131,28 +128,24 @@ impl Offcanvas {
/// Ajusta la capa de fondo del panel para definir su comportamiento al hacer clic fuera del
/// panel.
#[builder_fn]
pub fn with_backdrop(mut self, backdrop: bs::offcanvas::Backdrop) -> Self {
self.backdrop = backdrop;
self
}
/// Permite o bloquea el desplazamiento de la página principal mientras el panel está abierto.
#[builder_fn]
pub fn with_body_scroll(mut self, scrolling: bs::offcanvas::BodyScroll) -> Self {
self.body_scroll = scrolling;
self
}
/// Indica desde qué borde de la ventana entra y se ancla el panel.
#[builder_fn]
pub fn with_placement(mut self, placement: bs::offcanvas::Placement) -> Self {
self.placement = placement;
self
}
/// Fija el estado inicial del panel (oculto o visible al cargar).
#[builder_fn]
pub fn with_visibility(mut self, visibility: bs::offcanvas::Visibility) -> Self {
self.visibility = visibility;
self
@ -160,7 +153,6 @@ impl Offcanvas {
/// Añade un nuevo componente al panel o modifica la lista de componentes (`children`) con una
/// operación [`ChildOp`].
#[builder_fn]
pub fn with_child(mut self, op: impl Into<ChildOp>) -> Self {
self.children.alter_child(op.into());
self

View file

@ -65,6 +65,7 @@ impl Component for Item {
}
}
#[builder_impl]
impl Item {
/// Crea un ítem de navegación con etiqueta, ruta e icono.
///
@ -82,21 +83,18 @@ impl Item {
// **< Item BUILDER >***************************************************************************
/// Establece el texto localizable del ítem.
#[builder_fn]
pub fn with_label(mut self, label: Lc) -> Self {
self.label = label;
self
}
/// Establece la ruta de destino del ítem.
#[builder_fn]
pub fn with_route(mut self, route: impl Into<Option<Route>>) -> Self {
self.route = route.into();
self
}
/// Establece el nombre del icono de Bootstrap Icons (sin el prefijo `bi-`).
#[builder_fn]
pub fn with_icon(mut self, icon: impl Into<CowStr>) -> Self {
self.icon = icon.into();
self

View file

@ -40,6 +40,7 @@ impl Component for Section {
}
}
#[builder_impl]
impl Section {
/// Crea un encabezado de sección con el título indicado.
pub fn titled(title: Lc) -> Self {
@ -49,7 +50,6 @@ impl Section {
// **< Section BUILDER >************************************************************************
/// Establece el título localizable de la sección.
#[builder_fn]
pub fn with_title(mut self, title: Lc) -> Self {
self.title = title;
self

View file

@ -107,6 +107,7 @@ impl Component for MenuBlock {
}
}
#[builder_impl]
impl MenuBlock {
/// Crea un `MenuBlock` para el menú con el `machine_name` dado.
pub fn with(menu_name: impl Into<String>) -> Self {
@ -115,7 +116,6 @@ impl MenuBlock {
block
}
#[builder_fn]
pub fn with_show_title(mut self, v: impl Into<Option<bool>>) -> Self {
if let Some(v) = v.into() {
self.show_title = v;
@ -125,13 +125,11 @@ impl MenuBlock {
/// Establece la profundidad máxima de nodos a incluir. El efectivo nunca supera `2`, por muy
/// alto que sea el valor indicado (ver "Limitaciones conocidas" en [`MenuBlock`]).
#[builder_fn]
pub fn with_max_depth(mut self, v: impl Into<Option<u8>>) -> Self {
self.max_depth = v.into();
self
}
#[builder_fn]
pub fn with_include_disabled(mut self, v: impl Into<Option<bool>>) -> Self {
if let Some(v) = v.into() {
self.include_disabled = v;
@ -139,7 +137,6 @@ impl MenuBlock {
self
}
#[builder_fn]
pub fn with_hide_when_empty(mut self, v: impl Into<Option<bool>>) -> Self {
if let Some(v) = v.into() {
self.hide_when_empty = v;

View file

@ -73,6 +73,7 @@ impl Component for MenuBreadcrumb {
}
}
#[builder_impl]
impl MenuBreadcrumb {
/// Crea un `MenuBreadcrumb` para el menú con el `machine_name` dado.
pub fn with(menu_name: impl Into<String>) -> Self {
@ -81,7 +82,6 @@ impl MenuBreadcrumb {
bc
}
#[builder_fn]
pub fn with_include_current(mut self, v: impl Into<Option<bool>>) -> Self {
if let Some(v) = v.into() {
self.include_current = v;

View file

@ -43,22 +43,20 @@ impl Component for AdminPasswordForm {
}
}
#[builder_impl]
impl AdminPasswordForm {
// **< AdminPasswordForm BUILDER >**************************************************************
#[builder_fn]
pub(crate) fn with_user_id(mut self, user_id: i32) -> Self {
self.user_id = user_id;
self
}
#[builder_fn]
pub(crate) fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self
}
#[builder_fn]
pub(crate) fn with_waypoint(mut self, waypoint: impl Into<Waypoint>) -> Self {
self.waypoint = waypoint.into();
self

View file

@ -98,52 +98,45 @@ impl Component for RoleForm {
}
}
#[builder_impl]
impl RoleForm {
// **< RoleForm BUILDER >***********************************************************************
#[builder_fn]
pub(crate) fn with_mode(mut self, mode: RoleFormMode) -> Self {
self.mode = mode;
self
}
#[builder_fn]
pub(crate) fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self
}
#[builder_fn]
pub(crate) fn with_role_id(mut self, role_id: impl Into<Option<i32>>) -> Self {
self.role_id = role_id.into();
self
}
#[builder_fn]
pub(crate) fn with_waypoint(mut self, waypoint: impl Into<Waypoint>) -> Self {
self.waypoint = waypoint.into();
self
}
#[builder_fn]
pub(crate) fn with_machine_name(mut self, machine_name: impl Into<String>) -> Self {
self.machine_name = machine_name.into();
self
}
#[builder_fn]
pub(crate) fn with_label(mut self, label: impl Into<String>) -> Self {
self.label = label.into();
self
}
#[builder_fn]
pub(crate) fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = description.into();
self
}
#[builder_fn]
pub(crate) fn with_weight(mut self, weight: i32) -> Self {
self.weight = weight;
self

View file

@ -61,28 +61,25 @@ impl Component for RolePermissionsForm {
}
}
#[builder_impl]
impl RolePermissionsForm {
// **< RolePermissionsForm BUILDER >************************************************************
#[builder_fn]
pub(crate) fn with_role_id(mut self, role_id: i32) -> Self {
self.role_id = role_id;
self
}
#[builder_fn]
pub(crate) fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self
}
#[builder_fn]
pub(crate) fn with_groups(mut self, groups: PermissionGroups) -> Self {
self.groups = groups;
self
}
#[builder_fn]
pub(crate) fn with_waypoint(mut self, waypoint: impl Into<Waypoint>) -> Self {
self.waypoint = waypoint.into();
self

View file

@ -128,52 +128,45 @@ impl Component for RoleTable {
}
}
#[builder_impl]
impl RoleTable {
// **< RoleTable BUILDER >**********************************************************************
#[builder_fn]
pub(crate) fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
#[builder_fn]
pub(crate) fn with_items(mut self, items: Vec<RoleListItem>) -> Self {
self.items = items;
self
}
#[builder_fn]
pub(crate) fn with_message(mut self, message: impl Into<Option<Lc>>) -> Self {
self.message = message.into();
self
}
#[builder_fn]
pub(crate) fn with_sort(mut self, sort: RoleSortField) -> Self {
self.sort = sort;
self
}
#[builder_fn]
pub(crate) fn with_dir(mut self, dir: SortDir) -> Self {
self.dir = dir;
self
}
#[builder_fn]
pub(crate) fn with_page(mut self, page: u64) -> Self {
self.page = page;
self
}
#[builder_fn]
pub(crate) fn with_per_page(mut self, per_page: u64) -> Self {
self.per_page = per_page;
self
}
#[builder_fn]
pub(crate) fn with_total(mut self, total: u64) -> Self {
self.total = total;
self

View file

@ -121,76 +121,65 @@ impl Component for UserForm {
}
}
#[builder_impl]
impl UserForm {
// **< UserForm BUILDER >***********************************************************************
#[builder_fn]
pub(crate) fn with_mode(mut self, mode: UserFormMode) -> Self {
self.mode = mode;
self
}
#[builder_fn]
pub(crate) fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self
}
#[builder_fn]
pub(crate) fn with_user_id(mut self, user_id: impl Into<Option<i32>>) -> Self {
self.user_id = user_id.into();
self
}
#[builder_fn]
pub(crate) fn with_waypoint(mut self, waypoint: impl Into<Waypoint>) -> Self {
self.waypoint = waypoint.into();
self
}
#[builder_fn]
pub(crate) fn with_username(mut self, username: impl Into<String>) -> Self {
self.username = username.into();
self
}
#[builder_fn]
pub(crate) fn with_email(mut self, email: impl Into<String>) -> Self {
self.email = email.into();
self
}
#[builder_fn]
pub(crate) fn with_display_name(mut self, display_name: impl Into<String>) -> Self {
self.display_name = display_name.into();
self
}
#[builder_fn]
pub(crate) fn with_language(mut self, language: impl Into<String>) -> Self {
self.language = language.into();
self
}
#[builder_fn]
pub(crate) fn with_timezone(mut self, timezone: impl Into<String>) -> Self {
self.timezone = timezone.into();
self
}
#[builder_fn]
pub(crate) fn with_roles(mut self, roles: Vec<(i32, String, bool)>) -> Self {
self.roles = roles;
self
}
#[builder_fn]
pub(crate) fn with_allow_admin_field(mut self, allow_admin_field: bool) -> Self {
self.allow_admin_field = allow_admin_field;
self
}
#[builder_fn]
pub(crate) fn with_is_admin(mut self, is_admin: bool) -> Self {
self.is_admin = is_admin;
self

View file

@ -43,28 +43,25 @@ impl Component for UserRolesForm {
}
}
#[builder_impl]
impl UserRolesForm {
// **< UserRolesForm BUILDER >******************************************************************
#[builder_fn]
pub(crate) fn with_user_id(mut self, user_id: i32) -> Self {
self.user_id = user_id;
self
}
#[builder_fn]
pub(crate) fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self
}
#[builder_fn]
pub(crate) fn with_roles(mut self, roles: Vec<(i32, String, bool)>) -> Self {
self.roles = roles;
self
}
#[builder_fn]
pub(crate) fn with_waypoint(mut self, waypoint: impl Into<Waypoint>) -> Self {
self.waypoint = waypoint.into();
self

View file

@ -100,52 +100,45 @@ impl Component for UserTable {
}
}
#[builder_impl]
impl UserTable {
// **< UserTable BUILDER >**********************************************************************
#[builder_fn]
pub(crate) fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
#[builder_fn]
pub(crate) fn with_items(mut self, items: Vec<UserListItem>) -> Self {
self.items = items;
self
}
#[builder_fn]
pub(crate) fn with_sort(mut self, sort: UserSortField) -> Self {
self.sort = sort;
self
}
#[builder_fn]
pub(crate) fn with_dir(mut self, dir: SortDir) -> Self {
self.dir = dir;
self
}
#[builder_fn]
pub(crate) fn with_query(mut self, query: impl Into<Option<String>>) -> Self {
self.query = query.into();
self
}
#[builder_fn]
pub(crate) fn with_page(mut self, page: u64) -> Self {
self.page = page;
self
}
#[builder_fn]
pub(crate) fn with_per_page(mut self, per_page: u64) -> Self {
self.per_page = per_page;
self
}
#[builder_fn]
pub(crate) fn with_total(mut self, total: u64) -> Self {
self.total = total;
self

View file

@ -97,14 +97,13 @@ fn links(allow_registration: bool) -> Html {
})
}
#[builder_impl]
impl LoginForm {
#[builder_fn]
pub fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self
}
#[builder_fn]
pub fn with_waypoint(mut self, waypoint: impl Into<Waypoint>) -> Self {
self.waypoint = waypoint.into();
self

View file

@ -48,18 +48,17 @@ impl Component for PasswordConfirm {
}
}
#[builder_impl]
impl PasswordConfirm {
// **< PasswordConfirm BUILDER >********************************************************************
/// Establece la etiqueta del campo de contraseña (por defecto, "field-password").
#[builder_fn]
pub(crate) fn with_password_label(mut self, label: Lc) -> Self {
self.password_label = label;
self
}
/// Establece la etiqueta del campo de confirmación (por defecto, "field-confirm-password").
#[builder_fn]
pub(crate) fn with_confirm_label(mut self, label: Lc) -> Self {
self.confirm_label = label;
self

View file

@ -44,8 +44,8 @@ impl Component for PasswordResetConfirmForm {
}
}
#[builder_impl]
impl PasswordResetConfirmForm {
#[builder_fn]
pub fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self

View file

@ -49,8 +49,8 @@ fn back_to_login() -> Html {
})
}
#[builder_impl]
impl PasswordResetForm {
#[builder_fn]
pub fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self

View file

@ -45,8 +45,8 @@ impl Component for RegisterForm {
}
}
#[builder_impl]
impl RegisterForm {
#[builder_fn]
pub fn with_error(mut self, error: impl Into<Option<Lc>>) -> Self {
self.error = error.into();
self