support multi role on create user and invites

This commit is contained in:
miloschwartz
2026-03-29 12:11:22 -07:00
parent ee6fb34906
commit 2828dee94c
16 changed files with 629 additions and 416 deletions

View File

@@ -12,13 +12,6 @@ import { Button } from "@app/components/ui/button";
import { ArrowRight, ArrowUpDown, Crown, MoreHorizontal } from "lucide-react";
import { UsersDataTable } from "@app/components/UsersDataTable";
import { useState, useEffect } from "react";
import {
Popover,
PopoverContent,
PopoverTrigger
} from "@app/components/ui/popover";
import { Badge, badgeVariants } from "@app/components/ui/badge";
import { cn } from "@app/lib/cn";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { useOrgContext } from "@app/hooks/useOrgContext";
import { toast } from "@app/hooks/useToast";
@@ -31,6 +24,7 @@ import { useEnvContext } from "@app/hooks/useEnvContext";
import { useUserContext } from "@app/hooks/useUserContext";
import { useTranslations } from "next-intl";
import IdpTypeBadge from "./IdpTypeBadge";
import UserRoleBadges from "./UserRoleBadges";
export type UserRow = {
id: string;
@@ -47,61 +41,6 @@ export type UserRow = {
isOwner: boolean;
};
const MAX_ROLE_BADGES = 3;
function UserRoleBadges({ roleLabels }: { roleLabels: string[] }) {
const visible = roleLabels.slice(0, MAX_ROLE_BADGES);
const overflow = roleLabels.slice(MAX_ROLE_BADGES);
return (
<div className="flex flex-wrap items-center gap-1">
{visible.map((label, i) => (
<Badge key={`${label}-${i}`} variant="secondary">
{label}
</Badge>
))}
{overflow.length > 0 && (
<OverflowRolesPopover labels={overflow} />
)}
</div>
);
}
function OverflowRolesPopover({ labels }: { labels: string[] }) {
const [open, setOpen] = useState(false);
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<button
type="button"
className={cn(
badgeVariants({ variant: "secondary" }),
"border-dashed"
)}
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
+{labels.length}
</button>
</PopoverTrigger>
<PopoverContent
align="start"
side="top"
className="w-auto max-w-xs p-2"
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
<ul className="space-y-1 text-sm">
{labels.map((label, i) => (
<li key={`${label}-${i}`}>{label}</li>
))}
</ul>
</PopoverContent>
</Popover>
);
}
type UsersTableProps = {
users: UserRow[];
};