Improve how user roles are managed and displayed on the admin page

Introduce separation of direct and inherited roles in user profiles and API responses. Modify the admin UI to disable the "order receiver" toggle when a role is inherited, providing a clearer user experience. Update API endpoints and schemas to reflect these changes, alongside locale updates for translated strings.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 33aee19f-8f0f-4399-98e0-39fe09a87e1b
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/m92e9kU
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
riyadhafraa
2026-05-19 06:41:10 +00:00
parent f63a48fe1f
commit e00e015b8b
8 changed files with 145 additions and 27 deletions
@@ -218,6 +218,13 @@ export interface UserProfile {
avatarUrl?: string | null;
isActive: boolean;
roles: string[];
/** Roles assigned directly to the user (user_roles table only). The
`roles` field above is the effective set (direct + inherited via
group membership). The admin Users page uses the difference to
mark a role as "inherited from group X" and disables the toggle
so the admin doesn't try to remove a role that won't disappear.
*/
directRoles?: string[];
groups: GroupSummary[];
createdAt: string;
/** Dependent record counts. Populated only by the admin list endpoint
+10
View File
@@ -3291,6 +3291,16 @@ components:
type: array
items:
type: string
directRoles:
type: array
items:
type: string
description: |
Roles assigned directly to the user (user_roles table only). The
`roles` field above is the effective set (direct + inherited via
group membership). The admin Users page uses the difference to
mark a role as "inherited from group X" and disables the toggle
so the admin doesn't try to remove a role that won't disappear.
groups:
type: array
items:
+30
View File
@@ -1577,6 +1577,12 @@ export const ListUsersResponseItem = zod.object({
avatarUrl: zod.string().nullish(),
isActive: zod.boolean(),
roles: zod.array(zod.string()),
directRoles: zod
.array(zod.string())
.optional()
.describe(
"Roles assigned directly to the user (user_roles table only). The\n`roles` field above is the effective set (direct + inherited via\ngroup membership). The admin Users page uses the difference to\nmark a role as \"inherited from group X\" and disables the toggle\nso the admin doesn't try to remove a role that won't disappear.\n",
),
groups: zod.array(
zod.object({
id: zod.number(),
@@ -1649,6 +1655,12 @@ export const GetUserResponse = zod.object({
avatarUrl: zod.string().nullish(),
isActive: zod.boolean(),
roles: zod.array(zod.string()),
directRoles: zod
.array(zod.string())
.optional()
.describe(
"Roles assigned directly to the user (user_roles table only). The\n`roles` field above is the effective set (direct + inherited via\ngroup membership). The admin Users page uses the difference to\nmark a role as \"inherited from group X\" and disables the toggle\nso the admin doesn't try to remove a role that won't disappear.\n",
),
groups: zod.array(
zod.object({
id: zod.number(),
@@ -1709,6 +1721,12 @@ export const UpdateUserResponse = zod.object({
avatarUrl: zod.string().nullish(),
isActive: zod.boolean(),
roles: zod.array(zod.string()),
directRoles: zod
.array(zod.string())
.optional()
.describe(
"Roles assigned directly to the user (user_roles table only). The\n`roles` field above is the effective set (direct + inherited via\ngroup membership). The admin Users page uses the difference to\nmark a role as \"inherited from group X\" and disables the toggle\nso the admin doesn't try to remove a role that won't disappear.\n",
),
groups: zod.array(
zod.object({
id: zod.number(),
@@ -1822,6 +1840,12 @@ export const AddUserRoleResponse = zod.object({
avatarUrl: zod.string().nullish(),
isActive: zod.boolean(),
roles: zod.array(zod.string()),
directRoles: zod
.array(zod.string())
.optional()
.describe(
"Roles assigned directly to the user (user_roles table only). The\n`roles` field above is the effective set (direct + inherited via\ngroup membership). The admin Users page uses the difference to\nmark a role as \"inherited from group X\" and disables the toggle\nso the admin doesn't try to remove a role that won't disappear.\n",
),
groups: zod.array(
zod.object({
id: zod.number(),
@@ -1872,6 +1896,12 @@ export const RemoveUserRoleResponse = zod.object({
avatarUrl: zod.string().nullish(),
isActive: zod.boolean(),
roles: zod.array(zod.string()),
directRoles: zod
.array(zod.string())
.optional()
.describe(
"Roles assigned directly to the user (user_roles table only). The\n`roles` field above is the effective set (direct + inherited via\ngroup membership). The admin Users page uses the difference to\nmark a role as \"inherited from group X\" and disables the toggle\nso the admin doesn't try to remove a role that won't disappear.\n",
),
groups: zod.array(
zod.object({
id: zod.number(),