Skip to content

feat(admin): users-management page with admin/agent role toggles#50

Merged
mpge merged 1 commit into
mainfrom
feat/admin-users-management-ui
May 18, 2026
Merged

feat(admin): users-management page with admin/agent role toggles#50
mpge merged 1 commit into
mainfrom
feat/admin-users-management-ui

Conversation

@mpge
Copy link
Copy Markdown
Member

@mpge mpge commented May 10, 2026

Summary

Ports the admin Users management feature from escalated-laravel#94 into the Django plugin so the shared Escalated/Admin/Users/Index Inertia page (in @escalated-dev/escalated@0.8.0) has feature parity.

  • GET /support/admin/users/ (escalated:admin_users_index) — paginated users list (20/page) with name+email+username icontains search, exposing is_admin / is_agent per row plus currentUserId.
  • PATCH /support/admin/users/<int:user_id>/role/ (escalated:admin_users_role) — toggle admin or agent. Promoting to admin also flags the user as an agent; revoking agent from an admin cascades to is_admin=false. Self-demote is blocked with a redirect-back so admins cannot lock themselves out of the panel they are using.

Deviations from Laravel reference

Django's auth.User has no first-class is_admin / is_agent columns, so this port maps them via the same gates the rest of escalated-django already uses (escalated.permissions):

  • is_admin <-> User.is_staff
  • is_agent <-> membership in at least one active Department

Promoting to agent attaches the user to the first active Department (creating a default Support department if none exist). Revoking agent removes the user from every department they belong to. Hosts that model roles differently can override the views the same way they would in Laravel.

Test plan

  • python -m pytest tests/integration/test_admin_users_views.py — 8 cases (list, non-admin forbidden, search filter, promote-to-admin, promote-to-agent-only, self-demote guard, admin->agent cascade, role-toggle forbidden)
  • Full suite: python -m pytest — 730 passed
  • python -m ruff check — clean

Port the admin User-management surface from escalated-laravel#94 so the
shared `Escalated/Admin/Users/Index` Inertia page works against the
Django host. Adds:

- GET /support/admin/users (`escalated:admin_users_index`) — paginated
  users list with name+email LIKE search, exposing is_admin / is_agent
  per row plus currentUserId.
- PATCH /support/admin/users/<int:user_id>/role
  (`escalated:admin_users_role`) — toggle admin or agent. Promoting to
  admin also marks agent; revoking agent from an admin cascades to
  is_admin=false. Self-demote is blocked with a redirect-back so admins
  cannot lock themselves out of the panel they are using.

Django has no first-class is_admin / is_agent columns, so the package
maps is_admin <-> User.is_staff and is_agent <-> membership in any
active Department. Hosts that model roles differently can override the
controller as usual.

Tested via pytest (8 cases covering list, forbidden, search, promote
admin, promote agent only, self-demote guard, agent->admin cascade,
role-forbidden).

Ref: escalated-dev/escalated-laravel#94
@mpge mpge merged commit bb894a2 into main May 18, 2026
9 of 10 checks passed
@mpge mpge deleted the feat/admin-users-management-ui branch May 18, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant