Skip to content

Commit

Permalink
Ensure we include default values
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed Dec 17, 2024
1 parent 46a15e6 commit b2026b8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
26 changes: 25 additions & 1 deletion packages/ra-core/src/form/Form.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -833,22 +833,46 @@ describe('Form', () => {
state: { record: { body: 'from-state' } },
},
expectedValue: 'from-state',
expectedDefaultValue: '',
},
{
from: 'state with default values',
url: {
pathname: '/form/general',
state: { record: { body: 'from-state' } },
},
expectedValue: 'from-state',
defaultValues: { category: 'default category' },
expectedDefaultValue: 'default category',
},
{
from: 'search query',
url: `/form/general?source=${encodeURIComponent(JSON.stringify({ body: 'from-search' }))}` as To,
expectedValue: 'from-search',
expectedDefaultValue: '',
},
{
from: 'search query with default values',
url: `/form/general?source=${encodeURIComponent(JSON.stringify({ body: 'from-search' }))}` as To,
expectedValue: 'from-search',
defaultValues: { category: 'default category' },
expectedDefaultValue: 'default category',
},
])(
'should support overriding the record values from the location $from',
async ({ url, expectedValue }) => {
async ({ url, defaultValues, expectedValue, expectedDefaultValue }) => {
render(
<MultiRoutesForm
url={url}
initialRecord={{ title: 'lorem', body: 'unmodified' }}
defaultValues={defaultValues}
/>
);
await screen.findByDisplayValue('lorem');
expect(
(await screen.findByLabelText<HTMLInputElement>('category'))
.value
).toEqual(expectedDefaultValue);
expect(
(screen.getByText('Submit') as HTMLInputElement).disabled
).toEqual(false);
Expand Down
27 changes: 21 additions & 6 deletions packages/ra-core/src/form/Form.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {

import { CoreAdminContext } from '../core';
import { RecordContextProvider, SaveContextProvider } from '../controller';
import { Form } from './Form';
import { Form, FormProps } from './Form';
import { useInput } from './useInput';
import { required, ValidationError } from './validation';
import { mergeTranslations } from '../i18n';
Expand Down Expand Up @@ -58,10 +58,12 @@ const Input = props => {
};

const SubmitButton = () => {
const state = useFormState();
const { dirtyFields } = useFormState();
// 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;

return (
<button type="submit" disabled={!state.isDirty}>
<button type="submit" disabled={!isDirty}>
Submit
</button>
);
Expand Down Expand Up @@ -416,9 +418,11 @@ export const ServerSideValidation = () => {
export const MultiRoutesForm = ({
url,
initialRecord,
defaultValues,
}: {
url?: any;
initialRecord?: Partial<RaRecord>;
defaultValues?: Partial<RaRecord>;
}) => (
<TestMemoryRouter key={url} initialEntries={[url]}>
<CoreAdminContext i18nProvider={defaultI18nProvider}>
Expand All @@ -427,7 +431,7 @@ export const MultiRoutesForm = ({
path="/form/*"
element={
<RecordContextProvider value={initialRecord}>
<FormWithSubRoutes />
<FormWithSubRoutes defaultValues={defaultValues} />
</RecordContextProvider>
}
/>
Expand Down Expand Up @@ -458,6 +462,16 @@ MultiRoutesForm.argTypes = {
},
control: { type: 'select' },
},
defaultValues: {
options: ['none', 'provided'],
mapping: {
none: undefined,
provided: {
category: 'default category',
},
},
control: { type: 'select' },
},
initialRecord: {
options: ['none', 'provided'],
mapping: {
Expand All @@ -468,9 +482,9 @@ MultiRoutesForm.argTypes = {
},
};

const FormWithSubRoutes = () => {
const FormWithSubRoutes = (props: Partial<FormProps>) => {
return (
<Form>
<Form {...props}>
<TabbedForm />
<SubmitButton />
</Form>
Expand Down Expand Up @@ -502,6 +516,7 @@ const TabbedForm = () => {
</div>
<Tab name="general">
<Input source="title" />
<Input source="category" />
</Tab>
<Tab name="content">
<Input source="body" />
Expand Down
4 changes: 2 additions & 2 deletions packages/ra-core/src/form/useAugmentedForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ export const useAugmentedForm = <RecordType = any>(
const { reset } = form;
useEffect(() => {
if (recordFromLocation && !recordFromLocationApplied.current) {
reset(merge({}, record, recordFromLocation), {
reset(merge({}, defaultValuesIncludingRecord, recordFromLocation), {
keepDefaultValues: true,
});
recordFromLocationApplied.current = true;
}
}, [record, recordFromLocation, reset]);
}, [defaultValuesIncludingRecord, recordFromLocation, reset]);

// submit callbacks
const handleSubmit = useCallback(
Expand Down

0 comments on commit b2026b8

Please sign in to comment.