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

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


The following commit(s) were added to refs/heads/v3-2-test by this push:
     new 485bbfdbfad Adds the DAG run ID to the grid bar tooltip and also 
surfaces it in the task instance tooltip in the grid view. (#65626) (#66871)
485bbfdbfad is described below

commit 485bbfdbfad51cf4057fbcdb991ef4f393720d7c
Author: Rahul Vats <[email protected]>
AuthorDate: Thu May 14 19:56:13 2026 +0530

    Adds the DAG run ID to the grid bar tooltip and also surfaces it in the 
task instance tooltip in the grid view. (#65626) (#66871)
    
    * Add run ID to grid tooltips
    
    * Format GridTI after run ID tooltip update
    
    ---------
    
    
    (cherry picked from commit 2d4eb59b352affcd488344096080748bd691f004)
    
    Co-authored-by: PrithviBadiga 
<[email protected]>
    Co-authored-by: Prithvi Badiga <[email protected]>
---
 .../ui/src/components/TaskInstanceTooltip.test.tsx | 21 +++++++++
 .../ui/src/components/TaskInstanceTooltip.tsx      |  7 +--
 .../src/layouts/Details/Grid/GridButton.test.tsx   | 55 ++++++++++++++++++++++
 .../ui/src/layouts/Details/Grid/GridButton.tsx     |  2 +
 .../airflow/ui/src/layouts/Details/Grid/GridTI.tsx |  7 ++-
 5 files changed, 88 insertions(+), 4 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx 
b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx
index 51058868003..3f3d17a95de 100644
--- a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.test.tsx
@@ -196,4 +196,25 @@ describe("TaskInstanceTooltip", () => {
     expect(screen.getAllByText(/state/iu).length).toBeGreaterThan(0);
     expect(screen.getByText(/startDate/iu)).toBeInTheDocument();
   });
+
+  it("shows run ID when provided explicitly for grid summaries", () => {
+    const taskInstance: LightGridTaskInstanceSummary = {
+      child_states: null,
+      max_end_date: "2025-01-01T02:00:00Z",
+      min_start_date: "2025-01-01T00:00:00Z",
+      state: "success",
+      task_display_name: "My Task",
+      task_id: "my_task",
+    };
+
+    render(
+      <TaskInstanceTooltip open runId="manual__2025-01-01T00:00:00+00:00" 
taskInstance={taskInstance}>
+        <span>trigger</span>
+      </TaskInstanceTooltip>,
+      { wrapper: Wrapper },
+    );
+
+    expect(screen.getByText(/runId/iu)).toBeInTheDocument();
+    
expect(screen.getByText(/manual__2025-01-01T00:00:00\+00:00/iu)).toBeInTheDocument();
+  });
 });
diff --git a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx 
b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
index 8162c02a7c3..8f89c910247 100644
--- a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
@@ -29,11 +29,12 @@ import { Tooltip, type TooltipProps } from 
"src/components/ui";
 import { getDuration, renderDuration, sortStateEntries } from "src/utils";
 
 type Props = {
+  readonly runId?: string | null;
   readonly taskInstance?: LightGridTaskInstanceSummary | 
TaskInstanceHistoryResponse | TaskInstanceResponse;
   readonly tooltip?: string | null;
 } & Omit<TooltipProps, "content">;
 
-const TaskInstanceTooltip = ({ children, positioning, taskInstance, tooltip, 
...rest }: Props) => {
+const TaskInstanceTooltip = ({ children, positioning, runId, taskInstance, 
tooltip, ...rest }: Props) => {
   const { t: translate } = useTranslation("common");
 
   const hasTooltip = tooltip !== undefined && tooltip !== null;
@@ -62,9 +63,9 @@ const TaskInstanceTooltip = ({ children, positioning, 
taskInstance, tooltip, ...
                   ? translate(`common:states.${taskInstance.state}`)
                   : translate("common:states.no_status")}
               </Text>
-              {"dag_run_id" in taskInstance ? (
+              {"dag_run_id" in taskInstance || (runId !== undefined && runId 
!== null && runId !== "") ? (
                 <Text>
-                  {translate("runId")}: {taskInstance.dag_run_id}
+                  {translate("runId")}: {"dag_run_id" in taskInstance ? 
taskInstance.dag_run_id : runId}
                 </Text>
               ) : undefined}
               {"start_date" in taskInstance ? (
diff --git 
a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.test.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.test.tsx
new file mode 100644
index 00000000000..6164573e68c
--- /dev/null
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.test.tsx
@@ -0,0 +1,55 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import "@testing-library/jest-dom";
+import { act, fireEvent, render, screen } from "@testing-library/react";
+import { describe, expect, it, vi } from "vitest";
+
+import { Wrapper } from "src/utils/Wrapper";
+
+import { GridButton } from "./GridButton";
+
+describe("GridButton", () => {
+  it("shows run ID in the grid tooltip", () => {
+    vi.useFakeTimers();
+
+    render(
+      <GridButton
+        dagId="example_dag"
+        label="2026-04-21T00:00:00+00:00"
+        runId="manual__2026-04-21T00:00:00+00:00"
+        searchParams=""
+        state="success"
+      >
+        <span>bar</span>
+      </GridButton>,
+      { wrapper: Wrapper },
+    );
+
+    act(() => {
+      fireEvent.mouseEnter(screen.getByText("bar"));
+      vi.advanceTimersByTime(500);
+    });
+
+    expect(screen.getByTestId("basic-tooltip")).toHaveTextContent(
+      "common:runId: manual__2026-04-21T00:00:00+00:00",
+    );
+
+    vi.useRealTimers();
+  });
+});
diff --git 
a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx
index c452cf43a79..488ccffd0d0 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx
@@ -50,6 +50,8 @@ export const GridButton = ({
     <>
       {label}
       <br />
+      {translate("common:runId")}: {runId}
+      <br />
       {translate("state")}:{" "}
       {state ? translate(`common:states.${state}`) : 
translate("common:states.no_status")}
     </>
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
index ede81eccbb0..6cd21d252f9 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
@@ -80,7 +80,12 @@ export const GridTI = ({ dagId, instance, isGroup, isMapped, 
onClick, runId, tas
       py={0}
       transition="background-color 0.2s"
     >
-      <TaskInstanceTooltip openDelay={500} positioning={{ placement: "bottom" 
}} taskInstance={instance}>
+      <TaskInstanceTooltip
+        openDelay={500}
+        positioning={{ placement: "bottom" }}
+        runId={runId}
+        taskInstance={instance}
+      >
         <Box as="span" display="inline-block">
           <Link
             data-testid={`grid-${runId}-${taskId}`}

Reply via email to