Saltar a contenido

Core UI Specifications

🎯 Propósito

core/ui centraliza la interfaz común de todos los submódulos:

  • Define un layout estándar con Navbar y Sidebar.
  • Evita duplicar _ui en cada submódulo.
  • Proporciona macros y utilidades para renderizar menús de forma consistente.
  • Permite personalizar qué Navbar y Sidebar se muestran en cada submódulo, sin duplicar lógica.

📂 Estructura

core/ui
 ┣ templates
 ┃ ┗ core_ui
 ┃   ┗ layout.html     # Plantilla base global con Tailwind, Navbar y Sidebar
 ┣ menu_utils.py       # Funciones normalize_menu, icon, etc.
 ┗ __init__.py

⚙️ Lógica de uso

1. Cada submódulo define sus menús

En interface/web/web_bp.py de un submódulo:

# === NAVBAR específico ===
CRM_CM_NAVBAR = [
    {"title":"Panel",   "href":"/customer_relationship/customer_management/base/", "icon":"layout-dashboard"},
    {"title":"Clientes","href":"/customer_relationship/customer_management/registry/customers", "icon":"users"},
    {"title":"Nuevo",   "href":"/customer_relationship/customer_management/registry/customers/new", "icon":"user-plus"},
    {"title":"Docs",    "href":"/docs/modules/customer_relationship/customer_management", "icon":"book-open"},
]

# === SIDEBAR específico ===
CRM_CM_SIDEBAR = [
    {"title":"Overview", "href":"/customer_relationship/customer_management/base/", "icon":"info"},
    {"title":"Clientes", "icon":"users", "children":[
        {"title":"Listado", "href":"/customer_relationship/customer_management/registry/customers", "icon":"list"},
        {"title":"Nuevo cliente", "href":"/customer_relationship/customer_management/registry/customers/new", "icon":"user-plus"},
    ], "expanded": True},
    {"title":"Catálogos", "icon":"folder-tree", "children":[
        {"title":"Tipos de documento", "href":"/customer_relationship/customer_management/base/", "icon":"id-card"},
        {"title":"Reglas de marketing", "href":"/customer_relationship/customer_management/base/", "icon":"megaphone"},
    ]},
    {"title":"Ayuda", "icon":"life-buoy", "children":[
        {"title":"Especificaciones", "href":"/docs/modules/customer_relationship/customer_management", "icon":"file-text"},
    ]},
]

2. Se inyectan en el contexto

from core.ui.menu_utils import normalize_menu

@bp.app_context_processor
def inject_nav_sidebar():
    path = request.path
    return dict(
        navbar_menu  = normalize_menu(CRM_CM_NAVBAR,  path),
        sidebar_menu = normalize_menu(CRM_CM_SIDEBAR, path),
        active_business_name = session.get("business_display_name"),
    )

3. El layout.html global los renderiza

{% from "core_ui/layout.html" import navbar, sidebar_tree %}

<!doctype html>
<html>
  <body>
    <header>
      {{ navbar(navbar_menu, request.path) }}
    </header>
    <aside>
      {{ sidebar_tree(sidebar_menu) }}
    </aside>
    <main>
      {% block content %}{% endblock %}
    </main>
  </body>
</html>

  • normalize_menu: asegura que cada item tenga title, href, icon, children, expanded, y marca __active.
  • _mark_active_and_expand: abre automáticamente los menús padres si algún hijo está activo.

📊 Flujo

flowchart TD
    A[Submódulo Blueprint] --> B[Define NAVBAR / SIDEBAR]
    B --> C[normalize_menu core/ui/menu_utils]
    C --> D[Inject en contexto Jinja]
    D --> E[layout.html core/ui/templates/core_ui]
    E --> F[Render Navbar + Sidebar con Tailwind + Lucide Icons]

✅ Beneficios

  • Un solo layout global para todos los módulos.
  • Cada submódulo solo define qué menús quiere mostrar.
  • Navbar y Sidebar se sincronizan con la ruta activa automáticamente.
  • Flexibilidad: se pueden anidar menús y plegar secciones.