feat(i18n): translate inline strings — Batch B & C (notifications, JSX, HTML attrs)

Translates remaining hardcoded strings across ~100 frontend files:
- Batch B: deployments page, assistant panel, sidebar, editFlowSettings
- Batch C: placeholder/aria-label/title attrs across playground, trace,
  version sidebar, node components, voice assistant, file manager, paginator

Adds ~130 new keys to en.json and downloads updated locale files (fr, ja, es, de, pt, zh-Hans).
This commit is contained in:
RamGopalSrikar
2026-04-22 09:28:06 -04:00
parent 0f4d36a826
commit 26e9bb6622
100 changed files with 2064 additions and 297 deletions

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import type { handleOnNewValueType } from "@/CustomNodes/hooks/use-handle-new-value";
import { ParameterRenderComponent } from "@/components/core/parameterRenderComponent";
@ -40,6 +41,7 @@ export const NodeDialog: React.FC<NodeDialogProps> = ({
name,
nodeClass,
}) => {
const { t } = useTranslation();
const [isLoading, setIsLoading] = useState(false);
const [fieldValues, setFieldValues] = useState<Record<string, string>>({});
@ -156,7 +158,7 @@ export const NodeDialog: React.FC<NodeDialogProps> = ({
"Knowledge Base";
setSuccessData({
title: `Knowledge Base "${knowledgeBaseName}" created successfully!`,
title: t("success.knowledgeBaseNodeCreated", { name: knowledgeBaseName }),
});
onCreated?.(knowledgeBaseName);

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import useFlowStore from "@/stores/flowStore";
import { cn } from "@/utils/utils";
@ -12,6 +13,7 @@ export default function NodeLegacyComponent({
replacement?: string[];
setDismissAll: (value: boolean) => void;
}) {
const { t } = useTranslation();
const setFilterComponent = useFlowStore((state) => state.setFilterComponent);
const setFilterType = useFlowStore((state) => state.setFilterType);
const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
@ -42,7 +44,7 @@ export default function NodeLegacyComponent({
e.stopPropagation();
setDismissAll(true);
}}
aria-label="Dismiss warning bar"
aria-label={t("node.dismissWarning")}
data-testid="dismiss-warning-bar"
>
Dismiss

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { cn } from "@/utils/utils";
@ -20,6 +21,7 @@ export default function NodeUpdateComponent({
dismissed?: boolean;
isRequired?: boolean;
}) {
const { t } = useTranslation();
const showUpdateAction = !blocked;
if (dismissed && isRequired) {
@ -88,7 +90,7 @@ export default function NodeUpdateComponent({
e.stopPropagation();
setDismissAll(true);
}}
aria-label="Dismiss warning bar"
aria-label={t("node.dismissWarning")}
data-testid="dismiss-warning-bar"
>
Dismiss

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
@ -15,6 +16,7 @@ export default function OutputModal({
open,
setOpen,
}): JSX.Element {
const { t } = useTranslation();
const [activeTab, setActiveTab] = useState<"Outputs" | "Logs">("Outputs");
const [isCopied, setIsCopied] = useState(false);
const flowPool = useFlowStore((state) => state.flowPool);
@ -46,7 +48,7 @@ export default function OutputModal({
navigator.clipboard.writeText(content).then(() => {
setIsCopied(true);
setSuccessData({ title: "Copied to clipboard" });
setSuccessData({ title: t("success.outputCopied") });
setTimeout(() => {
setIsCopied(false);
}, 2000);

View File

@ -1,6 +1,7 @@
import { useUpdateNodeInternals } from "@xyflow/react";
import { cloneDeep, debounce } from "lodash";
import { useCallback, useMemo, useRef } from "react";
import { useTranslation } from "react-i18next";
import { DEBOUNCE_FIELD_LIST } from "@/constants/constants";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import { track } from "@/customization/utils/analytics";
@ -49,6 +50,7 @@ const useHandleOnNewValue = ({
update: AllNodeType | ((oldState: AllNodeType) => AllNodeType),
) => void;
}) => {
const { t } = useTranslation();
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const setNode = setNodeExternal ?? useFlowStore((state) => state.setNode);
const updateNodeInternals = useUpdateNodeInternals();
@ -104,14 +106,14 @@ const useHandleOnNewValue = ({
}
if (!template) {
setErrorData({ title: "Template not found in the component" });
setErrorData({ title: t("errors.templateNotFound") });
return;
}
const parameter = template[name];
if (!parameter) {
setErrorData({ title: "Parameter not found in the template" });
setErrorData({ title: t("errors.parameterNotFound") });
return;
}

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import {
PAGINATION_PAGE,
PAGINATION_ROWS_COUNT,
@ -24,6 +25,7 @@ export default function PaginatorComponent({
pages,
isComponent,
}: PaginatorComponentType) {
const { t } = useTranslation();
const [size, setPageSize] = useState(pageSize);
const [maxIndex, setMaxPageIndex] = useState(
Math.ceil(totalRowsCount / pageSize),
@ -66,7 +68,7 @@ export default function PaginatorComponent({
direction="up"
className="h-7 w-fit gap-1 border-none p-1 pl-1.5 text-mmd focus:border-none focus:ring-0 focus:!ring-offset-0"
>
<SelectValue placeholder="1" />
<SelectValue placeholder={t("paginator.placeholder")} />
</SelectTrigger>
<SelectContent>
{Array.from({ length: maxIndex }, (_, i) => i + 1).map((item) => (

View File

@ -75,7 +75,7 @@ export const MenuBar = memo((): JSX.Element => {
const handleSave = () => {
if (!onFlowPage) return;
saveFlow().then(() => {
setSuccessData({ title: "Saved successfully" });
setSuccessData({ title: t("flow.savedSuccessfully") });
});
};

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Button } from "@/components/ui/button";
@ -29,6 +30,7 @@ export function AssistantHeader({
onDeleteSession,
isExpanded,
}: AssistantHeaderProps) {
const { t } = useTranslation();
const isAtSessionLimit = sessions.length >= ASSISTANT_MAX_SESSIONS;
const isNewSessionDisabled = !hasMessages || isAtSessionLimit;
@ -39,7 +41,7 @@ export function AssistantHeader({
<ShadTooltip
content={
isAtSessionLimit
? `Maximum of ${ASSISTANT_MAX_SESSIONS} sessions reached. Delete a session to create a new one.`
? t("assistant.maxSessionsTooltip", { max: ASSISTANT_MAX_SESSIONS })
: ""
}
side="bottom"
@ -58,7 +60,7 @@ export function AssistantHeader({
name={isAtSessionLimit ? "AlertCircle" : "Plus"}
className="h-4 w-4"
/>
{isAtSessionLimit ? "Max sessions" : "New session"}
{isAtSessionLimit ? t("assistant.maxSessionsLabel") : t("assistant.newSession")}
</Button>
</span>
</ShadTooltip>

View File

@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import type { AgenticStepType } from "@/controllers/API/queries/agentic";
import { Button } from "@/components/ui/button";
@ -71,6 +72,7 @@ export function AssistantInput({
draftMessage = "",
onDraftChange,
}: AssistantInputProps) {
const { t } = useTranslation();
const [message, setMessage] = useState(draftMessage);
const [idlePlaceholder] = useState(getAssistantPlaceholder);
@ -176,7 +178,7 @@ export function AssistantInput({
isProcessing
? isPostGenerationStep
? ""
: "Working on it..."
: t("assistant.workingOnIt")
: (placeholder ?? idlePlaceholder)
}
disabled={disabled || isProcessing}
@ -221,7 +223,7 @@ export function AssistantInput({
<button
type="button"
onClick={onStop}
title="Stop generation"
title={t("assistant.stopGeneration")}
data-testid="assistant-stop-button"
className="flex h-8 w-8 items-center justify-center rounded-lg bg-muted-foreground/15 text-muted-foreground transition-colors hover:bg-muted-foreground/25"
>
@ -237,7 +239,7 @@ export function AssistantInput({
className="h-8 w-8 rounded-lg"
onClick={handleSend}
disabled={!canSend}
title="Send message"
title={t("assistant.sendMessage")}
>
<ForwardedIconComponent name="ArrowUp" className="h-4 w-4" />
</Button>

View File

@ -1,4 +1,5 @@
import { memo, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
ArrowRight,
Check,
@ -20,6 +21,7 @@ function AssistantLoadingStateComponent({
streamingContent,
onValidationComplete,
}: AssistantLoadingStateProps) {
const { t } = useTranslation();
const [codeOpen, setCodeOpen] = useState(true);
const streamingRef = useRef<HTMLPreElement>(null);
@ -108,7 +110,7 @@ function AssistantLoadingStateComponent({
<ChevronRight className="h-3 w-3" />
)}
<Code2 className="h-3 w-3" />
<span>Code</span>
<span>{t("assistant.code")}</span>
</button>
{codeOpen && (
<pre className="mt-2 max-h-[250px] overflow-auto rounded-md bg-muted p-3 text-xs leading-relaxed">
@ -126,7 +128,7 @@ function AssistantLoadingStateComponent({
onClick={() => onValidationComplete?.()}
className="mt-4 flex w-full items-center justify-center gap-2 rounded-md bg-accent-emerald-foreground/10 px-4 py-2.5 text-sm font-medium text-accent-emerald-foreground transition-colors hover:bg-accent-emerald-foreground/20"
>
<span>Continue</span>
<span>{t("assistant.continue")}</span>
<ArrowRight className="h-4 w-4" />
</button>
)}

View File

@ -1,9 +1,11 @@
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import langflowAssistantIcon from "@/assets/langflow_assistant.svg";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
export function AssistantNoModelsState() {
const { t } = useTranslation();
const navigate = useNavigate();
const handleConfigureModels = () => {
@ -20,11 +22,10 @@ export function AssistantNoModelsState() {
/>
</div>
<h3 className="mb-3 text-center text-base font-semibold leading-6 tracking-normal text-foreground">
No Model Provider Configured
{t("assistant.noModelsConfigured")}
</h3>
<p className="mb-6 max-w-[280px] text-center text-sm text-muted-foreground">
To use the assistant, please configure at least one model provider in
your settings.
{t("assistant.noModelsDescription")}
</p>
<Button
variant="outline"
@ -33,7 +34,7 @@ export function AssistantNoModelsState() {
onClick={handleConfigureModels}
>
<ForwardedIconComponent name="Settings" className="h-4 w-4" />
Configure Model Providers
{t("assistant.configureModels")}
</Button>
</div>
);

View File

@ -2,6 +2,7 @@
* Dropdown showing saved assistant sessions with switch and delete actions.
*/
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Button } from "@/components/ui/button";
@ -32,6 +33,7 @@ export function SessionHistoryDropdown({
onDeleteSession,
isExpanded = false,
}: SessionHistoryDropdownProps) {
const { t } = useTranslation();
const hasSessions = sessions.length > 0;
// Expanded panel (has messages / height > min) → dropdown grows down; compact → grows up
const dropAlign = isExpanded ? "start" : "end";
@ -43,7 +45,7 @@ export function SessionHistoryDropdown({
variant="ghost"
size="icon"
className="h-8 w-8"
title="Session history"
title={t("assistant.sessionHistory")}
data-testid="assistant-session-history"
disabled={!hasSessions}
>
@ -61,9 +63,9 @@ export function SessionHistoryDropdown({
className="z-[70] max-h-80 w-72 overflow-y-auto"
>
<DropdownMenuLabel className="flex items-center gap-1.5 text-xs font-semibold">
Session History
{t("assistant.sessionHistoryLabel")}
<ShadTooltip
content="Sessions are stored in your browser only and will not be preserved across different browsers or after clearing browser data."
content={t("assistant.sessionHistoryTooltip")}
side="right"
>
<div>
@ -78,7 +80,7 @@ export function SessionHistoryDropdown({
{!hasSessions ? (
<div className="px-2 py-3 text-center text-xs text-muted-foreground">
No previous sessions
{t("assistant.noPreviousSessions")}
</div>
) : (
sessions.map((entry) => {
@ -103,7 +105,7 @@ export function SessionHistoryDropdown({
{entry.firstUserMessage}
</span>
<span className="text-[10px] text-muted-foreground">
{entry.messageCount} msgs
{t("assistant.messageCounts", { count: entry.messageCount })}
{" · "}
{moment(entry.lastActiveAt).fromNow()}
</span>

View File

@ -1,5 +1,6 @@
import { Panel, useStoreApi } from "@xyflow/react";
import { type ReactNode, useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useShallow } from "zustand/react/shallow";
import langflowAssistantIcon from "@/assets/langflow_assistant.svg";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
@ -20,6 +21,7 @@ const CanvasControls = ({
selectedNode: AllNodeType | null;
effectiveLocked?: boolean;
}) => {
const { t } = useTranslation();
const reactFlowStoreApi = useStoreApi();
const isFlowLocked = useFlowStore(
useShallow((state) => state.currentFlow?.locked),
@ -116,7 +118,7 @@ const CanvasControls = ({
size="icon"
data-testid="canvas-add-note-button"
className="group flex h-8 w-8 items-center justify-center rounded-md hover:bg-muted"
title="Add Sticky Note"
title={t("canvas.addStickyNote")}
onClick={handleAddNote}
>
<ForwardedIconComponent

View File

@ -1,6 +1,7 @@
import * as Form from "@radix-ui/react-form";
import type React from "react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Switch } from "@/components/ui/switch";
import type { InputProps } from "../../../types/components";
@ -31,6 +32,7 @@ export const EditFlowSettings: React.FC<
locked?: boolean;
setLocked?: (v: boolean) => void;
}): JSX.Element => {
const { t } = useTranslation();
const [isMaxLength, setIsMaxLength] = useState(false);
const [isMaxDescriptionLength, setIsMaxDescriptionLength] = useState(false);
const [isMinLength, setIsMinLength] = useState(false);
@ -92,18 +94,18 @@ export const EditFlowSettings: React.FC<
<Form.Field name="name">
<div className="edit-flow-arrangement">
<Form.Label className="text-mmd font-medium">
Name{setName ? "" : ":"}
{t("flow.nameLabel")}{setName ? "" : ":"}
</Form.Label>
{isMaxLength && (
<span className="edit-flow-span">Character limit reached</span>
<span className="edit-flow-span">{t("flow.characterLimitReached")}</span>
)}
{isMinLength && (
<span className="edit-flow-span">
Minimum {minLength} character(s) required
{t("flow.minimumCharacters", { count: minLength })}
</span>
)}
{isInvalidName && (
<span className="edit-flow-span">Flow name already exists</span>
<span className="edit-flow-span">{t("flow.nameAlreadyExists")}</span>
)}
</div>
{setName ? (
@ -114,7 +116,7 @@ export const EditFlowSettings: React.FC<
type="text"
name="name"
value={name ?? ""}
placeholder="Flow name"
placeholder={t("flow.namePlaceholder")}
id="name"
maxLength={maxLength}
minLength={minLength}
@ -131,22 +133,22 @@ export const EditFlowSettings: React.FC<
</span>
)}
<Form.Message match="valueMissing" className="field-invalid">
Please enter a name
{t("flow.pleaseEnterName")}
</Form.Message>
<Form.Message
match={(value) => !!(value && invalidNameList.includes(value))}
className="field-invalid"
>
Flow name already exists
{t("flow.nameAlreadyExists")}
</Form.Message>
</Form.Field>
<Form.Field name="description">
<div className="edit-flow-arrangement mt-2">
<Form.Label className="text-mmd font-medium">
Description{setDescription ? "" : ":"}
{t("flow.descriptionLabel")}{setDescription ? "" : ":"}
</Form.Label>
{isMaxDescriptionLength && (
<span className="edit-flow-span">Character limit reached</span>
<span className="edit-flow-span">{t("flow.characterLimitReached")}</span>
)}
</div>
{setDescription ? (
@ -156,7 +158,7 @@ export const EditFlowSettings: React.FC<
id="description"
onChange={handleDescriptionChange}
value={description!}
placeholder="Flow description"
placeholder={t("flow.descriptionPlaceholder")}
data-testid="input-flow-description"
className="mt-2 max-h-[250px] resize-none font-normal"
rows={5}
@ -173,18 +175,18 @@ export const EditFlowSettings: React.FC<
description === "" ? "font-light italic" : "",
)}
>
{description === "" ? "No description" : description}
{description === "" ? t("flow.noDescription") : description}
</div>
)}
<Form.Message match="valueMissing" className="field-invalid">
Please enter a description
{t("flow.pleaseEnterDescription")}
</Form.Message>
<div className="mt-3">
<div className="flex items-center gap-2">
<div>
<div className="flex items-center gap-2">
<Form.Label className="text-mmd font-medium">
Lock Flow
{t("flow.lockFlow")}
</Form.Label>
<ForwardedIconComponent
@ -194,7 +196,7 @@ export const EditFlowSettings: React.FC<
</div>
<p className="text-xs text-muted-foreground/70 mt-1 font-normal">
Lock your flow to prevent edits or accidental changes.
{t("flow.lockFlowDescription")}
</p>
</div>

View File

@ -1,6 +1,7 @@
import * as Form from "@radix-ui/react-form";
import { cloneDeep } from "lodash";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import useSaveFlow from "@/hooks/flows/use-save-flow";
import useAlertStore from "@/stores/alertStore";
@ -57,6 +58,7 @@ const FlowSettingsComponent = ({
close,
open,
}: FlowSettingsComponentProps): JSX.Element => {
const { t } = useTranslation();
const saveFlow = useSaveFlow();
const currentFlow = useFlowStore((state) =>
flowData ? undefined : state.currentFlow,
@ -89,7 +91,7 @@ const FlowSettingsComponent = ({
saveFlow(newFlow)
?.then(() => {
setIsSaving(false);
setSuccessData({ title: "Changes saved successfully" });
setSuccessData({ title: t("success.changesSaved") });
close();
})
.catch(() => {

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import {
@ -41,10 +42,11 @@ export default function DeploymentPhaseContent({
onContinue,
onCancel,
}: DeploymentPhaseContentProps) {
const { t } = useTranslation();
return (
<>
<DialogHeader>
<DialogTitle>Select Deployment</DialogTitle>
<DialogTitle>{t("deployments.selectDeployment")}</DialogTitle>
<DialogDescription>
{selectedProvider
? `Deployments on ${selectedProvider.name} for this flow.`
@ -91,7 +93,7 @@ export default function DeploymentPhaseContent({
htmlFor="deploy-new"
className="flex flex-1 cursor-pointer flex-col gap-0.5"
>
<span className="text-sm font-medium">Create new deployment</span>
<span className="text-sm font-medium">{t("deployments.createNewDeployment")}</span>
<span className="text-xs text-muted-foreground">
{selectedProvider
? `New deployment on ${selectedProvider.name}`
@ -113,7 +115,7 @@ export default function DeploymentPhaseContent({
</Button>
)}
<Button onClick={onContinue} disabled={isBusy}>
Continue
{t("assistant.continue")}
</Button>
</div>
</div>

View File

@ -1,4 +1,5 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { usePatchSnapshot } from "@/controllers/API/queries/deployments";
import { useGetDeploymentAttachments } from "@/controllers/API/queries/deployments/use-get-deployment-attachments";
@ -56,6 +57,7 @@ export default function DeployChoiceDialog({
onUpdateComplete,
onTestDeployment,
}: DeployChoiceDialogProps) {
const { t } = useTranslation();
const [phase, setPhase] = useState<Phase>("provider");
const [selectedProviderId, setSelectedProviderId] =
useState<string>(NEW_DEPLOYMENT_VALUE);
@ -148,7 +150,7 @@ export default function DeployChoiceDialog({
);
if (!nextReviewAttachment) {
showError(
"Failed to load deployment details",
t("errors.failedToLoadDeployment"),
"No provider snapshot was found for this flow on the selected deployment.",
);
setPhase("deployments");

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
@ -23,10 +24,11 @@ export default function ProviderPhaseContent({
onContinue,
onCancel,
}: ProviderPhaseContentProps) {
const { t } = useTranslation();
return (
<>
<DialogHeader>
<DialogTitle>Select Provider</DialogTitle>
<DialogTitle>{t("deployments.selectProvider")}</DialogTitle>
<DialogDescription>
Choose a provider environment to deploy to, or create a new deployment
from scratch.
@ -60,7 +62,7 @@ export default function ProviderPhaseContent({
<Button variant="ghost" onClick={onCancel}>
Cancel
</Button>
<Button onClick={onContinue}>Continue</Button>
<Button onClick={onContinue}>{t("assistant.continue")}</Button>
</div>
</>
);

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
@ -34,12 +35,13 @@ export default function ReviewPhaseContent({
{ enabled: !!attachment.flow_version_id },
);
const { t } = useTranslation();
const currentVersionTag = currentVersion?.version_tag ?? "...";
return (
<>
<DialogHeader>
<DialogTitle>Review Update</DialogTitle>
<DialogTitle>{t("deployments.reviewUpdate")}</DialogTitle>
<DialogDescription>
Review the version change before updating the deployment.
</DialogDescription>
@ -55,7 +57,7 @@ export default function ReviewPhaseContent({
<div className="flex items-center gap-3">
<div className="flex flex-1 flex-col items-center gap-1.5 rounded-lg border p-3">
<span className="text-xs text-muted-foreground">Current</span>
<span className="text-xs text-muted-foreground">{t("deployments.current")}</span>
{isLoadingVersion ? (
<ForwardedIconComponent
name="Loader2"
@ -72,7 +74,7 @@ export default function ReviewPhaseContent({
/>
<div className="flex flex-1 flex-col items-center gap-1.5 rounded-lg border p-3">
<span className="text-xs text-muted-foreground">New</span>
<span className="text-xs text-muted-foreground">{t("deployments.new")}</span>
<Badge variant="default">{newVersionTag}</Badge>
</div>
</div>
@ -87,7 +89,7 @@ export default function ReviewPhaseContent({
Back
</Button>
<Button onClick={onConfirm} disabled={isBusy || isLoadingVersion}>
Update
{t("deployments.confirm")}
</Button>
</div>
</div>

View File

@ -78,8 +78,8 @@ export default function PublishDropdown({
setCurrentFlow(updatedFlow);
} else {
setErrorData({
title: "Failed to save flow",
list: ["Flows variable undefined"],
title: t("errors.failedToSaveFlow"),
list: [t("errors.flowsVariableUndefined")],
});
}
},
@ -87,7 +87,7 @@ export default function PublishDropdown({
const detail =
e.response?.data?.detail || e.message || "Unknown error";
setErrorData({
title: "Failed to save flow",
title: t("errors.failedToSaveFlow"),
list: [detail],
});
},

View File

@ -1,4 +1,5 @@
import { type FC, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { FaDiscord, FaGithub } from "react-icons/fa";
import IconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
@ -15,6 +16,7 @@ export const GetStartedProgress: FC<{
isDiscordJoined: boolean;
handleDismissDialog: () => void;
}> = ({ userData, isGithubStarred, isDiscordJoined, handleDismissDialog }) => {
const { t } = useTranslation();
const [isGithubStarredChild, setIsGithubStarredChild] =
useState(isGithubStarred);
const [isDiscordJoinedChild, setIsDiscordJoinedChild] =
@ -92,10 +94,10 @@ export const GetStartedProgress: FC<{
>
{percentageGetStarted >= 100 ? (
<>
<span>All Set</span> <span className="pl-1"> 🎉 </span>
<span>{t("sidebar.allSet")}</span> <span className="pl-1"> 🎉 </span>
</>
) : (
"Get started"
t("sidebar.getStarted")
)}
</span>
<button
@ -160,7 +162,7 @@ export const GetStartedProgress: FC<{
isGithubStarredChild && "text-muted-foreground line-through",
)}
>
Star repo for updates
{t("sidebar.starRepo")}
</span>
</div>
</Button>
@ -202,7 +204,7 @@ export const GetStartedProgress: FC<{
isDiscordJoinedChild && "text-muted-foreground line-through",
)}
>
Join the community
{t("sidebar.joinCommunity")}
</span>
</div>
</Button>
@ -229,7 +231,7 @@ export const GetStartedProgress: FC<{
/>
</span>
<span className={cn("text-sm", hasFlows && "line-through")}>
Create a flow
{t("sidebar.createFlow")}
</span>
</div>
</Button>

View File

@ -1,4 +1,5 @@
import type { FC } from "react";
import { useTranslation } from "react-i18next";
import MCPLangflow from "@/assets/MCPLangflow.png";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
@ -7,6 +8,7 @@ import { useCustomNavigate } from "@/customization/hooks/use-custom-navigate";
export const MCPServerNotice: FC<{
handleDismissDialog: () => void;
}> = ({ handleDismissDialog }) => {
const { t } = useTranslation();
const navigate = useCustomNavigate();
return (
<div className="relative flex flex-col gap-3 rounded-xl border p-4 shadow-md">
@ -19,12 +21,12 @@ export const MCPServerNotice: FC<{
</Button>
<div className="flex flex-col gap-3">
<div className="flex flex-col gap-1">
<div className="font-mono text-sm text-muted-foreground">New</div>
<div className="">Projects as MCP Servers</div>
<div className="font-mono text-sm text-muted-foreground">{t("sidebar.mcpNewBadge")}</div>
<div className="">{t("sidebar.mcpProjectsTitle")}</div>
</div>
<img src={MCPLangflow} alt="MCP Notice Modal" className="rounded-xl" />
<p className="text-sm text-secondary-foreground">
Expose flows as tools from clients like Cursor or Claude.
{t("sidebar.mcpExposeFlows")}
</p>
</div>
@ -36,7 +38,7 @@ export const MCPServerNotice: FC<{
}}
className="w-full"
>
<span>Go to Server</span>
<span>{t("sidebar.mcpGoToServer")}</span>
</Button>
</div>
</div>

View File

@ -25,6 +25,13 @@ export const createCopyButton = (
getEditor: () => any,
setSuccessData: (data: { title: string }) => void,
setErrorData: (data: { title: string; list: string[] }) => void,
messages: {
copyFailed: string;
editorNotAvailable: string;
jsonCopied: string;
unableToCopy: string;
copyJson: string;
},
): MenuItem => {
return {
type: "button" as const,
@ -32,8 +39,8 @@ export const createCopyButton = (
const editor = getEditor();
if (!editor) {
setErrorData({
title: "Copy Failed",
list: ["Editor not available"],
title: messages.copyFailed,
list: [messages.editorNotAvailable],
});
return;
}
@ -46,17 +53,17 @@ export const createCopyButton = (
navigator.clipboard
.writeText(textContent)
.then(() => {
setSuccessData({ title: "JSON copied to clipboard" });
setSuccessData({ title: messages.jsonCopied });
})
.catch(() => {
setErrorData({
title: "Copy Failed",
list: ["Unable to copy to clipboard. Please copy manually."],
title: messages.copyFailed,
list: [messages.unableToCopy],
});
});
},
icon: faCopy,
title: "Copy JSON to clipboard",
title: messages.copyJson,
};
};
@ -99,6 +106,14 @@ export const processTextModeItems = (
getEditor: () => any,
setSuccessData: (data: { title: string }) => void,
setErrorData: (data: { title: string; list: string[] }) => void,
messages: {
copyFailed: string;
editorNotAvailable: string;
jsonCopied: string;
unableToCopy: string;
copyJson: string;
outputCopied: string;
},
): MenuItem[] => {
let filteredItems = filterTextModeItems(items);
@ -107,10 +122,15 @@ export const processTextModeItems = (
getEditor,
setSuccessData,
setErrorData,
messages,
);
filteredItems = addCopyButtonToItems(filteredItems, copyButton);
} else {
filteredItems = enhanceExistingCopyButtons(filteredItems, setSuccessData);
filteredItems = enhanceExistingCopyButtons(
filteredItems,
setSuccessData,
messages.jsonCopied,
);
}
return filteredItems;
@ -119,10 +139,7 @@ export const processTextModeItems = (
export const processTreeModeItems = (
items: MenuItem[],
setSuccessData: (data: { title: string }) => void,
outputCopiedMsg: string,
): MenuItem[] => {
return enhanceExistingCopyButtons(
items,
setSuccessData,
"Copied to clipboard",
);
return enhanceExistingCopyButtons(items, setSuccessData, outputCopiedMsg);
};

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import type { MenuItem, Mode } from "vanilla-jsoneditor";
import { processTextModeItems, processTreeModeItems } from "./menuUtils";
@ -5,6 +6,16 @@ export const useMenuCustomization = (
setSuccessData: (data: { title: string }) => void,
setErrorData: (data: { title: string; list: string[] }) => void,
) => {
const { t } = useTranslation();
const messages = {
copyFailed: t("misc.copyFailed"),
editorNotAvailable: t("misc.editorNotAvailable"),
jsonCopied: t("success.jsonCopied"),
unableToCopy: t("misc.unableToCopy"),
copyJson: t("misc.copyJson"),
outputCopied: t("success.outputCopied"),
};
const customizeMenu = (
items: MenuItem[],
context: { mode: Mode; modal: boolean; readOnly: boolean },
@ -17,10 +28,15 @@ export const useMenuCustomization = (
getEditor,
setSuccessData,
setErrorData,
messages,
);
case "tree":
return processTreeModeItems(items, setSuccessData);
return processTreeModeItems(
items,
setSuccessData,
messages.outputCopied,
);
default:
// For all other modes, return items unchanged

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
import { ENABLE_MCP_COMPOSER } from "@/customization/feature-flags";
@ -25,6 +26,7 @@ export default function ToolsComponent({
template,
showParameter = true,
}: InputProps<any[] | undefined, ToolsComponentType>): JSX.Element | null {
const { t } = useTranslation();
const [isModalOpen, setIsModalOpen] = useState(false);
const actions = value
?.filter((action) => action.status === true)
@ -131,7 +133,7 @@ export default function ToolsComponent({
No actions added to this server
</span>
<Button size={"sm"} onClick={() => setIsModalOpen(true)}>
<span>Add actions</span>
<span>{t("input.addActions")}</span>
</Button>
</div>
)

View File

@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import {
@ -57,6 +58,7 @@ export default function AccordionPromptComponent({
showParameter = false,
isDoubleBrackets = false,
}: InputProps<string, PromptAreaComponentType>): JSX.Element {
const { t } = useTranslation();
const [isOpen, setIsOpen] = useState(true);
const [internalValue, setInternalValue] = useState(value);
const [isScrollable, setIsScrollable] = useState(false);
@ -564,7 +566,7 @@ export default function AccordionPromptComponent({
onClick={handleAddVariable}
disabled={disabled || readonly}
className="h-6 w-6 p-0 text-muted-foreground"
title="Add variable"
title={t("accordion.addVariable")}
>
<span className="text-xs">
{isDoubleBrackets ? "{{+}}" : "{+}"}
@ -632,7 +634,7 @@ export default function AccordionPromptComponent({
variant="ghost"
size="sm"
className="h-6 w-6 p-0 text-muted-foreground"
title="Fullscreen"
title={t("accordion.fullscreen")}
data-testid={
isDoubleBrackets
? "button_open_mustache_prompt_modal"

View File

@ -1,4 +1,5 @@
import { useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { GRADIENT_CLASS_DISABLED } from "@/constants/constants";
import { customGetHostProtocol } from "@/customization/utils/custom-get-host-protocol";
import useAlertStore from "@/stores/alertStore";
@ -61,6 +62,7 @@ export default function CopyFieldAreaComponent({
id = "",
showParameter = true,
}: InputProps<string, TextAreaComponentType>): JSX.Element | null {
const { t } = useTranslation();
const inputRef = useRef<HTMLInputElement>(null);
const [isFocused, setIsFocused] = useState(false);
const [isCopied, setIsCopied] = useState(false);
@ -96,7 +98,7 @@ export default function CopyFieldAreaComponent({
navigator.clipboard.writeText(valueToRender);
setSuccessData({
title: "Endpoint URL copied",
title: t("success.endpointUrlCopied"),
});
event?.stopPropagation();

View File

@ -7,6 +7,7 @@ import {
} from "@chakra-ui/number-input";
import { MinusIcon, PlusIcon } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { cn } from "@/utils/utils";
import { handleKeyDown } from "../../../../../utils/reactflowUtils";
import type { FloatComponentType, InputProps } from "../../types";
@ -20,6 +21,7 @@ export default function FloatComponent({
id = "",
showParameter = true,
}: InputProps<number, FloatComponentType>): JSX.Element | null {
const { t } = useTranslation();
const step = rangeSpec?.step ?? 0.1;
const min = rangeSpec?.min;
const max = rangeSpec?.max;
@ -105,7 +107,7 @@ export default function FloatComponent({
onKeyDown={(event) => handleKeyDown(event, localValue, "")}
onInput={handleInputChange}
disabled={disabled}
placeholder={editNode ? "Float number" : "Type a float number"}
placeholder={editNode ? t("input.floatNumberShort") : t("input.floatNumberFull")}
data-testid={id}
ref={inputRef}
onBlur={handleBlur}

View File

@ -1,4 +1,5 @@
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useGetGlobalVariables } from "@/controllers/API/queries/variables";
import GeneralDeleteConfirmationModal from "@/shared/components/delete-confirmation-modal";
import { looksLikeVariableName } from "../../../../../utils/reactflowUtils";
@ -30,6 +31,7 @@ export default function InputGlobalComponent({
hasRefreshButton = false,
showParameter = true,
}: InputProps<string, InputGlobalComponentType>): JSX.Element | null {
const { t } = useTranslation();
const {
data: globalVariables,
isFetchedAfterMount: isGlobalVariablesFetchedAfterMount,
@ -128,7 +130,7 @@ export default function InputGlobalComponent({
className={cn("mr-2 h-4 w-4 text-primary")}
aria-hidden="true"
/>
<span>Add New Variable</span>
<span>{t("input.addNewVariable")}</span>
</CommandItem>
</GlobalVariableModal>
);

View File

@ -1,5 +1,6 @@
import { cloneDeep } from "lodash";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Input } from "@/components/ui/input";
import { ICON_STROKE_WIDTH } from "@/constants/constants";
import {
@ -19,6 +20,7 @@ const KeypairListComponent = ({
id,
showParameter = true,
}) => {
const { t } = useTranslation();
const getTestId = (prefix, index) =>
`${editNode ? "editNode" : ""}${prefix}${index}`;
@ -130,7 +132,7 @@ const KeypairListComponent = ({
type="text"
value={key.trim()}
className={getInputClassName(editNode, duplicateKey)}
placeholder="Type key..."
placeholder={t("input.typeKey")}
onChange={(event) => handleChangeKey(event, index)}
/>
<Input
@ -140,7 +142,7 @@ const KeypairListComponent = ({
disabled={disabled}
value={obj[key]}
className={editNode ? "input-edit-node" : ""}
placeholder="Type a value..."
placeholder={t("input.typeValue")}
onChange={(event) => handleChangeValue(event, index)}
/>
<div className="hit-area-icon">

View File

@ -1,4 +1,5 @@
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useAddMCPServer } from "@/controllers/API/queries/mcp/use-add-mcp-server";
import { useGetMCPServers } from "@/controllers/API/queries/mcp/use-get-mcp-servers";
import AddMcpServerModal from "@/modals/addMcpServerModal";
@ -17,6 +18,7 @@ export default function McpComponent({
id = "",
showParameter = true,
}: InputProps<string, any>): JSX.Element | null {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const { data: mcpServers } = useGetMCPServers({ withCounts: true });
const { mutate: addMcpServer } = useAddMCPServer();
@ -102,7 +104,7 @@ export default function McpComponent({
},
onError: (error) => {
setErrorData({
title: "Error adding MCP server",
title: t("errors.addMcpServer"),
list: [error.message],
});
},
@ -197,7 +199,7 @@ export default function McpComponent({
onClick={handleAddButtonClick}
data-testid="add-mcp-server-simple-button"
>
<span>Add MCP Server</span>
<span>{t("input.addMcpServer")}</span>
</Button>
)}
{options && (

View File

@ -147,7 +147,7 @@ export default function MultiselectComponent({
onChange={(event) => {
setSearchValue(event.target.value);
}}
placeholder="Search options..."
placeholder={t("input.searchOptions")}
className="flex h-9 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
/>
<Button

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import IconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { Button } from "@/components/ui/button";
@ -24,6 +25,7 @@ export default function TableOptions({
tableOptions?: TableOptionsTypeAPI;
paginationInfo?: string;
}): JSX.Element {
const { t } = useTranslation();
const [tabIndex, setTabIndex] = useState(-1);
useEffect(() => {
@ -37,7 +39,7 @@ export default function TableOptions({
<div className="flex items-center gap-3">
{addRow && !tableOptions?.block_add && (
<div>
<ShadTooltip content={"Add a new row"}>
<ShadTooltip content={t("table.addRow")}>
<Button
data-testid="add-row-button"
unstyled
@ -57,9 +59,9 @@ export default function TableOptions({
<ShadTooltip
content={
!hasSelection ? (
<span>Select items to duplicate</span>
<span>{t("table.selectToDuplicate")}</span>
) : (
<span>Duplicate selected items</span>
<span>{t("table.duplicateSelected")}</span>
)
}
>
@ -88,9 +90,9 @@ export default function TableOptions({
<ShadTooltip
content={
!hasSelection ? (
<span>Select items to delete</span>
<span>{t("table.selectToDelete")}</span>
) : (
<span>Delete selected items</span>
<span>{t("table.deleteSelected")}</span>
)
}
>
@ -115,7 +117,7 @@ export default function TableOptions({
</div>
)}{" "}
<div>
<ShadTooltip content="Reset Columns">
<ShadTooltip content={t("table.resetColumns")}>
<Button
data-testid="reset-columns-button"
unstyled

View File

@ -1,4 +1,5 @@
import React from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
@ -15,6 +16,8 @@ export function ChatHeaderActions({
onClose,
renderPrefix,
}: ChatHeaderActionsProps) {
const { t } = useTranslation();
if (!onToggleFullscreen) {
return null;
}
@ -31,8 +34,8 @@ export function ChatHeaderActions({
variant="ghost"
size="icon"
className={actionButtonClasses}
title="Enter fullscreen"
aria-label="Enter fullscreen"
title={t("playgroundComponent.enterFullscreen")}
aria-label={t("playgroundComponent.enterFullscreen")}
>
<ForwardedIconComponent
name="Expand"
@ -47,8 +50,8 @@ export function ChatHeaderActions({
size="icon"
onClick={onClose}
className={actionButtonClasses}
title="Close and go back to flow"
aria-label="Close and go back to flow"
title={t("playgroundComponent.closeAndGoBack")}
aria-label={t("playgroundComponent.closeAndGoBack")}
data-testid="playground-close-button"
>
<ForwardedIconComponent

View File

@ -1,4 +1,5 @@
import React, { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { AnimatedConditional } from "@/components/ui/animated-close";
import useAlertStore from "@/stores/alertStore";
import { cn } from "@/utils/utils";
@ -30,6 +31,7 @@ export function ChatHeader({
onClearChat,
}: ChatHeaderProps & { sessions: string[] }) {
// State to coordinate menu open/close
const { t } = useTranslation();
const [sessionsDropdownOpen, setSessionsDropdownOpen] = useState(false);
const [moreMenuOpen, setMoreMenuOpen] = useState(false);
// Determine the title based on the current session
@ -57,13 +59,13 @@ export function ChatHeader({
const handleDeleteSessionInternal = () => {
if (!currentSessionId || isDefaultSession || !currentFlowId) return;
onDeleteSession?.(currentSessionId);
setSuccessData({ title: "Session deleted successfully." });
setSuccessData({ title: t("success.sessionDeleted") });
};
const handleClearChat = () => {
if (!currentSessionId || !isDefaultSession || !currentFlowId) return;
onClearChat?.();
setSuccessData({ title: "Chat cleared successfully." });
setSuccessData({ title: t("success.chatCleared") });
};
const { onMessageLogs } = useSessionMoreMenuHandlers({
@ -91,7 +93,7 @@ export function ChatHeader({
sideOffset={4}
contentClassName="z-[100] [&>div.p-1]:!h-auto [&>div.p-1]:!min-h-0"
isVisible={true}
tooltipContent="More options"
tooltipContent={t("playgroundComponent.moreOptions")}
tooltipSide="left"
dataTestid="chat-header-more-menu"
open={moreMenuOpen}

View File

@ -1,4 +1,5 @@
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import {
@ -29,6 +30,7 @@ export function ChatSessionsDropdown({
open: controlledOpen,
onOpenChange: controlledOnOpenChange,
}: ChatSessionsDropdownProps) {
const { t } = useTranslation();
const currentFlowId = useGetFlowId();
const hasSessions: boolean = sessions.length > 0;
const [internalOpen, setInternalOpen] = useState(false);
@ -44,7 +46,7 @@ export function ChatSessionsDropdown({
variant="ghost"
size="icon"
className="h-8 w-8 rounded"
aria-label="Chat sessions"
aria-label={t("playgroundComponent.chatSessions")}
data-testid="session-selector-trigger"
>
<ForwardedIconComponent name="ListRestart" className="h-4 w-4" />

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import {
@ -58,6 +59,7 @@ export function SessionMoreMenu({
open: controlledOpen,
onOpenChange: controlledOnOpenChange,
}: SessionMoreMenuProps) {
const { t } = useTranslation();
const [selectValue, setSelectValue] = useState("");
const [internalOpen, setInternalOpen] = useState(false);
@ -136,7 +138,7 @@ export function SessionMoreMenu({
name="SquarePen"
className="mr-2 h-4 w-4"
/>
Rename
{t("playgroundComponent.rename")}
</div>
</SelectItem>
)}
@ -151,7 +153,7 @@ export function SessionMoreMenu({
name="Scroll"
className="mr-2 h-4 w-4"
/>
Message logs
{t("playgroundComponent.messageLogs")}
</div>
</SelectItem>
)}
@ -163,7 +165,7 @@ export function SessionMoreMenu({
>
<div className="flex items-center text-status-red hover:text-status-red">
<ForwardedIconComponent name="X" className="mr-2 h-4 w-4" />
Clear chat
{t("playgroundComponent.clearChat")}
</div>
</SelectItem>
)}
@ -178,7 +180,7 @@ export function SessionMoreMenu({
name="Trash2"
className="mr-2 h-4 w-4"
/>
{isDefaultSession ? "Clear session" : "Delete session"}
{isDefaultSession ? t("playgroundComponent.clearSession") : t("playgroundComponent.deleteSession")}
</div>
</SelectItem>
)}

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ShadTooltip from "@/components/common/shadTooltipComponent";
import { useUpdateSessionName } from "@/controllers/API/queries/messages/use-rename-session";
@ -43,6 +44,7 @@ export function SessionSelector({
onToggleSelect,
showCheckbox = false,
}: SessionSelectorProps) {
const { t } = useTranslation();
const [isEditing, setIsEditing] = useState(false);
const { mutate: updateSessionName } = useUpdateSessionName();
const setNewSessionCloseVoiceAssistant = useVoiceStore(
@ -174,7 +176,7 @@ export function SessionSelector({
sideOffset={4}
contentClassName="z-[100] [&>div.p-1]:!h-auto [&>div.p-1]:!min-h-0"
isVisible={true}
tooltipContent="More options"
tooltipContent={t("playgroundComponent.moreOptions")}
tooltipSide="left"
open={menuOpen}
onOpenChange={onMenuOpenChange}

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { ENABLE_FILES_ON_PLAYGROUND } from "@/customization/feature-flags";
import type { FilePreviewType } from "@/types/components";
import FilePreviewDisplay from "../../utils/file-preview-display";
@ -44,6 +45,7 @@ const InputWrapper = ({
onStopRecording,
isAudioSupported,
}: InputWrapperProps) => {
const { t } = useTranslation();
const classNameFilePreview = `flex w-full items-center gap-2 py-2 overflow-auto`;
const onClick = (e: React.MouseEvent<HTMLDivElement>) => {
@ -89,7 +91,7 @@ const InputWrapper = ({
onKeyDown={onKeyDown}
role="button"
tabIndex={0}
aria-label="Focus chat input"
aria-label={t("playgroundComponent.focusChatInput")}
>
{/* Text input area */}
<div className="w-full">

View File

@ -1,4 +1,5 @@
import { memo, useState } from "react";
import { useTranslation } from "react-i18next";
import LangflowLogo from "@/assets/LangflowLogo.svg?react";
import IconComponent, {
ForwardedIconComponent,
@ -25,6 +26,7 @@ import { EditMessageButton } from "./message-options";
export const BotMessage = memo(
({ chat, lastMessage, updateChat, playgroundPage }: chatMessagePropsType) => {
const { t } = useTranslation();
const setErrorData = useAlertStore((state) => state.setErrorData);
const [editMessage, setEditMessage] = useState(false);
const isBuilding = useFlowStore((state) => state.isBuilding);
@ -65,7 +67,7 @@ export const BotMessage = memo(
},
onError: () => {
setErrorData({
title: "Error updating messages.",
title: t("errors.updatingMessages"),
});
},
},
@ -96,7 +98,7 @@ export const BotMessage = memo(
{
onError: () => {
setErrorData({
title: "Error updating messages.",
title: t("errors.updatingMessages"),
});
},
},

View File

@ -54,7 +54,7 @@ export const UserMessage = memo(
},
onError: () => {
setErrorData({
title: "Error updating messages.",
title: t("errors.updatingMessages"),
});
},
},
@ -88,7 +88,7 @@ export const UserMessage = memo(
{
onError: () => {
setErrorData({
title: "Error updating messages.",
title: t("errors.updatingMessages"),
});
},
},

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
import Loading from "@/components/ui/loading";
import { cn } from "@/utils/utils";
@ -56,6 +57,7 @@ export default function FilePreviewDisplay({
variant = "compact",
className,
}: FilePreviewDisplayProps) {
const { t } = useTranslation();
const [imageError, setImageError] = useState(false);
const previewUrl = getFilePreviewUrl(file);
const fileInfo = extractFileInfo(file);
@ -111,7 +113,7 @@ export default function FilePreviewDisplay({
onClick={onDelete}
className="absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-destructive text-destructive-foreground hover:bg-destructive/90"
type="button"
aria-label="Delete file"
aria-label={t("playgroundComponent.deleteFile")}
>
<ForwardedIconComponent name="X" className="h-3 w-3" />
</button>

View File

@ -1,4 +1,5 @@
import { useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { NEW_SESSION_NAME } from "@/constants/constants";
import { useDeleteSession } from "@/controllers/API/queries/messages/use-delete-sessions";
import { useBulkDeleteSessions } from "@/controllers/API/queries/messages/use-bulk-delete-sessions";
@ -34,6 +35,7 @@ export function useSessionManager({ flowId }: UseSessionManagerProps) {
const deleteSessionFromMessagesStore = useMessagesStore(
(state) => state.deleteSession,
);
const { t } = useTranslation();
const setErrorData = useAlertStore((state) => state.setErrorData);
const { data: dbSessionsResponse } = useGetSessionsFromFlowQuery({
@ -46,8 +48,8 @@ export function useSessionManager({ flowId }: UseSessionManagerProps) {
const { mutateAsync: updateSessionName } = useUpdateSessionName();
const notifyDeleteSessionError = useCallback(() => {
setErrorData({ title: "Error deleting session." });
}, [setErrorData]);
setErrorData({ title: t("errors.deleteSession") });
}, [setErrorData, t]);
// Initialize store when flowId changes
useEffect(() => {
@ -130,7 +132,7 @@ export function useSessionManager({ flowId }: UseSessionManagerProps) {
});
renameSessionInStore(oldId, newId);
} catch {
setErrorData({ title: "Error renaming session." });
setErrorData({ title: t("errors.renamingSession") });
}
},
[updateSessionName, renameSessionInStore, setErrorData],

View File

@ -5,6 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { PanelLeft } from "lucide-react";
import * as React from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useTranslation } from "react-i18next";
import { useIsMobile } from "@/hooks/use-mobile";
import isWrappedWithClass from "../../pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class";
import { useShortcutsStore } from "../../stores/shortcuts";
@ -405,16 +406,17 @@ const SidebarRail = React.forwardRef<
HTMLButtonElement,
React.ComponentProps<"button">
>(({ className, ...props }, ref) => {
const { t } = useTranslation();
const { toggleSidebar } = useSidebar();
return (
<button
ref={ref}
data-sidebar="rail"
aria-label="Toggle Sidebar"
aria-label={t("ui.toggleSidebar")}
tabIndex={-1}
onClick={toggleSidebar}
title="Toggle Sidebar"
title={t("ui.toggleSidebar")}
className={cn(
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
"[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize",

View File

@ -4,6 +4,7 @@ import { motion } from "framer-motion";
import { Play } from "lucide-react";
import * as React from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { useTranslation } from "react-i18next";
import isWrappedWithClass from "../../pages/FlowPage/components/PageComponent/utils/is-wrapped-with-class";
import { cn } from "../../utils/utils";
import { AnimatedConditional } from "./animated-close";
@ -245,6 +246,7 @@ const SimpleSidebarResizeHandle = React.forwardRef<
side?: "left" | "right";
}
>(({ side = "right", className, ...props }, ref) => {
const { t } = useTranslation();
const { setWidth, width, setIsResizing, isResizing } = useSimpleSidebar();
const [dragStartX, setDragStartX] = React.useState(0);
const [dragStartWidth, setDragStartWidth] = React.useState(0);
@ -324,7 +326,7 @@ const SimpleSidebarResizeHandle = React.forwardRef<
)}
onMouseDown={handleMouseDown}
onKeyDown={handleKeyDown}
aria-label="Resize sidebar (use arrow keys or drag to resize)"
aria-label={t("ui.resizeSidebar")}
{...props}
>
{/* Visual indicator */}

View File

@ -1,5 +1,6 @@
import { useQueryClient } from "@tanstack/react-query";
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { api } from "@/controllers/API/api";
import { getURL } from "@/controllers/API/helpers/constants";
import useApplyFlowToCanvas from "@/hooks/flows/use-apply-flow-to-canvas";
@ -7,6 +8,7 @@ import useAlertStore from "@/stores/alertStore";
import useVersionPreviewStore from "@/stores/versionPreviewStore";
export default function useRestoreVersion(flowId: string) {
const { t } = useTranslation();
const queryClient = useQueryClient();
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
@ -41,7 +43,7 @@ export default function useRestoreVersion(flowId: string) {
const apiDetail = err?.response?.data?.detail;
const message = apiDetail ?? err?.message ?? "Unknown error";
setErrorData({
title: "Failed to restore version",
title: t("errors.failedToRestoreVersion"),
list: [message],
});
setIsRestoring(false);
@ -54,7 +56,7 @@ export default function useRestoreVersion(flowId: string) {
try {
useVersionPreviewStore.setState({ didRestore: true });
clearPreview();
setSuccessData({ title: "Version restored" });
setSuccessData({ title: t("success.versionRestored") });
options?.onSuccess?.();
} catch (err) {
console.error("useRestoreVersion: post-restore cleanup failed", err);

View File

@ -1,4 +1,5 @@
import type { ReactFlowJsonObject } from "@xyflow/react";
import { useTranslation } from "react-i18next";
import { useGetFlow } from "@/controllers/API/queries/flows/use-get-flow";
import { usePatchUpdateFlow } from "@/controllers/API/queries/flows/use-patch-update-flow";
import useAlertStore from "@/stores/alertStore";
@ -8,6 +9,7 @@ import type { AllNodeType, EdgeType, FlowType } from "@/types/flow";
import { customStringify } from "@/utils/reactflowUtils";
const useSaveFlow = () => {
const { t } = useTranslation();
const setFlows = useFlowsManagerStore((state) => state.setFlows);
const setErrorData = useAlertStore((state) => state.setErrorData);
const setSaveLoading = useFlowsManagerStore((state) => state.setSaveLoading);
@ -104,8 +106,8 @@ const useSaveFlow = () => {
resolve();
} else {
setErrorData({
title: "Failed to save flow",
list: ["Flows variable undefined"],
title: t("errors.failedToSaveFlow"),
list: [t("errors.flowsVariableUndefined")],
});
reject(new Error("Flows variable undefined"));
}
@ -114,7 +116,7 @@ const useSaveFlow = () => {
const detail =
e.response?.data?.detail || e.message || "Unknown error";
setErrorData({
title: "Failed to save flow",
title: t("errors.failedToSaveFlow"),
list: [detail],
});
setSaveLoading(false);
@ -124,8 +126,8 @@ const useSaveFlow = () => {
);
} else {
setErrorData({
title: "Failed to save flow",
list: ["Flow not found"],
title: t("errors.failedToSaveFlow"),
list: [t("errors.flowNotFound")],
});
reject(new Error("Flow not found"));
}

View File

@ -1,5 +1,6 @@
import { QueryClient, useQueryClient } from "@tanstack/react-query";
import { useCallback, useRef } from "react";
import i18n from "../i18n";
import { api } from "@/controllers/API/api";
import { getURL } from "@/controllers/API/helpers/constants";
import useAlertStore from "@/stores/alertStore";
@ -111,7 +112,7 @@ export async function refreshAllModelInputs(
if (nodesWithModelFields.length === 0) {
if (showNotifications) {
setSuccessData({ title: "No model components to refresh" });
setSuccessData({ title: (i18n as any).t("errors.noModelsToRefresh") });
}
return;
}
@ -126,14 +127,13 @@ export async function refreshAllModelInputs(
if (showNotifications) {
const count = nodesWithModelFields.length;
const plural = count > 1 ? "s" : "";
setSuccessData({ title: `Refreshed ${count} model component${plural}` });
setSuccessData({ title: (i18n as any).t("alerts.modelsRefreshed", { count }) });
}
} catch (error) {
console.error("Error refreshing model inputs:", error);
if (showNotifications) {
setErrorData({
title: "Error refreshing model components",
title: (i18n as any).t("errors.refreshingModels"),
list: [(error as Error)?.message || "An unexpected error occurred"],
});
}

View File

@ -1,4 +1,6 @@
{
"accordion.addVariable": "Variable hinzufügen",
"accordion.fullscreen": "Vollbildschirm",
"account.adminPage": "Verwaltungsseite",
"account.discord": "Discord",
"account.docs": "Dokumente",
@ -32,12 +34,32 @@
"admin.saveButton": "Speichern",
"admin.searchPlaceholder": "Benutzername suchen",
"alerts.apiKeyCopied": "API-Schlüssel kopiert!",
"alerts.buildStopped": "Der Build wurde angehalten",
"alerts.criticalDataWarning": "Warnung: Sensible Daten die JSON-Datei enthält möglicherweise API-Schlüssel.",
"alerts.modelsRefreshed_one": "Aktualisierte Modellkomponente „ {{count}} “",
"alerts.modelsRefreshed_other": "Aktualisierte Komponenten des Modells „ {{count}} “",
"alerts.noChatOutput": "Im Ablauf ist keine „ ChatOutput “-Komponente vorhanden.",
"alerts.noTemplateVariables": "Ihre Vorlage enthält keine Variablen.",
"assistant.code": "Code erstellen",
"assistant.configureModels": "Modellanbieter konfigurieren",
"assistant.continue": "Weiter",
"assistant.maxSessionsLabel": "Max. Sitzungen",
"assistant.maxSessionsTooltip": "Die maximale Anzahl von {{max}} -Sitzungen wurde erreicht. Löschen Sie eine Sitzung, um eine neue zu erstellen.",
"assistant.messageCounts": "{{count}} Nachrichten",
"assistant.newSession": "Neue Sitzung",
"assistant.noModelsConfigured": "Es ist kein Modellanbieter konfiguriert",
"assistant.noModelsDescription": "Um den Assistenten nutzen zu können, konfigurieren Sie bitte mindestens einen Modellanbieter in Ihren Einstellungen.",
"assistant.noPreviousSessions": "Keine früheren Sitzungen",
"assistant.sendMessage": "Nachricht senden",
"assistant.sessionHistory": "Sitzungsverlauf",
"assistant.sessionHistoryLabel": "Sitzungsverlauf",
"assistant.sessionHistoryTooltip": "Sitzungen werden ausschließlich in Ihrem Browser gespeichert und bleiben weder in anderen Browsern noch nach dem Löschen der Browserdaten erhalten.",
"assistant.stopGeneration": "Erstellung stoppen",
"assistant.workingOnIt": "Ich arbeite daran...",
"auth.adminLoginButton": "Anmeldung",
"auth.adminTitle": "Administrator",
"auth.alertSaveWithApi": "⚠️ Achtung: Durch das Exportieren dieses Flows können vertrauliche Anmeldedaten offengelegt werden.",
"auth.confirmPassword": "Kennwort bestätigen",
"auth.confirmPasswordLabel": "Bestätigen Sie Ihr Passwort",
"auth.confirmPasswordPlaceholder": "Bestätigen Sie Ihr Passwort",
"auth.confirmPasswordRequired": "Bitte bestätigen Sie Ihr Passwort",
@ -58,6 +80,7 @@
"auth.signupTitle": "Bei Langflow anmelden",
"auth.usernameLabel": "Benutzername",
"auth.usernamePlaceholder": "Benutzername",
"auth.usernamePlaceholderInput": "Benutzername",
"auth.usernameRequired": "Bitte gib deinen Benutzernamen ein",
"authModal.apiKey.autoInstall": "erstellt einen Schlüssel und fügt ihn in das ausgewählte Client-Profil auf diesem Rechner ein.",
"authModal.apiKey.autoInstallBold": "Automatisches Installieren",
@ -89,6 +112,7 @@
"authModal.reinstallWarningClients": "Um den Authentifizierungstyp zu ändern, muss dieser Server unter {{clients}} sowie auf allen anderen Clients, auf denen er verwendet wird, neu installiert werden.",
"authModal.saveButton": "Speichern",
"authModal.title": "MCP-Server-Authentifizierung konfigurieren",
"canvas.addStickyNote": "Haftnotiz hinzufügen",
"canvas.agentWorking": "Agent im Einsatz",
"canvas.controls": "Canvas-Steuerelemente",
"canvas.fitViewTooltip": "Ansicht anpassen, um alle Knoten anzuzeigen",
@ -129,6 +153,99 @@
"deleteModal.noteFolderContents": "sowie alle damit verbundenen Abläufe und Komponenten",
"deleteModal.noteMessageHistory": "und den Nachrichtenverlauf",
"deleteModal.title": "Löschen",
"deployments.addVariable": "+ Variable hinzufügen",
"deployments.agentChat": "Agenten-Chat",
"deployments.ariaDeploymentType": "Bereitstellungstyp",
"deployments.ariaExistingEnvironments": "Vorhandene Umgebungen",
"deployments.ariaSendMessage": "Nachricht senden",
"deployments.attachConnectionToFlow": "Verbindung an den Fluss anhängen",
"deployments.attachFlows": "Flüsse anhängen",
"deployments.attachedFlowsCount": "Beigefügte Flows ( {{count}} )",
"deployments.attachedFlowsLabel": "Angehängte Abläufe",
"deployments.availableConnections": "Verfügbare Verbindungen",
"deployments.availableFlows": "Verfügbare Durchflussmengen",
"deployments.back": "Zurück",
"deployments.cancel": "Abbrechen",
"deployments.changeFlow": "Änderungsablauf",
"deployments.close": "Schließen",
"deployments.columnAttached": "Angehängt",
"deployments.columnCreated": "Erstellungsdatum",
"deployments.columnLastModified": "Letzte Änderung",
"deployments.columnName": "Ihren Namen",
"deployments.columnProvider": "Einbindung",
"deployments.columnProviderKey": "Anbieterschlüssel",
"deployments.columnTest": "Testen",
"deployments.columnType": "Typ",
"deployments.columnUrl": "URL",
"deployments.confirm": "Bestätigen",
"deployments.connecting": "Verbindung wird hergestellt...",
"deployments.connectionNameExists": "Es gibt bereits einen Eintrag mit diesem Namen.",
"deployments.connectionNameLabel": "Verbindungsname",
"deployments.createConnection": "Verbindung erstellen",
"deployments.createFirstConnection": "Stellen Sie Ihre erste Verbindung her",
"deployments.createNewDeployment": "Neue Bereitstellung erstellen",
"deployments.createNewDeploymentTitle": "Neue Bereitstellung erstellen",
"deployments.current": "Aktuell",
"deployments.deploy": "Bereitstellung",
"deployments.deploying": "Wird implementiert ...",
"deployments.deploymentLabel": "Bereitstellung",
"deployments.deploymentType": "Bereitstellungstyp",
"deployments.detachFlow": "Fluss trennen",
"deployments.detaching": "Lösen",
"deployments.editToolName": "Name des Bearbeitungswerkzeugs",
"deployments.environmentVariables": "Umgebungsvariablen",
"deployments.existingConnections": "Vorhandene Verbindungen",
"deployments.failedToLoadFlows": "Die angehängten Abläufe konnten nicht geladen werden",
"deployments.globalVariables": "Globale Variablen",
"deployments.labelCreated": "Erstellungsdatum",
"deployments.labelDesc": "Absteigend",
"deployments.labelModel": "Modell",
"deployments.labelModified": "Geändert",
"deployments.labelName": "Ihren Namen",
"deployments.labelProvider": "Einbindung",
"deployments.labelType": "Typ",
"deployments.loadingAttachedFlows": "Anhängende Abläufe werden geladen...",
"deployments.loadingDeploymentData": "Bereitstellungsdaten werden geladen...",
"deployments.new": "Neu",
"deployments.newConnections": "Neue Verbindungen",
"deployments.next": "Weiter",
"deployments.noConnectionsDescription": "Erstellen Sie eine Verbindung, um diesem Ablauf Anmeldedaten zuzuweisen.",
"deployments.noConnectionsMatch": "Es wurden keine Treffer für „ \"{{query}}\" “ gefunden",
"deployments.noConnectionsYet": "Noch keine Verbindungen",
"deployments.noDeployments": "Keine Bereitstellungen",
"deployments.noEnvironments": "Keine Umgebungen",
"deployments.noFlowsAttached": "Keine Strömungen verbunden",
"deployments.placeholderAgentPurpose": "Beschreiben Sie den Zweck des Agenten...",
"deployments.placeholderApiKey": "Geben Sie Ihren API-Schlüssel ein",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderConnectionName": "z. B. SALES_BOT_PROD",
"deployments.placeholderEnvironmentName": "z. B. Produktion",
"deployments.placeholderKey": "Schlüssel",
"deployments.placeholderMessage": "Nachricht",
"deployments.placeholderSalesBot": "z. B. Verkaufsbot",
"deployments.placeholderSearchConnections": "Verbindungen suchen ...",
"deployments.placeholderValue": "Wert",
"deployments.provider": "Einbindung",
"deployments.removing": "entfernen",
"deployments.review": "Prüfen",
"deployments.reviewAndConfirm": "Überprüfen & Bestätigen",
"deployments.reviewDetails": "Überprüfen Sie die Details Ihrer Bereitstellung, bevor Sie diese erstellen.",
"deployments.reviewUpdate": "Aktualisierung der Rezension",
"deployments.selectDeployment": "Bereitstellung auswählen",
"deployments.selectOrCreateConnection": "Verbindung auswählen oder neu erstellen",
"deployments.selectProvider": "Provider auswählen",
"deployments.skip": "Überspringen",
"deployments.stepOf": "Schritt {{current}} von {{total}}",
"deployments.test": "Testen",
"deployments.toolsWillBeDetached": "Diese Tools werden vom Agenten getrennt. Sie bleiben in Ihrem Provider-Tenant verfügbar.",
"deployments.undoDetach": "Rückgängig machen / Trennen",
"deployments.unknownFlow": "Unbekannter Durchfluss",
"deployments.untitled": "Unbenannt",
"deployments.update": "Aktualisieren!",
"deployments.updateDeployment": "Aktualisierung bereitstellen",
"deployments.updating": "Aktualisierung wird durchgeführt ...",
"deployments.variablesAutoDetected_one": "{{count}} Variable, die automatisch aus der ausgewählten Flow-Version ermittelt wird.",
"deployments.variablesAutoDetected_other": "{{count}} Variablen, die automatisch aus der ausgewählten Flow-Version erkannt wurden.",
"dialog.chat": "Kommuniziere mit deiner KI. Überwachen Sie Eingänge, Ausgänge und Speicher.",
"dialog.code": "Exportieren Sie Ihren Flow, um ihn mithilfe dieses Codes zu integrieren.",
"dialog.codeDict": "Passen Sie Ihr Wörterbuch an, indem Sie nach Bedarf Schlüssel-Wert-Paare hinzufügen oder bearbeiten. Unterstützt das Hinzufügen neuer Objekte {} oder Arrays [].",
@ -147,6 +264,7 @@
"emptyPage.emptyProject": "Leeres Projekt",
"emptyPage.newFlow": "Neuer Ablauf",
"emptyPage.startBuilding": "Erstellung starten",
"errors.addMcpServer": "Fehler beim Hinzufügen des MCP-Servers",
"errors.addUser": "Fehler beim Hinzufügen eines neuen Benutzers",
"errors.apiKey": "Fehler beim API-Schlüssel",
"errors.changePassword": "Fehler beim Ändern des Passworts",
@ -156,8 +274,15 @@
"errors.deleteKeys": "Fehler beim Löschen von Schlüsseln",
"errors.deleteSession": "Fehler beim Löschen der Sitzung.",
"errors.deleteUser": "Fehler beim Löschen eines Benutzers",
"errors.deletingMessages": "Fehler beim Löschen von Nachrichten.",
"errors.editUser": "Fehler beim Bearbeiten des Benutzers",
"errors.failedToExportFlow": "Der Export des Ablaufs ist fehlgeschlagen",
"errors.failedToLoadDeployment": "Die Bereitstellungsdetails konnten nicht geladen werden",
"errors.failedToRestoreVersion": "Die Wiederherstellung der Version ist fehlgeschlagen",
"errors.failedToSaveFlow": "Das Speichern des Ablaufs ist fehlgeschlagen",
"errors.fileTooLarge": "Die Datei ist zu groß. Bitte wählen Sie eine Datei aus, die kleiner als {{maxSizeMB}} ist.",
"errors.flowNotFound": "Fluss nicht gefunden",
"errors.flowsVariableUndefined": "Variable „Flows“ nicht definiert",
"errors.function": "In Ihrer Funktion ist ein Fehler",
"errors.generic": "Es ist ein Fehler aufgetreten. Bitte versuche es erneut",
"errors.getComponents": "Fehler beim Abrufen der Komponenten.",
@ -169,14 +294,22 @@
"errors.missedFields": "Hoppla! Du hast wohl etwas übersehen",
"errors.missingInfo": "Hoppla! Es sieht so aus, als hättest du einige erforderliche Angaben vergessen:",
"errors.noApiKey": "Sie haben keinen API-Schlüssel. Bitte fügen Sie einen hinzu, um den Langflow Store zu nutzen.",
"errors.noDataToExport": "Es sind keine Daten zum Exportieren verfügbar",
"errors.noModelsToRefresh": "Es sind keine Modellkomponenten zu aktualisieren",
"errors.parameterNotFound": "Parameter in der Vorlage nicht gefunden",
"errors.passwordMismatch": "Kennwörter stimmen nicht überein",
"errors.profilePictures": "Fehler beim Abrufen der Profilbilder",
"errors.prompt": "Mit dieser Eingabeaufforderung stimmt etwas nicht. Bitte überprüfe sie",
"errors.refreshingModels": "Fehler beim Aktualisieren der Modellkomponenten",
"errors.renamingSession": "Fehler beim Umbenennen der Sitzung.",
"errors.saveApiKey": "Beim Speichern des API-Schlüssels ist ein Fehler aufgetreten. Bitte versuche es erneut.",
"errors.saveChanges": "Fehler beim Speichern der Änderungen",
"errors.sendMessage": "Beim Senden der Nachricht ist ein Fehler aufgetreten",
"errors.signin": "Fehler beim Anmelden",
"errors.signup": "Fehler bei der Anmeldung",
"errors.templateNotFound": "Vorlage in der Komponente nicht gefunden",
"errors.tooManyFiles": "Es wurden zu viele Dateien erkannt ( {{count}} ). Dazu gehören wahrscheinlich auch große bzw. versteckte Verzeichnisse. Bitte wählen Sie einen kleineren Ordner aus oder schließen Sie Ordner wie „node_modules“ aus.",
"errors.updatingMessages": "Fehler beim Aktualisieren der Nachrichten.",
"errors.upload": "Fehler beim Hochladen der Datei",
"errors.uploadFile": "Beim Hochladen der Datei ist ein Fehler aufgetreten",
"errors.uploadJsonOnly": "Bitte laden Sie eine JSON-Datei hoch",
@ -191,6 +324,7 @@
"fileManager.errorUploadingFileDetail": "Beim Hochladen der Datei ist ein Fehler aufgetreten",
"fileManager.fileUploadedSuccessfully": "Datei erfolgreich hochgeladen",
"fileManager.filesUploadedSuccessfully": "Dateien erfolgreich hochgeladen",
"fileManager.searchFiles": "Dateien suchen...",
"fileManager.selectAtLeastOneFile": "Bitte wählen Sie mindestens eine Datei aus",
"fileManager.selectFile": "Datei auswählen",
"fileManager.selectFiles": "Dateien auswählen",
@ -214,11 +348,15 @@
"files.uploadFile": "Datei hochladen",
"files.uploadFiles": "Dateien hochladen",
"files.uploadedSuccessfully": "Datei erfolgreich hochgeladen",
"flow.addDescription": "Beschreibung hinzufügen...",
"flow.brokenEdgesWarning": "Einige Verbindungen wurden entfernt, da sie ungültig waren:",
"flow.buildStatus": "Erstellen, um den Status zu überprüfen.",
"flow.buildSuccess": "Erfolgreich erstellt ✨",
"flow.characterLimitReached": "Zeichenlimit erreicht",
"flow.defaultName": "Neuer Ablauf",
"flow.deletedSuccessfully": "Die ausgewählten Elemente wurden erfolgreich gelöscht",
"flow.descriptionLabel": "Beschreibung",
"flow.descriptionPlaceholder": "Beschreibung des Ablaufs",
"flow.duplicatedSuccess": "{{type}} Erfolgreich dupliziert",
"flow.enableAutoSaving": "Automatisches Speichern aktivieren",
"flow.errorDeleting": "Fehler beim Löschen von Elementen",
@ -226,14 +364,27 @@
"flow.exitAnyway": "Trotzdem beenden",
"flow.lastSaved": "Zuletzt gespeichert: {{time}}",
"flow.lastSavedNever": "Niemals",
"flow.lockFlow": "Durchfluss sperren",
"flow.lockFlowDescription": "Sperren Sie Ihren Fluss, um Bearbeitungen oder versehentliche Änderungen zu verhindern.",
"flow.menu.delete": "Löschen",
"flow.menu.duplicate": "Duplikat",
"flow.menu.editDetails": "Details bearbeiten",
"flow.menu.export": "Exportieren",
"flow.minimumCharacters": "Mindestens {{count}} Zeichen erforderlich",
"flow.missingFields": "Bitte füllen Sie alle Pflichtfelder aus.",
"flow.moreOptions": "Weitere Optionen",
"flow.nameAlreadyExists": "Der Name des Flusses ist bereits vorhanden",
"flow.nameLabel": "Ihren Namen",
"flow.namePlaceholder": "Ablaufname",
"flow.noCompatibleComponents": "Es wurden keine kompatiblen Komponenten gefunden.",
"flow.noDescription": "Keine Beschreibung",
"flow.pleaseEnterDescription": "Bitte geben Sie eine Beschreibung ein",
"flow.pleaseEnterName": "Bitte gib einen Namen ein",
"flow.replaceComponent": "Ersetzen",
"flow.restoreVersion": "Diese Version Ihres Ablaufs wiederherstellen",
"flow.runTimestampPrefix": "Letzter Lauf: ",
"flow.saveAndExit": "Speichern und beenden",
"flow.saveVersion": "Speichere eine Version deines Ablaufs",
"flow.savedHover": "Zuletzt gespeichert: ",
"flow.savedSuccessfully": "Der Ablauf wurde erfolgreich gespeichert!",
"flow.savingChanges": "Änderungen werden gespeichert...",
@ -299,15 +450,24 @@
"home.dragFlowType": "Lade hier dein „ {{flowType}} “ hoch",
"home.dragFlowsOrComponents": "Lade deine Flows oder Komponenten hier hoch",
"home.flowTypeNotSupported": "{{flowType}} wird nicht unterstützt",
"input.addActions": "Aktionen hinzufügen",
"input.addMcpServer": "MCP-Server hinzufügen",
"input.addNewVariable": "Neue Variable hinzufügen",
"input.editCodeTitle": "Code bearbeiten",
"input.editTextPlaceholder": "Geben Sie hier Ihre Nachricht ein.",
"input.editTextTitle": "Text bearbeiten",
"input.emptyOutput": "Die Nachricht ist leer.",
"input.errorUpdatingComponent": "Beim Aktualisieren der Komponente ist ein unerwarteter Fehler aufgetreten. Wiederholen Sie bitte den Vorgang.",
"input.floatNumberFull": "Geben Sie eine Fließkommazahl ein",
"input.floatNumberShort": "Float-Zahl",
"input.noInputMessage": "Es wurde keine Eingabemeldung angegeben.",
"input.placeholder": "Geben Sie etwas ein ...",
"input.searchOptions": "Suchoptionen...",
"input.titleErrorUpdatingComponent": "Fehler beim Aktualisieren der Komponente",
"input.toolsetPlaceholder": "Als Werkzeug verwendet",
"input.typeKey": "Geben Sie einen Schlüssel ein...",
"input.typeValue": "Geben Sie einen Wert ein...",
"jsonEditor.pathPlaceholder": "Geben Sie einen Pfad (z. B. users[0].name) oder eine JSONQuery (z. B..users | filter(.age > 25)) ein",
"knowledge.addKnowledge": "Wissen hinzufügen",
"knowledge.addSources": "Quellen hinzufügen",
"knowledge.addSourcesDescription": "Dateien hochladen und Chunking-Einstellungen konfigurieren",
@ -451,6 +611,9 @@
"misc.alertSaveWithApi": "⚠️ Achtung: Durch das Exportieren dieses Flows können vertrauliche Anmeldedaten offengelegt werden.",
"misc.apiAccess": "API-Zugriff",
"misc.chatTitle": "Langflow-Chat",
"misc.copyFailed": "Kopieroperation fehlgeschlagen",
"misc.copyJson": "JSON in die Zwischenablage kopieren",
"misc.editorNotAvailable": "Editor nicht verfügbar",
"misc.embedIntoSite": "In die Website einbetten",
"misc.export": "Exportieren",
"misc.fetchError": "Es konnte keine Verbindung hergestellt werden.",
@ -468,6 +631,7 @@
"misc.textInputModalTitle": "Textinhalt bearbeiten",
"misc.timeoutError": "Bitte haben Sie einen Moment Geduld, während der Server Ihre Anfrage bearbeitet.",
"misc.timeoutErrorDesc": "Der Server ist ausgelastet.",
"misc.unableToCopy": "Es ist nicht möglich, den Text in die Zwischenablage zu kopieren. Bitte manuell kopieren.",
"modal.api.createApiKey": "einen API-Schlüssel erstellen",
"modal.api.description": "Für den API-Zugriff ist ein API-Schlüssel erforderlich. Sie erhalten",
"modal.api.descriptionSuffix": "in den Einstellungen.",
@ -553,6 +717,7 @@
"nav.myCollection": "Meine Sammlung",
"nav.myCollectionDesc": "Verwalten Sie Ihre Projekte. Ganze Sammlungen herunterladen und hochladen.",
"nav.notifications": "Keine neuen Benachrichtigungen",
"node.dismissWarning": "Warnleiste schließen",
"node.errorNoTemplate": "Fehler in der Komponente „ {{name}} “",
"node.errorNoTemplateContact": "Bitte wenden Sie sich an den Entwickler der Komponente, um dieses Problem zu beheben.",
"node.errorNoTemplateDetail": "Die Komponente „ {{name}} “ verfügt über keine Vorlage.",
@ -595,6 +760,18 @@
"page.githubDescription": "Verfolge die Entwicklung, füge das Repo zu deinen Favoriten hinzu und gestalte die Zukunft mit.",
"page.welcomeDescription": "Deine neue Lieblingsmethode, um Agenten zu versenden",
"page.welcomeTitle": "Willkommen bei Langflow",
"paginator.placeholder": "1",
"playgroundComponent.chatSessions": "Chat-Sitzungen",
"playgroundComponent.clearChat": "Chat löschen",
"playgroundComponent.clearSession": "Sitzung löschen",
"playgroundComponent.closeAndGoBack": "Schließen und zum Arbeitsablauf zurückkehren",
"playgroundComponent.deleteFile": "Datei löschen",
"playgroundComponent.deleteSession": "Sitzung löschen",
"playgroundComponent.enterFullscreen": "Vollbildmodus aktivieren",
"playgroundComponent.focusChatInput": "Fokus auf Chat-Eingabe",
"playgroundComponent.messageLogs": "Meldungsprotokolle",
"playgroundComponent.moreOptions": "Weitere Optionen",
"playgroundComponent.rename": "Umbenennen von",
"project.deletedSuccessfully": "Das Projekt wurde erfolgreich gelöscht.",
"project.errorDeleting": "Fehler beim Löschen des Projekts.",
"project.newName": "Neues Projekt",
@ -681,6 +858,7 @@
"shortcuts.name.update": "Aktualisieren!",
"shortcuts.restoreButton": "Wiederherstellen",
"shortcuts.title": "Direktaufrufe",
"sidebar.allSet": "Alles bereit",
"sidebar.betaLabel": "Betaversion",
"sidebar.bundles": "Bundles",
"sidebar.category.agents": "Agenten",
@ -714,17 +892,24 @@
"sidebar.clearSearch": "Suche löschen",
"sidebar.componentSettings": "Komponenteneinstellungen",
"sidebar.components": "Komponenten",
"sidebar.createFlow": "Flow erstellen",
"sidebar.delete": "Löschen",
"sidebar.discoverMore": "Entdecken Sie weitere Komponenten",
"sidebar.download": "Herunterladen",
"sidebar.downloadError": "Beim Herunterladen Ihres Projekts ist ein Fehler aufgetreten.",
"sidebar.emptyMessage": "Erstellen Sie ein Projekt oder einen Ablauf",
"sidebar.getStarted": "Erste Schritte",
"sidebar.joinCommunity": "Werde Teil der Community",
"sidebar.knowledge": "Wissen",
"sidebar.legacyLabel": "Traditionell",
"sidebar.mcp.add": "MCP-Server hinzufügen",
"sidebar.mcp.empty": "Es wurden keine MCP-Server hinzugefügt",
"sidebar.mcp.manage": "Server verwalten",
"sidebar.mcp.title": "MCP-Server",
"sidebar.mcpExposeFlows": "Stellen Sie Flows als Tools in Clients wie Cursor oder Claude bereit.",
"sidebar.mcpGoToServer": "Zum Server",
"sidebar.mcpNewBadge": "Neu",
"sidebar.mcpProjectsTitle": "Projekte als MCP-Server",
"sidebar.myFiles": "Meine Dateien",
"sidebar.nav.addStickyNotes": "Haftnotizen hinzufügen",
"sidebar.nav.bundles": "Bundles",
@ -743,6 +928,7 @@
"sidebar.removeFilter": "Filter entfernen",
"sidebar.searchPlaceholder": "Suchen",
"sidebar.show": "Einblenden",
"sidebar.starRepo": "Folge dem Repo für Updates",
"sidebar.tryDifferentQuery": "oder filtern Sie und probieren Sie eine andere Suchanfrage aus.",
"sidebar.uploadSuccess": "Erfolgreich hochgeladen",
"slider.balanced": "Ausgeglichen",
@ -778,25 +964,49 @@
"store.tabFlows": "Abläufe",
"store.title": "Langflow-Shop",
"storeApiKey.description": "Verwalten Sie den Zugriff auf den Langflow Store.",
"storeApiKey.insertPlaceholder": "Geben Sie Ihren API-Schlüssel ein",
"storeApiKey.saveError": "Fehler beim Speichern des API-Schlüssels",
"storeApiKey.saveSuccess": "API-Schlüssel erfolgreich gespeichert",
"storeApiKey.title": "Langflow-Shop",
"success.apiKeySaved": "Erfolgreich! Ihr API-Schlüssel wurde gespeichert.",
"success.changesSaved": "Änderungen erfolgreich gespeichert!",
"success.chatCleared": "Der Chat wurde erfolgreich gelöscht.",
"success.codeReady": "Der Code ist bereit zur Ausführung",
"success.componentIdCopied": "Komponenten-ID in die Zwischenablage kopiert",
"success.componentOverridden": "{{id}} erfolgreich überschrieben!",
"success.componentSaved": "{{id}} Erfolgreich gespeichert",
"success.customComponentSaved": "Neue Komponente erfolgreich gespeichert!",
"success.endpointUrlCopied": "Endpunkt- URL en kopiert",
"success.fileUploaded": "Datei erfolgreich hochgeladen",
"success.flowBuilt": "Der Ablauf wurde erfolgreich erstellt",
"success.flowExported": "{{name}} Erfolgreich exportiert",
"success.ingestionCancelled": "Aufnahme abgebrochen",
"success.jsonCopied": "JSON in die Zwischenablage kopiert",
"success.keyDeleted": "Erfolgreich! Schlüssel gelöscht!",
"success.keysDeleted": "Erfolgreich! Schlüssel gelöscht!",
"success.knowledgeBaseDeleted": "Wissensdatenbank gelöscht",
"success.knowledgeBaseNodeCreated": "Die Wissensdatenbank \"{{name}}\" wurde erfolgreich erstellt!",
"success.messagesDeleted": "Die Nachrichten wurden erfolgreich gelöscht.",
"success.messagesUpdated": "Die Nachrichten wurden erfolgreich aktualisiert.",
"success.outputCopied": "In Zwischenablage kopiert",
"success.promptReady": "Die Eingabeaufforderung ist bereit",
"success.sessionDeleted": "Die Sitzung wurde erfolgreich gelöscht.",
"success.userAdded": "Erfolgreich! Neuer Benutzer hinzugefügt!",
"success.userDeleted": "Erfolgreich! Benutzer gelöscht!",
"success.userEdited": "Erfolgreich! Vom Benutzer bearbeitet!",
"success.versionDeleted": "Version gelöscht",
"success.versionRestored": "Version wiederhergestellt",
"success.versionSaved": "Version gespeichert",
"table.addRow": "Neue Zeile hinzufügen",
"table.deleteSelected": "Ausgewählte Elemente löschen",
"table.duplicateSelected": "Ausgewählte Elemente duplizieren",
"table.noColumnDescription": "Für diese Tabelle sind keine Spaltendefinitionen verfügbar.",
"table.noColumnTitle": "Keine Spaltendefinitionen",
"table.noDataMessage": "Hoppla! Es scheint, als gäbe es derzeit keine Daten, die angezeigt werden könnten. Bitte versuchen Sie es später noch einmal.",
"table.noDataTitle": "Keine Daten verfügbar",
"table.resetColumns": "Spalten zurücksetzen",
"table.selectToDelete": "Wählen Sie die zu löschenden Elemente aus",
"table.selectToDuplicate": "Wählen Sie die Elemente aus, die Sie duplizieren möchten",
"templatesModal.agents": "Agenten",
"templatesModal.allTemplates": "Alle Vorlagen",
"templatesModal.assistants": "Assistenten",
@ -837,5 +1047,21 @@
"toolsModal.parametersSubtitle": "Eingaben für dieses Tool verwalten",
"toolsModal.parametersTitle": "Parameter",
"toolsModal.searchPlaceholder": "Suchwerkzeuge...",
"toolsModal.slugHint": "Wird als Funktionsname verwendet, wenn dieses Tool dem Agenten zur Verfügung gestellt wird."
"toolsModal.slugHint": "Wird als Funktionsname verwendet, wenn dieses Tool dem Agenten zur Verfügung gestellt wird.",
"trace.allStatus": "Alle Status",
"trace.dateRange": "Datumsbereich",
"trace.download": "Herunterladen",
"trace.endDate": "Enddatum",
"trace.input": "Eingabe",
"trace.invalidDateRange": "Ungültiger Datumsbereich",
"trace.output": "Ausgabe",
"trace.reload": "Erneut laden",
"trace.searchRuns": "Die Suche läuft...",
"trace.spanTree": "Spannweiten",
"trace.startDate": "Startdatum",
"ui.resizeSidebar": "Seitenleiste in der Größe anpassen (mit den Pfeiltasten oder durch Ziehen)",
"ui.toggleSidebar": "Seitenleiste ein-/ausblenden",
"voice.selectLanguage": "Sprache auswählen",
"voice.selectMicrophone": "Mikrofon auswählen",
"voice.selectVoice": "Wählen"
}

View File

@ -837,5 +837,231 @@
"nodeToolbar.download": "Download",
"nodeToolbar.delete": "Delete",
"nodeToolbar.showMore": "Show More",
"noteNode.emptyPlaceholder": "Double-click to start typing or enter Markdown..."
"noteNode.emptyPlaceholder": "Double-click to start typing or enter Markdown...",
"errors.failedToSaveFlow": "Failed to save flow",
"errors.flowsVariableUndefined": "Flows variable undefined",
"errors.flowNotFound": "Flow not found",
"errors.failedToRestoreVersion": "Failed to restore version",
"errors.noModelsToRefresh": "No model components to refresh",
"errors.refreshingModels": "Error refreshing model components",
"errors.templateNotFound": "Template not found in the component",
"errors.parameterNotFound": "Parameter not found in the template",
"errors.renamingSession": "Error renaming session.",
"errors.noDataToExport": "No data available to export",
"errors.addMcpServer": "Error adding MCP server",
"errors.failedToExportFlow": "Failed to export flow",
"errors.deletingMessages": "Error deleting messages.",
"errors.updatingMessages": "Error updating messages.",
"errors.tooManyFiles": "Too many files detected ({{count}}). This likely includes large/hidden directories. Please select a smaller folder or exclude folders like node_modules.",
"errors.failedToLoadDeployment": "Failed to load deployment details",
"success.versionRestored": "Version restored",
"success.versionSaved": "Version saved",
"success.versionDeleted": "Version deleted",
"success.ingestionCancelled": "Ingestion cancelled",
"success.knowledgeBaseDeleted": "Knowledge base deleted",
"success.customComponentSaved": "New component successfully saved!",
"success.componentOverridden": "{{id}} successfully overridden!",
"success.componentSaved": "{{id}} saved successfully",
"success.flowExported": "{{name}} exported successfully",
"success.knowledgeBaseNodeCreated": "Knowledge Base \"{{name}}\" created successfully!",
"success.chatCleared": "Chat cleared successfully.",
"success.jsonCopied": "JSON copied to clipboard",
"success.outputCopied": "Copied to clipboard",
"success.endpointUrlCopied": "Endpoint URL copied",
"success.componentIdCopied": "Component ID copied to clipboard",
"success.messagesDeleted": "Messages deleted successfully.",
"success.messagesUpdated": "Messages updated successfully.",
"alerts.buildStopped": "Build stopped",
"alerts.modelsRefreshed_one": "Refreshed {{count}} model component",
"alerts.modelsRefreshed_other": "Refreshed {{count}} model components",
"misc.copyFailed": "Copy Failed",
"misc.editorNotAvailable": "Editor not available",
"misc.unableToCopy": "Unable to copy to clipboard. Please copy manually.",
"misc.copyJson": "Copy JSON to clipboard",
"deployments.selectDeployment": "Select Deployment",
"deployments.selectProvider": "Select Provider",
"deployments.reviewUpdate": "Review Update",
"deployments.deploymentType": "Deployment Type",
"deployments.provider": "Provider",
"deployments.attachFlows": "Attach Flows",
"deployments.reviewAndConfirm": "Review & Confirm",
"deployments.noDeployments": "No Deployments",
"deployments.noEnvironments": "No Environments",
"deployments.createNewDeployment": "Create new deployment",
"deployments.current": "Current",
"deployments.new": "New",
"deployments.noFlowsAttached": "No flows attached",
"deployments.agentChat": "Agent Chat",
"deployments.columnName": "Name",
"deployments.columnType": "Type",
"deployments.columnAttached": "Attached",
"deployments.columnProvider": "Provider",
"deployments.columnLastModified": "Last Modified",
"deployments.columnTest": "Test",
"deployments.columnUrl": "URL",
"deployments.columnProviderKey": "Provider Key",
"deployments.columnCreated": "Created",
"deployments.labelType": "Type",
"deployments.labelCreated": "Created",
"deployments.labelName": "Name",
"deployments.labelModified": "Modified",
"deployments.labelDesc": "Desc",
"deployments.labelModel": "Model",
"deployments.labelProvider": "Provider",
"deployments.placeholderSalesBot": "e.g., Sales Bot",
"deployments.placeholderAgentPurpose": "Describe the agent's purpose...",
"deployments.placeholderMessage": "Message",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderApiKey": "Enter your API key",
"deployments.placeholderEnvironmentName": "e.g. Production",
"deployments.placeholderSearchConnections": "Search connections...",
"deployments.placeholderConnectionName": "e.g., SALES_BOT_PROD",
"deployments.placeholderKey": "Key",
"deployments.placeholderValue": "Value",
"deployments.ariaExistingEnvironments": "Existing environments",
"deployments.ariaDeploymentType": "Deployment type",
"deployments.ariaSendMessage": "Send message",
"deployments.detachFlow": "Detach flow",
"deployments.undoDetach": "Undo detach",
"deployments.confirm": "Confirm",
"deployments.editToolName": "Edit tool name",
"table.addRow": "Add a new row",
"table.selectToDuplicate": "Select items to duplicate",
"table.duplicateSelected": "Duplicate selected items",
"table.selectToDelete": "Select items to delete",
"table.deleteSelected": "Delete selected items",
"table.resetColumns": "Reset Columns",
"input.addNewVariable": "Add New Variable",
"input.addMcpServer": "Add MCP Server",
"input.addActions": "Add actions",
"input.floatNumberShort": "Float number",
"input.floatNumberFull": "Type a float number",
"input.typeKey": "Type key...",
"input.typeValue": "Type a value...",
"input.searchOptions": "Search options...",
"accordion.addVariable": "Add variable",
"accordion.fullscreen": "Fullscreen",
"assistant.noModelsConfigured": "No Model Provider Configured",
"assistant.code": "Code",
"assistant.continue": "Continue",
"assistant.stopGeneration": "Stop generation",
"assistant.sendMessage": "Send message",
"assistant.sessionHistory": "Session history",
"assistant.noModelsDescription": "To use the assistant, please configure at least one model provider in your settings.",
"assistant.configureModels": "Configure Model Providers",
"assistant.maxSessionsTooltip": "Maximum of {{max}} sessions reached. Delete a session to create a new one.",
"assistant.maxSessionsLabel": "Max sessions",
"assistant.newSession": "New session",
"assistant.sessionHistoryLabel": "Session History",
"assistant.sessionHistoryTooltip": "Sessions are stored in your browser only and will not be preserved across different browsers or after clearing browser data.",
"assistant.noPreviousSessions": "No previous sessions",
"assistant.messageCounts": "{{count}} msgs",
"assistant.workingOnIt": "Working on it...",
"sidebar.mcpNewBadge": "New",
"sidebar.mcpProjectsTitle": "Projects as MCP Servers",
"sidebar.mcpGoToServer": "Go to Server",
"sidebar.allSet": "All Set",
"sidebar.mcpExposeFlows": "Expose flows as tools from clients like Cursor or Claude.",
"sidebar.getStarted": "Get started",
"sidebar.starRepo": "Star repo for updates",
"sidebar.joinCommunity": "Join the community",
"sidebar.createFlow": "Create a flow",
"flow.characterLimitReached": "Character limit reached",
"flow.nameAlreadyExists": "Flow name already exists",
"flow.namePlaceholder": "Flow name",
"flow.descriptionPlaceholder": "Flow description",
"flow.nameLabel": "Name",
"flow.descriptionLabel": "Description",
"flow.minimumCharacters": "Minimum {{count}} character(s) required",
"flow.pleaseEnterName": "Please enter a name",
"flow.lockFlow": "Lock Flow",
"flow.lockFlowDescription": "Lock your flow to prevent edits or accidental changes.",
"flow.pleaseEnterDescription": "Please enter a description",
"flow.noDescription": "No description",
"canvas.addStickyNote": "Add Sticky Note",
"jsonEditor.pathPlaceholder": "Enter path (e.g. users[0].name) or JSONQuery (e.g. .users | filter(.age > 25))",
"deployments.reviewDetails": "Review your deployment details before creating.",
"deployments.deploymentLabel": "Deployment",
"deployments.existingConnections": "Existing Connections",
"deployments.newConnections": "New Connections",
"deployments.detaching": "Detaching",
"deployments.unknownFlow": "Unknown flow",
"deployments.removing": "removing",
"deployments.toolsWillBeDetached": "These tools will be detached from the agent. They will remain available on your provider tenant.",
"deployments.selectOrCreateConnection": "Select or Create New Connection",
"deployments.availableConnections": "Available Connections",
"deployments.createConnection": "Create Connection",
"deployments.noConnectionsYet": "No connections yet",
"deployments.noConnectionsDescription": "Create a connection to attach credentials to this flow.",
"deployments.createFirstConnection": "Create your first connection",
"deployments.noConnectionsMatch": "No connections match \"{{query}}\"",
"deployments.connectionNameLabel": "Connection Name",
"deployments.connectionNameExists": "A connection with this name already exists.",
"deployments.environmentVariables": "Environment Variables",
"deployments.variablesAutoDetected_one": "{{count}} variable auto-detected from the selected flow version.",
"deployments.variablesAutoDetected_other": "{{count}} variables auto-detected from the selected flow version.",
"deployments.globalVariables": "Global Variables",
"deployments.addVariable": "+ Add variable",
"deployments.changeFlow": "Change Flow",
"deployments.skip": "Skip",
"deployments.attachConnectionToFlow": "Attach Connection to Flow",
"deployments.availableFlows": "Available Flows",
"deployments.attachedFlowsCount": "Attached Flows ({{count}})",
"deployments.attachedFlowsLabel": "Attached Flows",
"deployments.loadingAttachedFlows": "Loading attached flows...",
"deployments.failedToLoadFlows": "Failed to load attached flows",
"deployments.untitled": "Untitled",
"deployments.loadingDeploymentData": "Loading deployment data...",
"deployments.updateDeployment": "Update Deployment",
"deployments.createNewDeploymentTitle": "Create New Deployment",
"deployments.stepOf": "Step {{current}} of {{total}}",
"deployments.close": "Close",
"deployments.cancel": "Cancel",
"deployments.back": "Back",
"deployments.update": "Update",
"deployments.deploy": "Deploy",
"deployments.updating": "Updating...",
"deployments.deploying": "Deploying...",
"deployments.connecting": "Connecting...",
"deployments.next": "Next",
"deployments.test": "Test",
"deployments.review": "Review",
"playgroundComponent.focusChatInput": "Focus chat input",
"playgroundComponent.enterFullscreen": "Enter fullscreen",
"playgroundComponent.closeAndGoBack": "Close and go back to flow",
"playgroundComponent.chatSessions": "Chat sessions",
"playgroundComponent.deleteFile": "Delete file",
"playgroundComponent.moreOptions": "More options",
"playgroundComponent.rename": "Rename",
"playgroundComponent.messageLogs": "Message logs",
"playgroundComponent.clearChat": "Clear chat",
"playgroundComponent.deleteSession": "Delete session",
"playgroundComponent.clearSession": "Clear session",
"ui.toggleSidebar": "Toggle Sidebar",
"ui.resizeSidebar": "Resize sidebar (use arrow keys or drag to resize)",
"trace.dateRange": "Date range",
"trace.invalidDateRange": "Invalid date range",
"trace.startDate": "Start date",
"trace.endDate": "End date",
"trace.reload": "Reload",
"trace.download": "Download",
"trace.spanTree": "Trace spans",
"trace.searchRuns": "Search runs...",
"trace.allStatus": "All Status",
"trace.input": "Input",
"trace.output": "Output",
"flow.restoreVersion": "Restore this version of your flow",
"flow.saveVersion": "Save a version of your flow",
"flow.moreOptions": "More options",
"flow.replaceComponent": "Replace",
"flow.addDescription": "Add a description...",
"node.dismissWarning": "Dismiss warning bar",
"voice.selectLanguage": "Select language",
"voice.selectMicrophone": "Select microphone",
"voice.selectVoice": "Select",
"fileManager.searchFiles": "Search files...",
"auth.usernamePlaceholderInput": "Username",
"auth.confirmPassword": "Confirm password",
"storeApiKey.insertPlaceholder": "Insert your API Key",
"paginator.placeholder": "1"
}

View File

@ -1,4 +1,6 @@
{
"accordion.addVariable": "Añadir variable",
"accordion.fullscreen": "Pantalla completa",
"account.adminPage": "Página de administración",
"account.discord": "Discord",
"account.docs": "Documentos",
@ -32,12 +34,32 @@
"admin.saveButton": "Guardar",
"admin.searchPlaceholder": "Buscar nombre de usuario",
"alerts.apiKeyCopied": "¡Clave API copiada!",
"alerts.buildStopped": "La compilación se ha detenido",
"alerts.criticalDataWarning": "Advertencia: datos confidenciales; el archivo JSON puede contener claves de API.",
"alerts.modelsRefreshed_one": "Componente de modelo « {{count}} » actualizado",
"alerts.modelsRefreshed_other": "Componentes actualizados del modelo « {{count}} »",
"alerts.noChatOutput": "No hay ningún componente « ChatOutput » en el flujo.",
"alerts.noTemplateVariables": "Tu plantilla no contiene ninguna variable.",
"assistant.code": "Código",
"assistant.configureModels": "Configurar proveedores de modelos",
"assistant.continue": "Continuar",
"assistant.maxSessionsLabel": "Máx. sesiones",
"assistant.maxSessionsTooltip": "Se ha alcanzado el límite de sesiones de {{max}}. Elimina una sesión para crear una nueva.",
"assistant.messageCounts": "{{count}} mensajes",
"assistant.newSession": "Sesión nueva",
"assistant.noModelsConfigured": "No hay ningún proveedor de modelos configurado",
"assistant.noModelsDescription": "Para utilizar el asistente, configura al menos un proveedor de modelos en tus ajustes.",
"assistant.noPreviousSessions": "No hay sesiones anteriores",
"assistant.sendMessage": "Enviar mensaje",
"assistant.sessionHistory": "Historial de sesiones",
"assistant.sessionHistoryLabel": "Historial de sesiones",
"assistant.sessionHistoryTooltip": "Las sesiones se almacenan únicamente en tu navegador y no se conservarán en otros navegadores ni tras borrar los datos del navegador.",
"assistant.stopGeneration": "Detener la generación",
"assistant.workingOnIt": "Trabajando en ello...",
"auth.adminLoginButton": "Inicio de sesión",
"auth.adminTitle": "Administrador",
"auth.alertSaveWithApi": "⚠️ Precaución: al exportar este flujo, se pueden revelar credenciales confidenciales.",
"auth.confirmPassword": "Confirmar contraseña",
"auth.confirmPasswordLabel": "Confirma tu contraseña",
"auth.confirmPasswordPlaceholder": "Confirma tu contraseña",
"auth.confirmPasswordRequired": "Confirma tu contraseña",
@ -58,6 +80,7 @@
"auth.signupTitle": "Regístrate en Langflow",
"auth.usernameLabel": "Nombre de usuario",
"auth.usernamePlaceholder": "Nombre de usuario",
"auth.usernamePlaceholderInput": "Nombre de usuario",
"auth.usernameRequired": "Introduce tu nombre de usuario",
"authModal.apiKey.autoInstall": "crea e inserta una clave en el perfil de cliente seleccionado en este equipo.",
"authModal.apiKey.autoInstallBold": "Instalación automática",
@ -89,6 +112,7 @@
"authModal.reinstallWarningClients": "Para cambiar el tipo de autenticación, es necesario reinstalar este servidor en {{clients}} y en cualquier otro cliente en el que se utilice.",
"authModal.saveButton": "Guardar",
"authModal.title": "Configurar la autenticación del servidor MCP",
"canvas.addStickyNote": "Añadir nota adhesiva",
"canvas.agentWorking": "Agente en activo",
"canvas.controls": "Controles de Canvas",
"canvas.fitViewTooltip": "Ajustar la vista para mostrar todos los nodos",
@ -129,6 +153,99 @@
"deleteModal.noteFolderContents": "y todos los flujos y componentes asociados",
"deleteModal.noteMessageHistory": "y su historial de mensajes",
"deleteModal.title": "Suprimir",
"deployments.addVariable": "+ Añadir variable",
"deployments.agentChat": "Chat con agente",
"deployments.ariaDeploymentType": "Tipo de despliegue",
"deployments.ariaExistingEnvironments": "Entornos existentes",
"deployments.ariaSendMessage": "Enviar mensaje",
"deployments.attachConnectionToFlow": "Asociar conexión al flujo",
"deployments.attachFlows": "Adjuntar flujos",
"deployments.attachedFlowsCount": "Flujos adjuntos ( {{count}} )",
"deployments.attachedFlowsLabel": "Flujos adjuntos",
"deployments.availableConnections": "Conexiones disponibles",
"deployments.availableFlows": "Flujos disponibles",
"deployments.back": "Atrás",
"deployments.cancel": "Cancelar",
"deployments.changeFlow": "Flujo de cambios",
"deployments.close": "Cerrar",
"deployments.columnAttached": "Conectada",
"deployments.columnCreated": "Creado",
"deployments.columnLastModified": "Última modificación",
"deployments.columnName": "Nombre",
"deployments.columnProvider": "Proveedor",
"deployments.columnProviderKey": "Clave de proveedor",
"deployments.columnTest": "Prueba",
"deployments.columnType": "Tipo",
"deployments.columnUrl": "URL",
"deployments.confirm": "Confirmar",
"deployments.connecting": "Conectando...",
"deployments.connectionNameExists": "Ya existe una conexión con este nombre.",
"deployments.connectionNameLabel": "Nombre de conexión",
"deployments.createConnection": "Crear conexión",
"deployments.createFirstConnection": "Crea tu primera conexión",
"deployments.createNewDeployment": "Crear una nueva implementación",
"deployments.createNewDeploymentTitle": "Crear una nueva implementación",
"deployments.current": "Actual",
"deployments.deploy": "Desplegar",
"deployments.deploying": "Desplegando...",
"deployments.deploymentLabel": "virtual",
"deployments.deploymentType": "Tipo de despliegue",
"deployments.detachFlow": "Separar flujo",
"deployments.detaching": "Desconectar",
"deployments.editToolName": "Editar nombre de la herramienta",
"deployments.environmentVariables": "Variables de entorno",
"deployments.existingConnections": "Conexiones existentes",
"deployments.failedToLoadFlows": "No se han podido cargar los flujos adjuntos",
"deployments.globalVariables": "Variables globales",
"deployments.labelCreated": "Creado",
"deployments.labelDesc": "Descripción",
"deployments.labelModel": "Modelo",
"deployments.labelModified": "Modificado",
"deployments.labelName": "Nombre",
"deployments.labelProvider": "Proveedor",
"deployments.labelType": "Tipo",
"deployments.loadingAttachedFlows": "Cargando los flujos adjuntos...",
"deployments.loadingDeploymentData": "Cargando datos de implementación...",
"deployments.new": "Nuevo",
"deployments.newConnections": "Conexiones nuevas",
"deployments.next": "Siguiente",
"deployments.noConnectionsDescription": "Crea una conexión para asociar credenciales a este flujo.",
"deployments.noConnectionsMatch": "No se han encontrado resultados para « \"{{query}}\" »",
"deployments.noConnectionsYet": "Aún no hay conexiones",
"deployments.noDeployments": "No hay implementaciones",
"deployments.noEnvironments": "Sin entornos",
"deployments.noFlowsAttached": "Sin flujos asociados",
"deployments.placeholderAgentPurpose": "Describe el propósito del agente...",
"deployments.placeholderApiKey": "Introduce tu clave API",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderConnectionName": "p. ej., SALES_BOT_PROD",
"deployments.placeholderEnvironmentName": "p. ej., Producción",
"deployments.placeholderKey": "Clave",
"deployments.placeholderMessage": "Mensaje",
"deployments.placeholderSalesBot": "p. ej., bot de ventas",
"deployments.placeholderSearchConnections": "Buscar conexiones...",
"deployments.placeholderValue": "Valor",
"deployments.provider": "Proveedor",
"deployments.removing": "eliminación",
"deployments.review": "Revisar",
"deployments.reviewAndConfirm": "Revisar y confirmar",
"deployments.reviewDetails": "Revisa los detalles de la implementación antes de crearla.",
"deployments.reviewUpdate": "Actualización de la reseña",
"deployments.selectDeployment": "Seleccionar despliegue",
"deployments.selectOrCreateConnection": "Seleccionar o crear una nueva conexión",
"deployments.selectProvider": "Seleccionar proveedor",
"deployments.skip": "Omitir",
"deployments.stepOf": "Paso {{current}} de {{total}}",
"deployments.test": "Prueba",
"deployments.toolsWillBeDetached": "Estas herramientas se separarán del agente. Seguirán estando disponibles en el entorno de tu proveedor.",
"deployments.undoDetach": "Deshacer desacoplar",
"deployments.unknownFlow": "Caudal desconocido",
"deployments.untitled": "Sin título",
"deployments.update": "Actualizar",
"deployments.updateDeployment": "Actualización de la implementación",
"deployments.updating": "Actualizando...",
"deployments.variablesAutoDetected_one": "{{count}} variable detectada automáticamente a partir de la versión de flujo seleccionada.",
"deployments.variablesAutoDetected_other": "{{count}} variables detectadas automáticamente a partir de la versión del flujo seleccionada.",
"dialog.chat": "Interactúa con tu IA. Supervisa las entradas, las salidas y las memorias.",
"dialog.code": "Exporta tu flujo para integrarlo utilizando este código.",
"dialog.codeDict": "Personaliza tu diccionario añadiendo o editando pares clave-valor según sea necesario. Permite añadir nuevos objetos {} o matrices [].",
@ -147,6 +264,7 @@
"emptyPage.emptyProject": "Proyecto vacío",
"emptyPage.newFlow": "Nuevo flujo",
"emptyPage.startBuilding": "Empezar a crear",
"errors.addMcpServer": "Error al añadir el servidor MCP",
"errors.addUser": "Error al añadir un nuevo usuario",
"errors.apiKey": "Error de clave API",
"errors.changePassword": "Error al cambiar la contraseña",
@ -156,8 +274,15 @@
"errors.deleteKeys": "Error al eliminar claves",
"errors.deleteSession": "Error al eliminar la sesión.",
"errors.deleteUser": "Error al eliminar un usuario",
"errors.deletingMessages": "Error al eliminar mensajes.",
"errors.editUser": "Error al editar el usuario",
"errors.failedToExportFlow": "No se ha podido exportar el flujo",
"errors.failedToLoadDeployment": "No se han podido cargar los detalles de la implementación",
"errors.failedToRestoreVersion": "No se ha podido restaurar la versión",
"errors.failedToSaveFlow": "No se ha podido guardar el flujo",
"errors.fileTooLarge": "El archivo es demasiado grande. Selecciona un archivo que no supere los {{maxSizeMB}}.",
"errors.flowNotFound": "No se ha encontrado el flujo",
"errors.flowsVariableUndefined": "Variable de flujos no definida",
"errors.function": "Hay un error en tu función",
"errors.generic": "Ha ocurrido un error. Inténtalo de nuevo",
"errors.getComponents": "Error al cargar los componentes.",
@ -169,14 +294,22 @@
"errors.missedFields": "¡Ups! Parece que se te ha pasado algo por alto",
"errors.missingInfo": "¡Ups! Parece que te has olvidado de incluir algunos datos obligatorios:",
"errors.noApiKey": "No tienes una clave API. Añade uno para utilizar la tienda Langflow.",
"errors.noDataToExport": "No hay datos disponibles para exportar",
"errors.noModelsToRefresh": "No hay componentes del modelo que actualizar",
"errors.parameterNotFound": "Parámetro no encontrado en la plantilla",
"errors.passwordMismatch": "Las contraseñas no coinciden",
"errors.profilePictures": "Error al recuperar las fotos de perfil",
"errors.prompt": "Hay un error en esta indicación; por favor, revísala",
"errors.refreshingModels": "Error al actualizar los componentes del modelo",
"errors.renamingSession": "Error al cambiar el nombre de la sesión.",
"errors.saveApiKey": "Se ha producido un error al guardar la clave API. Inténtalo de nuevo.",
"errors.saveChanges": "Error al guardar los cambios",
"errors.sendMessage": "Se ha producido un error al enviar el mensaje",
"errors.signin": "Error al iniciar sesión",
"errors.signup": "Error al registrarse",
"errors.templateNotFound": "No se ha encontrado la plantilla en el componente",
"errors.tooManyFiles": "Se han detectado demasiados archivos ( {{count}} ). Es probable que esto incluya directorios grandes u ocultos. Selecciona una carpeta más pequeña o excluye carpetas como «node_modules».",
"errors.updatingMessages": "Error al actualizar los mensajes.",
"errors.upload": "Error al cargar el archivo",
"errors.uploadFile": "Se ha producido un error al cargar el archivo",
"errors.uploadJsonOnly": "Sube un archivo JSON",
@ -191,6 +324,7 @@
"fileManager.errorUploadingFileDetail": "Se ha producido un error al cargar el archivo",
"fileManager.fileUploadedSuccessfully": "El archivo se ha subido correctamente",
"fileManager.filesUploadedSuccessfully": "Archivos cargados correctamente",
"fileManager.searchFiles": "Buscar archivos...",
"fileManager.selectAtLeastOneFile": "Selecciona al menos un archivo",
"fileManager.selectFile": "Seleccionar archivo",
"fileManager.selectFiles": "Seleccionar archivos",
@ -214,11 +348,15 @@
"files.uploadFile": "Cargar archivo",
"files.uploadFiles": "Cargar archivos",
"files.uploadedSuccessfully": "El archivo se ha subido correctamente",
"flow.addDescription": "Añade una descripción...",
"flow.brokenEdgesWarning": "Se han eliminado algunas conexiones porque no eran válidas:",
"flow.buildStatus": "Compilar para comprobar el estado.",
"flow.buildSuccess": "Creado con éxito ✨",
"flow.characterLimitReached": "Se ha alcanzado el límite de caracteres",
"flow.defaultName": "Nuevo flujo",
"flow.deletedSuccessfully": "Los elementos seleccionados se han eliminado correctamente",
"flow.descriptionLabel": "Descripción",
"flow.descriptionPlaceholder": "Descripción del flujo",
"flow.duplicatedSuccess": "{{type}} se ha duplicado correctamente",
"flow.enableAutoSaving": "Activar el guardado automático",
"flow.errorDeleting": "Error al eliminar elementos",
@ -226,14 +364,27 @@
"flow.exitAnyway": "Salir de todos modos",
"flow.lastSaved": "Última actualización: {{time}}",
"flow.lastSavedNever": "Nunca",
"flow.lockFlow": "Bloqueo de flujo",
"flow.lockFlowDescription": "Bloquea tu flujo para evitar modificaciones o cambios accidentales.",
"flow.menu.delete": "Suprimir",
"flow.menu.duplicate": "Duplicado",
"flow.menu.editDetails": "Editar detalles",
"flow.menu.export": "Exportar",
"flow.minimumCharacters": "Se requiere un mínimo de {{count}} caracteres",
"flow.missingFields": "Rellene todos los campos obligatorios.",
"flow.moreOptions": "Más opciones",
"flow.nameAlreadyExists": "El nombre del flujo ya existe",
"flow.nameLabel": "Nombre",
"flow.namePlaceholder": "Nombre de flujo",
"flow.noCompatibleComponents": "No se han encontrado componentes compatibles.",
"flow.noDescription": "Ninguna descripción",
"flow.pleaseEnterDescription": "Introduce una descripción",
"flow.pleaseEnterName": "Introduce un nombre",
"flow.replaceComponent": "Sustituir",
"flow.restoreVersion": "Restaurar esta versión de tu flujo",
"flow.runTimestampPrefix": "Última carrera: ",
"flow.saveAndExit": "Guardar y salir",
"flow.saveVersion": "Guarda una versión de tu flujo",
"flow.savedHover": "Última vez guardado: ",
"flow.savedSuccessfully": "¡Flujo guardado correctamente!",
"flow.savingChanges": "Guardando los cambios...",
@ -299,15 +450,24 @@
"home.dragFlowType": "Deja aquí tu « {{flowType}} »",
"home.dragFlowsOrComponents": "Suelta aquí tus flujos o componentes",
"home.flowTypeNotSupported": "{{flowType}} no es compatible",
"input.addActions": "Añadir acciones",
"input.addMcpServer": "Añadir servidor MCP",
"input.addNewVariable": "Añadir nueva variable",
"input.editCodeTitle": "Editar código",
"input.editTextPlaceholder": "Escribe aquí tu mensaje.",
"input.editTextTitle": "Editar texto",
"input.emptyOutput": "Mensaje vacío.",
"input.errorUpdatingComponent": "Se ha producido un error inesperado al actualizar el componente. Inténtelo de nuevo.",
"input.floatNumberFull": "Escribe un número de tipo float",
"input.floatNumberShort": "Número de flotador",
"input.noInputMessage": "No se ha proporcionado ningún mensaje de entrada.",
"input.placeholder": "Escriba algo...",
"input.searchOptions": "Opciones de búsqueda...",
"input.titleErrorUpdatingComponent": "Se ha producido un error al actualizar el componente",
"input.toolsetPlaceholder": "Se utiliza como herramienta",
"input.typeKey": "Escribe una clave...",
"input.typeValue": "Escribe un valor...",
"jsonEditor.pathPlaceholder": "Introduce una ruta (por ejemplo, users[0].name) o una consulta JSON (por ejemplo,.users | filter(.age > 25))",
"knowledge.addKnowledge": "Añadir conocimiento",
"knowledge.addSources": "Añadir orígenes",
"knowledge.addSourcesDescription": "Sube archivos y configura los ajustes de fragmentación",
@ -451,6 +611,9 @@
"misc.alertSaveWithApi": "⚠️ Precaución: al exportar este flujo, se pueden revelar credenciales confidenciales.",
"misc.apiAccess": "Acceso de API",
"misc.chatTitle": "Langflow Chat",
"misc.copyFailed": "Anomalía en la copia",
"misc.copyJson": "Copiar JSON al portapapeles",
"misc.editorNotAvailable": "El editor no está disponible",
"misc.embedIntoSite": "Incorporar en el sitio web",
"misc.export": "Exportar",
"misc.fetchError": "No se ha podido establecer la conexión.",
@ -468,6 +631,7 @@
"misc.textInputModalTitle": "Editar el contenido del texto",
"misc.timeoutError": "Por favor, espere unos instantes mientras el servidor procesa su solicitud.",
"misc.timeoutErrorDesc": "El servidor está ocupado.",
"misc.unableToCopy": "No se puede copiar al portapapeles. Por favor, cópielo manualmente.",
"modal.api.createApiKey": "crear una clave API",
"modal.api.description": "Para acceder a la API se necesita una clave de API. Puedes",
"modal.api.descriptionSuffix": "en la configuración.",
@ -553,6 +717,7 @@
"nav.myCollection": "Mi colección",
"nav.myCollectionDesc": "Gestiona tus proyectos. Descarga y sube colecciones completas.",
"nav.notifications": "No hay nuevas notificaciones",
"node.dismissWarning": "Ocultar la barra de advertencia",
"node.errorNoTemplate": "Error en el componente {{name}}",
"node.errorNoTemplateContact": "Póngase en contacto con el desarrollador del componente para solucionar este problema.",
"node.errorNoTemplateDetail": "El componente {{name}} no tiene plantilla.",
@ -595,6 +760,18 @@
"page.githubDescription": "Sigue el desarrollo, marca el repositorio como favorito y da forma al futuro.",
"page.welcomeDescription": "Tu nueva forma favorita de enviar Agentes",
"page.welcomeTitle": "Bienvenido a Langflow",
"paginator.placeholder": "1",
"playgroundComponent.chatSessions": "Sesiones de chat",
"playgroundComponent.clearChat": "Borrar conversación",
"playgroundComponent.clearSession": "Borrar sesión",
"playgroundComponent.closeAndGoBack": "Cerrar y volver al flujo",
"playgroundComponent.deleteFile": "Suprimir archivo",
"playgroundComponent.deleteSession": "Suprimir sesión",
"playgroundComponent.enterFullscreen": "Pasar a pantalla completa",
"playgroundComponent.focusChatInput": "Enfocar el texto introducido en el chat",
"playgroundComponent.messageLogs": "Registros de mensajes",
"playgroundComponent.moreOptions": "Más opciones",
"playgroundComponent.rename": "Renombrar",
"project.deletedSuccessfully": "El proyecto se ha eliminado correctamente.",
"project.errorDeleting": "Error al eliminar el proyecto.",
"project.newName": "Nuevo proyecto",
@ -681,6 +858,7 @@
"shortcuts.name.update": "Actualizar",
"shortcuts.restoreButton": "Restaurar",
"shortcuts.title": "Atajos",
"sidebar.allSet": "Todo listo",
"sidebar.betaLabel": "Beta",
"sidebar.bundles": "Paquetes",
"sidebar.category.agents": "Agentes",
@ -714,17 +892,24 @@
"sidebar.clearSearch": "Borrar la búsqueda",
"sidebar.componentSettings": "Configuración de los componentes",
"sidebar.components": "Componentes",
"sidebar.createFlow": "Crear un flujo",
"sidebar.delete": "Suprimir",
"sidebar.discoverMore": "Descubre más componentes",
"sidebar.download": "Descargar",
"sidebar.downloadError": "Se ha producido un error al descargar tu proyecto.",
"sidebar.emptyMessage": "Empieza a crear un proyecto o un flujo",
"sidebar.getStarted": "Cómo empezar",
"sidebar.joinCommunity": "Únete a la comunidad",
"sidebar.knowledge": "Conocimientos",
"sidebar.legacyLabel": "Heredado",
"sidebar.mcp.add": "Añadir servidor MCP",
"sidebar.mcp.empty": "No se han añadido servidores MCP",
"sidebar.mcp.manage": "Gestionar servidores",
"sidebar.mcp.title": "Servidores MCP",
"sidebar.mcpExposeFlows": "Exhibe flujos como herramientas desde clientes como Cursor o Claude.",
"sidebar.mcpGoToServer": "Ir al servidor",
"sidebar.mcpNewBadge": "Nuevo",
"sidebar.mcpProjectsTitle": "Proyectos como servidores MCP",
"sidebar.myFiles": "Mis archivos",
"sidebar.nav.addStickyNotes": "Añadir notas adhesivas",
"sidebar.nav.bundles": "Paquetes",
@ -743,6 +928,7 @@
"sidebar.removeFilter": "Eliminar filtro",
"sidebar.searchPlaceholder": "Búsqueda",
"sidebar.show": "Mostrar",
"sidebar.starRepo": "Añade a tus favoritos para recibir actualizaciones",
"sidebar.tryDifferentQuery": "o aplica un filtro y prueba con otra consulta.",
"sidebar.uploadSuccess": "Cargado correctamente",
"slider.balanced": "Equilibrado",
@ -778,25 +964,49 @@
"store.tabFlows": "Flujos",
"store.title": "Tienda Langflow",
"storeApiKey.description": "Gestionar el acceso a la tienda de Langflow.",
"storeApiKey.insertPlaceholder": "Introduce tu clave API",
"storeApiKey.saveError": "Error al guardar la clave API",
"storeApiKey.saveSuccess": "La clave API se ha guardado correctamente",
"storeApiKey.title": "Tienda Langflow",
"success.apiKeySaved": "Correcto. Tu clave API se ha guardado.",
"success.changesSaved": "¡Los cambios se han guardado correctamente!",
"success.chatCleared": "El chat se ha borrado correctamente.",
"success.codeReady": "El código está listo para ejecutarse",
"success.componentIdCopied": "El ID del componente se ha copiado en el portapapeles",
"success.componentOverridden": "{{id}} ¡Se ha anulado correctamente!",
"success.componentSaved": "{{id}} Se ha guardado correctamente",
"success.customComponentSaved": "¡El nuevo componente se ha guardado correctamente!",
"success.endpointUrlCopied": "Se ha copiado el punto final URL",
"success.fileUploaded": "El archivo se ha subido correctamente",
"success.flowBuilt": "El flujo se ha creado correctamente",
"success.flowExported": "{{name}} se ha exportado correctamente",
"success.ingestionCancelled": "Ingestión cancelada",
"success.jsonCopied": "JSON copiado en el portapapeles",
"success.keyDeleted": "Correcto. ¡Clave eliminada!",
"success.keysDeleted": "Correcto. ¡Claves eliminadas!",
"success.knowledgeBaseDeleted": "Se ha eliminado la base de conocimientos",
"success.knowledgeBaseNodeCreated": "¡Se ha creado correctamente la base de conocimientos \"{{name}}\"!",
"success.messagesDeleted": "Los mensajes se han eliminado correctamente.",
"success.messagesUpdated": "Los mensajes se han actualizado correctamente.",
"success.outputCopied": "Copiado en el portapapeles",
"success.promptReady": "La indicación está lista",
"success.sessionDeleted": "La sesión se ha eliminado correctamente.",
"success.userAdded": "Correcto. ¡Se ha añadido un nuevo usuario!",
"success.userDeleted": "Correcto. ¡Usuario eliminado!",
"success.userEdited": "Correcto. ¡Editado por el usuario!",
"success.versionDeleted": "Versión eliminada",
"success.versionRestored": "Versión restaurada",
"success.versionSaved": "Versión guardada",
"table.addRow": "Añadir una nueva fila",
"table.deleteSelected": "Eliminar los elementos seleccionados",
"table.duplicateSelected": "Duplicar los elementos seleccionados",
"table.noColumnDescription": "No hay definiciones de columnas disponibles para esta tabla.",
"table.noColumnTitle": "No hay definiciones de columnas",
"table.noDataMessage": "¡Ups! Parece que no hay datos que mostrar en este momento. Vuelve a intentarlo más tarde.",
"table.noDataTitle": "No hay datos disponibles",
"table.resetColumns": "Restablecer columnas",
"table.selectToDelete": "Selecciona los elementos que deseas eliminar",
"table.selectToDuplicate": "Selecciona los elementos que deseas duplicar",
"templatesModal.agents": "Agentes",
"templatesModal.allTemplates": "Todas las plantillas",
"templatesModal.assistants": "Asistentes",
@ -837,5 +1047,21 @@
"toolsModal.parametersSubtitle": "Gestionar los datos de entrada de esta herramienta",
"toolsModal.parametersTitle": "Parámetros",
"toolsModal.searchPlaceholder": "Herramientas de búsqueda...",
"toolsModal.slugHint": "Se utiliza como nombre de la función cuando esta herramienta se pone a disposición del agente."
"toolsModal.slugHint": "Se utiliza como nombre de la función cuando esta herramienta se pone a disposición del agente.",
"trace.allStatus": "Todos los estados",
"trace.dateRange": "Rango de fechas",
"trace.download": "Descargar",
"trace.endDate": "Fecha de finalización",
"trace.input": "Entrada",
"trace.invalidDateRange": "Intervalo de fechas no válido",
"trace.output": "Resultado",
"trace.reload": "Recargar",
"trace.searchRuns": "Se está realizando una búsqueda...",
"trace.spanTree": "Longitudes de tramos",
"trace.startDate": "Fecha de inicio",
"ui.resizeSidebar": "Cambiar el tamaño de la barra lateral (utiliza las teclas de flecha o arrastra para cambiar el tamaño)",
"ui.toggleSidebar": "Mostrar/ocultar la barra lateral",
"voice.selectLanguage": "Seleccionar idioma",
"voice.selectMicrophone": "Seleccionar micrófono",
"voice.selectVoice": "Seleccionar"
}

View File

@ -1,4 +1,6 @@
{
"accordion.addVariable": "Ajouter la variable",
"accordion.fullscreen": "Plein écran",
"account.adminPage": "Page Admin",
"account.discord": "Discord",
"account.docs": "Documents",
@ -32,12 +34,32 @@
"admin.saveButton": "Sauvegarder",
"admin.searchPlaceholder": "Rechercher un nom d'utilisateur",
"alerts.apiKeyCopied": "Clé API copiée!",
"alerts.buildStopped": "La compilation s'est arrêtée",
"alerts.criticalDataWarning": "Avertissement : données sensibles; le fichier JSON peut contenir des clés API.",
"alerts.modelsRefreshed_one": "Composant modèle « {{count}} » mis à jour",
"alerts.modelsRefreshed_other": "Composants du modèle « {{count}} » mis à jour",
"alerts.noChatOutput": "Le flux ne contient aucun composant « ChatOutput ».",
"alerts.noTemplateVariables": "Votre modèle ne contient aucune variable.",
"assistant.code": "Coder",
"assistant.configureModels": "Configurer les fournisseurs de modèles",
"assistant.continue": "Continuer",
"assistant.maxSessionsLabel": "Nbre max. de sessions",
"assistant.maxSessionsTooltip": "Le nombre maximal de sessions d' {{max}} s a été atteint. Supprimez une session pour en créer une nouvelle.",
"assistant.messageCounts": "{{count}} messages",
"assistant.newSession": "Nouvelle session",
"assistant.noModelsConfigured": "Aucun fournisseur de modèles n'est configuré",
"assistant.noModelsDescription": "Pour utiliser l'assistant, veuillez configurer au moins un fournisseur de modèles dans vos paramètres.",
"assistant.noPreviousSessions": "Aucune session précédente",
"assistant.sendMessage": "Envoyer un message",
"assistant.sessionHistory": "Historique des sessions",
"assistant.sessionHistoryLabel": "Historique des sessions",
"assistant.sessionHistoryTooltip": "Les sessions sont enregistrées uniquement dans votre navigateur et ne seront pas conservées d'un navigateur à l'autre ni après la suppression des données du navigateur.",
"assistant.stopGeneration": "Arrêter la génération",
"assistant.workingOnIt": "En cours de traitement...",
"auth.adminLoginButton": "Connexion",
"auth.adminTitle": "Administrateur",
"auth.alertSaveWithApi": "⚠️ Attention : l'exportation de ce flux peut entraîner la divulgation d'identifiants sensibles.",
"auth.confirmPassword": "Confirmation du mot de passe",
"auth.confirmPasswordLabel": "Confirmez votre mot de passe",
"auth.confirmPasswordPlaceholder": "Confirmez votre mot de passe",
"auth.confirmPasswordRequired": "Veuillez confirmer votre mot de passe",
@ -58,6 +80,7 @@
"auth.signupTitle": "Inscrivez-vous à Langflow",
"auth.usernameLabel": "Nom d'utilisateur",
"auth.usernamePlaceholder": "Nom d'utilisateur",
"auth.usernamePlaceholderInput": "Nom d'utilisateur",
"auth.usernameRequired": "Veuillez saisir votre nom d'utilisateur",
"authModal.apiKey.autoInstall": "crée et injecte une clé dans le profil client sélectionné sur cet ordinateur.",
"authModal.apiKey.autoInstallBold": "Installation automatique",
@ -89,6 +112,7 @@
"authModal.reinstallWarningClients": "Pour modifier le type d'authentification, il faut réinstaller ce serveur sur {{clients}} ainsi que sur tous les autres clients qui l'utilisent.",
"authModal.saveButton": "Sauvegarder",
"authModal.title": "Configurer l'authentification du serveur MCP",
"canvas.addStickyNote": "Ajouter un post-it",
"canvas.agentWorking": "Agent en service",
"canvas.controls": "Commandes Canvas",
"canvas.fitViewTooltip": "Ajuster la vue pour afficher tous les nœuds",
@ -129,6 +153,99 @@
"deleteModal.noteFolderContents": "ainsi que tous les flux et composants associés",
"deleteModal.noteMessageHistory": "et l'historique de ses messages",
"deleteModal.title": "Supprimer",
"deployments.addVariable": "+ Ajouter une variable",
"deployments.agentChat": "Discussion de l'agent",
"deployments.ariaDeploymentType": "Type de déploiement",
"deployments.ariaExistingEnvironments": "Environnements existants",
"deployments.ariaSendMessage": "Envoyer un message",
"deployments.attachConnectionToFlow": "Associer une connexion à un flux",
"deployments.attachFlows": "Joindre des flux",
"deployments.attachedFlowsCount": "Flux associés ( {{count}} )",
"deployments.attachedFlowsLabel": "Débits associés",
"deployments.availableConnections": "Connexions disponibles",
"deployments.availableFlows": "Débits disponibles",
"deployments.back": "Précédent",
"deployments.cancel": "Annuler",
"deployments.changeFlow": "Modifier le flux",
"deployments.close": "Fermer",
"deployments.columnAttached": "Jointe",
"deployments.columnCreated": "Créé",
"deployments.columnLastModified": "Dernière modification",
"deployments.columnName": "Nom",
"deployments.columnProvider": "Fournisseur",
"deployments.columnProviderKey": "Clé du fournisseur",
"deployments.columnTest": "Tester",
"deployments.columnType": "Type",
"deployments.columnUrl": "URL",
"deployments.confirm": "Confirmer",
"deployments.connecting": "Connexion en cours...",
"deployments.connectionNameExists": "Une connexion portant ce nom existe déjà.",
"deployments.connectionNameLabel": "Nom de la connexion",
"deployments.createConnection": "Créer une connexion",
"deployments.createFirstConnection": "Établissez votre première connexion",
"deployments.createNewDeployment": "Créer un nouveau déploiement",
"deployments.createNewDeploymentTitle": "Créer un nouveau déploiement",
"deployments.current": "En cours",
"deployments.deploy": "Déployer",
"deployments.deploying": "Déploiement en cours...",
"deployments.deploymentLabel": "Déploiement",
"deployments.deploymentType": "Type de déploiement",
"deployments.detachFlow": "Déconnecter le flux",
"deployments.detaching": "Détacher",
"deployments.editToolName": "Modifier le nom de l'outil",
"deployments.environmentVariables": "Variables d'environnement",
"deployments.existingConnections": "Connexions existantes",
"deployments.failedToLoadFlows": "Échec du chargement des flux joints",
"deployments.globalVariables": "Variables globales",
"deployments.labelCreated": "Créé",
"deployments.labelDesc": "Description",
"deployments.labelModel": "Modèle",
"deployments.labelModified": "Modifiée",
"deployments.labelName": "Nom",
"deployments.labelProvider": "Fournisseur",
"deployments.labelType": "Type",
"deployments.loadingAttachedFlows": "Chargement des flux joints...",
"deployments.loadingDeploymentData": "Chargement des données de déploiement...",
"deployments.new": "Nouveau",
"deployments.newConnections": "Nouvelles connexions",
"deployments.next": "Suivant",
"deployments.noConnectionsDescription": "Créez une connexion pour associer des identifiants à ce flux.",
"deployments.noConnectionsMatch": "Aucun résultat ne correspond à « \"{{query}}\" »",
"deployments.noConnectionsYet": "Aucune connexion pour l'instant",
"deployments.noDeployments": "Aucun déploiement",
"deployments.noEnvironments": "Aucun environnement",
"deployments.noFlowsAttached": "Aucun flux associé",
"deployments.placeholderAgentPurpose": "Décrivez l'objectif de l'agent...",
"deployments.placeholderApiKey": "Saisissez votre clé API",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderConnectionName": "par exemple, SALES_BOT_PROD",
"deployments.placeholderEnvironmentName": "par exemple : Production",
"deployments.placeholderKey": "Clé",
"deployments.placeholderMessage": "Message",
"deployments.placeholderSalesBot": "par exemple, un bot commercial",
"deployments.placeholderSearchConnections": "Rechercher des connexions...",
"deployments.placeholderValue": "Valeur",
"deployments.provider": "Fournisseur",
"deployments.removing": "suppression",
"deployments.review": "Réviser",
"deployments.reviewAndConfirm": "Vérifier et confirmer",
"deployments.reviewDetails": "Vérifiez les détails de votre déploiement avant de le créer.",
"deployments.reviewUpdate": "Mise à jour de l'avis",
"deployments.selectDeployment": "Sélectionner un déploiement",
"deployments.selectOrCreateConnection": "Sélectionner ou créer une nouvelle connexion",
"deployments.selectProvider": "Sélectionner un fournisseur",
"deployments.skip": "Sauter",
"deployments.stepOf": "Étape {{current}} de {{total}}",
"deployments.test": "Tester",
"deployments.toolsWillBeDetached": "Ces outils seront dissociés de l'agent. Ils resteront disponibles sur l'instance de votre fournisseur.",
"deployments.undoDetach": "Annuler le détachement",
"deployments.unknownFlow": "Débit inconnu",
"deployments.untitled": "Sans titre",
"deployments.update": "Mettre à jour",
"deployments.updateDeployment": "Déploiement de la mise à jour",
"deployments.updating": "Mise à jour en cours...",
"deployments.variablesAutoDetected_one": "{{count}} variable détectée automatiquement à partir de la version du flux sélectionnée.",
"deployments.variablesAutoDetected_other": "{{count}} variables détectées automatiquement à partir de la version du flux sélectionnée.",
"dialog.chat": "Interagissez avec votre IA. Surveiller les entrées, les sorties et les mémoires.",
"dialog.code": "Exportez votre flux pour l'intégrer à l'aide de ce code.",
"dialog.codeDict": "Personnalisez votre dictionnaire en ajoutant ou en modifiant des paires clé-valeur selon vos besoins. Permet d'ajouter de nouveaux objets {} ou tableaux [].",
@ -147,6 +264,7 @@
"emptyPage.emptyProject": "Projet vide",
"emptyPage.newFlow": "Nouveau flux",
"emptyPage.startBuilding": "Démarrer la génération",
"errors.addMcpServer": "Erreur lors de l'ajout du serveur MCP",
"errors.addUser": "Erreur lors de l'ajout d'un nouvel utilisateur",
"errors.apiKey": "Erreur de clé API",
"errors.changePassword": "Erreur lors de la modification du mot de passe",
@ -156,8 +274,15 @@
"errors.deleteKeys": "Erreur lors de la suppression de clés",
"errors.deleteSession": "Erreur lors de la suppression de la session.",
"errors.deleteUser": "Erreur lors de la suppression d'un utilisateur",
"errors.deletingMessages": "Erreur lors de la suppression des messages.",
"errors.editUser": "Erreur lors de la modification d'un utilisateur",
"errors.failedToExportFlow": "Échec de l'exportation du flux",
"errors.failedToLoadDeployment": "Échec du chargement des détails du déploiement",
"errors.failedToRestoreVersion": "Échec de la restauration de la version",
"errors.failedToSaveFlow": "Échec de l'enregistrement du flux",
"errors.fileTooLarge": "La taille du fichier est trop importante. Veuillez sélectionner un fichier dont la taille est inférieure à {{maxSizeMB}}.",
"errors.flowNotFound": "Flux introuvable",
"errors.flowsVariableUndefined": "Variable « Flows » non définie",
"errors.function": "Il y a une erreur dans votre fonction",
"errors.generic": "Une erreur s'est produite. Veuillez réessayer",
"errors.getComponents": "Erreur lors de la récupération des composants.",
@ -169,14 +294,22 @@
"errors.missedFields": "Oups ! On dirait que tu as raté quelque chose",
"errors.missingInfo": "Oups ! Il semble que vous ayez oublié certaines informations obligatoires :",
"errors.noApiKey": "Vous ne disposez pas d'une clé API. Veuillez en ajouter un pour utiliser la boutique Langflow.",
"errors.noDataToExport": "Aucune donnée disponible à exporter",
"errors.noModelsToRefresh": "Aucun composant du modèle à actualiser",
"errors.parameterNotFound": "Paramètre introuvable dans le modèle",
"errors.passwordMismatch": "Les mots de passe ne correspondent pas",
"errors.profilePictures": "Erreur lors de la récupération des photos de profil",
"errors.prompt": "Il y a un problème avec cette consigne, merci de la vérifier",
"errors.refreshingModels": "Erreur lors de l'actualisation des composants du modèle",
"errors.renamingSession": "Erreur lors du changement de nom de la session.",
"errors.saveApiKey": "Une erreur s'est produite lors de l'enregistrement de la clé API. Veuillez réessayer.",
"errors.saveChanges": "Erreur lors de l'enregistrement des modifications",
"errors.sendMessage": "Une erreur s'est produite lors de l'envoi du message",
"errors.signin": "Erreur lors de la connexion",
"errors.signup": "Erreur lors de l'inscription",
"errors.templateNotFound": "Modèle introuvable dans le composant",
"errors.tooManyFiles": "Trop de fichiers détectés ( {{count}} ). Cela inclut probablement les répertoires volumineux ou cachés. Veuillez sélectionner un dossier plus petit ou exclure des dossiers tels que node_modules.",
"errors.updatingMessages": "Erreur lors de la mise à jour des messages.",
"errors.upload": "Erreur lors du téléchargement du fichier",
"errors.uploadFile": "Une erreur s'est produite lors du téléchargement du fichier",
"errors.uploadJsonOnly": "Veuillez télécharger un fichier JSON",
@ -191,6 +324,7 @@
"fileManager.errorUploadingFileDetail": "Une erreur s'est produite lors du téléchargement du fichier",
"fileManager.fileUploadedSuccessfully": "Le fichier a été téléchargé avec succès",
"fileManager.filesUploadedSuccessfully": "Fichiers téléchargés correctement",
"fileManager.searchFiles": "Rechercher des fichiers...",
"fileManager.selectAtLeastOneFile": "Veuillez sélectionner au moins un fichier",
"fileManager.selectFile": "Sélectionnez un fichier",
"fileManager.selectFiles": "Sélectionner des fichiers",
@ -214,11 +348,15 @@
"files.uploadFile": "Transférer le fichier",
"files.uploadFiles": "Transférer les fichiers",
"files.uploadedSuccessfully": "Le fichier a été téléchargé avec succès",
"flow.addDescription": "Ajouter une description...",
"flow.brokenEdgesWarning": "Certaines connexions ont été supprimées car elles n'étaient pas valides :",
"flow.buildStatus": "Compiler pour vérifier l'état.",
"flow.buildSuccess": "Réussite ✨",
"flow.characterLimitReached": "Limite de caractères atteinte",
"flow.defaultName": "Nouveau flux",
"flow.deletedSuccessfully": "Les éléments sélectionnés ont été supprimés avec succès",
"flow.descriptionLabel": "Descriptif",
"flow.descriptionPlaceholder": "Description du flux",
"flow.duplicatedSuccess": "{{type}} copie effectuée avec succès",
"flow.enableAutoSaving": "Activer la sauvegarde automatique",
"flow.errorDeleting": "Erreur lors de la suppression des éléments",
@ -226,14 +364,27 @@
"flow.exitAnyway": "Sortir quand même",
"flow.lastSaved": "Dernière mise à jour : {{time}}",
"flow.lastSavedNever": "Jamais",
"flow.lockFlow": "Débit de verrouillage",
"flow.lockFlowDescription": "Verrouillez votre flux pour empêcher toute modification ou tout changement accidentel.",
"flow.menu.delete": "Supprimer",
"flow.menu.duplicate": "Dupliquer",
"flow.menu.editDetails": "Editer les détails",
"flow.menu.export": "Exporter",
"flow.minimumCharacters": "{{count}} e d'au moins [nombre] caractères",
"flow.missingFields": "Veuillez remplir tous les champs obligatoires.",
"flow.moreOptions": "Plus d'options",
"flow.nameAlreadyExists": "Le nom du flux existe déjà",
"flow.nameLabel": "Nom",
"flow.namePlaceholder": "Nom du flux",
"flow.noCompatibleComponents": "Aucun composant compatible n'a été trouvé.",
"flow.noDescription": "Aucune description",
"flow.pleaseEnterDescription": "Veuillez saisir une description",
"flow.pleaseEnterName": "Veuillez saisir un nom",
"flow.replaceComponent": "Remplacer",
"flow.restoreVersion": "Restaurer cette version de votre flux",
"flow.runTimestampPrefix": "Dernière course : ",
"flow.saveAndExit": "Enregistrer et quitter",
"flow.saveVersion": "Enregistrer une version de votre flux",
"flow.savedHover": "Dernière sauvegarde : ",
"flow.savedSuccessfully": "Le flux a été enregistré avec succès!",
"flow.savingChanges": "Enregistrement des modifications...",
@ -299,15 +450,24 @@
"home.dragFlowType": "Partagez vos « {{flowType}} » ici",
"home.dragFlowsOrComponents": "Déposez vos flux ou vos composants ici",
"home.flowTypeNotSupported": "{{flowType}} non pris en charge",
"input.addActions": "Ajouter des actions",
"input.addMcpServer": "Ajouter un serveur MCP",
"input.addNewVariable": "Ajouter une nouvelle variable",
"input.editCodeTitle": "Editer le code",
"input.editTextPlaceholder": "Écrivez votre message ici.",
"input.editTextTitle": "Modifier le texte",
"input.emptyOutput": "Message vide.",
"input.errorUpdatingComponent": "Une erreur inattendue s'est produite lors de la mise à jour du composant. Faites une nouvelle tentative.",
"input.floatNumberFull": "Saisissez un nombre à virgule flottante",
"input.floatNumberShort": "Numéro de flotteur",
"input.noInputMessage": "Aucun message n'a été fourni.",
"input.placeholder": "Tapez quelque chose...",
"input.searchOptions": "Options de recherche...",
"input.titleErrorUpdatingComponent": "Erreur lors de la mise à jour du composant",
"input.toolsetPlaceholder": "Utilisé comme outil",
"input.typeKey": "Tapez une clé...",
"input.typeValue": "Entrez une valeur...",
"jsonEditor.pathPlaceholder": "Entrez un chemin d'accès (par exemple, users[0].name) ou une requête JSON (par exemple,.users | filter(.age > 25))",
"knowledge.addKnowledge": "Ajouter des connaissances",
"knowledge.addSources": "Ajouter des sources",
"knowledge.addSourcesDescription": "Télécharger des fichiers et configurer les paramètres de fractionnement",
@ -451,6 +611,9 @@
"misc.alertSaveWithApi": "⚠️ Attention : l'exportation de ce flux peut entraîner la divulgation d'identifiants sensibles.",
"misc.apiAccess": "Accès à l'API",
"misc.chatTitle": "Langflow Chat",
"misc.copyFailed": "La copie a échoué.",
"misc.copyJson": "Copier le JSON dans le presse-papiers",
"misc.editorNotAvailable": "Éditeur indisponible",
"misc.embedIntoSite": "Intégrer au site",
"misc.export": "Exporter",
"misc.fetchError": "Impossible d'établir une connexion.",
@ -468,6 +631,7 @@
"misc.textInputModalTitle": "Modifier le contenu du texte",
"misc.timeoutError": "Veuillez patienter quelques instants pendant que le serveur traite votre demande.",
"misc.timeoutErrorDesc": "Le serveur est occupé.",
"misc.unableToCopy": "Impossible de copier dans le presse-papiers. Veuillez le copier manuellement.",
"modal.api.createApiKey": "Créer une clé API",
"modal.api.description": "L'accès à l'API nécessite une clé API. Vous pouvez",
"modal.api.descriptionSuffix": "dans les paramètres.",
@ -553,6 +717,7 @@
"nav.myCollection": "Ma collection",
"nav.myCollectionDesc": "Gérez vos projets. Télécharger et mettre en ligne des collections entières.",
"nav.notifications": "Aucune nouvelle notification",
"node.dismissWarning": "Fermer la barre d'avertissement",
"node.errorNoTemplate": "Erreur dans le composant {{name}}",
"node.errorNoTemplateContact": "Veuillez contacter le développeur du composant pour résoudre ce problème.",
"node.errorNoTemplateDetail": "Le composant {{name}} ne dispose d'aucun modèle.",
@ -595,6 +760,18 @@
"page.githubDescription": "Suivez l'évolution du projet, ajoutez le dépôt à vos favoris et contribuez à façonner l'avenir.",
"page.welcomeDescription": "Votre nouvelle façon préférée d'expédier des agents",
"page.welcomeTitle": "Bienvenue chez Langflow",
"paginator.placeholder": "1",
"playgroundComponent.chatSessions": "Sessions de chat",
"playgroundComponent.clearChat": "Effacer la discussion",
"playgroundComponent.clearSession": "Effacer la session",
"playgroundComponent.closeAndGoBack": "Fermer et revenir au flux",
"playgroundComponent.deleteFile": "Supprimer le fichier",
"playgroundComponent.deleteSession": "Supprimer la session",
"playgroundComponent.enterFullscreen": "Passer en plein écran",
"playgroundComponent.focusChatInput": "Mettre en avant la saisie dans le chat",
"playgroundComponent.messageLogs": "Journaux de messages",
"playgroundComponent.moreOptions": "Plus d'options",
"playgroundComponent.rename": "Renommer",
"project.deletedSuccessfully": "Le projet a été supprimé avec succès.",
"project.errorDeleting": "Erreur lors de la suppression du projet.",
"project.newName": "Nouveau projet",
@ -681,6 +858,7 @@
"shortcuts.name.update": "Mettre à jour",
"shortcuts.restoreButton": "Restaurer",
"shortcuts.title": "Raccourcis",
"sidebar.allSet": "Tout est prêt",
"sidebar.betaLabel": "Bêta",
"sidebar.bundles": "Ensembles",
"sidebar.category.agents": "Agents",
@ -714,17 +892,24 @@
"sidebar.clearSearch": "Effacer votre recherche",
"sidebar.componentSettings": "Paramètres des composants",
"sidebar.components": "Composants",
"sidebar.createFlow": "Créez un flux",
"sidebar.delete": "Supprimer",
"sidebar.discoverMore": "Découvrez d'autres composants",
"sidebar.download": "Télécharger",
"sidebar.downloadError": "Une erreur s'est produite lors du téléchargement de votre projet.",
"sidebar.emptyMessage": "Commencez à créer un projet ou un flux",
"sidebar.getStarted": "Premiers pas",
"sidebar.joinCommunity": "Rejoignez la communauté",
"sidebar.knowledge": "Connaissances",
"sidebar.legacyLabel": "Existant",
"sidebar.mcp.add": "Ajouter un serveur MCP",
"sidebar.mcp.empty": "Aucun serveur MCP n'a été ajouté",
"sidebar.mcp.manage": "Gérer les serveurs",
"sidebar.mcp.title": "Serveurs MCP",
"sidebar.mcpExposeFlows": "Exposer les flux sous forme d'outils à partir de clients tels que Cursor ou Claude.",
"sidebar.mcpGoToServer": "Aller au serveur",
"sidebar.mcpNewBadge": "Nouveau",
"sidebar.mcpProjectsTitle": "Projets en tant que serveurs MCP",
"sidebar.myFiles": "Mes fichiers",
"sidebar.nav.addStickyNotes": "Ajouter des notes autocollantes",
"sidebar.nav.bundles": "Ensembles",
@ -743,6 +928,7 @@
"sidebar.removeFilter": "Retirer le filtre",
"sidebar.searchPlaceholder": "Rechercher",
"sidebar.show": "Afficher",
"sidebar.starRepo": "Ajoutez cette page à vos favoris pour rester informé",
"sidebar.tryDifferentQuery": "ou affinez votre recherche et essayez une autre requête.",
"sidebar.uploadSuccess": "Téléchargé avec succès",
"slider.balanced": "Réparti",
@ -778,25 +964,49 @@
"store.tabFlows": "Flux",
"store.title": "Boutique Langflow",
"storeApiKey.description": "Gérer l'accès à la boutique Langflow.",
"storeApiKey.insertPlaceholder": "Entrez votre clé API",
"storeApiKey.saveError": "Erreur lors de l'enregistrement de la clé API",
"storeApiKey.saveSuccess": "La clé API a été enregistrée avec succès",
"storeApiKey.title": "Boutique Langflow",
"success.apiKeySaved": "L'opération a abouti ! Votre clé API a été enregistrée.",
"success.changesSaved": "Les modifications ont été enregistrées avec succès!",
"success.chatCleared": "La conversation a été effacée avec succès.",
"success.codeReady": "Le code est prêt à être exécuté",
"success.componentIdCopied": "L'identifiant du composant a été copié dans le presse-papiers",
"success.componentOverridden": "{{id}} réussie!",
"success.componentSaved": "{{id}} Enregistré avec succès",
"success.customComponentSaved": "Le nouveau composant a été enregistré avec succès!",
"success.endpointUrlCopied": "URL s sur le terminal copiées",
"success.fileUploaded": "Le fichier a été téléchargé avec succès",
"success.flowBuilt": "Le flux a été créé avec succès",
"success.flowExported": "{{name}} exportation réussie",
"success.ingestionCancelled": "Ingestion annulée",
"success.jsonCopied": "Le JSON a été copié dans le presse-papiers",
"success.keyDeleted": "L'opération a abouti ! Clé supprimée!",
"success.keysDeleted": "L'opération a abouti ! Clés supprimées!",
"success.knowledgeBaseDeleted": "Base de connaissances supprimée",
"success.knowledgeBaseNodeCreated": "Base de connaissances \"{{name}}\" a été créée avec succès!",
"success.messagesDeleted": "Les messages ont été supprimés avec succès.",
"success.messagesUpdated": "Les messages ont été mis à jour avec succès.",
"success.outputCopied": "Copié dans le presse-papiers",
"success.promptReady": "La ligne de commande est prête",
"success.sessionDeleted": "La session a été supprimée avec succès.",
"success.userAdded": "L'opération a abouti ! Un nouvel utilisateur a été ajouté!",
"success.userDeleted": "L'opération a abouti ! Utilisateur supprimé!",
"success.userEdited": "L'opération a abouti ! Modifié par l'utilisateur!",
"success.versionDeleted": "Version supprimée",
"success.versionRestored": "Version restaurée",
"success.versionSaved": "Version enregistrée",
"table.addRow": "Ajouter une nouvelle ligne",
"table.deleteSelected": "Supprimer les éléments sélectionnés",
"table.duplicateSelected": "Dupliquer les éléments sélectionnés",
"table.noColumnDescription": "Il n'y a aucune définition de colonne disponible pour cette table.",
"table.noColumnTitle": "Aucune définition de colonne",
"table.noDataMessage": "Oups ! Il semble qu'il n'y ait aucune donnée à afficher pour le moment. Veuillez revenir plus tard.",
"table.noDataTitle": "Aucune donnée disponible",
"table.resetColumns": "Réinitialiser les colonnes",
"table.selectToDelete": "Sélectionnez les éléments à supprimer",
"table.selectToDuplicate": "Sélectionnez les éléments à dupliquer",
"templatesModal.agents": "Agents",
"templatesModal.allTemplates": "Tous les modèles",
"templatesModal.assistants": "Assistants",
@ -837,5 +1047,21 @@
"toolsModal.parametersSubtitle": "Gérer les données d'entrée pour cet outil",
"toolsModal.parametersTitle": "Paramètres",
"toolsModal.searchPlaceholder": "Outils de recherche...",
"toolsModal.slugHint": "Utilisé comme nom de fonction lorsque cet outil est mis à la disposition de l'agent."
"toolsModal.slugHint": "Utilisé comme nom de fonction lorsque cet outil est mis à la disposition de l'agent.",
"trace.allStatus": "Tous les statuts",
"trace.dateRange": "Plage de dates",
"trace.download": "Télécharger",
"trace.endDate": "Date de fin",
"trace.input": "Entrée",
"trace.invalidDateRange": "Plage de dates non valide",
"trace.output": "Sortie",
"trace.reload": "Recharger",
"trace.searchRuns": "La recherche est en cours...",
"trace.spanTree": "Portées de tracé",
"trace.startDate": "Date de début",
"ui.resizeSidebar": "Redimensionner la barre latérale (utilisez les touches fléchées ou faites glisser pour redimensionner)",
"ui.toggleSidebar": "Afficher/masquer la barre latérale",
"voice.selectLanguage": "Sélectionner une langue",
"voice.selectMicrophone": "Sélectionner un microphone",
"voice.selectVoice": "Sélectionner"
}

View File

@ -1,4 +1,6 @@
{
"accordion.addVariable": "変数の追加",
"accordion.fullscreen": "フルスクリーン",
"account.adminPage": "管理ページ",
"account.discord": "ディスコード",
"account.docs": "文書",
@ -32,12 +34,32 @@
"admin.saveButton": "保存",
"admin.searchPlaceholder": "ユーザー名を検索",
"alerts.apiKeyCopied": "APIキーをコピーしました",
"alerts.buildStopped": "ビルドが停止しました",
"alerts.criticalDataWarning": "警告重要なデータが含まれています。JSONファイルにはAPIキーが含まれている可能性があります。",
"alerts.modelsRefreshed_one": "{{count}} モデルコンポーネントの更新",
"alerts.modelsRefreshed_other": "{{count}} モデルのコンポーネントを更新しました",
"alerts.noChatOutput": "このフローには ChatOutput コンポーネントが含まれていません。",
"alerts.noTemplateVariables": "このテンプレートには変数が含まれていません。",
"assistant.code": "コード",
"assistant.configureModels": "モデルプロバイダーの設定",
"assistant.continue": "続行",
"assistant.maxSessionsLabel": "セッションの最大数",
"assistant.maxSessionsTooltip": "{{max}} セッションの上限に達しました。 セッションを削除して、新しいセッションを作成します。",
"assistant.messageCounts": "{{count}} メッセージ",
"assistant.newSession": "新規セッション",
"assistant.noModelsConfigured": "モデルプロバイダーが設定されていません",
"assistant.noModelsDescription": "アシスタントをご利用いただくには、設定で少なくとも1つのモデルプロバイダーを設定してください。",
"assistant.noPreviousSessions": "過去のセッションはありません",
"assistant.sendMessage": "メッセージの送信",
"assistant.sessionHistory": "セッション履歴",
"assistant.sessionHistoryLabel": "セッション履歴",
"assistant.sessionHistoryTooltip": "セッションデータはご利用のブラウザ内にのみ保存され、別のブラウザでは引き継がれません。また、ブラウザのデータを消去した後も保持されません。",
"assistant.stopGeneration": "生成の停止",
"assistant.workingOnIt": "作業しています...",
"auth.adminLoginButton": "ログイン",
"auth.adminTitle": "管理者",
"auth.alertSaveWithApi": "⚠️ 注意:このフローをエクスポートすると、機密性の高い認証情報が漏洩する恐れがあります。",
"auth.confirmPassword": "パスワードの確認",
"auth.confirmPasswordLabel": "パスワードを確認してください",
"auth.confirmPasswordPlaceholder": "パスワードを確認してください",
"auth.confirmPasswordRequired": "パスワードの確認をお願いします",
@ -58,6 +80,7 @@
"auth.signupTitle": "Langflowに登録する",
"auth.usernameLabel": "ユーザー名",
"auth.usernamePlaceholder": "ユーザー名",
"auth.usernamePlaceholderInput": "ユーザー名",
"auth.usernameRequired": "ユーザー名を入力してください",
"authModal.apiKey.autoInstall": "このマシン上で、選択されたクライアントプロファイルを作成し、キーを登録します。",
"authModal.apiKey.autoInstallBold": "自動インストール",
@ -89,6 +112,7 @@
"authModal.reinstallWarningClients": "認証タイプを変更するには、 {{clients}} およびこのサーバーを使用しているその他のクライアントで、このサーバーを再インストールする必要があります。",
"authModal.saveButton": "保存",
"authModal.title": "MCPサーバーの認証を設定する",
"canvas.addStickyNote": "付箋を追加",
"canvas.agentWorking": "エージェント稼働中",
"canvas.controls": "Canvas コントロール",
"canvas.fitViewTooltip": "すべてのノードを表示するようにビューを調整する",
@ -129,6 +153,99 @@
"deleteModal.noteFolderContents": "および関連するすべてのフローとコンポーネント",
"deleteModal.noteMessageHistory": "およびそのメッセージ履歴",
"deleteModal.title": "削除",
"deployments.addVariable": "+ 変数を追加",
"deployments.agentChat": "エージェント・チャット",
"deployments.ariaDeploymentType": "デプロイメント・タイプ",
"deployments.ariaExistingEnvironments": "既存の環境",
"deployments.ariaSendMessage": "メッセージの送信",
"deployments.attachConnectionToFlow": "「接続」を「フロー」に追加",
"deployments.attachFlows": "フローを添付する",
"deployments.attachedFlowsCount": "添付のフロー( {{count}} ",
"deployments.attachedFlowsLabel": "添付のフロー",
"deployments.availableConnections": "使用可能な接続",
"deployments.availableFlows": "利用可能なフロー",
"deployments.back": "戻る",
"deployments.cancel": "キャンセル",
"deployments.changeFlow": "変更履歴",
"deployments.close": "閉じる",
"deployments.columnAttached": "アタッチ済み",
"deployments.columnCreated": "作成日",
"deployments.columnLastModified": "最終変更日時",
"deployments.columnName": "名前",
"deployments.columnProvider": "プロバイダー",
"deployments.columnProviderKey": "プロバイダーキー",
"deployments.columnTest": "テスト",
"deployments.columnType": "タイプ",
"deployments.columnUrl": "URL",
"deployments.confirm": "確認",
"deployments.connecting": "接続中...",
"deployments.connectionNameExists": "この名前のアカウントはすでに存在します。",
"deployments.connectionNameLabel": "接続名",
"deployments.createConnection": "接続の作成",
"deployments.createFirstConnection": "最初の接続を作成する",
"deployments.createNewDeployment": "新しいデプロイを作成する",
"deployments.createNewDeploymentTitle": "新しいデプロイメントを作成する",
"deployments.current": "現在",
"deployments.deploy": "デプロイ",
"deployments.deploying": "デプロイしています...",
"deployments.deploymentLabel": "デプロイメント",
"deployments.deploymentType": "デプロイメント・タイプ",
"deployments.detachFlow": "フローを切り離す",
"deployments.detaching": "取り外し",
"deployments.editToolName": "ツール名の編集",
"deployments.environmentVariables": "環境変数",
"deployments.existingConnections": "既存の接続",
"deployments.failedToLoadFlows": "添付されたフローを読み込めませんでした",
"deployments.globalVariables": "グローバル変数",
"deployments.labelCreated": "作成日",
"deployments.labelDesc": "降順",
"deployments.labelModel": "モデル",
"deployments.labelModified": "変更済み",
"deployments.labelName": "名前",
"deployments.labelProvider": "プロバイダー",
"deployments.labelType": "タイプ",
"deployments.loadingAttachedFlows": "添付のフローを読み込んでいます...",
"deployments.loadingDeploymentData": "デプロイメントデータの読み込み中...",
"deployments.new": "新規",
"deployments.newConnections": "新しい接続",
"deployments.next": "次へ",
"deployments.noConnectionsDescription": "このフローに認証情報を紐付けるために接続を作成します。",
"deployments.noConnectionsMatch": "\"{{query}}\" に一致する接続はありません",
"deployments.noConnectionsYet": "まだ接続されていません",
"deployments.noDeployments": "デプロイなし",
"deployments.noEnvironments": "環境がありません",
"deployments.noFlowsAttached": "フローは添付されていません",
"deployments.placeholderAgentPurpose": "エージェントの目的を説明してください...",
"deployments.placeholderApiKey": "APIキーを入力してください",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderConnectionName": "例SALES_BOT_PROD",
"deployments.placeholderEnvironmentName": "例:生産",
"deployments.placeholderKey": "キー",
"deployments.placeholderMessage": "メッセージ",
"deployments.placeholderSalesBot": "例:セールスボット",
"deployments.placeholderSearchConnections": "接続を検索...",
"deployments.placeholderValue": "値",
"deployments.provider": "プロバイダー",
"deployments.removing": "削除",
"deployments.review": "レビュー",
"deployments.reviewAndConfirm": "確認・承認",
"deployments.reviewDetails": "作成する前に、デプロイの詳細を確認してください。",
"deployments.reviewUpdate": "レビューの更新",
"deployments.selectDeployment": "展開を選択",
"deployments.selectOrCreateConnection": "接続を選択するか、新しい接続を作成してください",
"deployments.selectProvider": "プロバイダーの選択",
"deployments.skip": "スキップ",
"deployments.stepOf": "{{total}} のステップ {{current}}",
"deployments.test": "テスト",
"deployments.toolsWillBeDetached": "これらのツールはエージェントから切り離されます。 これらは、ご利用のプロバイダーのテナント上で引き続き利用可能です。",
"deployments.undoDetach": "切り離しを元に戻す",
"deployments.unknownFlow": "不明なフロー",
"deployments.untitled": "無題",
"deployments.update": "更新",
"deployments.updateDeployment": "デプロイメントの更新",
"deployments.updating": "更新中...",
"deployments.variablesAutoDetected_one": "{{count}} 選択されたフローのバージョンから変数が自動検出されます。",
"deployments.variablesAutoDetected_other": "{{count}} 選択したフローのバージョンから自動的に検出された変数。",
"dialog.chat": "AIと対話しましょう。 入力、出力、およびメモリを監視する。",
"dialog.code": "このコードを使用して、フローをエクスポートし、統合してください。",
"dialog.codeDict": "必要に応じてキーと値のペアを追加・編集し、辞書をカスタマイズしてください。 新しいオブジェクト {} や配列 [] の追加に対応しています。",
@ -147,6 +264,7 @@
"emptyPage.emptyProject": "空のプロジェクト",
"emptyPage.newFlow": "新しい流れ",
"emptyPage.startBuilding": "構築の開始",
"errors.addMcpServer": "MCPサーバーの追加に失敗しました",
"errors.addUser": "新しいユーザーを追加する際のエラー",
"errors.apiKey": "APIキーのエラー",
"errors.changePassword": "パスワードの変更に失敗しました",
@ -156,8 +274,15 @@
"errors.deleteKeys": "キーの削除エラー",
"errors.deleteSession": "セッションの削除に失敗しました。",
"errors.deleteUser": "ユーザーの削除中にエラーが発生しました",
"errors.deletingMessages": "メッセージの削除に失敗しました。",
"errors.editUser": "ユーザーの編集中にエラーが発生しました",
"errors.failedToExportFlow": "フローのエクスポートに失敗しました",
"errors.failedToLoadDeployment": "デプロイメントの詳細を読み込めませんでした",
"errors.failedToRestoreVersion": "バージョンの復元に失敗しました",
"errors.failedToSaveFlow": "フローの保存に失敗しました",
"errors.fileTooLarge": "ファイルサイズが大きすぎます。 {{maxSizeMB}} より小さいファイルを選択してください。",
"errors.flowNotFound": "フローが見つかりません",
"errors.flowsVariableUndefined": "変数「flows」が未定義です",
"errors.function": "関数にエラーがあります",
"errors.generic": "エラーが発生しました。もう一度お試しください",
"errors.getComponents": "コンポーネントの取得に失敗しました。",
@ -169,14 +294,22 @@
"errors.missedFields": "申し訳ありません。 何か見落としているようですね",
"errors.missingInfo": "申し訳ありません。 必要な情報が入力されていないようです:",
"errors.noApiKey": "APIキーがありません。 Langflow Storeをご利用になるには、1つ追加してください。",
"errors.noDataToExport": "エクスポートできるデータがありません",
"errors.noModelsToRefresh": "更新するモデルコンポーネントはありません",
"errors.parameterNotFound": "テンプレートにそのパラメータが見つかりません",
"errors.passwordMismatch": "パスワードが一致しません",
"errors.profilePictures": "プロフィール画像の取得に失敗しました",
"errors.prompt": "このプロンプトに問題があります。確認してください",
"errors.refreshingModels": "モデルコンポーネントの更新中にエラーが発生しました",
"errors.renamingSession": "セッションの名前変更に失敗しました。",
"errors.saveApiKey": "APIキーの保存中にエラーが発生しました。もう一度お試しください。",
"errors.saveChanges": "変更の保存に失敗しました",
"errors.sendMessage": "メッセージの送信中にエラーが発生しました",
"errors.signin": "ログイン中にエラーが発生しました",
"errors.signup": "登録中にエラーが発生しました",
"errors.templateNotFound": "コンポーネント内にテンプレートが見つかりません",
"errors.tooManyFiles": "ファイルが多すぎます( {{count}} )。 これには、大規模なディレクトリや隠しディレクトリも含まれる可能性が高い。 より小さなフォルダを選択するか、node_modules などのフォルダを除外してください。",
"errors.updatingMessages": "メッセージの更新中にエラーが発生しました。",
"errors.upload": "ファイルのアップロードに失敗しました",
"errors.uploadFile": "ファイルのアップロード中にエラーが発生しました",
"errors.uploadJsonOnly": "JSONファイルをアップロードしてください",
@ -191,6 +324,7 @@
"fileManager.errorUploadingFileDetail": "ファイルのアップロード中にエラーが発生しました",
"fileManager.fileUploadedSuccessfully": "ファイルのアップロードが完了しました",
"fileManager.filesUploadedSuccessfully": "ファイルは正常にアップロードされました",
"fileManager.searchFiles": "ファイルを検索...",
"fileManager.selectAtLeastOneFile": "ファイルを1つ以上選択してください",
"fileManager.selectFile": "ファイルの選択",
"fileManager.selectFiles": "ファイルの選択",
@ -214,11 +348,15 @@
"files.uploadFile": "ファイルのアップロード",
"files.uploadFiles": "ファイルのアップロード",
"files.uploadedSuccessfully": "ファイルのアップロードが完了しました",
"flow.addDescription": "説明を追加...",
"flow.brokenEdgesWarning": "無効な接続がいくつか削除されました:",
"flow.buildStatus": "ステータスを確認するためにビルドする。",
"flow.buildSuccess": "無事に完成しました ✨",
"flow.characterLimitReached": "文字数制限に達しました",
"flow.defaultName": "新しい流れ",
"flow.deletedSuccessfully": "選択した項目が正常に削除されました",
"flow.descriptionLabel": "説明",
"flow.descriptionPlaceholder": "フローの説明",
"flow.duplicatedSuccess": "{{type}} 複製に成功しました",
"flow.enableAutoSaving": "自動保存を有効にする",
"flow.errorDeleting": "項目の削除に失敗しました",
@ -226,14 +364,27 @@
"flow.exitAnyway": "とにかく出る",
"flow.lastSaved": "最終更新日: {{time}}",
"flow.lastSavedNever": "なし",
"flow.lockFlow": "フローのロック",
"flow.lockFlowDescription": "編集や誤った変更を防ぐために、フローをロックしてください。",
"flow.menu.delete": "削除",
"flow.menu.duplicate": "重複",
"flow.menu.editDetails": "詳細の編集",
"flow.menu.export": "エクスポート",
"flow.minimumCharacters": "{{count}} 文字以上入力してください",
"flow.missingFields": "必須項目はすべてご記入ください。",
"flow.moreOptions": "その他のオプション",
"flow.nameAlreadyExists": "そのフロー名はすでに存在します",
"flow.nameLabel": "名前",
"flow.namePlaceholder": "フロー名",
"flow.noCompatibleComponents": "互換性のあるコンポーネントが見つかりませんでした。",
"flow.noDescription": "記述なし",
"flow.pleaseEnterDescription": "説明を入力してください",
"flow.pleaseEnterName": "名前を入力してください",
"flow.replaceComponent": "置換",
"flow.restoreVersion": "このバージョンのフローを復元する",
"flow.runTimestampPrefix": "最終走行: ",
"flow.saveAndExit": "保存して終了",
"flow.saveVersion": "フローのバージョンを保存する",
"flow.savedHover": "最終保存日時: ",
"flow.savedSuccessfully": "フローが正常に保存されました!",
"flow.savingChanges": "変更を保存しています...",
@ -299,15 +450,24 @@
"home.dragFlowType": "{{flowType}} をこちらに投稿してください",
"home.dragFlowsOrComponents": "フローやコンポーネントをここにドロップしてください",
"home.flowTypeNotSupported": "{{flowType}} 対応していません",
"input.addActions": "アクションを追加",
"input.addMcpServer": "MCP サーバーの追加",
"input.addNewVariable": "新しい変数を追加",
"input.editCodeTitle": "コードの編集",
"input.editTextPlaceholder": "ここにメッセージを入力してください。",
"input.editTextTitle": "テキストを編集",
"input.emptyOutput": "メッセージはありません。",
"input.errorUpdatingComponent": "コンポーネントの更新中に予期せぬエラーが発生しました。 再試行してください。",
"input.floatNumberFull": "浮動小数点数を入力してください",
"input.floatNumberShort": "浮き番号",
"input.noInputMessage": "入力メッセージが指定されていません。",
"input.placeholder": "何かを入力してください...",
"input.searchOptions": "検索オプション...",
"input.titleErrorUpdatingComponent": "コンポーネントの更新中にエラーが発生しました",
"input.toolsetPlaceholder": "道具として使われる",
"input.typeKey": "キーを入力してください...",
"input.typeValue": "値を入力してください...",
"jsonEditor.pathPlaceholder": "パスusers[0].nameまたはJSONQuery.users | filter(.age > 25))を入力してください",
"knowledge.addKnowledge": "知識の追加",
"knowledge.addSources": "ソースの追加",
"knowledge.addSourcesDescription": "ファイルをアップロードし、チャンキング設定を行う",
@ -451,6 +611,9 @@
"misc.alertSaveWithApi": "⚠️ 注意:このフローをエクスポートすると、機密性の高い認証情報が漏洩する恐れがあります。",
"misc.apiAccess": "API アクセス",
"misc.chatTitle": "Langflow Chat",
"misc.copyFailed": "コピーが失敗しました",
"misc.copyJson": "JSONをクリップボードにコピー",
"misc.editorNotAvailable": "エディタが利用できません",
"misc.embedIntoSite": "サイトに埋め込む",
"misc.export": "エクスポート",
"misc.fetchError": "接続できませんでした。",
@ -468,6 +631,7 @@
"misc.textInputModalTitle": "テキストの内容を編集する",
"misc.timeoutError": "サーバーがリクエストを処理している間、少々お待ちください。",
"misc.timeoutErrorDesc": "サーバーが混雑しています。",
"misc.unableToCopy": "クリップボードにコピーできません。 手動でコピーしてください。",
"modal.api.createApiKey": "APIキーを作成する",
"modal.api.description": "APIにアクセスするには、APIキーが必要です。 できます",
"modal.api.descriptionSuffix": "設定で。",
@ -553,6 +717,7 @@
"nav.myCollection": "私のコレクション",
"nav.myCollectionDesc": "プロジェクトを管理しましょう。 コレクション全体をダウンロードおよびアップロードします。",
"nav.notifications": "新しい通知はありません",
"node.dismissWarning": "警告バーを閉じる",
"node.errorNoTemplate": "コンポーネント「 {{name}} 」でエラーが発生しました",
"node.errorNoTemplateContact": "この問題を修正するには、コンポーネントの開発元にお問い合わせください。",
"node.errorNoTemplateDetail": "コンポーネント「 {{name}} 」にはテンプレートがありません。",
@ -595,6 +760,18 @@
"page.githubDescription": "開発の進捗をフォローし、リポジトリをスター登録して、未来を形作っていきましょう。",
"page.welcomeDescription": "エージェントを送るのに、きっとお気に入りになる新しい方法",
"page.welcomeTitle": "Langflowへようこそ",
"paginator.placeholder": "1",
"playgroundComponent.chatSessions": "チャットセッション",
"playgroundComponent.clearChat": "チャットをクリアする",
"playgroundComponent.clearSession": "クリア・セッション",
"playgroundComponent.closeAndGoBack": "閉じてフローに戻る",
"playgroundComponent.deleteFile": "ファイルの削除",
"playgroundComponent.deleteSession": "セッションを削除",
"playgroundComponent.enterFullscreen": "全画面表示にする",
"playgroundComponent.focusChatInput": "チャット入力を選択",
"playgroundComponent.messageLogs": "メッセージログ",
"playgroundComponent.moreOptions": "その他のオプション",
"playgroundComponent.rename": "名前変更",
"project.deletedSuccessfully": "プロジェクトが正常に削除されました。",
"project.errorDeleting": "プロジェクトの削除に失敗しました。",
"project.newName": "新規プロジェクト",
@ -681,6 +858,7 @@
"shortcuts.name.update": "更新",
"shortcuts.restoreButton": "復元",
"shortcuts.title": "ショートカット",
"sidebar.allSet": "準備完了",
"sidebar.betaLabel": "ベータ",
"sidebar.bundles": "バンドル",
"sidebar.category.agents": "エージェント",
@ -714,17 +892,24 @@
"sidebar.clearSearch": "検索を消去",
"sidebar.componentSettings": "コンポーネントの設定",
"sidebar.components": "コンポーネント",
"sidebar.createFlow": "フローの作成",
"sidebar.delete": "削除",
"sidebar.discoverMore": "その他のコンポーネントを見る",
"sidebar.download": "ダウンロード",
"sidebar.downloadError": "プロジェクトのダウンロード中にエラーが発生しました。",
"sidebar.emptyMessage": "プロジェクトまたはフローの作成を開始する",
"sidebar.getStarted": "使用を開始する",
"sidebar.joinCommunity": "コミュニティに参加しましょう",
"sidebar.knowledge": "ナレッジ",
"sidebar.legacyLabel": "レガシー",
"sidebar.mcp.add": "MCP サーバーの追加",
"sidebar.mcp.empty": "MCPサーバーは追加されていません",
"sidebar.mcp.manage": "サーバーの管理",
"sidebar.mcp.title": "MCPサーバー",
"sidebar.mcpExposeFlows": "CursorやClaudeなどのクライアントから、フローをツールとして公開する。",
"sidebar.mcpGoToServer": "サーバーへ移動",
"sidebar.mcpNewBadge": "新規",
"sidebar.mcpProjectsTitle": "MCPサーバーとしてのプロジェクト",
"sidebar.myFiles": "マイファイル",
"sidebar.nav.addStickyNotes": "付箋を追加する",
"sidebar.nav.bundles": "バンドル",
@ -743,6 +928,7 @@
"sidebar.removeFilter": "フィルターを削除します。",
"sidebar.searchPlaceholder": "検索",
"sidebar.show": "表示",
"sidebar.starRepo": "最新情報はStarリポジトリをご覧ください",
"sidebar.tryDifferentQuery": "またはフィルタを適用して、別のクエリを試してみてください。",
"sidebar.uploadSuccess": "アップロード成功",
"slider.balanced": "バランスの取れた",
@ -778,25 +964,49 @@
"store.tabFlows": "フロー",
"store.title": "Langflowストア",
"storeApiKey.description": "Langflow Storeへのアクセス権限を管理します。",
"storeApiKey.insertPlaceholder": "APIキーを入力してください",
"storeApiKey.saveError": "APIキーの保存エラー",
"storeApiKey.saveSuccess": "APIキーの保存に成功しました",
"storeApiKey.title": "Langflowストア",
"success.apiKeySaved": "正常終了しました APIキーが保存されました。",
"success.changesSaved": "変更が正常に保存されました!",
"success.chatCleared": "チャットの履歴が正常に削除されました。",
"success.codeReady": "コードは実行可能な状態です",
"success.componentIdCopied": "コンポーネントIDがクリップボードにコピーされました",
"success.componentOverridden": "{{id}} 上書きに成功しました!",
"success.componentSaved": "{{id}} 正常に保存されました",
"success.customComponentSaved": "新しいコンポーネントが正常に保存されました!",
"success.endpointUrlCopied": "エンドポイント URL がコピーされました",
"success.fileUploaded": "ファイルのアップロードが完了しました",
"success.flowBuilt": "フローが正常に構築されました",
"success.flowExported": "{{name}} 正常にエクスポートされました",
"success.ingestionCancelled": "摂取がキャンセルされました",
"success.jsonCopied": "JSONがクリップボードにコピーされました",
"success.keyDeleted": "正常終了しました キーが削除されました!",
"success.keysDeleted": "正常終了しました キーが削除されました!",
"success.knowledgeBaseDeleted": "ナレッジベースが削除されました",
"success.knowledgeBaseNodeCreated": "ナレッジベース「 \"{{name}}\" 」が正常に作成されました!",
"success.messagesDeleted": "メッセージは正常に削除されました。",
"success.messagesUpdated": "メッセージの更新に成功しました。",
"success.outputCopied": "クリップボードにコピーされました",
"success.promptReady": "プロンプトの準備が整いました",
"success.sessionDeleted": "セッションが正常に削除されました。",
"success.userAdded": "正常終了しました 新しいユーザーが追加されました!",
"success.userDeleted": "正常終了しました ユーザーが削除されました!",
"success.userEdited": "正常終了しました ユーザーによる編集!",
"success.versionDeleted": "バージョン削除済み",
"success.versionRestored": "復元されたバージョン",
"success.versionSaved": "バージョンが保存されました",
"table.addRow": "新しい行を追加する",
"table.deleteSelected": "選択した項目を削除する",
"table.duplicateSelected": "選択した項目を複製する",
"table.noColumnDescription": "このテーブルには列定義がありません。",
"table.noColumnTitle": "列の定義がありません",
"table.noDataMessage": "申し訳ありません。 現在、表示するデータがないようです。 後ほど再度ご確認ください。",
"table.noDataTitle": "使用可能なデータがありません",
"table.resetColumns": "列をリセット",
"table.selectToDelete": "削除する項目を選択してください",
"table.selectToDuplicate": "複製する項目を選択してください",
"templatesModal.agents": "エージェント",
"templatesModal.allTemplates": "すべてのテンプレート",
"templatesModal.assistants": "アシスタント",
@ -837,5 +1047,21 @@
"toolsModal.parametersSubtitle": "このツールの入力設定を管理する",
"toolsModal.parametersTitle": "パラメーター",
"toolsModal.searchPlaceholder": "検索ツール...",
"toolsModal.slugHint": "このツールをエージェントに公開する際の関数名として使用されます。"
"toolsModal.slugHint": "このツールをエージェントに公開する際の関数名として使用されます。",
"trace.allStatus": "すべてのステータス",
"trace.dateRange": "日付範囲",
"trace.download": "ダウンロード",
"trace.endDate": "終了日",
"trace.input": "入力",
"trace.invalidDateRange": "日付範囲が不正です",
"trace.output": "出力",
"trace.reload": "再ロード",
"trace.searchRuns": "検索が実行されます...",
"trace.spanTree": "トレースのスパン",
"trace.startDate": "開始日",
"ui.resizeSidebar": "サイドバーのサイズを変更する(矢印キーを使用するか、ドラッグしてサイズを変更してください)",
"ui.toggleSidebar": "サイドバーの表示/非表示を切り替える",
"voice.selectLanguage": "言語の選択",
"voice.selectMicrophone": "マイクを選択",
"voice.selectVoice": "選択"
}

View File

@ -1,4 +1,6 @@
{
"accordion.addVariable": "Incluir variável",
"accordion.fullscreen": "Tela cheia",
"account.adminPage": "Página de administração",
"account.discord": "Discord",
"account.docs": "Documentos",
@ -32,12 +34,32 @@
"admin.saveButton": "Salvar",
"admin.searchPlaceholder": "Pesquisar nome de usuário",
"alerts.apiKeyCopied": "Chave da API copiada!",
"alerts.buildStopped": "A compilação foi interrompida",
"alerts.criticalDataWarning": "Aviso: dados confidenciais; o arquivo JSON pode conter chaves de API.",
"alerts.modelsRefreshed_one": "Componente de modelo \" {{count}} \" atualizado",
"alerts.modelsRefreshed_other": "Componentes atualizados do modelo \" {{count}} \"",
"alerts.noChatOutput": "Não há nenhum componente \" ChatOutput \" no fluxo.",
"alerts.noTemplateVariables": "Seu modelo não contém nenhuma variável.",
"assistant.code": "Código",
"assistant.configureModels": "Configurar provedores de modelos",
"assistant.continue": "Continuar",
"assistant.maxSessionsLabel": "Máximo de sessões",
"assistant.maxSessionsTooltip": "Atingido o limite máximo de {{max}} sessões. Exclua uma sessão para criar uma nova.",
"assistant.messageCounts": "{{count}} mensagens",
"assistant.newSession": "Nova sessão",
"assistant.noModelsConfigured": "Nenhum provedor de modelo configurado",
"assistant.noModelsDescription": "Para usar o assistente, configure pelo menos um provedor de modelos nas suas configurações.",
"assistant.noPreviousSessions": "Não há sessões anteriores",
"assistant.sendMessage": "Enviar mensagem",
"assistant.sessionHistory": "Histórico de sessões",
"assistant.sessionHistoryLabel": "Histórico de sessões",
"assistant.sessionHistoryTooltip": "As sessões são armazenadas apenas no seu navegador e não serão mantidas em outros navegadores nem após a limpeza dos dados do navegador.",
"assistant.stopGeneration": "Parar geração",
"assistant.workingOnIt": "Trabalhando nisso...",
"auth.adminLoginButton": "Efetuar Login",
"auth.adminTitle": "Administrador",
"auth.alertSaveWithApi": "⚠️ Atenção: a exportação deste fluxo pode expor credenciais confidenciais.",
"auth.confirmPassword": "Confirmar senha",
"auth.confirmPasswordLabel": "Confirme sua senha",
"auth.confirmPasswordPlaceholder": "Confirme sua senha",
"auth.confirmPasswordRequired": "Confirme sua senha",
@ -58,6 +80,7 @@
"auth.signupTitle": "Inscreva-se no Langflow",
"auth.usernameLabel": "Nome do usuário",
"auth.usernamePlaceholder": "Nome do usuário",
"auth.usernamePlaceholderInput": "Nome do usuário",
"auth.usernameRequired": "Digite seu nome de usuário",
"authModal.apiKey.autoInstall": "cria e insere uma chave no perfil de cliente selecionado nesta máquina.",
"authModal.apiKey.autoInstallBold": "Instalação automática",
@ -89,6 +112,7 @@
"authModal.reinstallWarningClients": "A alteração do tipo de autenticação exige a reinstalação deste servidor no {{clients}} e em todos os outros clientes onde ele é utilizado.",
"authModal.saveButton": "Salvar",
"authModal.title": "Configurar a autenticação do servidor MCP",
"canvas.addStickyNote": "Adicionar nota adesiva",
"canvas.agentWorking": "Agente em atividade",
"canvas.controls": "Controles do Canvas",
"canvas.fitViewTooltip": "Ajustar a visualização para mostrar todos os nós",
@ -129,6 +153,99 @@
"deleteModal.noteFolderContents": "e todos os fluxos e componentes associados",
"deleteModal.noteMessageHistory": "e seu histórico de mensagens",
"deleteModal.title": "Excluir",
"deployments.addVariable": "+ Adicionar variável",
"deployments.agentChat": "Bate-papo com agentes",
"deployments.ariaDeploymentType": "Tipo de implementação",
"deployments.ariaExistingEnvironments": "Ambientes existentes",
"deployments.ariaSendMessage": "Enviar mensagem",
"deployments.attachConnectionToFlow": "Associar conexão ao fluxo",
"deployments.attachFlows": "Anexar fluxos",
"deployments.attachedFlowsCount": "Fluxos anexados ( {{count}} )",
"deployments.attachedFlowsLabel": "Fluxos anexados",
"deployments.availableConnections": "Conexões disponíveis",
"deployments.availableFlows": "Fluxos disponíveis",
"deployments.back": "Voltar",
"deployments.cancel": "Cancelar",
"deployments.changeFlow": "Fluxo de alterações",
"deployments.close": "Fechar",
"deployments.columnAttached": "Anexado",
"deployments.columnCreated": "Criado em",
"deployments.columnLastModified": "Modificado pela última vez",
"deployments.columnName": "Nome",
"deployments.columnProvider": "Provedor",
"deployments.columnProviderKey": "Chave do provedor",
"deployments.columnTest": "Testar",
"deployments.columnType": "Tipo",
"deployments.columnUrl": "URL",
"deployments.confirm": "Confirmar",
"deployments.connecting": "Conectando...",
"deployments.connectionNameExists": "Já existe uma conexão com esse nome.",
"deployments.connectionNameLabel": "Nome de conexão",
"deployments.createConnection": "Criar conexão",
"deployments.createFirstConnection": "Crie sua primeira conexão",
"deployments.createNewDeployment": "Criar nova implantação",
"deployments.createNewDeploymentTitle": "Criar nova implantação",
"deployments.current": "Atual",
"deployments.deploy": "Implementar",
"deployments.deploying": "Implementando...",
"deployments.deploymentLabel": "Implementação",
"deployments.deploymentType": "Tipo de implementação",
"deployments.detachFlow": "Desligar o fluxo",
"deployments.detaching": "Desligando",
"deployments.editToolName": "Editar nome da ferramenta",
"deployments.environmentVariables": "Variáveis de ambiente",
"deployments.existingConnections": "Conexões existentes",
"deployments.failedToLoadFlows": "Não foi possível carregar os fluxos anexados",
"deployments.globalVariables": "Variáveis globais",
"deployments.labelCreated": "Criado em",
"deployments.labelDesc": "Decresc.",
"deployments.labelModel": "Modelo",
"deployments.labelModified": "Modificado",
"deployments.labelName": "Nome",
"deployments.labelProvider": "Provedor",
"deployments.labelType": "Tipo",
"deployments.loadingAttachedFlows": "Carregando fluxos anexados...",
"deployments.loadingDeploymentData": "Carregando dados de implantação...",
"deployments.new": "Novo",
"deployments.newConnections": "Novas conexões",
"deployments.next": "Avançar",
"deployments.noConnectionsDescription": "Crie uma conexão para associar credenciais a este fluxo.",
"deployments.noConnectionsMatch": "Não foram encontradas conexões correspondentes a \"{{query}}\"",
"deployments.noConnectionsYet": "Ainda não há conexões",
"deployments.noDeployments": "Sem implantações",
"deployments.noEnvironments": "Sem ambientes",
"deployments.noFlowsAttached": "Sem fluxos associados",
"deployments.placeholderAgentPurpose": "Descreva o objetivo do agente...",
"deployments.placeholderApiKey": "Insira sua chave de API",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderConnectionName": "por exemplo, SALES_BOT_PROD",
"deployments.placeholderEnvironmentName": "por exemplo, Produção",
"deployments.placeholderKey": "Chave",
"deployments.placeholderMessage": "Mensagem",
"deployments.placeholderSalesBot": "por exemplo, Bot de vendas",
"deployments.placeholderSearchConnections": "Procurar conexões...",
"deployments.placeholderValue": "Valor",
"deployments.provider": "Provedor",
"deployments.removing": "removendo",
"deployments.review": "Revisão",
"deployments.reviewAndConfirm": "Revisar e confirmar",
"deployments.reviewDetails": "Verifique os detalhes da implantação antes de criar.",
"deployments.reviewUpdate": "Atualização da avaliação",
"deployments.selectDeployment": "Selecionar implementação",
"deployments.selectOrCreateConnection": "Selecionar ou criar uma nova conexão",
"deployments.selectProvider": "Selecione o provedor",
"deployments.skip": "Ignorar",
"deployments.stepOf": "Etapa {{current}} de {{total}}",
"deployments.test": "Testar",
"deployments.toolsWillBeDetached": "Essas ferramentas serão desligadas do agente. Eles continuarão disponíveis no seu tenant do provedor.",
"deployments.undoDetach": "Desfazer desanexar",
"deployments.unknownFlow": "Vazão desconhecida",
"deployments.untitled": "Sem título",
"deployments.update": "Atualizar",
"deployments.updateDeployment": "Atualização da implantação",
"deployments.updating": "Atualizando...",
"deployments.variablesAutoDetected_one": "{{count}} variável detectada automaticamente a partir da versão do fluxo selecionada.",
"deployments.variablesAutoDetected_other": "{{count}} variáveis detectadas automaticamente a partir da versão do fluxo selecionada.",
"dialog.chat": "Interaja com sua IA. Monitore entradas, saídas e memórias.",
"dialog.code": "Exporte seu fluxo para integrá-lo usando este código.",
"dialog.codeDict": "Personalize seu dicionário, adicionando ou editando pares chave-valor conforme necessário. Suporta a adição de novos objetos {} ou matrizes [].",
@ -147,6 +264,7 @@
"emptyPage.emptyProject": "Projeto vazio",
"emptyPage.newFlow": "Novo fluxo",
"emptyPage.startBuilding": "Iniciar a construção",
"errors.addMcpServer": "Erro ao adicionar o servidor MCP",
"errors.addUser": "Erro ao adicionar um novo usuário",
"errors.apiKey": "Erro na chave da API",
"errors.changePassword": "Erro ao alterar a senha",
@ -156,8 +274,15 @@
"errors.deleteKeys": "Erro ao excluir chaves",
"errors.deleteSession": "Erro ao excluir a sessão.",
"errors.deleteUser": "Erro ao excluir usuário",
"errors.deletingMessages": "Erro ao excluir mensagens.",
"errors.editUser": "Erro ao editar usuário",
"errors.failedToExportFlow": "Falha ao exportar o fluxo",
"errors.failedToLoadDeployment": "Não foi possível carregar os detalhes da implantação",
"errors.failedToRestoreVersion": "Falha ao restaurar a versão",
"errors.failedToSaveFlow": "Falha ao salvar o fluxo",
"errors.fileTooLarge": "O tamanho do arquivo é muito grande. Selecione um arquivo com menos de {{maxSizeMB}}.",
"errors.flowNotFound": "Fluxo não encontrado",
"errors.flowsVariableUndefined": "Variável Flows não definida",
"errors.function": "Há um erro na sua função",
"errors.generic": "Ocorreu um erro. Por favor, tente novamente",
"errors.getComponents": "Erro ao carregar os componentes.",
@ -169,14 +294,22 @@
"errors.missedFields": "Ops! Parece que você deixou passar alguma coisa",
"errors.missingInfo": "Ops! Parece que faltam algumas informações obrigatórias:",
"errors.noApiKey": "Você não possui uma chave de API. Adicione um para usar a Loja Langflow.",
"errors.noDataToExport": "Não há dados disponíveis para exportação",
"errors.noModelsToRefresh": "Não há componentes do modelo para atualizar",
"errors.parameterNotFound": "Parâmetro não encontrado no modelo",
"errors.passwordMismatch": "As senhas não correspondem",
"errors.profilePictures": "Erro ao recuperar fotos de perfil",
"errors.prompt": "Há algo de errado com esta solicitação; por favor, verifique-a",
"errors.refreshingModels": "Erro ao atualizar os componentes do modelo",
"errors.renamingSession": "Erro ao renomear a sessão.",
"errors.saveApiKey": "Ocorreu um erro ao salvar a chave da API. Tente novamente.",
"errors.saveChanges": "Erro ao salvar as alterações",
"errors.sendMessage": "Ocorreu um erro ao enviar a mensagem",
"errors.signin": "Erro ao fazer login",
"errors.signup": "Erro ao se inscrever",
"errors.templateNotFound": "Modelo não encontrado no componente",
"errors.tooManyFiles": "Foram detectados muitos arquivos ( {{count}} ). Isso provavelmente inclui diretórios grandes ou ocultos. Selecione uma pasta menor ou exclua pastas como node_modules.",
"errors.updatingMessages": "Erro ao atualizar as mensagens.",
"errors.upload": "Erro ao enviar o arquivo",
"errors.uploadFile": "Ocorreu um erro ao enviar o arquivo",
"errors.uploadJsonOnly": "Por favor, envie um arquivo JSON",
@ -191,6 +324,7 @@
"fileManager.errorUploadingFileDetail": "Ocorreu um erro ao enviar o arquivo",
"fileManager.fileUploadedSuccessfully": "Arquivo enviado com sucesso",
"fileManager.filesUploadedSuccessfully": "Arquivos transferidos por upload com sucesso",
"fileManager.searchFiles": "Pesquisar arquivos...",
"fileManager.selectAtLeastOneFile": "Selecione pelo menos um arquivo",
"fileManager.selectFile": "Selecione arquivo",
"fileManager.selectFiles": "Selecionar arquivos",
@ -214,11 +348,15 @@
"files.uploadFile": "Fazer upload de arquivo",
"files.uploadFiles": "Fazer upload de arquivos",
"files.uploadedSuccessfully": "Arquivo enviado com sucesso",
"flow.addDescription": "Adicione uma descrição...",
"flow.brokenEdgesWarning": "Algumas conexões foram removidas por serem inválidas:",
"flow.buildStatus": "Compilar para verificar o status.",
"flow.buildSuccess": "Construído com sucesso ✨",
"flow.characterLimitReached": "Limite de caracteres atingido",
"flow.defaultName": "Novo fluxo",
"flow.deletedSuccessfully": "Os itens selecionados foram excluídos com sucesso",
"flow.descriptionLabel": "Descrição",
"flow.descriptionPlaceholder": "Descrição do fluxo",
"flow.duplicatedSuccess": "{{type}} duplicado com sucesso",
"flow.enableAutoSaving": "Ativar o salvamento automático",
"flow.errorDeleting": "Erro ao excluir itens",
@ -226,14 +364,27 @@
"flow.exitAnyway": "Saia mesmo assim",
"flow.lastSaved": "Última gravação: {{time}}",
"flow.lastSavedNever": "Nunca",
"flow.lockFlow": "Bloquear fluxo",
"flow.lockFlowDescription": "Bloqueie seu fluxo para impedir edições ou alterações acidentais.",
"flow.menu.delete": "Excluir",
"flow.menu.duplicate": "Duplicata",
"flow.menu.editDetails": "Editar detalhes",
"flow.menu.export": "Exportar",
"flow.minimumCharacters": "São necessários pelo menos {{count}} caracteres",
"flow.missingFields": "Preencha todos os campos obrigatórios.",
"flow.moreOptions": "Mais opções",
"flow.nameAlreadyExists": "O nome do fluxo já existe",
"flow.nameLabel": "Nome",
"flow.namePlaceholder": "Nome do fluxo",
"flow.noCompatibleComponents": "Não foram encontrados componentes compatíveis.",
"flow.noDescription": "Sem descrição",
"flow.pleaseEnterDescription": "Insira uma descrição",
"flow.pleaseEnterName": "Digite um nome",
"flow.replaceComponent": "Substituir",
"flow.restoreVersion": "Restaurar esta versão do seu fluxo",
"flow.runTimestampPrefix": "Última corrida: ",
"flow.saveAndExit": "Salvar e sair",
"flow.saveVersion": "Salve uma versão do seu fluxo",
"flow.savedHover": "Última gravação: ",
"flow.savedSuccessfully": "Fluxo salvo com sucesso!",
"flow.savingChanges": "Salvando suas alterações...",
@ -299,15 +450,24 @@
"home.dragFlowType": "Envie aqui o seu \" {{flowType}} \"",
"home.dragFlowsOrComponents": "Coloque seus fluxos ou componentes aqui",
"home.flowTypeNotSupported": "{{flowType}} não é compatível",
"input.addActions": "Adicionar ações",
"input.addMcpServer": "Incluir servidor MCP",
"input.addNewVariable": "Adicionar nova variável",
"input.editCodeTitle": "Editar código",
"input.editTextPlaceholder": "Digite sua mensagem aqui.",
"input.editTextTitle": "Editar texto",
"input.emptyOutput": "Mensagem vazia.",
"input.errorUpdatingComponent": "Ocorreu um erro inesperado durante a atualização do componente. Tente novamente.",
"input.floatNumberFull": "Digite um número de tipo float",
"input.floatNumberShort": "Número de flutuação",
"input.noInputMessage": "Não foi fornecida nenhuma mensagem de entrada.",
"input.placeholder": "Digite algo...",
"input.searchOptions": "Opções de pesquisa...",
"input.titleErrorUpdatingComponent": "Erro ao atualizar o componente",
"input.toolsetPlaceholder": "Usado como ferramenta",
"input.typeKey": "Digite a tecla...",
"input.typeValue": "Digite um valor...",
"jsonEditor.pathPlaceholder": "Insira o caminho (por exemplo, users[0].name) ou uma consulta JSON (por exemplo,.users | filter(.age > 25))",
"knowledge.addKnowledge": "Incluir conhecimento",
"knowledge.addSources": "Incluir origens",
"knowledge.addSourcesDescription": "Carregue arquivos e configure as opções de fragmentação",
@ -451,6 +611,9 @@
"misc.alertSaveWithApi": "⚠️ Atenção: a exportação deste fluxo pode expor credenciais confidenciais.",
"misc.apiAccess": "Acesso à API",
"misc.chatTitle": "Langflow Chat",
"misc.copyFailed": "Cópia com falha",
"misc.copyJson": "Copiar JSON para a área de transferência",
"misc.editorNotAvailable": "Editor indisponível",
"misc.embedIntoSite": "Incorporar no site",
"misc.export": "Exportar",
"misc.fetchError": "Não foi possível estabelecer uma conexão.",
@ -468,6 +631,7 @@
"misc.textInputModalTitle": "Editar o conteúdo do texto",
"misc.timeoutError": "Aguarde alguns instantes enquanto o servidor processa sua solicitação.",
"misc.timeoutErrorDesc": "O servidor está ocupado.",
"misc.unableToCopy": "Não foi possível copiar para a área de transferência. Copie manualmente.",
"modal.api.createApiKey": "criar uma chave de API",
"modal.api.description": "O acesso à API requer uma chave de API. Você pode",
"modal.api.descriptionSuffix": "nas configurações.",
@ -553,6 +717,7 @@
"nav.myCollection": "Minha coleção",
"nav.myCollectionDesc": "Gerencie seus projetos. Baixe e envie coleções inteiras.",
"nav.notifications": "Não há novas notificações",
"node.dismissWarning": "Fechar a barra de aviso",
"node.errorNoTemplate": "Erro no componente {{name}}",
"node.errorNoTemplateContact": "Entre em contato com o desenvolvedor do componente para resolver esse problema.",
"node.errorNoTemplateDetail": "O componente {{name}} não possui modelo.",
@ -595,6 +760,18 @@
"page.githubDescription": "Acompanhe o desenvolvimento, marque o repositório como favorito e ajude a moldar o futuro.",
"page.welcomeDescription": "A sua nova forma preferida de enviar Agentes",
"page.welcomeTitle": "Bem-vindo ao Langflow",
"paginator.placeholder": "1",
"playgroundComponent.chatSessions": "Sessões de chat",
"playgroundComponent.clearChat": "Limpar o chat",
"playgroundComponent.clearSession": "Limpar sessão",
"playgroundComponent.closeAndGoBack": "Fechar e voltar ao fluxo",
"playgroundComponent.deleteFile": "Excluir arquivo",
"playgroundComponent.deleteSession": "Excluir sessão",
"playgroundComponent.enterFullscreen": "Entrar em tela cheia",
"playgroundComponent.focusChatInput": "Foco na entrada do chat",
"playgroundComponent.messageLogs": "Registros de mensagens",
"playgroundComponent.moreOptions": "Mais opções",
"playgroundComponent.rename": "Renomear",
"project.deletedSuccessfully": "O projeto foi excluído com sucesso.",
"project.errorDeleting": "Erro ao excluir o projeto.",
"project.newName": "Novo projeto",
@ -681,6 +858,7 @@
"shortcuts.name.update": "Atualizar",
"shortcuts.restoreButton": "Restaurar",
"shortcuts.title": "Atalhos",
"sidebar.allSet": "Tudo pronto",
"sidebar.betaLabel": "Beta",
"sidebar.bundles": "Pacotes Configuráveis",
"sidebar.category.agents": "Agentes",
@ -714,17 +892,24 @@
"sidebar.clearSearch": "Limpar a pesquisa",
"sidebar.componentSettings": "Configurações dos componentes",
"sidebar.components": "Componentes",
"sidebar.createFlow": "Crie um fluxo",
"sidebar.delete": "Excluir",
"sidebar.discoverMore": "Descubra mais componentes",
"sidebar.download": "Baixe aqui",
"sidebar.downloadError": "Ocorreu um erro ao baixar seu projeto.",
"sidebar.emptyMessage": "Comece a criar um projeto ou um fluxo",
"sidebar.getStarted": "Introdução",
"sidebar.joinCommunity": "Junte-se à comunidade",
"sidebar.knowledge": "Conhecimento",
"sidebar.legacyLabel": "Anterior",
"sidebar.mcp.add": "Incluir servidor MCP",
"sidebar.mcp.empty": "Nenhum servidor MCP foi adicionado",
"sidebar.mcp.manage": "Gerenciar servidores",
"sidebar.mcp.title": "Servidores MCP",
"sidebar.mcpExposeFlows": "Exiba fluxos como ferramentas a partir de clientes como o Cursor ou o Claude.",
"sidebar.mcpGoToServer": "Acessar o servidor",
"sidebar.mcpNewBadge": "Novo",
"sidebar.mcpProjectsTitle": "Projetos como servidores MCP",
"sidebar.myFiles": "Meus arquivos",
"sidebar.nav.addStickyNotes": "Adicionar notas adesivas",
"sidebar.nav.bundles": "Pacotes Configuráveis",
@ -743,6 +928,7 @@
"sidebar.removeFilter": "Remover filtro",
"sidebar.searchPlaceholder": "Procura",
"sidebar.show": "Mostrar",
"sidebar.starRepo": "Marque como favorito para receber atualizações",
"sidebar.tryDifferentQuery": "ou filtre e tente uma consulta diferente.",
"sidebar.uploadSuccess": "Transferido por upload com sucesso",
"slider.balanced": "Balanceado",
@ -778,25 +964,49 @@
"store.tabFlows": "Fluxos",
"store.title": "Loja Langflow",
"storeApiKey.description": "Gerenciar o acesso à Loja Langflow.",
"storeApiKey.insertPlaceholder": "Insira sua chave de API",
"storeApiKey.saveError": "Erro ao salvar a chave da API",
"storeApiKey.saveSuccess": "Chave da API salva com sucesso",
"storeApiKey.title": "Loja Langflow",
"success.apiKeySaved": "Sucesso! Sua chave de API foi salva.",
"success.changesSaved": "Alterações salvas com sucesso!",
"success.chatCleared": "O chat foi apagado com sucesso.",
"success.codeReady": "O código está pronto para ser executado",
"success.componentIdCopied": "ID do componente copiado para a área de transferência",
"success.componentOverridden": "{{id}} substituído com sucesso!",
"success.componentSaved": "{{id}} Salvo com sucesso",
"success.customComponentSaved": "Novo componente salvo com sucesso!",
"success.endpointUrlCopied": "URL o do terminal copiado",
"success.fileUploaded": "Arquivo enviado com sucesso",
"success.flowBuilt": "O fluxo foi criado com sucesso",
"success.flowExported": "{{name}} exportado com sucesso",
"success.ingestionCancelled": "Ingestão cancelada",
"success.jsonCopied": "JSON copiado para a área de transferência",
"success.keyDeleted": "Sucesso! Chave excluída!",
"success.keysDeleted": "Sucesso! Chaves excluídas!",
"success.knowledgeBaseDeleted": "Base de conhecimento excluída",
"success.knowledgeBaseNodeCreated": "A Base de Conhecimento \"{{name}}\" foi criada com sucesso!",
"success.messagesDeleted": "As mensagens foram excluídas com sucesso.",
"success.messagesUpdated": "As mensagens foram atualizadas com sucesso.",
"success.outputCopied": "Copiado para a área de transferência",
"success.promptReady": "O prompt está pronto",
"success.sessionDeleted": "A sessão foi excluída com sucesso.",
"success.userAdded": "Sucesso! Novo usuário adicionado!",
"success.userDeleted": "Sucesso! Usuário excluído!",
"success.userEdited": "Sucesso! Editado pelo usuário!",
"success.versionDeleted": "Versão excluída",
"success.versionRestored": "Versão restaurada",
"success.versionSaved": "Versão salva",
"table.addRow": "Adicionar uma nova linha",
"table.deleteSelected": "Excluir itens selecionados",
"table.duplicateSelected": "Duplicar os itens selecionados",
"table.noColumnDescription": "Não há definições de colunas disponíveis para esta tabela.",
"table.noColumnTitle": "Sem definições de colunas",
"table.noDataMessage": "Ops! Parece que não há dados para exibir no momento. Por favor, volte mais tarde.",
"table.noDataTitle": "Nenhum dado disponível",
"table.resetColumns": "Redefinir colunas",
"table.selectToDelete": "Selecione os itens a serem excluídos",
"table.selectToDuplicate": "Selecione os itens a serem duplicados",
"templatesModal.agents": "Agentes",
"templatesModal.allTemplates": "Todos os modelos",
"templatesModal.assistants": "Assistentes",
@ -837,5 +1047,21 @@
"toolsModal.parametersSubtitle": "Gerenciar entradas para esta ferramenta",
"toolsModal.parametersTitle": "Parâmetros",
"toolsModal.searchPlaceholder": "Ferramentas de pesquisa...",
"toolsModal.slugHint": "Usado como nome da função quando esta ferramenta é disponibilizada ao agente."
"toolsModal.slugHint": "Usado como nome da função quando esta ferramenta é disponibilizada ao agente.",
"trace.allStatus": "Todos os status",
"trace.dateRange": "Intervalo de data",
"trace.download": "Baixe aqui",
"trace.endDate": "Data de encerramento",
"trace.input": "Entrada",
"trace.invalidDateRange": "Intervalo de datas inválido",
"trace.output": "Saída",
"trace.reload": "Recarregar",
"trace.searchRuns": "Pesquisa em andamento...",
"trace.spanTree": "Intervalos de rastreamento",
"trace.startDate": "Data de Início",
"ui.resizeSidebar": "Redimensione a barra lateral (use as setas do teclado ou arraste para redimensionar)",
"ui.toggleSidebar": "Alternar a barra lateral",
"voice.selectLanguage": "Selecionar idioma",
"voice.selectMicrophone": "Selecionar microfone",
"voice.selectVoice": "Selecionar"
}

View File

@ -1,4 +1,6 @@
{
"accordion.addVariable": "添加变量",
"accordion.fullscreen": "全屏",
"account.adminPage": "管理页面",
"account.discord": "Discord",
"account.docs": "文档",
@ -32,12 +34,32 @@
"admin.saveButton": "保存",
"admin.searchPlaceholder": "搜索用户名",
"alerts.apiKeyCopied": "API密钥已复制",
"alerts.buildStopped": "构建已停止",
"alerts.criticalDataWarning": "警告关键数据JSON 文件可能包含 API 密钥。",
"alerts.modelsRefreshed_one": "更新了 {{count}} 模型组件",
"alerts.modelsRefreshed_other": "更新了 {{count}} 的模型组件",
"alerts.noChatOutput": "该流程中没有 ChatOutput 组件。",
"alerts.noTemplateVariables": "您的模板中没有变量。",
"assistant.code": "代码",
"assistant.configureModels": "配置模型提供程序",
"assistant.continue": "继续",
"assistant.maxSessionsLabel": "最大会话数",
"assistant.maxSessionsTooltip": "已达到 {{max}} 会话的上限。 删除当前会话以创建新会话。",
"assistant.messageCounts": "{{count}} msgs",
"assistant.newSession": "新建会话",
"assistant.noModelsConfigured": "未配置模型提供程序",
"assistant.noModelsDescription": "要使用该助手,请在设置中配置至少一个模型提供商。",
"assistant.noPreviousSessions": "没有之前的会话",
"assistant.sendMessage": "发送消息",
"assistant.sessionHistory": "会话历史记录",
"assistant.sessionHistoryLabel": "会话历史记录",
"assistant.sessionHistoryTooltip": "会话仅存储在您的浏览器中,不会在不同浏览器之间保留,也不会保留在清除浏览器数据之后。",
"assistant.stopGeneration": "停止生成",
"assistant.workingOnIt": "正在处理...",
"auth.adminLoginButton": "登录",
"auth.adminTitle": "管理员",
"auth.alertSaveWithApi": "⚠️ 注意:导出此流程可能会泄露敏感凭据。",
"auth.confirmPassword": "确认密码",
"auth.confirmPasswordLabel": "请确认您的密码",
"auth.confirmPasswordPlaceholder": "请确认您的密码",
"auth.confirmPasswordRequired": "请确认您的密码",
@ -58,6 +80,7 @@
"auth.signupTitle": "注册 Langflow",
"auth.usernameLabel": "用户名",
"auth.usernamePlaceholder": "用户名",
"auth.usernamePlaceholderInput": "用户名",
"auth.usernameRequired": "请输入您的用户名",
"authModal.apiKey.autoInstall": "在该计算机上创建密钥并将其注入到所选的客户端配置文件中。",
"authModal.apiKey.autoInstallBold": "自动安装",
@ -89,6 +112,7 @@
"authModal.reinstallWarningClients": "更改身份验证类型需要重新安装此服务器,包括在 {{clients}} 以及所有使用该服务器的其他客户端上。",
"authModal.saveButton": "保存",
"authModal.title": "配置 MCP 服务器身份验证",
"canvas.addStickyNote": "添加便签",
"canvas.agentWorking": "代理正在运行",
"canvas.controls": "Canvas 控件",
"canvas.fitViewTooltip": "调整视图以显示所有节点",
@ -129,6 +153,99 @@
"deleteModal.noteFolderContents": "以及所有相关的流程和组件",
"deleteModal.noteMessageHistory": "及其消息记录",
"deleteModal.title": "删除",
"deployments.addVariable": "+ 添加变量",
"deployments.agentChat": "代理交谈",
"deployments.ariaDeploymentType": "部署类型",
"deployments.ariaExistingEnvironments": "现有环境",
"deployments.ariaSendMessage": "发送消息",
"deployments.attachConnectionToFlow": "将连接附加到流程",
"deployments.attachFlows": "附加流程",
"deployments.attachedFlowsCount": "附带流程( {{count}} ",
"deployments.attachedFlowsLabel": "附带流程",
"deployments.availableConnections": "可用的连接",
"deployments.availableFlows": "可用流量",
"deployments.back": "后退",
"deployments.cancel": "取消",
"deployments.changeFlow": "变更流程",
"deployments.close": "关闭",
"deployments.columnAttached": "已连接",
"deployments.columnCreated": "创建时间",
"deployments.columnLastModified": "上次修改时间",
"deployments.columnName": "名称",
"deployments.columnProvider": "提供者",
"deployments.columnProviderKey": "提供商密钥",
"deployments.columnTest": "测试",
"deployments.columnType": "类型",
"deployments.columnUrl": "URL",
"deployments.confirm": "确认",
"deployments.connecting": "正在连接...",
"deployments.connectionNameExists": "已存在一个同名的联系人。",
"deployments.connectionNameLabel": "连接名称",
"deployments.createConnection": "创建连接",
"deployments.createFirstConnection": "建立您的第一个连接",
"deployments.createNewDeployment": "创建新部署",
"deployments.createNewDeploymentTitle": "创建新部署",
"deployments.current": "当前",
"deployments.deploy": "部署",
"deployments.deploying": "正在部署...",
"deployments.deploymentLabel": "部署",
"deployments.deploymentType": "部署类型",
"deployments.detachFlow": "分离流",
"deployments.detaching": "分离",
"deployments.editToolName": "编辑工具名称",
"deployments.environmentVariables": "环境变量",
"deployments.existingConnections": "现有连接",
"deployments.failedToLoadFlows": "无法加载附加的流程",
"deployments.globalVariables": "全局变量",
"deployments.labelCreated": "创建时间",
"deployments.labelDesc": "降序",
"deployments.labelModel": "模型",
"deployments.labelModified": "已修改",
"deployments.labelName": "名称",
"deployments.labelProvider": "提供者",
"deployments.labelType": "类型",
"deployments.loadingAttachedFlows": "正在加载附件流程...",
"deployments.loadingDeploymentData": "正在加载部署数据...",
"deployments.new": "新",
"deployments.newConnections": "新连接",
"deployments.next": "下一步",
"deployments.noConnectionsDescription": "创建连接,将凭据关联到此流程。",
"deployments.noConnectionsMatch": "没有符合条件的连接: \"{{query}}\"",
"deployments.noConnectionsYet": "尚未建立连接",
"deployments.noDeployments": "无部署",
"deployments.noEnvironments": "无环境",
"deployments.noFlowsAttached": "未附加任何流程",
"deployments.placeholderAgentPurpose": "描述该代理的用途……",
"deployments.placeholderApiKey": "请输入您的 API 密钥",
"deployments.placeholderApiUrl": "https://api.example.com",
"deployments.placeholderConnectionName": "例如SALES_BOT_PROD",
"deployments.placeholderEnvironmentName": "例如:生产",
"deployments.placeholderKey": "键",
"deployments.placeholderMessage": "消息",
"deployments.placeholderSalesBot": "例如:销售机器人",
"deployments.placeholderSearchConnections": "搜索连接...",
"deployments.placeholderValue": "值",
"deployments.provider": "提供者",
"deployments.removing": "移除",
"deployments.review": "复审",
"deployments.reviewAndConfirm": "查看并确认",
"deployments.reviewDetails": "创建前请检查您的部署详情。",
"deployments.reviewUpdate": "评论更新",
"deployments.selectDeployment": "选择部署",
"deployments.selectOrCreateConnection": "选择或创建新连接",
"deployments.selectProvider": "选择提供者",
"deployments.skip": "跳过",
"deployments.stepOf": "步骤 {{current}} ,来自 {{total}}",
"deployments.test": "测试",
"deployments.toolsWillBeDetached": "这些工具将从代理中分离出来。 它们将继续在您的服务提供商租户中可用。",
"deployments.undoDetach": "撤销分离",
"deployments.unknownFlow": "未知流量",
"deployments.untitled": "无标题",
"deployments.update": "更新",
"deployments.updateDeployment": "更新部署",
"deployments.updating": "正在更新...",
"deployments.variablesAutoDetected_one": "{{count}} 该变量已根据所选流程版本自动检测。",
"deployments.variablesAutoDetected_other": "{{count}} 从所选流程版本中自动检测到的变量。",
"dialog.chat": "与您的 AI 互动。 监控输入、输出和存储器。",
"dialog.code": "使用此代码导出您的流程以进行集成。",
"dialog.codeDict": "自定义您的字典,根据需要添加或编辑键值对。 支持添加新的对象 {} 或数组 []。",
@ -147,6 +264,7 @@
"emptyPage.emptyProject": "空项目",
"emptyPage.newFlow": "新流程",
"emptyPage.startBuilding": "开始构建",
"errors.addMcpServer": "添加 MCP 服务器时发生错误",
"errors.addUser": "添加新用户时发生错误",
"errors.apiKey": "API 密钥错误",
"errors.changePassword": "更改密码时发生错误",
@ -156,8 +274,15 @@
"errors.deleteKeys": "删除键时出错",
"errors.deleteSession": "删除会话时发生错误。",
"errors.deleteUser": "删除用户时发生错误",
"errors.deletingMessages": "删除消息时发生错误。",
"errors.editUser": "编辑用户时出错",
"errors.failedToExportFlow": "导出流程失败",
"errors.failedToLoadDeployment": "无法加载部署详情",
"errors.failedToRestoreVersion": "无法恢复版本",
"errors.failedToSaveFlow": "无法保存流程",
"errors.fileTooLarge": "文件太大。 请选择大小小于 {{maxSizeMB}} 的文件。",
"errors.flowNotFound": "未找到流程",
"errors.flowsVariableUndefined": "变量 Flows 未定义",
"errors.function": "您的函数中存在错误",
"errors.generic": "出现错误,请重试",
"errors.getComponents": "获取组件时出错。",
@ -169,14 +294,22 @@
"errors.missedFields": "糟糕! 看来你漏掉了什么",
"errors.missingInfo": "糟糕! 看来您遗漏了一些必填信息:",
"errors.noApiKey": "您没有 API 密钥。 请添加一个以使用 Langflow 商店。",
"errors.noDataToExport": "没有可导出的数据",
"errors.noModelsToRefresh": "没有需要刷新的模型组件",
"errors.parameterNotFound": "模板中未找到该参数",
"errors.passwordMismatch": "密码不匹配",
"errors.profilePictures": "无法获取个人头像",
"errors.prompt": "此提示存在问题,请检查一下",
"errors.refreshingModels": "刷新模型组件时发生错误",
"errors.renamingSession": "重命名会话时发生错误。",
"errors.saveApiKey": "保存 API 密钥时发生错误,请重试。",
"errors.saveChanges": "保存更改时发生错误",
"errors.sendMessage": "发送消息时发生错误",
"errors.signin": "登录失败",
"errors.signup": "注册失败",
"errors.templateNotFound": "在组件中未找到该模板",
"errors.tooManyFiles": "检测到文件过多( {{count}} )。 这可能包括大型或隐藏的目录。 请选择一个较小的文件夹,或排除如 node_modules 之类的文件夹。",
"errors.updatingMessages": "更新消息时发生错误。",
"errors.upload": "上传文件时出错",
"errors.uploadFile": "上传文件时发生错误",
"errors.uploadJsonOnly": "请上传一个 JSON 文件",
@ -191,6 +324,7 @@
"fileManager.errorUploadingFileDetail": "上传文件时发生错误",
"fileManager.fileUploadedSuccessfully": "文件已成功上传",
"fileManager.filesUploadedSuccessfully": "文件已上传成功",
"fileManager.searchFiles": "搜索文件...",
"fileManager.selectAtLeastOneFile": "请至少选择一个文件",
"fileManager.selectFile": "选择文件",
"fileManager.selectFiles": "选择文件",
@ -214,11 +348,15 @@
"files.uploadFile": "上载文件",
"files.uploadFiles": "上传文件",
"files.uploadedSuccessfully": "文件已成功上传",
"flow.addDescription": "添加描述...",
"flow.brokenEdgesWarning": "某些连接已被移除,因为它们无效:",
"flow.buildStatus": "构建以验证状态。",
"flow.buildSuccess": "已成功构建 ✨",
"flow.characterLimitReached": "已达到字符限制",
"flow.defaultName": "新流程",
"flow.deletedSuccessfully": "已成功删除所选项目",
"flow.descriptionLabel": "描述",
"flow.descriptionPlaceholder": "流程描述",
"flow.duplicatedSuccess": "{{type}} 已成功复制",
"flow.enableAutoSaving": "启用自动保存",
"flow.errorDeleting": "删除项目时发生错误",
@ -226,14 +364,27 @@
"flow.exitAnyway": "不管怎样,退出",
"flow.lastSaved": "最后保存时间: {{time}}",
"flow.lastSavedNever": "从不",
"flow.lockFlow": "锁定流量",
"flow.lockFlowDescription": "锁定流程以防止编辑或意外更改。",
"flow.menu.delete": "删除",
"flow.menu.duplicate": "复制",
"flow.menu.editDetails": "编辑详细信息",
"flow.menu.export": "导出",
"flow.minimumCharacters": "至少需要输入 {{count}} 个字符",
"flow.missingFields": "请填写所有必填项。",
"flow.moreOptions": "更多选项",
"flow.nameAlreadyExists": "流程名称已存在",
"flow.nameLabel": "名称",
"flow.namePlaceholder": "流程名称",
"flow.noCompatibleComponents": "未找到兼容的组件。",
"flow.noDescription": "无描述",
"flow.pleaseEnterDescription": "请输入描述",
"flow.pleaseEnterName": "请输入姓名",
"flow.replaceComponent": "替换",
"flow.restoreVersion": "恢复此版本的流程",
"flow.runTimestampPrefix": "最后一次运行: ",
"flow.saveAndExit": "保存并退出",
"flow.saveVersion": "保存流程的版本",
"flow.savedHover": "最后保存时间: ",
"flow.savedSuccessfully": "流程已成功保存!",
"flow.savingChanges": "正在保存您的更改...",
@ -299,15 +450,24 @@
"home.dragFlowType": "请在此处上传您的 {{flowType}}",
"home.dragFlowsOrComponents": "请将您的流程或组件拖放到此处",
"home.flowTypeNotSupported": "{{flowType}} 不支持",
"input.addActions": "添加操作",
"input.addMcpServer": "添加 MCP 服务器",
"input.addNewVariable": "添加新变量",
"input.editCodeTitle": "编辑代码",
"input.editTextPlaceholder": "请在此处输入消息。",
"input.editTextTitle": "编辑文本",
"input.emptyOutput": "消息为空。",
"input.errorUpdatingComponent": "更新组件时发生了一个意外错误。 请重试。",
"input.floatNumberFull": "请输入一个浮点数",
"input.floatNumberShort": "浮点数",
"input.noInputMessage": "未提供输入消息。",
"input.placeholder": "输入内容...",
"input.searchOptions": "搜索选项...",
"input.titleErrorUpdatingComponent": "更新组件时发生错误",
"input.toolsetPlaceholder": "作为一种工具",
"input.typeKey": "请输入键...",
"input.typeValue": "请输入一个值...",
"jsonEditor.pathPlaceholder": "输入路径(例如 users[0].name或 JSONQuery例如.users | filter(.age > 25)",
"knowledge.addKnowledge": "添加知识",
"knowledge.addSources": "添加源",
"knowledge.addSourcesDescription": "上传文件并配置分块设置",
@ -451,6 +611,9 @@
"misc.alertSaveWithApi": "⚠️ 注意:导出此流程可能会泄露敏感凭据。",
"misc.apiAccess": "API 访问权",
"misc.chatTitle": "Langflow Chat",
"misc.copyFailed": "复制失败",
"misc.copyJson": "将 JSON 复制到剪贴板",
"misc.editorNotAvailable": "编辑功能不可用",
"misc.embedIntoSite": "嵌入网站",
"misc.export": "导出",
"misc.fetchError": "无法建立连接。",
@ -468,6 +631,7 @@
"misc.textInputModalTitle": "编辑文本内容",
"misc.timeoutError": "请稍等片刻,服务器正在处理您的请求。",
"misc.timeoutErrorDesc": "服务器正在处理请求。",
"misc.unableToCopy": "无法复制到剪贴板。 请手动复制。",
"modal.api.createApiKey": "创建 API 密钥",
"modal.api.description": "访问 API 需要 API 密钥。 你可以",
"modal.api.descriptionSuffix": "在设置中。",
@ -553,6 +717,7 @@
"nav.myCollection": "我的收藏",
"nav.myCollectionDesc": "管理您的项目。 下载和上传整个收藏集。",
"nav.notifications": "没有新通知",
"node.dismissWarning": "关闭警告栏",
"node.errorNoTemplate": "组件 {{name}} 发生错误",
"node.errorNoTemplateContact": "请联系该组件的开发者以解决此问题。",
"node.errorNoTemplateDetail": "组件 {{name}} 没有模板。",
@ -595,6 +760,18 @@
"page.githubDescription": "关注开发动态,关注该仓库,共同塑造未来。",
"page.welcomeDescription": "您最喜爱的特工运输新方式",
"page.welcomeTitle": "欢迎来到Langflow",
"paginator.placeholder": "1",
"playgroundComponent.chatSessions": "聊天记录",
"playgroundComponent.clearChat": "清除交谈",
"playgroundComponent.clearSession": "清除会话",
"playgroundComponent.closeAndGoBack": "关闭并返回流程",
"playgroundComponent.deleteFile": "删除文件",
"playgroundComponent.deleteSession": "删除会话",
"playgroundComponent.enterFullscreen": "进入全屏模式",
"playgroundComponent.focusChatInput": "聚焦聊天输入",
"playgroundComponent.messageLogs": "消息日志",
"playgroundComponent.moreOptions": "更多选项",
"playgroundComponent.rename": "重命名",
"project.deletedSuccessfully": "项目已成功删除。",
"project.errorDeleting": "删除项目时发生错误。",
"project.newName": "新建项目",
@ -681,6 +858,7 @@
"shortcuts.name.update": "更新",
"shortcuts.restoreButton": "复原",
"shortcuts.title": "快捷方式",
"sidebar.allSet": "一切就绪",
"sidebar.betaLabel": "Beta 测试版",
"sidebar.bundles": "捆绑包",
"sidebar.category.agents": "代理",
@ -714,17 +892,24 @@
"sidebar.clearSearch": "清除搜索记录",
"sidebar.componentSettings": "组件设置",
"sidebar.components": "组件",
"sidebar.createFlow": "创建流",
"sidebar.delete": "删除",
"sidebar.discoverMore": "探索更多组件",
"sidebar.download": "下载",
"sidebar.downloadError": "下载项目时发生错误。",
"sidebar.emptyMessage": "开始创建项目或流程",
"sidebar.getStarted": "开始",
"sidebar.joinCommunity": "加入社区",
"sidebar.knowledge": "知识",
"sidebar.legacyLabel": "原有",
"sidebar.mcp.add": "添加 MCP 服务器",
"sidebar.mcp.empty": "未添加任何 MCP 服务器",
"sidebar.mcp.manage": "管理服务器",
"sidebar.mcp.title": "MCP 服务器",
"sidebar.mcpExposeFlows": "将流程作为工具在 Cursor 或 Claude 等客户端中呈现。",
"sidebar.mcpGoToServer": "前往服务器",
"sidebar.mcpNewBadge": "新",
"sidebar.mcpProjectsTitle": "作为 MCP 服务器的项目",
"sidebar.myFiles": "我的文件",
"sidebar.nav.addStickyNotes": "添加便签",
"sidebar.nav.bundles": "捆绑包",
@ -743,6 +928,7 @@
"sidebar.removeFilter": "移除过滤器",
"sidebar.searchPlaceholder": "搜索",
"sidebar.show": "显示",
"sidebar.starRepo": "关注此仓库以获取更新",
"sidebar.tryDifferentQuery": "或者筛选一下,试试其他查询。",
"sidebar.uploadSuccess": "已成功上载",
"slider.balanced": "均衡",
@ -778,25 +964,49 @@
"store.tabFlows": "流",
"store.title": "Langflow 商店",
"storeApiKey.description": "管理对 Langflow 商店的访问权限。",
"storeApiKey.insertPlaceholder": "请输入您的 API 密钥",
"storeApiKey.saveError": "API 密钥保存错误",
"storeApiKey.saveSuccess": "API密钥已成功保存",
"storeApiKey.title": "Langflow 商店",
"success.apiKeySaved": "成功! 您的 API 密钥已保存。",
"success.changesSaved": "更改已成功保存!",
"success.chatCleared": "聊天记录已成功清除。",
"success.codeReady": "代码已准备就绪",
"success.componentIdCopied": "组件 ID 已复制到剪贴板",
"success.componentOverridden": "{{id}} 已成功覆盖!",
"success.componentSaved": "{{id}} 已成功保存",
"success.customComponentSaved": "新组件已成功保存!",
"success.endpointUrlCopied": "已复制端点 URL",
"success.fileUploaded": "文件已成功上传",
"success.flowBuilt": "流程已成功建立",
"success.flowExported": "{{name}} 已成功导出",
"success.ingestionCancelled": "摄入已取消",
"success.jsonCopied": "JSON 已复制到剪贴板",
"success.keyDeleted": "成功! 密钥已删除!",
"success.keysDeleted": "成功! 密钥已删除!",
"success.knowledgeBaseDeleted": "知识库已删除",
"success.knowledgeBaseNodeCreated": "知识库 \"{{name}}\" 已成功创建!",
"success.messagesDeleted": "消息已成功删除。",
"success.messagesUpdated": "消息已成功更新。",
"success.outputCopied": "已复制到剪贴板",
"success.promptReady": "提示词已准备就绪",
"success.sessionDeleted": "会话已成功删除。",
"success.userAdded": "成功! 已添加新用户!",
"success.userDeleted": "成功! 用户已被删除!",
"success.userEdited": "成功! 用户编辑!",
"success.versionDeleted": "版本已删除",
"success.versionRestored": "已复原版本",
"success.versionSaved": "版本已保存",
"table.addRow": "添加新行",
"table.deleteSelected": "删除所选项目",
"table.duplicateSelected": "复制所选项目",
"table.noColumnDescription": "该表没有可用的列定义。",
"table.noColumnTitle": "没有列定义",
"table.noDataMessage": "糟糕! 目前似乎没有数据可显示。 请稍后再试。",
"table.noDataTitle": "无可用数据",
"table.resetColumns": "重置列",
"table.selectToDelete": "选择要删除的项目",
"table.selectToDuplicate": "选择要复制的项目",
"templatesModal.agents": "代理",
"templatesModal.allTemplates": "所有模板",
"templatesModal.assistants": "助手",
@ -837,5 +1047,21 @@
"toolsModal.parametersSubtitle": "管理此工具的输入",
"toolsModal.parametersTitle": "参数",
"toolsModal.searchPlaceholder": "搜索工具...",
"toolsModal.slugHint": "当此工具向代理暴露时,用作函数名称。"
"toolsModal.slugHint": "当此工具向代理暴露时,用作函数名称。",
"trace.allStatus": "所有状态",
"trace.dateRange": "日期范围",
"trace.download": "下载",
"trace.endDate": "结束日期",
"trace.input": "输入",
"trace.invalidDateRange": "日期范围无效",
"trace.output": "输出",
"trace.reload": "重新装入",
"trace.searchRuns": "正在搜索……",
"trace.spanTree": "轨迹跨度",
"trace.startDate": "开始日期",
"ui.resizeSidebar": "调整侧边栏大小(使用方向键或拖动来调整大小)",
"ui.toggleSidebar": "切换侧边栏",
"voice.selectLanguage": "选择语言",
"voice.selectMicrophone": "选择麦克风",
"voice.selectVoice": "选择"
}

View File

@ -96,7 +96,7 @@ const InputWrapper: React.FC<InputWrapperProps> = ({
onKeyDown={onKeyDown}
role="button"
tabIndex={0}
aria-label="Focus chat input"
aria-label={t("playgroundComponent.focusChatInput")}
>
<TextAreaWrapper
isBuilding={isBuilding}

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import { ALL_LANGUAGES } from "@/constants/constants";
import IconComponent from "../../../../../../../../../../components/common/genericIconComponent";
import ShadTooltip from "../../../../../../../../../../components/common/shadTooltipComponent";
@ -19,6 +20,7 @@ const LanguageSelect = ({
language,
handleSetLanguage,
}: LanguageSelectProps) => {
const { t } = useTranslation();
return (
<div className="grid w-full items-center gap-2">
<span className="flex w-full items-center text-sm">
@ -36,7 +38,7 @@ const LanguageSelect = ({
<Select value={language} onValueChange={handleSetLanguage}>
<SelectTrigger className="h-9 w-full">
<SelectValue placeholder="Select language" />
<SelectValue placeholder={t("voice.selectLanguage")} />
</SelectTrigger>
<SelectContent className="max-h-[200px]">
<SelectGroup>

View File

@ -1,4 +1,5 @@
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import IconComponent from "../../../../../../../../../../components/common/genericIconComponent";
import ShadTooltip from "../../../../../../../../../../components/common/shadTooltipComponent";
import {
@ -25,6 +26,7 @@ const MicrophoneSelect = ({
setMicrophones,
setSelectedMicrophone,
}: MicrophoneSelectProps) => {
const { t } = useTranslation();
useEffect(() => {
const getMicrophones = async () => {
try {
@ -88,7 +90,7 @@ const MicrophoneSelect = ({
<Select value={selectedMicrophone} onValueChange={handleSetMicrophone}>
<SelectTrigger className="h-9 w-full">
<SelectValue placeholder="Select microphone" />
<SelectValue placeholder={t("voice.selectMicrophone")} />
</SelectTrigger>
<SelectContent className="max-h-[200px]">
<SelectGroup>

View File

@ -1,4 +1,5 @@
import { useIsFetching } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import type { NewValueParams, SelectionChangedEvent } from "ag-grid-community";
import cloneDeep from "lodash/cloneDeep";
import { useEffect, useMemo, useState } from "react";
@ -22,6 +23,7 @@ export default function SessionView({
session?: string;
id?: string;
}) {
const { t } = useTranslation();
const messages = useMessagesStore((state) => state.messages);
const setMessages = useMessagesStore((state) => state.setMessages);
const setErrorData = useAlertStore((state) => state.setErrorData);
@ -77,12 +79,12 @@ export default function SessionView({
}
setSelectedRows([]);
setSuccessData({
title: "Messages deleted successfully.",
title: t("success.messagesDeleted"),
});
},
onError: () => {
setErrorData({
title: "Error deleting messages.",
title: t("errors.deletingMessages"),
});
},
});
@ -106,12 +108,12 @@ export default function SessionView({
updateMessage(data);
// Set success message
setSuccessData({
title: "Messages updated successfully.",
title: t("success.messagesUpdated"),
});
},
onError: () => {
setErrorData({
title: "Error updating messages.",
title: t("errors.updatingMessages"),
});
event.data[field] = event.oldValue;
event.api.refreshCells();

View File

@ -82,7 +82,7 @@ const ExportModal = forwardRef(
);
setSuccessData({
title: "Flow exported successfully",
title: t("success.flowExported", { name }),
});
setOpen(false);
track("Flow Exported", { flowId: currentFlow!.id });
@ -90,7 +90,7 @@ const ExportModal = forwardRef(
} catch (error: any) {
const detail = error?.response?.data?.detail;
setErrorData({
title: "Failed to export flow",
title: t("errors.failedToExportFlow"),
...(detail ? { list: [detail] } : {}),
});
}

View File

@ -173,7 +173,7 @@ export default function DragFilesComponent({
if (selected.length > 1000) {
throw new Error(
`Too many files detected (${selected.length}). This likely includes large/hidden directories. Please select a smaller folder or exclude folders like node_modules.`,
t("errors.tooManyFiles", { count: selected.length }),
);
}

View File

@ -36,6 +36,7 @@ export default function RecentFilesComponent({
types: string[];
isList: boolean;
}) {
const { t } = useTranslation();
const setErrorData = useAlertStore((state) => state.setErrorData);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
@ -68,7 +69,6 @@ export default function RecentFilesComponent({
}),
[filesWithDisabled],
);
const { t } = useTranslation();
const [searchQuery, setSearchQuery] = useState("");
const [lastClickedIndex, setLastClickedIndex] = useState<number | null>(null);
const [isShiftPressed, setIsShiftPressed] = useState(false);
@ -241,7 +241,7 @@ export default function RecentFilesComponent({
<div className="flex-1">
<Input
icon="Search"
placeholder="Search files..."
placeholder={t("fileManager.searchFiles")}
inputClassName="h-8"
data-testid="search-files-input"
value={searchQuery}

View File

@ -1,10 +1,12 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import LangflowLogo from "@/assets/LangflowLogo.svg?react";
import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input";
import BaseModal from "../../modals/baseModal";
export default function DeleteAccountPage() {
const { t } = useTranslation();
const [showConfirmation, setShowConfirmation] = useState(false);
const handleDeleteAccount = () => {
@ -25,7 +27,7 @@ export default function DeleteAccountPage() {
<span className="mb-4 text-center text-2xl font-semibold text-primary">
Delete your account
</span>
<Input className="bg-background" placeholder="Confirm password" />
<Input className="bg-background" placeholder={t("auth.confirmPassword")} />
<BaseModal
open={showConfirmation}

View File

@ -1,5 +1,6 @@
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import Markdown from "react-markdown";
import { useTranslation } from "react-i18next";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import useFlowStore from "@/stores/flowStore";
@ -18,6 +19,7 @@ export default function EditableHeaderContent({
editMode,
setEditMode,
}: EditableHeaderContentProps) {
const { t } = useTranslation();
const [localName, setLocalName] = useState<string>(
data.node?.display_name ?? data.type,
);
@ -206,7 +208,7 @@ export default function EditableHeaderContent({
onChange={handleDescriptionChange}
onKeyDown={handleDescriptionKeyDown}
className="nowheel w-full mt-1 text-muted-foreground !text-xs focus:border-primary focus:ring-0 px-2 py-0.5 min-h-[60px]"
placeholder="Add a description..."
placeholder={t("flow.addDescription")}
data-testid="inspection-panel-description"
/>
) : (

View File

@ -1,4 +1,5 @@
import { useCallback, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useHotkeys } from "react-hotkeys-hook";
import useHandleOnNewValue from "@/CustomNodes/hooks/use-handle-new-value";
import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class";
@ -27,6 +28,7 @@ export default function InspectionPanelHeader({
isEditingFields,
setIsEditingFields,
}: InspectionPanelHeaderProps) {
const { t } = useTranslation();
const [openCodeModal, setOpenCodeModal] = useState(false);
const [editMode, setEditMode] = useState(false);
const [isHoveringContent, setIsHoveringContent] = useState(false);
@ -47,7 +49,7 @@ export default function InspectionPanelHeader({
const handleCopyId = useCallback(() => {
navigator.clipboard.writeText(data.id);
setSuccessData({ title: "Component ID copied to clipboard" });
setSuccessData({ title: t("success.componentIdCopied") });
}, [data.id, setSuccessData]);
const handleOpenCode = useCallback(() => {

View File

@ -1,5 +1,6 @@
import { useState } from "react";
import { createPortal } from "react-dom";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
@ -18,6 +19,7 @@ export default function RestoreVersionButton({
versionId,
versionTag,
}: RestoreVersionButtonProps) {
const { t } = useTranslation();
const { restore, isRestoring } = useRestoreVersion(flowId);
const { setActiveSection } = useSidebar();
@ -41,7 +43,7 @@ export default function RestoreVersionButton({
<>
<CanvasBanner
icon="RotateCcw"
title="Restore this version of your flow"
title={t("flow.restoreVersion")}
description={
<>
Replace the current draft with{" "}

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { useSidebar } from "@/components/ui/sidebar";
import { usePostCreateSnapshot } from "@/controllers/API/queries/flow-version";
@ -12,6 +13,7 @@ interface SaveSnapshotButtonProps {
export default function SaveSnapshotButton({
flowId,
}: SaveSnapshotButtonProps) {
const { t } = useTranslation();
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const { setActiveSection, open, toggleSidebar } = useSidebar();
@ -34,7 +36,7 @@ export default function SaveSnapshotButton({
{ flowId, description: null },
{
onSuccess: () => {
setSuccessData({ title: "Version saved" });
setSuccessData({ title: t("success.versionSaved") });
setIsSavingDisplay(false);
setSavedSuccess(true);
},
@ -53,7 +55,7 @@ export default function SaveSnapshotButton({
return (
<CanvasBanner
icon="BookMarked"
title="Save a version of your flow"
title={t("flow.saveVersion")}
description="Capture the current state as a restore point"
actionSlot={
<div className="flex items-center gap-2">

View File

@ -1,4 +1,5 @@
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import IconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
@ -22,6 +23,7 @@ export function DateRangePopover({
onStartDateChange,
onEndDateChange,
}: DateRangePopoverProps) {
const { t } = useTranslation();
const rangeLabel = useMemo(() => {
if (!startDate && !endDate) return "";
if (startDate && !endDate) return `From ${formatDateLabel(startDate)}`;
@ -51,7 +53,7 @@ export function DateRangePopover({
variant="ghost"
size="sm"
className="h-8 gap-2 px-2 text-muted-foreground"
aria-label="Date range"
aria-label={t("trace.dateRange")}
>
<IconComponent name="Calendar" className="h-4 w-4" />
<span className="inline-flex items-center gap-1 text-xs text-foreground">
@ -64,11 +66,11 @@ export function DateRangePopover({
<IconComponent
name="AlertTriangle"
className="h-3 w-3 text-status-red"
aria-label="Invalid date range"
aria-label={t("trace.invalidDateRange")}
/>
</span>
</TooltipTrigger>
<TooltipContent>Invalid date range</TooltipContent>
<TooltipContent>{t("trace.invalidDateRange")}</TooltipContent>
</Tooltip>
</TooltipProvider>
) : null}
@ -78,23 +80,23 @@ export function DateRangePopover({
<PopoverContent align="end" className="w-[260px] p-3">
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-1">
<span className="text-xs text-muted-foreground">Start date</span>
<span className="text-xs text-muted-foreground">{t("trace.startDate")}</span>
<Input
type="date"
value={startDate}
onChange={(e) => handleStartChange(e.target.value)}
className="h-8 text-sm [color-scheme:light] dark:[color-scheme:white] dark:[&::-webkit-calendar-picker-indicator]:invert dark:[&::-webkit-calendar-picker-indicator]:opacity-80"
aria-label="Start date"
aria-label={t("trace.startDate")}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-xs text-muted-foreground">End date</span>
<span className="text-xs text-muted-foreground">{t("trace.endDate")}</span>
<Input
type="date"
value={endDate}
onChange={(e) => handleEndChange(e.target.value)}
className="h-8 text-sm [color-scheme:light] dark:[color-scheme:white] dark:[&::-webkit-calendar-picker-indicator]:invert dark:[&::-webkit-calendar-picker-indicator]:opacity-80"
aria-label="End date"
aria-label={t("trace.endDate")}
/>
</div>
{hasInvalidRange && (

View File

@ -261,14 +261,14 @@ export function FlowInsightsContent({
<Input
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
placeholder="Search runs..."
placeholder={t("trace.searchRuns")}
className="h-8 pl-8 text-sm"
/>
</div>
<Select value={statusFilter} onValueChange={setStatusFilter}>
<SelectTrigger className="h-8 w-[130px]">
<SelectValue placeholder="All Status" />
<SelectValue placeholder={t("trace.allStatus")} />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All Status</SelectItem>
@ -288,7 +288,7 @@ export function FlowInsightsContent({
variant="ghost"
size="icon"
onClick={() => refetch()}
aria-label="Reload"
aria-label={t("trace.reload")}
>
<IconComponent name="RefreshCcw" className="h-4 w-4" />
</Button>
@ -298,7 +298,7 @@ export function FlowInsightsContent({
onClick={() =>
downloadJson(`runs-${resolvedFlowId ?? "unknown"}.json`, rows)
}
aria-label="Download"
aria-label={t("trace.download")}
>
<IconComponent name="Download" className="h-4 w-4" />
</Button>

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import IconComponent from "@/components/common/genericIconComponent";
import SimplifiedCodeTabComponent from "@/components/core/codeTabsComponent";
import { Badge } from "@/components/ui/badge";
@ -17,6 +18,7 @@ import type { SpanDetailProps } from "./types";
* Includes inputs, outputs, model info, tokens, and errors
*/
export function SpanDetail({ span }: SpanDetailProps) {
const { t } = useTranslation();
if (!span) {
return (
<div
@ -137,7 +139,7 @@ export function SpanDetail({ span }: SpanDetailProps) {
{/* Inputs section */}
{hasInputs && (
<div className="mb-4">
<SectionHeader icon="ArrowRight" title="Input" />
<SectionHeader icon="ArrowRight" title={t("trace.input")} />
<div className="mt-2">
<SimplifiedCodeTabComponent
language="json"
@ -150,7 +152,7 @@ export function SpanDetail({ span }: SpanDetailProps) {
{/* Outputs section */}
{hasOutputs && (
<div className="mb-4">
<SectionHeader icon="ArrowLeft" title="Output" />
<SectionHeader icon="ArrowLeft" title={t("trace.output")} />
<div className="mt-2">
<SimplifiedCodeTabComponent
language="json"

View File

@ -1,4 +1,5 @@
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { SpanNode } from "./SpanNode";
import type { Span } from "./types";
@ -18,6 +19,7 @@ export function SpanTree({
onSelectSpan,
}: SpanTreeProps) {
// Track which spans are expanded (default: root level expanded)
const { t } = useTranslation();
const [expandedIds, setExpandedIds] = useState<Set<string>>(() => {
const initial = new Set<string>();
// Expand root level spans by default
@ -67,7 +69,7 @@ export function SpanTree({
<div
className="flex flex-col"
role="tree"
aria-label="Trace spans"
aria-label={t("trace.spanTree")}
data-testid="span-tree"
>
{spans.map((span) => renderSpan(span, 0))}

View File

@ -1,4 +1,5 @@
import type { ColDef } from "ag-grid-community";
import i18n from "@/i18n";
import IconComponent from "@/components/common/genericIconComponent";
import { formatSmartTimestamp } from "@/utils/dateTime";
import { formatTotalLatency, getStatusIconProps } from "../traceViewHelpers";
@ -47,7 +48,7 @@ export function createFlowTracesColumns({
valueGetter: (params) => formatSmartTimestamp(params.data?.startTime),
},
{
headerName: "Input",
headerName: i18n.t("trace.input"),
field: "input",
flex: 1,
minWidth: 150,
@ -57,7 +58,7 @@ export function createFlowTracesColumns({
valueGetter: (params) => formatObjectValue(params.data?.input),
},
{
headerName: "Output",
headerName: i18n.t("trace.output"),
field: "output",
flex: 1,
minWidth: 150,

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import {
DropdownMenu,
@ -27,6 +28,7 @@ export default function VersionListItem({
onExport,
onDeleteClick,
}: VersionListItemProps) {
const { t } = useTranslation();
return (
<SidebarMenuItem
className={cn(
@ -54,7 +56,7 @@ export default function VersionListItem({
<button
onClick={(e) => e.stopPropagation()}
className="group/trigger flex h-6 w-6 items-center justify-center rounded"
title="More options"
title={t("flow.moreOptions")}
>
{isSelected ? (
<>

View File

@ -7,6 +7,7 @@ import {
useRef,
useState,
} from "react";
import { useTranslation } from "react-i18next";
import { api } from "@/controllers/API/api";
import { getURL } from "@/controllers/API/helpers/constants";
import {
@ -26,6 +27,7 @@ import {
import { CURRENT_DRAFT_ID } from "./constants";
export function useFlowVersionSidebar(flowId: string) {
const { t } = useTranslation();
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const setPreview = useVersionPreviewStore((s) => s.setPreview);
@ -265,7 +267,7 @@ export function useFlowVersionSidebar(flowId: string) {
const data = response.data?.data;
const tag = response.data?.version_tag ?? "version";
if (!data) {
setErrorData({ title: "No data available to export" });
setErrorData({ title: t("errors.noDataToExport") });
return;
}
const flowName = `${currentFlow?.name || "flow"}_${tag}`;
@ -302,7 +304,7 @@ export function useFlowVersionSidebar(flowId: string) {
{ flowId, versionId: entry.id },
{
onSuccess: () => {
setSuccessData({ title: "Version deleted" });
setSuccessData({ title: t("success.versionDeleted") });
// Select the next entry (triggers fetch + preview via existing
// effects) instead of setting empty arrays into the store which
// would cause a blank canvas flash.

View File

@ -1,4 +1,5 @@
import { memo } from "react";
import { useTranslation } from "react-i18next";
import CodeAreaModal from "@/modals/codeAreaModal";
import ConfirmationModal from "@/modals/confirmationModal";
import EditNodeModal from "@/modals/editNodeModal";
@ -51,13 +52,14 @@ const ToolbarModals = memo(
addFlow,
name = "code",
}: ToolbarModalsProps) => {
const { t } = useTranslation();
// Handlers for confirmation modal
const handleConfirm = () => {
addFlow({
flow: flowComponent,
override: true,
});
setSuccessData({ title: `${data.id} successfully overridden!` });
setSuccessData({ title: t("success.componentOverridden", { id: data.id }) });
setShowOverrideModal(false);
};
@ -70,7 +72,7 @@ const ToolbarModals = memo(
flow: flowComponent,
override: true,
});
setSuccessData({ title: "New component successfully saved!" });
setSuccessData({ title: t("success.customComponentSaved") });
setShowOverrideModal(false);
};

View File

@ -265,7 +265,7 @@ const NodeToolbarComponent = memo(
flow: flowComponent,
override: false,
});
setSuccessData({ title: `${data.id} saved successfully` });
setSuccessData({ title: t("success.componentSaved", { id: data.id }) });
}, [isSaved, data.id, flowComponent, addFlow]);
const openDocs = useCallback(() => {

View File

@ -93,7 +93,7 @@ const ListComponent = ({
const handleExport = () => {
if (flowData.is_component) {
downloadFlow(flowData, flowData.name, flowData.description);
setSuccessData({ title: `${flowData.name} exported successfully` });
setSuccessData({ title: t("success.flowExported", { name: flowData.name }) });
} else {
setOpenExportModal(true);
}

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import type { DeploymentFlowVersionItem } from "@/controllers/API/queries/deployments/use-get-deployment-attachments";
import FlowVersionItem from "./flow-version-item";
@ -10,13 +11,14 @@ export default function DeploymentFlowList({
flowVersions,
getConnectionNames,
}: DeploymentFlowListProps) {
const { t } = useTranslation();
return (
<div className="flex flex-col gap-3">
<span className="text-sm font-medium text-foreground">
Attached Flows ({flowVersions.length})
{t("deployments.attachedFlowsCount", { count: flowVersions.length })}
</span>
{flowVersions.length === 0 ? (
<span className="text-sm text-muted-foreground">No flows attached</span>
<span className="text-sm text-muted-foreground">{t("deployments.noFlowsAttached")}</span>
) : (
<div className="flex flex-col gap-2">
{flowVersions.map((fv) => (

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import type { Deployment } from "../../types";
@ -20,9 +21,10 @@ export default function DeploymentInfoGrid({
providerName,
llm,
}: DeploymentInfoGridProps) {
const { t } = useTranslation();
return (
<div className="grid grid-cols-[auto_1fr_auto_1fr] items-baseline gap-x-3 gap-y-2">
<span className="text-xs text-muted-foreground">Type</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelType")}</span>
<div className="flex items-center gap-1.5">
<ForwardedIconComponent
name={deployment?.type === "agent" ? "Bot" : "Server"}
@ -32,21 +34,21 @@ export default function DeploymentInfoGrid({
{deployment?.type}
</span>
</div>
<span className="text-xs text-muted-foreground">Created</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelCreated")}</span>
<span className="text-sm text-foreground">
{deployment?.created_at ? formatDate(deployment.created_at) : "—"}
</span>
<span className="text-xs text-muted-foreground">Name</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelName")}</span>
<span className="text-sm text-foreground">{deployment?.name || "—"}</span>
<span className="text-xs text-muted-foreground">Modified</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelModified")}</span>
<span className="text-sm text-foreground">
{deployment?.updated_at ? formatDate(deployment.updated_at) : "—"}
</span>
{deployment?.description && (
<>
<span className="text-xs text-muted-foreground">Desc</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelDesc")}</span>
<span className="col-span-3 text-sm text-foreground">
{deployment.description}
</span>
@ -55,14 +57,14 @@ export default function DeploymentInfoGrid({
{llm && (
<>
<span className="text-xs text-muted-foreground">Model</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelModel")}</span>
<span className="col-span-3 break-words text-sm text-foreground">
{llm}
</span>
</>
)}
<span className="text-xs text-muted-foreground">Provider</span>
<span className="text-xs text-muted-foreground">{t("deployments.labelProvider")}</span>
<span className="col-span-3 text-sm text-foreground">
{providerName || "—"}
</span>

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Badge } from "@/components/ui/badge";
import Loading from "@/components/ui/loading";
@ -13,6 +14,7 @@ export default function DeploymentExpandedRow({
deploymentId,
colSpan,
}: DeploymentExpandedRowProps) {
const { t } = useTranslation();
const { data, isLoading, isError } = useGetDeploymentAttachments({
deploymentId,
});
@ -27,21 +29,21 @@ export default function DeploymentExpandedRow({
<div className="flex items-center gap-2 py-2">
<Loading size={14} className="text-muted-foreground" />
<span className="text-sm text-muted-foreground">
Loading attached flows...
{t("deployments.loadingAttachedFlows")}
</span>
</div>
) : isError ? (
<span className="text-sm text-destructive">
Failed to load attached flows
{t("deployments.failedToLoadFlows")}
</span>
) : flows.length === 0 ? (
<span className="text-sm text-muted-foreground">
No flows attached
{t("deployments.noFlowsAttached")}
</span>
) : (
<div className="flex flex-col gap-1.5">
<span className="text-xs font-medium text-muted-foreground">
Attached Flows
{t("deployments.attachedFlowsLabel")}
</span>
<div className="flex flex-wrap gap-2">
{flows.map((flow) => (
@ -55,7 +57,7 @@ export default function DeploymentExpandedRow({
name="Workflow"
className="h-3 w-3 text-muted-foreground"
/>
<span>{flow.flow_name ?? "Untitled"}</span>
<span>{flow.flow_name ?? t("deployments.untitled")}</span>
<span className="text-muted-foreground">
v{flow.version_number}
</span>

View File

@ -1,4 +1,5 @@
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import {
@ -50,6 +51,7 @@ export default function DeploymentStepperModal({
initialInstance,
editingDeployment,
}: DeploymentStepperModalProps) {
const { t } = useTranslation();
const [isDeploying, setIsDeploying] = useState(false);
const isEditMode = !!editingDeployment;
@ -130,7 +132,7 @@ export default function DeploymentStepperModal({
{isLoadingEditData ? (
<div className="flex flex-1 items-center justify-center">
<span className="text-sm text-muted-foreground">
Loading deployment data...
{t("deployments.loadingDeploymentData")}
</span>
</div>
) : (
@ -179,6 +181,7 @@ function DeploymentStepperModalContent({
) => void;
onDeployingChange: (isDeploying: boolean) => void;
}) {
const { t } = useTranslation();
const [deploymentPhase, setDeploymentPhase] =
useState<DeploymentPhase>("idle");
const [createdDeployment, setCreatedDeployment] = useState<{
@ -285,17 +288,17 @@ function DeploymentStepperModalContent({
setOpen(false);
};
const actionLabel = isEditMode ? "Update" : "Deploy";
const actionLabel = isEditMode ? t("deployments.update") : t("deployments.deploy");
const actionIcon = isEditMode ? "Save" : "Rocket";
const progressLabel = isEditMode ? "Updating..." : "Deploying...";
const progressLabel = isEditMode ? t("deployments.updating") : t("deployments.deploying");
return (
<>
<DialogTitle className="sr-only">
{isEditMode ? "Update Deployment" : "Create New Deployment"}
{isEditMode ? t("deployments.updateDeployment") : t("deployments.createNewDeploymentTitle")}
</DialogTitle>
<DialogDescription className="sr-only">
Step {currentStep} of {totalSteps}
{t("deployments.stepOf", { current: currentStep, total: totalSteps })}
</DialogDescription>
{/* Title + Stepper */}
@ -304,7 +307,7 @@ function DeploymentStepperModalContent({
className="text-center text-2xl font-semibold"
data-testid="stepper-modal-title"
>
{isEditMode ? "Update Deployment" : "Create New Deployment"}
{isEditMode ? t("deployments.updateDeployment") : t("deployments.createNewDeploymentTitle")}
</h2>
<DeploymentStepper />
</div>
@ -330,7 +333,7 @@ function DeploymentStepperModalContent({
{/* Footer */}
<div className="flex items-center justify-between border-t border-border px-6 py-4">
<Button variant="ghost" onClick={() => setOpen(false)}>
{isDeployed ? "Close" : "Cancel"}
{isDeployed ? t("deployments.close") : t("deployments.cancel")}
</Button>
<div className="flex items-center gap-3">
{!isDeployed && (
@ -339,7 +342,7 @@ function DeploymentStepperModalContent({
onClick={handleBack}
disabled={currentStep === minStep || isDeploying}
>
Back
{t("deployments.back")}
</Button>
)}
{!isInDeployPhase && (
@ -357,9 +360,9 @@ function DeploymentStepperModalContent({
{actionLabel}
</>
) : isCreatingAccount ? (
"Connecting..."
t("deployments.connecting")
) : (
"Next"
t("deployments.next")
)}
</Button>
)}
@ -377,7 +380,7 @@ function DeploymentStepperModalContent({
data-testid="deployment-stepper-test"
onClick={handleTest}
>
Test
{t("deployments.test")}
</Button>
)}
</div>

View File

@ -1,23 +1,25 @@
import { useTranslation } from "react-i18next";
import { cn } from "@/utils/utils";
import { useDeploymentStepper } from "../contexts/deployment-stepper-context";
const CREATE_STEPS = [
{ number: 1, label: "Provider" },
{ number: 2, label: "Type" },
{ number: 3, label: "Attach Flows" },
{ number: 4, label: "Review" },
] as const;
const EDIT_STEPS = [
{ number: 1, label: "Type" },
{ number: 2, label: "Attach Flows" },
{ number: 3, label: "Review" },
] as const;
export const DEPLOYMENT_STEPS = CREATE_STEPS;
export const DEPLOYMENT_STEPS_COUNT = 4;
export default function DeploymentStepper() {
const { t } = useTranslation();
const { currentStep, isEditMode } = useDeploymentStepper();
const CREATE_STEPS = [
{ number: 1, label: t("deployments.provider") },
{ number: 2, label: t("deployments.labelType") },
{ number: 3, label: t("deployments.attachFlows") },
{ number: 4, label: t("deployments.review") },
];
const EDIT_STEPS = [
{ number: 1, label: t("deployments.labelType") },
{ number: 2, label: t("deployments.attachFlows") },
{ number: 3, label: t("deployments.review") },
];
const steps = isEditMode ? EDIT_STEPS : CREATE_STEPS;
const progressPercent = ((currentStep - 1) / (steps.length - 1)) * 100;

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
@ -8,9 +9,10 @@ interface DeploymentsEmptyStateProps {
export default function DeploymentsEmptyState({
onAction,
}: DeploymentsEmptyStateProps) {
const { t } = useTranslation();
return (
<div className="flex flex-col items-center justify-center py-24">
<h3 className="text-lg font-semibold">No Deployments</h3>
<h3 className="text-lg font-semibold">{t("deployments.noDeployments")}</h3>
<p className="mt-1 text-sm text-muted-foreground">
Create your first deployment to run your flows in production.
</p>

View File

@ -1,4 +1,5 @@
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
@ -78,6 +79,7 @@ export default function DeploymentsTable({
onUpdateDeployment,
onDeleteDeployment,
}: DeploymentsTableProps) {
const { t } = useTranslation();
const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());
const toggleExpanded = (id: string) => {
@ -96,12 +98,12 @@ export default function DeploymentsTable({
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Type</TableHead>
<TableHead>Attached</TableHead>
<TableHead>Provider</TableHead>
<TableHead>Last Modified</TableHead>
<TableHead>Test</TableHead>
<TableHead>{t("deployments.columnName")}</TableHead>
<TableHead>{t("deployments.columnType")}</TableHead>
<TableHead>{t("deployments.columnAttached")}</TableHead>
<TableHead>{t("deployments.columnProvider")}</TableHead>
<TableHead>{t("deployments.columnLastModified")}</TableHead>
<TableHead>{t("deployments.columnTest")}</TableHead>
<TableHead className="w-10" />
</TableRow>
</TableHeader>

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Input } from "@/components/ui/input";
import type { ProviderCredentials } from "../types";
@ -14,6 +15,7 @@ export default function ProviderCredentialsForm({
onCredentialsChange,
layout = "single-column",
}: ProviderCredentialsFormProps) {
const { t } = useTranslation();
const [showApiKey, setShowApiKey] = useState(false);
const urlAndApiKeyFields = (
@ -24,7 +26,7 @@ export default function ProviderCredentialsForm({
</span>
<Input
type="url"
placeholder="https://api.example.com"
placeholder={t("deployments.placeholderApiUrl")}
className="bg-muted"
value={credentials.url}
onChange={(e) =>
@ -42,7 +44,7 @@ export default function ProviderCredentialsForm({
<div className="relative">
<Input
type={showApiKey ? "text" : "password"}
placeholder="Enter your API key"
placeholder={t("deployments.placeholderApiKey")}
className="bg-muted pr-10"
value={credentials.api_key}
onChange={(e) =>
@ -76,7 +78,7 @@ export default function ProviderCredentialsForm({
</span>
<Input
type="text"
placeholder="e.g. Production"
placeholder={t("deployments.placeholderEnvironmentName")}
className="bg-muted"
value={credentials.name}
onChange={(e) =>

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
@ -26,14 +27,15 @@ interface ProvidersContentProps {
}
function ProvidersLoadingSkeleton() {
const { t } = useTranslation();
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>URL</TableHead>
<TableHead>Provider Key</TableHead>
<TableHead>Created</TableHead>
<TableHead>{t("deployments.columnName")}</TableHead>
<TableHead>{t("deployments.columnUrl")}</TableHead>
<TableHead>{t("deployments.columnProviderKey")}</TableHead>
<TableHead>{t("deployments.columnCreated")}</TableHead>
<TableHead className="w-10" />
</TableRow>
</TableHeader>
@ -63,9 +65,10 @@ function ProvidersLoadingSkeleton() {
}
function ProvidersEmptyState({ onAddProvider }: { onAddProvider: () => void }) {
const { t } = useTranslation();
return (
<div className="flex flex-col items-center justify-center py-24">
<h3 className="text-lg font-semibold">No Environments</h3>
<h3 className="text-lg font-semibold">{t("deployments.noEnvironments")}</h3>
<p className="mt-1 text-sm text-muted-foreground">
Add your first environment to start deploying your flows.
</p>

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import {
@ -38,14 +39,15 @@ export default function ProvidersTable({
deletingId,
onDeleteProvider,
}: ProvidersTableProps) {
const { t } = useTranslation();
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>URL</TableHead>
<TableHead>Provider Key</TableHead>
<TableHead>Created</TableHead>
<TableHead>{t("deployments.columnName")}</TableHead>
<TableHead>{t("deployments.columnUrl")}</TableHead>
<TableHead>{t("deployments.columnProviderKey")}</TableHead>
<TableHead>{t("deployments.columnCreated")}</TableHead>
<TableHead className="w-10" />
</TableRow>
</TableHeader>

View File

@ -1,4 +1,5 @@
import { memo, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import InputComponent from "@/components/core/parameterRenderComponent/components/inputComponent";
import { Button } from "@/components/ui/button";
@ -48,6 +49,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
onCreateConnection: () => void;
isDuplicateName?: boolean;
}) {
const { t } = useTranslation();
const [searchQuery, setSearchQuery] = useState("");
const filteredConnections = useMemo(() => {
// Sort newly created connections to the top
@ -66,7 +68,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
return (
<>
<div className="border-b border-border p-4 text-sm text-muted-foreground">
Select or Create New Connection
{t("deployments.selectOrCreateConnection")}
</div>
<div className="flex min-w-0 flex-1 flex-col overflow-hidden px-4 py-4">
{/* Tab toggle */}
@ -85,8 +87,8 @@ export const ConnectionPanel = memo(function ConnectionPanel({
)}
>
{tab === "available"
? "Available Connections"
: "Create Connection"}
? t("deployments.availableConnections")
: t("deployments.createConnection")}
</button>
))}
</div>
@ -104,10 +106,10 @@ export const ConnectionPanel = memo(function ConnectionPanel({
/>
<div>
<p className="text-sm font-medium text-muted-foreground">
No connections yet
{t("deployments.noConnectionsYet")}
</p>
<p className="mt-0.5 text-xs text-muted-foreground/70">
Create a connection to attach credentials to this flow.
{t("deployments.noConnectionsDescription")}
</p>
</div>
<button
@ -115,7 +117,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
onClick={() => onTabChange("create")}
className="text-xs font-medium text-primary hover:underline"
>
Create your first connection
{t("deployments.createFirstConnection")}
</button>
</div>
) : (
@ -123,7 +125,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
<div className="min-w-0">
<Input
icon="Search"
placeholder="Search connections..."
placeholder={t("deployments.placeholderSearchConnections")}
className="bg-muted"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
@ -131,7 +133,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
</div>
{filteredConnections.length === 0 ? (
<p className="py-6 text-center text-sm text-muted-foreground">
No connections match &ldquo;{searchQuery}&rdquo;
{t("deployments.noConnectionsMatch", { query: searchQuery })}
</p>
) : (
filteredConnections.map((conn) => (
@ -157,10 +159,10 @@ export const ConnectionPanel = memo(function ConnectionPanel({
<div className="flex flex-col gap-4">
<div className="flex flex-col">
<span className="pb-2 text-sm font-medium">
Connection Name<span className="text-destructive">*</span>
{t("deployments.connectionNameLabel")}<span className="text-destructive">*</span>
</span>
<Input
placeholder="e.g., SALES_BOT_PROD"
placeholder={t("deployments.placeholderConnectionName")}
className="bg-muted"
value={newConnectionName}
onChange={(e) =>
@ -169,27 +171,25 @@ export const ConnectionPanel = memo(function ConnectionPanel({
/>
{isDuplicateName && (
<span className="pt-1 text-xs text-destructive">
A connection with this name already exists.
{t("deployments.connectionNameExists")}
</span>
)}
</div>
<div className="flex flex-col">
<span className="pb-2 text-sm font-medium">
Environment Variables
{t("deployments.environmentVariables")}
<span className="text-destructive">*</span>
</span>
{detectedVarCount > 0 && (
<p className="mb-2 text-xs text-muted-foreground">
{detectedVarCount} variable
{detectedVarCount > 1 ? "s" : ""} auto-detected from the
selected flow version.
{t("deployments.variablesAutoDetected", { count: detectedVarCount })}
</p>
)}
<div className="space-y-2">
{envVars.map((envVar) => (
<div key={envVar.id} className="grid grid-cols-2 gap-2">
<Input
placeholder="Key"
placeholder={t("deployments.placeholderKey")}
className="bg-muted"
value={envVar.key}
onChange={(e) =>
@ -200,10 +200,10 @@ export const ConnectionPanel = memo(function ConnectionPanel({
nodeStyle
password
id={`env-val-${envVar.id}`}
placeholder="Value"
placeholder={t("deployments.placeholderValue")}
value={envVar.value}
options={globalVariableOptions}
optionsPlaceholder="Global Variables"
optionsPlaceholder={t("deployments.globalVariables")}
optionsIcon="Globe"
selectedOption={envVar.globalVar ? envVar.value : ""}
setSelectedOption={(sel) =>
@ -220,7 +220,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
onClick={onAddEnvVar}
className="text-sm text-muted-foreground hover:text-foreground"
>
+ Add variable
{t("deployments.addVariable")}
</button>
</div>
</div>
@ -235,14 +235,14 @@ export const ConnectionPanel = memo(function ConnectionPanel({
onClick={onChangeFlow}
data-testid="connection-change-flow"
>
Change Flow
{t("deployments.changeFlow")}
</Button>
<Button
variant="outline"
onClick={onSkipConnection}
data-testid="connection-skip"
>
Skip
{t("deployments.skip")}
</Button>
{connectionTab === "available" ? (
<Button
@ -251,7 +251,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
onClick={onAttachConnection}
data-testid="connection-attach"
>
Attach Connection to Flow
{t("deployments.attachConnectionToFlow")}
</Button>
) : (
<Button
@ -260,7 +260,7 @@ export const ConnectionPanel = memo(function ConnectionPanel({
onClick={onCreateConnection}
data-testid="connection-create"
>
Create Connection
{t("deployments.createConnection")}
</Button>
)}
</div>

View File

@ -1,4 +1,5 @@
import { memo } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Badge } from "@/components/ui/badge";
import type { FlowType } from "@/types/flow";
@ -26,10 +27,11 @@ export const FlowListPanel = memo(function FlowListPanel({
onRemoveFlow?: (flowId: string) => void;
onUndoRemoveFlow?: (flowId: string) => void;
}) {
const { t } = useTranslation();
return (
<div className="flex w-[280px] flex-shrink-0 flex-col border-r border-border">
<div className="border-b border-border p-4 text-sm text-muted-foreground">
Available Flows
{t("deployments.availableFlows")}
</div>
<div className="flex-1 space-y-1 overflow-y-auto p-2">
{flows.map((flow) => {
@ -103,7 +105,7 @@ export const FlowListPanel = memo(function FlowListPanel({
type="button"
data-testid={`detach-flow-${flow.id}`}
className="flex-shrink-0 rounded p-1 text-muted-foreground hover:bg-destructive/10 hover:text-destructive"
title="Detach flow"
title={t("deployments.detachFlow")}
onClick={(e) => {
e.stopPropagation();
onRemoveFlow(flow.id);
@ -117,7 +119,7 @@ export const FlowListPanel = memo(function FlowListPanel({
type="button"
data-testid={`undo-remove-flow-${flow.id}`}
className="flex-shrink-0 rounded p-1 text-muted-foreground hover:bg-accent-blue-muted hover:text-accent-blue-muted-foreground"
title="Undo detach"
title={t("deployments.undoDetach")}
onClick={(e) => {
e.stopPropagation();
onUndoRemoveFlow(flow.id);

View File

@ -1,4 +1,5 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { useGetDeploymentConfigs } from "@/controllers/API/queries/deployments/use-get-deployment-configs";
import { useGetFlowVersions } from "@/controllers/API/queries/flow-version/use-get-flow-versions";
@ -17,6 +18,7 @@ import { VersionPanel } from "./step-attach-flows-version-panel";
type RightPanelView = "versions" | "connections";
export default function StepAttachFlows() {
const { t } = useTranslation();
const {
isEditMode,
initialFlowId,
@ -383,7 +385,7 @@ export default function StepAttachFlows() {
return (
<div className="flex min-h-0 flex-1 flex-col gap-4 py-3">
<h2 className="text-lg font-semibold">Attach Flows</h2>
<h2 className="text-lg font-semibold">{t("deployments.attachFlows")}</h2>
<div className="flex min-h-0 flex-1 overflow-hidden rounded-xl border border-border">
<FlowListPanel

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { useGetProviderAccounts } from "@/controllers/API/queries/deployment-provider-accounts/use-get-provider-accounts";
import { cn } from "@/utils/utils";
@ -59,6 +60,7 @@ function EnvironmentList({
selectedEnvironment: ProviderAccount | null;
onSelectEnvironment: (environment: ProviderAccount) => void;
}) {
const { t } = useTranslation();
return (
<div className="flex flex-col gap-3">
<span className="text-sm text-muted-foreground">
@ -66,7 +68,7 @@ function EnvironmentList({
</span>
<div
role="radiogroup"
aria-label="Existing environments"
aria-label={t("deployments.ariaExistingEnvironments")}
className="flex flex-col gap-3"
>
{environments.map((environment) => {
@ -97,6 +99,7 @@ function EnvironmentList({
}
export default function StepProvider() {
const { t } = useTranslation();
const {
setSelectedProvider,
selectedInstance,
@ -124,7 +127,7 @@ export default function StepProvider() {
return (
<div className="flex h-full w-full flex-col gap-6 overflow-y-auto py-3">
<h2 className="text-lg font-semibold">Provider</h2>
<h2 className="text-lg font-semibold">{t("deployments.provider")}</h2>
<div className="flex items-center gap-3 rounded-lg border border-border bg-muted p-3">
<ForwardedIconComponent

View File

@ -1,4 +1,5 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Badge } from "@/components/ui/badge";
@ -16,6 +17,7 @@ function EditableToolName({
placeholder: string;
onSave: (name: string) => void;
}) {
const { t } = useTranslation();
const [editing, setEditing] = useState(false);
const [draft, setDraft] = useState(value);
const inputRef = useRef<HTMLInputElement>(null);
@ -57,7 +59,7 @@ function EditableToolName({
type="button"
onClick={confirm}
className="rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground"
title="Confirm"
title={t("deployments.confirm")}
>
<ForwardedIconComponent name="Check" className="h-3.5 w-3.5" />
</button>
@ -77,7 +79,7 @@ function EditableToolName({
setEditing(true);
}}
className="rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground"
title="Edit tool name"
title={t("deployments.editToolName")}
data-testid="edit-tool-name"
>
<ForwardedIconComponent name="Pencil" className="h-3.5 w-3.5" />
@ -87,6 +89,7 @@ function EditableToolName({
}
export default function StepReview() {
const { t } = useTranslation();
const {
isEditMode,
deploymentType,
@ -147,9 +150,9 @@ export default function StepReview() {
return (
<div className="flex flex-col gap-4 py-3">
<div>
<h2 className="text-lg font-semibold">Review & Confirm</h2>
<h2 className="text-lg font-semibold">{t("deployments.reviewAndConfirm")}</h2>
<p className="text-sm text-muted-foreground">
Review your deployment details before creating.
{t("deployments.reviewDetails")}
</p>
</div>
@ -158,11 +161,11 @@ export default function StepReview() {
{/* Deployment column */}
<div className="flex flex-col gap-3">
<span className="text-sm font-medium text-foreground">
Deployment
{t("deployments.deploymentLabel")}
</span>
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2">
<span className="w-10 text-xs text-muted-foreground">Type</span>
<span className="w-10 text-xs text-muted-foreground">{t("deployments.labelType")}</span>
<div className="flex items-center gap-1.5">
<ForwardedIconComponent
name={deploymentType === "agent" ? "Bot" : "Server"}
@ -174,7 +177,7 @@ export default function StepReview() {
</div>
</div>
<div className="flex items-center gap-2">
<span className="w-10 text-xs text-muted-foreground">Name</span>
<span className="w-10 text-xs text-muted-foreground">{t("deployments.labelName")}</span>
<span className="text-sm text-foreground">
{deploymentName || "—"}
</span>
@ -182,7 +185,7 @@ export default function StepReview() {
{selectedLlm && (
<div className="flex items-center gap-2">
<span className="w-10 text-xs text-muted-foreground">
Model
{t("deployments.labelModel")}
</span>
<span className="text-sm text-foreground">{selectedLlm}</span>
</div>
@ -193,7 +196,7 @@ export default function StepReview() {
{/* Attached Flows column */}
<div className="flex flex-col gap-3">
<span className="text-sm font-medium text-foreground">
Attached Flows
{t("deployments.attachedFlowsLabel")}
</span>
<div className="flex flex-col gap-1.5">
{reviewFlows.length === 0 ? (
@ -285,7 +288,7 @@ export default function StepReview() {
{existingConns.length > 0 && (
<div className="flex flex-col gap-2">
<span className="text-xs font-medium text-muted-foreground">
Existing Connections
{t("deployments.existingConnections")}
</span>
{existingConns.map((conn) => (
<span
@ -300,7 +303,7 @@ export default function StepReview() {
{newConns.length > 0 && (
<div className="flex flex-col gap-2">
<span className="text-xs font-medium text-muted-foreground">
New Connections
{t("deployments.newConnections")}
</span>
{newConns.map((conn) => (
<div
@ -351,7 +354,7 @@ export default function StepReview() {
<div className="rounded-xl border border-destructive/30 bg-destructive/5 p-4">
<div className="flex flex-col gap-3">
<span className="text-sm font-medium text-destructive">
Detaching
{t("deployments.detaching")}
</span>
<div className="flex flex-col gap-2">
{Array.from(removedFlowIds).map((flowId) => {
@ -366,22 +369,21 @@ export default function StepReview() {
className="h-3.5 w-3.5 shrink-0 text-destructive/60"
/>
<span className="text-sm text-foreground">
{flow?.name ?? "Unknown flow"}
{flow?.name ?? t("deployments.unknownFlow")}
</span>
<Badge
variant="secondaryStatic"
size="tag"
className="bg-destructive/10 text-destructive"
>
removing
{t("deployments.removing")}
</Badge>
</div>
);
})}
</div>
<p className="text-xs text-muted-foreground">
These tools will be detached from the agent. They will remain
available on your provider tenant.
{t("deployments.toolsWillBeDetached")}
</p>
</div>
</div>

View File

@ -1,5 +1,6 @@
import { ChevronDown } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Input } from "@/components/ui/input";
import {
@ -26,6 +27,7 @@ const TYPE_OPTIONS = [
];
export default function StepType() {
const { t } = useTranslation();
const {
isEditMode,
deploymentType,
@ -72,7 +74,7 @@ export default function StepType() {
return (
<div className="flex w-full flex-col gap-6 overflow-y-auto py-3">
<h2 className="text-lg font-semibold">Deployment Type</h2>
<h2 className="text-lg font-semibold">{t("deployments.deploymentType")}</h2>
<div className="flex flex-col gap-3">
<span className="text-sm font-medium">
@ -81,7 +83,7 @@ export default function StepType() {
<div
className="grid grid-cols-2 gap-3"
role="radiogroup"
aria-label="Deployment type"
aria-label={t("deployments.ariaDeploymentType")}
>
{TYPE_OPTIONS.map((option) => (
<label
@ -129,7 +131,7 @@ export default function StepType() {
Agent Name <span className="text-destructive">*</span>
</span>
<Input
placeholder="e.g., Sales Bot"
placeholder={t("deployments.placeholderSalesBot")}
className="bg-muted"
value={deploymentName}
onChange={(e) => setDeploymentName(e.target.value)}
@ -188,7 +190,7 @@ export default function StepType() {
<div className="flex flex-col">
<span className="pb-2 text-sm font-medium">Description</span>
<Textarea
placeholder="Describe the agent's purpose..."
placeholder={t("deployments.placeholderAgentPurpose")}
rows={3}
className="resize-none bg-muted placeholder:text-placeholder-foreground"
value={deploymentDescription}

View File

@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { cn } from "@/utils/utils";
@ -9,6 +10,7 @@ interface ChatInputProps {
}
export default function ChatInput({ onSend, disabled }: ChatInputProps) {
const { t } = useTranslation();
const [value, setValue] = useState("");
const textareaRef = useRef<HTMLTextAreaElement>(null);
@ -52,7 +54,7 @@ export default function ChatInput({ onSend, disabled }: ChatInputProps) {
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={handleKeyDown}
placeholder="Message"
placeholder={t("deployments.placeholderMessage")}
disabled={disabled}
rows={1}
className="max-h-40 flex-1 resize-none overflow-y-auto bg-transparent text-sm leading-5 text-foreground placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
@ -63,7 +65,7 @@ export default function ChatInput({ onSend, disabled }: ChatInputProps) {
onClick={handleSend}
disabled={!value.trim() || disabled}
className="h-8 w-8 flex-shrink-0 self-end rounded-lg"
aria-label="Send message"
aria-label={t("deployments.ariaSendMessage")}
>
<ForwardedIconComponent name="Send" className="h-4 w-4" />
</Button>

View File

@ -1,4 +1,5 @@
import { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import ChatMessageBubble from "./chat-message-bubble";
import type { ChatMessage } from "./types";
@ -8,12 +9,13 @@ interface ChatMessagesProps {
}
function EmptyState() {
const { t } = useTranslation();
return (
<div className="flex flex-1 flex-col items-center justify-center gap-2 text-muted-foreground">
<div className="flex h-12 w-12 items-center justify-center rounded-full border border-border">
<ForwardedIconComponent name="Bot" className="h-6 w-6" />
</div>
<span className="text-sm">Agent Chat</span>
<span className="text-sm">{t("deployments.agentChat")}</span>
</div>
);
}

View File

@ -1,6 +1,7 @@
import { useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useCancelIngestion } from "@/controllers/API/queries/knowledge-bases/use-cancel-ingestion";
import { useDeleteKnowledgeBase } from "@/controllers/API/queries/knowledge-bases/use-delete-knowledge-base";
import type { KnowledgeBaseInfo } from "@/controllers/API/queries/knowledge-bases/use-get-knowledge-bases";
@ -18,6 +19,7 @@ export const useKnowledgeBaseActions = ({
selectedFiles,
clearSelection,
}: UseKnowledgeBaseActionsOptions) => {
const { t } = useTranslation();
const queryClient = useQueryClient();
const { setErrorData, setSuccessData } = useAlertStore((state) => ({
setErrorData: state.setErrorData,
@ -35,7 +37,7 @@ export const useKnowledgeBaseActions = ({
const cancelIngestionMutation = useCancelIngestion({
onSuccess: () => {
setSuccessData({ title: "Ingestion cancelled" });
setSuccessData({ title: t("success.ingestionCancelled") });
refetch();
},
onError: (error: AxiosError<{ detail?: string }>) => {
@ -54,7 +56,7 @@ export const useKnowledgeBaseActions = ({
const deleteKnowledgeBaseMutation = useDeleteKnowledgeBase({
onSuccess: () => {
setSuccessData({ title: "Knowledge base deleted" });
setSuccessData({ title: t("success.knowledgeBaseDeleted") });
},
onError: (error: AxiosError<{ detail?: string }>) => {
setErrorData({
@ -73,7 +75,7 @@ export const useKnowledgeBaseActions = ({
const deleteKnowledgeBasesMutation = useDeleteKnowledgeBase({
onSuccess: () => {
setSuccessData({ title: "Knowledge base(s) deleted" });
setSuccessData({ title: t("success.knowledgeBaseDeleted") });
},
onError: (error: AxiosError<{ detail?: string }>) => {
setErrorData({

View File

@ -59,7 +59,7 @@ const StoreApiKeyFormComponent = ({
value={apikey}
isForm
password={true}
placeholder="Insert your API Key"
placeholder={t("storeApiKey.insertPlaceholder")}
className="w-full"
/>
<Form.Message match="valueMissing" className="field-invalid">

View File

@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import {
useDeleteGlobalVariables,
@ -16,6 +17,7 @@ const GeneralDeleteConfirmationModal = ({
option,
onConfirmDelete,
}: GeneralDeleteConfirmationModalProps) => {
const { t } = useTranslation();
const setErrorData = useAlertStore((state) => state.setErrorData);
const { mutate: mutateDeleteGlobalVariable } = useDeleteGlobalVariables();
const { data: globalVariables } = useGetGlobalVariables();
@ -32,16 +34,16 @@ const GeneralDeleteConfirmationModal = ({
},
onError: () => {
setErrorData({
title: "Error deleting variable",
list: [cn("ID not found for variable: ", key)],
title: t("globalVars.errorDeletingVariable"),
list: [t("globalVars.errorIdNotFound", { name: key })],
});
},
},
);
} else {
setErrorData({
title: "Error deleting variable",
list: [cn("ID not found for variable: ", key)],
title: t("globalVars.errorDeletingVariable"),
list: [t("globalVars.errorIdNotFound", { name: key })],
});
}
}

View File

@ -44,7 +44,7 @@ export const useChatFileUpload = ({
if (!isAllowedChatAttachmentFile(file)) {
setErrorData({
title: "Error uploading file",
title: t("errors.upload"),
list: [FS_ERROR_TEXT, SN_ERROR_TEXT],
});
return;
@ -97,7 +97,7 @@ export const useChatFileUpload = ({
});
setErrorData({
title: "Error uploading file",
title: t("errors.upload"),
list: [t("misc.fsErrorText"), SN_ERROR_TEXT],
});
},

View File

@ -189,7 +189,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
set({ isBuilding: false });
get().revertBuiltStatusFromBuilding();
useAlertStore.getState().setErrorData({
title: "Build stopped",
title: (i18n as any).t("alerts.buildStopped"),
});
},
isPending: true,