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 520d5dd3997 UI: Apply default visibility to newly added table columns
(#74320)
520d5dd3997 is described below
commit 520d5dd3997f8a9bef3b637b306252d9621ed1bc
Author: Yuseok Jo <[email protected]>
AuthorDate: Wed Oct 7 03:43:04 2026 +0900
UI: Apply default visibility to newly added table columns (#74320)
* UI: Apply default visibility to newly added table columns
* Check column headers in the column visibility test
---
.../DataTable/DataTable.columnVisibility.test.tsx | 56 ++++++++++++++++++++++
.../ui/src/components/DataTable/DataTable.tsx | 5 +-
2 files changed, 60 insertions(+), 1 deletion(-)
diff --git
a/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.columnVisibility.test.tsx
b/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.columnVisibility.test.tsx
new file mode 100644
index 00000000000..70fa9861359
--- /dev/null
+++
b/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.columnVisibility.test.tsx
@@ -0,0 +1,56 @@
+/*!
+ * 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 type { ColumnDef } from "@tanstack/react-table";
+import "@testing-library/jest-dom";
+import { render, screen } from "@testing-library/react";
+import { describe, expect, it } from "vitest";
+
+import { ChakraWrapper } from "src/utils/ChakraWrapper.tsx";
+
+import { DataTable } from "./DataTable.tsx";
+
+const columns: Array<ColumnDef<{ name: string }>> = ["Name",
"Added"].map((header) => ({
+ cell: () => header,
+ header,
+ id: header,
+}));
+
+describe("DataTable column visibility", () => {
+ it("applies the default visibility to columns missing from the stored
visibility", () => {
+ localStorage.setItem("dataTable:task:columnVisibility", JSON.stringify({
Name: true }));
+
+ render(
+ <DataTable
+ columns={columns}
+ data={[{ name: "John Doe" }]}
+ initialState={{
+ columnVisibility: { Added: false },
+ pagination: { pageIndex: 0, pageSize: 10 },
+ sorting: [],
+ }}
+ modelName="task"
+ total={1}
+ />,
+ { wrapper: ChakraWrapper },
+ );
+
+ expect(screen.getByRole("columnheader", { name: "Name"
})).toBeInTheDocument();
+ expect(screen.queryByRole("columnheader", { name: "Added" })).toBeNull();
+ });
+});
diff --git a/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.tsx
b/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.tsx
index 8f1e1acf680..baafbf80266 100644
--- a/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DataTable/DataTable.tsx
@@ -162,10 +162,13 @@ export const DataTable = <TData,>({
[onStateChange],
);
- const [columnVisibility, setColumnVisibility] =
useLocalStorage<VisibilityState>(
+ const [storedColumnVisibility, setColumnVisibility] =
useLocalStorage<VisibilityState>(
`dataTable:${modelName}:columnVisibility`,
initialState?.columnVisibility ?? {},
);
+ // Stored visibility only covers columns that existed when it was saved, so
columns added
+ // later still need their default visibility.
+ const columnVisibility = { ...initialState?.columnVisibility,
...storedColumnVisibility };
// An absent total means the endpoint gives no count (e.g. cursor
pagination), which the heading
// reflects by naming the model without a number. Everything else still
needs a real number.