diff --git a/src/formio/components/EditGrid.stories.jsx b/src/formio/components/EditGrid.stories.jsx index aafa22180..2e18d9148 100644 --- a/src/formio/components/EditGrid.stories.jsx +++ b/src/formio/components/EditGrid.stories.jsx @@ -4,7 +4,7 @@ import {ConfigDecorator, withUtrechtDocument} from 'story-utils/decorators'; import {sleep} from 'utils'; import {mockBAGDataGet, mockBAGNoDataGet} from './AddressNL.mocks'; -import {SingleFormioComponent} from './story-util'; +import {MultipleFormioComponents, SingleFormioComponent} from './story-util'; const defaultNested = [ { @@ -357,3 +357,103 @@ export const WithLayoutComponents = { }); }, }; + +export const WithSoftRequiredComponent = { + name: 'With soft required component', + render: MultipleFormioComponents, + args: { + components: [ + { + type: 'editgrid', + key: 'editgrid', + label: "Auto's", + groupLabel: 'Auto', + hidden: false, + components: [ + { + type: 'file', + key: 'file', + label: 'Soft required upload', + openForms: {softRequired: true}, + }, + ], + }, + + { + type: 'softRequiredErrors', + html: ` +

Not all required fields are filled out. That can get expensive!

+ + {{ missingFields }} + +

Are you sure you want to continue?

+ `, + }, + ], + }, + play: async ({canvasElement}) => { + const canvas = within(canvasElement); + + // needed for formio + await sleep(100); + + expect(await canvas.findByText("Auto's")).toBeVisible(); + + const addButton = await canvas.findByRole('button', {name: 'Add Another'}); + await userEvent.click(addButton); + + const saveButton = await canvas.findByRole('button', {name: 'Save'}); + await userEvent.click(saveButton); + + await canvas.findByText('Not all required fields are filled out. That can get expensive!'); + const list = await canvas.findByRole('list', {name: 'Empty fields'}); + const listItem = within(list).getByRole('listitem'); + expect(listItem.textContent).toEqual('Soft required upload'); + }, +}; + +export const WithSoftRequiredComponentHiddenEditGrid = { + name: 'With soft required component hidden editgrid', + render: MultipleFormioComponents, + args: { + components: [ + { + type: 'editgrid', + key: 'editgrid', + label: "Auto's", + groupLabel: 'Auto', + hidden: true, + components: [ + { + type: 'file', + key: 'file', + label: 'Soft required upload', + openForms: {softRequired: true}, + }, + ], + }, + + { + type: 'softRequiredErrors', + html: ` +

Not all required fields are filled out. That can get expensive!

+ + {{ missingFields }} + +

Are you sure you want to continue?

+ `, + }, + ], + }, + play: async ({canvasElement}) => { + const canvas = within(canvasElement); + + // needed for formio + await sleep(100); + + await expect(canvas.queryByText("Auto's")).not.toBeInTheDocument(); + await expect( + canvas.queryByText('Not all required fields are filled out. That can get expensive!') + ).not.toBeInTheDocument(); + }, +}; diff --git a/src/formio/components/Fieldset.stories.js b/src/formio/components/Fieldset.stories.js index d676d7251..ca9c73211 100644 --- a/src/formio/components/Fieldset.stories.js +++ b/src/formio/components/Fieldset.stories.js @@ -1,6 +1,9 @@ +import {expect, within} from '@storybook/test'; + import {withUtrechtDocument} from 'story-utils/decorators'; +import {sleep} from 'utils'; -import {SingleFormioComponent} from './story-util'; +import {MultipleFormioComponents, SingleFormioComponent} from './story-util'; export default { title: 'Form.io components / Vanilla / Fieldset', @@ -67,3 +70,96 @@ export const Fieldset = { hideHeader: false, }, }; + +export const WithSoftRequiredComponent = { + name: 'With soft required component', + render: MultipleFormioComponents, + args: { + components: [ + { + type: 'fieldset', + key: 'fieldset', + label: "Auto's", + groupLabel: 'Auto', + components: [ + { + type: 'file', + key: 'file', + label: 'Soft required upload', + openForms: {softRequired: true}, + }, + ], + }, + + { + type: 'softRequiredErrors', + html: ` +

Not all required fields are filled out. That can get expensive!

+ + {{ missingFields }} + +

Are you sure you want to continue?

+ `, + }, + ], + }, + play: async ({canvasElement}) => { + const canvas = within(canvasElement); + + // needed for formio + await sleep(100); + + expect(await canvas.findByText("Auto's")).toBeVisible(); + + await canvas.findByText('Not all required fields are filled out. That can get expensive!'); + const list = await canvas.findByRole('list', {name: 'Empty fields'}); + const listItem = within(list).getByRole('listitem'); + expect(listItem.textContent).toEqual('Soft required upload'); + }, +}; + +export const WithSoftRequiredComponentHiddenParent = { + name: 'With soft required component hidden parent', + render: MultipleFormioComponents, + args: { + components: [ + { + type: 'fieldset', + key: 'fieldset', + label: "Auto's", + groupLabel: 'Auto', + hidden: true, + components: [ + { + type: 'file', + key: 'file', + label: 'Soft required upload', + openForms: {softRequired: true}, + }, + ], + }, + + { + type: 'softRequiredErrors', + html: ` +

Not all required fields are filled out. That can get expensive!

+ + {{ missingFields }} + +

Are you sure you want to continue?

+ `, + }, + ], + }, + play: async ({canvasElement}) => { + const canvas = within(canvasElement); + + // needed for formio + await sleep(100); + + await expect(canvas.queryByText("Auto's")).not.toBeInTheDocument(); + await expect( + canvas.queryByText('Not all required fields are filled out. That can get expensive!') + ).not.toBeInTheDocument(); + }, +}; diff --git a/src/formio/components/SoftRequiredErrors.js b/src/formio/components/SoftRequiredErrors.js index d6c40b860..38555f35b 100644 --- a/src/formio/components/SoftRequiredErrors.js +++ b/src/formio/components/SoftRequiredErrors.js @@ -33,7 +33,11 @@ class SoftRequiredErrors extends FormioContentField { // check which components have an empty value for (const component of softRequiredComponents) { const isEmpty = component.isEmpty(); - if (isEmpty) missingFieldLabels.push(component.label); + const isParentVisible = component.parent?.visible; + const isComponentVisible = component.visible; + + if (isEmpty && isParentVisible && isComponentVisible) + missingFieldLabels.push(component.label); } if (!missingFieldLabels.length) return '';