mirror of
https://github.com/langflow-ai/langflow.git
synced 2026-07-25 12:25:33 +08:00
feat(i18n): translate delete confirmation modal and fix CTA button overflow
- Translate DeleteConfirmationModal (title, body, buttons, "can't be undone") - Translate flow/folder/component description labels via use-description-modal - Translate "and its message history" and folder delete note at call sites - Fix empty page CTA button overflow with whitespace-normal w-auto Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -72,6 +72,21 @@
|
||||
"component.selectOption": "Auswahl einer Option",
|
||||
"component.updateError": "Beim Aktualisieren der Komponente ist ein unerwarteter Fehler aufgetreten. Wiederholen Sie bitte den Vorgang.",
|
||||
"component.updateErrorTitle": "Fehler beim Aktualisieren der Komponente",
|
||||
"deleteModal.body": "Dadurch wird die Datei „ {{description}} “ endgültig gelöscht.",
|
||||
"deleteModal.bodyWithNote": "Dadurch wird die Seite „ {{description}} “ unter {{note}} endgültig gelöscht.",
|
||||
"deleteModal.cancel": "Abbrechen",
|
||||
"deleteModal.cannotBeUndone": "Das lässt sich nicht rückgängig machen.",
|
||||
"deleteModal.component": "Komponente",
|
||||
"deleteModal.components": "Komponenten von",
|
||||
"deleteModal.delete": "Löschen",
|
||||
"deleteModal.flow": "Fluss",
|
||||
"deleteModal.flows": "Flüsse",
|
||||
"deleteModal.folder": "Ordner",
|
||||
"deleteModal.item": "Position",
|
||||
"deleteModal.items": "Positionen",
|
||||
"deleteModal.noteFolderContents": "sowie alle damit verbundenen Abläufe und Komponenten",
|
||||
"deleteModal.noteMessageHistory": "und den Nachrichtenverlauf",
|
||||
"deleteModal.title": "Löschen",
|
||||
"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 [].",
|
||||
|
||||
@ -469,5 +469,20 @@
|
||||
"files.columnName": "Name",
|
||||
"files.columnType": "Type",
|
||||
"files.columnSize": "Size",
|
||||
"files.columnModified": "Modified"
|
||||
"files.columnModified": "Modified",
|
||||
"deleteModal.title": "Delete",
|
||||
"deleteModal.body": "This will permanently delete the {{description}}.",
|
||||
"deleteModal.bodyWithNote": "This will permanently delete the {{description}} {{note}}.",
|
||||
"deleteModal.cannotBeUndone": "This can't be undone.",
|
||||
"deleteModal.cancel": "Cancel",
|
||||
"deleteModal.delete": "Delete",
|
||||
"deleteModal.flow": "flow",
|
||||
"deleteModal.flows": "flows",
|
||||
"deleteModal.component": "component",
|
||||
"deleteModal.components": "components",
|
||||
"deleteModal.item": "item",
|
||||
"deleteModal.items": "items",
|
||||
"deleteModal.folder": "folder",
|
||||
"deleteModal.noteMessageHistory": "and its message history",
|
||||
"deleteModal.noteFolderContents": "and all associated flows and components"
|
||||
}
|
||||
|
||||
@ -72,6 +72,21 @@
|
||||
"component.selectOption": "Seleccione una opción",
|
||||
"component.updateError": "Se ha producido un error inesperado al actualizar el componente. Inténtelo de nuevo.",
|
||||
"component.updateErrorTitle": "Se ha producido un error al actualizar el componente",
|
||||
"deleteModal.body": "Esto eliminará definitivamente el archivo « {{description}} ».",
|
||||
"deleteModal.bodyWithNote": "Esto eliminará definitivamente el archivo {{description}} {{note}}.",
|
||||
"deleteModal.cancel": "Cancelar",
|
||||
"deleteModal.cannotBeUndone": "Esto ya no tiene vuelta atrás.",
|
||||
"deleteModal.component": "componente",
|
||||
"deleteModal.components": "componentes",
|
||||
"deleteModal.delete": "Suprimir",
|
||||
"deleteModal.flow": "flujo",
|
||||
"deleteModal.flows": "flujos",
|
||||
"deleteModal.folder": "carpeta",
|
||||
"deleteModal.item": "elemento",
|
||||
"deleteModal.items": "Elementos",
|
||||
"deleteModal.noteFolderContents": "y todos los flujos y componentes asociados",
|
||||
"deleteModal.noteMessageHistory": "y su historial de mensajes",
|
||||
"deleteModal.title": "Suprimir",
|
||||
"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 [].",
|
||||
|
||||
@ -72,6 +72,21 @@
|
||||
"component.selectOption": "Sélectionnez une option",
|
||||
"component.updateError": "Une erreur inattendue s'est produite lors de la mise à jour du composant. Faites une nouvelle tentative.",
|
||||
"component.updateErrorTitle": "Erreur lors de la mise à jour du composant",
|
||||
"deleteModal.body": "Cela supprimera définitivement l' {{description}}.",
|
||||
"deleteModal.bodyWithNote": "Cela supprimera définitivement l' {{description}} {{note}}.",
|
||||
"deleteModal.cancel": "Annuler",
|
||||
"deleteModal.cannotBeUndone": "C'est irréversible.",
|
||||
"deleteModal.component": "composant",
|
||||
"deleteModal.components": "composants",
|
||||
"deleteModal.delete": "Supprimer",
|
||||
"deleteModal.flow": "flux",
|
||||
"deleteModal.flows": "flux",
|
||||
"deleteModal.folder": "dossier",
|
||||
"deleteModal.item": "élément",
|
||||
"deleteModal.items": "éléments",
|
||||
"deleteModal.noteFolderContents": "ainsi que tous les flux et composants associés",
|
||||
"deleteModal.noteMessageHistory": "et l'historique de ses messages",
|
||||
"deleteModal.title": "Supprimer",
|
||||
"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 [].",
|
||||
|
||||
@ -72,6 +72,21 @@
|
||||
"component.selectOption": "オプションを選択",
|
||||
"component.updateError": "コンポーネントの更新中に予期せぬエラーが発生しました。 再試行してください。",
|
||||
"component.updateErrorTitle": "コンポーネントの更新中にエラーが発生しました",
|
||||
"deleteModal.body": "これにより、 {{description}} が完全に削除されます。",
|
||||
"deleteModal.bodyWithNote": "これにより、 {{description}} {{note}} が完全に削除されます。",
|
||||
"deleteModal.cancel": "キャンセル",
|
||||
"deleteModal.cannotBeUndone": "これは取り消すことができません。",
|
||||
"deleteModal.component": "コンポーネント",
|
||||
"deleteModal.components": "コンポーネント",
|
||||
"deleteModal.delete": "削除",
|
||||
"deleteModal.flow": "フロー",
|
||||
"deleteModal.flows": "フロー",
|
||||
"deleteModal.folder": "フォルダー",
|
||||
"deleteModal.item": "項目",
|
||||
"deleteModal.items": "項目",
|
||||
"deleteModal.noteFolderContents": "および関連するすべてのフローとコンポーネント",
|
||||
"deleteModal.noteMessageHistory": "およびそのメッセージ履歴",
|
||||
"deleteModal.title": "削除",
|
||||
"dialog.chat": "AIと対話しましょう。 入力、出力、およびメモリを監視する。",
|
||||
"dialog.code": "このコードを使用して、フローをエクスポートし、統合してください。",
|
||||
"dialog.codeDict": "必要に応じてキーと値のペアを追加・編集し、辞書をカスタマイズしてください。 新しいオブジェクト {} や配列 [] の追加に対応しています。",
|
||||
|
||||
@ -72,6 +72,21 @@
|
||||
"component.selectOption": "Selecionar uma opção",
|
||||
"component.updateError": "Ocorreu um erro inesperado durante a atualização do componente. Tente novamente.",
|
||||
"component.updateErrorTitle": "Erro ao atualizar o componente",
|
||||
"deleteModal.body": "Isso excluirá definitivamente o arquivo {{description}}.",
|
||||
"deleteModal.bodyWithNote": "Isso excluirá definitivamente o arquivo {{description}} {{note}}.",
|
||||
"deleteModal.cancel": "Cancelar",
|
||||
"deleteModal.cannotBeUndone": "Isso não tem como ser desfeito.",
|
||||
"deleteModal.component": "componente",
|
||||
"deleteModal.components": "Componentes do",
|
||||
"deleteModal.delete": "Excluir",
|
||||
"deleteModal.flow": "fluxo",
|
||||
"deleteModal.flows": "fluxos",
|
||||
"deleteModal.folder": "pasta",
|
||||
"deleteModal.item": "item",
|
||||
"deleteModal.items": "itens",
|
||||
"deleteModal.noteFolderContents": "e todos os fluxos e componentes associados",
|
||||
"deleteModal.noteMessageHistory": "e seu histórico de mensagens",
|
||||
"deleteModal.title": "Excluir",
|
||||
"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 [].",
|
||||
|
||||
@ -72,6 +72,21 @@
|
||||
"component.selectOption": "选择一个选项",
|
||||
"component.updateError": "更新组件时发生了一个意外错误。 请重试。",
|
||||
"component.updateErrorTitle": "更新组件时发生错误",
|
||||
"deleteModal.body": "这将永久删除 {{description}}。",
|
||||
"deleteModal.bodyWithNote": "这将永久删除 {{description}} {{note}}。",
|
||||
"deleteModal.cancel": "取消",
|
||||
"deleteModal.cannotBeUndone": "这无法挽回。",
|
||||
"deleteModal.component": "组件",
|
||||
"deleteModal.components": "组件",
|
||||
"deleteModal.delete": "删除",
|
||||
"deleteModal.flow": "流",
|
||||
"deleteModal.flows": "流",
|
||||
"deleteModal.folder": "文件夹",
|
||||
"deleteModal.item": "项",
|
||||
"deleteModal.items": "项",
|
||||
"deleteModal.noteFolderContents": "以及所有相关的流程和组件",
|
||||
"deleteModal.noteMessageHistory": "及其消息记录",
|
||||
"deleteModal.title": "删除",
|
||||
"dialog.chat": "与您的 AI 互动。 监控输入、输出和存储器。",
|
||||
"dialog.code": "使用此代码导出您的流程以进行集成。",
|
||||
"dialog.codeDict": "自定义您的字典,根据需要添加或编辑键值对。 支持添加新的对象 {} 或数组 []。",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { DialogClose } from "@radix-ui/react-dialog";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
@ -27,6 +28,8 @@ export default function DeleteConfirmationModal({
|
||||
setOpen?: (open: boolean) => void;
|
||||
note?: string;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild={!children ? true : asChild} tabIndex={-1}>
|
||||
@ -40,15 +43,22 @@ export default function DeleteConfirmationModal({
|
||||
className="h-6 w-6 pr-1 text-foreground"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
<span className="pl-2">Delete</span>
|
||||
<span className="pl-2">{t("deleteModal.title")}</span>
|
||||
</div>
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<span className="pb-3 text-sm">
|
||||
This will permanently delete the {description ?? "flow"}
|
||||
{note ? " " + note : ""}.<br />
|
||||
{note
|
||||
? t("deleteModal.bodyWithNote", {
|
||||
description: description ?? t("deleteModal.flow"),
|
||||
note,
|
||||
})
|
||||
: t("deleteModal.body", {
|
||||
description: description ?? t("deleteModal.flow"),
|
||||
})}
|
||||
<br />
|
||||
This can't be undone.
|
||||
<br />
|
||||
{t("deleteModal.cannotBeUndone")}
|
||||
</span>
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
@ -58,7 +68,7 @@ export default function DeleteConfirmationModal({
|
||||
variant="outline"
|
||||
data-testid="btn_cancel_delete_confirmation_modal"
|
||||
>
|
||||
Cancel
|
||||
{t("deleteModal.cancel")}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<DialogClose asChild>
|
||||
@ -70,7 +80,7 @@ export default function DeleteConfirmationModal({
|
||||
}}
|
||||
data-testid="btn_delete_delete_confirmation_modal"
|
||||
>
|
||||
Delete
|
||||
{t("deleteModal.delete")}
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useParams } from "react-router-dom";
|
||||
import ForwardedIconComponent from "@/components/common/genericIconComponent";
|
||||
import useDragStart from "@/components/core/cardComponent/hooks/use-on-drag-start";
|
||||
@ -36,6 +37,7 @@ const ListComponent = ({
|
||||
setSelected: (selected: boolean) => void;
|
||||
shiftPressed: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useCustomNavigate();
|
||||
const [openDelete, setOpenDelete] = useState(false);
|
||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||
@ -216,7 +218,7 @@ const ListComponent = ({
|
||||
setOpen={setOpenDelete}
|
||||
onConfirm={handleDelete}
|
||||
description={descriptionModal}
|
||||
note={!flowData.is_component ? "and its message history" : ""}
|
||||
note={!flowData.is_component ? t("deleteModal.noteMessageHistory") : ""}
|
||||
/>
|
||||
)}
|
||||
<ExportModal
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// Modals.tsx
|
||||
import { useTranslation } from "react-i18next";
|
||||
import TemplatesModal from "@/modals/templatesModal";
|
||||
import DeleteConfirmationModal from "../../../../modals/deleteConfirmationModal";
|
||||
|
||||
@ -16,24 +17,28 @@ const ModalsComponent = ({
|
||||
openDeleteFolderModal = false,
|
||||
setOpenDeleteFolderModal = () => {},
|
||||
handleDeleteFolder = () => {},
|
||||
}: ModalsProps) => (
|
||||
<>
|
||||
{openModal && <TemplatesModal open={openModal} setOpen={setOpenModal} />}
|
||||
{openDeleteFolderModal && (
|
||||
<DeleteConfirmationModal
|
||||
open={openDeleteFolderModal}
|
||||
setOpen={setOpenDeleteFolderModal}
|
||||
onConfirm={() => {
|
||||
handleDeleteFolder();
|
||||
setOpenDeleteFolderModal(false);
|
||||
}}
|
||||
description="folder"
|
||||
note={"and all associated flows and components"}
|
||||
>
|
||||
<></>
|
||||
</DeleteConfirmationModal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}: ModalsProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
{openModal && <TemplatesModal open={openModal} setOpen={setOpenModal} />}
|
||||
{openDeleteFolderModal && (
|
||||
<DeleteConfirmationModal
|
||||
open={openDeleteFolderModal}
|
||||
setOpen={setOpenDeleteFolderModal}
|
||||
onConfirm={() => {
|
||||
handleDeleteFolder();
|
||||
setOpenDeleteFolderModal(false);
|
||||
}}
|
||||
description={t("deleteModal.folder")}
|
||||
note={t("deleteModal.noteFolderContents")}
|
||||
>
|
||||
<></>
|
||||
</DeleteConfirmationModal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalsComponent;
|
||||
|
||||
@ -1,24 +1,27 @@
|
||||
import { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const useDescriptionModal = (
|
||||
selectedFlowsComponentsCards: string[] | undefined,
|
||||
type: string | undefined,
|
||||
) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const getDescriptionModal = useMemo(() => {
|
||||
const getTypeLabel = (type) => {
|
||||
const labels = {
|
||||
all: "item",
|
||||
component: "component",
|
||||
flow: "flow",
|
||||
all: t("deleteModal.item"),
|
||||
component: t("deleteModal.component"),
|
||||
flow: t("deleteModal.flow"),
|
||||
};
|
||||
return labels[type] || "";
|
||||
};
|
||||
|
||||
const getPluralizedLabel = (type) => {
|
||||
const labels = {
|
||||
all: "items",
|
||||
component: "components",
|
||||
flow: "flows",
|
||||
all: t("deleteModal.items"),
|
||||
component: t("deleteModal.components"),
|
||||
flow: t("deleteModal.flows"),
|
||||
};
|
||||
return labels[type] || "";
|
||||
};
|
||||
@ -27,7 +30,7 @@ const useDescriptionModal = (
|
||||
return getTypeLabel(type);
|
||||
}
|
||||
return getPluralizedLabel(type);
|
||||
}, [selectedFlowsComponentsCards, type]);
|
||||
}, [selectedFlowsComponentsCards, type, t]);
|
||||
|
||||
return getDescriptionModal;
|
||||
};
|
||||
|
||||
@ -154,7 +154,7 @@ export const EmptyPageCommunity = ({
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
className="z-10 m-auto mt-3 h-auto min-h-10 w-full max-w-xs rounded-lg font-bold transition-all duration-300"
|
||||
className="z-10 m-auto mt-3 h-auto min-h-10 w-auto whitespace-normal rounded-lg font-bold transition-all duration-300"
|
||||
onClick={() => setOpenModal(true)}
|
||||
id="new-project-btn"
|
||||
data-testid="new_project_btn_empty_page"
|
||||
|
||||
Reference in New Issue
Block a user