Repository: apache/airflow
Pull request: ISSUE-43043 | AIP-38 | Add more sort options to Dags List
Add more sort options to Dags List `"dag_display_name","next_dagrun", "last_run_state", "last_run_start_date"`
closes: #43043

Updated UI:

https://github.com/user-attachments/assets/a75156b5-10ac-47bc-a9e1-50232d997a74





<!-- Please keep an empty line above the dashes. -->
---
**^ Add meaningful description above**
Read the **[Pull Request Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)** for more information.
In case of fundamental code changes, an Airflow Improvement Proposal ([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals)) is needed.
In case of a new dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x).
In case of backwards incompatible changes please leave a note in a newsfragment file, named `{pr_number}.significant.rst` or `{issue_number}.significant.rst`, in [newsfragments](https://github.com/apache/airflow/tree/main/newsfragments).


Problem statement:
AIP-38 | Add more sort options to Dags List
In our fastapi endpoint, we only sort the 

Right now, we only sort by `dag_id`. Let's swap that for display_name. Also, let's add `"next_dagrun", "last_run_state", "last_run_start_date"` as other sort options.

Since not all of these fields are currently columns in the dags list response, we probably need to always our `sort-by-select` instead of only when its a card list.

Hints from issue discussion:
Could you please assign this to me.

Commit message: reviews

Patch to review:
diff --git a/airflow/ui/src/pages/DagsList/DagsList.tsx b/airflow/ui/src/pages/DagsList/DagsList.tsx
index 9d5b01e20f73c..9259d6df82961 100644
--- a/airflow/ui/src/pages/DagsList/DagsList.tsx
+++ b/airflow/ui/src/pages/DagsList/DagsList.tsx
@@ -200,21 +200,31 @@ export const DagsList = () => {
           <Heading py={3} size="md">
             {pluralize("DAG", data?.total_entries)}
           </Heading>
-          {display === "card" ? (
-            <Select
-              data-testid="sort-by-select"
-              onChange={handleSortChange}
-              placeholder="Sort by…"
-              value={orderBy}
-              variant="flushed"
-              width="200px"
-            >
-              <option value="dag_id">Sort by DAG ID (A-Z)</option>
-              <option value="-dag_id">Sort by DAG ID (Z-A)</option>
-            </Select>
-          ) : (
-            false
-          )}
+          <Select
+            data-testid="sort-by-select"
+            onChange={handleSortChange}
+            placeholder="Sort by…"
+            value={orderBy}
+            variant="flushed"
+            width="200px"
+          >
+            <option value="dag_display_name">Sort by Display Name (A-Z)</option>
+            <option value="-dag_display_name">
+              Sort by Display Name (A-Z)
+            </option>
+            <option value="next_dagrun">Sort by Next DAG Run (A-Z)</option>
+            <option value="-next_dagrun">Sort by Next DAG Run (Z-A)</option>
+            <option value="last_run_state">Sort by Last Run State (A-Z)</option>
+            <option value="-last_run_state">
+              Sort by Last Run State (Z-A)
+            </option>
+            <option value="last_run_start_date">
+              Sort by Last Run Start Date (A-Z)
+            </option>
+            <option value="-last_run_start_date">
+              Sort by Last Run Start Date (Z-A)
+            </option>
+          </Select>
         </HStack>
       </VStack>
       <ToggleTableDisplay display={display} setDisplay={setDisplay} />


Code review comments:
diff_hunk: @@ -200,21 +200,31 @@ export const DagsList = () => {
           <Heading py={3} size="md">
             {pluralize("DAG", data?.total_entries)}
           </Heading>
-          {display === "card" ? (
path: airflow/ui/src/pages/DagsList/DagsList.tsx
text: @user1:
Let's keep the select only for the card list. But let's drop "sort by last run state", I think last run start_date is fine.

@user1:
We can pass a custom `sortingFn` [docs](https://tanstack.com/table/latest/docs/guide/sorting#sorting-fns) to sort the table view by start_date to the latest_dag_runs column definition.

@author:
Got it.

diff_hunk: @@ -200,21 +200,33 @@ export const DagsList = () => {
           <Heading py={3} size="md">
             {pluralize("DAG", data?.total_entries)}
           </Heading>
-          {display === "card" ? (
-            <Select
-              data-testid="sort-by-select"
-              onChange={handleSortChange}
-              placeholder="Sort by…"
-              value={orderBy}
-              variant="flushed"
-              width="200px"
-            >
-              <option value="dag_id">Sort by DAG ID (A-Z)</option>
-              <option value="-dag_id">Sort by DAG ID (Z-A)</option>
-            </Select>
-          ) : (
-            false
-          )}
+          <Select
+            data-testid="sort-by-select"
+            onChange={handleSortChange}
+            placeholder="Sort by…"
+            value={orderBy}
+            variant="flushed"
+            width="200px"
+          >
+            <option value="dag_display_name">Sort by Display Name (A-Z)</option>
path: airflow/ui/src/pages/DagsList/DagsList.tsx
text: @user1:
I definitely want to move the new UI to only use `dag_display_name`. dag_id is only a detail the user needs for debugging. But yes, we need to update our sorting in FastAPI to fallback to dag_id just like we do for search query.

@user2:
Ok got it. Yes normally default sorting id `dag_id` so we should be able to just remove it.

diff_hunk: @@ -200,21 +200,31 @@ export const DagsList = () => {
           <Heading py={3} size="md">
             {pluralize("DAG", data?.total_entries)}
           </Heading>
-          {display === "card" ? (
-            <Select
-              data-testid="sort-by-select"
-              onChange={handleSortChange}
-              placeholder="Sort by…"
-              value={orderBy}
-              variant="flushed"
-              width="200px"
-            >
-              <option value="dag_id">Sort by DAG ID (A-Z)</option>
-              <option value="-dag_id">Sort by DAG ID (Z-A)</option>
-            </Select>
-          ) : (
-            false
-          )}
+          <Select
+            data-testid="sort-by-select"
+            onChange={handleSortChange}
+            placeholder="Sort by…"
+            value={orderBy}
+            variant="flushed"
+            width="200px"
+          >
+            <option value="dag_display_name">Sort by Display Name (A-Z)</option>
+            <option value="-dag_display_name">
+              Sort by Display Name (A-Z)
+            </option>
+            <option value="next_dagrun">Sort by Next DAG Run (A-Z)</option>
+            <option value="-next_dagrun">Sort by Next DAG Run (Z-A)</option>
+            <option value="last_run_state">Sort by Last Run State (A-Z)</option>
+            <option value="-last_run_state">
+              Sort by Last Run State (Z-A)
+            </option>
+            <option value="last_run_start_date">
+              Sort by Last Run Start Date (A-Z)
+            </option>
+            <option value="-last_run_start_date">
+              Sort by Last Run Start Date (Z-A)
path: airflow/ui/src/pages/DagsList/DagsList.tsx
text: @user1:
A lot of these aren't actually alphabetical searches. Two options:

1. Just put a +/- indicator, even better if we used the same up and down arrow icons as the table sort function
2. Only have one option per select and each time you click it it cycles through asc, desc or removing that sort. With the symbols to match

@user1:
Let's just change the start_date from (A-Z) to (latest-earliest) and we can do the rest later.

@author:
The problem with 2 option is that it would not be user friendly in case of multi selection.

@user1:
Yeah, we can optimize later.