mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
feat(ui): i18n for cache settings
This commit is contained in:
parent
c81c0265ec
commit
c8228990a8
5 changed files with 101 additions and 25 deletions
|
|
@ -4,6 +4,7 @@ import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
|||
import { NumberInput, TextInput } from "@tremor/react";
|
||||
import { Select } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { fetchAvailableModels, ModelGroup } from "../playground/llm_calls/fetch_models";
|
||||
import NumericalInput from "../shared/numerical_input";
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ const CacheFieldRenderer: React.FC<CacheFieldRendererProps> = ({ field, currentV
|
|||
const [modelInfo, setModelInfo] = useState<ModelGroup[]>([]);
|
||||
const [selectedModel, setSelectedModel] = useState<string>(currentValue || "");
|
||||
const { accessToken } = useAuthorized();
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (!accessToken) return;
|
||||
|
|
@ -99,7 +101,7 @@ const CacheFieldRenderer: React.FC<CacheFieldRendererProps> = ({ field, currentV
|
|||
value={selectedModel}
|
||||
onChange={setSelectedModel}
|
||||
showSearch={true}
|
||||
placeholder="Search and select a model..."
|
||||
placeholder={t("cacheSettings.cacheFieldRenderer.searchAndSelectModel")}
|
||||
options={embeddingModels}
|
||||
style={{ width: "100%" }}
|
||||
className="rounded-md"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from "react";
|
||||
import { Select, SelectItem } from "@tremor/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface RedisTypeSelectorProps {
|
||||
redisType: string;
|
||||
|
|
@ -8,17 +9,18 @@ interface RedisTypeSelectorProps {
|
|||
}
|
||||
|
||||
const RedisTypeSelector: React.FC<RedisTypeSelectorProps> = ({ redisType, redisTypeDescriptions, onTypeChange }) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-gray-700">Redis Type</label>
|
||||
<label className="text-sm font-medium text-gray-700">{t("cacheSettings.redisTypeSelector.redisType")}</label>
|
||||
<Select value={redisType} onValueChange={onTypeChange}>
|
||||
<SelectItem value="node">Node (Single Instance)</SelectItem>
|
||||
<SelectItem value="cluster">Cluster</SelectItem>
|
||||
<SelectItem value="sentinel">Sentinel</SelectItem>
|
||||
<SelectItem value="semantic">Semantic</SelectItem>
|
||||
<SelectItem value="node">{t("cacheSettings.redisTypeSelector.nodeType")}</SelectItem>
|
||||
<SelectItem value="cluster">{t("cacheSettings.redisTypeSelector.clusterType")}</SelectItem>
|
||||
<SelectItem value="sentinel">{t("cacheSettings.redisTypeSelector.sentinelType")}</SelectItem>
|
||||
<SelectItem value="semantic">{t("cacheSettings.redisTypeSelector.semanticType")}</SelectItem>
|
||||
</Select>
|
||||
<p className="text-xs text-gray-500">
|
||||
{redisTypeDescriptions[redisType] || "Select the type of Redis deployment you're using"}
|
||||
{redisTypeDescriptions[redisType] || t("cacheSettings.redisTypeSelector.selectTypeDescription")}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button, Accordion, AccordionHeader, AccordionBody } from "@tremor/react";
|
||||
import { getCacheSettingsCall, testCacheConnectionCall, updateCacheSettingsCall } from "../networking";
|
||||
import NotificationsManager from "../molecules/notifications_manager";
|
||||
|
|
@ -13,6 +14,7 @@ interface CacheSettingsProps {
|
|||
}
|
||||
|
||||
const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, userID }) => {
|
||||
const { t } = useTranslation();
|
||||
const [cacheSettings, setCacheSettings] = useState<{ [key: string]: any }>({});
|
||||
const [fields, setFields] = useState<any[]>([]);
|
||||
const [redisTypeDescriptions, setRedisTypeDescriptions] = useState<{ [key: string]: string }>({});
|
||||
|
|
@ -43,7 +45,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load cache settings:", error);
|
||||
NotificationsManager.fromBackend("Failed to load cache settings");
|
||||
NotificationsManager.fromBackend(t("cacheSettings.index.failedToLoad"));
|
||||
}
|
||||
}, [accessToken]);
|
||||
|
||||
|
|
@ -65,13 +67,17 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
const result = await testCacheConnectionCall(accessToken, testSettings);
|
||||
|
||||
if (result.status === "success") {
|
||||
NotificationsManager.success("Cache connection test successful!");
|
||||
NotificationsManager.success(t("cacheSettings.index.testSuccessful"));
|
||||
} else {
|
||||
NotificationsManager.fromBackend(`Connection test failed: ${result.message || result.error}`);
|
||||
NotificationsManager.fromBackend(
|
||||
t("cacheSettings.index.testFailed", { message: result.message || result.error }),
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("Test connection error:", error);
|
||||
NotificationsManager.fromBackend(`Connection test failed: ${error.message || "Unknown error"}`);
|
||||
NotificationsManager.fromBackend(
|
||||
t("cacheSettings.index.testFailed", { message: error.message || t("common.unknown") }),
|
||||
);
|
||||
} finally {
|
||||
setIsTesting(false);
|
||||
}
|
||||
|
|
@ -89,12 +95,12 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
settingsToSave.type = "redis-semantic";
|
||||
}
|
||||
await updateCacheSettingsCall(accessToken, settingsToSave);
|
||||
NotificationsManager.success("Cache settings updated successfully");
|
||||
NotificationsManager.success(t("cacheSettings.index.updateSuccess"));
|
||||
// Reload settings to reflect saved values
|
||||
await loadCacheSettings();
|
||||
} catch (error) {
|
||||
console.error("Failed to save cache settings:", error);
|
||||
NotificationsManager.fromBackend("Failed to update cache settings");
|
||||
NotificationsManager.fromBackend(t("cacheSettings.index.failedToUpdate"));
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
|
@ -111,8 +117,8 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
<div className="w-full space-y-8 py-2">
|
||||
<div className="space-y-6">
|
||||
<div className="max-w-3xl">
|
||||
<h3 className="text-sm font-medium text-gray-900">Cache Settings</h3>
|
||||
<p className="text-xs text-gray-500 mt-1">Configure Redis cache for LiteLLM</p>
|
||||
<h3 className="text-sm font-medium text-gray-900">{t("cacheSettings.index.title")}</h3>
|
||||
<p className="text-xs text-gray-500 mt-1">{t("cacheSettings.index.subtitle")}</p>
|
||||
</div>
|
||||
|
||||
{/* Redis Type Selector */}
|
||||
|
|
@ -124,7 +130,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
|
||||
{/* Basic Fields */}
|
||||
<div className="space-y-6 pt-4 border-t border-gray-200">
|
||||
<h4 className="text-sm font-medium text-gray-900">Connection Settings</h4>
|
||||
<h4 className="text-sm font-medium text-gray-900">{t("cacheSettings.index.connectionSettings")}</h4>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{basicFields.map((field: any) => {
|
||||
if (!field) return null;
|
||||
|
|
@ -137,7 +143,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
{/* Redis Type-Specific Fields */}
|
||||
{redisType === "cluster" && clusterFields.length > 0 && (
|
||||
<div className="space-y-6 pt-4 border-t border-gray-200">
|
||||
<h4 className="text-sm font-medium text-gray-900">Cluster Configuration</h4>
|
||||
<h4 className="text-sm font-medium text-gray-900">{t("cacheSettings.index.clusterConfiguration")}</h4>
|
||||
<div className="grid grid-cols-1 gap-6">
|
||||
{clusterFields.map((field: any) => {
|
||||
const currentValue = cacheSettings[field.field_name] ?? field.field_default ?? "";
|
||||
|
|
@ -149,7 +155,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
|
||||
{redisType === "sentinel" && sentinelFields.length > 0 && (
|
||||
<div className="space-y-6 pt-4 border-t border-gray-200">
|
||||
<h4 className="text-sm font-medium text-gray-900">Sentinel Configuration</h4>
|
||||
<h4 className="text-sm font-medium text-gray-900">{t("cacheSettings.index.sentinelConfiguration")}</h4>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{sentinelFields.map((field: any) => {
|
||||
const currentValue = cacheSettings[field.field_name] ?? field.field_default ?? "";
|
||||
|
|
@ -161,7 +167,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
|
||||
{redisType === "semantic" && semanticFields.length > 0 && (
|
||||
<div className="space-y-6 pt-4 border-t border-gray-200">
|
||||
<h4 className="text-sm font-medium text-gray-900">Semantic Configuration</h4>
|
||||
<h4 className="text-sm font-medium text-gray-900">{t("cacheSettings.index.semanticConfiguration")}</h4>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{semanticFields.map((field: any) => {
|
||||
const currentValue = cacheSettings[field.field_name] ?? field.field_default ?? "";
|
||||
|
|
@ -174,14 +180,14 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
{/* Advanced Settings Accordion */}
|
||||
<Accordion className="mt-4">
|
||||
<AccordionHeader>
|
||||
<span className="text-sm font-medium text-gray-900">Advanced Settings</span>
|
||||
<span className="text-sm font-medium text-gray-900">{t("cacheSettings.index.advancedSettings")}</span>
|
||||
</AccordionHeader>
|
||||
<AccordionBody>
|
||||
<div className="space-y-6">
|
||||
{/* SSL Settings */}
|
||||
{sslFields.length > 0 && (
|
||||
<div className="space-y-4">
|
||||
<h5 className="text-sm font-medium text-gray-700">SSL Settings</h5>
|
||||
<h5 className="text-sm font-medium text-gray-700">{t("cacheSettings.index.sslSettings")}</h5>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{sslFields.map((field: any) => {
|
||||
if (!field) return null;
|
||||
|
|
@ -195,7 +201,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
{/* Cache Management */}
|
||||
{cacheManagementFields.length > 0 && (
|
||||
<div className="space-y-4 pt-4 border-t border-gray-200">
|
||||
<h5 className="text-sm font-medium text-gray-700">Cache Management</h5>
|
||||
<h5 className="text-sm font-medium text-gray-700">{t("cacheSettings.index.cacheManagement")}</h5>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{cacheManagementFields.map((field: any) => {
|
||||
if (!field) return null;
|
||||
|
|
@ -209,7 +215,7 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
{/* GCP Authentication */}
|
||||
{gcpFields.length > 0 && (
|
||||
<div className="space-y-4 pt-4 border-t border-gray-200">
|
||||
<h5 className="text-sm font-medium text-gray-700">GCP Authentication</h5>
|
||||
<h5 className="text-sm font-medium text-gray-700">{t("cacheSettings.index.gcpAuthentication")}</h5>
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||
{gcpFields.map((field: any) => {
|
||||
if (!field) return null;
|
||||
|
|
@ -227,10 +233,10 @@ const CacheSettings: React.FC<CacheSettingsProps> = ({ accessToken, userRole, us
|
|||
{/* Actions */}
|
||||
<div className="border-t border-gray-200 pt-6 flex justify-end gap-3">
|
||||
<Button variant="secondary" size="sm" onClick={handleTestConnection} disabled={isTesting} className="text-sm">
|
||||
{isTesting ? "Testing..." : "Test Connection"}
|
||||
{isTesting ? t("cacheSettings.index.testing") : t("cacheSettings.index.testConnection")}
|
||||
</Button>
|
||||
<Button size="sm" onClick={handleSaveChanges} disabled={isSaving} className="text-sm font-medium">
|
||||
{isSaving ? "Saving..." : "Save Changes"}
|
||||
{isSaving ? t("common.saving") : t("cacheSettings.index.saveChanges")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7675,5 +7675,38 @@
|
|||
"weekly": "weekly",
|
||||
"monthly": "monthly"
|
||||
}
|
||||
},
|
||||
"cacheSettings": {
|
||||
"cacheFieldRenderer": {
|
||||
"searchAndSelectModel": "Search and select a model..."
|
||||
},
|
||||
"redisTypeSelector": {
|
||||
"redisType": "Redis Type",
|
||||
"nodeType": "Node (Single Instance)",
|
||||
"clusterType": "Cluster",
|
||||
"sentinelType": "Sentinel",
|
||||
"semanticType": "Semantic",
|
||||
"selectTypeDescription": "Select the type of Redis deployment you're using"
|
||||
},
|
||||
"index": {
|
||||
"failedToLoad": "Failed to load cache settings",
|
||||
"testSuccessful": "Cache connection test successful!",
|
||||
"testFailed": "Connection test failed: {{message}}",
|
||||
"updateSuccess": "Cache settings updated successfully",
|
||||
"failedToUpdate": "Failed to update cache settings",
|
||||
"title": "Cache Settings",
|
||||
"subtitle": "Configure Redis cache for LiteLLM",
|
||||
"connectionSettings": "Connection Settings",
|
||||
"clusterConfiguration": "Cluster Configuration",
|
||||
"sentinelConfiguration": "Sentinel Configuration",
|
||||
"semanticConfiguration": "Semantic Configuration",
|
||||
"advancedSettings": "Advanced Settings",
|
||||
"sslSettings": "SSL Settings",
|
||||
"cacheManagement": "Cache Management",
|
||||
"gcpAuthentication": "GCP Authentication",
|
||||
"testing": "Testing...",
|
||||
"testConnection": "Test Connection",
|
||||
"saveChanges": "Save Changes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7675,5 +7675,38 @@
|
|||
"weekly": "每周",
|
||||
"monthly": "每月"
|
||||
}
|
||||
},
|
||||
"cacheSettings": {
|
||||
"cacheFieldRenderer": {
|
||||
"searchAndSelectModel": "搜索并选择模型..."
|
||||
},
|
||||
"redisTypeSelector": {
|
||||
"redisType": "Redis 类型",
|
||||
"nodeType": "节点(单实例)",
|
||||
"clusterType": "集群",
|
||||
"sentinelType": "哨兵",
|
||||
"semanticType": "语义",
|
||||
"selectTypeDescription": "选择您使用的 Redis 部署类型"
|
||||
},
|
||||
"index": {
|
||||
"failedToLoad": "加载缓存设置失败",
|
||||
"testSuccessful": "缓存连接测试成功!",
|
||||
"testFailed": "连接测试失败:{{message}}",
|
||||
"updateSuccess": "缓存设置已成功更新",
|
||||
"failedToUpdate": "更新缓存设置失败",
|
||||
"title": "缓存设置",
|
||||
"subtitle": "为 LiteLLM 配置 Redis 缓存",
|
||||
"connectionSettings": "连接设置",
|
||||
"clusterConfiguration": "集群配置",
|
||||
"sentinelConfiguration": "哨兵配置",
|
||||
"semanticConfiguration": "语义配置",
|
||||
"advancedSettings": "高级设置",
|
||||
"sslSettings": "SSL 设置",
|
||||
"cacheManagement": "缓存管理",
|
||||
"gcpAuthentication": "GCP 身份验证",
|
||||
"testing": "测试中...",
|
||||
"testConnection": "测试连接",
|
||||
"saveChanges": "保存更改"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue