This is an automated email from the ASF dual-hosted git repository.

bbovenzi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-1-test by this push:
     new 28415802c57 [v3-1-test] fix: Enable real-time extra links updates for 
TriggerDagRunOperator (#59507) (#60225)
28415802c57 is described below

commit 28415802c571442813d81d07345926192a48a01f
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jan 7 11:47:47 2026 -0500

    [v3-1-test] fix: Enable real-time extra links updates for 
TriggerDagRunOperator (#59507) (#60225)
    
    * fix: Enable real-time extra links updates for TriggerDagRunOperator
    
    - Add smart polling to ExtraLinks component using useAutoRefresh hook
    - Poll automatically when DAG is active and links are not yet available
    - Stop polling once extra links appear to reduce server load
    - Respects global auto_refresh_interval config and DAG paused state
    - Fixes issue where Triggered DAG button only appeared after manual refresh
    
    Closes #58928
    
    * fix: prevent infinite polling for tasks without extra links
    
    - Add task metadata check using useTaskServiceGetTask
    - Only poll if task.extra_links.length > 0
    - Conditionally render ExtraLinks component in Details.tsx
    - Prevents unnecessary API calls for tasks without extra links
    
    Addresses review feedback from @bbovenzi
    
    * refactor: reuse parent refetchInterval pattern in child components
    
    - Pass parent's refetchInterval to ExtraLinks and BlockingDeps components
    - Remove duplicate useAutoRefresh and useTaskServiceGetTask calls
    - Eliminate invalid taskInstance.extra_links property access (doesn't exist 
on TaskInstanceResponse)
    - Polling now tied to try instance pending state - stops automatically when 
task completes
    - Simplifies architecture by centralizing refresh logic in parent component
    
    Addresses review feedback from @pierrejeambrun and @bbovenzi
    
    * style: apply pre-commit hook formatting fixes
    
    - Reorder type union to alphabetical order (number | false)
    - Format ExtraLinks component to single line
    (cherry picked from commit 2768fba69549cb4030af8ce97c675ef893433017)
    
    Co-authored-by: subhash-0000 
<[email protected]>
---
 .../ui/src/pages/TaskInstance/BlockingDeps.tsx     | 25 ++++++++++++++++------
 .../airflow/ui/src/pages/TaskInstance/Details.tsx  |  7 ++++--
 .../ui/src/pages/TaskInstance/ExtraLinks.tsx       | 24 +++++++++++++++------
 3 files changed, 40 insertions(+), 16 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/pages/TaskInstance/BlockingDeps.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/BlockingDeps.tsx
index 2ed76613df7..fed7908b6ab 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/BlockingDeps.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/BlockingDeps.tsx
@@ -22,14 +22,25 @@ import { useTranslation } from "react-i18next";
 import { useTaskInstanceServiceGetTaskInstanceDependencies } from 
"openapi/queries";
 import type { TaskInstanceResponse } from "openapi/requests/types.gen";
 
-export const BlockingDeps = ({ taskInstance }: { readonly taskInstance: 
TaskInstanceResponse }) => {
+type BlockingDepsProps = {
+  readonly refetchInterval: number | false;
+  readonly taskInstance: TaskInstanceResponse;
+};
+
+export const BlockingDeps = ({ refetchInterval, taskInstance }: 
BlockingDepsProps) => {
   const { t: translate } = useTranslation();
-  const { data } = useTaskInstanceServiceGetTaskInstanceDependencies({
-    dagId: taskInstance.dag_id,
-    dagRunId: taskInstance.dag_run_id,
-    mapIndex: taskInstance.map_index,
-    taskId: taskInstance.task_id,
-  });
+  const { data } = useTaskInstanceServiceGetTaskInstanceDependencies(
+    {
+      dagId: taskInstance.dag_id,
+      dagRunId: taskInstance.dag_run_id,
+      mapIndex: taskInstance.map_index,
+      taskId: taskInstance.task_id,
+    },
+    undefined,
+    {
+      refetchInterval,
+    },
+  );
 
   if (data === undefined || data.dependencies.length < 1) {
     return undefined;
diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx
index a769498f6d0..5e7b66c7a5e 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Details.tsx
@@ -95,11 +95,14 @@ export const Details = () => {
           taskInstance={taskInstance}
         />
       )}
-      <ExtraLinks />
+      <ExtraLinks refetchInterval={isStatePending(tryInstance?.state) ? 
refetchInterval : false} />
       {taskInstance === undefined ||
       // eslint-disable-next-line unicorn/no-null
       ![null, "queued", "scheduled"].includes(taskInstance.state) ? undefined 
: (
-        <BlockingDeps taskInstance={taskInstance} />
+        <BlockingDeps
+          refetchInterval={isStatePending(tryInstance?.state) ? 
refetchInterval : false}
+          taskInstance={taskInstance}
+        />
       )}
       {taskInstance !== undefined && (taskInstance.trigger ?? 
taskInstance.triggerer_job) ? (
         <TriggererInfo taskInstance={taskInstance} />
diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/ExtraLinks.tsx 
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/ExtraLinks.tsx
index 3559d48065b..2ff7876dfc0 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/ExtraLinks.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/ExtraLinks.tsx
@@ -22,16 +22,26 @@ import { useParams } from "react-router-dom";
 
 import { useTaskInstanceServiceGetExtraLinks } from "openapi/queries";
 
-export const ExtraLinks = () => {
+type ExtraLinksProps = {
+  readonly refetchInterval: number | false;
+};
+
+export const ExtraLinks = ({ refetchInterval }: ExtraLinksProps) => {
   const { t: translate } = useTranslation("dag");
   const { dagId = "", mapIndex = "-1", runId = "", taskId = "" } = useParams();
 
-  const { data } = useTaskInstanceServiceGetExtraLinks({
-    dagId,
-    dagRunId: runId,
-    mapIndex: parseInt(mapIndex, 10),
-    taskId,
-  });
+  const { data } = useTaskInstanceServiceGetExtraLinks(
+    {
+      dagId,
+      dagRunId: runId,
+      mapIndex: parseInt(mapIndex, 10),
+      taskId,
+    },
+    undefined,
+    {
+      refetchInterval,
+    },
+  );
 
   return data && Object.keys(data.extra_links).length > 0 ? (
     <Box py={1}>

Reply via email to