This is an automated email from the ASF dual-hosted git repository.
eladkal 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 da6931561f Add support for arrays of different data types in the
Trigger Form UI (#32734)
da6931561f is described below
commit da6931561f59a64f6489c56a5675c2cc6e6a2bca
Author: Matthieu Blais <[email protected]>
AuthorDate: Thu Aug 3 17:02:34 2023 +0800
Add support for arrays of different data types in the Trigger Form UI
(#32734)
* Add JSON field for complex arrays with types other than string
---------
Co-authored-by: Matthieu Blais <[email protected]>
Co-authored-by: Jens Scheffler
<[email protected]>
Co-authored-by: eladkal <[email protected]>
---
airflow/example_dags/example_params_ui_tutorial.py | 22 ++++++++++++++++++++++
airflow/www/static/js/trigger.js | 11 ++++++++---
airflow/www/templates/airflow/trigger.html | 9 ++++++++-
docs/apache-airflow/core-concepts/params.rst | 5 ++++-
4 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/airflow/example_dags/example_params_ui_tutorial.py
b/airflow/example_dags/example_params_ui_tutorial.py
index c07f9fc7c2..cb25b1b408 100644
--- a/airflow/example_dags/example_params_ui_tutorial.py
+++ b/airflow/example_dags/example_params_ui_tutorial.py
@@ -127,6 +127,14 @@ with DAG(
# Note: Value display mapping does not need to be complete.s
},
),
+ # An array of numbers
+ "array_of_numbers": Param(
+ [1, 2, 3],
+ "Only integers are accepted in this array",
+ type="array",
+ title="Array of numbers",
+ items={"type": "number"},
+ ),
# Boolean as proper parameter with description
"bool": Param(
True,
@@ -208,6 +216,20 @@ with DAG(
title="JSON entry field",
section="Special advanced stuff with form fields",
),
+ "array_of_objects": Param(
+ [{"name": "account_name", "country": "country_name"}],
+ "Array with complex objects and validation rules. "
+ "See <a href='https://json-schema.org/understanding-json-schema"
+ "/reference/array.html#items'>JSON Schema validation options in
specs.</a>",
+ type="array",
+ title="JSON array field",
+ items={
+ "type": "object",
+ "properties": {"name": {"type": "string"}, "country_name":
{"type": "string"}},
+ "required": ["name"],
+ },
+ section="Special advanced stuff with form fields",
+ ),
# If you want to have static parameters which are always passed and
not editable by the user
# then you can use the JSON schema option of passing constant values.
These parameters
# will not be displayed but passed to the DAG
diff --git a/airflow/www/static/js/trigger.js b/airflow/www/static/js/trigger.js
index 6ada3d615e..2ded629240 100644
--- a/airflow/www/static/js/trigger.js
+++ b/airflow/www/static/js/trigger.js
@@ -63,7 +63,8 @@ function updateJSONconf() {
params[keyName] = null;
} else if (
elements[i].attributes.valuetype &&
- elements[i].attributes.valuetype.value === "object"
+ (elements[i].attributes.valuetype.value === "object" ||
+ elements[i].attributes.valuetype.value === "advancedarray")
) {
try {
const textValue = objectFields.get(elements[i].name).getValue();
@@ -112,6 +113,7 @@ function initForm() {
mode: { name: "javascript", json: true },
gutters: ["CodeMirror-lint-markers"],
lint: true,
+ indentUnit: 4,
});
jsonForm.setSize(null, height);
@@ -122,7 +124,8 @@ function initForm() {
if (elements[i].name && elements[i].name.startsWith("element_")) {
if (
elements[i].attributes.valuetype &&
- elements[i].attributes.valuetype.value === "object"
+ (elements[i].attributes.valuetype.value === "object" ||
+ elements[i].attributes.valuetype.value === "advancedarray")
) {
// Apply JSON formatting and linting to all object fields in the form
const field = CodeMirror.fromTextArea(elements[i], {
@@ -130,6 +133,7 @@ function initForm() {
mode: { name: "javascript", json: true },
gutters: ["CodeMirror-lint-markers"],
lint: true,
+ indentUnit: 4,
});
field.on("blur", updateJSONconf);
objectFields.set(elements[i].name, field);
@@ -230,7 +234,8 @@ function setRecentConfig(e) {
element.value = newValue.join("\n");
} else if (
element.attributes.valuetype &&
- element.attributes.valuetype.value === "object"
+ (element.attributes.valuetype.value === "object" ||
+ element.attributes.valuetype.value === "advancedarray")
) {
objectFields
.get(`element_${keys[i]}`)
diff --git a/airflow/www/templates/airflow/trigger.html
b/airflow/www/templates/airflow/trigger.html
index e8965c3654..69f168db52 100644
--- a/airflow/www/templates/airflow/trigger.html
+++ b/airflow/www/templates/airflow/trigger.html
@@ -86,7 +86,14 @@
{% endfor -%}
</select>
{% elif form_details.schema and "array" in form_details.schema.type %}
- {% if "examples" in form_details.schema and form_details.schema.examples
%}
+ {% if "items" in form_details.schema and form_details.schema.items %}
+ <textarea class="form-control" name="element_{{ form_key }}"
id="element_{{ form_key }}" valuetype="advancedarray" rows="6"
+ {%- if not "null" in form_details.schema.type %} required=""{% endif
-%}>
+ {%- if form_details.value is sequence %}
+ {{- form_details.value | tojson() -}}
+ {% endif -%}
+ </textarea>
+ {% elif "examples" in form_details.schema and
form_details.schema.examples %}
<select multiple name="element_{{ form_key }}" id="element_{{ form_key
}}" class="select2-drop-mask" valuetype="multiselect"
onchange="updateJSONconf();"{% if not "null" in
form_details.schema.type %} required=""{% endif %}>
{% for option in form_details.schema.examples -%}
diff --git a/docs/apache-airflow/core-concepts/params.rst
b/docs/apache-airflow/core-concepts/params.rst
index 7619d56171..4159231505 100644
--- a/docs/apache-airflow/core-concepts/params.rst
+++ b/docs/apache-airflow/core-concepts/params.rst
@@ -190,7 +190,10 @@ The following features are supported in the Trigger UI
Form:
- ``boolean``: Generates a toggle button to be used as ``True`` or
``False``.
- ``date``, ``datetime`` and ``time``: Generate date and/or time picker
- ``array``: Generates a HTML multi line text field, every line edited
will be made into a string array as value.
- if you add the attribute ``example`` with a list, a multi-value select
option will be generated.
+ If you add the attribute ``example`` with a list, a multi-value select
option will be generated.
+ If you add the attribute ``items``, a JSON entry field will be generated
for more array types
+ and additional type validation as described in
+ `JSON Schema Array Items
<https://json-schema.org/understanding-json-schema/reference/array.html#items>`_.
- ``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: