diff --git a/ui/litellm-dashboard/src/components/team/team_info.test.tsx b/ui/litellm-dashboard/src/components/team/team_info.test.tsx index c8753660e0..9b19611828 100644 --- a/ui/litellm-dashboard/src/components/team/team_info.test.tsx +++ b/ui/litellm-dashboard/src/components/team/team_info.test.tsx @@ -330,7 +330,9 @@ describe("TeamInfoView", () => { const editButton = await screen.findByRole("button", { name: "Edit Settings" }); act(() => fireEvent.click(editButton)); - const secretField = await screen.findByPlaceholderText('{"namespace": "admin", "mount": "secret", "path_prefix": "litellm"}'); + const secretField = await screen.findByPlaceholderText( + '{"namespace": "admin", "mount": "secret", "path_prefix": "litellm"}', + ); expect(secretField).toBeDisabled(); expect(secretField).toHaveValue(JSON.stringify(teamResponse.team_info.metadata.secret_manager_settings, null, 2)); }, 10000); @@ -391,7 +393,9 @@ describe("TeamInfoView", () => { const editButton = await screen.findByRole("button", { name: "Edit Settings" }); act(() => fireEvent.click(editButton)); - const secretField = await screen.findByPlaceholderText('{"namespace": "admin", "mount": "secret", "path_prefix": "litellm"}'); + const secretField = await screen.findByPlaceholderText( + '{"namespace": "admin", "mount": "secret", "path_prefix": "litellm"}', + ); expect(secretField).not.toBeDisabled(); act(() => { @@ -408,4 +412,75 @@ describe("TeamInfoView", () => { const payload = vi.mocked(networking.teamUpdateCall).mock.calls[0][1]; expect(payload.metadata.secret_manager_settings).toEqual({ provider: "azure", secret_id: "xyz" }); }, 10000); + + it("should include vector stores in object_permission when updating team", async () => { + const teamResponse = { + team_id: "123", + team_info: { + team_alias: "Test Team", + team_id: "123", + organization_id: null, + admins: ["admin@test.com"], + members: [], + members_with_roles: [], + metadata: {}, + tpm_limit: null, + rpm_limit: null, + max_budget: null, + budget_duration: null, + models: ["gpt-4"], + blocked: false, + spend: 0, + max_parallel_requests: null, + budget_reset_at: null, + model_id: null, + litellm_model_table: null, + created_at: "2024-01-01T00:00:00Z", + team_member_budget_table: null, + object_permission: { + vector_stores: ["store1", "store2"], + }, + }, + keys: [], + team_memberships: [], + }; + + vi.mocked(networking.teamInfoCall).mockResolvedValue(teamResponse as any); + vi.mocked(networking.getGuardrailsList).mockResolvedValue({ guardrails: [] }); + vi.mocked(networking.fetchMCPAccessGroups).mockResolvedValue([]); + vi.mocked(networking.teamUpdateCall).mockResolvedValue({ data: teamResponse.team_info, team_id: "123" } as any); + + render( + {}} + onClose={() => {}} + accessToken="123" + is_team_admin={true} + is_proxy_admin={true} + userModels={["gpt-4"]} + editTeam={false} + premiumUser={true} + />, + ); + + const settingsTab = await screen.findByRole("tab", { name: "Settings" }); + act(() => fireEvent.click(settingsTab)); + + const editButton = await screen.findByRole("button", { name: "Edit Settings" }); + act(() => fireEvent.click(editButton)); + + // Verify that Vector Stores field is present + expect(screen.getByLabelText("Vector Stores")).toBeInTheDocument(); + + const saveButton = await screen.findByRole("button", { name: "Save Changes" }); + act(() => fireEvent.click(saveButton)); + + await waitFor(() => { + expect(networking.teamUpdateCall).toHaveBeenCalled(); + }); + + const payload = vi.mocked(networking.teamUpdateCall).mock.calls[0][1]; + expect(payload.object_permission.vector_stores).toEqual(["store1", "store2"]); + }, 10000); }); diff --git a/ui/litellm-dashboard/src/components/team/team_info.tsx b/ui/litellm-dashboard/src/components/team/team_info.tsx index 83b5c1d475..49a04cce1d 100644 --- a/ui/litellm-dashboard/src/components/team/team_info.tsx +++ b/ui/litellm-dashboard/src/components/team/team_info.tsx @@ -463,6 +463,11 @@ const TeamInfoView: React.FC = ({ } delete values.agents_and_groups; + // Handle vector stores permissions + if (values.vector_stores && values.vector_stores.length > 0) { + updateData.object_permission.vector_stores = values.vector_stores; + } + const response = await teamUpdateCall(accessToken, updateData); NotificationsManager.success("Team settings updated successfully"); @@ -824,7 +829,7 @@ const TeamInfoView: React.FC = ({ - + form.setFieldValue("vector_stores", values)} value={form.getFieldValue("vector_stores")}