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 ( +
+ {pluginVariables} +
+ ); + })} +
+ ); +}; + +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...