Skip to content

Commit

Permalink
Introduce formMiddleware to intercept location changes
Browse files Browse the repository at this point in the history
  • Loading branch information
djhi committed Sep 19, 2018
1 parent 7c3c027 commit cc16e80
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 84 deletions.
2 changes: 1 addition & 1 deletion cypress/integration/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('Create Page', () => {
);
});

it.only('should redirect to edit page after create success', () => {
it('should redirect to edit page after create success', () => {
const values = [
{
type: 'input',
Expand Down
7 changes: 7 additions & 0 deletions packages/ra-core/src/actions/formActions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const INITIALIZE_FORM = 'RA/INITIALIZE_FORM';
export const RESET_FORM = 'RA/RESET_FORM';
export const BEFORE_LOCATION_CHANGE = 'RA/BEFORE_LOCATION_CHANGE';

export const initializeForm = initialValues => ({
type: INITIALIZE_FORM,
Expand All @@ -9,3 +10,9 @@ export const initializeForm = initialValues => ({
export const resetForm = () => ({
type: RESET_FORM,
});

export const beforeLocationChange = ({ payload, meta }) => ({
type: BEFORE_LOCATION_CHANGE,
payload,
meta,
});
7 changes: 6 additions & 1 deletion packages/ra-core/src/createAdminStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { USER_LOGOUT } from './actions/authActions';
import createAppReducer from './reducer';
import { adminSaga } from './sideEffect';
import { defaultI18nProvider } from './i18n';
import formMiddleware from './form/formMiddleware';

export default ({
authProvider,
Expand Down Expand Up @@ -36,7 +37,11 @@ export default ({
resettableAppReducer,
initialState,
compose(
applyMiddleware(sagaMiddleware, routerMiddleware(history)),
applyMiddleware(
sagaMiddleware,
formMiddleware,
routerMiddleware(history)
),
typeof window !== 'undefined' && window.devToolsExtension
? window.devToolsExtension()
: f => f
Expand Down
42 changes: 42 additions & 0 deletions packages/ra-core/src/form/formMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { LOCATION_CHANGE } from 'react-router-redux';
import { destroy } from 'redux-form';
import isEqual from 'lodash/isEqual';

import { resetForm } from '../actions/formActions';
import { REDUX_FORM_NAME } from '../form/constants';

let previousLocation;

/**
* This middleware ensure that whenever a location change happen, we get the
* chance to properly reset the redux-form record form, preventing data to be
* kept between different resources.
*
* A middleware is needed instead of a saga because we to control the actions
* order: we need to ensure we reset the redux form BEFORE the location actually
* change. Otherwise, the new page which may contains a record redux-form might
* initialize before our reset and loose its data.
*/
const formMiddleware = () => next => action => {
if (
action.type !== LOCATION_CHANGE ||
(action.payload.state && action.payload.state.skipFormReset)
) {
return next(action);
}

// history allows one to redirect to the same location which can happen
// when using a special menu for a create page for instance. In this case,
// we don't want to reset the form.
// See https://github.com/marmelab/react-admin/issues/2291
if (isEqual(action.payload, previousLocation)) {
return next(action);
}

previousLocation = action.payload;
next(resetForm());
next(destroy(REDUX_FORM_NAME));
return next(action);
};

export default formMiddleware;
2 changes: 0 additions & 2 deletions packages/ra-core/src/sideEffect/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import redirection from './redirection';
import accumulate from './accumulate';
import refresh from './refresh';
import undo from './undo';
import recordForm from './recordForm';

/**
* @param {Object} dataProvider A Data Provider function
Expand All @@ -27,6 +26,5 @@ export default (dataProvider, authProvider, i18nProvider) =>
refresh(),
notification(),
callback(),
recordForm(),
]);
};
1 change: 0 additions & 1 deletion packages/ra-core/src/sideEffect/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ export accumulateSaga from './accumulate';
export refreshSaga from './refresh';
export i18nSaga from './i18n';
export undoSaga from './undo';
export recordForm from './recordForm';
28 changes: 0 additions & 28 deletions packages/ra-core/src/sideEffect/recordForm.js

This file was deleted.

51 changes: 0 additions & 51 deletions packages/ra-core/src/sideEffect/recordForm.spec.js

This file was deleted.

0 comments on commit cc16e80

Please sign in to comment.