Skip to content

Commit

Permalink
Migrate from redux-form to react-final-form
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed Jul 31, 2019
1 parent 32d2b2a commit 306aef5
Show file tree
Hide file tree
Showing 57 changed files with 912 additions and 1,095 deletions.
4 changes: 2 additions & 2 deletions cypress/integration/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ describe('Create Page', () => {
value: 'Test teaser',
},
{
type: 'checkbox',
type: 'input',
name: 'commentable',
value: false,
value: 'false',
},
{
type: 'rich-text-input',
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('List Page', () => {
);
});

it('should filter directly while typing (with some debounce)', () => {
it.only('should filter directly while typing (with some debounce)', () => {
ListPagePosts.setFilterValue('q', 'quis culpa impedit');
cy.get(ListPagePosts.elements.recordRows).should(el =>
expect(el).to.have.length(1)
Expand Down
1 change: 0 additions & 1 deletion examples/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"react-router-dom": "^5.0.1",
"react-scripts": "^3.0.0",
"recompose": "~0.26.0",
"redux-form": "~8.2.0",
"redux-saga": "^1.0.0",
"source-map-explorer": "^2.0.0"
},
Expand Down
2 changes: 0 additions & 2 deletions examples/demo/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Admin, Resource } from 'react-admin';
import './App.css';

import authProvider from './authProvider';
import sagas from './sagas';
import themeReducer from './themeReducer';
import { Login, Layout } from './layout';
import { Dashboard } from './dashboard';
Expand Down Expand Up @@ -65,7 +64,6 @@ class App extends Component {
title=""
dataProvider={dataProvider}
customReducers={{ theme: themeReducer }}
customSagas={sagas}
customRoutes={customRoutes}
authProvider={authProvider}
dashboard={Dashboard}
Expand Down
152 changes: 79 additions & 73 deletions examples/demo/src/layout/Login.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { propTypes, reduxForm, Field } from 'redux-form';
import { Field, Form } from 'react-final-form';
import { useDispatch, useSelector } from 'react-redux';
import compose from 'recompose/compose';

import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
Expand All @@ -14,7 +13,7 @@ import { createMuiTheme, makeStyles } from '@material-ui/core/styles';
import { ThemeProvider } from '@material-ui/styles';
import LockIcon from '@material-ui/icons/Lock';

import { Notification, useTranslate, translate, userLogin } from 'react-admin';
import { Notification, useTranslate, userLogin } from 'react-admin';

import { lightTheme } from './themes';

Expand Down Expand Up @@ -58,7 +57,6 @@ const useStyles = makeStyles(theme => ({
},
}));

// see http://redux-form.com/6.4.3/examples/material-ui/
const renderInput = ({
meta: { touched, error } = {},
input: { ...inputProps },
Expand All @@ -73,7 +71,7 @@ const renderInput = ({
/>
);

const Login = ({ handleSubmit, location }) => {
const Login = ({ location }) => {
const translate = useTranslate();
const classes = useStyles();
const dispatch = useDispatch();
Expand All @@ -84,90 +82,98 @@ const Login = ({ handleSubmit, location }) => {
userLogin(auth, location.state ? location.state.nextPathname : '/')
);

const validate = (values, props) => {
const errors = {};
const { translate } = props;
if (!values.username) {
errors.username = translate('ra.validation.required');
}
if (!values.password) {
errors.password = translate('ra.validation.required');
}
return errors;
};

return (
<div className={classes.main}>
<Card className={classes.card}>
<div className={classes.avatar}>
<Avatar className={classes.icon}>
<LockIcon />
</Avatar>
</div>
<form onSubmit={handleSubmit(login)}>
<div className={classes.hint}>Hint: demo / demo</div>
<div className={classes.form}>
<div className={classes.input}>
<Field
autoFocus
name="username"
component={renderInput}
label={translate('ra.auth.username')}
disabled={isLoading}
/>
</div>
<div className={classes.input}>
<Field
name="password"
component={renderInput}
label={translate('ra.auth.password')}
type="password"
disabled={isLoading}
/>
</div>
<Form
onSubmit={login}
validate={validate}
render={({ handleSubmit, submitting }) => (
<form onSubmit={handleSubmit} noValidate>
<div className={classes.main}>
<Card className={classes.card}>
<div className={classes.avatar}>
<Avatar className={classes.icon}>
<LockIcon />
</Avatar>
</div>
<form onSubmit={handleSubmit(login)}>
<div className={classes.hint}>
Hint: demo / demo
</div>
<div className={classes.form}>
<div className={classes.input}>
<Field
autoFocus
name="username"
component={renderInput}
label={translate(
'ra.auth.username'
)}
disabled={isLoading}
/>
</div>
<div className={classes.input}>
<Field
name="password"
component={renderInput}
label={translate(
'ra.auth.password'
)}
type="password"
disabled={isLoading}
/>
</div>
</div>
<CardActions className={classes.actions}>
<Button
variant="contained"
type="submit"
color="primary"
disabled={isLoading}
className={classes.button}
fullWidth
>
{isLoading && (
<CircularProgress
size={25}
thickness={2}
/>
)}
{translate('ra.auth.sign_in')}
</Button>
</CardActions>
</form>
</Card>
<Notification />
</div>
<CardActions className={classes.actions}>
<Button
variant="contained"
type="submit"
color="primary"
disabled={isLoading}
className={classes.button}
fullWidth
>
{isLoading && (
<CircularProgress size={25} thickness={2} />
)}
{translate('ra.auth.sign_in')}
</Button>
</CardActions>
</form>
</Card>
<Notification />
</div>
)}
/>
);
};

Login.propTypes = {
...propTypes,
authProvider: PropTypes.func,
previousRoute: PropTypes.string,
};

const enhance = compose(
translate,
reduxForm({
form: 'signIn',
validate: (values, props) => {
const errors = {};
const { translate } = props;
if (!values.username) {
errors.username = translate('ra.validation.required');
}
if (!values.password) {
errors.password = translate('ra.validation.required');
}
return errors;
},
})
);

const EnhancedLogin = enhance(Login);

// We need to put the ThemeProvider decoration in another component
// Because otherwise the withStyles() HOC used in EnhancedLogin won't get
// the right theme
const LoginWithTheme = props => (
<ThemeProvider theme={createMuiTheme(lightTheme)}>
<EnhancedLogin {...props} />
<Login {...props} />
</ThemeProvider>
);

Expand Down
1 change: 1 addition & 0 deletions examples/demo/src/orders/OrderList.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class TabbedDatagrid extends React.Component {

render() {
const { classes, filterValues, ...props } = this.props;
console.log({ filterValues });
return (
<Fragment>
<Tabs
Expand Down
1 change: 0 additions & 1 deletion examples/demo/src/reviews/AcceptButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ const AcceptButton = ({ record }) => {

AcceptButton.propTypes = {
record: PropTypes.object,
comment: PropTypes.string,
};

export default AcceptButton;
51 changes: 30 additions & 21 deletions examples/demo/src/reviews/RejectButton.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { formValueSelector } from 'redux-form';
import Button from '@material-ui/core/Button';
import ThumbDown from '@material-ui/icons/ThumbDown';
import { useTranslate } from 'react-admin';
import { reviewReject as reviewRejectAction } from './reviewActions';
import { useTranslate, useMutation } from 'react-admin';

const options = {
undoable: true,
onSuccess: {
notification: {
body: 'resources.reviews.notification.rejected_success',
level: 'info',
},
redirectTo: '/reviews',
},
onFailure: {
notification: {
body: 'resources.reviews.notification.rejected_error',
level: 'warning',
},
},
};
/**
* This custom button demonstrate using a custom action to update data
*/
const RejectButton = ({ record, reviewReject, comment }) => {
const RejectButton = ({ record }) => {
const translate = useTranslate();
const handleReject = () => {
reviewReject(record.id, { ...record, comment });
};

const [reject, { loading }] = useMutation(
{
type: 'UPDATE',
resource: 'reviews',
payload: { id: record.id, data: { status: 'rejected' } },
},
options
);

return record && record.status === 'pending' ? (
<Button
variant="outlined"
color="primary"
size="small"
onClick={handleReject}
onClick={reject}
disabled={loading}
>
<ThumbDown
color="primary"
Expand All @@ -35,18 +55,7 @@ const RejectButton = ({ record, reviewReject, comment }) => {
};

RejectButton.propTypes = {
comment: PropTypes.string,
record: PropTypes.object,
reviewReject: PropTypes.func,
};

const selector = formValueSelector('record-form');

export default connect(
state => ({
comment: selector(state, 'comment'),
}),
{
reviewReject: reviewRejectAction,
}
)(RejectButton);
export default RejectButton;
57 changes: 0 additions & 57 deletions examples/demo/src/reviews/reviewActions.js

This file was deleted.

Loading

0 comments on commit 306aef5

Please sign in to comment.