diff --git a/src/openforms/js/compiled-lang/en.json b/src/openforms/js/compiled-lang/en.json
index e2f7fe336b..c4c3900c1f 100644
--- a/src/openforms/js/compiled-lang/en.json
+++ b/src/openforms/js/compiled-lang/en.json
@@ -1973,6 +1973,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,
@@ -2127,6 +2133,12 @@
"value": "Successful Submissions Removal Method field label"
}
],
+ "I3bGFV": [
+ {
+ "type": 0,
+ "value": "House number Schema target"
+ }
+ ],
"I3zyib": [
{
"type": 0,
@@ -4375,6 +4387,12 @@
"value": "Attachments"
}
],
+ "eD5x1W": [
+ {
+ "type": 0,
+ "value": "House letter Schema target"
+ }
+ ],
"eJEu3L": [
{
"type": 0,
@@ -4585,6 +4603,12 @@
"value": "Are you sure that you want to remove this mapping?"
}
],
+ "gdEbdr": [
+ {
+ "type": 0,
+ "value": "Map specific subfields"
+ }
+ ],
"gheRkp": [
{
"type": 0,
@@ -5303,6 +5327,12 @@
"value": "Something went wrong while retrieving the available object type versions."
}
],
+ "ndWy6O": [
+ {
+ "type": 0,
+ "value": "City Schema target"
+ }
+ ],
"neCqv9": [
{
"type": 0,
@@ -5327,6 +5357,12 @@
"value": "Tooltip"
}
],
+ "o4AUIi": [
+ {
+ "type": 0,
+ "value": "Multiple target paths configured"
+ }
+ ],
"o5Mfn3": [
{
"type": 0,
@@ -5339,6 +5375,12 @@
"value": "The email addresses to which the submission details will be sent"
}
],
+ "o5iEgm": [
+ {
+ "type": 0,
+ "value": "JSON Schema object target"
+ }
+ ],
"o83CBr": [
{
"type": 0,
@@ -5735,6 +5777,12 @@
"value": "If specified, the user must check at most this many options."
}
],
+ "sTZk2h": [
+ {
+ "type": 0,
+ "value": "Street name Schema target"
+ }
+ ],
"sU/n0S": [
{
"type": 0,
@@ -5879,6 +5927,12 @@
"value": "Footer"
}
],
+ "u7m/jP": [
+ {
+ "type": 0,
+ "value": "Postcode Schema target"
+ }
+ ],
"uBO/Al": [
{
"type": 0,
@@ -6161,6 +6215,12 @@
"value": "Create definition"
}
],
+ "xhwyFo": [
+ {
+ "type": 0,
+ "value": "House number addition Schema target"
+ }
+ ],
"xxVNeU": [
{
"type": 0,
diff --git a/src/openforms/js/compiled-lang/nl.json b/src/openforms/js/compiled-lang/nl.json
index 7354935a39..91920943b7 100644
--- a/src/openforms/js/compiled-lang/nl.json
+++ b/src/openforms/js/compiled-lang/nl.json
@@ -1994,6 +1994,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,
@@ -2148,6 +2154,12 @@
"value": "Opschoonmethode voor voltooide inzendingen"
}
],
+ "I3bGFV": [
+ {
+ "type": 0,
+ "value": "House number Schema target"
+ }
+ ],
"I3zyib": [
{
"type": 0,
@@ -4397,6 +4409,12 @@
"value": "Attachments"
}
],
+ "eD5x1W": [
+ {
+ "type": 0,
+ "value": "House letter Schema target"
+ }
+ ],
"eJEu3L": [
{
"type": 0,
@@ -4607,6 +4625,12 @@
"value": "Ben je zeker dat je deze koppeling wil verwijderen?"
}
],
+ "gdEbdr": [
+ {
+ "type": 0,
+ "value": "Map specific subfields"
+ }
+ ],
"gheRkp": [
{
"type": 0,
@@ -5325,6 +5349,12 @@
"value": "Er ging iets fout bij het ophalen van de objecttypeversies."
}
],
+ "ndWy6O": [
+ {
+ "type": 0,
+ "value": "City Schema target"
+ }
+ ],
"neCqv9": [
{
"type": 0,
@@ -5349,6 +5379,12 @@
"value": "Tooltip"
}
],
+ "o4AUIi": [
+ {
+ "type": 0,
+ "value": "Multiple target paths configured"
+ }
+ ],
"o5Mfn3": [
{
"type": 0,
@@ -5361,6 +5397,12 @@
"value": "The email addresses to which the submission details will be sent"
}
],
+ "o5iEgm": [
+ {
+ "type": 0,
+ "value": "JSON Schema object target"
+ }
+ ],
"o83CBr": [
{
"type": 0,
@@ -5757,6 +5799,12 @@
"value": "Indien opgegeven, dan mag de gebruiker maximaal dit aantal opties aanvinken."
}
],
+ "sTZk2h": [
+ {
+ "type": 0,
+ "value": "Street name Schema target"
+ }
+ ],
"sU/n0S": [
{
"type": 0,
@@ -5901,6 +5949,12 @@
"value": "Voettekst"
}
],
+ "u7m/jP": [
+ {
+ "type": 0,
+ "value": "Postcode Schema target"
+ }
+ ],
"uBO/Al": [
{
"type": 0,
@@ -6183,6 +6237,12 @@
"value": "Formulierdefinitie aanmaken"
}
],
+ "xhwyFo": [
+ {
+ "type": 0,
+ "value": "House number addition Schema target"
+ }
+ ],
"xxVNeU": [
{
"type": 0,
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..7fc71c11c3
--- /dev/null
+++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js
@@ -0,0 +1,340 @@
+import {FieldArray, useFormikContext} from 'formik';
+import isEqual from 'lodash/isEqual';
+import PropTypes from 'prop-types';
+import React, {useContext, useState} 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';
+
+const ADDRESSNL_NESTED_PROPERTIES = {
+ postcode: {type: 'string'},
+ houseLetter: {type: 'string'},
+ houseNumber: {type: 'string'},
+ houseNumberAddition: {type: 'string'},
+ city: {type: 'string'},
+ streetName: {type: 'string'},
+};
+
+const asJsonSchema = isSpecificTargetPaths => {
+ // Special handling for addressNL component type.
+ if (!isSpecificTargetPaths) {
+ return {
+ type: 'object',
+ properties: ADDRESSNL_NESTED_PROPERTIES,
+ };
+ } else {
+ return {
+ type: 'string',
+ };
+ }
+};
+
+export const AddressNlEditor = ({
+ variable,
+ components,
+ namePrefix,
+ isGeometry,
+ index,
+ mappedVariable,
+ objecttype,
+ objectsApiGroup,
+ objecttypeVersion,
+ TargetPathDisplay,
+}) => {
+ const {csrftoken} = useContext(APIContext);
+ const {values, setValues, setFieldValue} = useFormikContext();
+ const [jsonSchemaVisible, toggleJsonSchemaVisible] = useToggle(false);
+ const {specificTargetPaths} = values;
+ const [isSpecificTargetPaths, setIsSpecificTargetPaths] = useState(specificTargetPaths || false);
+
+ const deriveAddress = components[variable?.key]['deriveAddress'];
+
+ const {
+ loading,
+ value: targetPaths,
+ error,
+ } = useAsync(async () => {
+ const response = await post(REGISTRATION_OBJECTS_TARGET_PATHS, csrftoken, {
+ objectsApiGroup,
+ objecttype,
+ objecttypeVersion,
+ variableJsonSchema: asJsonSchema(isSpecificTargetPaths),
+ });
+ if (!response.ok) {
+ throw new Error('Error when loading target paths');
+ }
+
+ return response.data;
+ }, [isSpecificTargetPaths]);
+
+ 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 (
+
+
+
+ );
+
+ const onSpecificTargetPathsChange = event => {
+ setIsSpecificTargetPaths(event.target.checked);
+
+ if (event.target.checked) {
+ setFieldValue(`${namePrefix}.targetPath`, undefined);
+ }
+
+ // update Formik's state in order to be able to have this value as the default one for the React's state
+ setValues({
+ ...values,
+ specificTargetPaths: event.target.checked,
+ });
+ };
+
+ return (
+ <>
+
+
+ }
+ disabled={isSpecificTargetPaths}
+ >
+
+
+
+ }
+ helpText={
+
+ }
+ disabled={!!mappedVariable.targetPath}
+ >
+
+
+
+ {isSpecificTargetPaths && (
+
+ )}
+
+
e.preventDefault() || toggleJsonSchemaVisible()}>
+
+
+ {jsonSchemaVisible && (
+
+ {loading || (!mappedVariable.targetPath && !isSpecificTargetPaths) ? (
+
+ ) : isSpecificTargetPaths ? (
+ JSON.stringify(ADDRESSNL_NESTED_PROPERTIES, null, 2)
+ ) : (
+ 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 (
+ (
+