From 8371e6248baf9593bf972ccf343555ab6a456243 Mon Sep 17 00:00:00 2001 From: vasileios Date: Fri, 22 Nov 2024 08:34:51 +0100 Subject: [PATCH] [#4418] Added addressNl specific mappings to ObjectsAPI variable configuration --- src/openforms/api/drf_jsonschema.py | 13 +- src/openforms/api/fields.py | 13 + src/openforms/js/compiled-lang/en.json | 84 ++-- src/openforms/js/compiled-lang/nl.json | 86 ++-- .../admin/form_design/registrations/index.js | 2 +- ...NlObjectsApiVariableConfigurationEditor.js | 378 ++++++++++++++++++ ...icObjectsApiVariableConfigurationEditor.js | 187 +++++++++ .../objectsapi/ObjectsApiSummaryHandler.js | 16 +- .../ObjectsApiVariableConfigurationEditor.js | 264 +++--------- .../variables/VariablesEditor.stories.js | 238 +++++++++++ src/openforms/js/lang/en.json | 50 +++ src/openforms/js/lang/nl.json | 50 +++ .../contrib/objects_api/api/views.py | 1 + .../contrib/objects_api/config.py | 5 +- .../objects_api/submission_registration.py | 50 ++- .../objects_api/tests/test_backend_v2.py | 182 +++++++++ .../contrib/objects_api/typing.py | 14 +- 17 files changed, 1376 insertions(+), 257 deletions(-) create mode 100644 src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js create mode 100644 src/openforms/js/components/admin/form_design/registrations/objectsapi/GenericObjectsApiVariableConfigurationEditor.js diff --git a/src/openforms/api/drf_jsonschema.py b/src/openforms/api/drf_jsonschema.py index b5264333a3..8f6608045c 100644 --- a/src/openforms/api/drf_jsonschema.py +++ b/src/openforms/api/drf_jsonschema.py @@ -10,10 +10,11 @@ from drf_jsonschema_serializer.converters import ( BooleanFieldConverter, PrimaryKeyRelatedFieldConverter, + SerializerJSONFieldConverter, ) from rest_framework import serializers -from .fields import PrimaryKeyRelatedAsChoicesField +from .fields import JSONFieldWithSchema, PrimaryKeyRelatedAsChoicesField @converter @@ -60,3 +61,13 @@ def convert(self, field): ] return result + + +@converter +class JSONFieldConverter(SerializerJSONFieldConverter): + field_class = JSONFieldWithSchema + + def convert(self, field): + schema = super().convert(field) + schema.update(field.schema) + return schema diff --git a/src/openforms/api/fields.py b/src/openforms/api/fields.py index d049019d0d..f107f680f7 100644 --- a/src/openforms/api/fields.py +++ b/src/openforms/api/fields.py @@ -9,6 +9,19 @@ class PrimaryKeyRelatedAsChoicesField(serializers.PrimaryKeyRelatedField): pass +class JSONFieldWithSchema(serializers.JSONField): + """ + Custom subclass to register a custom drf-jsonschema-serializer converter. + """ + + @property + def schema(self): + return { + "type": "object", + "properties": {}, + } + + class RelatedFieldFromContext(serializers.HyperlinkedRelatedField): """ Look up the object in the serializer context. diff --git a/src/openforms/js/compiled-lang/en.json b/src/openforms/js/compiled-lang/en.json index 06f1ee8658..40638e9338 100644 --- a/src/openforms/js/compiled-lang/en.json +++ b/src/openforms/js/compiled-lang/en.json @@ -405,6 +405,12 @@ "value": "API group" } ], + "2nxTFx": [ + { + "type": 0, + "value": "Postcode Schema target" + } + ], "2sbkGI": [ { "type": 0, @@ -949,12 +955,6 @@ "value": "The text that will be displayed in the form step to save the current information. Leave blank to get value from global configuration." } ], - "8M403q": [ - { - "type": 0, - "value": "Soft required fields should be filled out, but empty values don't block the users' progress. Sometimes this is needed for legal reasons. A component cannot be hard and soft required at the same time." - } - ], "8NbOpb": [ { "type": 0, @@ -1825,6 +1825,12 @@ "value": "in" } ], + "F+UwT0": [ + { + "type": 0, + "value": "House letter Schema target" + } + ], "F+cPJR": [ { "type": 0, @@ -1981,6 +1987,12 @@ "value": "The text that will be displayed in the overview page to confirm the form is filled in correctly. Leave blank to get value from global configuration." } ], + "Ggu4I8": [ + { + "type": 0, + "value": "Whether to map the specific subfield of addressNl component" + } + ], "Gi+cvN": [ { "type": 0, @@ -2879,12 +2891,6 @@ "value": "Select existing form definition" } ], - "QL4SGQ": [ - { - "type": 0, - "value": "Soft required" - } - ], "QLTh2N": [ { "type": 0, @@ -3623,6 +3629,12 @@ "value": "Basic" } ], + "Xg9O5Y": [ + { + "type": 0, + "value": "House number Schema target" + } + ], "Xj1uvL": [ { "type": 0, @@ -4545,6 +4557,12 @@ "value": "Payment status update variable mapping" } ], + "fUaRWW": [ + { + "type": 0, + "value": "City Schema target" + } + ], "fWcg7I": [ { "type": 0, @@ -4641,6 +4659,12 @@ "value": "Are you sure that you want to remove this mapping?" } ], + "gdEbdr": [ + { + "type": 0, + "value": "Map specific subfields" + } + ], "gheRkp": [ { "type": 0, @@ -5039,12 +5063,6 @@ "value": "Folder path" } ], - "jtWzSW": [ - { - "type": 0, - "value": "option 2: € 15,99" - } - ], "jy1jTd": [ { "offset": 0, @@ -5481,12 +5499,24 @@ "value": "Tooltip" } ], + "o4AUIi": [ + { + "type": 0, + "value": "Multiple target paths configured" + } + ], "o5Mfn3": [ { "type": 0, "value": "Include children" } ], + "o5iEgm": [ + { + "type": 0, + "value": "JSON Schema object target" + } + ], "o6Ju6l": [ { "type": 0, @@ -5709,6 +5739,12 @@ "value": "Select registration backend" } ], + "pjbN8m": [ + { + "type": 0, + "value": "Street name Schema target" + } + ], "poZZD9": [ { "type": 0, @@ -5963,12 +5999,6 @@ "value": "Regular expression for city" } ], - "sxdJ/8": [ - { - "type": 0, - "value": "option 1: € 10,99" - } - ], "t5fg/K": [ { "type": 0, @@ -6061,6 +6091,12 @@ "value": "Description (omschrijving) of the ROLTYPE to use for employees filling in a form for a citizen/company." } ], + "u/0IPY": [ + { + "type": 0, + "value": "House number addition Schema target" + } + ], "u3P/1E": [ { "type": 0, diff --git a/src/openforms/js/compiled-lang/nl.json b/src/openforms/js/compiled-lang/nl.json index 11b9a0809d..4d40c08e71 100644 --- a/src/openforms/js/compiled-lang/nl.json +++ b/src/openforms/js/compiled-lang/nl.json @@ -405,6 +405,12 @@ "value": "API-groep" } ], + "2nxTFx": [ + { + "type": 0, + "value": "Postcode Schema target" + } + ], "2sbkGI": [ { "type": 0, @@ -953,12 +959,6 @@ "value": "De tekst op de knop om de gegevens van de huidige stap op te slaan en het formulier te onderbreken. Laat dit veld leeg om de standaardinstelling te gebruiken." } ], - "8M403q": [ - { - "type": 0, - "value": "Aangeraden velden moeten in principe ingevuld worden, maar ontbrekende waarden blokkeren de voortgang niet. Dit is soms nodig voor juridische redenen. Een component kan niet tegelijk verplicht en aangeraden zijn." - } - ], "8NbOpb": [ { "type": 0, @@ -1846,6 +1846,12 @@ "value": "in" } ], + "F+UwT0": [ + { + "type": 0, + "value": "House letter Schema target" + } + ], "F+cPJR": [ { "type": 0, @@ -2002,6 +2008,12 @@ "value": "De tekst om de ingevulde gegevens te bevestigen op de overzichtspagina. Laat dit veld leeg om de standaardinstelling te gebruiken." } ], + "Ggu4I8": [ + { + "type": 0, + "value": "Whether to map the specific subfield of addressNl component" + } + ], "Gi+cvN": [ { "type": 0, @@ -2896,12 +2908,6 @@ "value": "Selecteer een bestaande formulierdefinitie" } ], - "QL4SGQ": [ - { - "type": 0, - "value": "Aangeraden (niet-blokkerend verplicht)" - } - ], "QLTh2N": [ { "type": 0, @@ -3163,7 +3169,7 @@ "Su4nqf": [ { "type": 0, - "value": "Welke authenticatiemethode de mede-ondertekenaar moet gebruiken. Let op: Dit moet dezelfde authenticatiemethode zijn als is gebruikt op het formulier." + "value": "Welke authenticatiemethode de mede-ondertekener moet gebruiken. Let op: Dit moet dezelfde authenticatiemethode zijn als is gebruikt op het formulier." } ], "Sw6TLH": [ @@ -3640,6 +3646,12 @@ "value": "Basis" } ], + "Xg9O5Y": [ + { + "type": 0, + "value": "House number Schema target" + } + ], "Xj1uvL": [ { "type": 0, @@ -4567,6 +4579,12 @@ "value": "Payment status update variable mapping" } ], + "fUaRWW": [ + { + "type": 0, + "value": "City Schema target" + } + ], "fWcg7I": [ { "type": 0, @@ -4663,6 +4681,12 @@ "value": "Ben je zeker dat je deze koppeling wil verwijderen?" } ], + "gdEbdr": [ + { + "type": 0, + "value": "Map specific subfields" + } + ], "gheRkp": [ { "type": 0, @@ -5061,12 +5085,6 @@ "value": "Folder path" } ], - "jtWzSW": [ - { - "type": 0, - "value": "optie 2: € 15,99" - } - ], "jy1jTd": [ { "offset": 0, @@ -5503,12 +5521,24 @@ "value": "Tooltip" } ], + "o4AUIi": [ + { + "type": 0, + "value": "Multiple target paths configured" + } + ], "o5Mfn3": [ { "type": 0, "value": "Inclusief kinderen" } ], + "o5iEgm": [ + { + "type": 0, + "value": "JSON Schema object target" + } + ], "o6Ju6l": [ { "type": 0, @@ -5731,6 +5761,12 @@ "value": "Registratiemethode" } ], + "pjbN8m": [ + { + "type": 0, + "value": "Street name Schema target" + } + ], "poZZD9": [ { "type": 0, @@ -5985,12 +6021,6 @@ "value": "Reguliere expressie" } ], - "sxdJ/8": [ - { - "type": 0, - "value": "optie 1: € 10,99" - } - ], "t5fg/K": [ { "type": 0, @@ -6083,6 +6113,12 @@ "value": "Omschrijving van het ROLTYPE voor medewerkers die het formulier voor een burger/bedrijf invullen." } ], + "u/0IPY": [ + { + "type": 0, + "value": "House number addition Schema target" + } + ], "u3P/1E": [ { "type": 0, diff --git a/src/openforms/js/components/admin/form_design/registrations/index.js b/src/openforms/js/components/admin/form_design/registrations/index.js index 82792783f8..dafbebd58f 100644 --- a/src/openforms/js/components/admin/form_design/registrations/index.js +++ b/src/openforms/js/components/admin/form_design/registrations/index.js @@ -4,7 +4,7 @@ import EmailOptionsForm from './email'; import MSGraphOptionsForm from './ms_graph'; import ObjectsApiOptionsForm from './objectsapi/ObjectsApiOptionsForm'; import ObjectsApiSummaryHandler from './objectsapi/ObjectsApiSummaryHandler'; -import ObjectsApiVariableConfigurationEditor from './objectsapi/ObjectsApiVariableConfigurationEditor'; +import {ObjectsApiVariableConfigurationEditor} from './objectsapi/ObjectsApiVariableConfigurationEditor'; import {onCamundaStepEdit, onObjectsAPIStepEdit, onZGWStepEdit} from './stepEditHandlers'; import StufZDSOptionsForm from './stufzds'; import {onObjectsAPIUserDefinedVariableEdit} from './userDefinedVariableEditHandlers'; diff --git a/src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js b/src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js new file mode 100644 index 0000000000..47c8b75a30 --- /dev/null +++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js @@ -0,0 +1,378 @@ +import {FieldArray, useFormikContext} from 'formik'; +import isEqual from 'lodash/isEqual'; +import PropTypes from 'prop-types'; +import React, {useContext} from 'react'; +import {FormattedMessage} from 'react-intl'; +import {useAsync, useToggle} from 'react-use'; + +import {APIContext} from 'components/admin/form_design/Context'; +import {REGISTRATION_OBJECTS_TARGET_PATHS} from 'components/admin/form_design/constants'; +import Field from 'components/admin/forms/Field'; +import Fieldset from 'components/admin/forms/Fieldset'; +import FormRow from 'components/admin/forms/FormRow'; +import {Checkbox} from 'components/admin/forms/Inputs'; +import Select, {LOADING_OPTION} from 'components/admin/forms/Select'; +import ErrorMessage from 'components/errors/ErrorMessage'; +import {post} from 'utils/fetch'; + +import {TargetPathDisplay} from './ObjectsApiVariableConfigurationEditor'; + +const ADDRESSNL_NESTED_PROPERTIES = { + postcode: {type: 'string'}, + houseLetter: {type: 'string'}, + houseNumber: {type: 'number'}, + houseNumberAddition: {type: 'string'}, + city: {type: 'string'}, + streetName: {type: 'string'}, +}; + +const fetchTargetPaths = async ( + csrftoken, + objectsApiGroup, + objecttype, + objecttypeVersion, + schemaType +) => { + const response = await post(REGISTRATION_OBJECTS_TARGET_PATHS, csrftoken, { + objectsApiGroup, + objecttype, + objecttypeVersion, + variableJsonSchema: schemaType, + }); + + if (!response.ok) { + throw new Error(`Error when loading target paths for type: ${schemaType}`); + } + + return response.data; +}; + +export const AddressNlEditor = ({ + variable, + components, + namePrefix, + isGeometry, + index, + mappedVariable, + objecttype, + objectsApiGroup, + objecttypeVersion, +}) => { + const {csrftoken} = useContext(APIContext); + const {values, setFieldValue} = useFormikContext(); + const [jsonSchemaVisible, toggleJsonSchemaVisible] = useToggle(false); + const {specificTargetPaths} = values; + const isSpecificTargetPaths = + specificTargetPaths || + (mappedVariable.options && Object.keys(mappedVariable.options).length > 0); + + const deriveAddress = components[variable?.key]['deriveAddress']; + + // // Load all the possible target paths (obect,string and number types) in parallel and only once + const { + loading, + value: targetPaths, + error, + } = useAsync(async () => { + const schemaTypes = [ + {type: 'object', properties: ADDRESSNL_NESTED_PROPERTIES}, + {type: 'string'}, + {type: 'number'}, + ]; + + const promises = schemaTypes.map(type => + fetchTargetPaths(csrftoken, objectsApiGroup, objecttype, objecttypeVersion, type) + ); + + const results = await Promise.all(promises); + return results; + }, []); + + const [objectTypeTargetPaths = [], stringTypeTargetPaths = [], numberTypeTargetPaths = []] = + targetPaths || []; + + const choicesTypes = { + object: objectTypeTargetPaths, + string: stringTypeTargetPaths, + number: numberTypeTargetPaths, + }; + + const getChoices = type => + loading || error + ? LOADING_OPTION + : choicesTypes[type].map(t => [ + JSON.stringify(t.targetPath), + , + ]); + + const getTargetPath = pathSegment => + objectTypeTargetPaths.find(t => isEqual(t.targetPath, pathSegment)); + + if (error) + return ( + + + + ); + + const onSpecificTargetPathsChange = event => { + setFieldValue('specificTargetPaths', event.target.checked); + + if (event.target.checked) { + setFieldValue(`${namePrefix}.targetPath`, undefined); + } else { + setFieldValue(`${namePrefix}.options.postcode`, undefined); + setFieldValue(`${namePrefix}.options.houseLetter`, undefined); + setFieldValue(`${namePrefix}.options.houseNumber`, undefined); + setFieldValue(`${namePrefix}.options.houseNumberAddition`, undefined); + setFieldValue(`${namePrefix}.options.city`, undefined); + setFieldValue(`${namePrefix}.options.streetName`, undefined); + } + }; + + return ( + <> + + + + } + helpText={ + + } + checked={isSpecificTargetPaths} + onChange={onSpecificTargetPathsChange} + /> + + + + + } + disabled={isSpecificTargetPaths} + > + + + + {isSpecificTargetPaths && ( +
+ + + } + required + > + + + + + + } + required + > + + + + + + } + > + + + + + + } + > + + + + + + } + disabled={!deriveAddress} + > + + + + + + } + disabled={!deriveAddress} + > + + + +
+ )} + {!isSpecificTargetPaths && ( +
+ e.preventDefault() || toggleJsonSchemaVisible()}> + + + {jsonSchemaVisible && ( +
+              {loading || !mappedVariable.targetPath ? (
+                
+              ) : (
+                JSON.stringify(getTargetPath(mappedVariable.targetPath).jsonSchema, null, 2)
+              )}
+            
+ )} +
+ )} + + ); +}; + +const TargetPathSelect = ({id, name, index, choices, mappedVariable, disabled}) => { + // To avoid having an incomplete variable mapping added in the `variablesMapping` array, + // It is added only when an actual target path is selected. This way, having the empty + // option selected means the variable is unmapped (hence the `arrayHelpers.remove` call below). + const { + values: {variablesMapping}, + getFieldProps, + setFieldValue, + } = useFormikContext(); + const props = getFieldProps(name); + const isNew = variablesMapping.length === index; + + return ( + ( + { + if (event.target.value === '') { + arrayHelpers.remove(index); + } else { + if (isNew) { + arrayHelpers.push({...mappedVariable, targetPath: JSON.parse(event.target.value)}); + } else { + setFieldValue(name, JSON.parse(event.target.value)); + } + } + }} + /> + )} + /> + ); +}; + +TargetPathSelect.propTypes = { + name: PropTypes.string.isRequired, + index: PropTypes.number.isRequired, + choices: PropTypes.array.isRequired, + mappedVariable: PropTypes.object.isRequired, +}; diff --git a/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiSummaryHandler.js b/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiSummaryHandler.js index a132077f71..a1b5b5f493 100644 --- a/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiSummaryHandler.js +++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiSummaryHandler.js @@ -31,7 +31,12 @@ const ObjectsApiSummaryHandler = ({variable, backendOptions}) => { mapping => mapping.variableKey === variable.key ); - if (!variableMapping) { + if ( + !variableMapping || + (!variableMapping.targetPath && + variableMapping.options && + !Object.keys(variableMapping.options).length > 0) + ) { return ( { ); } + if (variableMapping.options && Object.keys(variableMapping.options).length > 0) { + return ( + + ); + } + return variableMapping.targetPath .map(p => {p}) .reduce((res, item) => ( diff --git a/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiVariableConfigurationEditor.js b/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiVariableConfigurationEditor.js index 069a2b6cf1..7d99c87432 100644 --- a/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiVariableConfigurationEditor.js +++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/ObjectsApiVariableConfigurationEditor.js @@ -1,24 +1,44 @@ -import {FieldArray, useFormikContext} from 'formik'; -import isEqual from 'lodash/isEqual'; +import {useFormikContext} from 'formik'; import PropTypes from 'prop-types'; import React, {useContext} from 'react'; import {FormattedMessage} from 'react-intl'; -import {useAsync, useToggle} from 'react-use'; -import {APIContext, FormContext} from 'components/admin/form_design/Context'; -import {REGISTRATION_OBJECTS_TARGET_PATHS} from 'components/admin/form_design/constants'; +import {FormContext} from 'components/admin/form_design/Context'; import Field from 'components/admin/forms/Field'; import Fieldset from 'components/admin/forms/Fieldset'; import FormRow from 'components/admin/forms/FormRow'; -import {Checkbox, TextInput} from 'components/admin/forms/Inputs'; -import Select, {LOADING_OPTION} from 'components/admin/forms/Select'; -import ErrorMessage from 'components/errors/ErrorMessage'; -import {post} from 'utils/fetch'; +import {TextInput} from 'components/admin/forms/Inputs'; -import {asJsonSchema} from './utils'; +import {AddressNlEditor} from './AddressNlObjectsApiVariableConfigurationEditor'; +import {GenericEditor} from './GenericObjectsApiVariableConfigurationEditor'; + +// This can be updated with component-specific variable configuration options which do not +// adhere to the generic behaviour (GenericEditor) +const VARIABLE_CONFIGURATION_OPTIONS = { + addressNL: AddressNlEditor, +}; + +const TargetPathDisplay = ({target}) => { + const path = target.targetPath.length ? target.targetPath.join(' > ') : '/ (root)'; + return ( + + ); +}; + +TargetPathDisplay.propTypes = { + target: PropTypes.shape({ + targetPath: PropTypes.arrayOf(PropTypes.string).isRequired, + isRequired: PropTypes.bool.isRequired, + }).isRequired, +}; /** - * Returns the Objects API Configuration editor modal for a specific variable. This only applies to V2 Options + * Returns the Objects API Configuration editor modal for a specific variable and a specific + * component type. This only applies to V2 Options * * @typedef {{ * version: 1 | 2; @@ -34,10 +54,8 @@ import {asJsonSchema} from './utils'; * @returns {JSX.Element} - The configuration form for the Objects API */ const ObjectsApiVariableConfigurationEditor = ({variable}) => { - const {csrftoken} = useContext(APIContext); - const {components} = useContext(FormContext); - const [jsonSchemaVisible, toggleJsonSchemaVisible] = useToggle(false); const {values: backendOptions, getFieldProps, setFieldValue} = useFormikContext(); + const {components} = useContext(FormContext); /** @type {ObjectsAPIRegistrationBackendOptions} */ const { @@ -71,126 +89,42 @@ const ObjectsApiVariableConfigurationEditor = ({variable}) => { // relative to that const namePrefix = `variablesMapping.${index}`; - const { - loading, - value: targetPaths, - error, - } = useAsync( - async () => { - const response = await post(REGISTRATION_OBJECTS_TARGET_PATHS, csrftoken, { - objectsApiGroup, - objecttype, - objecttypeVersion, - variableJsonSchema: asJsonSchema(variable, components), - }); - if (!response.ok) { - throw new Error('Error when loading target paths'); - } - - return response.data; - }, - // Load only once: - [] - ); - - const getTargetPath = pathSegment => targetPaths.find(t => isEqual(t.targetPath, pathSegment)); - - const choices = - loading || error - ? LOADING_OPTION - : targetPaths.map(t => [JSON.stringify(t.targetPath), ]); - - if (error) - return ( - - - - ); + // check if there is a specific ConfigurationEditor according to the variable type, + // if not, fallback to the default/generic one + const componentType = components[variable?.key]?.type; + const VariableConfigurationEditor = + VARIABLE_CONFIGURATION_OPTIONS?.[componentType] ?? GenericEditor; return ( -
- - - } - > - - - - - - } - helpText={ - record.geometry}} - /> - } - name="geometryVariableKey" - disabled={!!mappedVariable.targetPath} - > - { - const newValue = event.target.checked ? variable.key : undefined; - setFieldValue('geometryVariableKey', newValue); - }} - /> - - - - +
+ + + } + > + - } - disabled={isGeometry} - > - - - -
- e.preventDefault() || toggleJsonSchemaVisible()}> - - - {jsonSchemaVisible && ( -
-            {loading || !mappedVariable.targetPath ? (
-              
-            ) : (
-              JSON.stringify(getTargetPath(mappedVariable.targetPath).jsonSchema, null, 2)
-            )}
-          
- )} -
-
+
+
+ +
+ ); }; @@ -200,70 +134,4 @@ ObjectsApiVariableConfigurationEditor.propTypes = { }).isRequired, }; -const TargetPathSelect = ({name, index, choices, mappedVariable, disabled}) => { - // To avoid having an incomplete variable mapping added in the `variablesMapping` array, - // It is added only when an actual target path is selected. This way, having the empty - // option selected means the variable is unmapped (hence the `arrayHelpers.remove` call below). - const { - values: {variablesMapping}, - getFieldProps, - setFieldValue, - } = useFormikContext(); - const props = getFieldProps(name); - const isNew = variablesMapping.length === index; - - return ( - ( -