Skip to content

Commit a171deb

Browse files
authoredMar 11, 2021
Merge pull request #6005 from marmelab/fix-warn-when-unsaved-changes
Fix Form Loose Dirty Fields Values After Cancelling Navigation
2 parents 0f46765 + 7ba378c commit a171deb

File tree

10 files changed

+76
-89
lines changed

10 files changed

+76
-89
lines changed
 

‎packages/ra-core/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@
3737
"@types/react-router-dom": "^5.1.0",
3838
"connected-react-router": "^6.5.2",
3939
"cross-env": "^5.2.0",
40-
"final-form": "^4.20.0",
40+
"final-form": "^4.20.2",
4141
"history": "^4.7.2",
4242
"ignore-styles": "~5.0.1",
4343
"ra-test": "^3.13.2",
4444
"react": "^17.0.0",
4545
"react-dom": "^17.0.0",
46-
"react-final-form": "^6.5.0",
46+
"react-final-form": "^6.5.2",
4747
"react-redux": "^7.1.0",
4848
"react-router": "^5.1.0",
4949
"react-router-dom": "^5.1.0",
@@ -54,11 +54,11 @@
5454
},
5555
"peerDependencies": {
5656
"connected-react-router": "^6.5.2",
57-
"final-form": "^4.18.5",
57+
"final-form": "^4.20.2",
5858
"final-form-submit-errors": "^0.1.2",
5959
"react": "^16.9.0 || ^17.0.0",
6060
"react-dom": "^16.9.0 || ^17.0.0",
61-
"react-final-form": "^6.3.3",
61+
"react-final-form": "^6.5.2",
6262
"react-redux": "^7.1.0",
6363
"react-router": "^5.1.0",
6464
"react-router-dom": "^5.1.0",

‎packages/ra-core/src/form/FormWithRedirect.tsx

+23-16
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import * as React from 'react';
2-
import { FC, useRef, useCallback, useEffect, useMemo } from 'react';
3-
import {
4-
Form,
5-
FormProps,
6-
FormRenderProps as FinalFormFormRenderProps,
7-
} from 'react-final-form';
2+
import { useRef, useCallback, useEffect, useMemo } from 'react';
3+
import { Form, FormProps, FormRenderProps } from 'react-final-form';
84
import arrayMutators from 'final-form-arrays';
95
import { submitErrorsMutators } from 'final-form-submit-errors';
106

@@ -13,7 +9,12 @@ import useWarnWhenUnsavedChanges from './useWarnWhenUnsavedChanges';
139
import useResetSubmitErrors from './useResetSubmitErrors';
1410
import sanitizeEmptyValues from './sanitizeEmptyValues';
1511
import getFormInitialValues from './getFormInitialValues';
16-
import { FormContextValue, Record, OnSuccess, OnFailure } from '../types';
12+
import {
13+
FormContextValue,
14+
Record as RaRecord,
15+
OnSuccess,
16+
OnFailure,
17+
} from '../types';
1718
import { RedirectionSideEffect } from '../sideEffect';
1819
import { useDispatch } from 'react-redux';
1920
import { setAutomaticRefresh } from '../actions/uiActions';
@@ -44,7 +45,7 @@ import { FormContextProvider } from './FormContextProvider';
4445
*
4546
* @param {Props} props
4647
*/
47-
const FormWithRedirect: FC<FormWithRedirectProps> = ({
48+
const FormWithRedirect = ({
4849
debug,
4950
decorators,
5051
defaultValue,
@@ -65,7 +66,7 @@ const FormWithRedirect: FC<FormWithRedirectProps> = ({
6566
warnWhenUnsavedChanges,
6667
sanitizeEmptyValues: shouldSanitizeEmptyValues = true,
6768
...props
68-
}) => {
69+
}: FormWithRedirectProps) => {
6970
const redirect = useRef(props.redirect);
7071
const onSave = useRef(save);
7172
const formGroups = useRef<{ [key: string]: string[] }>({});
@@ -167,6 +168,7 @@ const FormWithRedirect: FC<FormWithRedirectProps> = ({
167168
validate={validate}
168169
validateOnBlur={validateOnBlur}
169170
render={formProps => (
171+
// @ts-ignore Ignored because of a weird error about the active prop
170172
<FormView
171173
{...props}
172174
{...formProps}
@@ -184,23 +186,28 @@ const FormWithRedirect: FC<FormWithRedirectProps> = ({
184186
};
185187

186188
export type FormWithRedirectProps = FormWithRedirectOwnProps &
187-
Omit<FormProps, 'onSubmit' | 'active'>;
189+
Omit<FormProps, 'onSubmit'>;
188190

191+
export type FormWithRedirectRenderProps = Omit<
192+
FormViewProps,
193+
'chilren' | 'render' | 'setRedirect'
194+
>;
189195
export type FormWithRedirectRender = (
190-
props: Omit<FormViewProps, 'render' | 'setRedirect'>
196+
props: FormWithRedirectRenderProps
191197
) => React.ReactElement<any, any>;
192198

193199
export type FormWithRedirectSave = (
194-
data: Partial<Record>,
200+
data: Partial<RaRecord>,
195201
redirectTo: RedirectionSideEffect,
196202
options?: {
197203
onSuccess?: OnSuccess;
198204
onFailure?: OnFailure;
199205
}
200206
) => void;
207+
201208
export interface FormWithRedirectOwnProps {
202209
defaultValue?: any;
203-
record?: Record;
210+
record?: RaRecord;
204211
redirect?: RedirectionSideEffect;
205212
render: FormWithRedirectRender;
206213
save?: FormWithRedirectSave;
@@ -228,18 +235,18 @@ export type HandleSubmitWithRedirect = (
228235
) => void;
229236
interface FormViewProps
230237
extends FormWithRedirectOwnProps,
231-
Omit<FinalFormFormRenderProps, 'render' | 'active'> {
238+
Omit<FormRenderProps, 'render' | 'component'> {
232239
handleSubmitWithRedirect?: HandleSubmitWithRedirect;
233240
setRedirect: SetRedirect;
234241
warnWhenUnsavedChanges?: boolean;
235242
}
236243

237-
const FormView: FC<FormViewProps> = ({
244+
const FormView = ({
238245
render,
239246
warnWhenUnsavedChanges,
240247
setRedirect,
241248
...props
242-
}) => {
249+
}: FormViewProps) => {
243250
// if record changes (after a getOne success or a refresh), the form must be updated
244251
useInitializeFormWithRecord(props.record);
245252
useWarnWhenUnsavedChanges(warnWhenUnsavedChanges);

‎packages/ra-core/src/form/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import FormField from './FormField';
77
import FormWithRedirect, {
88
FormWithRedirectProps,
99
FormWithRedirectRender,
10+
FormWithRedirectRenderProps,
1011
FormWithRedirectSave,
1112
HandleSubmitWithRedirect,
1213
} from './FormWithRedirect';
@@ -31,6 +32,7 @@ export type {
3132
FormDataConsumerRender,
3233
FormDataConsumerRenderParams,
3334
FormWithRedirectProps,
35+
FormWithRedirectRenderProps,
3436
FormWithRedirectRender,
3537
FormWithRedirectSave,
3638
HandleSubmitWithRedirect,

‎packages/ra-core/src/form/useInitializeFormWithRecord.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,8 @@ const useInitializeFormWithRecord = record => {
1919
// Disable this option when re-initializing the form because in this case, it should reset the dirty state of all fields
2020
// We do need to keep this option for dynamically added inputs though which is why it is kept at the form level
2121
form.setConfig('keepDirtyOnReinitialize', false);
22-
// Since the submit function returns a promise, use setTimeout to prevent the error "Cannot reset() in onSubmit()" in final-form
23-
// It will not be necessary anymore when the next version of final-form will be released (see https://github.com/final-form/final-form/pull/363)
24-
setTimeout(() => {
25-
// Ignored until next version of final-form is released. See https://github.com/final-form/final-form/pull/376
26-
// @ts-ignore
27-
form.restart(initialValuesMergedWithRecord);
28-
form.setConfig('keepDirtyOnReinitialize', true);
29-
});
22+
form.restart(initialValuesMergedWithRecord);
23+
form.setConfig('keepDirtyOnReinitialize', true);
3024
}, [form, JSON.stringify(record)]); // eslint-disable-line react-hooks/exhaustive-deps
3125
};
3226

‎packages/ra-test/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"@types/react-router-dom": "^5.1.0",
3737
"connected-react-router": "^6.5.2",
3838
"cross-env": "^5.2.0",
39-
"final-form": "^4.20.0",
39+
"final-form": "^4.20.2",
4040
"history": "^4.7.2",
4141
"ignore-styles": "~5.0.1",
4242
"ra-core": "^3.13.2",

‎packages/ra-ui-materialui/package.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@
3333
"@types/query-string": "5.1.0",
3434
"cross-env": "^5.2.0",
3535
"file-api": "~0.10.4",
36-
"final-form": "^4.20.0",
37-
"final-form-arrays": "^3.0.1",
36+
"final-form": "^4.20.2",
37+
"final-form-arrays": "^3.0.2",
3838
"ignore-styles": "~5.0.1",
3939
"ra-core": "^3.13.2",
4040
"react": "^17.0.0",
4141
"react-dom": "^17.0.0",
42-
"react-final-form": "^6.5.0",
43-
"react-final-form-arrays": "^3.1.1",
42+
"react-final-form": "^6.5.2",
43+
"react-final-form-arrays": "^3.1.3",
4444
"react-redux": "^7.1.0",
4545
"react-router": "^5.1.0",
4646
"react-router-dom": "^5.1.0",
@@ -52,13 +52,13 @@
5252
"@material-ui/core": "^4.11.2",
5353
"@material-ui/icons": "^4.11.2",
5454
"@material-ui/styles": "^4.11.2",
55-
"final-form": "^4.20.0",
56-
"final-form-arrays": "^3.0.1",
55+
"final-form": "^4.20.2",
56+
"final-form-arrays": "^3.0.2",
5757
"ra-core": "^3.9.0",
5858
"react": "^16.9.0 || ^17.0.0",
5959
"react-dom": "^16.9.0 || ^17.0.0",
60-
"react-final-form": "^6.3.3",
61-
"react-final-form-arrays": "^3.1.1",
60+
"react-final-form": "^6.5.2",
61+
"react-final-form-arrays": "^3.1.3",
6262
"react-redux": "^7.1.0",
6363
"react-router": "^5.1.0",
6464
"react-router-dom": "^5.1.0",

‎packages/ra-ui-materialui/src/form/SimpleFormView.tsx

+2-7
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { Children, FC, ReactElement } from 'react';
33
import classnames from 'classnames';
44
import FormInput from './FormInput';
55
import PropTypes from 'prop-types';
6-
import { FormRenderProps } from 'react-final-form';
7-
import { MutationMode, Record, RedirectionSideEffect } from 'ra-core';
6+
import { FormWithRedirectRenderProps, MutationMode, Record } from 'ra-core';
87
import Toolbar from './Toolbar';
98
import CardContentInner from '../layout/CardContentInner';
109

@@ -97,18 +96,14 @@ SimpleFormView.defaultProps = {
9796
component: CardContentInner,
9897
};
9998

100-
export interface SimpleFormViewProps extends FormRenderProps {
99+
export interface SimpleFormViewProps extends FormWithRedirectRenderProps {
101100
basePath?: string;
102101
className?: string;
103102
component?: React.ComponentType<any>;
104-
handleSubmitWithRedirect?: (redirectTo: RedirectionSideEffect) => void;
105103
margin?: 'none' | 'normal' | 'dense';
106104
mutationMode?: MutationMode;
107105
record?: Record;
108-
redirect?: RedirectionSideEffect;
109106
resource?: string;
110-
save?: () => void;
111-
saving?: boolean;
112107
toolbar?: ReactElement;
113108
/** @deprecated use mutationMode: undoable instead */
114109
undoable?: boolean;

‎packages/ra-ui-materialui/src/form/TabbedFormView.tsx

+3-8
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ import classnames from 'classnames';
1212
import { Route, useRouteMatch, useLocation } from 'react-router-dom';
1313
import { Divider } from '@material-ui/core';
1414
import { makeStyles } from '@material-ui/core/styles';
15-
import { FormRenderProps } from 'react-final-form';
1615
import {
1716
escapePath,
17+
FormWithRedirectRenderProps,
1818
MutationMode,
1919
Record,
20-
RedirectionSideEffect,
2120
} from 'ra-core';
2221
import Toolbar from './Toolbar';
2322
import TabbedFormTabs, { getTabFullPath } from './TabbedFormTabs';
@@ -29,7 +28,6 @@ export const TabbedFormView = (props: TabbedFormViewProps) => {
2928
children,
3029
className,
3130
classes: classesOverride,
32-
form,
3331
handleSubmit,
3432
handleSubmitWithRedirect,
3533
invalid,
@@ -183,18 +181,14 @@ TabbedFormView.defaultProps = {
183181
toolbar: <Toolbar />,
184182
};
185183

186-
export interface TabbedFormViewProps extends FormRenderProps {
184+
export interface TabbedFormViewProps extends FormWithRedirectRenderProps {
187185
basePath?: string;
188186
classes?: ClassesOverride<typeof useTabbedFormViewStyles>;
189187
className?: string;
190188
margin?: 'none' | 'normal' | 'dense';
191189
mutationMode?: MutationMode;
192-
handleSubmitWithRedirect?: (redirectTo: RedirectionSideEffect) => void;
193190
record?: Record;
194-
redirect?: RedirectionSideEffect;
195191
resource?: string;
196-
save?: () => void;
197-
saving?: boolean;
198192
syncWithLocation?: boolean;
199193
tabs?: ReactElement;
200194
toolbar?: ReactElement;
@@ -213,6 +207,7 @@ const sanitizeRestProps = ({
213207
dirtySinceLastSubmit,
214208
error,
215209
errors,
210+
form,
216211
hasSubmitErrors,
217212
hasValidationErrors,
218213
initialValues,

‎packages/react-admin/package.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@
3838
"@material-ui/icons": "^4.11.2",
3939
"@material-ui/styles": "^4.11.2",
4040
"connected-react-router": "^6.5.2",
41-
"final-form": "^4.20.0",
42-
"final-form-arrays": "^3.0.1",
41+
"final-form": "^4.20.2",
42+
"final-form-arrays": "^3.0.2",
4343
"final-form-submit-errors": "^0.1.2",
44-
"ra-core": "^3.13.2",
45-
"ra-i18n-polyglot": "^3.13.2",
46-
"ra-language-english": "^3.13.2",
47-
"ra-ui-materialui": "^3.13.2",
48-
"react-final-form": "^6.3.3",
49-
"react-final-form-arrays": "^3.1.1",
44+
"ra-core": "~3.13.2",
45+
"ra-i18n-polyglot": "~3.13.2",
46+
"ra-language-english": "~3.13.2",
47+
"ra-ui-materialui": "~3.13.2",
48+
"react-final-form": "^6.5.2",
49+
"react-final-form-arrays": "^3.1.3",
5050
"react-redux": "^7.1.0",
5151
"react-router": "^5.1.0",
5252
"react-router-dom": "^5.1.0",

0 commit comments

Comments
 (0)
Please sign in to comment.