Skip to content

feat: add CORE_PLUGINS hook and bundle the notifications tray#292

Merged
arbrandes merged 1 commit intooverhangio:mainfrom
arbrandes:core-plugins
Apr 21, 2026
Merged

feat: add CORE_PLUGINS hook and bundle the notifications tray#292
arbrandes merged 1 commit intooverhangio:mainfrom
arbrandes:core-plugins

Conversation

@arbrandes
Copy link
Copy Markdown
Collaborator

@arbrandes arbrandes commented Apr 20, 2026

Description

Ports tutor-contrib-platform-notifications into tutor-mfe so that enabling the plugin gives operators the notifications tray out of the box, with no extra plugin to install.

To support this cleanly, it introduces a CORE_PLUGINS filter in tutormfe.hooks: a registry of bundled frontend plugin packages that ship enabled by default. Operators can disable any core plugin by popping its entry from the filter, symmetrically to how MFE_APPS works today. Notifications is the first (and currently only) core plugin.

Testing

With this branch installed and tutor-mfe enabled, run tutor config save and inspect the rendered environment. In $(tutor config printroot)/env/plugins/mfe/build/mfe/Dockerfile each MFE stage should contain a RUN ... npm install ... @edx/frontend-plugin-notifications@^2.0.3 line just before the mfe-dockerfile-post-npm-install patch call. In $(tutor config printroot)/env/plugins/mfe/build/mfe/env.config.jsx there should be a const { NotificationsTray } = await import('@edx/frontend-plugin-notifications'); line inside the try {} block. In $(tutor config printroot)/env/apps/openedx/settings/lms/production.py, both MFE_CONFIG["SHOW_EMAIL_CHANNEL"] and MFE_CONFIG["SHOW_PUSH_CHANNEL"] should be set, and NOTIFICATIONS_DEFAULT_FROM_EMAIL should be defined via ENV_TOKENS.

To verify the disable path, create a file at $(tutor plugins printroot)/disable_notifications.py containing:

from tutormfe.hooks import CORE_PLUGINS


@CORE_PLUGINS.add()
def _disable_notifications(plugins):
    plugins.pop("notifications", None)
    return plugins

Then run tutor plugins enable disable_notifications && tutor config save. The rendered Dockerfile, env.config.jsx, LMS production settings, and lms-env should no longer reference frontend-plugin-notifications, NotificationsTray, SHOW_EMAIL_CHANNEL, or NOTIFICATIONS_DEFAULT_FROM_EMAIL. Running tutor plugins disable disable_notifications && tutor config save brings them all back.

LLM usage notice

Built with assistance from Claude.

Introduces a CORE_PLUGINS filter for bundled frontend plugin packages,
enabled by default and disableable symmetrically to MFE_APPS. Ports
tutor-contrib-platform-notifications into tutor-mfe as the first core
plugin.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment on lines +28 to +30
{%- if is_core_plugin_enabled("notifications") %}
const { NotificationsTray } = await import('@edx/frontend-plugin-notifications');
{%- endif %}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add this to mfe-env-config-runtime-definitions patch again like it was in tutor-contrib-platform-notifications instead of filling in env.config.jsx?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, but not cleanly: the patches tutor-mfe defines (such as mfe-env-config-runtime-definitions) are meant for other plugins to consume. That's what the templates are for: we put the stuff we own in there, and patches are for external use.

Comment on lines +34 to +52
{%- if is_core_plugin_enabled("notifications") %}
{%- for slot_name in [
"org.openedx.frontend.layout.header_desktop_secondary_menu.v1",
"org.openedx.frontend.layout.header_learning_help.v1",
"org.openedx.frontend.layout.studio_header_search_button_slot.v1",
] %}
addPlugins(config, '{{ slot_name }}', [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'notification-drawer-widget',
priority: 10,
type: DIRECT_PLUGIN,
RenderWidget: NotificationsTray,
},
},
]);
{%- endfor %}
{%- endif %}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also move this to plugin.py file under notifications section? As I was thinking we might end up adding plugin slots directly to env.config.jsx in future? Although its also fine if we don't do it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually tried, but it doesn't work well: we're consuming the hook (PLUGIN_SLOTS) we're defining ourselves, so there are timing/race conditions that result in the core plugin not being picked up here.

I know it looks funny, but defining this directly in the template is the right place.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are timing/race conditions that result in the core plugin not being picked up here.

I know it looks funny, but defining this directly in the template is the right place.

makes sense,

@Faraz32123
Copy link
Copy Markdown
Contributor

@arbrandes Do we need this PR? as most of these changes also exists in frontend-base PR e.g. NOTIFICATIONS_DEFAULT_FROM_EMAIL exists in both, hooks(CORE_PLUGINS & CORE_PLUGIN_ATTRS_TYPE also seems redundant & exists with different names in frontend-base PR) etc.

@arbrandes
Copy link
Copy Markdown
Collaborator Author

@Faraz32123, we do need this PR. It looks similar to frontend-base, but frontend-plugin-notifications and frontend-app-notifications are two separate things: the first is for legacy MFEs (which this PR takes care of), the second for frontend-base apps.

Once this PR merges, I'll have to rebase the frontend-base one so the two conditions are checked (is_core_plugin_enabled("notifications") and is_frontend_app_enabled("notifications"), for the backend stuff.

(Yes, this looks pretty redundant, but until all MFEs are converted to apps, we're going to have to live with some duplication.)

Copy link
Copy Markdown
Contributor

@Faraz32123 Faraz32123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@arbrandes arbrandes merged commit 84368d9 into overhangio:main Apr 21, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in Tutor project management Apr 21, 2026
@arbrandes arbrandes deleted the core-plugins branch April 21, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

3 participants