From cc7ae556fe35f44f7ccb42dc02fdc2a021a27ef5 Mon Sep 17 00:00:00 2001
From: "Guan-Ming (Wesley) Chiu"
<105915352+guan404ming@users.noreply.github.com>
Date: Wed, 4 Feb 2026 17:13:32 +0800
Subject: [PATCH] Add task_display_name to LightGridTaskInstanceSummary model
Signed-off-by: Guan-Ming (Wesley) Chiu <105915352+guan404ming@users.noreply.github.com>
---
.../api_fastapi/core_api/datamodels/ui/grid.py | 1 +
.../core_api/openapi/_private_ui.yaml | 4 ++++
.../api_fastapi/core_api/routes/ui/grid.py | 1 +
.../api_fastapi/core_api/services/ui/grid.py | 3 +++
.../ui/openapi-gen/requests/schemas.gen.ts | 6 +++++-
.../ui/openapi-gen/requests/types.gen.ts | 1 +
.../ui/src/pages/GroupTaskInstance/Header.tsx | 2 +-
.../ui/src/pages/MappedTaskInstance/Header.tsx | 2 +-
.../api_fastapi/core_api/routes/ui/test_grid.py | 17 +++++++++++++++++
9 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py
index b38c203825c53..46e275a803c3e 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/ui/grid.py
@@ -27,6 +27,7 @@ class LightGridTaskInstanceSummary(BaseModel):
"""Task Instance Summary model for the Grid UI."""
task_id: str
+ task_display_name: str
state: TaskInstanceState | None
child_states: dict[TaskInstanceState | None, int] | None
min_start_date: datetime | None
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
index 362c81d5397b1..5c1cc245243ae 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
+++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
@@ -2331,6 +2331,9 @@ components:
task_id:
type: string
title: Task Id
+ task_display_name:
+ type: string
+ title: Task Display Name
state:
anyOf:
- $ref: '#/components/schemas/TaskInstanceState'
@@ -2357,6 +2360,7 @@ components:
type: object
required:
- task_id
+ - task_display_name
- state
- child_states
- min_start_date
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py
index 0f061933b0d87..694f12e02944c 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/grid.py
@@ -414,6 +414,7 @@ def get_node_sumaries():
agg = _get_aggs_for_node(detail)
yield {
"task_id": task_id,
+ "task_display_name": task_id,
"type": "task",
"parent_id": None,
**agg,
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py
index 3b01f02b91630..2f1087a8f08af 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/services/ui/grid.py
@@ -95,6 +95,7 @@ def _find_aggregates(
mapped_details = details or [{"state": None, "start_date": None, "end_date": None}]
yield {
"task_id": node_id,
+ "task_display_name": node.task_display_name,
"type": "mapped_task",
"parent_id": parent_id,
**_get_aggs_for_node(mapped_details),
@@ -114,6 +115,7 @@ def _find_aggregates(
if node_id:
yield {
"task_id": node_id,
+ "task_display_name": node_id,
"type": "group",
"parent_id": parent_id,
**_get_aggs_for_node(children_details),
@@ -123,6 +125,7 @@ def _find_aggregates(
if isinstance(node, SerializedBaseOperator):
yield {
"task_id": node_id,
+ "task_display_name": node.task_display_name,
"type": "task",
"parent_id": parent_id,
**_get_aggs_for_node(details),
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
index 172a89744e625..9616c6dec944b 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
@@ -8070,6 +8070,10 @@ export const $LightGridTaskInstanceSummary = {
type: 'string',
title: 'Task Id'
},
+ task_display_name: {
+ type: 'string',
+ title: 'Task Display Name'
+ },
state: {
anyOf: [
{
@@ -8120,7 +8124,7 @@ export const $LightGridTaskInstanceSummary = {
}
},
type: 'object',
- required: ['task_id', 'state', 'child_states', 'min_start_date', 'max_end_date'],
+ required: ['task_id', 'task_display_name', 'state', 'child_states', 'min_start_date', 'max_end_date'],
title: 'LightGridTaskInstanceSummary',
description: 'Task Instance Summary model for the Grid UI.'
} as const;
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
index 995fc2e36a354..6c55ea8d56b64 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
@@ -1995,6 +1995,7 @@ export type HistoricalMetricDataResponse = {
*/
export type LightGridTaskInstanceSummary = {
task_id: string;
+ task_display_name: string;
state: TaskInstanceState | null;
child_states: {
[key: string]: (number);
diff --git a/airflow-core/src/airflow/ui/src/pages/GroupTaskInstance/Header.tsx b/airflow-core/src/airflow/ui/src/pages/GroupTaskInstance/Header.tsx
index ac4b48652a48e..9967dd9a5744d 100644
--- a/airflow-core/src/airflow/ui/src/pages/GroupTaskInstance/Header.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/GroupTaskInstance/Header.tsx
@@ -59,7 +59,7 @@ export const Header = ({ taskInstance }: { readonly taskInstance: LightGridTaskI
state={taskInstance.state}
stats={stats}
subTitle={}
- title={taskInstance.task_id}
+ title={taskInstance.task_display_name}
/>
);
diff --git a/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/Header.tsx b/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/Header.tsx
index 88d6bb122b696..97c86581a23c3 100644
--- a/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/Header.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/MappedTaskInstance/Header.tsx
@@ -59,7 +59,7 @@ export const Header = ({ taskInstance }: { readonly taskInstance: LightGridTaskI
state={taskInstance.state}
stats={stats}
subTitle={}
- title={`${taskInstance.task_id} [${taskCount}]`}
+ title={`${taskInstance.task_display_name} [${taskCount}]`}
/>
);
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py
index c9d8fcba6ab9f..3a3b44594c5b4 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_grid.py
@@ -695,6 +695,7 @@ def test_grid_ti_summaries_group(self, session, test_client):
{
"state": "success",
"task_id": "t1",
+ "task_display_name": "t1",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -702,6 +703,7 @@ def test_grid_ti_summaries_group(self, session, test_client):
{
"state": "success",
"task_id": "t2",
+ "task_display_name": "t2",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -709,6 +711,7 @@ def test_grid_ti_summaries_group(self, session, test_client):
{
"state": "success",
"task_id": "t7",
+ "task_display_name": "t7",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -719,10 +722,12 @@ def test_grid_ti_summaries_group(self, session, test_client):
"min_start_date": "2025-03-02T00:00:04Z",
"state": "success",
"task_id": "task_group-1",
+ "task_display_name": "task_group-1",
},
{
"state": "success",
"task_id": "task_group-1.t6",
+ "task_display_name": "task_group-1.t6",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -733,10 +738,12 @@ def test_grid_ti_summaries_group(self, session, test_client):
"min_start_date": "2025-03-02T00:00:06Z",
"state": "success",
"task_id": "task_group-1.task_group-2",
+ "task_display_name": "task_group-1.task_group-2",
},
{
"state": "success",
"task_id": "task_group-1.task_group-2.t3",
+ "task_display_name": "task_group-1.task_group-2.t3",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -744,6 +751,7 @@ def test_grid_ti_summaries_group(self, session, test_client):
{
"state": "success",
"task_id": "task_group-1.task_group-2.t4",
+ "task_display_name": "task_group-1.task_group-2.t4",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -751,6 +759,7 @@ def test_grid_ti_summaries_group(self, session, test_client):
{
"state": "success",
"task_id": "task_group-1.task_group-2.t5",
+ "task_display_name": "task_group-1.task_group-2.t5",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -784,6 +793,7 @@ def sort_dict(in_dict):
{
"child_states": {"None": 1},
"task_id": "mapped_task_2",
+ "task_display_name": "mapped_task_2",
"max_end_date": None,
"min_start_date": None,
"state": None,
@@ -794,10 +804,12 @@ def sort_dict(in_dict):
"min_start_date": "2024-12-30T01:00:00Z",
"state": "running",
"task_id": "mapped_task_group",
+ "task_display_name": "mapped_task_group",
},
{
"state": "running",
"task_id": "mapped_task_group.subtask",
+ "task_display_name": "mapped_task_group.subtask",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -805,6 +817,7 @@ def sort_dict(in_dict):
{
"state": "success",
"task_id": "task",
+ "task_display_name": "A Beautiful Task Name \U0001f680",
"child_states": None,
"max_end_date": None,
"min_start_date": None,
@@ -812,6 +825,7 @@ def sort_dict(in_dict):
{
"child_states": {"None": 6},
"task_id": "task_group",
+ "task_display_name": "task_group",
"max_end_date": None,
"min_start_date": None,
"state": None,
@@ -819,6 +833,7 @@ def sort_dict(in_dict):
{
"child_states": {"None": 2},
"task_id": "task_group.inner_task_group",
+ "task_display_name": "task_group.inner_task_group",
"max_end_date": None,
"min_start_date": None,
"state": None,
@@ -826,6 +841,7 @@ def sort_dict(in_dict):
{
"child_states": {"None": 2},
"task_id": "task_group.inner_task_group.inner_task_group_sub_task",
+ "task_display_name": "Inner Task Group Sub Task Label",
"max_end_date": None,
"min_start_date": None,
"state": None,
@@ -833,6 +849,7 @@ def sort_dict(in_dict):
{
"child_states": {"None": 4},
"task_id": "task_group.mapped_task",
+ "task_display_name": "task_group.mapped_task",
"max_end_date": None,
"min_start_date": None,
"state": None,