This is an automated email from the ASF dual-hosted git repository.
ash 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 29afd35b9c Enable clicking on DAG owner in autocomplete dropdown
(#23804)
29afd35b9c is described below
commit 29afd35b9cfe141b668ce7ceccecdba60775a8ff
Author: Mark Norman Francis <[email protected]>
AuthorDate: Tue May 24 14:43:23 2022 +0100
Enable clicking on DAG owner in autocomplete dropdown (#23804)
PR#18991 introduced directly navigating to a DAG when selecting one
from the typeahead search results. Unfortunately, the search results
also includes DAG owner names, and selecting one of those navigates to
a DAG with that name, which almost certainly doesn't exist.
This extends the autocompletion endpoint to return the type of result,
and adjusts the typeahead selection to use this to know which way to
navigate.
---
airflow/www/static/js/dags.js | 11 +++++++----
airflow/www/views.py | 21 ++++++++++++++-------
tests/www/views/test_views_acl.py | 10 +++++++---
3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/airflow/www/static/js/dags.js b/airflow/www/static/js/dags.js
index 99816c2508..d93216d32d 100644
--- a/airflow/www/static/js/dags.js
+++ b/airflow/www/static/js/dags.js
@@ -124,10 +124,13 @@ $('.typeahead').typeahead({
},
autoSelect: false,
afterSelect(value) {
- const dagId = value.trim();
- if (dagId) {
- const query = new URLSearchParams(window.location.search);
- window.location = `${gridUrl.replace('__DAG_ID__', dagId)}?${query}`;
+ const query = new URLSearchParams(window.location.search);
+ query.set('search', value.name);
+ if (value.type === 'owner') {
+ window.location = `${DAGS_INDEX}?${query}`;
+ }
+ if (value.type === 'dag') {
+ window.location = `${gridUrl.replace('__DAG_ID__',
value.name)}?${query}`;
}
},
});
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 7d814cccff..4c3d33a6b1 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -5113,12 +5113,18 @@ class AutocompleteView(AirflowBaseView):
return wwwutils.json_response([])
# Provide suggestions of dag_ids and owners
- dag_ids_query = session.query(DagModel.dag_id.label('item')).filter(
- ~DagModel.is_subdag, DagModel.is_active, DagModel.dag_id.ilike('%'
+ query + '%')
- )
+ dag_ids_query = session.query(
+ sqla.literal('dag').label('type'),
+ DagModel.dag_id.label('name'),
+ ).filter(~DagModel.is_subdag, DagModel.is_active,
DagModel.dag_id.ilike('%' + query + '%'))
- owners_query =
session.query(func.distinct(DagModel.owners).label('item')).filter(
- ~DagModel.is_subdag, DagModel.is_active, DagModel.owners.ilike('%'
+ query + '%')
+ owners_query = (
+ session.query(
+ sqla.literal('owner').label('type'),
+ DagModel.owners.label('name'),
+ )
+ .distinct()
+ .filter(~DagModel.is_subdag, DagModel.is_active,
DagModel.owners.ilike('%' + query + '%'))
)
# Hide DAGs if not showing status: "all"
@@ -5135,8 +5141,9 @@ class AutocompleteView(AirflowBaseView):
dag_ids_query =
dag_ids_query.filter(DagModel.dag_id.in_(filter_dag_ids))
owners_query = owners_query.filter(DagModel.dag_id.in_(filter_dag_ids))
- payload = [row[0] for row in
dag_ids_query.union(owners_query).limit(10).all()]
-
+ payload = [
+ row._asdict() for row in
dag_ids_query.union(owners_query).order_by('name').limit(10).all()
+ ]
return wwwutils.json_response(payload)
diff --git a/tests/www/views/test_views_acl.py
b/tests/www/views/test_views_acl.py
index 85c787f492..d96098a5c6 100644
--- a/tests/www/views/test_views_acl.py
+++ b/tests/www/views/test_views_acl.py
@@ -244,11 +244,15 @@ def test_index_failure(dag_test_client):
def test_dag_autocomplete_success(client_all_dags):
resp = client_all_dags.get(
- 'dagmodel/autocomplete?query=example_bash',
+ 'dagmodel/autocomplete?query=flow',
follow_redirects=False,
)
- check_content_in_response('example_bash_operator', resp)
- check_content_not_in_response('example_subdag_operator', resp)
+ assert resp.json == [
+ {'name': 'airflow', 'type': 'owner'},
+ {'name': 'test_mapped_taskflow', 'type': 'dag'},
+ {'name': 'tutorial_taskflow_api_etl', 'type': 'dag'},
+ {'name': 'tutorial_taskflow_api_etl_virtualenv', 'type': 'dag'},
+ ]
@pytest.mark.parametrize(