This is an automated email from the ASF dual-hosted git repository. ephraimanierobi pushed a commit to branch v2-6-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit b07ee7dd4e19ca929627b0cb913db4a925c9503a Author: herlambang <[email protected]> AuthorDate: Sat May 6 19:20:01 2023 +0700 Fix template error when iterating None value and fix params documentation (#31078) * Check if form value is iterable * Update doc params list to array * Add test render, prevent value mutaion in js (cherry picked from commit b8b18bd74b72edc4b40e91258fccc54cf3aff3c1) --- airflow/www/static/js/trigger.js | 2 +- airflow/www/templates/airflow/trigger.html | 8 +++++--- docs/apache-airflow/core-concepts/params.rst | 2 +- tests/www/views/test_views_trigger_dag.py | 26 ++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/airflow/www/static/js/trigger.js b/airflow/www/static/js/trigger.js index 22fa0fda53..27fcc09972 100644 --- a/airflow/www/static/js/trigger.js +++ b/airflow/www/static/js/trigger.js @@ -46,7 +46,7 @@ function updateJSONconf() { values[values.length] = lines[j].trim(); } } - params[keyName] = values; + params[keyName] = values.length === 0 ? params[keyName] : values; } else if (elements[i].value.length === 0) { params[keyName] = null; } else if ( diff --git a/airflow/www/templates/airflow/trigger.html b/airflow/www/templates/airflow/trigger.html index 34ce50833e..f98e31b0c9 100644 --- a/airflow/www/templates/airflow/trigger.html +++ b/airflow/www/templates/airflow/trigger.html @@ -80,9 +80,11 @@ {% elif form_details.schema and "array" in form_details.schema.type %} <textarea class="form-control" name="element_{{ form_key }}" id="element_{{ form_key }}" valuetype="array" rows="6" {%- if not "null" in form_details.schema.type %} required=""{% endif -%}> - {%- for txt in form_details.value -%} - {{ txt }}{{ "\n" }} - {%- endfor -%} + {%- if form_details.value is sequence %} + {%- for txt in form_details.value -%} + {{ txt }}{{ "\n" }} + {%- endfor -%} + {% endif -%} </textarea> {% elif form_details.schema and "object" in form_details.schema.type %} <textarea class="form-control" name="element_{{ form_key }}" id="element_{{ form_key }}" valuetype="object" rows="6" diff --git a/docs/apache-airflow/core-concepts/params.rst b/docs/apache-airflow/core-concepts/params.rst index 02732516c1..eacaef3c5d 100644 --- a/docs/apache-airflow/core-concepts/params.rst +++ b/docs/apache-airflow/core-concepts/params.rst @@ -189,7 +189,7 @@ The following features are supported in the Trigger UI Form: You can add the parameters ``minimum`` and ``maximum`` to restrict number range accepted. - ``boolean``: Generates a toggle button to be used as ``True`` or ``False``. - ``date``, ``datetime`` and ``time``: Generate date and/or time picker - - ``list``: Generates a HTML multi line text field, every line edited will be made into a string array as value + - ``array``: Generates a HTML multi line text field, every line edited will be made into a string array as value - ``object``: Generates a JSON entry field - Note: Per default if you specify a type, a field will be made required with input - because of JSON validation. If you want to have a field value being added optional only, you must allow JSON schema validation allowing null values via: diff --git a/tests/www/views/test_views_trigger_dag.py b/tests/www/views/test_views_trigger_dag.py index 6e793ed0d4..1c7cc5827e 100644 --- a/tests/www/views/test_views_trigger_dag.py +++ b/tests/www/views/test_views_trigger_dag.py @@ -260,3 +260,29 @@ def test_viewer_cant_trigger_dag(app): resp = client.get(url, follow_redirects=True) response_data = resp.data.decode() assert "Access is Denied" in response_data + + +def test_trigger_dag_params_array_value_none_render(admin_client, dag_maker, session, app, monkeypatch): + """ + Test that textarea in Trigger DAG UI is pre-populated + with param value None and type ["null", "array"] set in DAG. + """ + expected_conf = {"dag_param": None} + expected_dag_conf = json.dumps(expected_conf, indent=4).replace('"', """) + DAG_ID = "params_dag" + param = Param( + None, + type=["null", "array"], + minItems=0, + ) + with monkeypatch.context() as m: + with dag_maker(dag_id=DAG_ID, serialized=True, session=session, params={"dag_param": param}): + EmptyOperator(task_id="task1") + + m.setattr(app, "dag_bag", dag_maker.dagbag) + resp = admin_client.get(f"trigger?dag_id={DAG_ID}") + + check_content_in_response( + f'<textarea style="display: none;" id="json_start" name="json_start">{expected_dag_conf}</textarea>', + resp, + )
