feat: make widget registry to backward compatible#1899
feat: make widget registry to backward compatible#1899arbrandes merged 3 commits intoopenedx:masterfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1899 +/- ##
==========================================
+ Coverage 91.28% 91.30% +0.02%
==========================================
Files 343 343
Lines 5770 5775 +5
Branches 1388 1390 +2
==========================================
+ Hits 5267 5273 +6
+ Misses 484 483 -1
Partials 19 19 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
arbrandes
left a comment
There was a problem hiding this comment.
For a plugin author working against the documented contact points — targeting a slot via env.config.jsx, consuming pluginProps, comparing against WIDGETS.NOTIFICATIONS — the BC layer covers all three and nothing has to change on the plugin side: old slot ids resolve via idAliases, old prop names are emitted alongside the new ones, and the WIDGETS.NOTIFICATIONS constant now resolves to 'UPGRADE'.
The things this PR does not shim (literal 'NOTIFICATIONS' string comparisons, reads of old notification* properties on SidebarContext, and direct localStorage reads) are past the documented API, and for the SidebarContext case in particular there is no non-redundant use case: the two upgrade-flow values an external plugin could plausibly want are already delivered to it at the slot boundary via pluginProps, and the remaining three are the upgrade widget's own "has the learner seen this yet" bookkeeping, which no other widget should be touching. So: not a BC concern.
That said, we need to think about when this is eventually deprecated, which brings me to the first issue:
1. Removability of the deprecated surface
Removal eventually has to go through OEP-21, which requires a DEPR issue listing what's being removed, the replacement, and the deprecation window. The ADR (once item #3 folds the migration guide into it) is the natural place to stage that inventory so a future DEPR filer can lift it directly rather than reconstructing it from git archaeology. For example:
Deprecated identifiers
Deprecated Replacement Deprecated since Planned removal Slot id org.openedx.frontend.learning.notification_tray.v1(andnotification_tray_slot)org.openedx.frontend.learning.upgrade_panel.v1release including PR #1899 TBD — one full deprecation cycle after deprecation ships Slot id org.openedx.frontend.learning.notifications_discussions_sidebar.v1(andnotifications_discussions_sidebar_slot)org.openedx.frontend.learning.right_sidebar.v1/right_sidebar_slotrelease including PR #1899 TBD Slot id org.openedx.frontend.learning.notifications_discussions_sidebar_trigger.v1(andnotifications_discussions_sidebar_trigger_slot)org.openedx.frontend.learning.right_sidebar_trigger.v1/right_sidebar_trigger_slotrelease including PR #1899 TBD pluginPropskeysnotificationCurrentState/setNotificationCurrentStateon the upgrade panel slotupgradeCurrentState/setUpgradeCurrentStaterelease including PR #1899 TBD WIDGETS.NOTIFICATIONS(value now'UPGRADE')IDexported from@src/widgets/upgrade/src(widget owns its id)release including PR #1899 TBD Default-behavior change
upgradeWidgetConfigis currently included inDEFAULT_WIDGETS. A future release will remove it, after which operators who want the Upgrade panel visible must add it toSIDEBAR_WIDGETSinenv.config.jsx. Target release: TBD.
2. Annotate every alias site with @deprecated
Only WIDGETS.NOTIFICATIONS carries a @deprecated JSDoc today; the four other shim sites do not:
RightSidebarSlot/index.tsx:10— old ids insideidAliasesRightSidebarTriggerSlot/index.tsx:10— sameUpgradePanel.jsx:91— sameUpgradePanel.jsx:97-98—notificationCurrentState/setNotificationCurrentStatekeys inpluginProps
A one-line JSDoc or inline comment per site is enough; grep -R '@deprecated' should then enumerate all five without needing the ADR.
3. docs/upgrade-widget-migration.md should be folded into ADR 0010
Fold the migration guide into ADR 0010 as a "Migration" / "Backward compatibility" section, and retarget the README link there. Keeping them separate invites drift between the decision and its compat story.
4. Errors in the migration content (carry forward when folding into the ADR)
Two bugs in docs/upgrade-widget-migration.md that need fixing wherever the content ends up living:
-
L87 — heading
`WIDGETS.NOTIFICATIONS` → `WIDGETS.NOTIFICATIONS` (deprecated alias)has the same identifier on both sides of the arrow. Either write out the value change ('NOTIFICATIONS'→'UPGRADE') or drop the arrow. -
L136-L143 — localStorage key table lists one rename but the pre-ADR code (NotificationTrigger.jsx at 0664dc38^) wrote three. The two missing rows:
Old key New key upgradeNotificationLastSeen.${courseId}upgradeWidgetLastSeen.${courseId}upgradeNotificationCurrentState.${courseId}upgradeWidgetState.${courseId}
5. .gitignore: keep env.config.jsx ignored
Restore the env.config.jsx line; it must stay ignored.
6. src/plugin-slots/README.md: misleading wording, missing entry, broken links
Three problems on src/plugin-slots/README.md#L16:
- "removed" is factually wrong. The entry reads
~~notification_tray.v1~~ _(removed; aliased to the upgrade panel...)_. It isn't removed — it still resolves viaidAliases. A plugin author reading this would reasonably conclude their plugin has stopped working. Use "deprecated / renamed" or "aliased" instead of "removed". - The replacement slot isn't listed.
org.openedx.frontend.learning.upgrade_panel.v1is a real, plugin-targetable slot introduced by this PR, but it doesn't appear in the README's slot list at all — only in the strikethrough breadcrumb for the old id. Since the slot lives undersrc/widgets/upgrade/rather than undersrc/plugin-slots/<Name>Slot/, the list entry will have to point somewhere other than a./UpgradePanelSlot/directory (e.g.,src/widgets/upgrade/README.mdor the ADR), but it needs to be findable from here. - Both doc links are 404s. From
src/plugin-slots/README.md,../docs/resolves tosrc/docs/, which does not exist. Correct prefix is../../docs/.
7. Commit hygiene
The commit message test: updete breaking test cases has a typo ("updete"). Non-blocking, but easy to fix via a rebase if you're pushing another round.
81031c1 to
9169360
Compare
arbrandes
left a comment
There was a problem hiding this comment.
Thank you for doing this so quickly!
|
@pdpinch, do you mind checking whether this unbreaks your build? |
|
Thanks @arbrandes -- yes, this did unbreak our build. And our pluginslots are working again. |
This PR introduces backward compatibility following the rename of the Notifications sidebar widget to Upgrade (ADR 0010). It ensures existing operator configurations, plugin slots, context consumers, and JS constant references continue to work without changes while the platform migrates to the new naming.
Key changes
Widget registry deduplication
getEnabledWidgets() now prevents external SIDEBAR_WIDGETS config from accidentally overriding or duplicating platform-default widgets. External entries with the same ID as a default are ignored (platform default wins); setting enabled: false on a matching ID disables the default entirely.
upgradeWidgetConfig added to DEFAULT_WIDGETS
The Upgrade widget is now a first-class default alongside Discussions, so it appears without any env.config.jsx configuration.
WIDGETS.NOTIFICATIONS deprecated alias
constants.ts adds WIDGETS.NOTIFICATIONS = 'UPGRADE' so legacy checks like currentSidebar === WIDGETS.NOTIFICATIONS resolve correctly against the renamed widget ID.
Plugin slot ID aliases
RightSidebarSlot and RightSidebarTriggerSlot add the old notifications_discussions_sidebar* full IDs to their idAliases, preserving existing plugin configs.
Prop aliases in UpgradePanel
The upgrade panel slot exposes notificationCurrentState / setNotificationCurrentState alongside the new prop names so plugins using the old names still receive values.
Migration guide
docs/upgrade-widget-migration.md documents every renamed identifier, the deprecation timeline, and the copy-paste env.config.jsx examples for operators.
Test Plan
env.config.js