diff --git a/packages/ra-core/package.json b/packages/ra-core/package.json index c64483159b0..7dd4116b550 100644 --- a/packages/ra-core/package.json +++ b/packages/ra-core/package.json @@ -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", @@ -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", diff --git a/packages/ra-core/src/form/FormWithRedirect.tsx b/packages/ra-core/src/form/FormWithRedirect.tsx index dbe40dac831..46a0117a7a8 100644 --- a/packages/ra-core/src/form/FormWithRedirect.tsx +++ b/packages/ra-core/src/form/FormWithRedirect.tsx @@ -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'; @@ -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'; @@ -44,7 +45,7 @@ import { FormContextProvider } from './FormContextProvider'; * * @param {Props} props */ -const FormWithRedirect: FC = ({ +const FormWithRedirect = ({ debug, decorators, defaultValue, @@ -65,7 +66,7 @@ const FormWithRedirect: FC = ({ warnWhenUnsavedChanges, sanitizeEmptyValues: shouldSanitizeEmptyValues = true, ...props -}) => { +}: FormWithRedirectProps) => { const redirect = useRef(props.redirect); const onSave = useRef(save); const formGroups = useRef<{ [key: string]: string[] }>({}); @@ -167,6 +168,7 @@ const FormWithRedirect: FC = ({ validate={validate} validateOnBlur={validateOnBlur} render={formProps => ( + // @ts-ignore Ignored because of a weird error about the active prop = ({ }; export type FormWithRedirectProps = FormWithRedirectOwnProps & - Omit; + Omit; +export type FormWithRedirectRenderProps = Omit< + FormViewProps, + 'chilren' | 'render' | 'setRedirect' +>; export type FormWithRedirectRender = ( - props: Omit + props: FormWithRedirectRenderProps ) => React.ReactElement; export type FormWithRedirectSave = ( - data: Partial, + data: Partial, redirectTo: RedirectionSideEffect, options?: { onSuccess?: OnSuccess; onFailure?: OnFailure; } ) => void; + export interface FormWithRedirectOwnProps { defaultValue?: any; - record?: Record; + record?: RaRecord; redirect?: RedirectionSideEffect; render: FormWithRedirectRender; save?: FormWithRedirectSave; @@ -228,18 +235,18 @@ export type HandleSubmitWithRedirect = ( ) => void; interface FormViewProps extends FormWithRedirectOwnProps, - Omit { + Omit { handleSubmitWithRedirect?: HandleSubmitWithRedirect; setRedirect: SetRedirect; warnWhenUnsavedChanges?: boolean; } -const FormView: FC = ({ +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); diff --git a/packages/ra-core/src/form/index.ts b/packages/ra-core/src/form/index.ts index eb2e75fbfe9..1ef6670495e 100644 --- a/packages/ra-core/src/form/index.ts +++ b/packages/ra-core/src/form/index.ts @@ -7,6 +7,7 @@ import FormField from './FormField'; import FormWithRedirect, { FormWithRedirectProps, FormWithRedirectRender, + FormWithRedirectRenderProps, FormWithRedirectSave, HandleSubmitWithRedirect, } from './FormWithRedirect'; @@ -31,6 +32,7 @@ export type { FormDataConsumerRender, FormDataConsumerRenderParams, FormWithRedirectProps, + FormWithRedirectRenderProps, FormWithRedirectRender, FormWithRedirectSave, HandleSubmitWithRedirect, diff --git a/packages/ra-core/src/form/useInitializeFormWithRecord.ts b/packages/ra-core/src/form/useInitializeFormWithRecord.ts index 9671a770c94..262c1c02b50 100644 --- a/packages/ra-core/src/form/useInitializeFormWithRecord.ts +++ b/packages/ra-core/src/form/useInitializeFormWithRecord.ts @@ -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 }; diff --git a/packages/ra-test/package.json b/packages/ra-test/package.json index 65983f70b42..52c80f75a25 100644 --- a/packages/ra-test/package.json +++ b/packages/ra-test/package.json @@ -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", diff --git a/packages/ra-ui-materialui/package.json b/packages/ra-ui-materialui/package.json index 67d20754f77..082f3a93709 100644 --- a/packages/ra-ui-materialui/package.json +++ b/packages/ra-ui-materialui/package.json @@ -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", @@ -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", diff --git a/packages/ra-ui-materialui/src/form/SimpleFormView.tsx b/packages/ra-ui-materialui/src/form/SimpleFormView.tsx index 7fe40f5398c..4b75666bc44 100644 --- a/packages/ra-ui-materialui/src/form/SimpleFormView.tsx +++ b/packages/ra-ui-materialui/src/form/SimpleFormView.tsx @@ -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'; @@ -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; - 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; diff --git a/packages/ra-ui-materialui/src/form/TabbedFormView.tsx b/packages/ra-ui-materialui/src/form/TabbedFormView.tsx index f3038d9d8a5..97881c57dd3 100644 --- a/packages/ra-ui-materialui/src/form/TabbedFormView.tsx +++ b/packages/ra-ui-materialui/src/form/TabbedFormView.tsx @@ -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'; @@ -29,7 +28,6 @@ export const TabbedFormView = (props: TabbedFormViewProps) => { children, className, classes: classesOverride, - form, handleSubmit, handleSubmitWithRedirect, invalid, @@ -183,18 +181,14 @@ TabbedFormView.defaultProps = { toolbar: , }; -export interface TabbedFormViewProps extends FormRenderProps { +export interface TabbedFormViewProps extends FormWithRedirectRenderProps { basePath?: string; classes?: ClassesOverride; 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; @@ -213,6 +207,7 @@ const sanitizeRestProps = ({ dirtySinceLastSubmit, error, errors, + form, hasSubmitErrors, hasValidationErrors, initialValues, diff --git a/packages/react-admin/package.json b/packages/react-admin/package.json index 8db218655ce..bc8caacb6f4 100644 --- a/packages/react-admin/package.json +++ b/packages/react-admin/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index 36c3892ac80..c675d8fd963 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1211,7 +1211,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ== @@ -1232,6 +1232,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.1": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.9.tgz#97dbe2116e2630c489f22e0656decd60aaa1fcee" + integrity sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.12.5": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" @@ -1888,11 +1895,6 @@ dependencies: any-observable "^0.3.0" -"@scarf/scarf@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.0.5.tgz#accee0bce88a9047672f7c8faf3cada59c996b81" - integrity sha512-9WKaGVpQH905Aqkk+BczFEeLQxS07rl04afFRPUG9IcSlOwmo5EVVuuNu0d4M9LMYucObvK0LoAe+5HfMW2QhQ== - "@sindresorhus/is@^0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" @@ -8212,7 +8214,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -final-form-arrays@^3.0.1: +final-form-arrays@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/final-form-arrays/-/final-form-arrays-3.0.2.tgz#9f3bef778dec61432357744eb6f3abef7e7f3847" integrity sha512-TfO8aZNz3RrsZCDx8GHMQcyztDNpGxSSi9w4wpSNKlmv2PfFWVVM8P7Yj5tj4n0OWax+x5YwTLhT5BnqSlCi+w== @@ -8222,13 +8224,12 @@ final-form-submit-errors@^0.1.2: resolved "https://registry.yarnpkg.com/final-form-submit-errors/-/final-form-submit-errors-0.1.2.tgz#1c59d10386d7b5a1a5e89f9389fa7cf85d1255c5" integrity sha512-2EwHSdf9Sy80bnsGRrDKBLp5C2uY7hL65o8tpqK/FWxyBpXtT519SsIZC4etLpGen2kjFCpYrxYkzFUfbIEXsQ== -final-form@^4.20.0: - version "4.20.0" - resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.20.0.tgz#454ba46f783a4c4404ad875cf36f470395ad5efa" - integrity sha512-kdPGNlR/23M2p7ccVwE/vCBQH9TH1NAhhMVkETHbaQXkTWIJdEii3ZdHrOgYvFY7O87myEhcqzx3zjMERtoNJg== +final-form@^4.20.2: + version "4.20.2" + resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.20.2.tgz#c820b37d7ebb73d71169480256a36c7e6e6c9155" + integrity sha512-5i0IxqwjjPG1nUNCjWhqPCvQJJ2R+QwTwaAnjPmFnLbyjIHWuBPU8u+Ps4G3TcX2Sjno+O5xCZJzYcMJEzzfCQ== dependencies: "@babel/runtime" "^7.10.0" - "@scarf/scarf" "^1.0.5" finalhandler@1.1.1: version "1.1.1" @@ -14789,21 +14790,19 @@ react-error-overlay@^6.0.8: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de" integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw== -react-final-form-arrays@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/react-final-form-arrays/-/react-final-form-arrays-3.1.1.tgz#39d23e7ede966e418cad209e8fde46da1d603e99" - integrity sha512-e6S1x9597cvI4QPniOPmllXXandDAqCCuBo4AvXstZYgcV8whsqzk8aCrmQEy6eEfy2tEhvn6f4VI1GY+JBRsg== +react-final-form-arrays@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/react-final-form-arrays/-/react-final-form-arrays-3.1.3.tgz#d3594c500495a4cf5e437070ada989da9624bba2" + integrity sha512-dzBiLfbr9l1YRExARBpJ8uA/djBenCvFrbrsXjd362joDl3vT+WhmMKKr6HDQMJffjA8T4gZ3n5+G9M59yZfuQ== dependencies: - "@babel/runtime" "^7.4.5" + "@babel/runtime" "^7.12.1" -react-final-form@^6.3.3, react-final-form@^6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.5.0.tgz#b0440acf534fd57991c048764ab20af13124aed6" - integrity sha512-H97PLCtfMIN32NHqm85E738Pj+NOF1p0eQEG+h5DbdaofwtqDRp7taHu45+PlXOqg9ANbM6MyXkYxWpIiE6qbQ== +react-final-form@^6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.5.2.tgz#d04d1eb7d92eabc6f6c35206bb0eebfc4bfd924b" + integrity sha512-c5l45FYOoxtfpvsvMFh3w2WW8KNxbuebBUrM16rUrooQkewTs0Zahmv0TuKFX5jsC9BKn5Fo84j3ZVXQdURS4w== dependencies: - "@babel/runtime" "^7.10.0" - "@scarf/scarf" "^1.0.5" - ts-essentials "^6.0.5" + "@babel/runtime" "^7.12.1" "react-is@^16.12.0 || ^17.0.0", "react-is@^16.8.0 || ^17.0.0", react-is@^17.0.1: version "17.0.1" @@ -17474,11 +17473,6 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -ts-essentials@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-6.0.5.tgz#dd5b98f73bd56dc94d15dfbc0fbf01da3163eb42" - integrity sha512-RSAKlpu+E0DCGY8FsbG92EveRLw2Y+UgK3ksX01w1VaHeG01dKkYo/KtAV4q0qPT6nPbLfyerb2YPVSediP+8g== - ts-invariant@^0.4.0: version "0.4.4" resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86"