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:
RamGopalSrikar
2026-04-13 15:08:42 -04:00
parent 826e0e675f
commit ce5a6b4092
12 changed files with 160 additions and 35 deletions

View File

@ -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 [].",

View File

@ -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"
}

View File

@ -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 [].",

View File

@ -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 [].",

View File

@ -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": "必要に応じてキーと値のペアを追加・編集し、辞書をカスタマイズしてください。 新しいオブジェクト {} や配列 [] の追加に対応しています。",

View File

@ -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 [].",

View File

@ -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": "自定义您的字典,根据需要添加或编辑键值对。 支持添加新的对象 {} 或数组 []。",

View File

@ -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>

View File

@ -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

View File

@ -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;

View File

@ -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;
};

View File

@ -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"