This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun 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 5000cd62ec7 Add filters to Task Instances Tab (#56920)
5000cd62ec7 is described below
commit 5000cd62ec7a0fe9c1f3c264aec0c12d9a21d921
Author: Sean Yu <[email protected]>
AuthorDate: Tue Nov 25 23:02:24 2025 +0800
Add filters to Task Instances Tab (#56920)
* Add several filters to Task View (squashed, de-duplicated)
* fix traslation problem stick to Operator in task
* fix format
* fix too long file
* fix format
* add run_id_pattern as backend filter
* fix format
* change run_id filter to name pattern filter
* merge date range picker
---
.../core_api/openapi/v2-rest-api-generated.yaml | 12 ++
.../core_api/routes/public/task_instances.py | 2 +
.../src/airflow/ui/openapi-gen/queries/common.ts | 5 +-
.../ui/openapi-gen/queries/ensureQueryData.ts | 6 +-
.../src/airflow/ui/openapi-gen/queries/prefetch.ts | 6 +-
.../src/airflow/ui/openapi-gen/queries/queries.ts | 6 +-
.../src/airflow/ui/openapi-gen/queries/suspense.ts | 6 +-
.../ui/openapi-gen/requests/services.gen.ts | 2 +
.../airflow/ui/openapi-gen/requests/types.gen.ts | 4 +
.../src/airflow/ui/src/constants/filterConfigs.tsx | 51 +++++-
.../src/airflow/ui/src/constants/searchParams.ts | 4 +
.../ui/src/pages/TaskInstances/TaskInstances.tsx | 52 ++++--
.../pages/TaskInstances/TaskInstancesFilter.tsx | 196 ++++++++-------------
.../src/airflow/ui/src/utils/useFiltersHandler.ts | 4 +
.../core_api/routes/public/test_task_instances.py | 12 ++
15 files changed, 213 insertions(+), 155 deletions(-)
diff --git
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
index 59b9210a9d3..d1ed9ba9f3e 100644
---
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
+++
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
@@ -6609,6 +6609,18 @@ paths:
title: Dag Id Pattern
description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g.
`%customer_%`).\
\ Regular expressions are **not** supported."
+ - name: run_id_pattern
+ in: query
+ required: false
+ schema:
+ anyOf:
+ - type: string
+ - type: 'null'
+ description: "SQL LIKE expression \u2014 use `%` / `_` wildcards
(e.g. `%customer_%`).\
+ \ Regular expressions are **not** supported."
+ title: Run Id Pattern
+ description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g.
`%customer_%`).\
+ \ Regular expressions are **not** supported."
- name: state
in: query
required: false
diff --git
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
index c7903b389da..f0cea4100d7 100644
---
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
+++
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/task_instances.py
@@ -425,6 +425,7 @@ def get_task_instances(
duration_range: Annotated[RangeFilter,
Depends(float_range_filter_factory("duration", TI))],
task_display_name_pattern: QueryTITaskDisplayNamePatternSearch,
dag_id_pattern: Annotated[_SearchParam,
Depends(search_param_factory(TI.dag_id, "dag_id_pattern"))],
+ run_id_pattern: Annotated[_SearchParam,
Depends(search_param_factory(TI.run_id, "run_id_pattern"))],
state: QueryTIStateFilter,
pool: QueryTIPoolFilter,
pool_name_pattern: QueryTIPoolNamePatternSearch,
@@ -510,6 +511,7 @@ def get_task_instances(
task_id,
task_display_name_pattern,
dag_id_pattern,
+ run_id_pattern,
version_number,
readable_ti_filter,
try_number,
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
index 29162a5dab0..9453643554c 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
@@ -474,7 +474,7 @@ export const
UseTaskInstanceServiceGetMappedTaskInstanceKeyFn = ({ dagId, dagRun
export type TaskInstanceServiceGetTaskInstancesDefaultResponse =
Awaited<ReturnType<typeof TaskInstanceService.getTaskInstances>>;
export type TaskInstanceServiceGetTaskInstancesQueryResult<TData =
TaskInstanceServiceGetTaskInstancesDefaultResponse, TError = unknown> =
UseQueryResult<TData, TError>;
export const useTaskInstanceServiceGetTaskInstancesKey =
"TaskInstanceServiceGetTaskInstances";
-export const UseTaskInstanceServiceGetTaskInstancesKeyFn = ({ dagId,
dagIdPattern, dagRunId, durationGt, durationGte, durationLt, durationLte,
endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueNamePattern,
runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte,
startDateLt, startDateLte, state, taskDis [...]
+export const UseTaskInstanceServiceGetTaskInstancesKeyFn = ({ dagId,
dagIdPattern, dagRunId, durationGt, durationGte, durationLt, durationLte,
endDateGt, endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueNamePattern,
runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, startDateGt,
startDateGte, startDateLt, startDateLte, [...]
dagId: string;
dagIdPattern?: string;
dagRunId: string;
@@ -505,6 +505,7 @@ export const UseTaskInstanceServiceGetTaskInstancesKeyFn =
({ dagId, dagIdPatter
runAfterGte?: string;
runAfterLt?: string;
runAfterLte?: string;
+ runIdPattern?: string;
startDateGt?: string;
startDateGte?: string;
startDateLt?: string;
@@ -518,7 +519,7 @@ export const UseTaskInstanceServiceGetTaskInstancesKeyFn =
({ dagId, dagIdPatter
updatedAtLt?: string;
updatedAtLte?: string;
versionNumber?: number[];
-}, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetTaskInstancesKey,
...(queryKey ?? [{ dagId, dagIdPattern, dagRunId, durationGt, durationGte,
durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte,
executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte,
mapIndex, offset, operator, operatorNamePattern, orderBy, pool,
poolNamePattern, queue, queueNamePattern, runAfterGt, runAfterGte, runAfterLt,
runAfterLte, startDateGt, startDateGte, startDa [...]
+}, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetTaskInstancesKey,
...(queryKey ?? [{ dagId, dagIdPattern, dagRunId, durationGt, durationGte,
durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte,
executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte,
mapIndex, offset, operator, operatorNamePattern, orderBy, pool,
poolNamePattern, queue, queueNamePattern, runAfterGt, runAfterGte, runAfterLt,
runAfterLte, runIdPattern, startDateGt, startDa [...]
export type TaskInstanceServiceGetTaskInstanceTryDetailsDefaultResponse =
Awaited<ReturnType<typeof TaskInstanceService.getTaskInstanceTryDetails>>;
export type TaskInstanceServiceGetTaskInstanceTryDetailsQueryResult<TData =
TaskInstanceServiceGetTaskInstanceTryDetailsDefaultResponse, TError = unknown>
= UseQueryResult<TData, TError>;
export const useTaskInstanceServiceGetTaskInstanceTryDetailsKey =
"TaskInstanceServiceGetTaskInstanceTryDetails";
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
index 066187914ae..939dbfa7987 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
@@ -926,6 +926,7 @@ export const
ensureUseTaskInstanceServiceGetMappedTaskInstanceData = (queryClien
* @param data.durationLt
* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_`
wildcards (e.g. `%customer_%`). Regular expressions are **not** supported.
* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
+* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
* @param data.state
* @param data.pool
* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards
(e.g. `%customer_%`). Regular expressions are **not** supported.
@@ -943,7 +944,7 @@ export const
ensureUseTaskInstanceServiceGetMappedTaskInstanceData = (queryClien
* @returns TaskInstanceCollectionResponse Successful Response
* @throws ApiError
*/
-export const ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient:
QueryClient, { dagId, dagIdPattern, dagRunId, durationGt, durationGte,
durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte,
executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte,
mapIndex, offset, operator, operatorNamePattern, orderBy, pool,
poolNamePattern, queue, queueNamePattern, runAfterGt, runAfterGte, runAfterLt,
runAfterLte, startDateGt, startDateGte, startDateL [...]
+export const ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient:
QueryClient, { dagId, dagIdPattern, dagRunId, durationGt, durationGte,
durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte,
executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte,
mapIndex, offset, operator, operatorNamePattern, orderBy, pool,
poolNamePattern, queue, queueNamePattern, runAfterGt, runAfterGte, runAfterLt,
runAfterLte, runIdPattern, startDateGt, startDateG [...]
dagId: string;
dagIdPattern?: string;
dagRunId: string;
@@ -974,6 +975,7 @@ export const
ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient: Qu
runAfterGte?: string;
runAfterLt?: string;
runAfterLte?: string;
+ runIdPattern?: string;
startDateGt?: string;
startDateGte?: string;
startDateLt?: string;
@@ -987,7 +989,7 @@ export const
ensureUseTaskInstanceServiceGetTaskInstancesData = (queryClient: Qu
updatedAtLt?: string;
updatedAtLte?: string;
versionNumber?: number[];
-}) => queryClient.ensureQueryData({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueNamePattern,
runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte,
star [...]
+}) => queryClient.ensureQueryData({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueNamePattern,
runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, startDateGt,
star [...]
/**
* Get Task Instance Try Details
* Get task instance details by try number.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
index 59677f9cda0..12d4fd68ea1 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
@@ -926,6 +926,7 @@ export const
prefetchUseTaskInstanceServiceGetMappedTaskInstance = (queryClient:
* @param data.durationLt
* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_`
wildcards (e.g. `%customer_%`). Regular expressions are **not** supported.
* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
+* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
* @param data.state
* @param data.pool
* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards
(e.g. `%customer_%`). Regular expressions are **not** supported.
@@ -943,7 +944,7 @@ export const
prefetchUseTaskInstanceServiceGetMappedTaskInstance = (queryClient:
* @returns TaskInstanceCollectionResponse Successful Response
* @throws ApiError
*/
-export const prefetchUseTaskInstanceServiceGetTaskInstances = (queryClient:
QueryClient, { dagId, dagIdPattern, dagRunId, durationGt, durationGte,
durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte,
executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte,
mapIndex, offset, operator, operatorNamePattern, orderBy, pool,
poolNamePattern, queue, queueNamePattern, runAfterGt, runAfterGte, runAfterLt,
runAfterLte, startDateGt, startDateGte, startDateLt, [...]
+export const prefetchUseTaskInstanceServiceGetTaskInstances = (queryClient:
QueryClient, { dagId, dagIdPattern, dagRunId, durationGt, durationGte,
durationLt, durationLte, endDateGt, endDateGte, endDateLt, endDateLte,
executor, limit, logicalDateGt, logicalDateGte, logicalDateLt, logicalDateLte,
mapIndex, offset, operator, operatorNamePattern, orderBy, pool,
poolNamePattern, queue, queueNamePattern, runAfterGt, runAfterGte, runAfterLt,
runAfterLte, runIdPattern, startDateGt, startDateGte [...]
dagId: string;
dagIdPattern?: string;
dagRunId: string;
@@ -974,6 +975,7 @@ export const prefetchUseTaskInstanceServiceGetTaskInstances
= (queryClient: Quer
runAfterGte?: string;
runAfterLt?: string;
runAfterLte?: string;
+ runIdPattern?: string;
startDateGt?: string;
startDateGte?: string;
startDateLt?: string;
@@ -987,7 +989,7 @@ export const prefetchUseTaskInstanceServiceGetTaskInstances
= (queryClient: Quer
updatedAtLt?: string;
updatedAtLte?: string;
versionNumber?: number[];
-}) => queryClient.prefetchQuery({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueNamePattern,
runAfterGt, runAfterGte, runAfterLt, runAfterLte, startDateGt, startDateGte,
startD [...]
+}) => queryClient.prefetchQuery({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueNamePattern,
runAfterGt, runAfterGte, runAfterLt, runAfterLte, runIdPattern, startDateGt,
startD [...]
/**
* Get Task Instance Try Details
* Get task instance details by try number.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
index e8c6ca0e6f2..3d20b53573f 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
@@ -926,6 +926,7 @@ export const useTaskInstanceServiceGetMappedTaskInstance =
<TData = Common.TaskI
* @param data.durationLt
* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_`
wildcards (e.g. `%customer_%`). Regular expressions are **not** supported.
* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
+* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
* @param data.state
* @param data.pool
* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards
(e.g. `%customer_%`). Regular expressions are **not** supported.
@@ -943,7 +944,7 @@ export const useTaskInstanceServiceGetMappedTaskInstance =
<TData = Common.TaskI
* @returns TaskInstanceCollectionResponse Successful Response
* @throws ApiError
*/
-export const useTaskInstanceServiceGetTaskInstances = <TData =
Common.TaskInstanceServiceGetTaskInstancesDefaultResponse, TError = unknown,
TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagIdPattern, dagRunId,
durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte,
endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte,
logicalDateLt, logicalDateLte, mapIndex, offset, operator, operatorNamePattern,
orderBy, pool, poolNamePattern, queue, queueNameP [...]
+export const useTaskInstanceServiceGetTaskInstances = <TData =
Common.TaskInstanceServiceGetTaskInstancesDefaultResponse, TError = unknown,
TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagIdPattern, dagRunId,
durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte,
endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte,
logicalDateLt, logicalDateLte, mapIndex, offset, operator, operatorNamePattern,
orderBy, pool, poolNamePattern, queue, queueNameP [...]
dagId: string;
dagIdPattern?: string;
dagRunId: string;
@@ -974,6 +975,7 @@ export const useTaskInstanceServiceGetTaskInstances =
<TData = Common.TaskInstan
runAfterGte?: string;
runAfterLt?: string;
runAfterLte?: string;
+ runIdPattern?: string;
startDateGt?: string;
startDateGte?: string;
startDateLt?: string;
@@ -987,7 +989,7 @@ export const useTaskInstanceServiceGetTaskInstances =
<TData = Common.TaskInstan
updatedAtLt?: string;
updatedAtLte?: string;
versionNumber?: number[];
-}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>,
"queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueName [...]
+}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>,
"queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, queueName [...]
/**
* Get Task Instance Try Details
* Get task instance details by try number.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
index d03b23a0708..2745bee178c 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
@@ -926,6 +926,7 @@ export const
useTaskInstanceServiceGetMappedTaskInstanceSuspense = <TData = Comm
* @param data.durationLt
* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_`
wildcards (e.g. `%customer_%`). Regular expressions are **not** supported.
* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
+* @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g.
`%customer_%`). Regular expressions are **not** supported.
* @param data.state
* @param data.pool
* @param data.poolNamePattern SQL LIKE expression — use `%` / `_` wildcards
(e.g. `%customer_%`). Regular expressions are **not** supported.
@@ -943,7 +944,7 @@ export const
useTaskInstanceServiceGetMappedTaskInstanceSuspense = <TData = Comm
* @returns TaskInstanceCollectionResponse Successful Response
* @throws ApiError
*/
-export const useTaskInstanceServiceGetTaskInstancesSuspense = <TData =
Common.TaskInstanceServiceGetTaskInstancesDefaultResponse, TError = unknown,
TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagIdPattern, dagRunId,
durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte,
endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte,
logicalDateLt, logicalDateLte, mapIndex, offset, operator, operatorNamePattern,
orderBy, pool, poolNamePattern, queue, qu [...]
+export const useTaskInstanceServiceGetTaskInstancesSuspense = <TData =
Common.TaskInstanceServiceGetTaskInstancesDefaultResponse, TError = unknown,
TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagIdPattern, dagRunId,
durationGt, durationGte, durationLt, durationLte, endDateGt, endDateGte,
endDateLt, endDateLte, executor, limit, logicalDateGt, logicalDateGte,
logicalDateLt, logicalDateLte, mapIndex, offset, operator, operatorNamePattern,
orderBy, pool, poolNamePattern, queue, qu [...]
dagId: string;
dagIdPattern?: string;
dagRunId: string;
@@ -974,6 +975,7 @@ export const useTaskInstanceServiceGetTaskInstancesSuspense
= <TData = Common.Ta
runAfterGte?: string;
runAfterLt?: string;
runAfterLte?: string;
+ runIdPattern?: string;
startDateGt?: string;
startDateGte?: string;
startDateLt?: string;
@@ -987,7 +989,7 @@ export const useTaskInstanceServiceGetTaskInstancesSuspense
= <TData = Common.Ta
updatedAtLt?: string;
updatedAtLte?: string;
versionNumber?: number[];
-}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>,
"queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, q [...]
+}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>,
"queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey:
Common.UseTaskInstanceServiceGetTaskInstancesKeyFn({ dagId, dagIdPattern,
dagRunId, durationGt, durationGte, durationLt, durationLte, endDateGt,
endDateGte, endDateLt, endDateLte, executor, limit, logicalDateGt,
logicalDateGte, logicalDateLt, logicalDateLte, mapIndex, offset, operator,
operatorNamePattern, orderBy, pool, poolNamePattern, queue, q [...]
/**
* Get Task Instance Try Details
* Get task instance details by try number.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
index 0b058cc2622..dea17f7b8f6 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
@@ -2336,6 +2336,7 @@ export class TaskInstanceService {
* @param data.durationLt
* @param data.taskDisplayNamePattern SQL LIKE expression — use `%` / `_`
wildcards (e.g. `%customer_%`). Regular expressions are **not** supported.
* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards
(e.g. `%customer_%`). Regular expressions are **not** supported.
+ * @param data.runIdPattern SQL LIKE expression — use `%` / `_` wildcards
(e.g. `%customer_%`). Regular expressions are **not** supported.
* @param data.state
* @param data.pool
* @param data.poolNamePattern SQL LIKE expression — use `%` / `_`
wildcards (e.g. `%customer_%`). Regular expressions are **not** supported.
@@ -2389,6 +2390,7 @@ export class TaskInstanceService {
duration_lt: data.durationLt,
task_display_name_pattern: data.taskDisplayNamePattern,
dag_id_pattern: data.dagIdPattern,
+ run_id_pattern: data.runIdPattern,
state: data.state,
pool: data.pool,
pool_name_pattern: data.poolNamePattern,
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
index 8fefb28e5bd..9704369f913 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
@@ -2885,6 +2885,10 @@ export type GetTaskInstancesData = {
runAfterGte?: string | null;
runAfterLt?: string | null;
runAfterLte?: string | null;
+ /**
+ * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`).
Regular expressions are **not** supported.
+ */
+ runIdPattern?: string | null;
startDateGt?: string | null;
startDateGte?: string | null;
startDateLt?: string | null;
diff --git a/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx
b/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx
index a845244800a..a2308e2869f 100644
--- a/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx
+++ b/airflow-core/src/airflow/ui/src/constants/filterConfigs.tsx
@@ -16,8 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
+
+/* eslint-disable max-lines */
import { Flex } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
+import { BiTargetLock } from "react-icons/bi";
import { FiBarChart, FiUser } from "react-icons/fi";
import { LuBrackets } from "react-icons/lu";
import {
@@ -28,15 +31,17 @@ import {
MdCode,
MdPlayArrow,
MdCheckCircle,
+ MdBuild,
} from "react-icons/md";
+import { PiQueue } from "react-icons/pi";
-import type { DagRunState, DagRunType } from "openapi/requests/types.gen";
+import type { DagRunState, DagRunType, TaskInstanceState } from
"openapi/requests/types.gen";
import { DagIcon } from "src/assets/DagIcon";
import { TaskIcon } from "src/assets/TaskIcon";
import type { FilterConfig } from "src/components/FilterBar";
import { RunTypeIcon } from "src/components/RunTypeIcon";
import { StateBadge } from "src/components/StateBadge";
-import { dagRunStateOptions, dagRunTypeOptions } from
"src/constants/stateOptions";
+import { dagRunStateOptions, dagRunTypeOptions, taskInstanceStateOptions }
from "src/constants/stateOptions";
import { SearchParamsKeys } from "./searchParams";
@@ -49,13 +54,13 @@ export enum FilterTypes {
}
export const useFilterConfigs = () => {
- const { t: translate } = useTranslation(["browse", "common", "admin",
"hitl"]);
+ const { t: translate } = useTranslation(["browse", "common", "components",
"admin", "hitl"]);
const filterConfigMap = {
[SearchParamsKeys.ASSET_EVENT_DATE_RANGE]: {
endKey: SearchParamsKeys.END_DATE,
icon: <MdDateRange />,
- label: translate("common:logicalDate"),
+ label: translate("components:backfill.dateRange"),
startKey: SearchParamsKeys.START_DATE,
type: FilterTypes.DATERANGE,
},
@@ -144,6 +149,30 @@ export const useFilterConfigs = () => {
min: -1,
type: FilterTypes.NUMBER,
},
+ [SearchParamsKeys.NAME_PATTERN]: {
+ hotkeyDisabled: true,
+ icon: <TaskIcon />,
+ label: translate("common:taskId"),
+ type: FilterTypes.TEXT,
+ },
+ [SearchParamsKeys.OPERATOR_NAME_PATTERN]: {
+ hotkeyDisabled: true,
+ icon: <MdBuild />,
+ label: translate("common:task.operator"),
+ type: FilterTypes.TEXT,
+ },
+ [SearchParamsKeys.POOL_NAME_PATTERN]: {
+ hotkeyDisabled: true,
+ icon: <BiTargetLock />,
+ label: translate("common:taskInstance.pool"),
+ type: FilterTypes.TEXT,
+ },
+ [SearchParamsKeys.QUEUE_NAME_PATTERN]: {
+ hotkeyDisabled: true,
+ icon: <PiQueue />,
+ label: translate("common:taskInstance.queue"),
+ type: FilterTypes.TEXT,
+ },
[SearchParamsKeys.RESPONDED_BY_USER_NAME]: {
hotkeyDisabled: true,
icon: <FiUser />,
@@ -233,6 +262,20 @@ export const useFilterConfigs = () => {
label: translate("common:taskId"),
type: FilterTypes.TEXT,
},
+ [SearchParamsKeys.TASK_STATE]: {
+ icon: <MdCheckCircle />,
+ label: translate("common:state"),
+ options: taskInstanceStateOptions.items.map((option) => ({
+ label:
+ option.value === "all" ? (
+ translate(option.label)
+ ) : (
+ <StateBadge state={option.value as
TaskInstanceState}>{translate(option.label)}</StateBadge>
+ ),
+ value: option.value === "all" ? "" : option.value,
+ })),
+ type: FilterTypes.SELECT,
+ },
[SearchParamsKeys.TRIGGERING_USER_NAME_PATTERN]: {
hotkeyDisabled: true,
icon: <FiUser />,
diff --git a/airflow-core/src/airflow/ui/src/constants/searchParams.ts
b/airflow-core/src/airflow/ui/src/constants/searchParams.ts
index 17be1231ada..91e2a0be00f 100644
--- a/airflow-core/src/airflow/ui/src/constants/searchParams.ts
+++ b/airflow-core/src/airflow/ui/src/constants/searchParams.ts
@@ -51,9 +51,12 @@ export enum SearchParamsKeys {
NEEDS_REVIEW = "needs_review",
OFFSET = "offset",
OPERATOR = "operator",
+ OPERATOR_NAME_PATTERN = "operator_name_pattern",
OWNERS = "owners",
PAUSED = "paused",
POOL = "pool",
+ POOL_NAME_PATTERN = "pool_name_pattern",
+ QUEUE_NAME_PATTERN = "queue_name_pattern",
RESPONDED_BY_USER_NAME = "responded_by_user_name",
RESPONSE_RECEIVED = "response_received",
RETRIES = "retries",
@@ -72,6 +75,7 @@ export enum SearchParamsKeys {
TAGS_MATCH_MODE = "tags_match_mode",
TASK_ID = "task_id",
TASK_ID_PATTERN = "task_id_pattern",
+ TASK_STATE = "task_state",
TRIGGER_RULE = "trigger_rule",
TRIGGERING_USER_NAME_PATTERN = "triggering_user_name_pattern",
TRY_NUMBER = "try_number",
diff --git
a/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstances.tsx
b/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstances.tsx
index 9d13622ffe1..f4e0e14aca6 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstances.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstances.tsx
@@ -21,7 +21,7 @@
import { Flex, Link } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
-import { useMemo, useState } from "react";
+import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useParams, useSearchParams } from
"react-router-dom";
@@ -47,11 +47,21 @@ type TaskInstanceRow = { row: { original:
TaskInstanceResponse } };
const {
DAG_ID_PATTERN: DAG_ID_PATTERN_PARAM,
+ DAG_VERSION: DAG_VERSION_PARAM,
+ DURATION_GTE: DURATION_GTE_PARAM,
+ DURATION_LTE: DURATION_LTE_PARAM,
END_DATE: END_DATE_PARAM,
+ LOGICAL_DATE_GTE: LOGICAL_DATE_GTE_PARAM,
+ LOGICAL_DATE_LTE: LOGICAL_DATE_LTE_PARAM,
+ MAP_INDEX: MAP_INDEX_PARAM,
NAME_PATTERN: NAME_PATTERN_PARAM,
- POOL: POOL_PARAM,
+ OPERATOR_NAME_PATTERN: OPERATOR_NAME_PATTERN_PARAM,
+ POOL_NAME_PATTERN: POOL_NAME_PATTERN_PARAM,
+ QUEUE_NAME_PATTERN: QUEUE_NAME_PATTERN_PARAM,
+ RUN_ID_PATTERN: RUN_ID_PATTERN_PARAM,
START_DATE: START_DATE_PARAM,
- STATE: STATE_PARAM,
+ TASK_STATE: STATE_PARAM,
+ TRY_NUMBER: TRY_NUMBER_PARAM,
}: SearchParamsKeysType = SearchParamsKeys;
const taskInstanceColumns = ({
@@ -229,16 +239,22 @@ export const TaskInstances = () => {
const orderBy = sort ? [`${sort.desc ? "-" : ""}${sort.id}`] :
["-start_date", "-run_after"];
const filteredState = searchParams.getAll(STATE_PARAM);
+ const filteredDagVersion = searchParams.get(DAG_VERSION_PARAM);
+ const durationGte = searchParams.get(DURATION_GTE_PARAM);
+ const durationLte = searchParams.get(DURATION_LTE_PARAM);
+ const logicalDateGte = searchParams.get(LOGICAL_DATE_GTE_PARAM);
+ const logicalDateLte = searchParams.get(LOGICAL_DATE_LTE_PARAM);
+ const tryNumberFilter = searchParams.get(TRY_NUMBER_PARAM);
+ const mapIndexFilter = searchParams.get(MAP_INDEX_PARAM);
const startDate = searchParams.get(START_DATE_PARAM);
const endDate = searchParams.get(END_DATE_PARAM);
- const pool = searchParams.getAll(POOL_PARAM);
+ const poolNamePattern = searchParams.get(POOL_NAME_PATTERN_PARAM);
+ const queueNamePattern = searchParams.get(QUEUE_NAME_PATTERN_PARAM);
+ const operatorNamePattern = searchParams.get(OPERATOR_NAME_PATTERN_PARAM);
const filteredDagIdPattern = searchParams.get(DAG_ID_PATTERN_PARAM);
+ const filteredRunId = searchParams.get(RUN_ID_PATTERN_PARAM);
const hasFilteredState = filteredState.length > 0;
- const hasFilteredPool = pool.length > 0;
-
- const [taskDisplayNamePattern, setTaskDisplayNamePattern] = useState(
- searchParams.get(NAME_PATTERN_PARAM) ?? undefined,
- );
+ const taskDisplayNamePattern = searchParams.get(NAME_PATTERN_PARAM);
const refetchInterval = useAutoRefresh({});
@@ -247,15 +263,26 @@ export const TaskInstances = () => {
dagId: dagId ?? "~",
dagIdPattern: filteredDagIdPattern ?? undefined,
dagRunId: runId ?? "~",
+ durationGte: durationGte !== null && durationGte !== "" ?
Number(durationGte) : undefined,
+ durationLte: durationLte !== null && durationLte !== "" ?
Number(durationLte) : undefined,
endDateLte: endDate ?? undefined,
limit: pagination.pageSize,
+ logicalDateGte: logicalDateGte ?? undefined,
+ logicalDateLte: logicalDateLte ?? undefined,
+ mapIndex: mapIndexFilter !== null && mapIndexFilter !== "" ?
[Number(mapIndexFilter)] : undefined,
offset: pagination.pageIndex * pagination.pageSize,
+ operatorNamePattern: operatorNamePattern ?? undefined,
orderBy,
- pool: hasFilteredPool ? pool : undefined,
+ poolNamePattern: poolNamePattern ?? undefined,
+ queueNamePattern: queueNamePattern ?? undefined,
+ runIdPattern: filteredRunId ?? undefined,
startDateGte: startDate ?? undefined,
state: hasFilteredState ? filteredState : undefined,
taskDisplayNamePattern: groupId ?? taskDisplayNamePattern ?? undefined,
taskId: Boolean(groupId) ? undefined : taskId,
+ tryNumber: tryNumberFilter !== null && tryNumberFilter !== "" ?
[Number(tryNumberFilter)] : undefined,
+ versionNumber:
+ filteredDagVersion !== null && filteredDagVersion !== "" ?
[Number(filteredDagVersion)] : undefined,
},
undefined,
{
@@ -277,10 +304,7 @@ export const TaskInstances = () => {
return (
<>
- <TaskInstancesFilter
- setTaskDisplayNamePattern={setTaskDisplayNamePattern}
- taskDisplayNamePattern={taskDisplayNamePattern}
- />
+ <TaskInstancesFilter />
<DataTable
columns={columns}
data={data?.task_instances ?? []}
diff --git
a/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstancesFilter.tsx
b/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstancesFilter.tsx
index f7295080b7d..ccb4ba91f99 100644
---
a/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstancesFilter.tsx
+++
b/airflow-core/src/airflow/ui/src/pages/TaskInstances/TaskInstancesFilter.tsx
@@ -16,151 +16,93 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { HStack, type SelectValueChangeDetails } from "@chakra-ui/react";
-import { useCallback } from "react";
-import { useTranslation } from "react-i18next";
+import { VStack } from "@chakra-ui/react";
+import { useMemo } from "react";
import { useSearchParams, useParams } from "react-router-dom";
-import type { TaskInstanceState } from "openapi/requests/types.gen";
-import { useTableURLState } from "src/components/DataTable/useTableUrlState";
-import { SearchBar } from "src/components/SearchBar";
-import { StateBadge } from "src/components/StateBadge";
-import { Select } from "src/components/ui";
+import { FilterBar, type FilterValue } from "src/components/FilterBar";
import { SearchParamsKeys, type SearchParamsKeysType } from
"src/constants/searchParams";
-import { taskInstanceStateOptions } from "src/constants/stateOptions";
+import { useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils";
const {
+ ASSET_EVENT_DATE_RANGE: ASSET_EVENT_DATE_RANGE_PARAM,
DAG_ID_PATTERN: DAG_ID_PATTERN_PARAM,
+ DAG_VERSION: DAG_VERSION_PARAM,
+ DURATION_GTE: DURATION_GTE_PARAM,
+ DURATION_LTE: DURATION_LTE_PARAM,
+ LOGICAL_DATE_RANGE: LOGICAL_DATE_RANGE_PARAM,
+ MAP_INDEX: MAP_INDEX_PARAM,
NAME_PATTERN: NAME_PATTERN_PARAM,
- STATE: STATE_PARAM,
+ OPERATOR_NAME_PATTERN: OPERATOR_NAME_PATTERN_PARAM,
+ POOL_NAME_PATTERN: POOL_NAME_PATTERN_PARAM,
+ QUEUE_NAME_PATTERN: QUEUE_NAME_PATTERN_PARAM,
+ RUN_ID_PATTERN: RUN_ID_PATTERN_PARAM,
+ TASK_STATE: STATE_PARAM,
+ TRY_NUMBER: TRY_NUMBER_PARAM,
}: SearchParamsKeysType = SearchParamsKeys;
-export const TaskInstancesFilter = ({
- setTaskDisplayNamePattern,
- taskDisplayNamePattern,
-}: {
- readonly setTaskDisplayNamePattern:
React.Dispatch<React.SetStateAction<string | undefined>>;
- readonly taskDisplayNamePattern: string | undefined;
-}) => {
+export const TaskInstancesFilter = () => {
const { dagId, runId } = useParams();
- const [searchParams, setSearchParams] = useSearchParams();
- const { setTableURLState, tableURLState } = useTableURLState();
- const { pagination, sorting } = tableURLState;
- const { t: translate } = useTranslation();
+ const paramKeys = useMemo((): Array<FilterableSearchParamsKeys> => {
+ const keys: Array<FilterableSearchParamsKeys> = [
+ NAME_PATTERN_PARAM as FilterableSearchParamsKeys,
+ LOGICAL_DATE_RANGE_PARAM as FilterableSearchParamsKeys,
+ ASSET_EVENT_DATE_RANGE_PARAM as FilterableSearchParamsKeys,
+ DURATION_GTE_PARAM as FilterableSearchParamsKeys,
+ DURATION_LTE_PARAM as FilterableSearchParamsKeys,
+ TRY_NUMBER_PARAM as FilterableSearchParamsKeys,
+ MAP_INDEX_PARAM as FilterableSearchParamsKeys,
+ DAG_VERSION_PARAM as FilterableSearchParamsKeys,
+ OPERATOR_NAME_PATTERN_PARAM as FilterableSearchParamsKeys,
+ POOL_NAME_PATTERN_PARAM as FilterableSearchParamsKeys,
+ QUEUE_NAME_PATTERN_PARAM as FilterableSearchParamsKeys,
+ STATE_PARAM as FilterableSearchParamsKeys,
+ ];
- const filteredState = searchParams.getAll(STATE_PARAM);
- const filteredDagIdPattern = searchParams.get(DAG_ID_PATTERN_PARAM);
- const hasFilteredState = filteredState.length > 0;
+ if (runId === undefined) {
+ keys.unshift(RUN_ID_PATTERN_PARAM as FilterableSearchParamsKeys);
+ }
- const handleStateChange = useCallback(
- ({ value }: SelectValueChangeDetails<string>) => {
- const [val, ...rest] = value;
+ if (dagId === undefined) {
+ keys.unshift(DAG_ID_PATTERN_PARAM as FilterableSearchParamsKeys);
+ }
- if ((val === undefined || val === "all") && rest.length === 0) {
- searchParams.delete(STATE_PARAM);
- } else {
- searchParams.delete(STATE_PARAM);
- value.filter((state) => state !== "all").map((state) =>
searchParams.append(STATE_PARAM, state));
- }
- setTableURLState({
- pagination: { ...pagination, pageIndex: 0 },
- sorting,
- });
- setSearchParams(searchParams);
- },
- [pagination, searchParams, setSearchParams, setTableURLState, sorting],
- );
+ return keys;
+ }, [dagId, runId]);
- const handleSearchChange = (value: string) => {
- if (value) {
- searchParams.set(NAME_PATTERN_PARAM, value);
- } else {
- searchParams.delete(NAME_PATTERN_PARAM);
- }
- setTableURLState({
- pagination: { ...pagination, pageIndex: 0 },
- sorting,
- });
- setTaskDisplayNamePattern(value);
- setSearchParams(searchParams);
- };
+ const [searchParams] = useSearchParams();
+
+ const { filterConfigs, handleFiltersChange } = useFiltersHandler(paramKeys);
- const handleDagIdPatternChange = useCallback(
- (value: string) => {
- if (value === "") {
- searchParams.delete(DAG_ID_PATTERN_PARAM);
- } else {
- searchParams.set(DAG_ID_PATTERN_PARAM, value);
+ const initialValues = useMemo(() => {
+ const values: Record<string, FilterValue> = {};
+
+ filterConfigs.forEach((config) => {
+ const value = searchParams.get(config.key);
+
+ if (value !== null && value !== "") {
+ if (config.type === "number") {
+ const parsedValue = Number(value);
+
+ values[config.key] = isNaN(parsedValue) ? value : parsedValue;
+ } else {
+ values[config.key] = value;
+ }
}
- setTableURLState({
- pagination: { ...pagination, pageIndex: 0 },
- sorting,
- });
- setSearchParams(searchParams);
- },
- [pagination, searchParams, setSearchParams, setTableURLState, sorting],
- );
+ });
+
+ return values;
+ }, [searchParams, filterConfigs]);
return (
- <HStack paddingY="4px">
- {dagId === undefined && (
- <SearchBar
- buttonProps={{ disabled: true }}
- defaultValue={filteredDagIdPattern ?? ""}
- hideAdvanced
- hotkeyDisabled={true}
- onChange={handleDagIdPatternChange}
- placeHolder={translate("dags:search.dags")}
+ <VStack align="start" justifyContent="space-between">
+ <VStack alignItems="flex-start" gap={1}>
+ <FilterBar
+ configs={filterConfigs}
+ initialValues={initialValues}
+ onFiltersChange={handleFiltersChange}
/>
- )}
- <SearchBar
- buttonProps={{ disabled: true }}
- defaultValue={taskDisplayNamePattern ?? ""}
- hideAdvanced
- hotkeyDisabled={Boolean(runId)}
- onChange={handleSearchChange}
- placeHolder={translate("dags:search.tasks")}
- />
- <Select.Root
- collection={taskInstanceStateOptions}
- maxW="450px"
- multiple
- onValueChange={handleStateChange}
- value={hasFilteredState ? filteredState : ["all"]}
- >
- <Select.Trigger
- {...(hasFilteredState ? { clearable: true } : {})}
- colorPalette="brand"
- isActive={Boolean(filteredState)}
- >
- <Select.ValueText>
- {() =>
- hasFilteredState ? (
- <HStack flexWrap="wrap" fontSize="sm" gap="4px" paddingY="8px">
- {filteredState.map((state) => (
- <StateBadge key={state} state={state as TaskInstanceState}>
- {translate(`common:states.${state}`)}
- </StateBadge>
- ))}
- </HStack>
- ) : (
- translate("dags:filters.allStates")
- )
- }
- </Select.ValueText>
- </Select.Trigger>
- <Select.Content>
- {taskInstanceStateOptions.items.map((option) => (
- <Select.Item item={option} key={option.label}>
- {option.value === "all" ? (
- translate(option.label)
- ) : (
- <StateBadge state={option.value as
TaskInstanceState}>{translate(option.label)}</StateBadge>
- )}
- </Select.Item>
- ))}
- </Select.Content>
- </Select.Root>
- </HStack>
+ </VStack>
+ </VStack>
);
};
diff --git a/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts
b/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts
index e4f90060054..298a1c357da 100644
--- a/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts
+++ b/airflow-core/src/airflow/ui/src/utils/useFiltersHandler.ts
@@ -72,6 +72,10 @@ export type FilterableSearchParamsKeys =
| SearchParamsKeys.KEY_PATTERN
| SearchParamsKeys.LOGICAL_DATE_RANGE
| SearchParamsKeys.MAP_INDEX
+ | SearchParamsKeys.NAME_PATTERN
+ | SearchParamsKeys.OPERATOR_NAME_PATTERN
+ | SearchParamsKeys.POOL_NAME_PATTERN
+ | SearchParamsKeys.QUEUE_NAME_PATTERN
| SearchParamsKeys.RESPONDED_BY_USER_NAME
| SearchParamsKeys.RESPONSE_RECEIVED
| SearchParamsKeys.RUN_AFTER_RANGE
diff --git
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
index e592961bff1..1c53c2ec061 100644
---
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
+++
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
@@ -1325,6 +1325,18 @@ class TestGetTaskInstances(TestTaskInstanceEndpoint):
3,
id="test map_index filter",
),
+ pytest.param(
+ [
+ {},
+ ],
+ True,
+ ("/dags/~/dagRuns/~/taskInstances"),
+ {"run_id_pattern": "TEST_DAG_"},
+ 1, # apart from the TIs in the fixture, we also get one from
+ # the create_task_instances method
+ 3,
+ id="test run_id_pattern filter",
+ ),
pytest.param(
"dag_id_pattern_test", # Special marker for multi-DAG test
False,