diff --git a/RELEASE.md b/RELEASE.md index a5875a34e..6f0e619ff 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -41,7 +41,11 @@ - ... --> -## Versione X.X.X (dd/mm/yyyy) +## Versione x.x.x (xx/xx/xxxx) + +### Migliorie + +- Nel blocco form, se in fase di compilazione ci sono degli errori, viene mostrato un messaggio di errore specifico per ogni campo con errori. ### Fix diff --git a/package.json b/package.json index dd8c9ede5..166ab0786 100644 --- a/package.json +++ b/package.json @@ -146,7 +146,7 @@ "volto-dropdownmenu": "4.1.1", "volto-editablefooter": "5.0.3", "volto-feedback": "0.2.0", - "volto-form-block": "3.3.1", + "volto-form-block": "3.4.0", "volto-gdpr-privacy": "2.1.1", "volto-google-analytics": "2.0.0", "volto-multilingual-widget": "3.0.0", diff --git a/src/components/ItaliaTheme/View/Commons/RenderBlocks.jsx b/src/components/ItaliaTheme/View/Commons/RenderBlocks.jsx index 06d5c319a..50ef0cbdc 100644 --- a/src/components/ItaliaTheme/View/Commons/RenderBlocks.jsx +++ b/src/components/ItaliaTheme/View/Commons/RenderBlocks.jsx @@ -48,6 +48,9 @@ const RenderBlocks = ({ if (block['@type'] === 'text' && !block.text) { return null; } + if (block['@type'] === 'slate' && block.plaintext?.length === 0) { + return null; + } } return items?.length > 0 ? ( <> diff --git a/src/components/ItaliaTheme/manage/Widgets/FileWidget.jsx b/src/components/ItaliaTheme/manage/Widgets/FileWidget.jsx index 05aa33c98..6b12bd1cf 100644 --- a/src/components/ItaliaTheme/manage/Widgets/FileWidget.jsx +++ b/src/components/ItaliaTheme/manage/Widgets/FileWidget.jsx @@ -5,6 +5,7 @@ import React from 'react'; import PropTypes from 'prop-types'; +import cx from 'classnames'; import { Dimmer, Button } from 'design-react-kit'; import { readAsDataURL } from 'promise-file-reader'; import { injectIntl, defineMessages, useIntl } from 'react-intl'; @@ -56,14 +57,25 @@ const messages = defineMessages({ * @returns {string} Markup of the component. */ const FileWidget = (props) => { - const { id, value, onChange, label, onEdit, infoText, required, invalid } = - props; + const { + id, + value, + onChange, + label, + onEdit, + infoText, + required, + invalid, + validationText, + } = props; const [isImage, setIsImage] = React.useState(false); const intl = useIntl(); React.useEffect(() => { if (value && imageMimetypes.includes(value['content-type'])) { setIsImage(true); + } else { + setIsImage(false); } }, [value]); @@ -150,7 +162,7 @@ const FileWidget = (props) => { )} - + {value ? intl.formatMessage(messages.replaceFile) : intl.formatMessage(messages.addNewFile)} @@ -171,7 +183,16 @@ const FileWidget = (props) => { )} - {infoText && {infoText}} + {infoText && ( + + {infoText} + + )} {value && (
{value.filename} @@ -189,6 +210,11 @@ const FileWidget = (props) => {
)} + {validationText && ( +
+ {validationText} +
+ )} ); }; diff --git a/src/customizations/volto-form-block/components/Edit.jsx b/src/customizations/volto-form-block/components/Edit.jsx index 27889ad7d..792cae715 100644 --- a/src/customizations/volto-form-block/components/Edit.jsx +++ b/src/customizations/volto-form-block/components/Edit.jsx @@ -11,6 +11,7 @@ import React from 'react'; import EditBlock from 'volto-form-block/components/EditBlock'; // eslint-disable-next-line import/no-unresolved import Sidebar from 'volto-form-block/components/Sidebar'; +import ValidateConfigForm from 'volto-form-block/components/ValidateConfigForm'; import { Card, CardBody, Button, Row, Col } from 'design-react-kit'; import { @@ -78,17 +79,18 @@ class Edit extends SubblocksEdit { return (
-
- {this.props?.data?.title &&

{this.props.data.title}

} - {this.props?.data?.description && ( -
- {this.props.data.description} -
- )} - - - - {/*this.state.subblocks.filter((s) => s.field_type === 'from') + +
+ {this.props?.data?.title &&

{this.props.data.title}

} + {this.props?.data?.description && ( +
+ {this.props.data.description} +
+ )} + + + + {/*this.state.subblocks.filter((s) => s.field_type === 'from') .length == 0 && (

{this.props.intl.formatMessage(messages.warning)}

@@ -98,48 +100,49 @@ class Edit extends SubblocksEdit {
)*/} - {this.state.subblocks.map((subblock, subindex) => ( -
- -
- ))} + {this.state.subblocks.map((subblock, subindex) => ( +
+ +
+ ))} - {this.props.selected && ( -
- {this.renderAddBlockButton( - this.props.intl.formatMessage(messages.addField), - )} -
- )} + {this.props.selected && ( +
+ {this.renderAddBlockButton( + this.props.intl.formatMessage(messages.addField), + )} +
+ )} - - - {this.props.data?.show_cancel && ( - + )} + - )} - - - -
-
-
-
+ + +
+
+
+
+ { @@ -56,6 +57,15 @@ const Field = ({ return !isOnEdit && !valid; }; + const infoText = errorMessage ? ( + <> +
{description}
+ {errorMessage} + + ) : ( + description + ); + return (
{field_type === 'text' && ( @@ -65,7 +75,7 @@ const Field = ({ label={getLabel()} type="text" required={required} - infoText={description} + infoText={infoText} disabled={disabled} readOnly={disabled} invalid={isInvalid() ? 'true' : null} @@ -83,14 +93,14 @@ const Field = ({ tag="textarea" rows={10} required={required} - infoText={description} + infoText={infoText} disabled={disabled} readOnly={disabled} invalid={isInvalid() ? 'true' : null} onChange={(e) => { onChange(name, e.target.value); }} - {...(value ? { value } : {})} + value={value ?? undefined} /> )} {field_type === 'select' && ( @@ -120,9 +130,13 @@ const Field = ({ aria-label={intl.formatMessage(messages.select_a_value)} classNamePrefix="react-select" className={isInvalid() ? 'is-invalid' : ''} + value={value ? [{ value: value, label: value }] : []} /> - {description && ( - {description} + {description && {description}} + {errorMessage && ( +
+ {errorMessage} +
)}
@@ -146,16 +160,19 @@ const Field = ({ onChange={(e) => { onChange(name, v); }} - invalid={isInvalid() ? 'true' : null} addon // Needed to avoid application of form-control class as of kit v4.0.2 + checked={value === v} /> ))} - {description && ( - {description} + {description && {description}} + {errorMessage && ( +
+ {errorMessage} +
)} @@ -192,8 +209,11 @@ const Field = ({ ))} - {description && ( - {description} + {description && {description}} + {errorMessage && ( +
+ {errorMessage} +
)} @@ -222,8 +242,11 @@ const Field = ({ {getLabel()} - {description && ( - {description} + {description && {description}} + {errorMessage && ( +
+ {errorMessage} +
)} @@ -235,13 +258,14 @@ const Field = ({ label={getLabel()} type="date" required={required} - infoText={description} + infoText={infoText} disabled={disabled} readOnly={disabled} invalid={isInvalid() ? 'true' : null} onChange={(e) => { onChange(name, e.target.value); }} + value={value ?? ''} /> )} {field_type === 'attachment' && ( @@ -251,7 +275,7 @@ const Field = ({ label={getLabel()} type="file" required={required} - infoText={description} + infoText={infoText} disabled={disabled} readOnly={disabled} invalid={isInvalid() ? 'true' : null} @@ -267,14 +291,15 @@ const Field = ({ label={getLabel()} type="email" required={true} - infoText={description} + infoText={infoText} disabled={disabled} readOnly={disabled} invalid={isInvalid() ? 'true' : null} + validationText={errorMessage} onChange={(e) => { onChange(name, e.target.value); }} - {...(value ? { value } : {})} + value={value ?? ''} /> )} {field_type === 'static_text' && @@ -305,6 +330,7 @@ const Field = ({ name={name} title={label} description={description} + infoText={infoText} required={required} onChange={onChange} value={value} diff --git a/src/customizations/volto-form-block/components/FormView.jsx b/src/customizations/volto-form-block/components/FormView.jsx index 77f6534a8..e608e3bf5 100644 --- a/src/customizations/volto-form-block/components/FormView.jsx +++ b/src/customizations/volto-form-block/components/FormView.jsx @@ -38,9 +38,9 @@ const messages = defineMessages({ id: 'Email Success', defaultMessage: 'Form inviato correttamente', }, - empty_values: { - id: 'form_empty_values_validation', - defaultMessage: 'Compila i campi richiesti', + form_errors: { + id: 'form_errors_validation', + defaultMessage: 'Attenzione! Alcuni campi inseriti sono da controllare.', }, reset: { id: 'form_reset', @@ -62,6 +62,8 @@ const FormView = ({ resetFormState, resetFormOnError, captcha, + id, + getErrorMessage, }) => { const intl = useIntl(); const alertTransition = { @@ -81,7 +83,7 @@ const FormView = ({ config.settings.siteProperties.enableVoltoFormBlockCaptcha; const isValidField = (field) => { - return formErrors?.indexOf(field) < 0; + return formErrors?.filter((e) => e.field === field).length === 0; }; /* Function that replaces variables from the user customized message */ @@ -220,6 +222,7 @@ const FormView = ({ : formData[name]?.value } valid={isValidField(name)} + errorMessage={getErrorMessage(name)} formHasErrors={formErrors.length > 0} /> @@ -238,7 +241,7 @@ const FormView = ({ transition={alertTransition} >

{intl.formatMessage(messages.error)}

-

{intl.formatMessage(messages.empty_values)}

+

{intl.formatMessage(messages.form_errors)}

)} {formState.error && ( diff --git a/src/theme/bootstrap-override/bootstrap-italia/_form.scss b/src/theme/bootstrap-override/bootstrap-italia/_form.scss index 28f3d7a6b..7389d3a20 100644 --- a/src/theme/bootstrap-override/bootstrap-italia/_form.scss +++ b/src/theme/bootstrap-override/bootstrap-italia/_form.scss @@ -5,12 +5,6 @@ &.is-invalid { background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23f73e5a' viewBox='0 0 384 512'%3E%3Cpath d='M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z'/%3E%3C/svg%3E"); - - small, - small.text-muted, - small.form-feedback.just-validate-error-label { - color: $danger !important; - } } .was-validated &:valid, @@ -50,3 +44,8 @@ } } } + +.invalid-feedback { + //nella versione vecchia di bootstrap-italia che usiamo (2.3.4) questa regola non c'รจ e serve. + display: block; +} diff --git a/yarn.lock b/yarn.lock index 8052dc649..8db7bce59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6576,7 +6576,7 @@ __metadata: volto-dropdownmenu: 4.1.1 volto-editablefooter: 5.0.3 volto-feedback: 0.2.0 - volto-form-block: 3.3.1 + volto-form-block: 3.4.0 volto-gdpr-privacy: 2.1.1 volto-google-analytics: 2.0.0 volto-multilingual-widget: 3.0.0 @@ -14354,9 +14354,9 @@ __metadata: languageName: node linkType: hard -"volto-form-block@npm:3.3.1": - version: 3.3.1 - resolution: "volto-form-block@npm:3.3.1" +"volto-form-block@npm:3.4.0": + version: 3.4.0 + resolution: "volto-form-block@npm:3.4.0" dependencies: "@hcaptcha/react-hcaptcha": ^0.3.6 file-saver: ^2.0.5 @@ -14365,7 +14365,7 @@ __metadata: peerDependencies: "@plone/volto": ">=16.0.0-alpha.38" volto-subblocks: ^2.0.0 - checksum: 8bd22321126b19e5fccaff8f7783b42f83f7d4cc175d821bfe247c21bc9afcd52c9f301bc7b17ab1dbab0907748cd85e8897d3311ff30a50f84b2ebcc2465581 + checksum: ff8f3fbf63656790e86ee626b6eb1b344f6eaafd39846daef3709c52855ecd2e838a7509fe2493b424a01e01c2cc02c8dc6821a054753ef95be1aa38d47ead2e languageName: node linkType: hard