Añade acciones base y renderizado de componentes

- Añade acciones BeforeRender y AfterRender para ejecutar código
  personalizado antes y después de renderizar un componente.
- Introduce la acción PrepareRender para personalizar totalmente el
  renderizado de un componente.
- Se actualizan las definiciones de acciones para utilizar el nuevo
  "trait" ActionDispatcher.
- Se crea un nuevo trait ComponentTrait para definir componentes
  renderizables.
- Se implementan las estructuras Children y Child para gestionar
  componentes hijos dentro de un componente padre.
- Se añade OptionComponent para encapsular de forma segura componentes
  opcionales y poder usarlos en otros componentes.
This commit is contained in:
Manuel Cillero 2025-07-24 08:38:17 +02:00
parent f76a208520
commit 37df2ada75
28 changed files with 1102 additions and 147 deletions

View file

@ -1,9 +1,11 @@
use crate::core::action::add_action;
use crate::core::extension::ExtensionRef;
use crate::core::theme::all::THEMES;
use crate::{service, trace};
use crate::{/*global, include_files, include_files_service, */ service, trace};
use std::sync::{LazyLock, RwLock};
use parking_lot::RwLock;
use std::sync::LazyLock;
// EXTENSIONES *************************************************************************************
@ -27,11 +29,11 @@ pub fn register_extensions(root_extension: Option<ExtensionRef>) {
add_to_enabled(&mut enabled_list, extension);
}
/* Añade la página de bienvenida por defecto a la lista de extensiones habilitadas.
add_to_enabled(&mut enabled_list, &crate::base::extension::Welcome); */
// Guarda la lista final de extensiones habilitadas.
ENABLED_EXTENSIONS
.write()
.unwrap()
.append(&mut enabled_list);
ENABLED_EXTENSIONS.write().append(&mut enabled_list);
// Prepara una lista de extensiones deshabilitadas.
let mut dropped_list: Vec<ExtensionRef> = Vec::new();
@ -42,10 +44,7 @@ pub fn register_extensions(root_extension: Option<ExtensionRef>) {
}
// Guarda la lista final de extensiones deshabilitadas.
DROPPED_EXTENSIONS
.write()
.unwrap()
.append(&mut dropped_list);
DROPPED_EXTENSIONS.write().append(&mut dropped_list);
}
fn add_to_enabled(list: &mut Vec<ExtensionRef>, extension: ExtensionRef) {
@ -61,7 +60,7 @@ fn add_to_enabled(list: &mut Vec<ExtensionRef>, extension: ExtensionRef) {
// Comprueba si la extensión tiene un tema asociado que deba registrarse.
if let Some(theme) = extension.theme() {
let mut registered_themes = THEMES.write().unwrap();
let mut registered_themes = THEMES.write();
// Asegura que el tema no esté ya registrado para evitar duplicados.
if !registered_themes
.iter()
@ -84,7 +83,6 @@ fn add_to_dropped(list: &mut Vec<ExtensionRef>, extension: ExtensionRef) {
// Comprueba si la extensión está habilitada. Si es así, registra una advertencia.
if ENABLED_EXTENSIONS
.read()
.unwrap()
.iter()
.any(|e| e.type_id() == extension.type_id())
{
@ -109,7 +107,7 @@ fn add_to_dropped(list: &mut Vec<ExtensionRef>, extension: ExtensionRef) {
// REGISTRO DE LAS ACCIONES ************************************************************************
pub fn register_actions() {
for extension in ENABLED_EXTENSIONS.read().unwrap().iter() {
for extension in ENABLED_EXTENSIONS.read().iter() {
for a in extension.actions().into_iter() {
add_action(a);
}
@ -120,15 +118,20 @@ pub fn register_actions() {
pub fn initialize_extensions() {
trace::info!("Calling application bootstrap");
for extension in ENABLED_EXTENSIONS.read().unwrap().iter() {
for extension in ENABLED_EXTENSIONS.read().iter() {
extension.initialize();
}
}
// CONFIGURA LOS SERVICIOS *************************************************************************
//include_files!(assets);
pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
for extension in ENABLED_EXTENSIONS.read().unwrap().iter() {
for extension in ENABLED_EXTENSIONS.read().iter() {
extension.configure_service(scfg);
}
/*include_files_service!(
scfg, assets => "/", [&global::SETTINGS.dev.pagetop_project_dir, "static"]
);*/
}

View file

@ -2,7 +2,7 @@ use crate::core::action::ActionBox;
use crate::core::theme::ThemeRef;
use crate::core::AnyInfo;
use crate::locale::L10n;
use crate::{inject_actions, service};
use crate::{actions_boxed, service};
/// Representa una referencia a una extensión.
///
@ -77,7 +77,7 @@ pub trait ExtensionTrait: AnyInfo + Send + Sync {
/// [peso](crate::Weight), permitiendo personalizar el comportamiento de la aplicación en puntos
/// específicos.
fn actions(&self) -> Vec<ActionBox> {
inject_actions![]
actions_boxed![]
}
/// Inicializa la extensión durante la lógica de arranque de la aplicación.