From 7256b5e8f5e6014b8f9bf0a99dd46de0f120b6ca Mon Sep 17 00:00:00 2001 From: Gildas <1122076+djhi@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:33:11 +0200 Subject: [PATCH 1/2] Fix `` is not enabled when the form is prefilled (from `` for instance) --- .../src/button/SaveButton.spec.tsx | 28 ++++---- .../src/button/SaveButton.stories.tsx | 70 ++++++++++++------- .../src/button/SaveButton.tsx | 7 +- 3 files changed, 66 insertions(+), 39 deletions(-) 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..34e74779d16 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,14 @@ 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 || isValidating || isSubmitting) && + recordFromLocation == null ); warning( From 70c2666bc50eebd535e6f868236a802aa8da34bc Mon Sep 17 00:00:00 2001 From: Gildas <1122076+djhi@users.noreply.github.com> Date: Wed, 4 Jun 2025 16:45:19 +0200 Subject: [PATCH 2/2] Apply review suggestion --- packages/ra-ui-materialui/src/button/SaveButton.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/ra-ui-materialui/src/button/SaveButton.tsx b/packages/ra-ui-materialui/src/button/SaveButton.tsx index 34e74779d16..735012c4a3e 100644 --- a/packages/ra-ui-materialui/src/button/SaveButton.tsx +++ b/packages/ra-ui-materialui/src/button/SaveButton.tsx @@ -82,8 +82,10 @@ export const SaveButton = ( alwaysEnable === false || alwaysEnable === undefined ? undefined : !alwaysEnable, - (disabledProp || !isDirty || isValidating || isSubmitting) && - recordFromLocation == null + disabledProp || + (!isDirty && recordFromLocation == null) || + isValidating || + isSubmitting ); warning(