From 50270c0f4a04e49802457c7a2a4d4a31bc9056d8 Mon Sep 17 00:00:00 2001
From: Viicos <65306057+Viicos@users.noreply.github.com>
Date: Fri, 8 Mar 2024 16:25:40 +0100
Subject: [PATCH] [#3688] An extra admin variables tab for registration
variables
---
.../components/admin/form_design/Context.js | 4 +-
.../components/admin/form_design/constants.js | 1 +
.../admin/form_design/form-creation-form.js | 4 +-
.../admin/form_design/story-decorators.js | 1 +
.../variables/RegistrationVariables.js | 100 +++++++++++
.../form_design/variables/VariablesEditor.js | 10 ++
.../variables/VariablesEditor.stories.js | 166 ++++++++++++++++++
.../registration/RegistrationsSummaryList.js | 8 +-
8 files changed, 289 insertions(+), 5 deletions(-)
create mode 100644 src/openforms/js/components/admin/form_design/variables/RegistrationVariables.js
diff --git a/src/openforms/js/components/admin/form_design/Context.js b/src/openforms/js/components/admin/form_design/Context.js
index 7cae19a806..dcb8a787a9 100644
--- a/src/openforms/js/components/admin/form_design/Context.js
+++ b/src/openforms/js/components/admin/form_design/Context.js
@@ -12,7 +12,9 @@ const FormContext = React.createContext({
formSteps: [],
formDefinitions: [],
reusableFormDefinitionsLoaded: false,
- formVariables: {},
+ formVariables: [],
+ staticVariables: [],
+ registrationPluginsVariables: [],
registrationBackends: [],
plugins: {},
languages: [],
diff --git a/src/openforms/js/components/admin/form_design/constants.js b/src/openforms/js/components/admin/form_design/constants.js
index a0293847e5..e3f25697dd 100644
--- a/src/openforms/js/components/admin/form_design/constants.js
+++ b/src/openforms/js/components/admin/form_design/constants.js
@@ -15,6 +15,7 @@ export const THEMES_ENDPOINT = '/api/v2/themes';
export const PROCESS_DEFINITIONS_ENDPOINT =
'/api/v2/registration/plugins/camunda/process-definitions';
export const STATIC_VARIABLES_ENDPOINT = '/api/v2/variables/static';
+export const REGISTRATION_VARIABLES_ENDPOINT = '/api/v2/variables/registration';
export const LANGUAGE_INFO_ENDPOINT = '/api/v2/i18n/info';
export const LOGIC_DESCRIPTION_ENDPOINT = '/api/v2/logic/description';
export const SERVICES_ENDPOINT = '/api/v2/services';
diff --git a/src/openforms/js/components/admin/form_design/form-creation-form.js b/src/openforms/js/components/admin/form_design/form-creation-form.js
index 1d54851ea9..bf9eeb6bb5 100644
--- a/src/openforms/js/components/admin/form_design/form-creation-form.js
+++ b/src/openforms/js/components/admin/form_design/form-creation-form.js
@@ -41,13 +41,13 @@ import {FormWarnings} from './Warnings';
import {
AUTH_PLUGINS_ENDPOINT,
CATEGORIES_ENDPOINT,
- DMN_DECISION_DEFINITIONS_LIST,
DMN_PLUGINS_ENDPOINT,
FORM_DEFINITIONS_ENDPOINT,
LANGUAGE_INFO_ENDPOINT,
PAYMENT_PLUGINS_ENDPOINT,
PREFILL_PLUGINS_ENDPOINT,
REGISTRATION_BACKENDS_ENDPOINT,
+ REGISTRATION_VARIABLES_ENDPOINT,
STATIC_VARIABLES_ENDPOINT,
THEMES_ENDPOINT,
} from './constants';
@@ -999,6 +999,7 @@ const FormCreationForm = ({formUuid, formUrl, formHistoryUrl}) => {
{endpoint: PREFILL_PLUGINS_ENDPOINT, stateVar: 'availablePrefillPlugins'},
{endpoint: DMN_PLUGINS_ENDPOINT, stateVar: 'availableDMNPlugins'},
{endpoint: STATIC_VARIABLES_ENDPOINT, stateVar: 'staticVariables'},
+ {endpoint: REGISTRATION_VARIABLES_ENDPOINT, stateVar: 'registrationPluginsVariables'},
];
if (formUuid) {
@@ -1250,6 +1251,7 @@ const FormCreationForm = ({formUuid, formUrl, formHistoryUrl}) => {
reusableFormDefinitionsLoaded: state.reusableFormDefinitionsLoaded,
formVariables: state.formVariables,
staticVariables: state.staticVariables,
+ registrationPluginsVariables: state.registrationPluginsVariables,
plugins: {
availableAuthPlugins: state.availableAuthPlugins,
selectedAuthPlugins: state.selectedAuthPlugins,
diff --git a/src/openforms/js/components/admin/form_design/story-decorators.js b/src/openforms/js/components/admin/form_design/story-decorators.js
index dfb1764c5b..e7aed331fe 100644
--- a/src/openforms/js/components/admin/form_design/story-decorators.js
+++ b/src/openforms/js/components/admin/form_design/story-decorators.js
@@ -26,6 +26,7 @@ export const FormDecorator = (Story, {args}) => (
formSteps: args.availableFormSteps || [],
staticVariables: args.availableStaticVariables || [],
formVariables: args.availableFormVariables || [],
+ registrationPluginsVariables: args.registrationPluginsVariables || [],
selectedAuthPlugins: args.selectedAuthPlugins || [],
plugins: {
availableAuthPlugins: args.availableAuthPlugins || [],
diff --git a/src/openforms/js/components/admin/form_design/variables/RegistrationVariables.js b/src/openforms/js/components/admin/form_design/variables/RegistrationVariables.js
new file mode 100644
index 0000000000..e999e6fa85
--- /dev/null
+++ b/src/openforms/js/components/admin/form_design/variables/RegistrationVariables.js
@@ -0,0 +1,100 @@
+import React, {useContext} from 'react';
+import {FormattedMessage} from 'react-intl';
+
+import {FormContext} from 'components/admin/form_design/Context';
+import Fieldset from 'components/admin/forms/Fieldset';
+import {ChangelistTableWrapper, HeadColumn} from 'components/admin/tables';
+
+import RegistrationSummaryList from './registration';
+
+const PluginVariables = ({
+ headColumns,
+ registrationPlugin,
+ registrationBackends,
+ onFieldChange,
+}) => (
+
+ {registrationPlugin.pluginVariables.map((variable, index) => {
+ return (
+
+ |
+ {variable.name} |
+ {variable.key} |
+
+ b.backend === registrationPlugin.pluginIdentifier
+ )}
+ />
+ |
+ {variable.dataType} |
+
+ );
+ })}
+
+);
+
+const RegistrationVariables = ({onFieldChange}) => {
+ const formContext = useContext(FormContext);
+ const registrationBackends = formContext.registrationBackends;
+ const registrationPluginsVariables = formContext.registrationPluginsVariables.filter(
+ plugin =>
+ registrationBackends.some(b => b.backend === plugin.pluginIdentifier) &&
+ plugin.pluginVariables.length
+ );
+
+ const headColumns = (
+ <>
+
+ }
+ />
+ }
+ />
+
+ }
+ />
+
+ }
+ />
+ >
+ );
+
+ return (
+
+ {registrationPluginsVariables.map((registrationPlugin, index) => {
+ const pluginVariables = (
+
+ );
+
+ if (registrationPluginsVariables.length === 1) return pluginVariables;
+
+ return (
+
+ );
+ })}
+
+ );
+};
+
+export default RegistrationVariables;
diff --git a/src/openforms/js/components/admin/form_design/variables/VariablesEditor.js b/src/openforms/js/components/admin/form_design/variables/VariablesEditor.js
index 5ec954c2b1..cf68530dda 100644
--- a/src/openforms/js/components/admin/form_design/variables/VariablesEditor.js
+++ b/src/openforms/js/components/admin/form_design/variables/VariablesEditor.js
@@ -5,6 +5,7 @@ import {TabList, TabPanel, Tabs} from 'react-tabs';
import Tab from 'components/admin/form_design/Tab';
import Fieldset from 'components/admin/forms/Fieldset';
+import RegistrationVariables from './RegistrationVariables';
import StaticData from './StaticData';
import UserDefinedVariables from './UserDefinedVariables';
import VariablesTable from './VariablesTable';
@@ -48,6 +49,12 @@ const VariablesEditor = ({variables, onAdd, onDelete, onChange, onFieldChange})
+
+
+
@@ -65,6 +72,9 @@ const VariablesEditor = ({variables, onAdd, onDelete, onChange, onFieldChange})
+
+
+
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 8dfa5a5e9c..8edc70c5f4 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,8 +1,18 @@
+import {expect} from '@storybook/jest';
+import {userEvent, within} from '@storybook/testing-library';
+
+import {BACKEND_OPTIONS_FORMS} from 'components/admin/form_design/registrations';
import {mockTargetPathsPost} from 'components/admin/form_design/registrations/objectsapi/mocks';
import {FormDecorator} from '../story-decorators';
import VariablesEditor from './VariablesEditor';
+BACKEND_OPTIONS_FORMS.testPlugin = {
+ configurableFromVariables: true,
+ summaryHandler: () => 'placeholder',
+ variableConfigurationEditor: () => 'placeholder',
+};
+
export default {
title: 'Form design / Variables editor',
component: VariablesEditor,
@@ -120,6 +130,162 @@ export const WithObjectsAPIRegistrationBackends = {
},
},
],
+ registrationPluginsVariables: [
+ {
+ pluginIdentifier: 'objects_api',
+ pluginVerboseName: 'Objects API registration',
+ pluginVariables: [
+ {
+ form: null,
+ formDefinition: null,
+ name: 'PDF Url',
+ key: 'pdf_url',
+ source: '',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'string',
+ dataFormat: '',
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: '',
+ },
+ ],
+ },
+ {
+ pluginIdentifier: 'zgw-create-zaak',
+ pluginVerboseName: "ZGW API's",
+ pluginVariables: [
+ {
+ form: null,
+ formDefinition: null,
+ name: 'ZGW specific variable',
+ key: 'zgw_var',
+ source: '',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'string',
+ dataFormat: '',
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: '',
+ },
+ ],
+ },
+ ],
+ onFieldChange: data => {
+ console.log(data);
+ },
+ },
+ parameters: {
+ msw: {
+ handlers: [
+ mockTargetPathsPost([
+ {
+ targetPath: ['path', 'to.the', 'target'],
+ isRequired: true,
+ jsonSchema: {type: 'string'},
+ },
+ {
+ targetPath: ['other', 'path'],
+ isRequired: false,
+ jsonSchema: {type: 'object', properties: {a: {type: 'string'}}, required: ['a']},
+ },
+ ]),
+ ],
+ },
+ },
+ play: async ({canvasElement}) => {
+ const canvas = within(canvasElement);
+
+ const registrationTab = canvas.getByRole('tab', {name: 'Registration'});
+ await userEvent.click(registrationTab);
+
+ const pdfUrl = canvas.getByRole('cell', {name: 'pdf_url'});
+ expect(pdfUrl).toBeVisible();
+
+ // With a single backend, the heading shouldn't display:
+ const objectsApiTitle = canvas.queryByRole('heading', {name: 'Objects API registration'});
+ expect(objectsApiTitle).toBeNull();
+ },
+};
+
+export const WithObjectsAPIAndTestRegistrationBackends = {
+ args: {
+ registrationBackends: [
+ {
+ backend: 'objects_api',
+ key: 'objects_api_1',
+ name: 'Example Objects API reg.',
+ options: {
+ version: 2,
+ objecttype:
+ 'https://objecttypen.nl/api/v1/objecttypes/2c77babf-a967-4057-9969-0200320d23f1',
+ objecttypeVersion: 2,
+ variablesMapping: [
+ {
+ variableKey: 'formioComponent',
+ targetPath: ['path', 'to.the', 'target'],
+ },
+ {
+ variableKey: 'userDefined',
+ targetPath: ['other', 'path'],
+ },
+ ],
+ },
+ },
+ {
+ backend: 'testPlugin',
+ key: 'test_backend',
+ name: 'Example test registration',
+ options: {},
+ },
+ ],
+ registrationPluginsVariables: [
+ {
+ pluginIdentifier: 'objects_api',
+ pluginVerboseName: 'Objects API registration',
+ pluginVariables: [
+ {
+ form: null,
+ formDefinition: null,
+ name: 'PDF Url',
+ key: 'pdf_url',
+ source: '',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'string',
+ dataFormat: '',
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: '',
+ },
+ ],
+ },
+ {
+ pluginIdentifier: 'testPlugin',
+ pluginVerboseName: 'Test plugin',
+ pluginVariables: [
+ {
+ form: null,
+ formDefinition: null,
+ name: 'Test plugin variable',
+ key: 'test_plugin_var',
+ source: '',
+ prefillPlugin: '',
+ prefillAttribute: '',
+ prefillIdentifierRole: 'main',
+ dataType: 'string',
+ dataFormat: '',
+ isSensitiveData: false,
+ serviceFetchConfiguration: undefined,
+ initialValue: '',
+ },
+ ],
+ },
+ ],
onFieldChange: data => {
console.log(data);
},
diff --git a/src/openforms/js/components/admin/form_design/variables/registration/RegistrationsSummaryList.js b/src/openforms/js/components/admin/form_design/variables/registration/RegistrationsSummaryList.js
index 24b91de45e..7a1896fbbb 100644
--- a/src/openforms/js/components/admin/form_design/variables/registration/RegistrationsSummaryList.js
+++ b/src/openforms/js/components/admin/form_design/variables/registration/RegistrationsSummaryList.js
@@ -105,17 +105,19 @@ RegistrationSummary.propTypes = {
*
* @param {Object} p
* @param {Object} p.variable - The current variable
+ * @param {RegistrationBackend[]?} p.registrationBackends - The registration backends to be
+ * taken into account. If not provided, will fallback to the backends from the form context.
* @returns {JSX.Element} - A list of summaries
*/
-const RegistrationsSummaryList = ({variable, onFieldChange}) => {
+const RegistrationsSummaryList = ({variable, onFieldChange, registrationBackends}) => {
const formContext = useContext(FormContext);
/** @type {RegistrationBackend[]} */
- const registrationBackends = formContext.registrationBackends;
+ const filteredRegistrationBackends = registrationBackends || formContext.registrationBackends;
const summaries = [];
- for (const [backendIndex, backend] of registrationBackends.entries()) {
+ for (const [backendIndex, backend] of filteredRegistrationBackends.entries()) {
const backendInfo = BACKEND_OPTIONS_FORMS[backend.backend];
// Check if the registration backend can be configured from the variables tab...