diff --git a/packages/e2e-tests/fixtures/admin-setup-page.js b/packages/e2e-tests/fixtures/admin-setup-page.js
index 704a9caf..6d5b85c2 100644
--- a/packages/e2e-tests/fixtures/admin-setup-page.js
+++ b/packages/e2e-tests/fixtures/admin-setup-page.js
@@ -1,4 +1,4 @@
-import { BasePage } from "./base-page";
+import { BasePage } from './base-page';
const { faker } = require('@faker-js/faker');
const { expect } = require('@playwright/test');
@@ -6,16 +6,18 @@ export class AdminSetupPage extends BasePage {
path = '/installation';
/**
- * @param {import('@playwright/test').Page} page
- */
+ * @param {import('@playwright/test').Page} page
+ */
constructor(page) {
super(page);
this.fullNameTextField = this.page.getByTestId('fullName-text-field');
this.emailTextField = this.page.getByTestId('email-text-field');
this.passwordTextField = this.page.getByTestId('password-text-field');
- this.repeatPasswordTextField = this.page.getByTestId('repeat-password-text-field');
- this.createAdminButton = this.page.getByTestId('signUp-button');
+ this.repeatPasswordTextField = this.page.getByTestId(
+ 'repeat-password-text-field'
+ );
+ this.createAdminButton = this.page.getByTestId('installation-button');
this.invalidFields = this.page.locator('p.Mui-error');
this.successAlert = this.page.getByTestId('success-alert');
}
@@ -46,7 +48,7 @@ export class AdminSetupPage extends BasePage {
await this.repeatPasswordTextField.fill(testUser.wronglyRepeatedPassword);
}
- async submitAdminForm() {
+ async submitAdminForm() {
await this.createAdminButton.click();
}
@@ -59,7 +61,10 @@ export class AdminSetupPage extends BasePage {
}
async expectSuccessMessageToContainLoginLink() {
- await expect(await this.successAlert.locator('a')).toHaveAttribute('href', '/login');
+ await expect(await this.successAlert.locator('a')).toHaveAttribute(
+ 'href',
+ '/login'
+ );
}
generateUser() {
@@ -69,7 +74,7 @@ export class AdminSetupPage extends BasePage {
fullName: faker.person.fullName(),
email: faker.internet.email(),
password: faker.internet.password(),
- wronglyRepeatedPassword: faker.internet.password()
+ wronglyRepeatedPassword: faker.internet.password(),
};
}
-};
+}
diff --git a/packages/web/src/components/Form/index.jsx b/packages/web/src/components/Form/index.jsx
index 614873f7..d501e5a8 100644
--- a/packages/web/src/components/Form/index.jsx
+++ b/packages/web/src/components/Form/index.jsx
@@ -2,6 +2,7 @@ import * as React from 'react';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import PropTypes from 'prop-types';
import isEqual from 'lodash/isEqual';
+import useFormatMessage from 'hooks/useFormatMessage';
const noop = () => null;
@@ -18,6 +19,8 @@ function Form(props) {
...formProps
} = props;
+ const formatMessage = useFormatMessage();
+
const methods = useForm({
defaultValues,
reValidateMode,
@@ -25,6 +28,8 @@ function Form(props) {
mode,
});
+ const { setError } = methods;
+
const form = useWatch({ control: methods.control });
const prevDefaultValues = React.useRef(defaultValues);
@@ -44,9 +49,53 @@ function Form(props) {
}
}, [defaultValues]);
+ const handleErrors = React.useCallback(
+ function (errors) {
+ if (!errors) return;
+
+ let shouldSetGenericGeneralError = true;
+ const fieldNames = Object.keys(defaultValues);
+
+ Object.entries(errors).forEach(([fieldName, fieldErrors]) => {
+ if (fieldNames.includes(fieldName) && Array.isArray(fieldErrors)) {
+ shouldSetGenericGeneralError = false;
+ setError(fieldName, {
+ type: 'fieldRequestError',
+ message: fieldErrors.join(', '),
+ });
+ }
+ });
+
+ // in case of general errors
+ if (Array.isArray(errors.general)) {
+ for (const error of errors.general) {
+ shouldSetGenericGeneralError = false;
+ setError('root.general', { type: 'requestError', message: error });
+ }
+ }
+
+ if (shouldSetGenericGeneralError) {
+ setError('root.general', {
+ type: 'requestError',
+ message: formatMessage('form.genericError'),
+ });
+ }
+ },
+ [defaultValues, formatMessage, setError],
+ );
+
return (