This is an automated email from the ASF dual-hosted git repository. jedcunningham pushed a commit to branch v2-3-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 14b1ea9ababac400b09507b5211f8231ba6a6b7f 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. (cherry picked from commit 29afd35b9cfe141b668ce7ceccecdba60775a8ff) --- 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 3ada349fb8..56afe8b48e 100644 --- a/airflow/www/static/js/dags.js +++ b/airflow/www/static/js/dags.js @@ -119,10 +119,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 b2360fca81..0ae53e5a5f 100644 --- a/airflow/www/views.py +++ b/airflow/www/views.py @@ -5112,12 +5112,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" @@ -5134,8 +5140,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(
