diff --git a/cypress/integration/create.js b/cypress/integration/create.js index 5bc0b84e5ac..39a135db3e8 100644 --- a/cypress/integration/create.js +++ b/cypress/integration/create.js @@ -127,6 +127,38 @@ describe('Create Page', () => { EditPage.delete(); }); + it('should redirect to edit page after submit on enter', () => { + const values = [ + { + type: 'input', + name: 'title', + value: 'Test title', + }, + { + type: 'textarea', + name: 'teaser', + value: 'Test teaser', + }, + { + type: 'rich-text-input', + name: 'body', + value: 'Test body', + }, + ]; + + CreatePage.setValues(values); + CreatePage.submitWithKeyboard(); + EditPage.waitUntilVisible(); + cy.get(EditPage.elements.input('title')).should(el => + expect(el).to.have.value('Test title') + ); + cy.get(EditPage.elements.input('teaser')).should(el => + expect(el).to.have.value('Test teaser') + ); + + EditPage.delete(); + }); + it('should redirect to show page after create success with "Save and show"', () => { const values = [ { diff --git a/cypress/support/CreatePage.js b/cypress/support/CreatePage.js index d0d91fb8929..9a57b904ea2 100644 --- a/cypress/support/CreatePage.js +++ b/cypress/support/CreatePage.js @@ -67,6 +67,13 @@ export default url => ({ cy.wait(200); // let the notification disappear (could block further submits) }, + submitWithKeyboard() { + cy.get('input:first').type('{enter}'); + cy.get(this.elements.snackbar); + cy.get(this.elements.body).click(); // dismiss notification + cy.wait(200); // let the notification disappear (could block further submits) + }, + submitAndShow() { cy.get(this.elements.submitAndShowButton).click(); cy.get(this.elements.snackbar); diff --git a/packages/ra-input-rich-text/src/index.js b/packages/ra-input-rich-text/src/index.js index 86a258ca1bd..5f2d4efe649 100644 --- a/packages/ra-input-rich-text/src/index.js +++ b/packages/ra-input-rich-text/src/index.js @@ -17,7 +17,7 @@ const RichTextInput = ({ toolbar = true, fullWidth = true, configureQuill, - helperText = false, + helperText, label, source, resource, diff --git a/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx b/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx index f19160d1ef7..a4d09863d84 100644 --- a/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx +++ b/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx @@ -42,7 +42,7 @@ describe('', () => { ); - fireEvent.mouseDown(getByLabelText('ra.action.save')); + fireEvent.click(getByLabelText('ra.action.save')); expect(onSubmit).toHaveBeenCalled(); }); @@ -55,7 +55,7 @@ describe('', () => { ); - fireEvent.mouseDown(getByLabelText('ra.action.save')); + fireEvent.click(getByLabelText('ra.action.save')); expect(onSubmit).not.toHaveBeenCalled(); }); @@ -77,7 +77,7 @@ describe('', () => { ); - fireEvent.mouseDown(getByLabelText('ra.action.save')); + fireEvent.click(getByLabelText('ra.action.save')); expect(dispatchSpy).toHaveBeenCalledWith({ payload: { message: 'ra.message.invalid_form', diff --git a/packages/ra-ui-materialui/src/button/SaveButton.tsx b/packages/ra-ui-materialui/src/button/SaveButton.tsx index bdeadff6fa8..8831d6d4bf2 100644 --- a/packages/ra-ui-materialui/src/button/SaveButton.tsx +++ b/packages/ra-ui-materialui/src/button/SaveButton.tsx @@ -31,12 +31,7 @@ const SaveButton: FC = ({ const notify = useNotify(); const translate = useTranslate(); - // We handle the click event through mousedown because of an issue when - // the button is not as the same place when mouseup occurs, preventing the click - // event to fire. - // It can happen when some errors appear under inputs, pushing the button - // towards the window bottom. - const handleMouseDown = event => { + const handleClick = event => { if (saving) { // prevent double submission event.preventDefault(); @@ -56,14 +51,6 @@ const SaveButton: FC = ({ } }; - // As we handle the "click" through the mousedown event, we have to make sure we cancel - // the default click in case the issue mentionned above does not occur. - // Otherwise, this would trigger a standard HTML submit, not the final-form one. - const handleClick = event => { - event.preventDefault(); - event.stopPropagation(); - }; - const type = submitOnEnter ? 'submit' : 'button'; const displayedLabel = label && translate(label, { _: label }); return ( @@ -71,7 +58,6 @@ const SaveButton: FC = ({ className={classnames(classes.button, className)} variant={variant} type={type} - onMouseDown={handleMouseDown} onClick={handleClick} color={saving ? 'default' : 'primary'} aria-label={displayedLabel} diff --git a/packages/ra-ui-materialui/src/input/ReferenceInput.tsx b/packages/ra-ui-materialui/src/input/ReferenceInput.tsx index 41fb0c78b01..7b8546facc4 100644 --- a/packages/ra-ui-materialui/src/input/ReferenceInput.tsx +++ b/packages/ra-ui-materialui/src/input/ReferenceInput.tsx @@ -12,6 +12,7 @@ import { InputProps, Pagination, Sort, + warning as warningLog, } from 'ra-core'; import sanitizeInputProps from './sanitizeRestProps'; @@ -192,7 +193,7 @@ interface ReferenceInputViewProps { classes?: object; className?: string; error?: string; - helperText?: string; + helperText?: string | boolean; id: string; input: FieldInputProps; isRequired: boolean; @@ -268,6 +269,15 @@ export const ReferenceInputView: FunctionComponent = ({ } : meta; + // helperText should never be set on ReferenceInput, only in child component + // But in a Filter component, the child helperText have to be forced to false + warningLog( + helperText !== undefined && helperText !== false, + " doesn't accept a helperText prop. Set the helperText prop on the child component instead" + ); + + const disabledHelperText = helperText === false ? { helperText } : {}; + return cloneElement(children, { allowEmpty, classes, @@ -284,6 +294,7 @@ export const ReferenceInputView: FunctionComponent = ({ setPagination, setSort, translateChoice: false, + ...disabledHelperText, ...sanitizeRestProps(rest), }); };