This is an automated email from the ASF dual-hosted git repository. jscheffl pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push: new a14b7381398 Fix translations for toasts (#51674) a14b7381398 is described below commit a14b7381398fe868738279a8b165fac062eb93fa Author: Brent Bovenzi <br...@astronomer.io> AuthorDate: Fri Jun 13 00:39:27 2025 -0400 Fix translations for toasts (#51674) --- .../ui/src/components/Clear/Run/ClearRunButton.tsx | 4 +- .../ui/src/components/Clear/Run/ClearRunDialog.tsx | 5 ++- .../Clear/TaskInstance/ClearTaskInstanceButton.tsx | 4 +- .../Clear/TaskInstance/ClearTaskInstanceDialog.tsx | 5 ++- .../src/airflow/ui/src/components/DeleteDialog.tsx | 2 +- .../src/components/MarkAs/Run/MarkRunAsButton.tsx | 4 +- .../src/components/MarkAs/Run/MarkRunAsDialog.tsx | 7 +++- .../TaskInstance/MarkTaskInstanceAsButton.tsx | 6 ++- .../TaskInstance/MarkTaskInstanceAsDialog.tsx | 6 ++- .../src/airflow/ui/src/i18n/locales/en/admin.json | 21 ++++++++++- .../src/airflow/ui/src/i18n/locales/en/common.json | 37 +++++++++++++++++++ .../airflow/ui/src/i18n/locales/en/components.json | 18 ++++++++- .../src/airflow/ui/src/i18n/locales/en/dag.json | 13 +++++++ .../src/airflow/ui/src/i18n/locales/en/dags.json | 1 + .../src/airflow/ui/src/pages/DeleteRunButton.tsx | 12 +++--- .../TaskInstances/DeleteTaskInstanceButton.tsx | 16 +++++--- .../src/airflow/ui/src/queries/useAddConnection.ts | 11 +++++- .../src/airflow/ui/src/queries/useAddPool.ts | 11 ++++-- .../src/airflow/ui/src/queries/useAddVariable.ts | 11 ++++-- .../ui/src/queries/useBulkDeleteConnections.tsx | 10 ++++- .../ui/src/queries/useBulkDeleteVariables.ts | 10 ++++- .../src/airflow/ui/src/queries/useClearRun.ts | 18 +++++---- .../ui/src/queries/useClearTaskInstances.ts | 18 +++++---- .../ui/src/queries/useConnectionTypeMeta.ts | 43 ++++++++++++++++++---- .../airflow/ui/src/queries/useCreateBackfill.ts | 10 +++-- .../src/airflow/ui/src/queries/useDagParams.ts | 7 +++- .../src/airflow/ui/src/queries/useDagParsing.ts | 22 ++++++----- .../airflow/ui/src/queries/useDeleteConnection.ts | 28 +++++++++----- .../src/airflow/ui/src/queries/useDeleteDag.ts | 28 +++++++++----- .../src/airflow/ui/src/queries/useDeleteDagRun.ts | 8 ++-- .../src/airflow/ui/src/queries/useDeletePool.ts | 28 +++++++++----- .../ui/src/queries/useDeleteTaskInstance.ts | 12 ++++-- .../airflow/ui/src/queries/useDeleteVariable.ts | 28 +++++++++----- .../airflow/ui/src/queries/useEditConnection.tsx | 11 ++++-- .../src/airflow/ui/src/queries/useEditPool.ts | 10 ++++- .../src/airflow/ui/src/queries/useEditVariable.ts | 10 ++++- .../airflow/ui/src/queries/useImportVariables.ts | 12 +++++- .../src/airflow/ui/src/queries/usePatchDagRun.ts | 20 ++++++---- .../airflow/ui/src/queries/usePatchTaskInstance.ts | 20 ++++++---- .../src/airflow/ui/src/queries/useTrigger.ts | 7 ++-- 40 files changed, 400 insertions(+), 154 deletions(-) diff --git a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx index 0124598fd20..6d5fe9f1b60 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunButton.tsx @@ -54,10 +54,10 @@ const ClearRunButton = ({ dagRun, isHotkeyEnabled = false, withText = true }: Pr > <Box> <ActionButton - actionName={translate("dags:runAndTaskActions.clear.button", { type: "Run" })} + actionName={translate("dags:runAndTaskActions.clear.button", { type: translate("dagRun_one") })} icon={<CgRedo />} onClick={onOpen} - text={translate("dags:runAndTaskActions.clear.button", { type: "Run" })} + text={translate("dags:runAndTaskActions.clear.button", { type: translate("dagRun_one") })} withText={withText} /> diff --git a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx index 0dda538103e..696ada0ee38 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/Run/ClearRunDialog.tsx @@ -68,7 +68,10 @@ const ClearRunDialog = ({ dagRun, onClose, open }: Props) => { <Dialog.Header> <VStack align="start" gap={4}> <Heading size="xl"> - <strong>{translate("dags:runAndTaskActions.clear.title", { type: "Run" })}: </strong> {dagRunId} + <strong> + {translate("dags:runAndTaskActions.clear.title", { type: translate("dagRun_one") })}:{" "} + </strong>{" "} + {dagRunId} </Heading> </VStack> </Dialog.Header> diff --git a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceButton.tsx b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceButton.tsx index e9a4bdc9885..4f55f8480fa 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceButton.tsx @@ -54,10 +54,10 @@ const ClearTaskInstanceButton = ({ isHotkeyEnabled = false, taskInstance, withTe > <Box> <ActionButton - actionName={translate("runAndTaskActions.clear.button", { type: "Task Instance" })} + actionName={translate("runAndTaskActions.clear.button", { type: translate("taskInstance_one") })} icon={<CgRedo />} onClick={onOpen} - text={translate("runAndTaskActions.clear.button", { type: "Task Instance" })} + text={translate("runAndTaskActions.clear.button", { type: translate("taskInstance_one") })} withText={withText} /> diff --git a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceDialog.tsx b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceDialog.tsx index 6f53c07d647..3f0906d8725 100644 --- a/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/Clear/TaskInstance/ClearTaskInstanceDialog.tsx @@ -95,7 +95,10 @@ const ClearTaskInstanceDialog = ({ onClose, open, taskInstance }: Props) => { <VStack align="start" gap={4}> <Heading size="xl"> <strong> - {translate("dags:runAndTaskActions.clear.dialog.title", { type: "Task Instance" })}: + {translate("dags:runAndTaskActions.clear.dialog.title", { + type: translate("taskInstance_one"), + })} + : </strong>{" "} {taskInstance.task_display_name} <Time datetime={taskInstance.start_date} /> </Heading> diff --git a/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx b/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx index b77262838bf..01db1ada889 100644 --- a/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/DeleteDialog.tsx @@ -55,7 +55,7 @@ const DeleteDialog: React.FC<DeleteDialogProps> = ({ <Dialog.CloseTrigger /> <Dialog.Body> <Text>{translate("modal.delete.confirmation", { resourceName })}</Text> - <Text color="red.500" fontWeight="bold" mt={4}> + <Text color="fg.error" fontWeight="bold" mt={4}> {warningText} </Text> </Dialog.Body> diff --git a/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsButton.tsx b/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsButton.tsx index 72e2c9a434a..aaff49bd35a 100644 --- a/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsButton.tsx @@ -64,10 +64,10 @@ const MarkRunAsButton = ({ dagRun, isHotkeyEnabled = false, withText = true }: P <Menu.Root positioning={{ gutter: 0, placement: "bottom" }}> <Menu.Trigger asChild> <ActionButton - actionName={translate("dags:runAndTaskActions.markAs.button", { type: "Run" })} + actionName={translate("dags:runAndTaskActions.markAs.button", { type: translate("dagRun_one") })} flexDirection="row-reverse" icon={<MdArrowDropDown />} - text={translate("dags:runAndTaskActions.markAs.button", { type: "Run" })} + text={translate("dags:runAndTaskActions.markAs.button", { type: translate("dagRun_one") })} withText={withText} /> </Menu.Trigger> diff --git a/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx b/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx index 48c4ac64fd7..c91f05d4e95 100644 --- a/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/MarkAs/Run/MarkRunAsDialog.tsx @@ -47,8 +47,11 @@ const MarkRunAsDialog = ({ dagRun, onClose, open, state }: Props) => { <Dialog.Header> <VStack align="start" gap={4}> <Heading size="xl"> - {translate("dags:runAndTaskActions.markAs.title", { state, type: "Run" })}: {dagRunId}{" "} - <StateBadge state={state} /> + {translate("dags:runAndTaskActions.markAs.title", { + state, + type: translate("dagRun_one"), + })} + : {dagRunId} <StateBadge state={state} /> </Heading> </VStack> </Dialog.Header> diff --git a/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsButton.tsx b/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsButton.tsx index f75607d5a3f..aa8ab4995c6 100644 --- a/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsButton.tsx +++ b/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsButton.tsx @@ -65,10 +65,12 @@ const MarkTaskInstanceAsButton = ({ isHotkeyEnabled = false, taskInstance, withT <Menu.Root positioning={{ gutter: 0, placement: "bottom" }}> <Menu.Trigger asChild> <ActionButton - actionName={translate("dags:runAndTaskActions.markAs.button", { type: "Task Instance" })} + actionName={translate("dags:runAndTaskActions.markAs.button", { + type: translate("taskInstance_one"), + })} flexDirection="row-reverse" icon={<MdArrowDropDown />} - text={translate("dags:runAndTaskActions.markAs.button", { type: "Task Instance" })} + text={translate("dags:runAndTaskActions.markAs.button", { type: translate("taskInstance_one") })} withText={withText} /> </Menu.Trigger> diff --git a/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsDialog.tsx b/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsDialog.tsx index 21ebb1d12a6..afde1862458 100644 --- a/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsDialog.tsx +++ b/airflow-core/src/airflow/ui/src/components/MarkAs/TaskInstance/MarkTaskInstanceAsDialog.tsx @@ -90,7 +90,11 @@ const MarkTaskInstanceAsDialog = ({ onClose, open, state, taskInstance }: Props) <VStack align="start" gap={4}> <Heading size="xl"> <strong> - {translate("dags:runAndTaskActions.markAs.title", { state, type: "Task Instance" })}: + {translate("dags:runAndTaskActions.markAs.title", { + state, + type: translate("taskInstance_one"), + })} + : </strong>{" "} {taskInstance.task_display_name} <Time datetime={taskInstance.start_date} />{" "} <StateBadge state={state} /> diff --git a/airflow-core/src/airflow/ui/src/i18n/locales/en/admin.json b/airflow-core/src/airflow/ui/src/i18n/locales/en/admin.json index c8684c15927..aeb93b92c76 100644 --- a/airflow-core/src/airflow/ui/src/i18n/locales/en/admin.json +++ b/airflow-core/src/airflow/ui/src/i18n/locales/en/admin.json @@ -19,6 +19,8 @@ "host": "Host", "port": "Port" }, + "connection_one": "Connection", + "connection_other": "Connections", "delete":{ "deleteConnection_one": "Delete 1 connection", "deleteConnection_other": "Delete {{count}} connections", @@ -40,7 +42,18 @@ "noRowMessage": "No connections found", "searchPlaceholder": "Search Connections", "test": "Test Connection", - "testDisabled": "Test connection feature is disabled. Please contact an administrator to enable it." + "testDisabled": "Test connection feature is disabled. Please contact an administrator to enable it.", + "typeMeta": { + "error": "Failed to retrieve Connection Type Meta", + "standardFields": { + "description": "Description", + "host": "Host", + "login": "Login", + "password": "Password", + "port": "Port", + "url_schema": "Schema" + } + } }, "deleteActions":{ "button": "Delete", @@ -81,6 +94,8 @@ "slots": "Slots" }, "noPoolsFound": "No pools found", + "pool_one": "Pool", + "pool_other": "Pools", "searchPlaceholder": "Search Pools", "sort": { "asc": "Name (A-Z)", @@ -139,6 +154,8 @@ "uploadPlaceholder": "Upload a JSON file containing variables (e.g., {\"key\": \"value\", ...})" }, "noRowsMessage": "No variables found", - "searchPlaceholder": "Search Keys" + "searchPlaceholder": "Search Keys", + "variable_one": "Variable", + "variable_other": "Variables" } } diff --git a/airflow-core/src/airflow/ui/src/i18n/locales/en/common.json b/airflow-core/src/airflow/ui/src/i18n/locales/en/common.json index 0cebcabf44a..6cebff264bd 100644 --- a/airflow-core/src/airflow/ui/src/i18n/locales/en/common.json +++ b/airflow-core/src/airflow/ui/src/i18n/locales/en/common.json @@ -223,6 +223,43 @@ "title": "Select Timezone", "utc": "UTC (Coordinated Universal Time)" }, + "toaster": { + "bulkDelete": { + "error": "Bulk Delete {{resourceName}} Request Failed", + "success": { + "description": "{{count}} {{resourceName}} have been successfully deleted. Keys: {{keys}}", + "title": "Bulk Delete {{resourceName}} Request Submitted" + } + }, + "create": { + "error": "Create {{resourceName}} Request Failed", + "success": { + "description": "{{resourceName}} has been successfully created.", + "title": "Create {{resourceName}} Request Submitted" + } + }, + "delete": { + "error": "Delete {{resourceName}} Request Failed", + "success": { + "description": "{{resourceName}} has been successfully deleted.", + "title": "Delete {{resourceName}} Request Submitted" + } + }, + "import": { + "error": "Import {{resourceName}} Request Failed", + "success": { + "description": "{{count}} {{resourceName}} have been successfully imported.", + "title": "Import {{resourceName}} Request Submitted" + } + }, + "update": { + "error": "Update {{resourceName}} Request Failed", + "success": { + "description": "{{resourceName}} has been successfully updated.", + "title": "Update {{resourceName}} Request Submitted" + } + } + }, "triggered": "Triggered", "tryNumber": "Try Number", "user": "User", diff --git a/airflow-core/src/airflow/ui/src/i18n/locales/en/components.json b/airflow-core/src/airflow/ui/src/i18n/locales/en/components.json index e1e5b3973df..1e48b630632 100644 --- a/airflow-core/src/airflow/ui/src/i18n/locales/en/components.json +++ b/airflow-core/src/airflow/ui/src/i18n/locales/en/components.json @@ -14,8 +14,18 @@ "selectDescription": "Run this Dag for a range of dates", "selectLabel": "Backfill", "title": "Run Backfill", + "toaster": { + "success": { + "description": "Backfill jobs have been successfully triggered.", + "title": "Backfill generated" + } + }, "tooltip": "Backfill requires a schedule", - "unpause": "Unpause {{dag_display_name}} on trigger" + "unpause": "Unpause {{dag_display_name}} on trigger", + "validation": { + "datesRequired": "Both Data Interval Start Date and End Date must be provided.", + "startBeforeEnd": "Data Interval Start Date must be less than or equal to Data Interval End Date." + } }, "banner": { "backfillInProgress": "Backfill in progress", @@ -95,6 +105,12 @@ "selectDescription": "Trigger a single run of this Dag", "selectLabel": "Single Run", "title": "Trigger Dag", + "toaster": { + "success": { + "description": "Dag run has been successfully triggered.", + "title": "Dag Run Triggered" + } + }, "unpause": "Unpause {{dagDisplayName}} on trigger" }, "trimText": { diff --git a/airflow-core/src/airflow/ui/src/i18n/locales/en/dag.json b/airflow-core/src/airflow/ui/src/i18n/locales/en/dag.json index 3c3cd336341..314a6861dbd 100644 --- a/airflow-core/src/airflow/ui/src/i18n/locales/en/dag.json +++ b/airflow-core/src/airflow/ui/src/i18n/locales/en/dag.json @@ -66,6 +66,19 @@ "label": "Graph Direction" } }, + "paramsFailed": "Failed to load params", + "parse": { + "toaster": { + "error": { + "description": "Dag parsing request failed. There could be pending parsing requests yet to be processed.", + "title": "Dag Failed to Reparse" + }, + "success": { + "description": "Dag should reparse soon.", + "title": "Reparsing request submitted successfully" + } + } + }, "tabs": { "assetEvents": "Asset Events", "auditLog": "Audit Log", diff --git a/airflow-core/src/airflow/ui/src/i18n/locales/en/dags.json b/airflow-core/src/airflow/ui/src/i18n/locales/en/dags.json index 75dc4d692b8..c804a985fb5 100644 --- a/airflow-core/src/airflow/ui/src/i18n/locales/en/dags.json +++ b/airflow-core/src/airflow/ui/src/i18n/locales/en/dags.json @@ -24,6 +24,7 @@ "clear": { "button": "Clear {{type}}", "buttonTooltip": "Press shift+c to clear", + "error": "Failed to clear {{type}}", "title": "Clear {{type}}" }, "delete": { diff --git a/airflow-core/src/airflow/ui/src/pages/DeleteRunButton.tsx b/airflow-core/src/airflow/ui/src/pages/DeleteRunButton.tsx index 175d1fabc56..1ecf39c991d 100644 --- a/airflow-core/src/airflow/ui/src/pages/DeleteRunButton.tsx +++ b/airflow-core/src/airflow/ui/src/pages/DeleteRunButton.tsx @@ -45,11 +45,11 @@ const DeleteRunButton = ({ dagRun, withText = true }: DeleteRunButtonProps) => { return ( <> <ActionButton - actionName={translate("dags:runAndTaskActions.delete.button", { type: "Run" })} + actionName={translate("dags:runAndTaskActions.delete.button", { type: translate("dagRun_one") })} colorPalette="red" icon={<FiTrash2 />} onClick={onOpen} - text={translate("dags:runAndTaskActions.delete.button", { type: "Run" })} + text={translate("dags:runAndTaskActions.delete.button", { type: translate("dagRun_one") })} variant="solid" withText={withText} /> @@ -66,10 +66,12 @@ const DeleteRunButton = ({ dagRun, withText = true }: DeleteRunButtonProps) => { open={open} resourceName={translate("dags:runAndTaskActions.delete.dialog.resourceName", { id: dagRun.dag_run_id, - type: "Run", + type: translate("dagRun_one"), + })} + title={translate("dags:runAndTaskActions.delete.dialog.title", { type: translate("dagRun_one") })} + warningText={translate("dags:runAndTaskActions.delete.dialog.warning", { + type: translate("dagRun_one"), })} - title={translate("dags:runAndTaskActions.delete.dialog.title", { type: "Run" })} - warningText={translate("dags:runAndTaskActions.delete.dialog.warning", { type: "Run" })} /> </> ); diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstances/DeleteTaskInstanceButton.tsx b/airflow-core/src/airflow/ui/src/pages/TaskInstances/DeleteTaskInstanceButton.tsx index c220b4f5f46..7759d8d628f 100644 --- a/airflow-core/src/airflow/ui/src/pages/TaskInstances/DeleteTaskInstanceButton.tsx +++ b/airflow-core/src/airflow/ui/src/pages/TaskInstances/DeleteTaskInstanceButton.tsx @@ -47,11 +47,13 @@ const DeleteTaskInstanceButton = ({ taskInstance, withText = true }: DeleteTaskI return ( <> <ActionButton - actionName={translate("dags:runAndTaskActions.delete.button", { type: "Task Instance" })} + actionName={translate("dags:runAndTaskActions.delete.button", { + type: translate("taskInstance_one"), + })} colorPalette="red" icon={<FiTrash2 />} onClick={onOpen} - text={translate("dags:runAndTaskActions.delete.button", { type: "Task Instance" })} + text={translate("dags:runAndTaskActions.delete.button", { type: translate("taskInstance_one") })} variant="solid" withText={withText} /> @@ -70,10 +72,14 @@ const DeleteTaskInstanceButton = ({ taskInstance, withText = true }: DeleteTaskI open={open} resourceName={translate("dags:runAndTaskActions.delete.dialog.resourceName", { id: taskInstance.task_id, - type: "Task Instance", + type: translate("taskInstance_one"), + })} + title={translate("dags:runAndTaskActions.delete.dialog.title", { + type: translate("taskInstance_one"), + })} + warningText={translate("dags:runAndTaskActions.delete.dialog.warning", { + type: translate("taskInstance_one"), })} - title={translate("dags:runAndTaskActions.delete.dialog.title", { type: "Task Instance" })} - warningText={translate("dags:runAndTaskActions.delete.dialog.warning", { type: "Task Instance" })} /> </> ); diff --git a/airflow-core/src/airflow/ui/src/queries/useAddConnection.ts b/airflow-core/src/airflow/ui/src/queries/useAddConnection.ts index 24aa2715883..f5c9bc1f8a5 100644 --- a/airflow-core/src/airflow/ui/src/queries/useAddConnection.ts +++ b/airflow-core/src/airflow/ui/src/queries/useAddConnection.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useConnectionServiceGetConnectionsKey, useConnectionServicePostConnection } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -26,6 +27,7 @@ import type { ConnectionBody } from "src/pages/Connections/Connections"; export const useAddConnection = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -33,8 +35,13 @@ export const useAddConnection = ({ onSuccessConfirm }: { onSuccessConfirm: () => }); toaster.create({ - description: "Connection has been added successfully", - title: "Connection Add Request Submitted", + description: translate("toaster.success.description", { + resourceName: translate("admin:connections.connection_one"), + }), + title: translate("toaster.success.title", { + action: translate("toaster.create"), + resourceName: translate("admin:connections.connection_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useAddPool.ts b/airflow-core/src/airflow/ui/src/queries/useAddPool.ts index 31d8e98986a..e96085bc565 100644 --- a/airflow-core/src/airflow/ui/src/queries/useAddPool.ts +++ b/airflow-core/src/airflow/ui/src/queries/useAddPool.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { usePoolServiceGetPoolsKey, usePoolServicePostPool } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -26,15 +27,19 @@ import type { PoolBody } from "src/pages/Pools/PoolForm"; export const useAddPool = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); - + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async () => { await queryClient.invalidateQueries({ queryKey: [usePoolServiceGetPoolsKey], }); toaster.create({ - description: "Pool has been added successfully", - title: "Pool Add Request Submitted", + description: translate("toaster.create.success.description", { + resourceName: translate("admin:pools.pool_one"), + }), + title: translate("toaster.create.success.title", { + resourceName: translate("admin:pools.pool_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useAddVariable.ts b/airflow-core/src/airflow/ui/src/queries/useAddVariable.ts index acc88788248..07248b27617 100644 --- a/airflow-core/src/airflow/ui/src/queries/useAddVariable.ts +++ b/airflow-core/src/airflow/ui/src/queries/useAddVariable.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useVariableServiceGetVariablesKey, useVariableServicePostVariable } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -26,15 +27,19 @@ import type { VariableBody } from "src/pages/Variables/ManageVariable/VariableFo export const useAddVariable = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); - + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async () => { await queryClient.invalidateQueries({ queryKey: [useVariableServiceGetVariablesKey], }); toaster.create({ - description: "Variable has been added successfully", - title: "Variable Add Request Submitted", + description: translate("toaster.create.success.description", { + resourceName: translate("admin:variables.variable_one"), + }), + title: translate("toaster.create.success.title", { + resourceName: translate("admin:variables.variable_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useBulkDeleteConnections.tsx b/airflow-core/src/airflow/ui/src/queries/useBulkDeleteConnections.tsx index f2cd7d7361a..d56f8e0fa0b 100644 --- a/airflow-core/src/airflow/ui/src/queries/useBulkDeleteConnections.tsx +++ b/airflow-core/src/airflow/ui/src/queries/useBulkDeleteConnections.tsx @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useConnectionServiceBulkConnections, useConnectionServiceGetConnectionsKey } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -30,6 +31,7 @@ type Props = { export const useBulkDeleteConnections = ({ clearSelections, onSuccessConfirm }: Props) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async (responseData: { delete?: { errors: Array<unknown>; success: Array<string> } }) => { await queryClient.invalidateQueries({ @@ -47,8 +49,12 @@ export const useBulkDeleteConnections = ({ clearSelections, onSuccessConfirm }: }); } else if (Array.isArray(success) && success.length > 0) { toaster.create({ - description: `${success.length} variables deleted successfully. Keys: ${success.join(", ")}`, - title: "Delete Variables Request Successful", + description: translate("toaster.bulkDelete.success.description", { + count: success.length, + keys: success.join(", "), + resourceName: translate("admin:connections.connection_other"), + }), + title: translate("toaster.bulkDelete.success.title"), type: "success", }); clearSelections(); diff --git a/airflow-core/src/airflow/ui/src/queries/useBulkDeleteVariables.ts b/airflow-core/src/airflow/ui/src/queries/useBulkDeleteVariables.ts index 7fa1447436d..dd197a237bc 100644 --- a/airflow-core/src/airflow/ui/src/queries/useBulkDeleteVariables.ts +++ b/airflow-core/src/airflow/ui/src/queries/useBulkDeleteVariables.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useVariableServiceBulkVariables, useVariableServiceGetVariablesKey } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -30,6 +31,7 @@ type Props = { export const useBulkDeleteVariables = ({ clearSelections, onSuccessConfirm }: Props) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async (responseData: { delete?: { errors: Array<unknown>; success: Array<string> } }) => { await queryClient.invalidateQueries({ @@ -47,8 +49,12 @@ export const useBulkDeleteVariables = ({ clearSelections, onSuccessConfirm }: Pr }); } else if (Array.isArray(success) && success.length > 0) { toaster.create({ - description: `${success.length} variables deleted successfully. Keys: ${success.join(", ")}`, - title: "Delete Variables Request Successful", + description: translate("toaster.bulkDelete.success.description", { + count: success.length, + keys: success.join(", "), + resourceName: translate("admin:variables.variable_other"), + }), + title: translate("toaster.bulkDelete.success.title"), type: "success", }); clearSelections(); diff --git a/airflow-core/src/airflow/ui/src/queries/useClearRun.ts b/airflow-core/src/airflow/ui/src/queries/useClearRun.ts index 1c7a80d2a99..2fe1dd10478 100644 --- a/airflow-core/src/airflow/ui/src/queries/useClearRun.ts +++ b/airflow-core/src/airflow/ui/src/queries/useClearRun.ts @@ -17,6 +17,7 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { useDagRunServiceClearDagRun, @@ -30,14 +31,6 @@ import { toaster } from "src/components/ui"; import { useClearDagRunDryRunKey } from "./useClearDagRunDryRun"; -const onError = () => { - toaster.create({ - description: "Clear Dag Run request failed", - title: "Failed to clear the Dag Run", - type: "error", - }); -}; - export const useClearDagRun = ({ dagId, dagRunId, @@ -48,6 +41,15 @@ export const useClearDagRun = ({ onSuccessConfirm: () => void; }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation("dags"); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("dags:runAndTaskActions.clear.error", { type: translate("dagRun_one") }), + type: "error", + }); + }; const onSuccess = async () => { const queryKeys = [ diff --git a/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts b/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts index 205f6faa072..b4e8f38c05b 100644 --- a/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts +++ b/airflow-core/src/airflow/ui/src/queries/useClearTaskInstances.ts @@ -17,6 +17,7 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { UseDagRunServiceGetDagRunKeyFn, @@ -31,14 +32,6 @@ import { toaster } from "src/components/ui"; import { useClearTaskInstancesDryRunKey } from "./useClearTaskInstancesDryRun"; import { usePatchTaskInstanceDryRunKey } from "./usePatchTaskInstanceDryRun"; -const onError = () => { - toaster.create({ - description: "Clear Task Instance request failed", - title: "Failed to clear the Task Instance", - type: "error", - }); -}; - export const useClearTaskInstances = ({ dagId, dagRunId, @@ -49,6 +42,15 @@ export const useClearTaskInstances = ({ onSuccessConfirm: () => void; }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation("dags"); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("dags:runAndTaskActions.clear.error", { type: translate("taskInstance_one") }), + type: "error", + }); + }; const onSuccess = async ( _: TaskInstanceCollectionResponse, diff --git a/airflow-core/src/airflow/ui/src/queries/useConnectionTypeMeta.ts b/airflow-core/src/airflow/ui/src/queries/useConnectionTypeMeta.ts index 5f6f5c88267..f24f2d303a4 100644 --- a/airflow-core/src/airflow/ui/src/queries/useConnectionTypeMeta.ts +++ b/airflow-core/src/airflow/ui/src/queries/useConnectionTypeMeta.ts @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import { useTranslation } from "react-i18next"; + import { useConnectionServiceHookMetaData } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -41,6 +43,7 @@ export type ConnectionMetaEntry = { type ConnectionMeta = Array<ConnectionMetaEntry>; export const useConnectionTypeMeta = () => { + const { t: translate } = useTranslation("admin"); const { data, error, isPending }: { data?: ConnectionMeta; error?: unknown; isPending: boolean } = useConnectionServiceHookMetaData(); @@ -51,8 +54,8 @@ export const useConnectionTypeMeta = () => { : String(Boolean(error) ? error : ""); // Convert other types (e.g., numbers, strings) to string toaster.create({ - description: `Connection Type Meta request failed. Error: ${errorDescription}`, - title: "Failed to retrieve Connection Type Meta", + description: errorDescription, + title: translate("admin:connections.typeMeta.error"), type: "error", }); } @@ -62,12 +65,36 @@ export const useConnectionTypeMeta = () => { const keysList: Array<string> = []; const defaultStandardFields: StandardFieldSpec | undefined = { - description: { hidden: false, placeholder: undefined, title: "Description" }, - host: { hidden: false, placeholder: undefined, title: "Host" }, - login: { hidden: false, placeholder: undefined, title: "Login" }, - password: { hidden: false, placeholder: undefined, title: "Password" }, - port: { hidden: false, placeholder: undefined, title: "Port" }, - url_schema: { hidden: false, placeholder: undefined, title: "Schema" }, + description: { + hidden: false, + placeholder: undefined, + title: translate("admin:connections.typeMeta.standardFields.description"), + }, + host: { + hidden: false, + placeholder: undefined, + title: translate("admin:connections.typeMeta.standardFields.host"), + }, + login: { + hidden: false, + placeholder: undefined, + title: translate("admin:connections.typeMeta.standardFields.login"), + }, + password: { + hidden: false, + placeholder: undefined, + title: translate("admin:connections.typeMeta.standardFields.password"), + }, + port: { + hidden: false, + placeholder: undefined, + title: translate("admin:connections.typeMeta.standardFields.port"), + }, + url_schema: { + hidden: false, + placeholder: undefined, + title: translate("admin:connections.typeMeta.standardFields.url_schema"), + }, }; const mergeWithDefaults = ( diff --git a/airflow-core/src/airflow/ui/src/queries/useCreateBackfill.ts b/airflow-core/src/airflow/ui/src/queries/useCreateBackfill.ts index faebe834a16..673f7d5a82d 100644 --- a/airflow-core/src/airflow/ui/src/queries/useCreateBackfill.ts +++ b/airflow-core/src/airflow/ui/src/queries/useCreateBackfill.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useBackfillServiceCreateBackfill, useBackfillServiceListBackfillsUiKey } from "openapi/queries"; import type { CreateBackfillData } from "openapi/requests/types.gen"; @@ -27,14 +28,15 @@ export const useCreateBackfill = ({ onSuccessConfirm }: { onSuccessConfirm: () = const [dateValidationError, setDateValidationError] = useState<unknown>(undefined); const [error, setError] = useState<unknown>(undefined); const queryClient = useQueryClient(); + const { t: translate } = useTranslation("components"); const onSuccess = async () => { await queryClient.invalidateQueries({ queryKey: [useBackfillServiceListBackfillsUiKey], }); toaster.create({ - description: "Backfill jobs have been successfully triggered.", - title: "Backfill generated", + description: translate("backfill.toaster.success.description"), + title: translate("backfill.toaster.success.title"), type: "success", }); onSuccessConfirm(); @@ -50,7 +52,7 @@ export const useCreateBackfill = ({ onSuccessConfirm }: { onSuccessConfirm: () = if (data.requestBody.from_date === "" || data.requestBody.to_date === "") { setDateValidationError({ body: { - detail: "Both Data Interval Start Date and End Date must be provided.", + detail: translate("backfill.validation.datesRequired"), }, }); @@ -64,7 +66,7 @@ export const useCreateBackfill = ({ onSuccessConfirm }: { onSuccessConfirm: () = if (dataIntervalStart > dataIntervalEnd) { setDateValidationError({ body: { - detail: "Data Interval Start Date must be less than or equal to Data Interval End Date.", + detail: translate("backfill.validation.startBeforeEnd"), }, }); diff --git a/airflow-core/src/airflow/ui/src/queries/useDagParams.ts b/airflow-core/src/airflow/ui/src/queries/useDagParams.ts index 64a7f0915af..798ed692b97 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDagParams.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDagParams.ts @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import { useTranslation } from "react-i18next"; + import { useDagServiceGetDagDetails } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -46,6 +48,7 @@ export type ParamSchema = { }; export const useDagParams = (dagId: string, open: boolean) => { + const { t: translate } = useTranslation("dag"); const { data, error }: { data?: Record<string, ParamsSpec>; error?: unknown } = useDagServiceGetDagDetails( { dagId }, undefined, @@ -61,8 +64,8 @@ export const useDagParams = (dagId: string, open: boolean) => { : String(Boolean(error) ? error : ""); // Convert other types (e.g., numbers, strings) to string toaster.create({ - description: `Dag params request failed. Error: ${errorDescription}`, - title: "Getting Dag Params Failed", + description: errorDescription, + title: translate("paramsFailed"), type: "error", }); } diff --git a/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts b/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts index 0ddab03c69a..914799dfc54 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts @@ -17,6 +17,7 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { useDagParsingServiceReparseDagFile, @@ -25,16 +26,17 @@ import { } from "openapi/queries"; import { toaster } from "src/components/ui"; -const onError = () => { - toaster.create({ - description: "Dag parsing request failed. There could be pending parsing requests yet to be processed.", - title: "Dag Failed to Reparse", - type: "error", - }); -}; - export const useDagParsing = ({ dagId }: { readonly dagId: string }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation("dag"); + + const onError = () => { + toaster.create({ + description: translate("parse.toaster.error.description"), + title: translate("parse.toaster.error.title"), + type: "error", + }); + }; const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -46,8 +48,8 @@ export const useDagParsing = ({ dagId }: { readonly dagId: string }) => { }); toaster.create({ - description: "Dag should reparse soon.", - title: "Reparsing request submitted successfully", + description: translate("parse.toaster.success.description"), + title: translate("parse.toaster.success.title"), type: "success", }); }; diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteConnection.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteConnection.ts index 9f2f82b3d9b..c7823e9e302 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteConnection.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteConnection.ts @@ -17,20 +17,24 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { useConnectionServiceDeleteConnection, useConnectionServiceGetConnectionsKey } from "openapi/queries"; import { toaster } from "src/components/ui"; -const onError = () => { - toaster.create({ - description: "Delete connection request failed.", - title: "Failed to delete the connection", - type: "error", - }); -}; - export const useDeleteConnection = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation("admin"); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("toaster.delete.error.title", { + resourceName: translate("admin:connections.connection_one"), + }), + type: "error", + }); + }; const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -38,8 +42,12 @@ export const useDeleteConnection = ({ onSuccessConfirm }: { onSuccessConfirm: () }); toaster.create({ - description: "The connection deletion request was successful.", - title: "Connection Deleted Successfully", + description: translate("toaster.delete.success.description", { + resourceName: translate("admin:connections.connection_one"), + }), + title: translate("toaster.delete.success.title", { + resourceName: translate("admin:connections.connection_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteDag.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteDag.ts index 0de86a85357..6d4c4399f19 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteDag.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteDag.ts @@ -17,19 +17,12 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { useDagServiceDeleteDag } from "openapi/queries"; import { useDagServiceGetDagKey } from "openapi/queries"; import { toaster } from "src/components/ui"; -const onError = () => { - toaster.create({ - description: "Delete DAG request failed", - title: "Failed to delete DAG", - type: "error", - }); -}; - export const useDeleteDag = ({ dagId, onSuccessConfirm, @@ -38,6 +31,17 @@ export const useDeleteDag = ({ onSuccessConfirm: () => void; }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation(); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("toaster.delete.error.title", { + resourceName: translate("dag_one"), + }), + type: "error", + }); + }; const onSuccess = async () => { const queryKeys = [[useDagServiceGetDagKey, { dagId }]]; @@ -45,8 +49,12 @@ export const useDeleteDag = ({ await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); toaster.create({ - description: "The DAG deletion request was successful.", - title: "DAG Deleted Successfully", + description: translate("toaster.delete.success.description", { + resourceName: translate("dag_one"), + }), + title: translate("toaster.delete.success.title", { + resourceName: translate("dag_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts index c9120e66b73..7f5c9e670ea 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteDagRun.ts @@ -40,7 +40,7 @@ export const useDeleteDagRun = ({ dagId, dagRunId, onSuccessConfirm }: DeleteDag const onError = (error: Error) => { toaster.create({ description: error.message, - title: translate("dags:runAndTaskActions.delete.error", { type: "Run" }), + title: translate("dags:runAndTaskActions.delete.error", { type: translate("dagRun_one") }), type: "error", }); }; @@ -55,8 +55,10 @@ export const useDeleteDagRun = ({ dagId, dagRunId, onSuccessConfirm }: DeleteDag await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); toaster.create({ - description: translate("dags:runAndTaskActions.delete.success.description", { type: "Run" }), - title: translate("dags:runAndTaskActions.delete.success.title", { type: "Run" }), + description: translate("dags:runAndTaskActions.delete.success.description", { + type: translate("dagRun_one"), + }), + title: translate("dags:runAndTaskActions.delete.success.title", { type: translate("dagRun_one") }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeletePool.ts b/airflow-core/src/airflow/ui/src/queries/useDeletePool.ts index f12f1921bb8..bf5fbbbffe9 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeletePool.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeletePool.ts @@ -17,20 +17,24 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { usePoolServiceDeletePool, usePoolServiceGetPoolsKey } from "openapi/queries"; import { toaster } from "src/components/ui"; -const onError = () => { - toaster.create({ - description: "Delete pool request failed.", - title: "Failed to delete the pool", - type: "error", - }); -}; - export const useDeletePool = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation(["common", "admin"]); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("toaster.delete.error.title", { + resourceName: translate("admin:pools.pool_one"), + }), + type: "error", + }); + }; const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -38,8 +42,12 @@ export const useDeletePool = ({ onSuccessConfirm }: { onSuccessConfirm: () => vo }); toaster.create({ - description: "The pool deletion request was successful.", - title: "Pool Deleted Successfully", + description: translate("toaster.delete.success.description", { + resourceName: translate("admin:pools.pool_one"), + }), + title: translate("toaster.delete.success.title", { + resourceName: translate("admin:pools.pool_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts index f43133a3c6a..cf84f7cc068 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteTaskInstance.ts @@ -45,12 +45,12 @@ export const useDeleteTaskInstance = ({ taskId, }: DeleteTaskInstanceParams) => { const queryClient = useQueryClient(); - const { t: translate } = useTranslation(); + const { t: translate } = useTranslation(["common", "dags"]); const onError = (error: Error) => { toaster.create({ description: error.message, - title: translate("dags:runAndTaskActions.delete.error", { type: "Task Instance" }), + title: translate("dags:runAndTaskActions.delete.error", { type: translate("taskInstance_one") }), type: "error", }); }; @@ -67,8 +67,12 @@ export const useDeleteTaskInstance = ({ await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); toaster.create({ - description: translate("dags:runAndTaskActions.delete.success.description", { type: "Task Instance" }), - title: translate("dags:runAndTaskActions.delete.success.title", { type: "Task Instance" }), + description: translate("dags:runAndTaskActions.delete.success.description", { + type: translate("taskInstance_one"), + }), + title: translate("dags:runAndTaskActions.delete.success.title", { + type: translate("taskInstance_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useDeleteVariable.ts b/airflow-core/src/airflow/ui/src/queries/useDeleteVariable.ts index 10b3abb7c6f..c07681679fe 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDeleteVariable.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDeleteVariable.ts @@ -17,20 +17,24 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { useVariableServiceDeleteVariable, useVariableServiceGetVariablesKey } from "openapi/queries"; import { toaster } from "src/components/ui"; -const onError = () => { - toaster.create({ - description: "Delete variable request failed.", - title: "Failed to delete the variable", - type: "error", - }); -}; - export const useDeleteVariable = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation(["common", "admin"]); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("toaster.delete.error.title", { + resourceName: translate("admin:variables.variable_one"), + }), + type: "error", + }); + }; const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -38,8 +42,12 @@ export const useDeleteVariable = ({ onSuccessConfirm }: { onSuccessConfirm: () = }); toaster.create({ - description: "The variable key deletion request was successful.", - title: "Variable Deleted Successfully", + description: translate("toaster.delete.success.description", { + resourceName: translate("admin:variables.variable_one"), + }), + title: translate("toaster.delete.success.title", { + resourceName: translate("admin:variables.variable_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useEditConnection.tsx b/airflow-core/src/airflow/ui/src/queries/useEditConnection.tsx index 6f7face3a32..60c813aa644 100644 --- a/airflow-core/src/airflow/ui/src/queries/useEditConnection.tsx +++ b/airflow-core/src/airflow/ui/src/queries/useEditConnection.tsx @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useConnectionServiceGetConnectionsKey, useConnectionServicePatchConnection } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -33,15 +34,19 @@ export const useEditConnection = ( ) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); - + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async () => { await queryClient.invalidateQueries({ queryKey: [useConnectionServiceGetConnectionsKey], }); toaster.create({ - description: "Connection has been edited successfully", - title: "Connection Edit Request Submitted", + description: translate("toaster.edit.success.description", { + resourceName: translate("admin:connections.connection_one"), + }), + title: translate("toaster.edit.success.title", { + resourceName: translate("admin:connections.connection_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useEditPool.ts b/airflow-core/src/airflow/ui/src/queries/useEditPool.ts index 402bba155f5..6cafe2b696e 100644 --- a/airflow-core/src/airflow/ui/src/queries/useEditPool.ts +++ b/airflow-core/src/airflow/ui/src/queries/useEditPool.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { usePoolServiceGetPoolsKey, usePoolServicePatchPool } from "openapi/queries"; import type { PoolBody } from "openapi/requests/types.gen"; @@ -33,6 +34,7 @@ export const useEditPool = ( ) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -40,8 +42,12 @@ export const useEditPool = ( }); toaster.create({ - description: "Pool has been edited successfully", - title: "Pool Edit Request Submitted", + description: translate("toaster.update.success.description", { + resourceName: translate("admin:pools.pool_one"), + }), + title: translate("toaster.update.success.title", { + resourceName: translate("admin:pools.pool_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useEditVariable.ts b/airflow-core/src/airflow/ui/src/queries/useEditVariable.ts index befdeab0d53..e02501cc6a8 100644 --- a/airflow-core/src/airflow/ui/src/queries/useEditVariable.ts +++ b/airflow-core/src/airflow/ui/src/queries/useEditVariable.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useVariableServiceGetVariablesKey, useVariableServicePatchVariable } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -33,6 +34,7 @@ export const useEditVariable = ( ) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async () => { await queryClient.invalidateQueries({ @@ -40,8 +42,12 @@ export const useEditVariable = ( }); toaster.create({ - description: "Variable has been edited successfully", - title: "Variable Edit Request Submitted", + description: translate("toaster.edit.success.description", { + resourceName: translate("admin:variables.variable_one"), + }), + title: translate("toaster.edit.success.title", { + resourceName: translate("admin:variables.variable_one"), + }), type: "success", }); diff --git a/airflow-core/src/airflow/ui/src/queries/useImportVariables.ts b/airflow-core/src/airflow/ui/src/queries/useImportVariables.ts index 212d9c83e19..64f608ac027 100644 --- a/airflow-core/src/airflow/ui/src/queries/useImportVariables.ts +++ b/airflow-core/src/airflow/ui/src/queries/useImportVariables.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { useVariableServiceBulkVariables, useVariableServiceGetVariablesKey } from "openapi/queries"; import { toaster } from "src/components/ui"; @@ -25,6 +26,7 @@ import { toaster } from "src/components/ui"; export const useImportVariables = ({ onSuccessConfirm }: { onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); + const { t: translate } = useTranslation(["common", "admin"]); const onSuccess = async (responseData: { create?: { errors: Array<unknown>; success: Array<string> } }) => { await queryClient.invalidateQueries({ @@ -42,8 +44,14 @@ export const useImportVariables = ({ onSuccessConfirm }: { onSuccessConfirm: () }); } else if (Array.isArray(success) && success.length > 0) { toaster.create({ - description: `${success.length} variables created successfully. Keys: ${success.join(", ")}`, - title: "Import Variables Request Successful", + description: translate("toaster.import.success.description", { + count: success.length, + keys: success.join(", "), + resourceName: translate("admin:variables.variable_other"), + }), + title: translate("toaster.import.success.title", { + resourceName: translate("admin:variables.variable_other"), + }), type: "success", }); onSuccessConfirm(); diff --git a/airflow-core/src/airflow/ui/src/queries/usePatchDagRun.ts b/airflow-core/src/airflow/ui/src/queries/usePatchDagRun.ts index 6ca008b6dc1..f7f37c33a95 100644 --- a/airflow-core/src/airflow/ui/src/queries/usePatchDagRun.ts +++ b/airflow-core/src/airflow/ui/src/queries/usePatchDagRun.ts @@ -17,6 +17,7 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { UseDagRunServiceGetDagRunKeyFn, @@ -29,14 +30,6 @@ import { toaster } from "src/components/ui"; import { useClearDagRunDryRunKey } from "./useClearDagRunDryRun"; -const onError = () => { - toaster.create({ - description: "Patch Dag Run request failed", - title: "Failed to patch the Dag Run", - type: "error", - }); -}; - export const usePatchDagRun = ({ dagId, dagRunId, @@ -47,6 +40,17 @@ export const usePatchDagRun = ({ onSuccess?: () => void; }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation(); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("toaster.update.error.title", { + resourceName: translate("dagRun_one"), + }), + type: "error", + }); + }; const onSuccessFn = async () => { const queryKeys = [ diff --git a/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts b/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts index 8cd6a7c36cb..fc99136c457 100644 --- a/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts +++ b/airflow-core/src/airflow/ui/src/queries/usePatchTaskInstance.ts @@ -17,6 +17,7 @@ * under the License. */ import { useQueryClient } from "@tanstack/react-query"; +import { useTranslation } from "react-i18next"; import { UseGridServiceGridDataKeyFn, @@ -30,14 +31,6 @@ import { toaster } from "src/components/ui"; import { useClearTaskInstancesDryRunKey } from "./useClearTaskInstancesDryRun"; import { usePatchTaskInstanceDryRunKey } from "./usePatchTaskInstanceDryRun"; -const onError = () => { - toaster.create({ - description: "Patch Task Instance request failed", - title: "Failed to patch the Task Instance", - type: "error", - }); -}; - export const usePatchTaskInstance = ({ dagId, dagRunId, @@ -52,6 +45,17 @@ export const usePatchTaskInstance = ({ taskId: string; }) => { const queryClient = useQueryClient(); + const { t: translate } = useTranslation(); + + const onError = (error: Error) => { + toaster.create({ + description: error.message, + title: translate("toaster.update.error.title", { + resourceName: translate("taskInstance_one"), + }), + type: "error", + }); + }; const onSuccessFn = async () => { const queryKeys = [ diff --git a/airflow-core/src/airflow/ui/src/queries/useTrigger.ts b/airflow-core/src/airflow/ui/src/queries/useTrigger.ts index 27f27df1058..3009ecbfc81 100644 --- a/airflow-core/src/airflow/ui/src/queries/useTrigger.ts +++ b/airflow-core/src/airflow/ui/src/queries/useTrigger.ts @@ -18,6 +18,7 @@ */ import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { UseDagRunServiceGetDagRunsKeyFn, @@ -32,7 +33,7 @@ import { toaster } from "src/components/ui"; export const useTrigger = ({ dagId, onSuccessConfirm }: { dagId: string; onSuccessConfirm: () => void }) => { const queryClient = useQueryClient(); const [error, setError] = useState<unknown>(undefined); - + const { t: translate } = useTranslation("components"); const onSuccess = async () => { const queryKeys = [ [useDagServiceGetDagsUiKey], @@ -44,8 +45,8 @@ export const useTrigger = ({ dagId, onSuccessConfirm }: { dagId: string; onSucce await Promise.all(queryKeys.map((key) => queryClient.invalidateQueries({ queryKey: key }))); toaster.create({ - description: "DAG run has been successfully triggered.", - title: "DAG Run Request Submitted", + description: translate("triggerDag.toaster.success.description"), + title: translate("triggerDag.toaster.success.title"), type: "success", }); onSuccessConfirm();