This is an automated email from the ASF dual-hosted git repository. kaxilnaik pushed a commit to branch v3-0-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit cae60348d192d205f6a3d18d4c41b0195996a2c6 Author: Brent Bovenzi <[email protected]> AuthorDate: Fri May 2 17:25:23 2025 -0400 Add TIs tab to mapped task details (#50085) * Add TIs tab to mapped task details * Adjust Tab title to total mapped count (cherry picked from commit b11895dcd39d0f33a91c4294d31665e0a862b60a) --- .../MappedTaskInstance/MappedTaskInstance.tsx | 6 ++- .../ui/src/pages/TaskInstance/TaskInstance.tsx | 43 ++++++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/MappedTaskInstance.tsx b/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/MappedTaskInstance.tsx index 770c6e9348d..9225610bc24 100644 --- a/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/MappedTaskInstance.tsx +++ b/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/MappedTaskInstance.tsx @@ -30,8 +30,6 @@ import { isStatePending, useAutoRefresh } from "src/utils"; import { Header } from "./Header"; -const tabs = [{ icon: <MdOutlineTask />, label: "Task Instances", value: "" }]; - export const MappedTaskInstance = () => { const { dagId = "", runId = "", taskId = "" } = useParams(); const refetchInterval = useAutoRefresh({ dagId }); @@ -74,6 +72,10 @@ export const MappedTaskInstance = () => { .find((dr) => dr.dag_run_id === runId) ?.task_instances.find((ti) => ti.task_id === taskId); + const tabs = [ + { icon: <MdOutlineTask />, label: `Task Instances [${taskInstance?.task_count}]`, value: "" }, + ]; + return ( <ReactFlowProvider> <DetailsLayout dag={dag} error={error ?? dagError} isLoading={isLoading || isDagLoading} tabs={tabs}> diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx index f6993b87b27..8e19e7dbec2 100644 --- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx +++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx @@ -18,11 +18,15 @@ */ import { ReactFlowProvider } from "@xyflow/react"; import { FiCode } from "react-icons/fi"; -import { MdDetails, MdOutlineEventNote, MdReorder, MdSyncAlt } from "react-icons/md"; +import { MdDetails, MdOutlineEventNote, MdOutlineTask, MdReorder, MdSyncAlt } from "react-icons/md"; import { PiBracketsCurlyBold } from "react-icons/pi"; import { useParams } from "react-router-dom"; -import { useDagServiceGetDagDetails, useTaskInstanceServiceGetMappedTaskInstance } from "openapi/queries"; +import { + useDagServiceGetDagDetails, + useGridServiceGridData, + useTaskInstanceServiceGetMappedTaskInstance, +} from "openapi/queries"; import { DetailsLayout } from "src/layouts/Details/DetailsLayout"; import { isStatePending, useAutoRefresh } from "src/utils"; @@ -67,9 +71,42 @@ export const TaskInstance = () => { }, ); + // Filter grid data to get only a single dag run + const { data } = useGridServiceGridData( + { + dagId, + limit: 1, + offset: 0, + runAfterGte: taskInstance?.run_after, + runAfterLte: taskInstance?.run_after, + }, + undefined, + { + enabled: taskInstance !== undefined, + }, + ); + + const mappedTaskInstance = data?.dag_runs + .find((dr) => dr.dag_run_id === runId) + ?.task_instances.find((ti) => ti.task_id === taskId); + + let newTabs = tabs; + + if (taskInstance && taskInstance.map_index > -1) { + newTabs = [ + ...tabs.slice(0, 1), + { + icon: <MdOutlineTask />, + label: `Task Instances [${mappedTaskInstance?.task_count ?? ""}]`, + value: "task_instances", + }, + ...tabs.slice(1), + ]; + } + return ( <ReactFlowProvider> - <DetailsLayout dag={dag} error={error ?? dagError} isLoading={isLoading || isDagLoading} tabs={tabs}> + <DetailsLayout dag={dag} error={error ?? dagError} isLoading={isLoading || isDagLoading} tabs={newTabs}> {taskInstance === undefined ? undefined : ( <Header isRefreshing={Boolean(isStatePending(taskInstance.state) && Boolean(refetchInterval))}
