mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-07 18:23:28 +00:00
Merge pull request #19718 from BerriAI/litellm_ui_team_member_add_error
[Feature] UI - Virtual Keys: Auto Truncation of Table Values
This commit is contained in:
@@ -97,6 +97,7 @@ const mockKey: KeyResponse = {
|
||||
litellm_budget_table: {},
|
||||
organization_id: "org-1",
|
||||
created_at: "2024-11-01T10:00:00Z",
|
||||
created_by: "user-1",
|
||||
updated_at: "2024-11-15T10:00:00Z",
|
||||
team_spend: 5.5,
|
||||
team_alias: "Test Team",
|
||||
@@ -177,6 +178,7 @@ beforeEach(() => {
|
||||
total_pages: 1,
|
||||
} as KeysResponse,
|
||||
isPending: false,
|
||||
isFetching: false,
|
||||
refetch: vi.fn(),
|
||||
} as any);
|
||||
|
||||
@@ -265,6 +267,7 @@ it("should show skeleton loaders when isLoading is true", () => {
|
||||
mockUseKeys.mockReturnValue({
|
||||
data: null,
|
||||
isPending: true,
|
||||
isFetching: true,
|
||||
refetch: vi.fn(),
|
||||
} as any);
|
||||
|
||||
@@ -439,8 +442,8 @@ it("should open KeyInfoView when clicking on a key ID button", async () => {
|
||||
// Verify table is visible before clicking - check for table-specific text
|
||||
expect(screen.getByText(/Showing.*results/)).toBeInTheDocument();
|
||||
|
||||
// Find the key ID button (it should show the truncated token)
|
||||
const keyIdButton = screen.getByText("sk-1234...");
|
||||
// Find the key ID button (it shows the full token value, truncation is CSS-only)
|
||||
const keyIdButton = screen.getByText("sk-1234567890abcdef");
|
||||
expect(keyIdButton).toBeInTheDocument();
|
||||
|
||||
// Click on the key ID button
|
||||
@@ -457,3 +460,85 @@ it("should open KeyInfoView when clicking on a key ID button", async () => {
|
||||
// The "Showing X of Y results" text should not be visible when KeyInfoView is open
|
||||
expect(screen.queryByText(/Showing.*results/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display 'Default Proxy Admin' for user_id when value is 'default_user_id'", async () => {
|
||||
const keyWithDefaultUserId = {
|
||||
...mockKey,
|
||||
user_id: "default_user_id",
|
||||
};
|
||||
|
||||
mockUseFilterLogic.mockReturnValue({
|
||||
filters: {
|
||||
"Team ID": "",
|
||||
"Organization ID": "",
|
||||
"Key Alias": "",
|
||||
"User ID": "",
|
||||
"Sort By": "created_at",
|
||||
"Sort Order": "desc",
|
||||
},
|
||||
filteredKeys: [keyWithDefaultUserId],
|
||||
allKeyAliases: ["test-key-alias"],
|
||||
allTeams: [mockTeam],
|
||||
allOrganizations: [mockOrganization],
|
||||
handleFilterChange: vi.fn(),
|
||||
handleFilterReset: vi.fn(),
|
||||
});
|
||||
|
||||
const mockProps = {
|
||||
teams: [mockTeam],
|
||||
organizations: [mockOrganization],
|
||||
onSortChange: vi.fn(),
|
||||
currentSort: {
|
||||
sortBy: "created_at",
|
||||
sortOrder: "desc" as const,
|
||||
},
|
||||
};
|
||||
|
||||
renderWithProviders(<VirtualKeysTable {...mockProps} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Default Proxy Admin")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should display 'Default Proxy Admin' for created_by when value is 'default_user_id'", async () => {
|
||||
const keyWithDefaultCreatedBy = {
|
||||
...mockKey,
|
||||
created_by: "default_user_id",
|
||||
};
|
||||
|
||||
mockUseFilterLogic.mockReturnValue({
|
||||
filters: {
|
||||
"Team ID": "",
|
||||
"Organization ID": "",
|
||||
"Key Alias": "",
|
||||
"User ID": "",
|
||||
"Sort By": "created_at",
|
||||
"Sort Order": "desc",
|
||||
},
|
||||
filteredKeys: [keyWithDefaultCreatedBy],
|
||||
allKeyAliases: ["test-key-alias"],
|
||||
allTeams: [mockTeam],
|
||||
allOrganizations: [mockOrganization],
|
||||
handleFilterChange: vi.fn(),
|
||||
handleFilterReset: vi.fn(),
|
||||
});
|
||||
|
||||
const mockProps = {
|
||||
teams: [mockTeam],
|
||||
organizations: [mockOrganization],
|
||||
onSortChange: vi.fn(),
|
||||
currentSort: {
|
||||
sortBy: "created_at",
|
||||
sortOrder: "desc" as const,
|
||||
},
|
||||
};
|
||||
|
||||
renderWithProviders(<VirtualKeysTable {...mockProps} />);
|
||||
|
||||
await waitFor(() => {
|
||||
// The created_by column should display "Default Proxy Admin"
|
||||
const defaultProxyAdminElements = screen.getAllByText("Default Proxy Admin");
|
||||
expect(defaultProxyAdminElements.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -129,22 +129,25 @@ export function VirtualKeysTable({ teams, organizations, onSortChange, currentSo
|
||||
id: "token",
|
||||
accessorKey: "token",
|
||||
header: "Key ID",
|
||||
size: 150,
|
||||
size: 100,
|
||||
enableSorting: true,
|
||||
cell: (info) => (
|
||||
<div className="overflow-hidden">
|
||||
<Tooltip title={info.getValue() as string}>
|
||||
cell: (info) => {
|
||||
const value = info.getValue() as string;
|
||||
const width = info.cell.column.getSize();
|
||||
return (
|
||||
<Tooltip title={value}>
|
||||
<Button
|
||||
size="xs"
|
||||
variant="light"
|
||||
className="font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left overflow-hidden truncate max-w-[200px]"
|
||||
className="font-mono text-blue-500 bg-blue-50 hover:bg-blue-100 text-xs font-normal px-2 py-0.5 text-left overflow-hidden truncate block"
|
||||
style={{ maxWidth: width, overflow: "hidden" }}
|
||||
onClick={() => setSelectedKey(info.row.original)}
|
||||
>
|
||||
{info.getValue() ? `${(info.getValue() as string).slice(0, 7)}...` : "-"}
|
||||
{value ?? "-"}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "key_alias",
|
||||
@@ -188,13 +191,19 @@ export function VirtualKeysTable({ teams, organizations, onSortChange, currentSo
|
||||
id: "team_id",
|
||||
accessorKey: "team_id",
|
||||
header: "Team ID",
|
||||
size: 120,
|
||||
size: 80,
|
||||
enableSorting: false,
|
||||
cell: (info) => (
|
||||
<Tooltip title={info.getValue() as string}>
|
||||
{info.getValue() ? `${(info.getValue() as string).slice(0, 7)}...` : "-"}
|
||||
</Tooltip>
|
||||
),
|
||||
cell: (info) => {
|
||||
const value = info.getValue() as string | null;
|
||||
const width = info.cell.column.getSize();
|
||||
return (
|
||||
<Tooltip title={value}>
|
||||
<span className={`font-mono text-xs truncate block`} style={{ maxWidth: width, overflow: "hidden" }}>
|
||||
{value ?? "-"}
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "organization_id",
|
||||
@@ -227,18 +236,19 @@ export function VirtualKeysTable({ teams, organizations, onSortChange, currentSo
|
||||
id: "user_id",
|
||||
accessorKey: "user_id",
|
||||
header: "User ID",
|
||||
size: 120,
|
||||
size: 70,
|
||||
enableSorting: false,
|
||||
cell: (info) => {
|
||||
const userId = info.getValue() as string | null;
|
||||
if (userId && userId.length > 15) {
|
||||
return (
|
||||
<Tooltip title={userId}>
|
||||
<span>{userId.slice(0, 7)}...</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return userId ? userId : "-";
|
||||
const displayValue = userId === "default_user_id" ? "Default Proxy Admin" : userId;
|
||||
const width = info.cell.column.getSize();
|
||||
return (
|
||||
<Tooltip title={displayValue}>
|
||||
<span className={`font-mono text-xs truncate block`} style={{ maxWidth: width, overflow: "hidden" }}>
|
||||
{displayValue ?? "-"}
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -256,18 +266,19 @@ export function VirtualKeysTable({ teams, organizations, onSortChange, currentSo
|
||||
id: "created_by",
|
||||
accessorKey: "created_by",
|
||||
header: "Created By",
|
||||
size: 120,
|
||||
size: 70,
|
||||
enableSorting: false,
|
||||
cell: (info) => {
|
||||
const value = info.getValue() as string | null;
|
||||
if (value && value.length > 15) {
|
||||
return (
|
||||
<Tooltip title={value}>
|
||||
<span>{value.slice(0, 7)}...</span>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return value;
|
||||
const displayValue = value === "default_user_id" ? "Default Proxy Admin" : value;
|
||||
const width = info.cell.column.getSize();
|
||||
return (
|
||||
<Tooltip title={displayValue}>
|
||||
<span className={`font-mono text-xs truncate block`} style={{ maxWidth: width, overflow: "hidden" }}>
|
||||
{displayValue ?? "-"}
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user