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 e1155edf1e0 Display latest dagrun state per dag in search result. 
(#69414)
e1155edf1e0 is described below

commit e1155edf1e01a3096348b86270c43d586b2277a5
Author: Karthikeyan Singaravelan <[email protected]>
AuthorDate: Thu Jul 9 21:44:20 2026 +0530

    Display latest dagrun state per dag in search result. (#69414)
    
    * Display latest dagrun state per dag in search result.
    
    * Limit dagrun to 1 for latest run and use option.label to show 
dag_display_name if present.
---
 .../ui/src/components/SearchDags/SearchDags.tsx    | 38 ++++++++++++++++------
 .../SearchDags/SearchDagsDropdownIndicator.tsx     |  4 +--
 airflow-core/src/airflow/ui/src/utils/option.ts    |  5 +++
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git 
a/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDags.tsx 
b/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDags.tsx
index 76e42dde6f6..56f7a1a8550 100644
--- a/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDags.tsx
+++ b/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDags.tsx
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { Field } from "@chakra-ui/react";
+import { Field, Flex, Text } from "@chakra-ui/react";
 import { useQueryClient } from "@tanstack/react-query";
 import { AsyncSelect } from "chakra-react-select";
 import type { OptionsOrGroups, GroupBase, SingleValue } from 
"chakra-react-select";
@@ -25,10 +25,14 @@ import { useTranslation } from "react-i18next";
 import { useNavigate } from "react-router-dom";
 import { useDebouncedCallback } from "use-debounce";
 
-import { UseDagServiceGetDagsKeyFn } from "openapi/queries";
+import { UseDagServiceGetDagsUiKeyFn } from "openapi/queries";
 import { DagService } from "openapi/requests/services.gen";
-import type { DAGCollectionResponse, DAGResponse } from 
"openapi/requests/types.gen";
-import type { Option } from "src/utils/option";
+import type {
+  DAGWithLatestDagRunsCollectionResponse,
+  DAGWithLatestDagRunsResponse,
+} from "openapi/requests/types.gen";
+import { StateBadge } from "src/components/StateBadge";
+import type { DagSearchOption } from "src/utils/option";
 
 import { DropdownIndicator } from "./SearchDagsDropdownIndicator";
 
@@ -42,7 +46,7 @@ export const SearchDags = ({
   const navigate = useNavigate();
   const SEARCH_LIMIT = 10;
 
-  const onSelect = (selected: SingleValue<Option>) => {
+  const onSelect = (selected: SingleValue<DagSearchOption>) => {
     if (selected) {
       setIsOpen(false);
       void Promise.resolve(navigate(`/dags/${selected.value}`));
@@ -50,15 +54,20 @@ export const SearchDags = ({
   };
 
   const searchDagDebounced = useDebouncedCallback(
-    (inputValue: string, callback: (options: OptionsOrGroups<Option, 
GroupBase<Option>>) => void) => {
+    (
+      inputValue: string,
+      callback: (options: OptionsOrGroups<DagSearchOption, 
GroupBase<DagSearchOption>>) => void,
+    ) => {
       void queryClient.fetchQuery({
         queryFn: () =>
-          DagService.getDags({
+          DagService.getDagsUi({
             dagDisplayNamePrefixPattern: inputValue,
+            dagRunsLimit: 1,
             limit: SEARCH_LIMIT,
-          }).then((data: DAGCollectionResponse) => {
-            const options = data.dags.map((dag: DAGResponse) => ({
+          }).then((data: DAGWithLatestDagRunsCollectionResponse) => {
+            const options = data.dags.map((dag: DAGWithLatestDagRunsResponse) 
=> ({
               label: dag.dag_display_name || dag.dag_id,
+              state: dag.latest_dag_runs[0]?.state ?? null,
               value: dag.dag_id,
             }));
 
@@ -66,8 +75,9 @@ export const SearchDags = ({
 
             return options;
           }),
-        queryKey: UseDagServiceGetDagsKeyFn({
+        queryKey: UseDagServiceGetDagsUiKeyFn({
           dagDisplayNamePrefixPattern: inputValue,
+          dagRunsLimit: 1,
         }),
         staleTime: 0,
       });
@@ -75,6 +85,13 @@ export const SearchDags = ({
     300,
   );
 
+  const formatOptionLabel = (option: DagSearchOption) => (
+    <Flex alignItems="center" gap={2}>
+      <StateBadge state={option.state} />
+      <Text>{option.label}</Text>
+    </Flex>
+  );
+
   return (
     <Field.Root>
       <AsyncSelect
@@ -82,6 +99,7 @@ export const SearchDags = ({
         components={{ DropdownIndicator }}
         defaultOptions
         filterOption={undefined}
+        formatOptionLabel={formatOptionLabel}
         loadOptions={searchDagDebounced}
         menuIsOpen
         onChange={onSelect}
diff --git 
a/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsDropdownIndicator.tsx
 
b/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsDropdownIndicator.tsx
index 4bfbd83984c..cffc8aaf2ac 100644
--- 
a/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsDropdownIndicator.tsx
+++ 
b/airflow-core/src/airflow/ui/src/components/SearchDags/SearchDagsDropdownIndicator.tsx
@@ -20,9 +20,9 @@ import { chakraComponents } from "chakra-react-select";
 import type { DropdownIndicatorProps } from "chakra-react-select";
 import { FiSearch } from "react-icons/fi";
 
-import type { Option } from "src/utils/option";
+import type { DagSearchOption } from "src/utils/option";
 
-export const DropdownIndicator: React.FC<DropdownIndicatorProps<Option, 
false>> = (props) => (
+export const DropdownIndicator: 
React.FC<DropdownIndicatorProps<DagSearchOption, false>> = (props) => (
   <chakraComponents.DropdownIndicator {...props}>
     <FiSearch />
   </chakraComponents.DropdownIndicator>
diff --git a/airflow-core/src/airflow/ui/src/utils/option.ts 
b/airflow-core/src/airflow/ui/src/utils/option.ts
index 0d6b799ab3c..7251892a7e4 100644
--- a/airflow-core/src/airflow/ui/src/utils/option.ts
+++ b/airflow-core/src/airflow/ui/src/utils/option.ts
@@ -16,9 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import type { DagRunState } from "openapi/requests/types.gen";
 
 export type Option = {
   readonly disabled?: boolean;
   readonly label: string;
   readonly value: string;
 };
+
+export type DagSearchOption = {
+  readonly state: DagRunState | null;
+} & Option;

Reply via email to