feat: certificate regeneration flow with confirmation modals#197
Conversation
|
Thanks for the pull request, @wgu-jesse-stewart! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are 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. DetailsWhere 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. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #197 +/- ##
==========================================
+ Coverage 90.28% 90.76% +0.48%
==========================================
Files 141 147 +6
Lines 2408 2621 +213
Branches 521 559 +38
==========================================
+ Hits 2174 2379 +205
- Misses 226 236 +10
+ Partials 8 6 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
awais-ansari
left a comment
There was a problem hiding this comment.
Hardcoded strings in test cases if the defaultMessage changes, tests silently verify wrong content.
Thank you for the great feedback, @awais-ansari |
|
can you add some screenshots on how this new implementation/changes looks? |
It uses the Tabs component from Paragon, which I assume was the intended implementation. If @edschema flags it, I will change it. https://paragon-openedx.netlify.app/components/tabs/ |
As i mentioned on the prev message, you can use a button group to get the desired styles as figma (is also on paragon And for the unselected button use outline primary variant and for the selected one primary, that gets the same styles as the figma |
@diana-villalvazo-wgu - done. I was looking at the Grading and Special Exams implementations as examples for how to handle the tab styling issue in Certificates, and I wanted to flag some accessibility gaps I noticed with the ButtonGroup approach.
I know we're working around the Paragon styling issue, but if we're replacing with custom buttons, we should implement the full accessible tab pattern - otherwise we're trading a temporary styling problem for a permanent accessibility one. I went ahead and implemented the full pattern here if you want to use it as a reference for updating Grading and Special Exams. |
|
can you update the demo? |
updated |
|
🎉 This PR is included in version 1.0.0-alpha.40 🎉 The release is available on: Your semantic-release bot 📦🚀 |




Description
This PR replaces the previous one-click certificate regeneration flow with explicit confirmation modals that adapt to the currently-selected learner filter, and adds a dedicated generation flow for granted exceptions with the option to skip learners who already have a certificate.
Screen.Recording.2026-05-12.at.12.28.51.PM.mov
Behavior changes:
All LearnersorInvalidated, with a tooltip explaining what the operator needs to do (pick a specific learner group). Previously, clicking withAll Learnerswould fire a regeneration against'all'immediately.Granted Exceptionsfilter, the button label changes toGenerate Certificatesand opens a newGenerateCertificatesModalwith two radio options:student_set: 'allowlisted')student_set: 'allowlisted_not_generated')Received,Not Received,Audit - Passing,Audit - Not Passing,Error), the button opens a newRegenerateCertificatesModalwith a filter-specific title and a confirmation message that includes the affected learner count.Supporting changes:
regenerateCertificates(API) anduseRegenerateCertificates(hook) now acceptonlyWithoutCertificateso the granted-exceptions flow can pick the correctstudent_set. The hook'smutatesignature changed frommutate(filter)tomutate({ filter, onlyWithoutCertificate }).getErrorMessagewas hardened to handle responses whereresponse.datais either a string or an object, and to fall througherror,message, anddetailfields before using the fallback. This is what surfaces backend validation errors in the new modals' error path.getFilterLabelhelper and theregenerateCertificatesButtonWithFilterbutton-text variant from the toolbar.User roles impacted: Operator / Course Staff (instructor dashboard users).
Fixes #{issue}
Supporting information
(Link Discourse / issue here if applicable.)
Testing instructions
All Learners(default), confirm the regenerate button is disabled and that hovering it shows the tooltip directing you to pick a learner group.Invalidated. Confirm the button is still disabled and shows the corresponding tooltip.Received. ClickRegenerate Certificates:Cancel; modal should close with no API call.Regenerate; confirm a success toast appears and the API was called withstudent_set: 'verified'(or the appropriate set for that filter).Not Received,Audit - Passing,Audit - Not Passing, andErrorand confirm the modal copy adapts to each filter.Granted Exceptions. Confirm the button label changes toGenerate Certificates. Click it:GenerateCertificatesModalopens with two radio options,All Users on the Exception listselected by default.Generatewith the default selection; confirm the API is called withstudent_set: 'allowlisted'.All Users on the Exception list who do not yet have a certificate, clickGenerate; confirm the API is called withstudent_set: 'allowlisted_not_generated'.npm test -- src/certificates.Other information
student_set: 'allowlisted_not_generated'value is already supported by the existing certificate regeneration endpoint contract.spaninsideOverlayTriggerso the tooltip remains reachable while the button itself is non-interactive. Both modals use Paragon'sModalDialogandForm.RadioSetfor keyboard and screen-reader support.useRegenerateCertificateshook signature change is a minor breaking change for any in-tree caller, butCertificatesPageis currently the only consumer.Best Practices Checklist
.ts,.tsx).propTypes,defaultProps, andinjectIntlpatterns are not used in any new or modified code.src/testUtils.tsx(specificallyinitializeMocks)messages.tsfiles have adescriptionfor translators to use.../.