diff --git a/src/openforms/js/compiled-lang/en.json b/src/openforms/js/compiled-lang/en.json
index 35e9958410..790c4a6d3e 100644
--- a/src/openforms/js/compiled-lang/en.json
+++ b/src/openforms/js/compiled-lang/en.json
@@ -6427,6 +6427,12 @@
"value": "Variable"
}
],
+ "xBb5YI": [
+ {
+ "type": 0,
+ "value": "Select an object type and version before you can pick a source path."
+ }
+ ],
"xI6md8": [
{
"type": 0,
diff --git a/src/openforms/js/compiled-lang/nl.json b/src/openforms/js/compiled-lang/nl.json
index 2c2060d55b..e354b6c13e 100644
--- a/src/openforms/js/compiled-lang/nl.json
+++ b/src/openforms/js/compiled-lang/nl.json
@@ -6449,6 +6449,12 @@
"value": "Variabele"
}
],
+ "xBb5YI": [
+ {
+ "type": 0,
+ "value": "Select an object type and version before you can pick a source path."
+ }
+ ],
"xI6md8": [
{
"type": 0,
diff --git a/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js b/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js
index 0d28050491..726b9cc2fa 100644
--- a/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js
+++ b/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js
@@ -6,6 +6,7 @@ import {
mockCataloguesGet as mockObjectsApiCataloguesGet,
mockObjecttypeVersionsGet,
mockObjecttypesGet,
+ mockTargetPathsPost,
} from 'components/admin/form_design/registrations/objectsapi/mocks';
import {
mockCaseTypesGet,
@@ -512,6 +513,15 @@ export default {
]),
mockObjectsApiCataloguesGet(),
mockDocumentTypesGet(),
+ mockTargetPathsPost({
+ string: [
+ {
+ targetPath: ['path', 'to.the', 'target'],
+ isRequired: true,
+ jsonSchema: {type: 'string'},
+ },
+ ],
+ }),
],
zgwMocks: [
mockZGWApisCataloguesGet(),
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
index 7f9265580b..f6b5f624c4 100644
--- a/src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js
+++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/AddressNlObjectsApiVariableConfigurationEditor.js
@@ -1,6 +1,5 @@
-import {FieldArray, useFormikContext} from 'formik';
+import {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';
@@ -11,11 +10,12 @@ 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 {TargetPathDisplay} from 'components/admin/forms/objects_api';
+import {TargetPathSelect} from 'components/admin/forms/objects_api';
import ErrorMessage from 'components/errors/ErrorMessage';
import {post} from 'utils/fetch';
+import {MappedVariableTargetPathSelect} from './GenericObjectsApiVariableConfigurationEditor';
+
const ADDRESSNL_NESTED_PROPERTIES = {
postcode: {type: 'string'},
houseLetter: {type: 'string'},
@@ -58,16 +58,17 @@ export const AddressNlEditor = ({
objecttypeVersion,
}) => {
const {csrftoken} = useContext(APIContext);
- const {values, setFieldValue} = useFormikContext();
+ const {setValues} = useFormikContext();
+
+ const hasSpecificOptions = Object.values(mappedVariable?.options ?? {}).some(
+ targetPath => targetPath && targetPath.length
+ );
+ const [specificTargetPaths, toggleSpecificTargetPaths] = useToggle(hasSpecificOptions);
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
+ // Load all the possible target paths (obect,string and number types) in parallel and only once
const {
loading,
value: targetPaths,
@@ -90,20 +91,6 @@ export const AddressNlEditor = ({
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));
@@ -118,18 +105,31 @@ export const AddressNlEditor = ({
);
const onSpecificTargetPathsChange = event => {
- setFieldValue('specificTargetPaths', event.target.checked);
+ const makeSpecific = event.target.checked;
+ toggleSpecificTargetPaths(makeSpecific);
- 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);
- }
+ setValues(prevValues => {
+ const newVariablesMapping = [...prevValues.variablesMapping];
+ const newMappedVariable = {
+ ...(newVariablesMapping[index] ?? mappedVariable),
+ // clear targetPath if we're switching to specific subfields
+ targetPath: makeSpecific ? undefined : mappedVariable.targetPath,
+ // prepare the options structure if we're switching to specific subfields,
+ // otherwise remove it entirely
+ options: makeSpecific
+ ? {
+ postcode: undefined,
+ houseLetter: undefined,
+ houseNumber: undefined,
+ houseNumberAddition: undefined,
+ city: undefined,
+ streetName: undefined,
+ }
+ : undefined,
+ };
+ newVariablesMapping[index] = newMappedVariable;
+ return {...prevValues, variablesMapping: newVariablesMapping};
+ });
};
return (
@@ -150,7 +150,7 @@ export const AddressNlEditor = ({
defaultMessage="Whether to map the specific subfield of addressNl component"
/>
}
- checked={isSpecificTargetPaths}
+ checked={specificTargetPaths}
onChange={onSpecificTargetPathsChange}
/>
@@ -164,18 +164,19 @@ export const AddressNlEditor = ({
description="'JSON Schema object target' label"
/>
}
- disabled={isSpecificTargetPaths}
+ disabled={specificTargetPaths}
>
-
- {isSpecificTargetPaths && (
+ {specificTargetPaths && (
)}
- {!isSpecificTargetPaths && (
+ {!specificTargetPaths && (
e.preventDefault() || toggleJsonSchemaVisible()}>
);
};
-
-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 (
- (
-