mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
feat(ui): save team admin editable fields from their own card with a Save button
Ticking a field only changes the draft. The allow-list is written when the proxy admin clicks Save, and the card sits next to UI Settings instead of inside its auto-saving toggles.
This commit is contained in:
parent
6e2ae19670
commit
b92bd98df6
5 changed files with 270 additions and 183 deletions
|
|
@ -17,6 +17,7 @@ import SCIMConfig from "@/components/SCIM";
|
|||
import LoggingSettings from "@/components/Settings/AdminSettings/LoggingSettings/LoggingSettings";
|
||||
import SSOSettings from "@/components/Settings/AdminSettings/SSOSettings/SSOSettings";
|
||||
import UISettings from "@/components/Settings/AdminSettings/UISettings/UISettings";
|
||||
import TeamAdminEditableFieldsSettings from "@/components/Settings/AdminSettings/UISettings/TeamAdminEditableFieldsSettings";
|
||||
import UserBannerSettings from "@/components/Settings/AdminSettings/UserBannerSettings/UserBannerSettings";
|
||||
import CyberArk from "@/components/Settings/AdminSettings/CyberArk/CyberArk";
|
||||
import HashicorpVault from "@/components/Settings/AdminSettings/HashicorpVault/HashicorpVault";
|
||||
|
|
@ -382,6 +383,7 @@ const AdminPanel: React.FC<AdminPanelProps> = ({ proxySettings }) => {
|
|||
children: (
|
||||
<div className="flex flex-col gap-4">
|
||||
<UISettings />
|
||||
<TeamAdminEditableFieldsSettings />
|
||||
<UserBannerSettings />
|
||||
</div>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,91 +1,175 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { renderWithProviders, screen } from "@/../tests/test-utils";
|
||||
import { fireEvent, renderWithProviders, screen, waitFor } from "@/../tests/test-utils";
|
||||
import { toast } from "@/lib/toast";
|
||||
|
||||
import TeamAdminEditableFieldsSettings from "./TeamAdminEditableFieldsSettings";
|
||||
|
||||
const mockUseUISettings = vi.hoisted(() => vi.fn());
|
||||
const mockUseUpdateUISettings = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("@/app/(dashboard)/hooks/useAuthorized", () => ({
|
||||
default: () => ({ accessToken: "test-token" }),
|
||||
}));
|
||||
|
||||
vi.mock("@/app/(dashboard)/hooks/uiSettings/useUISettings", () => ({
|
||||
useUISettings: mockUseUISettings,
|
||||
}));
|
||||
|
||||
vi.mock("@/app/(dashboard)/hooks/uiSettings/useUpdateUISettings", () => ({
|
||||
useUpdateUISettings: mockUseUpdateUISettings,
|
||||
}));
|
||||
|
||||
const TPM_LABEL = "Tokens per minute Limit (TPM)";
|
||||
|
||||
const mockSettings = (supported: readonly string[], enabled: readonly string[]) =>
|
||||
mockUseUISettings.mockReturnValue({
|
||||
isLoading: false,
|
||||
data: {
|
||||
field_schema: {
|
||||
properties: {
|
||||
team_admin_editable_team_fields: {
|
||||
description: "Fields a team admin may change",
|
||||
items: { type: "string", enum: supported },
|
||||
},
|
||||
},
|
||||
},
|
||||
values: { team_admin_editable_team_fields: enabled },
|
||||
},
|
||||
});
|
||||
|
||||
const mockSave = ({
|
||||
isPending = false,
|
||||
outcome = "success",
|
||||
}: {
|
||||
isPending?: boolean;
|
||||
outcome?: "success" | "error";
|
||||
}) => {
|
||||
const mutate = vi.fn((_settings: unknown, options: { onSuccess: () => void; onError: (error: Error) => void }) =>
|
||||
outcome === "success" ? options.onSuccess() : options.onError(new Error("save failed")),
|
||||
);
|
||||
mockUseUpdateUISettings.mockReturnValue({ mutate, isPending });
|
||||
return mutate;
|
||||
};
|
||||
|
||||
const saveButton = () => screen.getByRole("button", { name: "Save" });
|
||||
|
||||
describe("TeamAdminEditableFieldsSettings", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("explains that nothing can be enabled when the proxy supports no fields", () => {
|
||||
renderWithProviders(
|
||||
<TeamAdminEditableFieldsSettings
|
||||
editableFields={[]}
|
||||
supportedFields={[]}
|
||||
isUpdating={false}
|
||||
onUpdate={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
mockSettings([], []);
|
||||
mockSave({});
|
||||
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
|
||||
expect(screen.getByText("Team admins cannot edit team settings")).toBeInTheDocument();
|
||||
expect(screen.getByText(/does not support enabling any team settings fields/)).toBeInTheDocument();
|
||||
expect(screen.queryByRole("checkbox")).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("button", { name: "Save" })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders one checkbox per supported field, checked for the enabled ones and named by the field's form label when the dashboard has one", () => {
|
||||
renderWithProviders(
|
||||
<TeamAdminEditableFieldsSettings
|
||||
editableFields={["tpm_limit"]}
|
||||
supportedFields={["max_budget", "tpm_limit"]}
|
||||
description="Fields a team admin may change"
|
||||
isUpdating={false}
|
||||
onUpdate={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
it("renders one checkbox per supported field, checked for the saved ones, with Save disabled until something changes", () => {
|
||||
mockSettings(["max_budget", "tpm_limit"], ["tpm_limit"]);
|
||||
mockSave({});
|
||||
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
|
||||
expect(screen.getByText("Team admin editable fields")).toBeInTheDocument();
|
||||
expect(screen.getByText("1 field enabled")).toBeInTheDocument();
|
||||
expect(screen.getByText("Fields a team admin may change")).toBeInTheDocument();
|
||||
expect(screen.getByRole("checkbox", { name: "max_budget" })).not.toBeChecked();
|
||||
expect(screen.getByRole("checkbox", { name: "Tokens per minute Limit (TPM)" })).toBeChecked();
|
||||
expect(screen.getByRole("checkbox", { name: TPM_LABEL })).toBeChecked();
|
||||
expect(saveButton()).toBeDisabled();
|
||||
});
|
||||
|
||||
it("saves the list with the field added when an unchecked field is ticked", async () => {
|
||||
const onUpdate = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(
|
||||
<TeamAdminEditableFieldsSettings
|
||||
editableFields={["tpm_limit"]}
|
||||
supportedFields={["max_budget", "tpm_limit"]}
|
||||
isUpdating={false}
|
||||
onUpdate={onUpdate}
|
||||
/>,
|
||||
it("only saves a ticked field once Save is clicked", async () => {
|
||||
mockSettings(["max_budget", "tpm_limit"], ["tpm_limit"]);
|
||||
const mutate = mockSave({});
|
||||
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: "max_budget" }));
|
||||
|
||||
expect(screen.getByRole("checkbox", { name: "max_budget" })).toBeChecked();
|
||||
expect(mutate).not.toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(saveButton());
|
||||
|
||||
await waitFor(() => expect(toast.success).toHaveBeenCalledWith("Team admin editable fields updated successfully"));
|
||||
expect(mutate).toHaveBeenCalledWith(
|
||||
{ team_admin_editable_team_fields: ["max_budget", "tpm_limit"] },
|
||||
expect.anything(),
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("checkbox", { name: "max_budget" }));
|
||||
|
||||
expect(onUpdate).toHaveBeenCalledWith({ team_admin_editable_team_fields: ["tpm_limit", "max_budget"] });
|
||||
expect(saveButton()).toBeDisabled();
|
||||
});
|
||||
|
||||
it("saves the list with the field removed when a checked field is unticked", async () => {
|
||||
const onUpdate = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(
|
||||
<TeamAdminEditableFieldsSettings
|
||||
editableFields={["max_budget", "tpm_limit"]}
|
||||
supportedFields={["max_budget", "tpm_limit"]}
|
||||
isUpdating={false}
|
||||
onUpdate={onUpdate}
|
||||
/>,
|
||||
);
|
||||
it("saves the list without an unticked field", async () => {
|
||||
mockSettings(["max_budget", "tpm_limit"], ["max_budget", "tpm_limit"]);
|
||||
const mutate = mockSave({});
|
||||
|
||||
await user.click(screen.getByRole("checkbox", { name: "Tokens per minute Limit (TPM)" }));
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
fireEvent.click(saveButton());
|
||||
|
||||
expect(onUpdate).toHaveBeenCalledWith({ team_admin_editable_team_fields: ["max_budget"] });
|
||||
await waitFor(() => expect(mutate).toHaveBeenCalledTimes(1));
|
||||
expect(mutate).toHaveBeenCalledWith({ team_admin_editable_team_fields: ["max_budget"] }, expect.anything());
|
||||
});
|
||||
|
||||
it("blocks toggling while a save is in flight", async () => {
|
||||
const onUpdate = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(
|
||||
<TeamAdminEditableFieldsSettings
|
||||
editableFields={[]}
|
||||
supportedFields={["tpm_limit"]}
|
||||
isUpdating={true}
|
||||
onUpdate={onUpdate}
|
||||
/>,
|
||||
);
|
||||
it("disables Save again when the draft is ticked back to the saved list", () => {
|
||||
mockSettings(["tpm_limit"], []);
|
||||
mockSave({});
|
||||
|
||||
await user.click(screen.getByRole("checkbox", { name: "Tokens per minute Limit (TPM)" }));
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
|
||||
expect(onUpdate).not.toHaveBeenCalled();
|
||||
expect(saveButton()).toBeEnabled();
|
||||
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
|
||||
expect(screen.getByRole("checkbox", { name: TPM_LABEL })).not.toBeChecked();
|
||||
expect(saveButton()).toBeDisabled();
|
||||
});
|
||||
|
||||
it("treats a saved list in another order, or with fields this proxy dropped, as the same selection", () => {
|
||||
mockSettings(["max_budget", "tpm_limit"], ["tpm_limit", "retired_field", "max_budget"]);
|
||||
mockSave({});
|
||||
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
|
||||
expect(screen.getByText("2 fields enabled")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
|
||||
expect(saveButton()).toBeDisabled();
|
||||
});
|
||||
|
||||
it("keeps the draft and shows the error when the save fails", async () => {
|
||||
mockSettings(["tpm_limit"], []);
|
||||
const mutate = mockSave({ outcome: "error" });
|
||||
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
fireEvent.click(saveButton());
|
||||
|
||||
await waitFor(() => expect(toast.fromError).toHaveBeenCalledTimes(1));
|
||||
expect(mutate).toHaveBeenCalledTimes(1);
|
||||
expect(toast.success).not.toHaveBeenCalled();
|
||||
expect(screen.getByRole("checkbox", { name: TPM_LABEL })).toBeChecked();
|
||||
expect(saveButton()).toBeEnabled();
|
||||
});
|
||||
|
||||
it("blocks ticking and saving while a save is in flight", () => {
|
||||
mockSettings(["tpm_limit"], []);
|
||||
const mutate = mockSave({ isPending: true });
|
||||
|
||||
renderWithProviders(<TeamAdminEditableFieldsSettings />);
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: TPM_LABEL }));
|
||||
|
||||
expect(screen.getByRole("checkbox", { name: TPM_LABEL })).not.toBeChecked();
|
||||
expect(screen.getByRole("button", { name: "Saving..." })).toBeDisabled();
|
||||
expect(mutate).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,65 +1,136 @@
|
|||
"use client";
|
||||
|
||||
import { Controller } from "react-hook-form";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings";
|
||||
import { useUpdateUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUpdateUISettings";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import {
|
||||
parseSupportedTeamAdminEditableFields,
|
||||
parseTeamAdminEditableFields,
|
||||
teamAdminFieldLabel,
|
||||
} from "@/components/team/teamAdminEditAccess";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { teamAdminFieldLabel } from "@/components/team/teamAdminEditAccess";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { useZodForm } from "@/lib/forms/useZodForm";
|
||||
import { toast } from "@/lib/toast";
|
||||
|
||||
interface TeamAdminEditableFieldsSettingsProps {
|
||||
editableFields: readonly string[];
|
||||
supportedFields: readonly string[];
|
||||
description?: string;
|
||||
isUpdating: boolean;
|
||||
onUpdate: (settings: { team_admin_editable_team_fields: string[] }) => void;
|
||||
}
|
||||
const editableFieldsSchema = z.object({ team_admin_editable_team_fields: z.array(z.string()) });
|
||||
|
||||
export default function TeamAdminEditableFieldsSettings({
|
||||
editableFields,
|
||||
supportedFields,
|
||||
description,
|
||||
isUpdating,
|
||||
onUpdate,
|
||||
}: TeamAdminEditableFieldsSettingsProps) {
|
||||
const toggleField = (field: string, checked: boolean) => {
|
||||
const next = checked ? [...editableFields, field] : editableFields.filter((item) => item !== field);
|
||||
onUpdate({ team_admin_editable_team_fields: next });
|
||||
};
|
||||
type SaveEditableFields = ReturnType<typeof useUpdateUISettings>["mutate"];
|
||||
|
||||
export default function TeamAdminEditableFieldsSettings() {
|
||||
const { accessToken } = useAuthorized();
|
||||
const { data, isLoading } = useUISettings();
|
||||
const { mutate: saveSettings, isPending } = useUpdateUISettings(accessToken);
|
||||
const supportedFields = parseSupportedTeamAdminEditableFields(data?.field_schema);
|
||||
const savedFields = parseTeamAdminEditableFields(data?.values);
|
||||
const enabledFields = supportedFields.filter((field) => savedFields.includes(field));
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-1">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-sm font-medium text-foreground">Team admin editable fields</p>
|
||||
<Badge variant={editableFields.length > 0 ? "secondary" : "outline"}>
|
||||
{editableFields.length > 0
|
||||
? `${editableFields.length} field${editableFields.length !== 1 ? "s" : ""} enabled`
|
||||
<CardTitle>Team admin editable fields</CardTitle>
|
||||
<Badge variant={enabledFields.length > 0 ? "secondary" : "outline"}>
|
||||
{enabledFields.length > 0
|
||||
? `${enabledFields.length} field${enabledFields.length !== 1 ? "s" : ""} enabled`
|
||||
: "Team admins cannot edit team settings"}
|
||||
</Badge>
|
||||
</div>
|
||||
{description && <p className="text-sm text-muted-foreground">{description}</p>}
|
||||
</div>
|
||||
|
||||
{supportedFields.length === 0 ? (
|
||||
<p className="text-xs italic text-muted-foreground">
|
||||
This proxy version does not support enabling any team settings fields for team admins yet.
|
||||
</p>
|
||||
) : (
|
||||
<div className="ml-4 space-y-2">
|
||||
{supportedFields.map((field) => {
|
||||
const checkboxId = `team-admin-editable-${field}`;
|
||||
return (
|
||||
<label key={field} htmlFor={checkboxId} className="flex cursor-pointer items-center gap-2">
|
||||
<Checkbox
|
||||
id={checkboxId}
|
||||
checked={editableFields.includes(field)}
|
||||
disabled={isUpdating}
|
||||
onCheckedChange={(checked) => toggleField(field, checked === true)}
|
||||
/>
|
||||
<span className="text-sm text-foreground">{teamAdminFieldLabel(field)}</span>
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<CardDescription>
|
||||
{data?.field_schema?.properties?.team_admin_editable_team_fields?.description ??
|
||||
"Team settings fields a team admin may change on the teams they administer."}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{isLoading ? (
|
||||
<Skeleton className="h-16 w-full" />
|
||||
) : (
|
||||
<TeamAdminEditableFieldsForm
|
||||
key={enabledFields.join(",")}
|
||||
enabledFields={enabledFields}
|
||||
supportedFields={supportedFields}
|
||||
isPending={isPending}
|
||||
saveSettings={saveSettings}
|
||||
/>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
interface TeamAdminEditableFieldsFormProps {
|
||||
enabledFields: readonly string[];
|
||||
supportedFields: readonly string[];
|
||||
isPending: boolean;
|
||||
saveSettings: SaveEditableFields;
|
||||
}
|
||||
|
||||
function TeamAdminEditableFieldsForm({
|
||||
enabledFields,
|
||||
supportedFields,
|
||||
isPending,
|
||||
saveSettings,
|
||||
}: TeamAdminEditableFieldsFormProps) {
|
||||
const form = useZodForm(editableFieldsSchema, {
|
||||
defaultValues: { team_admin_editable_team_fields: [...enabledFields] },
|
||||
});
|
||||
const submit = form.handleSubmit((values) =>
|
||||
saveSettings(values, {
|
||||
onSuccess: () => {
|
||||
form.reset(values);
|
||||
toast.success("Team admin editable fields updated successfully");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.fromError(error);
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
if (supportedFields.length === 0) {
|
||||
return (
|
||||
<p className="text-sm italic text-muted-foreground">
|
||||
This proxy version does not support enabling any team settings fields for team admins yet.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={(event) => void submit(event)} className="space-y-4">
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="team_admin_editable_team_fields"
|
||||
render={({ field }) => (
|
||||
<div className="space-y-2">
|
||||
{supportedFields.map((name) => {
|
||||
const checkboxId = `team-admin-editable-${name}`;
|
||||
return (
|
||||
<label key={name} htmlFor={checkboxId} className="flex cursor-pointer items-center gap-2">
|
||||
<Checkbox
|
||||
id={checkboxId}
|
||||
checked={field.value.includes(name)}
|
||||
disabled={isPending}
|
||||
onCheckedChange={(checked) =>
|
||||
field.onChange(
|
||||
supportedFields.filter((item) => (item === name ? checked : field.value.includes(item))),
|
||||
)
|
||||
}
|
||||
/>
|
||||
<span className="text-sm text-foreground">{teamAdminFieldLabel(name)}</span>
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit" disabled={isPending || !form.formState.isDirty}>
|
||||
{isPending ? "Saving..." : "Save"}
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,48 +155,4 @@ describe("UISettings", () => {
|
|||
);
|
||||
expect(toast.success).toHaveBeenCalledWith("UI settings updated successfully");
|
||||
});
|
||||
|
||||
it("saves the team admin editable field list when a supported field is ticked", () => {
|
||||
const mutateMock = vi.fn((_settings, options) => {
|
||||
options?.onSuccess?.();
|
||||
});
|
||||
mockUseUpdateUISettings.mockReturnValue({
|
||||
mutate: mutateMock,
|
||||
isPending: false,
|
||||
error: null,
|
||||
});
|
||||
mockUseUISettings.mockReturnValue(
|
||||
buildSettingsResponse({
|
||||
data: {
|
||||
field_schema: {
|
||||
properties: {
|
||||
team_admin_editable_team_fields: {
|
||||
description: "Team settings fields a team admin may change",
|
||||
type: "array",
|
||||
items: { type: "string", enum: ["tpm_limit"] },
|
||||
},
|
||||
},
|
||||
},
|
||||
values: { team_admin_editable_team_fields: [] },
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
render(<UISettings />);
|
||||
|
||||
expect(screen.getByText("Team settings fields a team admin may change")).toBeInTheDocument();
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole("checkbox", { name: "Tokens per minute Limit (TPM)" }));
|
||||
});
|
||||
|
||||
expect(mutateMock).toHaveBeenCalledWith(
|
||||
{ team_admin_editable_team_fields: ["tpm_limit"] },
|
||||
expect.objectContaining({
|
||||
onSuccess: expect.any(Function),
|
||||
onError: expect.any(Function),
|
||||
}),
|
||||
);
|
||||
expect(toast.success).toHaveBeenCalledWith("Team admin editable fields updated successfully");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,12 +9,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|||
import { Separator } from "@/components/ui/separator";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import {
|
||||
parseSupportedTeamAdminEditableFields,
|
||||
parseTeamAdminEditableFields,
|
||||
} from "@/components/team/teamAdminEditAccess";
|
||||
import PageVisibilitySettings from "./PageVisibilitySettings";
|
||||
import TeamAdminEditableFieldsSettings from "./TeamAdminEditableFieldsSettings";
|
||||
|
||||
interface SettingRowProps {
|
||||
ariaLabel: string;
|
||||
|
|
@ -70,7 +65,6 @@ export default function UISettings() {
|
|||
const allowVectorStoresTeamAdminsProperty = schema?.properties?.allow_vector_stores_for_team_admins;
|
||||
const scopeUserSearchProperty = schema?.properties?.scope_user_search_to_org;
|
||||
const disableCustomApiKeysProperty = schema?.properties?.disable_custom_api_keys;
|
||||
const teamAdminEditableFieldsProperty = schema?.properties?.team_admin_editable_team_fields;
|
||||
const values = data?.values ?? {};
|
||||
const isDisabledForInternalUsers = Boolean(values.disable_model_add_for_internal_users);
|
||||
const isDisabledTeamAdminDeleteTeamUser = Boolean(values.disable_team_admin_delete_team_user);
|
||||
|
|
@ -116,17 +110,6 @@ export default function UISettings() {
|
|||
});
|
||||
};
|
||||
|
||||
const handleUpdateTeamAdminEditableFields = (settings: { team_admin_editable_team_fields: string[] }) => {
|
||||
updateSettings(settings, {
|
||||
onSuccess: () => {
|
||||
toast.success("Team admin editable fields updated successfully");
|
||||
},
|
||||
onError: (error) => {
|
||||
toast.fromError(error);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggleForwardClientHeaders = (checked: boolean) => {
|
||||
updateSettings(
|
||||
{ forward_client_headers_to_llm_api: checked },
|
||||
|
|
@ -456,15 +439,6 @@ export default function UISettings() {
|
|||
isUpdating={isUpdating}
|
||||
onUpdate={handleUpdatePageVisibility}
|
||||
/>
|
||||
|
||||
<Separator />
|
||||
<TeamAdminEditableFieldsSettings
|
||||
editableFields={parseTeamAdminEditableFields(values)}
|
||||
supportedFields={parseSupportedTeamAdminEditableFields(schema)}
|
||||
description={teamAdminEditableFieldsProperty?.description}
|
||||
isUpdating={isUpdating}
|
||||
onUpdate={handleUpdateTeamAdminEditableFields}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue