This is an automated email from the ASF dual-hosted git repository.
potiuk 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 dfd1ea30527 Add expand/collapse all for Dag Run conf JSON in Dag Runs
list (#69567)
dfd1ea30527 is described below
commit dfd1ea30527af9dfd2c1662703f98a8f7de27796
Author: Ashutosh Shaha <[email protected]>
AuthorDate: Sun Jul 12 21:39:50 2026 +0530
Add expand/collapse all for Dag Run conf JSON in Dag Runs list (#69567)
---
.../src/airflow/ui/src/mocks/handlers/dag_runs.ts | 2 +-
.../airflow/ui/src/pages/DagRuns/DagRuns.test.tsx | 44 +++++++++++++++++++++-
.../src/airflow/ui/src/pages/DagRuns/DagRuns.tsx | 21 +++++++++--
3 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/airflow-core/src/airflow/ui/src/mocks/handlers/dag_runs.ts
b/airflow-core/src/airflow/ui/src/mocks/handlers/dag_runs.ts
index ed55e14b019..7fcb78ebfc9 100644
--- a/airflow-core/src/airflow/ui/src/mocks/handlers/dag_runs.ts
+++ b/airflow-core/src/airflow/ui/src/mocks/handlers/dag_runs.ts
@@ -38,7 +38,7 @@ const dagRunBeforeFilter = {
};
const dagRunInRange = {
- conf: null,
+ conf: { batch: 42, env: "prod" },
dag_display_name: "test_dag",
dag_id: "test_dag",
dag_run_id: "run_in_range",
diff --git a/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.test.tsx
b/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.test.tsx
index 50d1d9d8e6a..3b9b19e0eab 100644
--- a/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.test.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.test.tsx
@@ -17,11 +17,19 @@
* under the License.
*/
import "@testing-library/jest-dom";
-import { render, screen, waitFor } from "@testing-library/react";
-import { describe, expect, it } from "vitest";
+import { fireEvent, render, screen, waitFor } from "@testing-library/react";
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { AppWrapper } from "src/utils/AppWrapper";
+// Stand in for the Monaco-backed JSON viewer so the test can assert the
collapse
+// state without loading the editor.
+vi.mock("src/components/RenderedJsonField", () => ({
+ default: ({ collapsed }: { readonly collapsed?: boolean }) => (
+ <div data-collapsed={collapsed} data-testid="rendered-json-field" />
+ ),
+}));
+
// The dag_runs mock handler (see src/mocks/handlers/dag_runs.ts) returns:
// - run_before_filter (logical_date: 2024-12-31) — excluded when filtering
Jan 2025
// - run_in_range (logical_date: 2025-01-15) — included when filtering
Jan 2025
@@ -46,3 +54,35 @@ describe("DagRuns logical date filter", () => {
expect(screen.queryByText("run_before_filter")).not.toBeInTheDocument();
});
});
+
+describe("DagRuns conf expand/collapse", () => {
+ beforeEach(() => {
+ // The conf column is hidden by default; reveal it so the JSON viewer
renders.
+ globalThis.localStorage.setItem(
+ "dataTable:common:dagRun:columnVisibility",
+ JSON.stringify({ conf: true }),
+ );
+ });
+
+ afterEach(() => {
+ globalThis.localStorage.clear();
+ });
+
+ it("toggles conf JSON collapse state via the expand/collapse all buttons",
async () => {
+ render(<AppWrapper initialEntries={["/dag_runs"]} />);
+
+ await waitFor(() =>
expect(screen.getByTestId("rendered-json-field")).toBeInTheDocument());
+
+
expect(screen.getByTestId("rendered-json-field")).toHaveAttribute("data-collapsed",
"true");
+
+ fireEvent.click(screen.getByTestId("expand-all-button"));
+ await waitFor(() =>
+
expect(screen.getByTestId("rendered-json-field")).toHaveAttribute("data-collapsed",
"false"),
+ );
+
+ fireEvent.click(screen.getByTestId("collapse-all-button"));
+ await waitFor(() =>
+
expect(screen.getByTestId("rendered-json-field")).toHaveAttribute("data-collapsed",
"true"),
+ );
+ });
+});
diff --git a/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.tsx
b/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.tsx
index ac4d1b9a886..d9efe994719 100644
--- a/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.tsx
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Flex, HStack, Text } from "@chakra-ui/react";
+import { Flex, HStack, Text, useDisclosure } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
import { useTranslation } from "react-i18next";
@@ -36,6 +36,7 @@ import {
} from "src/components/DataTable/useRowSelection";
import { useTableURLState } from "src/components/DataTable/useTableUrlState";
import { ErrorAlert } from "src/components/ErrorAlert";
+import { ExpandCollapseButtons } from "src/components/ExpandCollapseButtons";
import { LimitedItemsList } from "src/components/LimitedItemsList";
import { MarkRunAsButton } from "src/components/MarkAs";
import RenderedJsonField from "src/components/RenderedJsonField";
@@ -86,10 +87,11 @@ const {
type ColumnProps = {
readonly dagId?: string;
+ readonly open: boolean;
readonly translate: TFunction;
} & GetColumnsParams;
-const runColumns = ({ dagId, translate }: ColumnProps):
Array<ColumnDef<DAGRunResponse>> => [
+const runColumns = ({ dagId, open, translate }: ColumnProps):
Array<ColumnDef<DAGRunResponse>> => [
{
accessorKey: "select",
cell: ({ row }) => <SelectionRowCheckbox colorPalette="brand"
rowKey={getRowKey(row.original)} />,
@@ -196,7 +198,7 @@ const runColumns = ({ dagId, translate }: ColumnProps):
Array<ColumnDef<DAGRunRe
accessorKey: "conf",
cell: ({ row: { original } }) =>
original.conf && Object.keys(original.conf).length > 0 ? (
- <RenderedJsonField collapsed content={original.conf} />
+ <RenderedJsonField collapsed={!open} content={original.conf} />
) : undefined,
header: translate("dagRun.conf"),
},
@@ -226,6 +228,7 @@ export const DagRuns = () => {
useDocumentTitle(dagId === undefined ? translate("common:dagRun_other") :
undefined);
const [searchParams] = useSearchParams();
+ const { onClose, onOpen, open } = useDisclosure();
const { setTableURLState, tableURLState } = useTableURLState({
columnVisibility: {
@@ -337,6 +340,7 @@ export const DagRuns = () => {
const columns = runColumns({
dagId,
multiTeam: false,
+ open,
translate,
});
@@ -347,7 +351,16 @@ export const DagRuns = () => {
onSelectAll={handleSelectAll}
selectedRows={selectedRows}
>
- <DagRunsFilters dagId={dagId} />
+ <Flex alignItems="center" justifyContent="space-between">
+ <DagRunsFilters dagId={dagId} />
+ <ExpandCollapseButtons
+ collapseLabel={translate("common:collapseAllExtra")}
+ expandLabel={translate("common:expandAllExtra")}
+ isExpanded={open}
+ onCollapse={onClose}
+ onExpand={onOpen}
+ />
+ </Flex>
<DataTable
columns={columns}
data={data?.dag_runs ?? []}