This is an automated email from the ASF dual-hosted git repository.
bbovenzi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new f5774789ea0 Pr/split storage tab (#73989)
f5774789ea0 is described below
commit f5774789ea02120e0fcc712b457a58466aaa4dce
Author: Brent Bovenzi <[email protected]>
AuthorDate: Mon Oct 5 15:56:27 2026 -0400
Pr/split storage tab (#73989)
* UI: Split the Storage tab into XCom and Task State Store
XCom and the task state store were grouped behind one Storage tab because
both are key-value stores, which groups them by storage mechanism rather
than by what a user came to look at. Neither is a sub-view of the other.
* Cleanup i18n
* Drop the dead layout-children branch from task-instance sub-routes
Splitting the Storage tab removed the only pathless layout route, so
`taskInstanceRoutes` no longer has an entry with `children`. That left the
`"children" in route` branch unreachable, and with nothing in the union to
type it `route.children` degraded to `any`, failing the UI lint with four
`no-unsafe-*` errors.
Co-Authored-By: Claude <[email protected]>
---------
Co-authored-by: Claude <[email protected]>
---
.../src/airflow/ui/public/i18n/locales/ar/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/ca/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/de/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/el/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/en/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/es/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/fr/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/he/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/hi/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/hu/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/ko/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/nl/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/pl/dag.json | 1 -
.../src/airflow/ui/public/i18n/locales/ru/dag.json | 1 -
.../airflow/ui/public/i18n/locales/zh-CN/dag.json | 1 -
.../airflow/ui/public/i18n/locales/zh-TW/dag.json | 1 -
.../src/airflow/ui/src/layouts/StorageLayout.tsx | 40 ----------------------
.../src/pages/TaskInstance/TaskInstance.test.tsx | 3 +-
.../ui/src/pages/TaskInstance/TaskInstance.tsx | 17 +++++----
airflow-core/src/airflow/ui/src/router.tsx | 10 ++----
airflow-core/src/airflow/ui/src/utils/links.ts | 15 +-------
21 files changed, 15 insertions(+), 86 deletions(-)
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json
index 73b4b152f35..1295499b3a6 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ar/dag.json
@@ -252,7 +252,6 @@
"renderedTemplates": "القوالب المعروضة",
"requiredActions": "إجراءات مطلوبة",
"runs": "تشغيلات",
- "storage": "التخزين",
"taskInstances": "مثيلات المهام",
"taskStateStore": "مخزن حالة المهمة",
"tasks": "المهام",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json
index 44a598e0b4f..f41ccfed5b2 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/dag.json
@@ -216,7 +216,6 @@
"renderedTemplates": "Plantilles renderitzades",
"requiredActions": "Accions requerides",
"runs": "Execucions",
- "storage": "Emmagatzematge",
"taskInstances": "Instàncies de tasca",
"taskStateStore": "Magatzem de tasca",
"tasks": "Tasques",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json
index 87f9114acd8..e2f9a1fd214 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/dag.json
@@ -221,7 +221,6 @@
"renderedTemplates": "Ausgefüllte Vorlagen",
"requiredActions": "Interaktionen",
"runs": "Läufe",
- "storage": "Speicher",
"taskInstances": "Task Instanzen",
"taskStateStore": "Task Status Zwischenspeicher",
"tasks": "Tasks",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json
index fa3e170889f..12c0f628fb2 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/el/dag.json
@@ -221,7 +221,6 @@
"renderedTemplates": "Αποδοθέντα Πρότυπα",
"requiredActions": "Απαιτούμενες Ενέργειες",
"runs": "Εκτελέσεις",
- "storage": "Αποθήκευση",
"taskInstances": "Στιγμιαίες Καταστάσεις Εργασίας",
"taskStateStore": "Αποθήκη Καταστάσεων Εργασίας",
"tasks": "Εργασίες",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
index f82b24453dd..ce354726ad2 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/dag.json
@@ -221,7 +221,6 @@
"renderedTemplates": "Rendered Templates",
"requiredActions": "Required Actions",
"runs": "Runs",
- "storage": "Storage",
"taskInstances": "Task Instances",
"taskStateStore": "Task State Store",
"tasks": "Tasks",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json
index 00324562d4d..f017c882610 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/es/dag.json
@@ -216,7 +216,6 @@
"renderedTemplates": "Plantillas Renderizadas",
"requiredActions": "Acciones Requeridas",
"runs": "Ejecuciones",
- "storage": "Almacenamiento",
"taskInstances": "Instancias de Tarea",
"taskStateStore": "Almacenamiento de Estado de Tarea",
"tasks": "Tareas",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json
index 5e06822ae46..536aaeb5726 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/fr/dag.json
@@ -224,7 +224,6 @@
"renderedTemplates": "Modèles rendus",
"requiredActions": "Actions requises",
"runs": "Runs",
- "storage": "Stockage",
"taskInstances": "Task Instances",
"taskStateStore": "Stockage d'état de tâche",
"tasks": "Tâches",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json
index c1ee6c8493b..eb6fba38edf 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/he/dag.json
@@ -233,7 +233,6 @@
"renderedTemplates": "תבניות מעובדות",
"requiredActions": "פעולות נדרשות",
"runs": "הרצות",
- "storage": "אחסון",
"taskInstances": "מופעי משימות",
"taskStateStore": "מאגר מצבי משימות",
"tasks": "משימות",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json
index 8e436ab7a4b..8b8c4638942 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/hi/dag.json
@@ -225,7 +225,6 @@
"renderedTemplates": "रेंडर किए गए टेम्प्लेट्स",
"requiredActions": "आवश्यक क्रियाएं",
"runs": "रन्स",
- "storage": "स्टोरेज",
"taskInstances": "टास्क इंस्टेंसेज",
"taskStateStore": "Task State Store",
"tasks": "टास्क्स",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
index a4a8c1cb057..7cc8523da9b 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
@@ -225,7 +225,6 @@
"renderedTemplates": "Renderelt sablonok",
"requiredActions": "Szükséges műveletek",
"runs": "Futások",
- "storage": "Tárhely",
"taskInstances": "Feladatpéldányok",
"taskStore": "Feladat tároló",
"tasks": "Feladatok",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json
index 5f2aacfa6e8..601d06dda9a 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ko/dag.json
@@ -216,7 +216,6 @@
"renderedTemplates": "렌더링된 템플릿",
"requiredActions": "필수 작업",
"runs": "실행",
- "storage": "스토리지",
"taskInstances": "태스크 인스턴스",
"taskStateStore": "태스크 상태 저장소",
"tasks": "태스크",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json
index fda29c0f75f..3e5e00dcce8 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/dag.json
@@ -226,7 +226,6 @@
"renderedTemplates": "Gerenderde templates",
"requiredActions": "Vereiste acties",
"runs": "Runs",
- "storage": "Opslag",
"taskInstances": "Taakinstanties",
"taskStateStore": "Task State Store",
"tasks": "Taken",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json
index 9c1390aa8c2..f5ca47e39b0 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pl/dag.json
@@ -232,7 +232,6 @@
"renderedTemplates": "Wyrenderowane szablony",
"requiredActions": "Wymagane akcje",
"runs": "Wykonania",
- "storage": "Magazyn",
"taskInstances": "Instancje zadań",
"taskStateStore": "Magazyn stanu zadania",
"tasks": "Zadania",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ru/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/ru/dag.json
index 0771d24b42d..96a95157c8e 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ru/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ru/dag.json
@@ -240,7 +240,6 @@
"renderedTemplates": "Отрендеренные шаблоны",
"requiredActions": "Необходимые действия",
"runs": "Запуски",
- "storage": "Хранилище",
"taskInstances": "Экземпляры задач",
"taskStateStore": "Хранилище состояния задач",
"tasks": "Задачи",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json
index 0cfd93ff137..997cc2e2378 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/dag.json
@@ -216,7 +216,6 @@
"renderedTemplates": "渲染后的模板",
"requiredActions": "待响应的任务实例",
"runs": "执行记录",
- "storage": "存储",
"taskInstances": "任务实例",
"taskStateStore": "任务存储",
"tasks": "任务",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json
b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json
index e32e2606d0d..b058abf241a 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-TW/dag.json
@@ -216,7 +216,6 @@
"renderedTemplates": "渲染後的範本",
"requiredActions": "待回應的任務實例",
"runs": "執行紀錄",
- "storage": "儲存空間",
"taskInstances": "任務實例",
"taskStateStore": "任務儲存區",
"tasks": "任務",
diff --git a/airflow-core/src/airflow/ui/src/layouts/StorageLayout.tsx
b/airflow-core/src/airflow/ui/src/layouts/StorageLayout.tsx
deleted file mode 100644
index 4c68755d508..00000000000
--- a/airflow-core/src/airflow/ui/src/layouts/StorageLayout.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-/*!
- * 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 { useTranslation } from "react-i18next";
-import { MdOutlineStorage, MdSyncAlt } from "react-icons/md";
-import { Outlet } from "react-router-dom";
-
-import { NavTabs } from "src/layouts/Details/NavTabs";
-
-/** Sub-nav tabs shared by the task-store and xcom routes. */
-export const StorageLayout = () => {
- const { t: translate } = useTranslation("dag");
-
- return (
- <>
- <NavTabs
- tabs={[
- { icon: <MdSyncAlt />, label: translate("tabs.xcom"), value: "xcom"
},
- { icon: <MdOutlineStorage />, label:
translate("tabs.taskStateStore"), value: "task-state-store" },
- ]}
- />
- <Outlet />
- </>
- );
-};
diff --git
a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.test.tsx
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.test.tsx
index c0c66b1f838..369535f0a23 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.test.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.test.tsx
@@ -160,7 +160,8 @@ describe("TaskInstance", () => {
["tabs.auditLog", "events"],
["tabs.mappedTaskInstances_other", "task_instances"],
["tabs.renderedTemplates", "rendered_templates"],
- ["tabs.storage", "xcom"],
+ ["tabs.xcom", "xcom"],
+ ["tabs.taskStateStore", "task-state-store"],
["tabs.assetEvents", "asset_events"],
["tabs.code", "code"],
])("does not carry try selection into %s", async (label, destination) => {
diff --git
a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
index df0c52d451a..284bf61b2b6 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/TaskInstance.tsx
@@ -20,7 +20,14 @@ import { Heading } from "@chakra-ui/react";
import { ReactFlowProvider } from "@xyflow/react";
import { useTranslation } from "react-i18next";
import { FiCode, FiDatabase, FiUser } from "react-icons/fi";
-import { MdDetails, MdOutlineEventNote, MdOutlineStorage, MdOutlineTask,
MdReorder } from "react-icons/md";
+import {
+ MdDetails,
+ MdOutlineEventNote,
+ MdOutlineStorage,
+ MdOutlineTask,
+ MdReorder,
+ MdSyncAlt,
+} from "react-icons/md";
import { PiBracketsCurlyBold } from "react-icons/pi";
import { useParams, useSearchParams } from "react-router-dom";
@@ -78,12 +85,8 @@ export const TaskInstance = () => {
label: translate("tabs.renderedTemplates"),
value: "rendered_templates",
},
- {
- icon: <MdOutlineStorage />,
- label: translate("tabs.storage"),
- matchPaths: ["task-state-store", "xcom"],
- value: "xcom",
- },
+ { icon: <MdSyncAlt />, label: translate("tabs.xcom"), value: "xcom" },
+ { icon: <MdOutlineStorage />, label: translate("tabs.taskStateStore"),
value: "task-state-store" },
{ icon: <FiDatabase />, label: translate("tabs.assetEvents"), value:
"asset_events" },
{ icon: <MdOutlineEventNote />, label: translate("tabs.auditLog"), value:
"events" },
{ icon: <FiCode />, label: translate("tabs.code"), value: "code" },
diff --git a/airflow-core/src/airflow/ui/src/router.tsx
b/airflow-core/src/airflow/ui/src/router.tsx
index e94f369c0a3..0345d06cd72 100644
--- a/airflow-core/src/airflow/ui/src/router.tsx
+++ b/airflow-core/src/airflow/ui/src/router.tsx
@@ -77,7 +77,6 @@ import { XCom } from "src/pages/XCom";
import { TabEntity, TabName, TaskInstanceTab } from "src/constants/tab";
-import { StorageLayout } from "./layouts/StorageLayout";
import { client } from "./queryClient";
const pluginRoute = {
@@ -89,13 +88,8 @@ export const taskInstanceRoutes = [
{ element: <TaskInstanceDefaultTab />, index: true, path: undefined },
{ element: <Logs />, path: TaskInstanceTab.Logs },
{ element: <Events />, path: TaskInstanceTab.Events },
- {
- children: [
- { element: <XCom />, path: TaskInstanceTab.XCom },
- { element: <TaskStateStore />, path: TaskInstanceTab.TaskStateStore },
- ],
- element: <StorageLayout />,
- },
+ { element: <XCom />, path: TaskInstanceTab.XCom },
+ { element: <TaskStateStore />, path: TaskInstanceTab.TaskStateStore },
{ element: <Code />, path: TaskInstanceTab.Code },
{ element: <TaskInstanceDetails />, path: TaskInstanceTab.Details },
{ element: <RenderedTemplates />, path: TaskInstanceTab.RenderedTemplates },
diff --git a/airflow-core/src/airflow/ui/src/utils/links.ts
b/airflow-core/src/airflow/ui/src/utils/links.ts
index b2d96e93b2b..935b29ef70c 100644
--- a/airflow-core/src/airflow/ui/src/utils/links.ts
+++ b/airflow-core/src/airflow/ui/src/utils/links.ts
@@ -66,20 +66,7 @@ export const getNextHref = (location: Pick<Location, "hash"
| "pathname" | "sear
`${location.pathname}${location.search}${location.hash}`;
export const getTaskInstanceAdditionalPath = (pathname: string): string => {
- const subRoutes = taskInstanceRoutes.flatMap((route) => {
- if (route.path !== undefined) {
- return [route.path];
- }
-
- // Include paths from children of pathless layout routes (e.g. StoragePage
wrapping task-store and xcom)
- if ("children" in route && Array.isArray(route.children)) {
- return route.children
- .filter((child) => "path" in child && typeof child.path === "string")
- .map((child) => child.path);
- }
-
- return [];
- });
+ const subRoutes = taskInstanceRoutes.flatMap((route) => (route.path ===
undefined ? [] : [route.path]));
// Look for patterns like /tasks/{taskId}/mapped/{mapIndex}/{sub-route}
const mappedRegex = /\/tasks\/[^/]+\/mapped\/[^/]+\/(?<subRoute>.+)$/u;
const mappedMatch = mappedRegex.exec(pathname);