diff --git a/ui/litellm-dashboard/src/components/organization/organization_view.tsx b/ui/litellm-dashboard/src/components/organization/organization_view.tsx index 76f5e81b2fc..962ec6fa4ea 100644 --- a/ui/litellm-dashboard/src/components/organization/organization_view.tsx +++ b/ui/litellm-dashboard/src/components/organization/organization_view.tsx @@ -39,7 +39,7 @@ import { } from "../networking"; import ObjectPermissionsView from "../object_permissions_view"; import NumericalInput from "../shared/numerical_input"; -import MemberModal from "../team/edit_membership"; +import MemberModal from "../team/EditMembership"; import VectorStoreSelector from "../vector_store_management/VectorStoreSelector"; interface OrganizationInfoProps { diff --git a/ui/litellm-dashboard/src/components/team/EditMembership.test.tsx b/ui/litellm-dashboard/src/components/team/EditMembership.test.tsx new file mode 100644 index 00000000000..03837ac7ff1 --- /dev/null +++ b/ui/litellm-dashboard/src/components/team/EditMembership.test.tsx @@ -0,0 +1,72 @@ +import { act, fireEvent, screen, waitFor } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; +import { renderWithProviders } from "../../../tests/test-utils"; +import EditMembership from "./EditMembership"; + +describe("EditMembership", () => { + const mockOnCancel = vi.fn(); + const mockOnSubmit = vi.fn(); + + const defaultConfig = { + title: "Add Member", + roleOptions: [ + { label: "Admin", value: "admin" }, + { label: "Member", value: "member" }, + ], + defaultRole: "member", + showEmail: true, + showUserId: false, + }; + + it("should render", () => { + renderWithProviders( + , + ); + + expect(screen.getByRole("dialog")).toBeInTheDocument(); + expect(screen.getByLabelText("Email")).toBeInTheDocument(); + expect(screen.getByLabelText("Role")).toBeInTheDocument(); + }); + + it("should submit form data when adding a member", async () => { + renderWithProviders( + , + ); + + const emailInput = screen.getByPlaceholderText("user@example.com"); + const submitButton = screen.getByRole("button", { name: "Add Member" }); + + act(() => { + fireEvent.change(emailInput, { target: { value: "test@example.com" } }); + }); + + await waitFor(() => { + expect(emailInput).toHaveValue("test@example.com"); + }); + + act(() => { + fireEvent.click(submitButton); + }); + + await waitFor(() => { + expect(mockOnSubmit).toHaveBeenCalledWith( + expect.objectContaining({ + user_email: "test@example.com", + role: "member", + }), + ); + }); + }); +}); diff --git a/ui/litellm-dashboard/src/components/team/edit_membership.tsx b/ui/litellm-dashboard/src/components/team/EditMembership.tsx similarity index 93% rename from ui/litellm-dashboard/src/components/team/edit_membership.tsx rename to ui/litellm-dashboard/src/components/team/EditMembership.tsx index 93142599aca..e201075cf41 100644 --- a/ui/litellm-dashboard/src/components/team/edit_membership.tsx +++ b/ui/litellm-dashboard/src/components/team/EditMembership.tsx @@ -1,7 +1,6 @@ +import { Text, TextInput } from "@tremor/react"; +import { Button as AntButton, Form, Modal, Select } from "antd"; import React, { useEffect } from "react"; -import { Modal, Form, Button as AntButton } from "antd"; -import { Select, SelectItem, TextInput } from "@tremor/react"; -import { Text } from "@tremor/react"; import NumericalInput from "../shared/numerical_input"; interface BaseMember { @@ -135,9 +134,9 @@ const MemberModal = ({ return ( ); @@ -199,14 +198,14 @@ const MemberModal = ({ // Then all other roles ...config.roleOptions.filter((option) => option.value !== initialData.role), ].map((option) => ( - + {option.label} - + )) : config.roleOptions.map((option) => ( - + {option.label} - + ))} diff --git a/ui/litellm-dashboard/src/components/team/team_info.tsx b/ui/litellm-dashboard/src/components/team/team_info.tsx index e9e5e6f640d..f2ca96c9d69 100644 --- a/ui/litellm-dashboard/src/components/team/team_info.tsx +++ b/ui/litellm-dashboard/src/components/team/team_info.tsx @@ -32,20 +32,20 @@ import { Button, Form, Input, message, Select, Switch, Tooltip } from "antd"; import { CheckIcon, CopyIcon } from "lucide-react"; import React, { useEffect, useMemo, useState } from "react"; import { copyToClipboard as utilCopyToClipboard } from "../../utils/dataUtils"; +import AgentSelector from "../agent_management/AgentSelector"; import DeleteResourceModal from "../common_components/DeleteResourceModal"; import PassThroughRoutesSelector from "../common_components/PassThroughRoutesSelector"; import { getModelDisplayName, unfurlWildcardModelsInList } from "../key_team_helpers/fetch_available_models_team_key"; import LoggingSettingsView from "../logging_settings_view"; import MCPServerSelector from "../mcp_server_management/MCPServerSelector"; import MCPToolPermissions from "../mcp_server_management/MCPToolPermissions"; -import AgentSelector from "../agent_management/AgentSelector"; import NotificationsManager from "../molecules/notifications_manager"; import { fetchMCPAccessGroups } from "../networking"; import ObjectPermissionsView from "../object_permissions_view"; import NumericalInput from "../shared/numerical_input"; import VectorStoreSelector from "../vector_store_management/VectorStoreSelector"; -import MemberModal from "./edit_membership"; import EditLoggingSettings from "./EditLoggingSettings"; +import MemberModal from "./EditMembership"; import MemberPermissions from "./member_permissions"; import TeamMembersComponent from "./team_member_view";