This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun 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 c280a3a3757 [v3-1-test] Fix group TI tab memory (#58288) (#58557)
c280a3a3757 is described below
commit c280a3a3757298a8231d0cf20536436332cd07c5
Author: Guan-Ming (Wesley) Chiu <[email protected]>
AuthorDate: Fri Nov 21 22:26:52 2025 +0800
[v3-1-test] Fix group TI tab memory (#58288) (#58557)
* fix: Prevent preserving tabs when navigating to Task Groups
* refactor: Centralize keyboard navigation logic to use
* test: update test, Groups should not preserve tabs
(cherry picked from commit 7b232c39200631448d5041d1577e03c5a3e5b140)
Co-authored-by: LI,JHE-CHEN <[email protected]>
---
.../ui/src/hooks/navigation/useNavigation.ts | 22 ++++++++++------------
.../src/airflow/ui/src/utils/links.test.ts | 15 +++++++++++++--
airflow-core/src/airflow/ui/src/utils/links.ts | 3 ++-
3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/airflow-core/src/airflow/ui/src/hooks/navigation/useNavigation.ts
b/airflow-core/src/airflow/ui/src/hooks/navigation/useNavigation.ts
index f8a63bc29ee..0c831ecb309 100644
--- a/airflow-core/src/airflow/ui/src/hooks/navigation/useNavigation.ts
+++ b/airflow-core/src/airflow/ui/src/hooks/navigation/useNavigation.ts
@@ -21,7 +21,7 @@ import { useLocation, useNavigate, useParams } from
"react-router-dom";
import type { GridRunsResponse } from "openapi/requests";
import type { GridTask } from "src/layouts/Details/Grid/utils";
-import { getTaskInstanceAdditionalPath } from "src/utils/links";
+import { buildTaskInstanceUrl } from "src/utils/links";
import type {
NavigationDirection,
@@ -72,7 +72,6 @@ const buildPath = (params: {
}): string => {
const { dagId, mapIndex = "-1", mode, pathname, run, task } = params;
const groupPath = task.isGroup ? "group/" : "";
- const additionalPath = getTaskInstanceAdditionalPath(pathname);
switch (mode) {
case "run":
@@ -80,16 +79,15 @@ const buildPath = (params: {
case "task":
return `/dags/${dagId}/tasks/${groupPath}${task.id}`;
case "TI":
- if (task.is_mapped ?? false) {
- if (mapIndex !== "-1") {
- // For mapped tasks with specific map index, we need to construct
the path manually
- return
`/dags/${dagId}/runs/${run.run_id}/tasks/${groupPath}${task.id}/mapped/${mapIndex}${additionalPath}`;
- }
-
- return
`/dags/${dagId}/runs/${run.run_id}/tasks/${groupPath}${task.id}/mapped${additionalPath}`;
- }
-
- return
`/dags/${dagId}/runs/${run.run_id}/tasks/${groupPath}${task.id}${additionalPath}`;
+ return buildTaskInstanceUrl({
+ currentPathname: pathname,
+ dagId,
+ isGroup: task.isGroup,
+ isMapped: task.is_mapped ?? false,
+ mapIndex,
+ runId: run.run_id,
+ taskId: task.id,
+ });
default:
return `/dags/${dagId}`;
}
diff --git a/airflow-core/src/airflow/ui/src/utils/links.test.ts
b/airflow-core/src/airflow/ui/src/utils/links.test.ts
index 2f4720897ee..47dd032ebc5 100644
--- a/airflow-core/src/airflow/ui/src/utils/links.test.ts
+++ b/airflow-core/src/airflow/ui/src/utils/links.test.ts
@@ -232,7 +232,18 @@ describe("buildTaskInstanceUrl", () => {
}),
).toBe("/dags/my_dag/runs/run_123/tasks/mapped_task/mapped");
- // Complex: group + mapped + sub-routes
+ // Groups should never preserve tabs (only have "Task Instances" tab)
+ expect(
+ buildTaskInstanceUrl({
+ currentPathname:
"/dags/old/runs/old/tasks/old_task/rendered_templates",
+ dagId: "new_dag",
+ isGroup: true,
+ runId: "new_run",
+ taskId: "new_group",
+ }),
+ ).toBe("/dags/new_dag/runs/new_run/tasks/group/new_group");
+
+ // Groups should never preserve tabs even for mapped groups
expect(
buildTaskInstanceUrl({
currentPathname: "/dags/old/runs/old/tasks/group/old_group/events",
@@ -243,6 +254,6 @@ describe("buildTaskInstanceUrl", () => {
runId: "new_run",
taskId: "new_group",
}),
- ).toBe("/dags/new_dag/runs/new_run/tasks/group/new_group/mapped/3/events");
+ ).toBe("/dags/new_dag/runs/new_run/tasks/group/new_group/mapped/3");
});
});
diff --git a/airflow-core/src/airflow/ui/src/utils/links.ts
b/airflow-core/src/airflow/ui/src/utils/links.ts
index 80041700860..3beafb06afe 100644
--- a/airflow-core/src/airflow/ui/src/utils/links.ts
+++ b/airflow-core/src/airflow/ui/src/utils/links.ts
@@ -84,7 +84,8 @@ export const buildTaskInstanceUrl = (params: {
}): string => {
const { currentPathname, dagId, isGroup = false, isMapped = false, mapIndex,
runId, taskId } = params;
const groupPath = isGroup ? "group/" : "";
- const additionalPath = getTaskInstanceAdditionalPath(currentPathname);
+ // Task groups only have "Task Instances" tab, so never preserve tabs for
groups
+ const additionalPath = isGroup ? "" :
getTaskInstanceAdditionalPath(currentPathname);
let basePath = `/dags/${dagId}/runs/${runId}/tasks/${groupPath}${taskId}`;