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
+40 -14
View File
@@ -4355,20 +4355,46 @@ function UsersPanel({
>
<KeyRound size={14} />
</button>
<label className="flex items-center gap-1 text-[10px] text-muted-foreground select-none">
<span className="hidden lg:inline">{t("admin.orderReceiverRole")}</span>
<Switch
checked={u.roles?.includes("order_receiver") ?? false}
onCheckedChange={(v) => {
const opts = {
onSuccess: invalidateUsers,
onError: () => toast({ title: t("common.error"), variant: "destructive" }),
};
if (v) addUserRole.mutate({ id: u.id, data: { roleName: "order_receiver" } }, opts);
else removeUserRole.mutate({ id: u.id, roleName: "order_receiver" }, opts);
}}
/>
</label>
{(() => {
// The Switch toggles the DIRECT user_roles row only. If
// the role is inherited via a group (present in `roles`
// but not in `directRoles`), removing the direct row is a
// no-op and the Switch would flip back on after refetch.
// Disable it and show which group grants the role so the
// admin edits group membership instead.
const hasEffective = u.roles?.includes("order_receiver") ?? false;
const hasDirect = u.directRoles?.includes("order_receiver") ?? false;
const isInherited = hasEffective && !hasDirect;
return (
<label
className="flex items-center gap-1 text-[10px] text-muted-foreground select-none"
title={isInherited ? t("admin.roleInheritedFromGroup") : undefined}
>
<span className="hidden lg:inline">{t("admin.orderReceiverRole")}</span>
<Switch
checked={hasEffective}
disabled={isInherited}
onCheckedChange={(v) => {
const opts = {
onSuccess: invalidateUsers,
onError: () =>
toast({ title: t("common.error"), variant: "destructive" }),
};
if (v)
addUserRole.mutate(
{ id: u.id, data: { roleName: "order_receiver" } },
opts,
);
else
removeUserRole.mutate(
{ id: u.id, roleName: "order_receiver" },
opts,
);
}}
/>
</label>
);
})()}
{u.id !== currentUserId && (
<button
onClick={() => {