-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: handle unsaved changes in text & problem editors #1444
feat: handle unsaved changes in text & problem editors #1444
Conversation
Thanks for the pull request, @navinkarkera! What's next?Please work through the following steps to get your changes ready for engineering review: 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. 🔘 Let us know that your PR is ready for review:Who will review my changes?This repository is currently maintained by Where can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:
When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
// Not using useNavigate from react router to use browser navigation | ||
// which allows us to block back button if unsaved changes in editor are present. | ||
window.location.assign( | ||
createCorrectInternalRoute(`/course/${courseId}/editor/${type}/${id}`), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the part that replaces use of useNavigate
from react-router to normal browser navigation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be possible to implement with react-router if you want, though: https://reactrouter.com/en/main/hooks/use-blocker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bradenmacdonald I did try it out but it has some issues as mentioned in the description:
React router has support for blocking navigation when required but it seems to refresh the page regardless of user clicking cancel or stay which keeps the user in the page but the changes are lost. So I had to use browser navigation to take user to editors even from new MFE unit page which can then make use of beforeunload event to block navigation when required. Not using react router to navigate to editor results in slow navigation although it is the default way of going back to unit page on clicking cancel button.
@rpenido also tried it out with same results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sorry I missed that. Thanks for investigating it.
import { useEffect } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const PromptIfDirty = ({ dirty }) => { | ||
const usePromptIfDirty = (checkIfDirty : Function) => { | ||
useEffect(() => { | ||
// eslint-disable-next-line consistent-return | ||
const handleBeforeUnload = (event) => { | ||
if (dirty) { | ||
if (checkIfDirty()) { | ||
event.preventDefault(); | ||
// Included for legacy support, e.g. Chrome/Edge < 119 | ||
event.returnValue = true; // eslint-disable-line no-param-reassign | ||
} | ||
}; | ||
window.addEventListener('beforeunload', handleBeforeUnload); | ||
|
||
return () => { | ||
window.removeEventListener('beforeunload', handleBeforeUnload); | ||
}; | ||
}, [dirty]); | ||
}, [checkIfDirty]); | ||
|
||
return null; | ||
}; | ||
PromptIfDirty.propTypes = { | ||
dirty: PropTypes.bool.isRequired, | ||
}; | ||
export default PromptIfDirty; | ||
|
||
export default usePromptIfDirty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a duplicate PromptIfDirty file that I modified for this usecase.
98c8b20
to
87868c1
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1444 +/- ##
=======================================
Coverage 93.27% 93.27%
=======================================
Files 1052 1052
Lines 20465 20499 +34
Branches 4299 4379 +80
=======================================
+ Hits 19089 19121 +32
+ Misses 1316 1315 -1
- Partials 60 63 +3 ☔ View full report in Codecov by Sentry. |
The issue happens when we try to navigate back using the new unit outline, right? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Thank you for your work, @navinkarkera!
- I tested this using the instructions from the PR
- I read through the code
- I checked for accessibility issues
- Includes documentation
"react-router": "6.27.0", | ||
"react-router-dom": "6.27.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intended?
Not a problem, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was checking if useBlocker
is fixed in the latest version and then left it as is.
The text & problem xblock editors will display a confirmation box before cancelling only if user has changed something else it will directly go back.
87868c1
to
c620d5b
Compare
cf8423c
to
9ebfec4
Compare
9ebfec4
to
0c5079e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
Thank you for your work, @navinkarkera !
- I tested this using the instructions from the PR
- I read through the code
- I checked for accessibility issues
- Includes documentation
@navinkarkera Looks good. One thing:
This also doesn't work in library MFE, Is it within these limitations? |
@ChrisChV Yes, navigating back in library is using react-routers client side routing which does not trigger beforeunload event. Using react-routers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍 You need to comment all the limitations in AC testing
The text & problem xblock editors will display a confirmation box before cancelling only if user has changed something else it will directly go back. (cherry picked from commit df8a65d)
Description
Fixes: #1388 and #1389.
vokoscreenNG-2024-10-28_19-48-59.mp4
Supporting information
Private-ref
: FAL-3919Testing instructions
Limitations
beforeunload
which we use to detect navigation away from site does not trigger in mobile browsers in some cases. For more information please refer this doc about the event.beforeunload
event to block navigation when required. Not using react router to navigate to editor results in slow navigation although it is the default way of going back to unit page on clicking cancel button.