Skip to content

Commit

Permalink
Merge pull request #3990 from open-formulieren/feature/3688-registrat…
Browse files Browse the repository at this point in the history
…ion-variables-frontend

[#3688] An extra admin variables tab for registration variables
  • Loading branch information
Viicos authored Mar 15, 2024
2 parents 50ff077 + 50270c0 commit a940355
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/openforms/js/components/admin/form_design/Context.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const FormContext = React.createContext({
formSteps: [],
formDefinitions: [],
reusableFormDefinitionsLoaded: false,
formVariables: {},
formVariables: [],
staticVariables: [],
registrationPluginsVariables: [],
registrationBackends: [],
plugins: {},
languages: [],
Expand Down
1 change: 1 addition & 0 deletions src/openforms/js/components/admin/form_design/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 || [],
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
}) => (
<ChangelistTableWrapper headColumns={headColumns} extraModifiers={['fixed']}>
{registrationPlugin.pluginVariables.map((variable, index) => {
return (
<tr className={`row${(index % 2) + 1}`} key={variable.key}>
<td />
<td>{variable.name}</td>
<td>{variable.key}</td>
<td>
<RegistrationSummaryList
variable={variable}
onFieldChange={onFieldChange}
registrationBackends={registrationBackends.filter(
b => b.backend === registrationPlugin.pluginIdentifier
)}
/>
</td>
<td>{variable.dataType}</td>
</tr>
);
})}
</ChangelistTableWrapper>
);

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 = (
<>
<HeadColumn content="" />
<HeadColumn
content={<FormattedMessage defaultMessage="Name" description="Variable table name title" />}
/>
<HeadColumn
content={<FormattedMessage defaultMessage="Key" description="Variable table key title" />}
/>
<HeadColumn
content={
<FormattedMessage
defaultMessage="Registration"
description="Variable table registration title"
/>
}
/>
<HeadColumn
content={
<FormattedMessage
defaultMessage="Data type"
description="Variable table data type title"
/>
}
/>
</>
);

return (
<div className="variables-table">
{registrationPluginsVariables.map((registrationPlugin, index) => {
const pluginVariables = (
<PluginVariables
headColumns={headColumns}
registrationPlugin={registrationPlugin}
registrationBackends={registrationBackends}
onFieldChange={onFieldChange}
/>
);

if (registrationPluginsVariables.length === 1) return pluginVariables;

return (
<Fieldset title={registrationPlugin.pluginVerboseName} key={index}>
{pluginVariables}
</Fieldset>
);
})}
</div>
);
};

export default RegistrationVariables;
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -48,6 +49,12 @@ const VariablesEditor = ({variables, onAdd, onDelete, onChange, onFieldChange})
<Tab>
<FormattedMessage defaultMessage="Static" description="Static variables tab title" />
</Tab>
<Tab>
<FormattedMessage
defaultMessage="Registration"
description="Registration variables tab title"
/>
</Tab>
</TabList>

<TabPanel>
Expand All @@ -65,6 +72,9 @@ const VariablesEditor = ({variables, onAdd, onDelete, onChange, onFieldChange})
<TabPanel>
<StaticData onFieldChange={onFieldChange} />
</TabPanel>
<TabPanel>
<RegistrationVariables onFieldChange={onFieldChange} />
</TabPanel>
</Tabs>
</div>
</Fieldset>
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <ul> 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...
Expand Down

0 comments on commit a940355

Please sign in to comment.