{# Panel de usuarios + roles + audit. Contrato con el router `make_users_router`: mount_prefix → prefijo del router (ej: "/admin/users") catalog → dict {permission_key: human_label} Todos los endpoints son relativos a `mount_prefix`: GET {mount_prefix}/data → JSON users POST {mount_prefix}/invite → form invite POST {mount_prefix}/create → form crear con password PATCH {mount_prefix}/{user_id}/roles → JSON roles POST {mount_prefix}/{user_id}/password/reset DELETE {mount_prefix}/{user_id} GET {mount_prefix}/{user_id}/effective-permissions GET {mount_prefix}/roles POST {mount_prefix}/roles PATCH {mount_prefix}/roles/{slug}/permissions DELETE {mount_prefix}/roles/{slug} GET {mount_prefix}/audit La pagina carga los datos en JS via fetch para evitar acoplar el render server-side a un layout especifico del host. El host es responsable de incluir HTMX/fetch y de envolver este template con su propio layout (sidebar, header, etc.). #} {% from "dg/components/page_header.html" import page_header %} {% from "dg/components/button.html" import button %} {% set base = mount_prefix | default('/admin/users') %} {% call page_header(title="Usuarios", subtitle="Gestión de cuentas, roles y permisos") %} {{ button("Invitar", variant="primary", attrs="onclick=\"document.getElementById('dg-invite').showModal()\"") }} {{ button("Crear con contraseña", variant="ghost", attrs="onclick=\"document.getElementById('dg-create').showModal()\"") }} {% endcall %}
EmailRolesPermisos efectivos
Cargando…
{# ---------- Modales ---------- #}

Invitar usuario

Roles

Crear con contraseña

Roles

Editar roles

Roles

Permisos efectivos

Crear rol

Permisos