Skip to content

Commit

Permalink
Merge pull request #4730 from open-formulieren/feature/4524-react-sel…
Browse files Browse the repository at this point in the history
…ect-in-variable-dropdown-cleaned-up

Improve the user experience of the form variable select/dropdown
  • Loading branch information
sergei-maertens authored Oct 11, 2024
2 parents d0a504f + 72859d8 commit 97d32bc
Show file tree
Hide file tree
Showing 20 changed files with 474 additions and 172 deletions.
20 changes: 14 additions & 6 deletions src/openforms/forms/tests/e2e_tests/test_service_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
from zgw_consumers.models import Service

from openforms.config.models import GlobalConfiguration
from openforms.tests.e2e.base import E2ETestCase, browser_page, create_superuser
from openforms.tests.e2e.base import (
E2ETestCase,
browser_page,
create_superuser,
rs_select_option,
)
from openforms.variables.constants import DataMappingTypes, FormVariableSources
from openforms.variables.models import ServiceFetchConfiguration
from openforms.variables.tests.factories import ServiceFetchConfigurationFactory
Expand All @@ -29,8 +34,10 @@ async def add_new_variable_with_service_fetch(page: Page):
await page.get_by_text("Add rule").click()
await page.get_by_text("Simple").click()

await page.locator('select[name="variable"]').select_option(
label="Environment (environment)"
await rs_select_option(
page.locator(".form-variable-dropdown").get_by_role("combobox"),
option_label="environment",
exact=False,
)
await page.locator('select[name="operator"]').select_option(label="is equal to")
await page.locator('select[name="operandType"]').select_option(label="value")
Expand All @@ -40,9 +47,10 @@ async def add_new_variable_with_service_fetch(page: Page):
await page.locator('select[name="action.type"]').select_option(
label="fetch the value for a variable from a service"
)
# FIXME Name conflict with the select above
await page.locator('select[name="variable"]').last.select_option(
label="Variable 1 (variable1)"
await rs_select_option(
page.locator(".form-variable-dropdown").last.get_by_role("combobox"),
option_label="variable1",
exact=False,
)

await expect(
Expand Down
36 changes: 18 additions & 18 deletions src/openforms/js/compiled-lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,12 @@
"value": "length"
}
],
"5obGLN": [
{
"type": 0,
"value": "User defined"
}
],
"5uaKBM": [
{
"type": 0,
Expand Down Expand Up @@ -1309,12 +1315,6 @@
"value": "Save changes"
}
],
"Bl2NMf": [
{
"type": 0,
"value": "Static"
}
],
"BqA9of": [
{
"type": 0,
Expand Down Expand Up @@ -2979,6 +2979,12 @@
"value": "Organisation RSIN"
}
],
"SgdAj7": [
{
"type": 0,
"value": "Static variables"
}
],
"SjbNyf": [
{
"type": 0,
Expand Down Expand Up @@ -3951,12 +3957,6 @@
"value": "Build a JsonLogic expression using raw JSON."
}
],
"c1XyJ4": [
{
"type": 0,
"value": "Component"
}
],
"cAC5kL": [
{
"type": 0,
Expand Down Expand Up @@ -4683,6 +4683,12 @@
"value": "collapsed"
}
],
"iXJKU7": [
{
"type": 0,
"value": "Component variables"
}
],
"iZESbd": [
{
"type": 0,
Expand Down Expand Up @@ -6079,12 +6085,6 @@
"value": "Use globally configured map component settings"
}
],
"zGMQ75": [
{
"type": 0,
"value": "User defined"
}
],
"zLTTBw": [
{
"type": 0,
Expand Down
36 changes: 18 additions & 18 deletions src/openforms/js/compiled-lang/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,12 @@
"value": "length"
}
],
"5obGLN": [
{
"type": 0,
"value": "Gebruikersvariabelen"
}
],
"5uaKBM": [
{
"type": 0,
Expand Down Expand Up @@ -1313,12 +1319,6 @@
"value": "Opslaan"
}
],
"Bl2NMf": [
{
"type": 0,
"value": "Vaste variabelen"
}
],
"BqA9of": [
{
"type": 0,
Expand Down Expand Up @@ -2996,6 +2996,12 @@
"value": "RSIN Organisatie"
}
],
"SgdAj7": [
{
"type": 0,
"value": "Vaste variabelen"
}
],
"SjbNyf": [
{
"type": 0,
Expand Down Expand Up @@ -3973,12 +3979,6 @@
"value": "Geef een JSON-logic expressie op in JSON."
}
],
"c1XyJ4": [
{
"type": 0,
"value": "Component"
}
],
"cAC5kL": [
{
"type": 0,
Expand Down Expand Up @@ -4705,6 +4705,12 @@
"value": "collapsed"
}
],
"iXJKU7": [
{
"type": 0,
"value": "Component"
}
],
"iZESbd": [
{
"type": 0,
Expand Down Expand Up @@ -6101,12 +6107,6 @@
"value": "Gebruik algemene kaartinstellingen"
}
],
"zGMQ75": [
{
"type": 0,
"value": "Gebruikersvariabelen"
}
],
"zLTTBw": [
{
"type": 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {expect, fireEvent, fn, userEvent, waitFor, within} from '@storybook/test';
import {expect, findByRole, fireEvent, fn, userEvent, waitFor, within} from '@storybook/test';
import selectEvent from 'react-select-event';

import {
mockDMNDecisionDefinitionVersionsGet,
Expand All @@ -7,6 +8,7 @@ import {
} from 'components/admin/form_design/mocks';
import {FormDecorator} from 'components/admin/form_design/story-decorators';
import {serializeValue} from 'components/admin/forms/VariableMapping';
import {getReactSelectContainer} from 'utils/storybookTestHelpers';

import DMNActionConfig from './DMNActionConfig';

Expand Down Expand Up @@ -185,7 +187,7 @@ export const Empty = {
outputMapping: [],
},
},
play: async ({canvasElement, step}) => {
play: async ({canvasElement, step, args}) => {
const canvas = within(canvasElement);
const originalConfirm = window.confirm;
window.confirm = () => true;
Expand All @@ -197,7 +199,7 @@ export const Empty = {
await step('Selecting plugin, decision definition and version.', async () => {
await userEvent.selectOptions(pluginDropdown, 'Camunda 7');

await expect(pluginDropdown.value).toBe('camunda7');
await expect(pluginDropdown).toHaveValue('camunda7');

await waitFor(async () => {
const renderedOptions = within(decisionDefDropdown).getAllByRole('option');
Expand All @@ -207,7 +209,7 @@ export const Empty = {

await userEvent.selectOptions(decisionDefDropdown, 'Approve payment');

await expect(decisionDefDropdown.value).toBe('approve-payment');
await expect(decisionDefDropdown).toHaveValue('approve-payment');

await waitFor(async () => {
const renderedOptions = within(decisionDefVersionDropdown).getAllByRole('option');
Expand All @@ -217,7 +219,7 @@ export const Empty = {

await userEvent.selectOptions(decisionDefVersionDropdown, 'v2 (version tag: n/a)');

await expect(decisionDefVersionDropdown.value).toBe('2');
await expect(decisionDefVersionDropdown).toHaveValue('2');
});

await step('Adding input mappings', async () => {
Expand All @@ -228,16 +230,25 @@ export const Empty = {
const dropdowns = within(document.querySelector('.logic-dmn__mapping-config')).getAllByRole(
'combobox'
);

await expect(dropdowns.length).toBe(2);
expect(dropdowns.length).toBe(2);

const [formVarsDropdowns, dmnVarsDropdown] = dropdowns;

await userEvent.selectOptions(formVarsDropdowns, 'Name (name)');
await userEvent.selectOptions(dmnVarsDropdown, 'Camunda variable');
await selectEvent.select(formVarsDropdowns, 'Name');
// this is super flaky for some reason on both Chromium and Firefox :/
await waitFor(async () => {
await userEvent.selectOptions(dmnVarsDropdown, 'Camunda variable');
expect(dmnVarsDropdown).toHaveValue(serializeValue('camundaVar'));
});

await expect(formVarsDropdowns).toHaveValue('name');
await expect(dmnVarsDropdown).toHaveValue(serializeValue('camundaVar'));
await userEvent.click(canvas.getByRole('button', {name: 'Save'}));
expect(args.onSave).toHaveBeenCalledWith({
pluginId: 'camunda7',
decisionDefinitionId: 'approve-payment',
decisionDefinitionVersion: '2',
inputMapping: [{formVariable: 'name', dmnVariable: 'camundaVar'}],
outputMapping: [],
});
});

await step('Changing plugin clears decision definition, version and DMN vars', async () => {
Expand Down Expand Up @@ -318,9 +329,15 @@ export const withInitialValues = {
const formVariableDropdowns = await canvas.findAllByLabelText('Formuliervariabele');

await waitFor(async () => {
await expect(formVariableDropdowns[0]).toHaveValue('name');
await expect(formVariableDropdowns[1]).toHaveValue('surname');
await expect(formVariableDropdowns[2]).toHaveValue('canApply');
expect(
await within(getReactSelectContainer(formVariableDropdowns[0])).findByText('Name')
).toBeVisible();
expect(
await within(getReactSelectContainer(formVariableDropdowns[1])).findByText('Surname')
).toBeVisible();
expect(
await within(getReactSelectContainer(formVariableDropdowns[2])).findByText('Can apply?')
).toBeVisible();
});
});

Expand Down Expand Up @@ -378,7 +395,7 @@ export const OnePluginAvailable = {

const pluginDropdown = canvas.getByLabelText('Plugin');

await expect(pluginDropdown.value).toBe('camunda7');
await expect(pluginDropdown).toHaveValue('camunda7');
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {FormattedMessage} from 'react-intl';
import {FormattedMessage, useIntl} from 'react-intl';
import {TabList, TabPanel, Tabs} from 'react-tabs';

import Tab from 'components/admin/form_design/Tab';
Expand All @@ -9,10 +9,11 @@ import RegistrationVariables from './RegistrationVariables';
import StaticData from './StaticData';
import UserDefinedVariables from './UserDefinedVariables';
import VariablesTable from './VariablesTable';
import {VARIABLE_SOURCES} from './constants';
import {VARIABLE_SOURCES, VARIABLE_SOURCES_GROUP_LABELS} from './constants';
import {variableHasErrors} from './utils';

const VariablesEditor = ({variables, onAdd, onDelete, onChange, onFieldChange}) => {
const intl = useIntl();
const userDefinedVariables = variables.filter(
variable => variable.source === VARIABLE_SOURCES.userDefined
);
Expand All @@ -35,20 +36,12 @@ const VariablesEditor = ({variables, onAdd, onDelete, onChange, onFieldChange})
<Tabs>
<TabList>
<Tab hasErrors={componentVariables.some(variable => variableHasErrors(variable))}>
<FormattedMessage
defaultMessage="Component"
description="Component variables tab title"
/>
{intl.formatMessage(VARIABLE_SOURCES_GROUP_LABELS.component)}
</Tab>
<Tab hasErrors={userDefinedVariables.some(variable => variableHasErrors(variable))}>
<FormattedMessage
defaultMessage="User defined"
description="User defined variables tab title"
/>
</Tab>
<Tab>
<FormattedMessage defaultMessage="Static" description="Static variables tab title" />
{intl.formatMessage(VARIABLE_SOURCES_GROUP_LABELS.userDefined)}
</Tab>
<Tab>{intl.formatMessage(VARIABLE_SOURCES_GROUP_LABELS.static)}</Tab>
<Tab>
<FormattedMessage
defaultMessage="Registration"
Expand Down
Loading

0 comments on commit 97d32bc

Please sign in to comment.