diff --git a/packages/volto/locales/ca/LC_MESSAGES/volto.po b/packages/volto/locales/ca/LC_MESSAGES/volto.po index ae5579927f..f7d124eb1f 100644 --- a/packages/volto/locales/ca/LC_MESSAGES/volto.po +++ b/packages/volto/locales/ca/LC_MESSAGES/volto.po @@ -1323,6 +1323,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/de/LC_MESSAGES/volto.po b/packages/volto/locales/de/LC_MESSAGES/volto.po index 41c93762f1..af4a222f30 100644 --- a/packages/volto/locales/de/LC_MESSAGES/volto.po +++ b/packages/volto/locales/de/LC_MESSAGES/volto.po @@ -1322,6 +1322,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/en/LC_MESSAGES/volto.po b/packages/volto/locales/en/LC_MESSAGES/volto.po index 7804879208..36c7e49bc9 100644 --- a/packages/volto/locales/en/LC_MESSAGES/volto.po +++ b/packages/volto/locales/en/LC_MESSAGES/volto.po @@ -1317,6 +1317,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/es/LC_MESSAGES/volto.po b/packages/volto/locales/es/LC_MESSAGES/volto.po index 395afdfd49..7c65f830fe 100644 --- a/packages/volto/locales/es/LC_MESSAGES/volto.po +++ b/packages/volto/locales/es/LC_MESSAGES/volto.po @@ -1324,6 +1324,7 @@ msgstr "Entradas" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/eu/LC_MESSAGES/volto.po b/packages/volto/locales/eu/LC_MESSAGES/volto.po index 1678b97357..df2346fe94 100644 --- a/packages/volto/locales/eu/LC_MESSAGES/volto.po +++ b/packages/volto/locales/eu/LC_MESSAGES/volto.po @@ -1324,6 +1324,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/fi/LC_MESSAGES/volto.po b/packages/volto/locales/fi/LC_MESSAGES/volto.po index 400bdbc90c..65f4b2954d 100644 --- a/packages/volto/locales/fi/LC_MESSAGES/volto.po +++ b/packages/volto/locales/fi/LC_MESSAGES/volto.po @@ -1322,6 +1322,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/fr/LC_MESSAGES/volto.po b/packages/volto/locales/fr/LC_MESSAGES/volto.po index dd042b9143..e508ccd7f7 100644 --- a/packages/volto/locales/fr/LC_MESSAGES/volto.po +++ b/packages/volto/locales/fr/LC_MESSAGES/volto.po @@ -1324,6 +1324,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/it/LC_MESSAGES/volto.po b/packages/volto/locales/it/LC_MESSAGES/volto.po index d9fea77b71..b486b4f07f 100644 --- a/packages/volto/locales/it/LC_MESSAGES/volto.po +++ b/packages/volto/locales/it/LC_MESSAGES/volto.po @@ -1317,6 +1317,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/ja/LC_MESSAGES/volto.po b/packages/volto/locales/ja/LC_MESSAGES/volto.po index 7ebf883d72..b010510bdb 100644 --- a/packages/volto/locales/ja/LC_MESSAGES/volto.po +++ b/packages/volto/locales/ja/LC_MESSAGES/volto.po @@ -1322,6 +1322,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/nl/LC_MESSAGES/volto.po b/packages/volto/locales/nl/LC_MESSAGES/volto.po index 821a97b1fb..86adb3dde8 100644 --- a/packages/volto/locales/nl/LC_MESSAGES/volto.po +++ b/packages/volto/locales/nl/LC_MESSAGES/volto.po @@ -1321,6 +1321,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/pt/LC_MESSAGES/volto.po b/packages/volto/locales/pt/LC_MESSAGES/volto.po index 528f7cfd10..5f3e553d7c 100644 --- a/packages/volto/locales/pt/LC_MESSAGES/volto.po +++ b/packages/volto/locales/pt/LC_MESSAGES/volto.po @@ -1322,6 +1322,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po b/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po index 16bbc03fa7..6a1bbd54a5 100644 --- a/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po +++ b/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po @@ -1323,6 +1323,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/ro/LC_MESSAGES/volto.po b/packages/volto/locales/ro/LC_MESSAGES/volto.po index 02eec7298d..6c67597531 100644 --- a/packages/volto/locales/ro/LC_MESSAGES/volto.po +++ b/packages/volto/locales/ro/LC_MESSAGES/volto.po @@ -1317,6 +1317,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/volto.pot b/packages/volto/locales/volto.pot index f0525ab267..42b37ef8ee 100644 --- a/packages/volto/locales/volto.pot +++ b/packages/volto/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2024-03-06T08:38:38.161Z\n" +"POT-Creation-Date: 2024-04-05T18:51:53.248Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "Content-Type: text/plain; charset=utf-8\n" @@ -1319,6 +1319,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po b/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po index 8b5f5165a6..3f360a40bc 100644 --- a/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po +++ b/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po @@ -1323,6 +1323,7 @@ msgstr "" #: components/manage/Add/Add #: components/manage/Controlpanels/AddonsControlpanel #: components/manage/Controlpanels/ContentTypeSchema +#: components/manage/Controlpanels/Controlpanel #: components/manage/Controlpanels/UndoControlpanel #: components/manage/Edit/Edit #: components/manage/Form/InlineForm diff --git a/packages/volto/news/5274.bugfix b/packages/volto/news/5274.bugfix new file mode 100644 index 0000000000..da9be01184 --- /dev/null +++ b/packages/volto/news/5274.bugfix @@ -0,0 +1 @@ +Displays validation error messages on control panel forms. @wesleybl diff --git a/packages/volto/src/components/manage/Controlpanels/Controlpanel.jsx b/packages/volto/src/components/manage/Controlpanels/Controlpanel.jsx index a55477d787..842d0b4072 100644 --- a/packages/volto/src/components/manage/Controlpanels/Controlpanel.jsx +++ b/packages/volto/src/components/manage/Controlpanels/Controlpanel.jsx @@ -8,7 +8,7 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { compose } from 'redux'; import { withRouter } from 'react-router-dom'; -import { Helmet } from '@plone/volto/helpers'; +import { Helmet, tryParseJSON } from '@plone/volto/helpers'; import { createPortal } from 'react-dom'; import { Button, Container } from 'semantic-ui-react'; import { defineMessages, injectIntl } from 'react-intl'; @@ -43,6 +43,10 @@ const messages = defineMessages({ id: 'Info', defaultMessage: 'Info', }, + error: { + id: 'Error', + defaultMessage: 'Error', + }, }); /** @@ -92,7 +96,7 @@ class Controlpanel extends Component { super(props); this.onCancel = this.onCancel.bind(this); this.onSubmit = this.onSubmit.bind(this); - this.state = { isClient: false }; + this.state = { isClient: false, error: null }; } /** @@ -112,6 +116,38 @@ class Controlpanel extends Component { * @returns {undefined} */ UNSAFE_componentWillReceiveProps(nextProps) { + if (this.props.updateRequest.loading && nextProps.updateRequest.error) { + const message = + nextProps.updateRequest.error?.response?.body?.error?.message || + nextProps.updateRequest.error?.response?.body?.message || + nextProps.updateRequest.error?.response?.text || + ''; + + const error = + new DOMParser().parseFromString(message, 'text/html')?.all?.[0] + ?.textContent || message; + + const errorsList = tryParseJSON(error); + let invariantErrors = []; + if (Array.isArray(errorsList)) { + invariantErrors = errorsList + .filter((errorItem) => !('field' in errorItem)) + .map((errorItem) => errorItem['message']); + } + + this.setState({ error: error }); + + if (invariantErrors.length > 0) { + toast.error( + , + ); + } + } + if (this.props.updateRequest.loading && nextProps.updateRequest.loaded) { toast.info( jest.fn(() =>
)); -jest.mock('../Form/Form', () => jest.fn(() =>
)); +jest.mock('../Form/Form', () => + jest.fn(({ requestError }) => ( +
+ {requestError ? `requestError : ${requestError}` : null} +
+ )), +); + +const store = mockStore({ + controlpanels: { + controlpanel: { + '@id': 'http://localhost:8080/Plone/@controlpanels/date-and-time', + title: 'Date and Time', + schema: { + fieldsets: [], + properties: [], + }, + data: {}, + }, + update: { + loading: false, + loaded: true, + error: { response: { body: { message: null } } }, + }, + }, + intl: { + locale: 'en', + messages: {}, + }, +}); describe('Controlpanel', () => { it('renders a controlpanel component', () => { - const store = mockStore({ - controlpanels: { - controlpanel: { - '@id': 'http://localhost:8080/Plone/@controlpanels/date-and-time', - title: 'Date and Time', - schema: { - fieldsets: [], - properties: [], - }, - data: {}, - }, - update: { - loading: false, - loaded: true, - }, - }, - intl: { - locale: 'en', - messages: {}, - }, - }); const { container } = render( @@ -44,6 +51,30 @@ describe('Controlpanel', () => { , ); + expect(container).toMatchSnapshot(); + }); + it('renders a controlpanel component with error', () => { + const { container, rerender } = render( + + + +
+
+
, + ); + store.getState().controlpanels.update.loading = true; + store.getState().controlpanels.update.error.response.body.message = + "[{'message': 'Twitter username should not include the \"@\" prefix character.', 'field': 'twitter_username', 'error': 'ValidationError'}]"; + + rerender( + + + +
+
+
, + ); + expect(container).toMatchSnapshot(); }); }); diff --git a/packages/volto/src/components/manage/Controlpanels/__snapshots__/Controlpanel.test.jsx.snap b/packages/volto/src/components/manage/Controlpanels/__snapshots__/Controlpanel.test.jsx.snap index c496e9059b..1ec4bd1127 100644 --- a/packages/volto/src/components/manage/Controlpanels/__snapshots__/Controlpanel.test.jsx.snap +++ b/packages/volto/src/components/manage/Controlpanels/__snapshots__/Controlpanel.test.jsx.snap @@ -22,3 +22,28 @@ exports[`Controlpanel renders a controlpanel component 1`] = `
`; + +exports[`Controlpanel renders a controlpanel component with error 1`] = ` +
+
+
+
+ requestError : [{'message': 'Twitter username should not include the "@" prefix character.', 'field': 'twitter_username', 'error': 'ValidationError'}] +
+
+
+
+
+
+
+`; diff --git a/packages/volto/src/helpers/FormValidation/FormValidation.js b/packages/volto/src/helpers/FormValidation/FormValidation.js index 95c470fa77..c9bba4210e 100644 --- a/packages/volto/src/helpers/FormValidation/FormValidation.js +++ b/packages/volto/src/helpers/FormValidation/FormValidation.js @@ -165,7 +165,14 @@ export const tryParseJSON = (requestItem) => { try { resultObj = JSON.parse(requestItem.replace(/'/g, '"')); } catch (e) { - resultObj = null; + try { + // Treats strings like: `'String "double quotes"'` + resultObj = JSON.parse( + requestItem.replace(/"/g, '\\"').replace(/'/g, '"'), + ); + } catch (e) { + resultObj = null; + } } } return resultObj;