Skip to content

Commit

Permalink
Merge pull request #2784 from marmelab/beforeunload
Browse files Browse the repository at this point in the history
[RFR] Add an alert preventing data loss when a user closes the app while in optimistic mode
  • Loading branch information
Gildas Garcia authored Jan 18, 2019
2 parents 735fc80 + 10c0b31 commit 43d5508
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/ra-core/src/sideEffect/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import redirection from './redirection';
import accumulate from './accumulate';
import refresh from './refresh';
import undo from './undo';
import unload from './unload';

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

export {
adminSaga,
Expand All @@ -22,4 +23,5 @@ export {
refreshSaga,
i18nSaga,
undoSaga,
unloadSaga,
};
44 changes: 44 additions & 0 deletions packages/ra-core/src/sideEffect/unload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { takeEvery } from 'redux-saga/effects';

import {
START_OPTIMISTIC_MODE,
STOP_OPTIMISTIC_MODE,
} from '../actions/undoActions';

/**
* Unload saga
*
* When a user closes the browser window while an optimistic update/delete
* hasn't been sent to the dataProvider yet, warn them that their edits
* may be lost.
*
* To achieve that, this saga registers a window event handler on the
* 'beforeunload' event when entering the optimistic mode, and removes
* the event when quitting the optimistic mode.
*/
export default function* watchUnload() {
yield takeEvery(START_OPTIMISTIC_MODE, handleStartOptimistic);
yield takeEvery(STOP_OPTIMISTIC_MODE, handleStopOptimisticMode);
}

const eventListener = event => {
event.preventDefault(); // standard
event.returnValue = ''; // Chrome
return 'Your latest modifications are not yet sent to the server. Are you sure?'; // Old IE
};

export function* handleStartOptimistic() {
// SSR escape hatch
if (!window) {
return;
}
window.addEventListener('beforeunload', eventListener);
}

export function* handleStopOptimisticMode() {
// SSR escape hatch
if (!window) {
return;
}
window.removeEventListener('beforeunload', eventListener);
}

0 comments on commit 43d5508

Please sign in to comment.