Skip to content

feat(users): redesign the admin users page, keep custom roles on save - #214

Merged
nechodom merged 1 commit into
mainfrom
claude/redesign-user-settings-58603b
Oct 5, 2026
Merged

nechodom merged 1 commit into
mainfrom
claude/redesign-user-settings-58603b

Conversation

@nechodom

@nechodom nechodom commented Oct 5, 2026

Copy link
Copy Markdown
Owner

What

Redesign of /admin/users, plus a fix for a bug that silently dropped a user's custom role.

  • Each user is now an expandable row inside one grouped-flat panel. The summary row shows avatar, username + email, role, 2FA, status and last sign-in. Manage opens a full-width panel with three sections side by side: Role, Sign-in (lock/unlock; a locked account shows its reason) and Password. Delete user sits apart in a danger strip at the bottom.
  • Add user moved below the list as a collapsible group. It opens automatically when the list is empty. The role descriptions are now a legend instead of one run-on paragraph.
  • On screens under 900px the row metadata wraps into a compact line and the three sections stack.
  • WebUserSummary gains custom_role_id, filled by WebUserList through a new web_users::custom_role_assignments query.

Why

The old row crammed a role select, a lock form, a password reset and a delete button into the narrow Actions column, which was hard to read and easy to misclick.

The bug: a custom-role user's role column holds the operator sentinel. The dropdown therefore preselected "Operator", and one Save role click replaced the custom role with Operator without any warning. The page now preselects the custom role and shows its name in the list, marked "custom".

Operator-facing change?

  • No operator-facing change.
  • Operator-facing change — described below:
    • Admin users page redesigned: expandable per-user rows with Role / Sign-in / Password sections, and a collapsible "Add user".
    • Users with a custom role now show that role on the page and keep it when an admin saves the role form.

Test plan

  • cargo test -p hyperion-web -p hyperion-state -p hyperion-types passes.
  • cargo clippy -p hyperion-web -p hyperion-state -p hyperion-core --all-targets produces no warnings.
  • cargo fmt --all -- --check passes.
  • Checked by hand in the devpanel (tests/devserver.rs) on desktop and mobile widths, with a custom-role user and a locked user.
  • Added custom_role_assignments_lists_linked_users_only, a write-then-read-back test.

Anti-scope

  • The routes, the form fields and the confirm and CSRF wiring are unchanged; only the markup around them moved.
  • web_user_get still returns custom_role_id: None. Only the list view needs the field.
  • No per-user hosting access management here; that stays on each hosting's Access tab.

🤖 Generated with Claude Code

The users table crammed a role select + save, a lock form, a password
reset and a delete button into one row; "Actions" expanded them inside
the narrow right column. Each user is now an expandable row in one
grouped panel: the summary is the scan line (name, role, 2FA, status,
last sign-in), and "Manage" opens Role / Sign-in / Password side by
side with Delete split off at the bottom. Add user moved below the list
as a collapsible group with a role legend. Stacks on narrow screens.

Fixes a data-loss bug found on the way: a custom-role user's `role`
column holds the operator sentinel, so the dropdown preselected
"Operator" and one "Save role" silently dropped the custom role.
WebUserList now carries `custom_role_id` (serde default for older
agents) and the page preselects and shows the custom role.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nechodom
nechodom merged commit 09b222b into main Oct 5, 2026
1 check passed
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