@@ -105,33 +110,32 @@ const VariableMapping = ({
description="Open Forms variable label"
/>
-
-
- |
+ {targetsColumnLabel} |
|
- {values[mappingName].map((_, index) => (
+ {get(values, mappingName).map((_, index) => (
arrayHelpers.remove(index)}
loading={loading}
includeStaticVariables={includeStaticVariables}
- dmnVariables={dmnVariables}
+ targets={targets}
+ targetsFieldName={targetsFieldName}
+ selectAriaLabel={selectAriaLabel}
alreadyMapped={alreadyMapped}
/>
))}
- arrayHelpers.insert(values[mappingName].length, {formVariable: '', dmnVariable: ''})
- }
+ onClick={() => {
+ const initial = {formVariable: ''};
+ initial[targetsFieldName] = '';
+ arrayHelpers.insert(get(values, mappingName).length, initial);
+ }}
>
@@ -145,7 +149,11 @@ VariableMapping.propTypes = {
loading: PropTypes.bool,
mappingName: PropTypes.string,
includeStaticVariables: PropTypes.bool,
- dmnVariables: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
+ targets: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
+ targetsFieldName: PropTypes.string,
+ targetsColumnLabel: PropTypes.string.isRequired,
+ selectAriaLabel: PropTypes.string.isRequired,
+ cssBlockName: PropTypes.string,
alreadyMapped: PropTypes.arrayOf(PropTypes.string),
};
diff --git a/src/openforms/js/components/admin/form_design/mocks.js b/src/openforms/js/components/admin/form_design/mocks.js
index 01b5c08547..d3a18f722f 100644
--- a/src/openforms/js/components/admin/form_design/mocks.js
+++ b/src/openforms/js/components/admin/form_design/mocks.js
@@ -61,3 +61,13 @@ export const mockPrefillAttributesGet = pluginAttributes =>
const attributeList = pluginAttributes[plugin] || [];
return res(ctx.json(attributeList));
});
+
+export const mockObjectsAPIPrefillAttributesGet = pluginAttributes =>
+ rest.get(
+ `${API_BASE_URL}/api/v2/prefill/plugins/objects-api/objecttypes/:uuid/versions/:version/properties`,
+ (req, res, ctx) => {
+ const {uuid, version} = req.params;
+ const attributeList = pluginAttributes[uuid][version] || [];
+ return res(ctx.json(attributeList));
+ }
+ );
diff --git a/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/ObjectTypeSelect.js b/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/ObjectTypeSelect.js
index 997ea60ed6..301fa58f22 100644
--- a/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/ObjectTypeSelect.js
+++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/ObjectTypeSelect.js
@@ -1,4 +1,5 @@
import {useField, useFormikContext} from 'formik';
+import _ from 'lodash';
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';
import {usePrevious, useUpdateEffect} from 'react-use';
@@ -20,13 +21,15 @@ const getAvailableObjectTypes = async apiGroupID => {
return response.data;
};
-const ObjectTypeSelect = ({onChangeCheck}) => {
- const [fieldProps, , fieldHelpers] = useField('objecttype');
+const ObjectTypeSelect = ({onChangeCheck, prefix = undefined}) => {
+ const namePrefix = prefix ? `${prefix}.` : '';
+ const [fieldProps, , fieldHelpers] = useField(`${namePrefix}objecttype`);
const {
- values: {objectsApiGroup = null},
+ values,
setFieldValue,
initialValues: {objecttype: initialObjecttype},
} = useFormikContext();
+ const objectsApiGroup = _.get(values, `${namePrefix}objectsApiGroup`, null);
const {value} = fieldProps;
const {setValue} = fieldHelpers;
@@ -48,7 +51,7 @@ const ObjectTypeSelect = ({onChangeCheck}) => {
]);
const options = choices.map(([value, label]) => ({value, label}));
- useSynchronizeSelect('objecttype', loading, choices);
+ useSynchronizeSelect(`${namePrefix}objecttype`, loading, choices);
const previousValue = usePrevious(value);
@@ -56,13 +59,13 @@ const ObjectTypeSelect = ({onChangeCheck}) => {
useUpdateEffect(() => {
if (loading) return;
if (value === initialObjecttype || value === previousValue) return;
- setFieldValue('objecttypeVersion', undefined); // clears the value
+ setFieldValue(`${namePrefix}objecttypeVersion`, undefined); // clears the value
}, [loading, value]);
return (
{
noManageChildProps
>
{
return versions.sort((v1, v2) => v2.version - v1.version);
};
-const ObjectTypeVersionSelect = () => {
- const {
- values: {objectsApiGroup = null, objecttype = ''},
- } = useFormikContext();
+const ObjectTypeVersionSelect = ({prefix = undefined}) => {
+ const namePrefix = prefix ? `${prefix}.` : '';
+ const {values} = useFormikContext();
+ const objectsApiGroup = _.get(values, `${namePrefix}objectsApiGroup`, null);
+ const objecttype = _.get(values, `${namePrefix}objecttype`, '');
const {
loading,
@@ -43,13 +45,13 @@ const ObjectTypeVersionSelect = () => {
? []
: versions.map(version => [version.version, `${version.version} (${version.status})`]);
- useSynchronizeSelect('objecttypeVersion', loading, choices);
+ useSynchronizeSelect(`${namePrefix}objecttypeVersion`, loading, choices);
const options = choices.map(([value, label]) => ({value, label}));
return (
{
noManageChildProps
>
{
- const [{onChange: onChangeFormik, ...fieldProps}, , {setValue}] = useField('objectsApiGroup');
+const ObjectsAPIGroup = ({apiGroupChoices, onChangeCheck, prefix = undefined}) => {
+ const namePrefix = prefix ? `${prefix}.` : '';
+ const [{onChange: onChangeFormik, ...fieldProps}, , {setValue}] = useField(
+ `${namePrefix}objectsApiGroup`
+ );
const {setValues} = useFormikContext();
const {value} = fieldProps;
// reset the objecttype specific-configuration whenever the API group changes
useUpdateEffect(() => {
- setValues(prevValues => ({
- ...prevValues,
- objecttype: '',
- objecttypeVersion: undefined,
- variablesMapping: [],
- }));
+ setValues(prevValues => {
+ const newValues = {...prevValues};
+ _.set(newValues, `${namePrefix}objecttype`, '');
+ _.set(newValues, `${namePrefix}objecttypeVersion`, undefined);
+ _.set(newValues, `${namePrefix}variablesMapping`, []);
+ return newValues;
+ });
}, [setValues, value]);
const options = apiGroupChoices.map(([value, label]) => ({value, label}));
return (
{
noManageChildProps
>
{
diff --git a/src/openforms/js/components/admin/form_design/variables/VariablesEditor.stories.js b/src/openforms/js/components/admin/form_design/variables/VariablesEditor.stories.js
index ebbb5b3b03..8b5f501916 100644
--- a/src/openforms/js/components/admin/form_design/variables/VariablesEditor.stories.js
+++ b/src/openforms/js/components/admin/form_design/variables/VariablesEditor.stories.js
@@ -1,9 +1,13 @@
-import {expect, fn, screen, userEvent, within} from '@storybook/test';
+import {expect, fn, screen, userEvent, waitFor, within} from '@storybook/test';
-import {mockPrefillAttributesGet} from 'components/admin/form_design/mocks';
+import {
+ mockObjectsAPIPrefillAttributesGet,
+ mockPrefillAttributesGet,
+} from 'components/admin/form_design/mocks';
import {BACKEND_OPTIONS_FORMS} from 'components/admin/form_design/registrations';
import {mockTargetPathsPost} from 'components/admin/form_design/registrations/objectsapi/mocks';
+import {mockObjecttypeVersionsGet, mockObjecttypesGet} from '../registrations/objectsapi/mocks';
import {FormDecorator} from '../story-decorators';
import VariablesEditor from './VariablesEditor';
@@ -13,73 +17,83 @@ BACKEND_OPTIONS_FORMS.testPlugin = {
variableConfigurationEditor: () => 'placeholder',
};
+const VARIABLES = [
+ {
+ form: 'http://localhost:8000/api/v2/forms/36612390',
+ formDefinition: 'http://localhost:8000/api/v2/form-definitions/6de1ea5a',
+ name: 'Form.io component',
+ key: 'formioComponent',
+ source: 'component',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'string',
+ dataFormat: undefined,
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: '',
+ },
+ {
+ form: 'http://localhost:8000/api/v2/forms/36612390',
+ formDefinition: 'http://localhost:8000/api/v2/form-definitions/6de1ea5a',
+ name: 'Single File',
+ key: 'aSingleFile',
+ source: 'component',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'array',
+ dataFormat: undefined,
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: [],
+ },
+ {
+ form: 'http://localhost:8000/api/v2/forms/36612390',
+ formDefinition: 'http://localhost:8000/api/v2/form-definitions/6de1ea5a',
+ name: 'Multiple File',
+ key: 'aMultipleFile',
+ source: 'component',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'array',
+ dataFormat: undefined,
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: [],
+ },
+ {
+ form: 'http://localhost:8000/api/v2/forms/36612390',
+ formDefinition: undefined,
+ name: 'User defined',
+ key: 'userDefined',
+ source: 'user_defined',
+ prefillPlugin: 'objects_api',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'array',
+ dataFormat: undefined,
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: [],
+ prefillOptions: {
+ objectsApiGroup: 1,
+ objecttype: '2c77babf-a967-4057-9969-0200320d23f2',
+ objecttypeVersion: 1,
+ variablesMapping: [{formVariable: 'formioComponent', prefillAttribute: 'firstName'}],
+ },
+ },
+];
+
export default {
title: 'Form design / Variables editor',
component: VariablesEditor,
decorators: [FormDecorator],
args: {
- variables: [
- {
- form: 'http://localhost:8000/api/v2/forms/36612390',
- formDefinition: 'http://localhost:8000/api/v2/form-definitions/6de1ea5a',
- name: 'Form.io component',
- key: 'formioComponent',
- source: 'component',
- prefillPlugin: '',
- prefillAttribute: '',
- prefillIdentifierRole: 'main',
- dataType: 'string',
- dataFormat: undefined,
- isSensitiveData: false,
- serviceFetchConfiguration: undefined,
- initialValue: '',
- },
- {
- form: 'http://localhost:8000/api/v2/forms/36612390',
- formDefinition: 'http://localhost:8000/api/v2/form-definitions/6de1ea5a',
- name: 'Single File',
- key: 'aSingleFile',
- source: 'component',
- prefillPlugin: '',
- prefillAttribute: '',
- prefillIdentifierRole: 'main',
- dataType: 'array',
- dataFormat: undefined,
- isSensitiveData: false,
- serviceFetchConfiguration: undefined,
- initialValue: [],
- },
- {
- form: 'http://localhost:8000/api/v2/forms/36612390',
- formDefinition: 'http://localhost:8000/api/v2/form-definitions/6de1ea5a',
- name: 'Multiple File',
- key: 'aMultipleFile',
- source: 'component',
- prefillPlugin: '',
- prefillAttribute: '',
- prefillIdentifierRole: 'main',
- dataType: 'array',
- dataFormat: undefined,
- isSensitiveData: false,
- serviceFetchConfiguration: undefined,
- initialValue: [],
- },
- {
- form: 'http://localhost:8000/api/v2/forms/36612390',
- formDefinition: undefined,
- name: 'User defined',
- key: 'userDefined',
- source: 'user_defined',
- prefillPlugin: '',
- prefillAttribute: '',
- prefillIdentifierRole: 'main',
- dataType: 'array',
- dataFormat: undefined,
- isSensitiveData: false,
- serviceFetchConfiguration: undefined,
- initialValue: [],
- },
- ],
+ // TODO are both needed?
+ variables: VARIABLES,
+ availableFormVariables: VARIABLES,
availableStaticVariables: [
{
form: null,
@@ -116,6 +130,16 @@ export default {
availablePrefillPlugins: [
{id: 'stuf-bg', label: 'StUF-BG'},
{id: 'haalcentraal', label: 'BRP Personen (HaalCentraal)'},
+ {
+ id: 'objects_api',
+ label: 'Objects API',
+ extraData: {
+ apiGroups: [
+ [1, 'Objects API group 1'],
+ [2, 'Objects API group 2'],
+ ],
+ },
+ },
],
onChange: fn(),
onAdd: fn(),
@@ -135,7 +159,55 @@ export default {
{id: 'bsn', label: 'BSN'},
{id: 'verblijfsAdres.postcode', label: 'Verblijfsadres > Postcode'},
],
+ objects_api: [
+ {id: 'street', label: 'Address > street'},
+ {id: 'firstName', label: 'First name'},
+ {id: 'lastName', label: 'Last name'},
+ {id: 'age', label: 'Age'},
+ ],
+ }),
+ mockObjectsAPIPrefillAttributesGet({
+ '2c77babf-a967-4057-9969-0200320d23f2': {
+ 1: [
+ {
+ targetPath: ['firstName'],
+ jsonSchema: {type: 'string', description: 'First name'},
+ },
+ {
+ targetPath: ['lastName'],
+ jsonSchema: {type: 'string', description: 'Last name'},
+ },
+ {targetPath: ['age'], jsonSchema: {type: 'integer', description: 'Age'}},
+ ],
+ },
+ '2c77babf-a967-4057-9969-0200320d23f1': {
+ 1: [{targetPath: ['height'], jsonSchema: {type: 'integer', description: 'Height'}}],
+ 2: [
+ {targetPath: ['height'], jsonSchema: {type: 'integer', description: 'Height'}},
+ {targetPath: ['species'], jsonSchema: {type: 'string', description: 'Species'}},
+ ],
+ },
}),
+ mockObjecttypesGet([
+ {
+ url: 'https://objecttypen.nl/api/v1/objecttypes/2c77babf-a967-4057-9969-0200320d23f1',
+ uuid: '2c77babf-a967-4057-9969-0200320d23f1',
+ name: 'Tree',
+ namePlural: 'Trees',
+ dataClassification: 'open',
+ },
+ {
+ url: 'https://objecttypen.nl/api/v1/objecttypes/2c77babf-a967-4057-9969-0200320d23f2',
+ uuid: '2c77babf-a967-4057-9969-0200320d23f2',
+ name: 'Person',
+ namePlural: 'Persons',
+ dataClassification: 'open',
+ },
+ ]),
+ mockObjecttypeVersionsGet([
+ {version: 1, status: 'published'},
+ {version: 2, status: 'draft'},
+ ]),
],
},
},
@@ -516,6 +588,35 @@ export const ConfigurePrefill = {
},
};
+export const ConfigurePrefillObjectsAPI = {
+ play: async ({canvasElement}) => {
+ const canvas = within(canvasElement);
+
+ const userDefinedVarsTab = await canvas.findByRole('tab', {name: 'Gebruikersvariabelen'});
+ expect(userDefinedVarsTab).toBeVisible();
+ await userEvent.click(userDefinedVarsTab);
+
+ // open modal for configuration
+ const editIcon = canvas.getByTitle('Prefill instellen');
+ await userEvent.click(editIcon);
+
+ const pluginDropdown = await screen.findByLabelText('Plugin');
+ expect(pluginDropdown).toBeVisible();
+
+ await userEvent.selectOptions(pluginDropdown, 'objects_api');
+
+ const variableSelect = await screen.findByLabelText('Formuliervariabele');
+ await expect(variableSelect.value).toBe('formioComponent');
+
+ // Wait until the API call to retrieve the prefillAttributes is done
+ await waitFor(async () => {
+ const prefillAttributeSelect = await screen.findByLabelText('Prefill attribute');
+ expect(prefillAttributeSelect).toBeVisible();
+ await expect(prefillAttributeSelect.value).toBe('firstName');
+ });
+ },
+};
+
export const WithValidationErrors = {
args: {
variables: [
diff --git a/src/openforms/js/components/admin/form_design/variables/VariablesTable.js b/src/openforms/js/components/admin/form_design/variables/VariablesTable.js
index f0a1418b12..ef78cd9d08 100644
--- a/src/openforms/js/components/admin/form_design/variables/VariablesTable.js
+++ b/src/openforms/js/components/admin/form_design/variables/VariablesTable.js
@@ -161,6 +161,7 @@ const EditableVariableRow = ({index, variable, onDelete, onChange, onFieldChange
attribute={variable.prefillAttribute}
identifierRole={variable.prefillIdentifierRole}
errors={variable.errors}
+ prefillOptions={variable.prefillOptions}
onChange={({plugin, attribute, identifierRole}) =>
onChange(variable.key, '', {
prefillPlugin: plugin,
diff --git a/src/openforms/js/components/admin/form_design/variables/prefill/PrefillConfigurationForm.js b/src/openforms/js/components/admin/form_design/variables/prefill/PrefillConfigurationForm.js
index a107cc29e9..45798f9c0e 100644
--- a/src/openforms/js/components/admin/form_design/variables/prefill/PrefillConfigurationForm.js
+++ b/src/openforms/js/components/admin/form_design/variables/prefill/PrefillConfigurationForm.js
@@ -1,6 +1,6 @@
import {Formik, useField, useFormikContext} from 'formik';
import PropTypes from 'prop-types';
-import React, {useContext, useEffect} from 'react';
+import React, {useContext, useEffect, useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import useAsync from 'react-use/esm/useAsync';
import useUpdateEffect from 'react-use/esm/useUpdateEffect';
@@ -12,8 +12,13 @@ import Fieldset from 'components/admin/forms/Fieldset';
import FormRow from 'components/admin/forms/FormRow';
import Select, {LOADING_OPTION} from 'components/admin/forms/Select';
import SubmitRow from 'components/admin/forms/SubmitRow';
+import ErrorBoundary from 'components/errors/ErrorBoundary';
import {get} from 'utils/fetch';
+import VariableMapping from '../../logic/actions/dmn/VariableMapping';
+import ObjectTypeSelect from '../../registrations/objectsapi/fields/ObjectTypeSelect';
+import ObjectTypeVersionSelect from '../../registrations/objectsapi/fields/ObjectTypeVersionSelect';
+import ObjectsAPIGroup from '../../registrations/objectsapi/fields/ObjectsAPIGroup';
import {IDENTIFIER_ROLE_CHOICES} from '../constants';
const PrefillConfigurationForm = ({
@@ -21,82 +26,50 @@ const PrefillConfigurationForm = ({
plugin = '',
attribute = '',
identifierRole = 'main',
+ prefillOptions = {
+ objectsApiGroup: '',
+ objecttype: '',
+ objecttypeVersion: null,
+ variablesMapping: [],
+ },
errors,
-}) => (
- // XXX: we're not using formik's initialErrors yet because it doesn't support arrays of
- // error messages, which our backend *can* produce.
- {
- onSubmit(values);
- actions.setSubmitting(false);
- }}
- >
- {({handleSubmit}) => (
- <>
-
-
-
-
-
- }
- errors={errors.attribute}
- >
-
-
-
-
-
-
- }
- errors={errors.identifierRole}
- >
-
-
-
-
-
-
- {
- event.preventDefault();
- handleSubmit(event);
- }}
- />
-
- >
- )}
-
-);
+}) => {
+ return (
+
{
+ // TODO should be implemented in https://github.com/open-formulieren/open-forms/issues/4693
+ console.log(values);
+ onSubmit(values);
+ actions.setSubmitting(false);
+ }}
+ >
+ {({handleSubmit, values}) => (
+ <>
+ {values.plugin === 'objects_api' ? (
+
+ ) : (
+
+ )}
+
+
+ {
+ event.preventDefault();
+ handleSubmit(event);
+ }}
+ />
+
+ >
+ )}
+
+ );
+};
PrefillConfigurationForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
@@ -128,14 +101,41 @@ const PluginField = () => {
return
;
};
-const AttributeField = () => {
+const AttributeField = ({prefillAttributes}) => {
const [fieldProps] = useField('attribute');
const {
values: {plugin},
} = useFormikContext();
+ return (
+
+ );
+};
+
+const IdentifierRoleField = () => {
+ const [fieldProps] = useField('identifierRole');
+ const choices = Object.entries(IDENTIFIER_ROLE_CHOICES);
+ return (
+
+ );
+};
+
+const PrefillFields = ({values, errors}) => {
// Load the possible prefill attributes
// XXX: this would benefit from client-side caching
+ const plugin = values.plugin;
const {
loading,
value = [],
@@ -152,29 +152,197 @@ const AttributeField = () => {
// throw errors to the nearest error boundary
if (error) throw error;
- const choices = loading ? LOADING_OPTION : value;
+ const prefillAttributes = loading ? LOADING_OPTION : value;
+
return (
-
+
);
};
-const IdentifierRoleField = () => {
- const [fieldProps] = useField('identifierRole');
- const choices = Object.entries(IDENTIFIER_ROLE_CHOICES);
+const ObjectsAPIPrefillFields = ({values, errors}) => {
+ const intl = useIntl();
+ const plugin = values.plugin;
+
+ const {
+ plugins: {availablePrefillPlugins},
+ } = useContext(FormContext);
+ const {setFieldValue} = useFormikContext();
+ const objectsPlugin = availablePrefillPlugins.find(elem => elem.id === 'objects_api');
+
+ const apiGroups = objectsPlugin.extraData.apiGroups;
+
+ const prefillAttributeLabel = intl.formatMessage({
+ description: 'Accessible label for prefill attribute dropdown',
+ defaultMessage: 'Prefill attribute',
+ });
+
+ const {objecttype, objecttypeVersion, objectsApiGroup} = values.prefillOptions;
+
+ // Load the possible prefill attributes
+ // XXX: this would benefit from client-side caching
+ const {
+ loading,
+ value = [],
+ error,
+ } = useAsync(async () => {
+ if (!plugin || !objecttype || !objecttypeVersion || !objectsApiGroup) return [];
+
+ const endpoint = `/api/v2/prefill/plugins/objects-api/objecttypes/${objecttype}/versions/${objecttypeVersion}/properties`;
+ const params = new URLSearchParams({objects_api_group: objectsApiGroup});
+ // XXX: clean up error handling here at some point...
+ const response = await get(`${endpoint}?${params.toString()}`);
+ if (!response.ok) throw response.data;
+
+ return response.data.map(attribute => [attribute.targetPath, attribute.targetPath.join(' > ')]);
+ }, [plugin, objecttype, objecttypeVersion, objectsApiGroup]);
+
+ // throw errors to the nearest error boundary
+ if (error) throw error;
+ const prefillAttributes = loading ? LOADING_OPTION : value;
+
return (
-
+ <>
+
+
+
+ }
+ >
+
+ mapping.prefillAttribute
+ )}
+ />
+
+
+ >
);
};
diff --git a/src/openforms/js/components/admin/form_design/variables/prefill/PrefillSummary.js b/src/openforms/js/components/admin/form_design/variables/prefill/PrefillSummary.js
index 2f86590168..9ed029eac8 100644
--- a/src/openforms/js/components/admin/form_design/variables/prefill/PrefillSummary.js
+++ b/src/openforms/js/components/admin/form_design/variables/prefill/PrefillSummary.js
@@ -14,6 +14,7 @@ const PrefillSummary = ({
plugin = '',
attribute = '',
identifierRole = 'main',
+ prefillOptions = undefined,
onChange = undefined,
errors = {},
}) => {
@@ -90,6 +91,7 @@ const PrefillSummary = ({
plugin={plugin}
attribute={attribute}
identifierRole={identifierRole}
+ prefillOptions={prefillOptions}
onSubmit={values => {
onChange(values);
setModalOpen(false);
diff --git a/src/openforms/prefill/api/serializers.py b/src/openforms/prefill/api/serializers.py
index a5f902ca43..82756fe671 100644
--- a/src/openforms/prefill/api/serializers.py
+++ b/src/openforms/prefill/api/serializers.py
@@ -19,6 +19,7 @@ class PrefillPluginSerializer(PluginBaseSerializer):
),
allow_null=True,
)
+ extra_data = serializers.JSONField()
class PrefillPluginQueryParameterSerializer(serializers.Serializer):
diff --git a/src/openforms/prefill/api/tests/test_endpoints.py b/src/openforms/prefill/api/tests/test_endpoints.py
index a370468559..6787eb966e 100644
--- a/src/openforms/prefill/api/tests/test_endpoints.py
+++ b/src/openforms/prefill/api/tests/test_endpoints.py
@@ -112,16 +112,19 @@ def test_prefill_list(self):
"id": "test",
"label": "Test",
"requiresAuth": AuthAttribute.bsn,
+ "extraData": None,
},
{
"id": "onlyvars",
"label": "Only Vars",
"requiresAuth": AuthAttribute.bsn,
+ "extraData": None,
},
{
"id": "vanityplates",
"label": "Vanity Plates",
"requiresAuth": AuthAttribute.bsn,
+ "extraData": None,
},
]
@@ -139,12 +142,14 @@ def test_prefill_list_for_component_type(self):
"id": "test",
"label": "Test",
"requiresAuth": AuthAttribute.bsn,
+ "extraData": None,
},
# spec'd for licenseplate
{
"id": "vanityplates",
"label": "Vanity Plates",
"requiresAuth": AuthAttribute.bsn,
+ "extraData": None,
},
]
diff --git a/src/openforms/prefill/base.py b/src/openforms/prefill/base.py
index 4d7eacda8c..73c1ea702a 100644
--- a/src/openforms/prefill/base.py
+++ b/src/openforms/prefill/base.py
@@ -89,3 +89,7 @@ def get_identifier_value(
and submission.auth_info.attribute == cls.requires_auth
):
return submission.auth_info.value
+
+ @property
+ def extra_data(self):
+ return None
diff --git a/src/openforms/prefill/contrib/objects_api/plugin.py b/src/openforms/prefill/contrib/objects_api/plugin.py
index 2320515d1f..80ad566e39 100644
--- a/src/openforms/prefill/contrib/objects_api/plugin.py
+++ b/src/openforms/prefill/contrib/objects_api/plugin.py
@@ -4,7 +4,10 @@
from django.utils.translation import gettext_lazy as _
from openforms.contrib.objects_api.checks import check_config
-from openforms.registrations.contrib.objects_api.models import ObjectsAPIConfig
+from openforms.registrations.contrib.objects_api.models import (
+ ObjectsAPIConfig,
+ ObjectsAPIGroupConfig,
+)
from ...base import BasePlugin
from ...registry import register
@@ -37,3 +40,11 @@ def get_config_actions(self):
),
),
]
+
+ @property
+ def extra_data(self):
+ return {
+ "api_groups": [
+ (group.pk, group.name) for group in ObjectsAPIGroupConfig.objects.all()
+ ]
+ }