diff --git a/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.test.tsx b/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.test.tsx index 90c39ec41eb0d..add9a7796a2fc 100644 --- a/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.test.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.test.tsx @@ -18,13 +18,32 @@ */ import "@testing-library/jest-dom"; import { render, screen } from "@testing-library/react"; -import { describe, expect, it, vi } from "vitest"; +import type { PropsWithChildren } from "react"; +import { MemoryRouter } from "react-router-dom"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import type { ReactAppResponse } from "openapi/requests/types.gen"; -import { Wrapper } from "src/utils/Wrapper"; +import { BaseWrapper, Wrapper } from "src/utils/Wrapper"; import { Overview } from "./Overview"; +const { mockUseTaskInstanceServiceGetTaskInstances } = vi.hoisted(() => ({ + mockUseTaskInstanceServiceGetTaskInstances: vi.fn(() => ({ + data: { task_instances: [], total_entries: 0 }, + isLoading: false, + })), +})); + +const wrapperWithSearch = (search: string) => { + const RouterWrapper = ({ children }: PropsWithChildren) => ( + + {children} + + ); + + return RouterWrapper; +}; + vi.mock("openapi/queries", () => ({ usePluginServiceGetPlugins: () => ({ data: { @@ -44,10 +63,7 @@ vi.mock("openapi/queries", () => ({ ], }, }), - useTaskInstanceServiceGetTaskInstances: () => ({ - data: { task_instances: [], total_entries: 0 }, - isLoading: false, - }), + useTaskInstanceServiceGetTaskInstances: mockUseTaskInstanceServiceGetTaskInstances, })); vi.mock("src/components/DurationChart", () => ({ DurationChart: () => null })); @@ -79,3 +95,29 @@ describe("Task overview plugins", () => { expect(screen.queryByText("Scoped overview plugin")).not.toBeInTheDocument(); }); }); + +describe("Task overview duration chart limit", () => { + beforeEach(() => { + mockUseTaskInstanceServiceGetTaskInstances.mockClear(); + }); + + it("requests the default number of task instances when no limit is set", () => { + render(, { wrapper: wrapperWithSearch("") }); + + expect(mockUseTaskInstanceServiceGetTaskInstances).toHaveBeenCalledWith( + expect.objectContaining({ limit: 10, orderBy: ["-run_after"] }), + undefined, + expect.anything(), + ); + }); + + it("requests the number of task instances given by the limit search param", () => { + render(, { wrapper: wrapperWithSearch("?limit=50") }); + + expect(mockUseTaskInstanceServiceGetTaskInstances).toHaveBeenCalledWith( + expect.objectContaining({ limit: 50, orderBy: ["-run_after"] }), + undefined, + expect.anything(), + ); + }); +}); diff --git a/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.tsx b/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.tsx index 470877d1742fc..377a674f36869 100644 --- a/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Task/Overview/Overview.tsx @@ -20,7 +20,7 @@ import { Box, HStack, Skeleton, VStack } from "@chakra-ui/react"; import dayjs from "dayjs"; import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { useParams } from "react-router-dom"; +import { useParams, useSearchParams } from "react-router-dom"; import { usePluginServiceGetPlugins, useTaskInstanceServiceGetTaskInstances } from "openapi/queries"; import { DurationChart } from "src/components/DurationChart"; @@ -38,6 +38,9 @@ export const Overview = () => { const { dagId = "", groupId, taskId } = useParams(); const { t: translate } = useTranslation("dag"); + const [searchParams] = useSearchParams(); + const limit = Number(searchParams.get(SearchParamsKeys.LIMIT) ?? "10"); + const now = dayjs(); const [startDate, setStartDate] = useState(now.subtract(Number(defaultHour), "hour").toISOString()); const [endDate, setEndDate] = useState(now.toISOString()); @@ -62,7 +65,7 @@ export const Overview = () => { { dagId, dagRunId: "~", - limit: 14, + limit, orderBy: ["-run_after"], taskGroupId: groupId ?? undefined, taskId: Boolean(groupId) ? undefined : taskId,