From d2c6db823ef9782c2851acd5346c77bdcc872014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B9=E9=9B=AA?= <2b@yorha.xyz> Date: Wed, 10 Jun 2026 23:24:25 +0900 Subject: [PATCH] feat(ui): i18n for policy attachment and creation forms --- .../policies/add_attachment_form.tsx | 72 +++-- .../components/policies/add_policy_form.tsx | 293 ++++++++++-------- ui/litellm-dashboard/src/locales/en.json | 77 +++++ ui/litellm-dashboard/src/locales/zh-CN.json | 77 +++++ 4 files changed, 350 insertions(+), 169 deletions(-) diff --git a/ui/litellm-dashboard/src/components/policies/add_attachment_form.tsx b/ui/litellm-dashboard/src/components/policies/add_attachment_form.tsx index e19a14a2b82..8ce1e0bfe1b 100644 --- a/ui/litellm-dashboard/src/components/policies/add_attachment_form.tsx +++ b/ui/litellm-dashboard/src/components/policies/add_attachment_form.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from "react"; import { Modal, Form, Select, Radio, Divider, Typography } from "antd"; import { Button } from "@tremor/react"; +import { useTranslation, Trans } from "react-i18next"; import { Policy } from "./types"; import { teamListCall, keyListCall, modelAvailableCall, estimateAttachmentImpactCall } from "../networking"; import NotificationsManager from "../molecules/notifications_manager"; @@ -27,6 +28,7 @@ const AddAttachmentForm: React.FC = ({ policies, createAttachment, }) => { + const { t } = useTranslation(); const [form] = Form.useForm(); const [isSubmitting, setIsSubmitting] = useState(false); const [scopeType, setScopeType] = useState<"global" | "specific">("global"); @@ -158,11 +160,11 @@ const AddAttachmentForm: React.FC = ({ const failed = results.filter((r) => r.status === "rejected") as PromiseRejectedResult[]; if (successCount > 0 && failed.length === 0) { - NotificationsManager.success( - successCount === 1 ? "Attachment created successfully" : `${successCount} attachments created successfully`, - ); + NotificationsManager.success(t("policies.addAttachmentForm.attachmentCreatedSuccess", { count: successCount })); } else if (successCount > 0 && failed.length > 0) { - NotificationsManager.fromBackend(`${successCount} attachments created, ${failed.length} failed`); + NotificationsManager.fromBackend( + t("policies.addAttachmentForm.attachmentsPartialSuccess", { successCount, failedCount: failed.length }), + ); } else { throw new Error(failed[0]?.reason instanceof Error ? failed[0].reason.message : "Failed to create attachments"); } @@ -173,7 +175,9 @@ const AddAttachmentForm: React.FC = ({ } catch (error) { console.error("Failed to create attachment:", error); NotificationsManager.fromBackend( - "Failed to create attachment: " + (error instanceof Error ? error.message : String(error)), + t("policies.addAttachmentForm.createAttachmentFailed", { + error: error instanceof Error ? error.message : String(error), + }), ); } finally { setIsSubmitting(false); @@ -186,7 +190,13 @@ const AddAttachmentForm: React.FC = ({ })); return ( - +
= ({ > ({ label: team, @@ -244,12 +254,12 @@ const AddAttachmentForm: React.FC = ({ ({ label: model, @@ -286,19 +294,17 @@ const AddAttachmentForm: React.FC = ({ - Matches tags from key/team metadata.tags or tags passed dynamically in the request body. - Use * as a suffix wildcard (e.g., prod-* matches prod-us,{" "} - prod-eu). + }} /> } >