import React , { cloneElement , ReactElement , SyntheticEvent } from 'react' ; import PropTypes from 'prop-types' ; import Button , { ButtonProps } from '@material-ui/core/Button' ; import CircularProgress from '@material-ui/core/CircularProgress' ; import { makeStyles } from '@material-ui/core/styles' ; import ContentSave from '@material-ui/icons/Save' ; import classnames from 'classnames' ; import { useTranslate , useNotify , RedirectionSideEffect , OnSuccess , OnFailure , TransformData , Record , HandleSubmitWithRedirect , useSaveContext , useFormContext , } from 'ra-core' ; import { sanitizeButtonRestProps } from './Button' ; import { FormRenderProps } from 'react-final-form' ; typedef Props prop { string } className prop { string } label prop { boolean } disabled prop { string } variant prop { ReactElement } icon prop { string | boolean } redirect prop { function } onSave prop { function } onSuccess prop { function } onFailure prop { function } transform param { Props } props example example example const SaveButton = ( props ) => { const { className , classes : classesOverride , invalid , label = 'ra.action.save' , disabled , redirect , saving , submitOnEnter , variant = 'contained' , icon = defaultIcon , onClick , handleSubmitWithRedirect , onSave , onSuccess , onFailure , transform , ... rest } = props ; const classes = useStyles ( props ) ; const notify = useNotify ( ) ; const translate = useTranslate ( ) ; const formContext = useFormContext ( ) ; const { setOnSuccess , setOnFailure , setTransform } = useSaveContext ( props ) ; const handleClick = event => { if ( typeof onSave === 'function' ) { if ( process . env . NODE_ENV !== 'production' ) { console . warn ( '<SaveButton onSave> prop is deprecated, use the onSuccess prop instead.' ) ; if ( ! formContext || ! formContext . setOnSave ) { console . warn ( 'Using <SaveButton> outside a FormContext is deprecated.' ) ; } } if ( formContext && formContext . setOnSave ) { formContext . setOnSave ( onSave ) ; } } else { if ( process . env . NODE_ENV !== 'production' && ( ! formContext || ! formContext . setOnSave ) ) { console . warn ( 'Using <SaveButton> outside a FormContext is deprecated.' ) ; } if ( formContext && formContext . setOnSave ) { formContext . setOnSave ( ) ; } } if ( onSuccess ) { setOnSuccess ( onSuccess ) ; } if ( onFailure ) { setOnFailure ( onFailure ) ; } if ( transform ) { setTransform ( transform ) ; } if ( saving ) { event . preventDefault ( ) ; } else { if ( invalid ) { notify ( 'ra.message.invalid_form' , { type : 'warning' } ) ; } if ( event ) { event . preventDefault ( ) ; } handleSubmitWithRedirect ( redirect ) ; } if ( typeof onClick === 'function' ) { onClick ( event ) ; } } ; const type = submitOnEnter ? 'submit' : 'button' ; const displayedLabel = label && translate ( label , { _ : label } ) ; return ( < Button className = { classnames ( classes . button , className ) } variant = { variant } type = { type } onClick = { handleClick } color = { saving ? 'default' : 'primary' } aria - label = { displayedLabel } disabled = { disabled } { ... sanitizeButtonRestProps ( rest ) } > { saving ? ( < CircularProgress size = { 18 } thickness = { 2 } className = { classes . leftIcon } / > ) : ( cloneElement ( icon , { className : classnames ( classes . leftIcon , classes . icon ) , } ) ) } { displayedLabel } < /Button>); } ; const defaultIcon = < ContentSave />; const useStyles = makeStyles ( theme => ( { button : { position : 'relative' , } , leftIcon : { marginRight : theme . spacing ( 1 ) , } , icon : { fontSize : 18 , } , } ) , { name : 'RaSaveButton' } ) ; interface Props { classes ? : object ; className ? : string ; handleSubmitWithRedirect ? : HandleSubmitWithRedirect | FormRenderProps [ 'handleSubmit' ] ; onSave ? : ( values : object , redirect : RedirectionSideEffect ) => void ; onSuccess ? : OnSuccess ; onFailure ? : OnFailure ; transform ? : TransformData ; icon ? : ReactElement ; invalid ? : boolean ; label ? : string ; onClick ? : ( ) => void ; disabled ? : boolean ; redirect ? : RedirectionSideEffect ; saving ? : boolean ; submitOnEnter ? : boolean ; variant ? : string ; basePath ? : string ; handleSubmit ? : ( event ? : SyntheticEvent < HTMLFormElement > ) => Promise < Object > ; record ? : Record ; resource ? : string ; undoable ? : boolean ; } export type SaveButtonProps = Props & ButtonProps ; SaveButton . propTypes = { className : PropTypes . string , classes : PropTypes . object , handleSubmitWithRedirect : PropTypes . func , onSave : PropTypes . func , invalid : PropTypes . bool , label : PropTypes . string , redirect : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . bool , PropTypes . func , ] ) , saving : PropTypes . bool , submitOnEnter : PropTypes . bool , variant : PropTypes . oneOf ( [ 'text' , 'outlined' , 'contained' ] ) , icon : PropTypes . element , } ; export default SaveButton ;