diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index d4ac60e501b..0cadc13a213 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -215,9 +215,6 @@ }, "max-lines": { "count": 1 - }, - "react/no-unescaped-entities": { - "count": 2 } }, "src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx": { @@ -247,6 +244,9 @@ } }, "src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx": { + "max-lines": { + "count": 1 + }, "no-nested-ternary": { "count": 6 }, @@ -281,6 +281,9 @@ "local/no-complex-jsx-arrow": { "count": 1 }, + "max-lines": { + "count": 1 + }, "max-params": { "count": 1 }, diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailDeleteModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailDeleteModal.tsx index a3ed15b630f..8dfe9442d7c 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailDeleteModal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailDeleteModal.tsx @@ -1,12 +1,10 @@ import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; import DeleteResourceModal from "@/components/common_components/DeleteResourceModal"; import { deleteGuardrailCall } from "@/components/networking"; import { toast } from "@/lib/toast"; import { formatGuardrailMode, getGuardrailLogoAndName } from "./guardrail_info_helpers"; -const DANGLING_REFERENCE_WARNING = - "Keys, teams, and policies that list this guardrail will silently stop running it. Policy pipeline steps that use it will block every request with a 400 error, unless the step's on_error is next or allow (or its on_fail, when on_error is not set)."; - export interface DeletableGuardrail { guardrail_id: string; guardrail_name?: string | null; @@ -25,6 +23,7 @@ interface GuardrailDeleteModalProps { } export function GuardrailDeleteModal({ guardrail, accessToken, onClose, onDeleted }: GuardrailDeleteModalProps) { + const { t } = useTranslation(); const [isDeleting, setIsDeleting] = useState(false); const guardrailName = guardrail ? guardrail.guardrail_name || guardrail.guardrail_id : ""; const providerDisplayName = getGuardrailLogoAndName(guardrail?.litellm_params?.guardrail || "").displayName; @@ -34,11 +33,11 @@ export function GuardrailDeleteModal({ guardrail, accessToken, onClose, onDelete setIsDeleting(true); try { await deleteGuardrailCall(accessToken, guardrail.guardrail_id); - toast.success(`Guardrail "${guardrailName}" deleted successfully`); + toast.success(t("guardrails.deleteModal.toast.deleted", { name: guardrailName })); onClose(); onDeleted(); } catch { - toast.fromError("Failed to delete guardrail"); + toast.fromError(t("guardrails.deleteModal.toast.deleteFailed")); onClose(); } finally { setIsDeleting(false); @@ -48,16 +47,21 @@ export function GuardrailDeleteModal({ guardrail, accessToken, onClose, onDelete return ( = ({ ); }; -const SKIP_MESSAGE_ITEMS = [ - { label: "Use global default", value: "inherit" }, - { label: "Yes — exclude from guardrail scan", value: "yes" }, - { label: "No — always include in scan", value: "no" }, +const SKIP_MESSAGE_ITEMS: { labelKey: ParseKeys; value: string }[] = [ + { labelKey: "guardrails.formField.skipMessage.options.inherit", value: "inherit" }, + { labelKey: "guardrails.formField.skipMessage.options.yes", value: "yes" }, + { labelKey: "guardrails.formField.skipMessage.options.no", value: "no" }, ]; export const SkipMessageSelect: React.FC<{ control: GuardrailFieldControlProps }> = ({ control }) => { + const { t } = useTranslation(); const { id, value, onChange, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy } = control; + const items = SKIP_MESSAGE_ITEMS.map(({ labelKey, value: itemValue }) => ({ label: t(labelKey), value: itemValue })); return ( - - + - {SKIP_MESSAGE_ITEMS.map((item) => ( + {items.map((item) => ( {item.label} @@ -150,8 +154,9 @@ export const LoggingOnlyScopeSelect: React.FC<{ control: GuardrailFieldControlProps; directionalScopeSupported: boolean; }> = ({ control, directionalScopeSupported }) => { + const { t } = useTranslation(); const { id, value, onChange, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy } = control; - const items = getLoggingOnlyScopeOptions(directionalScopeSupported); + const items = getLoggingOnlyScopeOptions(directionalScopeSupported, t); useEffect(() => { const currentChoice = isLoggingOnlyScopeChoice(value) ? value : "default"; @@ -162,7 +167,7 @@ export const LoggingOnlyScopeSelect: React.FC<{ return (