Fix end-user agreement checkbox reset and navigation hang #5099
+20
−5
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
References
Fixes #5085
Description
This PR fixes two critical bugs in the end-user agreement flow:
Part 1 - Checkbox reset preventing form submission: When new users accessed the end-user agreement page, checking the accept checkbox would sometimes get reset automatically, making the Save button appear non-functional until page reload.
Part 2 - Navigation hanging after successful submission: After successfully accepting the agreement (PATCH request succeeded), the page would stall indefinitely without redirecting to the intended destination.
Root Causes
Both issues were caused by improper handling of ngrx store observables that never complete:
Checkbox reset: The initAccepted() subscription to hasCurrentUserOrCookieAcceptedAgreement() lacked take(1), allowing store re-emissions to override user interactions by resetting this.accepted to false.
Navigation hang: After the PATCH operation, the endUserAgreementCurrentUserGuard would check user acceptance status using store selectors that could return stale data or never complete, causing the Angular router to hang.
Solution
Applied established DSpace patterns for handling store-backed observables:
Added take(1) to all store selector subscriptions to ensure they complete after first emission
Implemented cookie fallback after successful PATCH operations for synchronous state verification
Updated the guard to use hasCurrentUserOrCookieAcceptedAgreement() which checks the cookie first before querying potentially stale store data
Instructions for Reviewers
This PR modifies the end-user agreement component, service, and guard to properly handle RxJS observables from the ngrx store.
List of changes in this PR:
end-user-agreement.component.ts: Added take(1) to initAccepted() subscription to prevent store re-emissions from overriding user checkbox interactions
end-user-agreement.service.ts:
end-user-agreement-current-user.guard.ts: Updated to use hasCurrentUserOrCookieAcceptedAgreement() with take(1), leveraging cookie-based checks to prevent guard hangs
How to test / review:
Setup:
Test Part 1 - Checkbox functionality:
Test Part 2 - Navigation after submission:
Verify no regressions:
Verify the fix persists:
Checklist