Skip to content

Commit

Permalink
Merge pull request #60 from open-formulieren/feature/59-select-component
Browse files Browse the repository at this point in the history
Implement the select component edit form
  • Loading branch information
sergei-maertens authored Nov 24, 2023
2 parents 0367e61 + 04affe5 commit 63010fb
Show file tree
Hide file tree
Showing 14 changed files with 864 additions and 13 deletions.
223 changes: 223 additions & 0 deletions src/components/ComponentConfiguration.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,11 @@ export const FileUpload: Story = {
});
await expect(canvas.queryByText('.pdf')).toBeVisible();
await userEvent.click(canvas.getByText('.jpg'));
// wait for dropdown to close and selected option to be visible;
await waitFor(async () => {
await expect(canvas.queryByText('.pdf')).toBeNull();
});
await expect(canvas.queryByText('.jpg')).toBeVisible();
});

await step('Submit configuration', async () => {
Expand Down Expand Up @@ -1387,6 +1392,224 @@ export const Radio: Story = {
},
};

export const Select: Story = {
render: Template,
name: 'type: select',

args: {
component: {
id: 'wqimsadk',
type: 'select',
key: 'select',
label: 'A select field',
openForms: {
dataSrc: 'manual',
translations: {},
},
dataSrc: 'values',
data: {values: []},
defaultValue: '',
},

builderInfo: {
title: 'Select',
icon: 'th-list',
group: 'basic',
weight: 70,
schema: {},
},
},

play: async ({canvasElement, step, args}) => {
const canvas = within(canvasElement);
const editForm = within(canvas.getByTestId('componentEditForm'));
const preview = within(canvas.getByTestId('componentPreview'));

await expect(canvas.getByLabelText('Label')).toHaveValue('A select field');
await waitFor(async () => {
await expect(canvas.getByLabelText('Property Name')).toHaveValue('aSelectField');
});
await expect(canvas.getByLabelText('Description')).toHaveValue('');
await expect(canvas.getByLabelText('Tooltip')).toHaveValue('');
await expect(canvas.getByLabelText('Show in summary')).toBeChecked();
await expect(canvas.getByLabelText('Show in email')).not.toBeChecked();
await expect(canvas.getByLabelText('Show in PDF')).toBeChecked();

// ensure that changing fields in the edit form properly update the preview

await userEvent.clear(canvas.getByLabelText('Label'));
await userEvent.type(canvas.getByLabelText('Label'), 'Updated preview label');
expect(await preview.findByText('Updated preview label'));

// Ensure that the manually entered key is kept instead of derived from the label,
// even when key/label components are not mounted.
const keyInput = canvas.getByLabelText('Property Name');
// fireEvent is deliberate, as userEvent.clear + userEvent.type briefly makes the field
// not have any value, which triggers the generate-key-from-label behaviour.
fireEvent.change(keyInput, {target: {value: 'customKey'}});
await userEvent.click(canvas.getByRole('tab', {name: 'Basic'}));
await userEvent.clear(canvas.getByLabelText('Label'));
await userEvent.type(canvas.getByLabelText('Label'), 'Other label', {delay: 50});
await expect(canvas.getByLabelText('Property Name')).toHaveDisplayValue('customKey');

await step('Set up manual options', async () => {
// enter some possible options
const firstOptionLabelInput = canvas.getByLabelText('Option label');
expect(firstOptionLabelInput).toHaveDisplayValue('');
await userEvent.type(firstOptionLabelInput, 'Option label 1');
const firstOptionValue = canvas.getByLabelText('Option value');
await waitFor(() => expect(firstOptionValue).toHaveDisplayValue('optionLabel1'));

// add a second option
await userEvent.click(canvas.getByRole('button', {name: 'Add another'}));
const optionLabels = canvas.queryAllByLabelText('Option label');
const optionValues = canvas.queryAllByLabelText('Option value');
expect(optionLabels).toHaveLength(2);
expect(optionValues).toHaveLength(2);
await userEvent.type(optionValues[1], 'manualValue');
await userEvent.type(optionLabels[1], 'Second option');

const previewSearchInput = preview.getByLabelText('Other label');
previewSearchInput.focus();
await userEvent.keyboard('[ArrowDown]');
await expect(await preview.findByText('Second option')).toBeVisible();
await waitFor(() => {
expect(preview.queryByRole('listbox')).toBeNull();
});

await userEvent.click(canvas.getByRole('button', {name: 'Save'}));
expect(args.onSubmit).toHaveBeenCalledWith({
id: 'wqimsadk',
type: 'select',
// basic tab
label: 'Other label',
key: 'customKey',
description: '',
tooltip: '',
showInSummary: true,
showInEmail: false,
showInPDF: true,
hidden: false,
clearOnHide: true,
isSensitiveData: false,
dataSrc: 'values',
data: {
values: [
{
value: 'optionLabel1',
label: 'Option label 1',
},
{
value: 'manualValue',
label: 'Second option',
openForms: {translations: {}},
},
],
},
openForms: {
dataSrc: 'manual',
translations: {},
},
defaultValue: '',
// Advanced tab
conditional: {
show: undefined,
when: '',
eq: '',
},
// Validation tab
validate: {
required: false,
plugins: [],
},
translatedErrors: {
nl: {required: ''},
},
// registration tab
registration: {
attribute: '',
},
});
// @ts-expect-error
args.onSubmit.mockClear();
});

await step('Option labels are translatable', async () => {
await userEvent.click(canvas.getByRole('tab', {name: 'Translations'}));

// check that the option labels are in the translations table
expect(await editForm.findByText('Option label 1')).toBeVisible();
expect(await editForm.findByText('Second option')).toBeVisible();
});

await step('Set up itemsExpression for options', async () => {
await userEvent.click(canvas.getByRole('tab', {name: 'Basic'}));

canvas.getByLabelText('Data source').focus();
await userEvent.keyboard('[ArrowDown]');
await userEvent.click(await canvas.findByText('From variable'));
const itemsExpressionInput = canvas.getByLabelText('Items expression');
await userEvent.clear(itemsExpressionInput);
// { needs to be escaped: https://github.com/testing-library/user-event/issues/584
const expression = '{"var": "someVar"}'.replace(/[{[]/g, '$&$&');
await userEvent.type(itemsExpressionInput, expression);

await expect(editForm.queryByLabelText('Default value')).toBeNull();

const previewSearchInput = preview.getByLabelText('Other label');
previewSearchInput.focus();
await userEvent.keyboard('[ArrowDown]');
await expect(await preview.findByText(/"someVar"/)).toBeVisible();
await userEvent.keyboard('[Esc]');

await userEvent.click(canvas.getByRole('button', {name: 'Save'}));
expect(args.onSubmit).toHaveBeenCalledWith({
id: 'wqimsadk',
type: 'select',
// basic tab
label: 'Other label',
key: 'customKey',
description: '',
tooltip: '',
showInSummary: true,
showInEmail: false,
showInPDF: true,
hidden: false,
clearOnHide: true,
isSensitiveData: false,
dataSrc: 'values',
data: {},
openForms: {
dataSrc: 'variable',
itemsExpression: {var: 'someVar'},
translations: {},
},
defaultValue: '',
// Advanced tab
conditional: {
show: undefined,
when: '',
eq: '',
},
// Validation tab
validate: {
required: false,
plugins: [],
},
translatedErrors: {
nl: {required: ''},
},
// registration tab
registration: {
attribute: '',
},
});
// @ts-expect-error
args.onSubmit.mockClear();
});
},
};

export const BSN: Story = {
render: Template,
name: 'type: bsn',
Expand Down
Loading

0 comments on commit 63010fb

Please sign in to comment.