Skip to content

Commit

Permalink
Merge pull request #6005 from marmelab/fix-warn-when-unsaved-changes
Browse files Browse the repository at this point in the history
Fix Form Loose Dirty Fields Values After Cancelling Navigation
  • Loading branch information
fzaninotto authored Mar 11, 2021
2 parents 0f46765 + 7ba378c commit a171deb
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 89 deletions.
8 changes: 4 additions & 4 deletions packages/ra-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
"@types/react-router-dom": "^5.1.0",
"connected-react-router": "^6.5.2",
"cross-env": "^5.2.0",
"final-form": "^4.20.0",
"final-form": "^4.20.2",
"history": "^4.7.2",
"ignore-styles": "~5.0.1",
"ra-test": "^3.13.2",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-final-form": "^6.5.0",
"react-final-form": "^6.5.2",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand All @@ -54,11 +54,11 @@
},
"peerDependencies": {
"connected-react-router": "^6.5.2",
"final-form": "^4.18.5",
"final-form": "^4.20.2",
"final-form-submit-errors": "^0.1.2",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react-final-form": "^6.3.3",
"react-final-form": "^6.5.2",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand Down
39 changes: 23 additions & 16 deletions packages/ra-core/src/form/FormWithRedirect.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import * as React from 'react';
import { FC, useRef, useCallback, useEffect, useMemo } from 'react';
import {
Form,
FormProps,
FormRenderProps as FinalFormFormRenderProps,
} from 'react-final-form';
import { useRef, useCallback, useEffect, useMemo } from 'react';
import { Form, FormProps, FormRenderProps } from 'react-final-form';
import arrayMutators from 'final-form-arrays';
import { submitErrorsMutators } from 'final-form-submit-errors';

Expand All @@ -13,7 +9,12 @@ import useWarnWhenUnsavedChanges from './useWarnWhenUnsavedChanges';
import useResetSubmitErrors from './useResetSubmitErrors';
import sanitizeEmptyValues from './sanitizeEmptyValues';
import getFormInitialValues from './getFormInitialValues';
import { FormContextValue, Record, OnSuccess, OnFailure } from '../types';
import {
FormContextValue,
Record as RaRecord,
OnSuccess,
OnFailure,
} from '../types';
import { RedirectionSideEffect } from '../sideEffect';
import { useDispatch } from 'react-redux';
import { setAutomaticRefresh } from '../actions/uiActions';
Expand Down Expand Up @@ -44,7 +45,7 @@ import { FormContextProvider } from './FormContextProvider';
*
* @param {Props} props
*/
const FormWithRedirect: FC<FormWithRedirectProps> = ({
const FormWithRedirect = ({
debug,
decorators,
defaultValue,
Expand All @@ -65,7 +66,7 @@ const FormWithRedirect: FC<FormWithRedirectProps> = ({
warnWhenUnsavedChanges,
sanitizeEmptyValues: shouldSanitizeEmptyValues = true,
...props
}) => {
}: FormWithRedirectProps) => {
const redirect = useRef(props.redirect);
const onSave = useRef(save);
const formGroups = useRef<{ [key: string]: string[] }>({});
Expand Down Expand Up @@ -167,6 +168,7 @@ const FormWithRedirect: FC<FormWithRedirectProps> = ({
validate={validate}
validateOnBlur={validateOnBlur}
render={formProps => (
// @ts-ignore Ignored because of a weird error about the active prop
<FormView
{...props}
{...formProps}
Expand All @@ -184,23 +186,28 @@ const FormWithRedirect: FC<FormWithRedirectProps> = ({
};

export type FormWithRedirectProps = FormWithRedirectOwnProps &
Omit<FormProps, 'onSubmit' | 'active'>;
Omit<FormProps, 'onSubmit'>;

export type FormWithRedirectRenderProps = Omit<
FormViewProps,
'chilren' | 'render' | 'setRedirect'
>;
export type FormWithRedirectRender = (
props: Omit<FormViewProps, 'render' | 'setRedirect'>
props: FormWithRedirectRenderProps
) => React.ReactElement<any, any>;

export type FormWithRedirectSave = (
data: Partial<Record>,
data: Partial<RaRecord>,
redirectTo: RedirectionSideEffect,
options?: {
onSuccess?: OnSuccess;
onFailure?: OnFailure;
}
) => void;

export interface FormWithRedirectOwnProps {
defaultValue?: any;
record?: Record;
record?: RaRecord;
redirect?: RedirectionSideEffect;
render: FormWithRedirectRender;
save?: FormWithRedirectSave;
Expand Down Expand Up @@ -228,18 +235,18 @@ export type HandleSubmitWithRedirect = (
) => void;
interface FormViewProps
extends FormWithRedirectOwnProps,
Omit<FinalFormFormRenderProps, 'render' | 'active'> {
Omit<FormRenderProps, 'render' | 'component'> {
handleSubmitWithRedirect?: HandleSubmitWithRedirect;
setRedirect: SetRedirect;
warnWhenUnsavedChanges?: boolean;
}

const FormView: FC<FormViewProps> = ({
const FormView = ({
render,
warnWhenUnsavedChanges,
setRedirect,
...props
}) => {
}: FormViewProps) => {
// if record changes (after a getOne success or a refresh), the form must be updated
useInitializeFormWithRecord(props.record);
useWarnWhenUnsavedChanges(warnWhenUnsavedChanges);
Expand Down
2 changes: 2 additions & 0 deletions packages/ra-core/src/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import FormField from './FormField';
import FormWithRedirect, {
FormWithRedirectProps,
FormWithRedirectRender,
FormWithRedirectRenderProps,
FormWithRedirectSave,
HandleSubmitWithRedirect,
} from './FormWithRedirect';
Expand All @@ -31,6 +32,7 @@ export type {
FormDataConsumerRender,
FormDataConsumerRenderParams,
FormWithRedirectProps,
FormWithRedirectRenderProps,
FormWithRedirectRender,
FormWithRedirectSave,
HandleSubmitWithRedirect,
Expand Down
10 changes: 2 additions & 8 deletions packages/ra-core/src/form/useInitializeFormWithRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,8 @@ const useInitializeFormWithRecord = record => {
// Disable this option when re-initializing the form because in this case, it should reset the dirty state of all fields
// We do need to keep this option for dynamically added inputs though which is why it is kept at the form level
form.setConfig('keepDirtyOnReinitialize', false);
// Since the submit function returns a promise, use setTimeout to prevent the error "Cannot reset() in onSubmit()" in final-form
// 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)
setTimeout(() => {
// Ignored until next version of final-form is released. See https://github.com/final-form/final-form/pull/376
// @ts-ignore
form.restart(initialValuesMergedWithRecord);
form.setConfig('keepDirtyOnReinitialize', true);
});
form.restart(initialValuesMergedWithRecord);
form.setConfig('keepDirtyOnReinitialize', true);
}, [form, JSON.stringify(record)]); // eslint-disable-line react-hooks/exhaustive-deps
};

Expand Down
2 changes: 1 addition & 1 deletion packages/ra-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@types/react-router-dom": "^5.1.0",
"connected-react-router": "^6.5.2",
"cross-env": "^5.2.0",
"final-form": "^4.20.0",
"final-form": "^4.20.2",
"history": "^4.7.2",
"ignore-styles": "~5.0.1",
"ra-core": "^3.13.2",
Expand Down
16 changes: 8 additions & 8 deletions packages/ra-ui-materialui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
"@types/query-string": "5.1.0",
"cross-env": "^5.2.0",
"file-api": "~0.10.4",
"final-form": "^4.20.0",
"final-form-arrays": "^3.0.1",
"final-form": "^4.20.2",
"final-form-arrays": "^3.0.2",
"ignore-styles": "~5.0.1",
"ra-core": "^3.13.2",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-final-form": "^6.5.0",
"react-final-form-arrays": "^3.1.1",
"react-final-form": "^6.5.2",
"react-final-form-arrays": "^3.1.3",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand All @@ -52,13 +52,13 @@
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.2",
"final-form": "^4.20.0",
"final-form-arrays": "^3.0.1",
"final-form": "^4.20.2",
"final-form-arrays": "^3.0.2",
"ra-core": "^3.9.0",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react-final-form": "^6.3.3",
"react-final-form-arrays": "^3.1.1",
"react-final-form": "^6.5.2",
"react-final-form-arrays": "^3.1.3",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand Down
9 changes: 2 additions & 7 deletions packages/ra-ui-materialui/src/form/SimpleFormView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { Children, FC, ReactElement } from 'react';
import classnames from 'classnames';
import FormInput from './FormInput';
import PropTypes from 'prop-types';
import { FormRenderProps } from 'react-final-form';
import { MutationMode, Record, RedirectionSideEffect } from 'ra-core';
import { FormWithRedirectRenderProps, MutationMode, Record } from 'ra-core';
import Toolbar from './Toolbar';
import CardContentInner from '../layout/CardContentInner';

Expand Down Expand Up @@ -97,18 +96,14 @@ SimpleFormView.defaultProps = {
component: CardContentInner,
};

export interface SimpleFormViewProps extends FormRenderProps {
export interface SimpleFormViewProps extends FormWithRedirectRenderProps {
basePath?: string;
className?: string;
component?: React.ComponentType<any>;
handleSubmitWithRedirect?: (redirectTo: RedirectionSideEffect) => void;
margin?: 'none' | 'normal' | 'dense';
mutationMode?: MutationMode;
record?: Record;
redirect?: RedirectionSideEffect;
resource?: string;
save?: () => void;
saving?: boolean;
toolbar?: ReactElement;
/** @deprecated use mutationMode: undoable instead */
undoable?: boolean;
Expand Down
11 changes: 3 additions & 8 deletions packages/ra-ui-materialui/src/form/TabbedFormView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import classnames from 'classnames';
import { Route, useRouteMatch, useLocation } from 'react-router-dom';
import { Divider } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import { FormRenderProps } from 'react-final-form';
import {
escapePath,
FormWithRedirectRenderProps,
MutationMode,
Record,
RedirectionSideEffect,
} from 'ra-core';
import Toolbar from './Toolbar';
import TabbedFormTabs, { getTabFullPath } from './TabbedFormTabs';
Expand All @@ -29,7 +28,6 @@ export const TabbedFormView = (props: TabbedFormViewProps) => {
children,
className,
classes: classesOverride,
form,
handleSubmit,
handleSubmitWithRedirect,
invalid,
Expand Down Expand Up @@ -183,18 +181,14 @@ TabbedFormView.defaultProps = {
toolbar: <Toolbar />,
};

export interface TabbedFormViewProps extends FormRenderProps {
export interface TabbedFormViewProps extends FormWithRedirectRenderProps {
basePath?: string;
classes?: ClassesOverride<typeof useTabbedFormViewStyles>;
className?: string;
margin?: 'none' | 'normal' | 'dense';
mutationMode?: MutationMode;
handleSubmitWithRedirect?: (redirectTo: RedirectionSideEffect) => void;
record?: Record;
redirect?: RedirectionSideEffect;
resource?: string;
save?: () => void;
saving?: boolean;
syncWithLocation?: boolean;
tabs?: ReactElement;
toolbar?: ReactElement;
Expand All @@ -213,6 +207,7 @@ const sanitizeRestProps = ({
dirtySinceLastSubmit,
error,
errors,
form,
hasSubmitErrors,
hasValidationErrors,
initialValues,
Expand Down
16 changes: 8 additions & 8 deletions packages/react-admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.2",
"connected-react-router": "^6.5.2",
"final-form": "^4.20.0",
"final-form-arrays": "^3.0.1",
"final-form": "^4.20.2",
"final-form-arrays": "^3.0.2",
"final-form-submit-errors": "^0.1.2",
"ra-core": "^3.13.2",
"ra-i18n-polyglot": "^3.13.2",
"ra-language-english": "^3.13.2",
"ra-ui-materialui": "^3.13.2",
"react-final-form": "^6.3.3",
"react-final-form-arrays": "^3.1.1",
"ra-core": "~3.13.2",
"ra-i18n-polyglot": "~3.13.2",
"ra-language-english": "~3.13.2",
"ra-ui-materialui": "~3.13.2",
"react-final-form": "^6.5.2",
"react-final-form-arrays": "^3.1.3",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand Down
Loading

0 comments on commit a171deb

Please sign in to comment.