Skip to content

Commit

Permalink
Displays validation error messages on control panel forms
Browse files Browse the repository at this point in the history
  • Loading branch information
wesleybl committed Apr 5, 2024
1 parent 8aa167a commit d465ffc
Show file tree
Hide file tree
Showing 20 changed files with 143 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/volto/locales/ca/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/de/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/en/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/es/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/eu/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/fi/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/fr/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/it/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/ja/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/nl/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/pt/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/pt_BR/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/ro/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion packages/volto/locales/volto.pot
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>\n"
"Language-Team: Plone i18n <[email protected]>\n"
"Content-Type: text/plain; charset=utf-8\n"
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/locales/zh_CN/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions packages/volto/news/5274.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Displays validation error messages on control panel forms. @wesleybl
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -43,6 +43,10 @@ const messages = defineMessages({
id: 'Info',
defaultMessage: 'Info',
},
error: {
id: 'Error',
defaultMessage: 'Error',
},
});

/**
Expand Down Expand Up @@ -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 };
}

/**
Expand All @@ -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(
<Toast
error
title={this.props.intl.formatMessage(messages.error)}
content={invariantErrors.join(' - ')}
/>,
);
}
}

if (this.props.updateRequest.loading && nextProps.updateRequest.loaded) {
toast.info(
<Toast
Expand Down Expand Up @@ -161,6 +197,7 @@ class Controlpanel extends Component {
title={this.props.controlpanel.title}
schema={filterControlPanelsSchema(this.props.controlpanel)}
formData={this.props.controlpanel.data}
requestError={this.state.error}
onSubmit={this.onSubmit}
onCancel={this.onCancel}
hideActions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import { render } from '@testing-library/react';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-intl-redux';
Expand All @@ -10,31 +9,39 @@ const mockStore = configureStore();

jest.mock('../Toolbar/Toolbar', () => jest.fn(() => <div id="Portal" />));

jest.mock('../Form/Form', () => jest.fn(() => <div id="form" />));
jest.mock('../Form/Form', () =>
jest.fn(({ requestError }) => (
<div id="form">
{requestError ? `requestError : ${requestError}` : null}
</div>
)),
);

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(
<Provider store={store}>
<MemoryRouter initialEntries={['/controlpanel/date-and-time']}>
Expand All @@ -44,6 +51,30 @@ describe('Controlpanel', () => {
</Provider>,
);

expect(container).toMatchSnapshot();
});
it('renders a controlpanel component with error', () => {
const { container, rerender } = render(
<Provider store={store}>
<MemoryRouter initialEntries={['/controlpanel/date-and-time']}>
<Route path={'/controlpanel/:id'} component={Controlpanel} />
<div id="toolbar"></div>
</MemoryRouter>
</Provider>,
);
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(
<Provider store={store}>
<MemoryRouter initialEntries={['/controlpanel/date-and-time']}>
<Route path={'/controlpanel/:id'} component={Controlpanel} />
<div id="toolbar"></div>
</MemoryRouter>
</Provider>,
);

expect(container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,28 @@ exports[`Controlpanel renders a controlpanel component 1`] = `
</div>
</div>
`;

exports[`Controlpanel renders a controlpanel component with error 1`] = `
<div>
<div
id="page-controlpanel"
>
<div
class="ui container"
>
<div
id="form"
>
requestError : [{'message': 'Twitter username should not include the "@" prefix character.', 'field': 'twitter_username', 'error': 'ValidationError'}]
</div>
</div>
</div>
<div
id="toolbar"
>
<div
id="Portal"
/>
</div>
</div>
`;
9 changes: 8 additions & 1 deletion packages/volto/src/helpers/FormValidation/FormValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit d465ffc

Please sign in to comment.