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
_uien 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>
🧩 menu_utils.py¶
normalize_menu: asegura que cada item tengatitle,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.