Skip to content
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

Merged
merged 6 commits into from
Nov 4, 2024

Conversation

navinkarkera
Copy link
Contributor

Description

Fixes: #1388 and #1389.

vokoscreenNG-2024-10-28_19-48-59.mp4
  • Which edX user roles will this change impact?: "Course Author".

Supporting information

Testing instructions

  • Edit any text or problem block from new mfe unit page as well as legacy unit page.
  • Try going back or cancelling without any change, it should take you back without requiring any confirmation.
  • Edit again and make some changes, now clicking on cancel button or close button or refreshing page or using browser back button should be blocked by a popup.
  • Test cancelling and saving changes from the editor.

Limitations

  • The browsers ability to block users action is not perfect, for example, the event 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.
  • This PR does not add the functionality of detecting unsaved chanegs in video editor yet as it seems to be bit more involved. I can look into it if it is required.
  • 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.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Oct 28, 2024
@openedx-webhooks
Copy link

openedx-webhooks commented Oct 28, 2024

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 approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.

🔘 Provide context

To 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:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads

🔘 Get a green build

If 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 @openedx/2u-tnl. Tag them in a comment and let them know that your changes are ready for review.

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:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

Comment on lines +61 to +65
// 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}`),
);
Copy link
Contributor Author

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.

Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Comment on lines 1 to 23
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;
Copy link
Contributor Author

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.

@navinkarkera navinkarkera force-pushed the navin/fix/editor-confirmation branch from 98c8b20 to 87868c1 Compare October 29, 2024 10:32
Copy link

codecov bot commented Oct 29, 2024

Codecov Report

Attention: Patch coverage is 94.73684% with 2 lines in your changes missing coverage. Please review.

Project coverage is 93.27%. Comparing base (549dbaa) to head (0c5079e).
Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...ProblemEditor/components/EditProblemView/index.jsx 33.33% 2 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

@rpenido
Copy link
Contributor

rpenido commented Oct 30, 2024

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.

The issue happens when we try to navigate back using the new unit outline, right?
I was able to reproduce the issue and didn't find a better way to solve it either

Copy link
Contributor

@rpenido rpenido left a 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

Comment on lines +96 to +97
"react-router": "6.27.0",
"react-router-dom": "6.27.0",
Copy link
Contributor

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.

Copy link
Contributor Author

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.

src/generic/promptIfDirty/usePromptIfDirty.ts Outdated Show resolved Hide resolved
src/editors/containers/EditorContainer/index.tsx Outdated Show resolved Hide resolved
The text & problem xblock editors will display a confirmation box before
cancelling only if user has changed something else it will directly go
back.
@navinkarkera navinkarkera force-pushed the navin/fix/editor-confirmation branch from 87868c1 to c620d5b Compare November 1, 2024 07:33
@navinkarkera navinkarkera marked this pull request as ready for review November 1, 2024 07:45
@navinkarkera navinkarkera requested a review from a team as a code owner November 1, 2024 07:45
@navinkarkera navinkarkera force-pushed the navin/fix/editor-confirmation branch from cf8423c to 9ebfec4 Compare November 1, 2024 10:43
@navinkarkera navinkarkera force-pushed the navin/fix/editor-confirmation branch from 9ebfec4 to 0c5079e Compare November 1, 2024 11:01
@navinkarkera navinkarkera requested a review from rpenido November 1, 2024 14:26
Copy link
Contributor

@rpenido rpenido left a 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

@ChrisChV
Copy link
Contributor

ChrisChV commented Nov 1, 2024

@navinkarkera Looks good. One thing:

The browsers ability to block users action is not perfect, for example, the event 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.

This also doesn't work in library MFE, Is it within these limitations?

https://www.loom.com/share/94f213bef6ec429ebcca7baa89de3e3a

@navinkarkera
Copy link
Contributor Author

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 useBlocker does not preserve data changes and only blocks user from going back.

Copy link
Contributor

@ChrisChV ChrisChV left a 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

@ChrisChV ChrisChV merged commit df8a65d into openedx:master Nov 4, 2024
7 checks passed
@ChrisChV ChrisChV deleted the navin/fix/editor-confirmation branch November 4, 2024 17:41
navinkarkera added a commit to open-craft/frontend-app-authoring that referenced this pull request Nov 5, 2024
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)
ChrisChV pushed a commit that referenced this pull request Nov 6, 2024
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-source-contribution PR author is not from Axim or 2U
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Bug: Closing editor without changes still prompts warning
5 participants