diff --git a/airflow-core/src/airflow/ui/src/components/Assets/AssetEvents.tsx b/airflow-core/src/airflow/ui/src/components/Assets/AssetEvents.tsx index ee1dfb2570123..8f6b818f2d290 100644 --- a/airflow-core/src/airflow/ui/src/components/Assets/AssetEvents.tsx +++ b/airflow-core/src/airflow/ui/src/components/Assets/AssetEvents.tsx @@ -29,6 +29,7 @@ import { Select } from "src/components/ui"; import { DataTable } from "../DataTable"; import type { CardDef, TableState } from "../DataTable/types"; import { AssetEvent } from "./AssetEvent"; +import { AssetEventsFilter } from "./AssetEventsFilter"; const cardDef = (assetId?: number): CardDef => ({ card: ({ row }) => , @@ -43,6 +44,7 @@ type AssetEventProps = { readonly isLoading?: boolean; readonly setOrderBy?: (order: string) => void; readonly setTableUrlState?: (state: TableState) => void; + readonly showFilters?: boolean; readonly tableUrlState?: TableState; readonly titleKey?: string; }; @@ -53,6 +55,7 @@ export const AssetEvents = ({ isLoading, setOrderBy, setTableUrlState, + showFilters = false, tableUrlState, titleKey, ...rest @@ -101,6 +104,7 @@ export const AssetEvents = ({ )} + {showFilters ? : null} { + const { t: translate } = useTranslation("common"); + const [searchParams, setSearchParams] = useSearchParams(); + const startDate = searchParams.get(START_DATE) ?? ""; + const endDate = searchParams.get(END_DATE) ?? ""; + const dagId = searchParams.get(DAG_ID) ?? ""; + const taskId = searchParams.get(TASK_ID) ?? ""; + const [resetKey, setResetKey] = useState(0); + const handleFilterChange = useCallback( + (paramKey: string) => (value: string) => { + if (value === "") { + searchParams.delete(paramKey); + } else { + searchParams.set(paramKey, value); + } + setSearchParams(searchParams); + }, + [searchParams, setSearchParams], + ); + const filterCount = useMemo( + () => filterKeys.reduce((acc, key) => (searchParams.get(key) === null ? acc : acc + 1), 0), + [searchParams], + ); + const handleResetFilters = useCallback(() => { + filterKeys.forEach((key) => searchParams.delete(key)); + setSearchParams(searchParams); + setResetKey((prev) => prev + 1); + }, [searchParams, setSearchParams]); + + return ( + + + + {translate("common:table.from")} + handleFilterChange(START_DATE)(event.target.value)} + value={startDate} + /> + + + {translate("common:table.to")} + handleFilterChange(END_DATE)(event.target.value)} + value={endDate} + /> + + + {translate("common:filters.dagDisplayNamePlaceholder")} + + + + {translate("common:filters.taskIdPlaceholder")} + + + + {filterCount > 0 && ( + + )} + + + + ); +}; diff --git a/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx b/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx index 51a1442fcc90b..e499afda799bf 100644 --- a/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx @@ -22,12 +22,14 @@ import { useCallback } from "react"; import { useTranslation } from "react-i18next"; import { PanelGroup, Panel, PanelResizeHandle } from "react-resizable-panels"; import { useParams } from "react-router-dom"; +import { useSearchParams } from "react-router-dom"; import { useAssetServiceGetAsset, useAssetServiceGetAssetEvents } from "openapi/queries"; import { AssetEvents } from "src/components/Assets/AssetEvents"; import { BreadcrumbStats } from "src/components/BreadcrumbStats"; import { useTableURLState } from "src/components/DataTable/useTableUrlState"; import { ProgressBar } from "src/components/ui"; +import { SearchParamsKeys } from "src/constants/searchParams"; import { AssetGraph } from "./AssetGraph"; import { CreateAssetEvent } from "./CreateAssetEvent"; @@ -59,12 +61,18 @@ export const AssetLayout = () => { }, ]; + const { DAG_ID, END_DATE, START_DATE, TASK_ID } = SearchParamsKeys; + const [searchParams] = useSearchParams(); const { data, isLoading: isLoadingEvents } = useAssetServiceGetAssetEvents( { assetId: asset?.id, limit: pagination.pageSize, offset: pagination.pageIndex * pagination.pageSize, orderBy, + sourceDagId: searchParams.get(DAG_ID) ?? undefined, + sourceTaskId: searchParams.get(TASK_ID) ?? undefined, + timestampGte: searchParams.get(START_DATE) ?? undefined, + timestampLte: searchParams.get(END_DATE) ?? undefined, }, undefined, { enabled: Boolean(asset?.id) }, @@ -127,6 +135,7 @@ export const AssetLayout = () => { isLoading={isLoadingEvents} setOrderBy={setOrderBy} setTableUrlState={setTableURLState} + showFilters={true} tableUrlState={tableURLState} />