Revert "UI Settings Frontend"

This reverts commit 51275e7014.
This commit is contained in:
yuneng-jiang
2025-12-09 10:21:30 -08:00
parent 51275e7014
commit 486bcbe4e8
6 changed files with 0 additions and 243 deletions
@@ -1,15 +0,0 @@
import { getUiSettings } from "@/components/networking";
import { useQuery } from "@tanstack/react-query";
import { createQueryKeys } from "../common/queryKeysFactory";
const uiSettingsKeys = createQueryKeys("uiSettings");
export const useUISettings = (accessToken: string) => {
return useQuery<Record<string, any>>({
queryKey: uiSettingsKeys.list({}),
queryFn: async () => await getUiSettings(accessToken),
enabled: !!accessToken,
staleTime: 60 * 60 * 1000, // 1 hour - data rarely changes
gcTime: 60 * 60 * 1000, // 1 hour - keep in cache for 1 hour
});
};
@@ -1,21 +0,0 @@
import { updateUiSettings } from "@/components/networking";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createQueryKeys } from "../common/queryKeysFactory";
const uiSettingsKeys = createQueryKeys("uiSettings");
export const useUpdateUISettings = (accessToken: string) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (settings: Record<string, any>) => {
if (!accessToken) {
throw new Error("Access token is required");
}
return updateUiSettings(accessToken, settings);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: uiSettingsKeys.all });
},
});
};
@@ -1,90 +0,0 @@
import { render, screen, fireEvent, act } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import UISettings from "./UISettings";
import NotificationManager from "@/components/molecules/notifications_manager";
const mockUseAuthorized = vi.hoisted(() => vi.fn());
const mockUseUISettings = vi.hoisted(() => vi.fn());
const mockUseUpdateUISettings = vi.hoisted(() => vi.fn());
vi.mock("@/app/(dashboard)/hooks/useAuthorized", () => ({
__esModule: true,
default: mockUseAuthorized,
}));
vi.mock("@/app/(dashboard)/hooks/uiSettings/useUISettings", () => ({
useUISettings: mockUseUISettings,
}));
vi.mock("@/app/(dashboard)/hooks/uiSettings/useUpdateUISettings", () => ({
useUpdateUISettings: mockUseUpdateUISettings,
}));
const buildSettingsResponse = (overrides?: Partial<Record<string, unknown>>) => ({
data: {
field_schema: {
description: "UI settings description",
properties: {
disable_model_add_for_internal_users: {
description: "Disable model add for internal users",
},
},
},
values: {
disable_model_add_for_internal_users: false,
},
},
isLoading: false,
isError: false,
error: null,
...overrides,
});
describe("UISettings", () => {
beforeEach(() => {
vi.clearAllMocks();
mockUseAuthorized.mockReturnValue({ accessToken: "test-token" });
mockUseUISettings.mockReturnValue(buildSettingsResponse());
mockUseUpdateUISettings.mockReturnValue({
mutate: vi.fn(),
isPending: false,
error: null,
});
});
it("should render", () => {
render(<UISettings />);
expect(screen.getByText("UI Settings")).toBeInTheDocument();
expect(screen.getByRole("switch", { name: "Disable model add for internal users" })).toBeInTheDocument();
});
it("should toggle setting and call update", () => {
const mutateMock = vi.fn((_settings, options) => {
options?.onSuccess?.();
});
mockUseUpdateUISettings.mockReturnValue({
mutate: mutateMock,
isPending: false,
error: null,
});
render(<UISettings />);
const toggle = screen.getByRole("switch", { name: "Disable model add for internal users" });
act(() => {
fireEvent.click(toggle);
});
expect(mutateMock).toHaveBeenCalledWith(
{ disable_model_add_for_internal_users: true },
expect.objectContaining({
onSuccess: expect.any(Function),
onError: expect.any(Function),
}),
);
expect(NotificationManager.success).toHaveBeenCalledWith("UI settings updated successfully");
});
});
@@ -1,74 +0,0 @@
"use client";
import { useUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUISettings";
import { useUpdateUISettings } from "@/app/(dashboard)/hooks/uiSettings/useUpdateUISettings";
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
import NotificationManager from "@/components/molecules/notifications_manager";
import { Alert, Card, Skeleton, Space, Switch, Typography } from "antd";
export default function UISettings() {
const { accessToken } = useAuthorized();
const { data, isLoading, isError, error } = useUISettings(accessToken);
const { mutate: updateSettings, isPending: isUpdating, error: updateError } = useUpdateUISettings(accessToken);
const schema = data?.field_schema;
const property = schema?.properties?.disable_model_add_for_internal_users;
const values = data?.values ?? {};
const isDisabledForInternalUsers = Boolean(values.disable_model_add_for_internal_users);
const handleToggle = (checked: boolean) => {
updateSettings(
{ disable_model_add_for_internal_users: checked },
{
onSuccess: () => {
NotificationManager.success("UI settings updated successfully");
},
onError: (error) => {
NotificationManager.fromBackend(error);
},
},
);
};
return (
<Card title="UI Settings">
{isLoading ? (
<Skeleton active />
) : isError ? (
<Alert
type="error"
message="Could not load UI settings"
description={error instanceof Error ? error.message : undefined}
/>
) : (
<Space direction="vertical" size="large" style={{ width: "100%" }}>
{schema?.description && (
<Typography.Paragraph style={{ marginBottom: 0 }}>{schema.description}</Typography.Paragraph>
)}
{updateError && (
<Alert
type="error"
message="Could not update UI settings"
description={updateError instanceof Error ? updateError.message : undefined}
/>
)}
<Space align="start" size="middle">
<Switch
checked={isDisabledForInternalUsers}
disabled={isUpdating}
loading={isUpdating}
onChange={handleToggle}
aria-label={property?.description ?? "Disable model add for internal users"}
/>
<Space direction="vertical" size={4}>
<Typography.Text strong>Disable model add for internal users</Typography.Text>
{property?.description && <Typography.Text type="secondary">{property.description}</Typography.Text>}
</Space>
</Space>
</Space>
)}
</Card>
);
}
@@ -54,7 +54,6 @@ import {
deleteAllowedIP,
getSSOSettings,
} from "./networking";
import UISettings from "./Settings/AdminSettings/UISettings/UISettings";
const AdminPanel: React.FC<AdminPanelProps> = ({
searchParams,
@@ -498,7 +497,6 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
<TabList>
<Tab>Security Settings</Tab>
<Tab>SCIM</Tab>
<Tab>UI Settings</Tab>
</TabList>
<TabPanels>
<TabPanel>
@@ -650,9 +648,6 @@ const AdminPanel: React.FC<AdminPanelProps> = ({
<TabPanel>
<SCIMConfig accessToken={accessToken} userID={userID} proxySettings={proxySettings} />
</TabPanel>
<TabPanel>
<UISettings />
</TabPanel>
</TabPanels>
</TabGroup>
</div>
@@ -8030,41 +8030,3 @@ export const loginCall = async (username: string, password: string): Promise<Log
const data = await response.json();
return data;
};
export const getUiSettings = async (accessToken: string) => {
const proxyBaseUrl = getProxyBaseUrl();
const url = proxyBaseUrl ? `${proxyBaseUrl}/get/ui_settings` : `/get/ui_settings`;
const response = await fetch(url, {
method: "GET",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
},
});
if (!response.ok) {
const errorData = await response.json();
const errorMessage = deriveErrorMessage(errorData);
throw new Error(errorMessage);
}
const data = await response.json();
return data;
};
export const updateUiSettings = async (accessToken: string, settings: Record<string, any>) => {
const proxyBaseUrl = getProxyBaseUrl();
const url = proxyBaseUrl ? `${proxyBaseUrl}/update/ui_settings` : `/update/ui_settings`;
const response = await fetch(url, {
method: "PATCH",
headers: {
[globalLitellmHeaderName]: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(settings),
});
if (!response.ok) {
const errorData = await response.json();
const errorMessage = deriveErrorMessage(errorData);
throw new Error(errorMessage);
}
const data = await response.json();
return data;
};