feat: Version 2 Created the plugin slot for UpgradeToCompleteAlert#47
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new plugin slot intended to support upgrade-related messaging in the Course Home “Dates” banner area, and wires the Dates tab to render that slot.
Changes:
- Added
BannerDatesUpgradeSlotwith slot IDorg.openedx.frontend.learning.banner_dates_upgrade.v1(+ alias) and documentation. - Updated
DatesTabto render the new plugin slot in place ofUpgradeToCompleteAlert. - Updated Dates tab tests to reflect the new default rendering behavior (and removed the prior analytics test for the old alert).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/plugin-slots/README.md |
Registers the new slot in the plugin slots index. |
src/plugin-slots/BannerDatesUpgradeSlot/index.tsx |
Introduces the new PluginSlot wrapper component for the dates upgrade banner. |
src/plugin-slots/BannerDatesUpgradeSlot/README.md |
Documents the slot’s ID, aliases, and intended usage. |
src/course-home/dates-tab/DatesTab.jsx |
Replaces UpgradeToCompleteAlert with BannerDatesUpgradeSlot. |
src/course-home/dates-tab/DatesTab.test.jsx |
Updates expectations to no longer render UpgradeToCompleteAlert by default and removes the related analytics click test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <BannerDatesUpgradeSlot courseId={courseId} /> | ||
| <UpgradeToShiftDatesAlert logUpgradeLinkClick={logUpgradeLinkClick} model="dates" /> |
There was a problem hiding this comment.
Swapping UpgradeToCompleteAlert for BannerDatesUpgradeSlot changes the default UX: the upgrade-to-complete banner (and its click analytics) will no longer appear unless a plugin supplies it. If the intent is only to introduce a plugin extension point, consider keeping the existing alert as the slot’s default children (or otherwise preserving the current behavior) and pass through any needed props (e.g., the existing logUpgradeLinkClick).
| <BannerDatesUpgradeSlot courseId={courseId} /> | |
| <UpgradeToShiftDatesAlert logUpgradeLinkClick={logUpgradeLinkClick} model="dates" /> | |
| <BannerDatesUpgradeSlot courseId={courseId}> | |
| <UpgradeToShiftDatesAlert logUpgradeLinkClick={logUpgradeLinkClick} model="dates" /> | |
| </BannerDatesUpgradeSlot> |
There was a problem hiding this comment.
Agree with co-pilot. Let's keep the Alert as the default content for now until we actually remove the component from frontend-app-learning. I know the ticket said to remove it but I think we should reconsider that. We can remove the default via env.config.js instead.
| export const BannerDatesUpgradeSlot = ({ | ||
| courseId, | ||
| }: BannerDatesUpgradeSlotProps) => ( | ||
| <PluginSlot | ||
| id="org.openedx.frontend.learning.banner_dates_upgrade.v1" | ||
| idAliases={['dates_upgrade_banner_slot']} | ||
| pluginProps={{ | ||
| courseId, | ||
| }} | ||
| /> |
There was a problem hiding this comment.
This slot currently renders no default content and only passes courseId. If it is meant to be the extension point for the existing Upgrade-to-Complete banner, consider rendering the current default alert as PluginSlot children (so behavior stays the same when no plugins are installed) and include any additional pluginProps/callbacks needed to avoid duplicating logic (e.g., the upgrade click analytics handler / upgrade URL).
| @@ -182,8 +182,9 @@ describe('DatesTab', () => { | |||
| axiosMock.onGet(datesUrl).reply(200, datesTabData); | |||
| render(component); | |||
|
|
|||
| await waitFor(() => expect(screen.getByText('You are auditing this course, which means that you are unable to participate in graded assignments. To complete graded assignments as part of this course, you can upgrade today.')).toBeInTheDocument()); | |||
| expect(screen.getByRole('button', { name: 'Upgrade now' })).toBeInTheDocument(); | |||
| await waitFor(() => expect(screen.getByText('We’ve built a suggested schedule to help you stay on track. But don’t worry—it’s flexible so you can learn at your own pace.')).toBeInTheDocument()); | |||
| expect(screen.queryByText('You are auditing this course, which means that you are unable to participate in graded assignments. To complete graded assignments as part of this course, you can upgrade today.')).not.toBeInTheDocument(); | |||
| expect(screen.queryByRole('button', { name: 'Upgrade now' })).not.toBeInTheDocument(); | |||
There was a problem hiding this comment.
The updated test now asserts that UpgradeToCompleteAlert does not render by default, which reflects a behavioral change (the alert previously rendered for eligible audit learners). If the PR’s scope is just “create a plugin slot”, the test should continue to expect the default alert (potentially rendered as the slot’s fallback) and keep equivalent coverage for the upgrade-button analytics event.
| ### Props: | ||
| * `courseId` - The course ID (string) | ||
|
|
||
| ### Example Usage | ||
| Plugins can inject components here to show upgrade-related alerts and notifications in the dates banner section. |
There was a problem hiding this comment.
This README describes the slot as enabling upgrade notifications, but it doesn’t clarify whether anything renders by default (without plugins) or how it relates to the existing UpgradeToCompleteAlert behavior. Please document whether the slot includes a default fallback and, if not, note that plugins must provide the entire alert/analytics behavior.
| ### Props: | |
| * `courseId` - The course ID (string) | |
| ### Example Usage | |
| Plugins can inject components here to show upgrade-related alerts and notifications in the dates banner section. | |
| ### Default behavior | |
| By default, this slot does not render any UI or trigger any analytics on its own; if no plugins target this slot, nothing additional will appear in the dates banner section. | |
| This slot does not automatically reuse or wrap existing upgrade experiences such as `UpgradeToCompleteAlert`—plugins are responsible for providing the full alert component, user interactions, and any associated tracking or reporting behavior. | |
| ### Props: | |
| * `courseId` - The course ID (string) | |
| ### Example Usage | |
| Plugins can inject components here to show upgrade-related alerts and notifications in the dates banner section, including any desired visual treatment, call-to-action buttons, and analytics/tracking events. |
There was a problem hiding this comment.
We should add screenshots to the README. See this file as an example: https://github.com/edx/frontend-app-learner-dashboard/blob/release-ulmo/src/plugin-slots/WidgetSidebarSlot/README.md
77d35e0 to
d00008d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/course-home/dates-tab/DatesTab.test.jsx:281
- The analytics test for the upgrade button in
UpgradeToCompleteAlertwas removed. SinceBannerDatesUpgradeSlotstill rendersUpgradeToCompleteAlertby default (andlogUpgradeLinkClickstill sends the track event), losing this assertion reduces coverage and could hide regressions in upgrade-click tracking on the Dates tab. Consider restoring a test that clicks "Upgrade now" and verifiessendTrackEventpayloads.
it('sends analytics event onClick of upgrade button in UpgradeToShiftDatesAlert', async () => {
sendTrackEvent.mockClear();
datesTabData.datesBannerInfo = {
contentTypeGatingEnabled: true,
missedDeadlines: true,
missedGatedContent: true,
verifiedUpgradeLink: 'http://localhost:18130/basket/add/?sku=8CF08E5',
};
axiosMock.onGet(datesUrl).reply(200, datesTabData);
render(component);
const upgradeButton = await waitFor(() => screen.getByRole('button', { name: 'Upgrade to shift due dates' }));
fireEvent.click(upgradeButton);
expect(sendTrackEvent).toHaveBeenCalledTimes(1);
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.ecommerce.upsell_links_clicked', {
org_key: 'edX',
courserun_key: courseId,
linkCategory: 'personalized_learner_schedules',
linkName: 'dates_upgrade',
linkType: 'button',
pageName: 'dates_tab',
});
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Banner Dates Upgrade Slot | ||
|
|
||
| ### Slot ID: `org.openedx.frontend.learning.banner_dates_upgrade.v1` | ||
|
|
There was a problem hiding this comment.
PR title mentions "Version 2", but this slot is introduced as org.openedx.frontend.learning.banner_dates_upgrade.v1 here (and in the code). If the intent is a v2 slot, the ID/docs should be updated accordingly; otherwise consider adjusting the PR title to avoid confusion for plugin integrators.
df7903d to
d3de574
Compare
No description provided.