Skip to content

Commit

Permalink
Merge pull request #3599 from jaytula/usestyles-nodeform
Browse files Browse the repository at this point in the history
[RFR] Convert NodeForm component to hooks
  • Loading branch information
djhi authored Aug 27, 2019
2 parents 2044887 + 2a465e3 commit 6456961
Showing 1 changed file with 112 additions and 110 deletions.
222 changes: 112 additions & 110 deletions packages/ra-tree-ui-materialui/src/NodeForm.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { cloneElement, Children, Component } from 'react';
import React, { cloneElement, Children, useCallback } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import { withStyles } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/core/styles';
import { Form } from 'react-final-form';
import {
crudUpdate as crudUpdateAction,
Expand All @@ -11,13 +10,13 @@ import {

import NodeFormActions from './NodeFormActions';

const styles = {
const useStyles = makeStyles({
root: {
alignItems: 'center',
display: 'flex',
flexGrow: 1,
},
};
});

const sanitizeRestProps = ({
anyTouched,
Expand Down Expand Up @@ -71,58 +70,52 @@ const sanitizeRestProps = ({
validate,
...props
}) => props;
class NodeForm extends Component {
static propTypes = {
actions: PropTypes.node,
basePath: PropTypes.string.isRequired,
cancelDropOnChildren: PropTypes.bool,
children: PropTypes.node,
classes: PropTypes.object,
dispatchCrudUpdate: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
invalid: PropTypes.bool,
node: PropTypes.object.isRequired,
pristine: PropTypes.bool,
resource: PropTypes.string.isRequired,
saving: PropTypes.bool,
startUndoable: PropTypes.func.isRequired,
submitOnEnter: PropTypes.bool,
undoable: PropTypes.bool,
};

static defaultProps = {
actions: <NodeFormActions />,
};
function NodeForm({
actions,
basePath,
children,
classes: classesOverride,
handleSubmit: handleSubmitProp,
invalid,
node,
pristine,
resource,
saving,
submitOnEnter = true,
...props
}) {
const classes = useStyles({ classes: classesOverride });

handleClick = event => {
const handleClick = useCallback(event => {
event.persist();
// This ensure clicking on an input or button does not collapse/expand a node
// When clicking on the form (empty spaces around inputs) however, it should
// propagate to the parent
if (event.target.tagName.toLowerCase() !== 'form') {
event.stopPropagation();
}
};
}, []);

handleDrop = event => {
event.persist();
if (this.props.cancelDropOnChildren) {
event.preventDefault();
}
};
const { cancelDropOnChildren } = props;
const handleDrop = useCallback(
event => {
event.persist();
if (cancelDropOnChildren) {
event.preventDefault();
}
},
[cancelDropOnChildren]
);

handleSubmit = () => {
const {
basePath,
dispatchCrudUpdate,
handleSubmit,
node: { record },
resource,
startUndoable,
undoable = true,
} = this.props;

return handleSubmit(values =>
const {
dispatchCrudUpdate,
node: { record },
startUndoable,
undoable = true,
} = props;
const handleSubmit = useCallback(() => {
return handleSubmitProp(values =>
undoable
? startUndoable(
crudUpdateAction(
Expand All @@ -143,76 +136,85 @@ class NodeForm extends Component {
false
)
);
};

render() {
const {
actions,
basePath,
children,
classes,
handleSubmit,
invalid,
node,
pristine,
resource,
saving,
submitOnEnter = true,
...props
} = this.props;
}, [
basePath,
handleSubmitProp,
resource,
dispatchCrudUpdate,
record,
startUndoable,
undoable,
]);

return (
<Form
onSubmit={this.handleSubmit}
render={({ handleSubmit }) => (
<form
className={classes.root}
onClick={this.handleClick}
onSubmit={handleSubmit}
{...sanitizeRestProps(props)}
>
{Children.map(children, field =>
field
? cloneElement(field, {
basePath:
field.props.basePath || basePath,
onDrop: this.handleDrop,
record: node.record,
resource,
})
: null
)}
{actions &&
cloneElement(actions, {
basePath,
record: node.record,
resource,
handleSubmit: this.handleSubmit,
handleSubmitWithRedirect: this.handleSubmit,
invalid,
pristine,
saving,
submitOnEnter,
})}
</form>
)}
/>
);
}
return (
<Form
onSubmit={handleSubmit}
render={({ handleSubmit }) => (
<form
className={classes.root}
onClick={handleClick}
onSubmit={handleSubmit}
{...sanitizeRestProps(props)}
>
{Children.map(children, field =>
field
? cloneElement(field, {
basePath: field.props.basePath || basePath,
onDrop: handleDrop,
record: node.record,
resource,
})
: null
)}
{actions &&
cloneElement(actions, {
basePath,
record: node.record,
resource,
handleSubmit: handleSubmit,
handleSubmitWithRedirect: handleSubmit,
invalid,
pristine,
saving,
submitOnEnter,
})}
</form>
)}
/>
);
}

NodeForm.propTypes = {
actions: PropTypes.node,
basePath: PropTypes.string.isRequired,
cancelDropOnChildren: PropTypes.bool,
children: PropTypes.node,
classes: PropTypes.object,
dispatchCrudUpdate: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
invalid: PropTypes.bool,
node: PropTypes.object.isRequired,
pristine: PropTypes.bool,
resource: PropTypes.string.isRequired,
saving: PropTypes.bool,
startUndoable: PropTypes.func.isRequired,
submitOnEnter: PropTypes.bool,
undoable: PropTypes.bool,
};

NodeForm.defaultProps = {
actions: <NodeFormActions />,
};

const mapStateToProps = (state, { node }) => ({
initialValues: node.record,
record: node.record,
});

export default compose(
connect(
mapStateToProps,
{
dispatchCrudUpdate: crudUpdateAction,
startUndoable: startUndoableAction,
}
),
withStyles(styles)
export default connect(
mapStateToProps,
{
dispatchCrudUpdate: crudUpdateAction,
startUndoable: startUndoableAction,
}
)(NodeForm);

0 comments on commit 6456961

Please sign in to comment.