diff --git a/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx b/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx index 931ccb92bd3..3e1dea27c67 100644 --- a/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx +++ b/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx @@ -20,6 +20,11 @@ import { NumberInput, } from '../input'; import { AdminContext } from '../AdminContext'; +import { + AlwaysEnable, + Basic, + EnabledWhenFormIsPrefilled, +} from './SaveButton.stories'; const invalidButtonDomProps = { disabled: true, @@ -64,13 +69,7 @@ describe('', () => { }); it('should render as submit type by default', async () => { - render( - -
- - -
- ); + render(); await waitFor(() => expect( screen.getByLabelText('ra.action.save').getAttribute('type') @@ -388,13 +387,16 @@ describe('', () => { }); it('should render enabled if alwaysEnable is true', async () => { - render( - -
- - -
+ render(); + await waitFor(() => + expect(screen.getByLabelText('ra.action.save')['disabled']).toEqual( + false + ) ); + }); + + it('should render enabled if the form is prefilled', async () => { + render(); await waitFor(() => expect(screen.getByLabelText('ra.action.save')['disabled']).toEqual( false diff --git a/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx b/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx index 64fd6caab25..760d3819675 100644 --- a/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx +++ b/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Form } from 'ra-core'; +import { Form, TestMemoryRouter } from 'ra-core'; import { Paper } from '@mui/material'; import { SaveButton } from './SaveButton'; @@ -29,33 +29,55 @@ const MakeFormChange = () => { }; export const Dirty = () => ( - - -
- - - -
-
+ + + +
+ + + +
+
+
+); + +export const EnabledWhenFormIsPrefilled = () => ( + + + +
+ + +
+
+
); export const AlwaysEnable = () => ( - - -
- - -
-
+ + + +
+ + +
+
+
); export const Submitting = () => ( - - -
new Promise(() => {})}> - - - -
-
+ + + +
new Promise(() => {})}> + + + +
+
+
); diff --git a/packages/ra-ui-materialui/src/button/SaveButton.tsx b/packages/ra-ui-materialui/src/button/SaveButton.tsx index 80a351597e4..735012c4a3e 100644 --- a/packages/ra-ui-materialui/src/button/SaveButton.tsx +++ b/packages/ra-ui-materialui/src/button/SaveButton.tsx @@ -18,6 +18,7 @@ import { useTranslate, warning, setSubmissionErrors, + useRecordFromLocation, } from 'ra-core'; /** @@ -75,12 +76,16 @@ export const SaveButton = ( // useFormState().isDirty might differ from useFormState().dirtyFields (https://github.com/react-hook-form/react-hook-form/issues/4740) const isDirty = Object.keys(dirtyFields).length > 0; // Use form isDirty, isValidating and form context saving to enable or disable the save button - // if alwaysEnable is undefined + // if alwaysEnable is undefined and the form wasn't prefilled + const recordFromLocation = useRecordFromLocation(); const disabled = valueOrDefault( alwaysEnable === false || alwaysEnable === undefined ? undefined : !alwaysEnable, - disabledProp || !isDirty || isValidating || isSubmitting + disabledProp || + (!isDirty && recordFromLocation == null) || + isValidating || + isSubmitting ); warning(