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 acf333c64a884..5b20511d31f47 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 @@ -98,28 +98,26 @@ def _find_aggregates( "type": "mapped_task", "parent_id": parent_id, **_get_aggs_for_node(mapped_details), + "details": mapped_details, } return if isinstance(node, SerializedTaskGroup): - children = [] + children_details = [] for child in get_task_group_children_getter()(node): for child_node in _find_aggregates(node=child, parent_node=node, ti_details=ti_details): if child_node["parent_id"] == node_id: - children.append( - { - "state": child_node["state"], - "start_date": child_node["min_start_date"], - "end_date": child_node["max_end_date"], - } - ) + # Collect detailed task instance data from all children + if child_node.get("details"): + children_details.extend(child_node["details"]) yield child_node if node_id: yield { "task_id": node_id, "type": "group", "parent_id": parent_id, - **_get_aggs_for_node(children), + **_get_aggs_for_node(children_details), + "details": children_details, } return if isinstance(node, SerializedBaseOperator): @@ -128,5 +126,6 @@ def _find_aggregates( "type": "task", "parent_id": parent_id, **_get_aggs_for_node(details), + "details": details, } return 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 93b5ecfa48794..9bd06f764d5ad 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 @@ -598,7 +598,7 @@ def test_grid_ti_summaries_group(self, session, test_client): "min_start_date": None, }, { - "child_states": {"success": 2}, + "child_states": {"success": 4}, "max_end_date": "2025-03-02T00:00:12Z", "min_start_date": "2025-03-02T00:00:04Z", "state": "success", @@ -671,7 +671,7 @@ def sort_dict(in_dict): "state": None, }, { - "child_states": {"running": 1}, + "child_states": {"success": 1, "running": 1, "None": 1}, "max_end_date": "2024-12-30T01:02:03Z", "min_start_date": "2024-12-30T01:00:00Z", "state": "running", @@ -692,14 +692,14 @@ def sort_dict(in_dict): "min_start_date": None, }, { - "child_states": {"None": 2}, + "child_states": {"None": 6}, "task_id": "task_group", "max_end_date": None, "min_start_date": None, "state": None, }, { - "child_states": {"None": 1}, + "child_states": {"None": 2}, "task_id": "task_group.inner_task_group", "max_end_date": None, "min_start_date": None,