-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
352 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 80 additions & 24 deletions
104
packages/ra-core/src/controller/details/useEditContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,91 @@ | ||
import { useContext } from 'react'; | ||
import { useContext, useMemo } from 'react'; | ||
import merge from 'lodash/merge'; | ||
|
||
import { Record } from '../../types'; | ||
import { EditContext } from './EditContext'; | ||
import { EditControllerProps } from './useEditController'; | ||
|
||
/** | ||
* Hook to read the edit controller props from the CreateContext. | ||
* | ||
* Mostly used within a <EditContext.Provider> (e.g. as a descendent of <Edit>). | ||
* | ||
* But you can also use it without a <EditContext.Provider>. In this case, it is up to you | ||
* to pass all the necessary props. | ||
* | ||
* The given props will take precedence over context values. | ||
* | ||
* @typedef {Object} EditControllerProps | ||
* | ||
* @returns {EditControllerProps} edit controller props | ||
* | ||
* @see useEditController for how it is filled | ||
* | ||
*/ | ||
export const useEditContext = <RecordType extends Record = Record>( | ||
props?: Partial<EditControllerProps<RecordType>> | ||
): Partial<EditControllerProps<RecordType>> => { | ||
// Can't find a way to specify the RecordType when CreateContext is declared | ||
// Can't find a way to specify the RecordType when EditContext is declared | ||
// @ts-ignore | ||
const context = useContext<EditControllerProps<RecordType>>(EditContext); | ||
|
||
if (!context.resource) { | ||
/** | ||
* The element isn't inside a <EditContext.Provider> | ||
* To avoid breakage in that case, fallback to props | ||
* | ||
* @deprecated - to be removed in 4.0 | ||
*/ | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.log( | ||
"Edit components must be used inside a <EditContext.Provider>. Relying on props rather than context to get Edit data and callbacks is deprecated and won't be supported in the next major version of react-admin." | ||
); | ||
} | ||
// Necessary for actions (EditActions) which expect a data prop containing the record | ||
// @deprecated - to be removed in 4.0d | ||
return { | ||
...props, | ||
record: props.record || props.data, | ||
data: props.record || props.data, | ||
}; | ||
} | ||
|
||
return context; | ||
// Props take precedence over the context | ||
return useMemo( | ||
() => | ||
merge( | ||
{}, | ||
context, | ||
props != null ? extractEditContextProps(props) : {} | ||
), | ||
[context, props] | ||
); | ||
}; | ||
|
||
/** | ||
* Extract only the edit controller props | ||
* | ||
* @param {Object} props props passed to the useEditContext hook | ||
* | ||
* @returns {EditControllerProps} edit controller props | ||
*/ | ||
const extractEditContextProps = ({ | ||
basePath, | ||
data, | ||
record, | ||
defaultTitle, | ||
onFailureRef, | ||
onSuccessRef, | ||
transformRef, | ||
loaded, | ||
loading, | ||
redirect, | ||
setOnFailure, | ||
setOnSuccess, | ||
setTransform, | ||
resource, | ||
save, | ||
saving, | ||
successMessage, | ||
version, | ||
}: any) => ({ | ||
basePath, | ||
// Necessary for actions (EditActions) which expect a data prop containing the record | ||
// @deprecated - to be removed in 4.0d | ||
data: record || data, | ||
record: record || data, | ||
defaultTitle, | ||
onFailureRef, | ||
onSuccessRef, | ||
transformRef, | ||
loaded, | ||
loading, | ||
redirect, | ||
setOnFailure, | ||
setOnSuccess, | ||
setTransform, | ||
resource, | ||
save, | ||
saving, | ||
successMessage, | ||
version, | ||
}); |
84 changes: 60 additions & 24 deletions
84
packages/ra-core/src/controller/details/useShowContext.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,71 @@ | ||
import { useContext } from 'react'; | ||
import { useContext, useMemo } from 'react'; | ||
import merge from 'lodash/merge'; | ||
|
||
import { Record } from '../../types'; | ||
import { ShowContext } from './ShowContext'; | ||
import { ShowControllerProps } from './useShowController'; | ||
|
||
/** | ||
* Hook to read the show controller props from the ShowContext. | ||
* | ||
* Mostly used within a <ShowContext.Provider> (e.g. as a descendent of <Show>). | ||
* | ||
* But you can also use it without a <ShowContext.Provider>. In this case, it is up to you | ||
* to pass all the necessary props. | ||
* | ||
* The given props will take precedence over context values. | ||
* | ||
* @typedef {Object} ShowControllerProps | ||
* | ||
* @returns {ShowControllerProps} create controller props | ||
* | ||
* @see useShowController for how it is filled | ||
* | ||
*/ | ||
export const useShowContext = <RecordType extends Record = Record>( | ||
props?: Partial<ShowControllerProps<RecordType>> | ||
): Partial<ShowControllerProps<RecordType>> => { | ||
// Can't find a way to specify the RecordType when CreateContext is declared | ||
// Can't find a way to specify the RecordType when ShowContext is declared | ||
// @ts-ignore | ||
const context = useContext<ShowControllerProps<RecordType>>(ShowContext); | ||
|
||
if (!context.resource) { | ||
/** | ||
* The element isn't inside a <ShowContext.Provider> | ||
* To avoid breakage in that case, fallback to props | ||
* | ||
* @deprecated - to be removed in 4.0 | ||
*/ | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.log( | ||
"Show components must be used inside a <ShowContext.Provider>. Relying on props rather than context to get Show data and callbacks is deprecated and won't be supported in the next major version of react-admin." | ||
); | ||
} | ||
// Necessary for actions (EditActions) which expect a data prop containing the record | ||
// @deprecated - to be removed in 4.0d | ||
return { | ||
...props, | ||
record: props.record || props.data, | ||
data: props.record || props.data, | ||
}; | ||
} | ||
|
||
return context; | ||
// Props take precedence over the context | ||
return useMemo( | ||
() => | ||
merge( | ||
{}, | ||
context, | ||
props != null ? extractShowContextProps(props) : {} | ||
), | ||
[context, props] | ||
); | ||
}; | ||
|
||
/** | ||
* Extract only the show controller props | ||
* | ||
* @param {Object} props props passed to the useShowContext hook | ||
* | ||
* @returns {ShowControllerProps} show controller props | ||
*/ | ||
const extractShowContextProps = ({ | ||
basePath, | ||
record, | ||
data, | ||
defaultTitle, | ||
loaded, | ||
loading, | ||
resource, | ||
version, | ||
}: any) => ({ | ||
basePath, | ||
// Necessary for actions (EditActions) which expect a data prop containing the record | ||
// @deprecated - to be removed in 4.0d | ||
record: record || data, | ||
data: record || data, | ||
defaultTitle, | ||
loaded, | ||
loading, | ||
resource, | ||
version, | ||
}); |
Oops, something went wrong.