Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance User Experience by Opening external UI Links in new Tab on browser. #40635

Merged
merged 12 commits into from
Jul 9, 2024
2 changes: 1 addition & 1 deletion airflow/www/templates/airflow/providers.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h2>{{ title }}</h2>

{% for provider in providers %}
<tr>
<td><a href="{{ provider['documentation_url'] }}">{{ provider["package_name"] }}</a></td>
<td><a href="{{ provider['documentation_url'] }}" target="_blank" rel="noopener noreferrer">{{ provider["package_name"] }}</a></td>
<td>{{ provider["version"] }}</td>
<td>{{ provider["description"]}}</td>
</tr>
Expand Down
14 changes: 13 additions & 1 deletion airflow/www/templates/appbuilder/navbar_menu.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,20 @@
under the License.
#}

{% set external_menu_url_prefixes = [
'https://github.com',
'https://airflow.apache.org',
'http://apache-airflow-docs.s3-website.eu-central-1.amazonaws.com']
%}

{% macro menu_item(item) %}
<a href="{{item.get_url()}}">{{_(item.label)}}</a>
{% set url = item.get_url() %}
{% set prefix = "/".join(url.split("/")[:3]) %}
{% if prefix in external_menu_url_prefixes %}
<a href="{{ url }}" target="_blank" rel="noopener noreferrer">{{ item.label }}</a>
{% else %}
<a href="{{ url }}">{{ item.label }}</a>
{% endif %}
{% endmacro %}

{% for item1 in auth_manager.filter_permitted_menu_items(menu.get_list()) %}
Expand Down
4 changes: 2 additions & 2 deletions airflow/www/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4514,13 +4514,13 @@ def _build_link(match_obj):
text = match_obj.group(1)
url = match_obj.group(2)

# parsing the url to check if ita a valid url
# parsing the url to check if it's a valid url
parsed_url = urlparse(url)
if not (parsed_url.scheme == "http" or parsed_url.scheme == "https"):
# returning the original raw text
return escape(match_obj.group(0))

return Markup(f'<a href="{url}">{text}</a>')
return Markup(f'<a href="{url}" target="_blank" rel="noopener noreferrer">{text}</a>')

cd = escape(description)
cd = re2.sub(r"`(.*)[\s+]+&lt;(.*)&gt;`__", _build_link, cd)
Expand Down
3 changes: 2 additions & 1 deletion chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ airflowLocalSettings: |-
UIAlert(
'Usage of a dynamic webserver secret key detected. We recommend a static webserver secret key instead.'
' See the <a href='
'"https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#webserver-secret-key">'
'"https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#webserver-secret-key" '
'target="_blank" rel="noopener noreferrer">'
'Helm Chart Production Guide</a> for more details.',
category="warning",
roles=["Admin"],
Expand Down
17 changes: 11 additions & 6 deletions tests/www/views/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ def test_should_list_providers_on_page_with_details(admin_client):
resp = admin_client.get("/provider")
beam_href = '<a href="https://airflow.apache.org/docs/apache-airflow-providers-apache-beam/'
beam_text = "apache-airflow-providers-apache-beam</a>"
beam_description = '<a href="https://beam.apache.org/">Apache Beam</a>'
beam_description = (
'<a href="https://beam.apache.org/" target="_blank" rel="noopener noreferrer">Apache Beam</a>'
)
check_content_in_response(beam_href, resp)
check_content_in_response(beam_text, resp)
check_content_in_response(beam_description, resp)
Expand All @@ -147,20 +149,23 @@ def test_should_list_providers_on_page_with_details(admin_client):
@pytest.mark.parametrize(
"provider_description, expected",
[
("`Airbyte <https://airbyte.com/>`__", Markup('<a href="https://airbyte.com/">Airbyte</a>')),
(
"`Airbyte <https://airbyte.com/>`__",
Markup('<a href="https://airbyte.com/" target="_blank" rel="noopener noreferrer">Airbyte</a>'),
),
(
"Amazon integration (including `Amazon Web Services (AWS) <https://aws.amazon.com/>`__).",
Markup(
'Amazon integration (including <a href="https://aws.amazon.com/">Amazon Web Services ('
"AWS)</a>)."
'Amazon integration (including <a href="https://aws.amazon.com/" '
'target="_blank" rel="noopener noreferrer">Amazon Web Services (AWS)</a>).'
),
),
(
"`Java Database Connectivity (JDBC) <https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc"
"/>`__",
Markup(
'<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/">Java '
"Database Connectivity (JDBC)</a>"
'<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/" '
'target="_blank" rel="noopener noreferrer">Java Database Connectivity (JDBC)</a>'
),
),
(
Expand Down