mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-11 22:51:28 +00:00
fix(ui): name the popover copy buttons after the field they copy
The shared user popover copied alias, email and ID through three copy
buttons that all announced themselves as "Copy ID", so a screen reader
could not tell them apart. IdCell now takes the label, defaulting to the
old text everywhere else.
Also drops the closest("tr") the new link tests used, which put the
testing-library/no-node-access budget over its ceiling, and asserts the
sentinel row leaves User Email and the admin badge unlinked too.
Claude-Session: https://claude.ai/code/session_01NfwfQhamRNnSqgXMUjf3h4
This commit is contained in:
parent
56e2d8846d
commit
06b259e092
4 changed files with 23 additions and 11 deletions
|
|
@ -31,7 +31,7 @@ export function UserPopoverCell({ userAlias, userEmail, userId, width }: UserPop
|
|||
<div key={label} className="flex flex-col min-w-0">
|
||||
<span className="text-muted-foreground">{label}</span>
|
||||
{value ? (
|
||||
<IdCell value={value} variant="plain" copyable className="max-w-full" />
|
||||
<IdCell value={value} variant="plain" copyable copyLabel={`Copy ${label}`} className="max-w-full" />
|
||||
) : (
|
||||
<span className="font-mono">-</span>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,14 @@ describe("IdCell", () => {
|
|||
expect(rowClick).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("names the copy button after the field it copies", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<IdCell value="alice@example.com" copyable copyLabel="Copy User Email" />);
|
||||
expect(screen.queryByRole("button", { name: "Copy ID" })).not.toBeInTheDocument();
|
||||
await user.click(screen.getByRole("button", { name: "Copy User Email" }));
|
||||
expect(copyToClipboardMock).toHaveBeenCalledWith("alice@example.com");
|
||||
});
|
||||
|
||||
it("passes dataTestId through to the id element", () => {
|
||||
render(<IdCell value="k-1" dataTestId="key-id-cell" />);
|
||||
expect(screen.getByTestId("key-id-cell")).toHaveTextContent("k-1");
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ interface IdCellProps {
|
|||
variant?: IdCellVariant;
|
||||
onClick?: (value: string) => void;
|
||||
copyable?: boolean;
|
||||
copyLabel?: string;
|
||||
truncate?: boolean;
|
||||
fallback?: string;
|
||||
tooltip?: React.ReactNode;
|
||||
|
|
@ -39,6 +40,7 @@ export function IdCell({
|
|||
variant = "pill",
|
||||
onClick,
|
||||
copyable = false,
|
||||
copyLabel = "Copy ID",
|
||||
truncate = true,
|
||||
fallback = "-",
|
||||
tooltip,
|
||||
|
|
@ -80,7 +82,7 @@ export function IdCell({
|
|||
{withTooltip}
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Copy ID"
|
||||
aria-label={copyLabel}
|
||||
className="shrink-0 cursor-pointer text-muted-foreground hover:text-foreground"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
|
|
|
|||
|
|
@ -396,7 +396,8 @@ describe("TeamVirtualKeysTable", () => {
|
|||
refetch: vi.fn(),
|
||||
} as any);
|
||||
renderWithProviders(<TeamVirtualKeysTable {...defaultProps} organization={organization} />);
|
||||
return (await screen.findByText(key.key_alias as string)).closest("tr") as HTMLElement;
|
||||
await screen.findByText(key.key_alias as string);
|
||||
return screen.getByRole("row", { name: new RegExp(key.key_alias as string) });
|
||||
};
|
||||
|
||||
it("points the Organization ID cell at the org's detail page", async () => {
|
||||
|
|
@ -433,17 +434,18 @@ describe("TeamVirtualKeysTable", () => {
|
|||
|
||||
it("leaves the default_user_id placeholder unlinked in the User ID and Created By cells", async () => {
|
||||
const placeholder = { user_id: "default_user_id", user_email: "admin@example.com", user_alias: "Proxy Admin" };
|
||||
const row = await renderRow(
|
||||
createMockKey({
|
||||
user_id: placeholder.user_id,
|
||||
user: placeholder,
|
||||
created_by: placeholder.user_id,
|
||||
created_by_user: placeholder,
|
||||
}),
|
||||
);
|
||||
const ownedAndCreatedByPlaceholder = {
|
||||
user_id: placeholder.user_id,
|
||||
user: placeholder,
|
||||
created_by: placeholder.user_id,
|
||||
created_by_user: placeholder,
|
||||
};
|
||||
const row = await renderRow(createMockKey(ownedAndCreatedByPlaceholder));
|
||||
expect(within(row).getByText("Default Proxy Admin")).toBeInTheDocument();
|
||||
expect(within(row).getByText("Proxy Admin")).toBeInTheDocument();
|
||||
expect(within(row).queryByRole("link", { name: "Proxy Admin" })).not.toBeInTheDocument();
|
||||
expect(within(row).queryByRole("link", { name: placeholder.user_email })).not.toBeInTheDocument();
|
||||
expect(within(row).queryByRole("link", { name: "Default Proxy Admin" })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue