diff --git a/airflow/example_dags/example_params_ui_tutorial.py b/airflow/example_dags/example_params_ui_tutorial.py index c07f9fc7c2bd9..cb25b1b4084d6 100644 --- a/airflow/example_dags/example_params_ui_tutorial.py +++ b/airflow/example_dags/example_params_ui_tutorial.py @@ -127,6 +127,14 @@ # 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 @@ 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 JSON Schema validation options in specs.", + 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 6ada3d615eaed..2ded629240146 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 e8965c365406c..69f168db521e2 100644 --- a/airflow/www/templates/airflow/trigger.html +++ b/airflow/www/templates/airflow/trigger.html @@ -86,7 +86,14 @@ {% endfor -%} {% 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 %} + + {% elif "examples" in form_details.schema and form_details.schema.examples %}