From 87faedc677f5184015f63a6362afb57ad129fc39 Mon Sep 17 00:00:00 2001 From: Farhaan Bukhsh Date: Tue, 30 Sep 2025 18:09:03 +0530 Subject: [PATCH 1/5] feat: Adds notification tray slot Signed-off-by: Farhaan Bukhsh --- src/desktop-header/DesktopHeader.jsx | 4 ++ src/learning-header/LearningHeader.jsx | 16 +++-- src/mobile-header/MobileHeader.jsx | 4 ++ src/plugin-slots/NotificationSlot/README.md | 75 +++++++++++++++++++++ src/plugin-slots/NotificationSlot/index.jsx | 11 +++ src/studio-header/HeaderBody.tsx | 4 ++ 6 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 src/plugin-slots/NotificationSlot/README.md create mode 100644 src/plugin-slots/NotificationSlot/index.jsx diff --git a/src/desktop-header/DesktopHeader.jsx b/src/desktop-header/DesktopHeader.jsx index 5828ae6da..2c318ac8b 100644 --- a/src/desktop-header/DesktopHeader.jsx +++ b/src/desktop-header/DesktopHeader.jsx @@ -18,6 +18,7 @@ import { desktopUserMenuDataShape } from './DesktopHeaderUserMenu'; // i18n import messages from '../Header.messages'; +import NotificationTraySlot from '../plugin-slots/NotificationSlot'; // Assets @@ -39,6 +40,8 @@ const DesktopHeader = ({ const renderSecondaryMenu = () => ; + const renderNotificationTray = () => ; + const renderUserMenu = () => ( + {renderNotificationTray()} {renderSecondaryMenu()} {renderUserMenu()} diff --git a/src/learning-header/LearningHeader.jsx b/src/learning-header/LearningHeader.jsx index 349690bb2..87a9e936d 100644 --- a/src/learning-header/LearningHeader.jsx +++ b/src/learning-header/LearningHeader.jsx @@ -11,6 +11,7 @@ import CourseInfoSlot from '../plugin-slots/CourseInfoSlot'; import { courseInfoDataShape } from './LearningHeaderCourseInfo'; import messages from './messages'; import LearningHelpSlot from '../plugin-slots/LearningHelpSlot'; +import NotificationTraySlot from '../plugin-slots/NotificationSlot'; const LearningHeader = ({ courseOrg, @@ -38,15 +39,16 @@ const LearningHeader = ({ {showUserDropdown && authenticatedUser && ( - <> - - - + <> + + + + )} {showUserDropdown && !authenticatedUser && ( - + )} diff --git a/src/mobile-header/MobileHeader.jsx b/src/mobile-header/MobileHeader.jsx index 6d48efd07..1a9bb8d58 100644 --- a/src/mobile-header/MobileHeader.jsx +++ b/src/mobile-header/MobileHeader.jsx @@ -13,6 +13,7 @@ import MobileMainMenuSlot from '../plugin-slots/MobileMainMenuSlot'; import { mobileHeaderMainMenuDataShape } from './MobileHeaderMainMenu'; import MobileUserMenuSlot from '../plugin-slots/MobileUserMenuSlot'; import { mobileHeaderUserMenuDataShape } from './MobileHeaderUserMenu'; +import NotificationTraySlot from '../plugin-slots/NotificationSlot'; // i18n import messages from '../Header.messages'; @@ -43,6 +44,8 @@ const MobileHeader = ({ const renderUserMenuToggle = () => ; + const renderNotificationTray = () => ; + const logoProps = { src: logo, alt: logoAltText, href: logoDestination }; const stickyClassName = stickyOnMobile ? 'sticky-top' : ''; const logoClasses = getConfig().AUTHN_MINIMAL_HEADER ? 'justify-content-left pl-3' : 'justify-content-center'; @@ -87,6 +90,7 @@ const MobileHeader = ({ aria-label={intl.formatMessage(messages['header.label.account.menu'])} title={intl.formatMessage(messages['header.label.account.menu'])} > + {renderNotificationTray()} {renderUserMenuToggle()} diff --git a/src/plugin-slots/NotificationSlot/README.md b/src/plugin-slots/NotificationSlot/README.md new file mode 100644 index 000000000..8e2963692 --- /dev/null +++ b/src/plugin-slots/NotificationSlot/README.md @@ -0,0 +1,75 @@ +# Notification Tray Slot + +### Slot ID: `org.openedx.frontend.layout.notification_tray.v1` + +## Description + +This slot is used to replace, modify, or hide the contents of the notification tray in the Open edX header. It allows developers to easily extend or customize the notification tray using the [Open edX Frontend Plugin Framework](https://github.com/openedx/frontend-plugin-framework). + +The slot is kept empty so that it can only be enabled when it is required else +nothing is displayed. + +## Examples + +### Insert Notification Tray with Custom Component + +The following `env.config.jsx` will replace the notification tray's contents entirely (in this case with a custom emoji icon): + +```jsx +import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework'; + +const config = { + pluginSlots: { + 'org.openedx.frontend.layout.notification_tray.v1': { + keepDefault: false, + plugins: [ + { + op: PLUGIN_OPERATIONS.Insert, + widget: { + id: 'custom_notification_tray', + type: DIRECT_PLUGIN, + RenderWidget: () => ( + 🔔 Custom Notification + ), + }, + }, + ], + }, + }, +}; + +export default config; +``` + +## Component Usage + +Import the `NotificationTraySlot` component and use it in your layout or header component where you want the notifications tray to appear: + +```jsx +import NotificationTraySlot from './src/plugin-slots/NotificationSlot'; + +function Header() { + return ( +
+ {/* Other header content */} + +
+ ); +} +``` + +## API + +- **Slot ID:** `org.openedx.frontend.layout.notification_tray.v1` +- **Alias:** `notification_tray_plugin` +- **Component:** Uses the [PluginSlot](https://github.com/openedx/frontend-plugin-framework#pluginslot) from the Open edX Frontend Plugin Framework for plugin injection. +- **Props:** This component does not accept any props directly. + +## License + +This component is part of the [open-craft/frontend-component-header](https://github.com/open-craft/frontend-component-header) repository and is made available under its license. + +## Contributing + +If you would like to contribute improvements or additional plugin slots, please open a pull request or issue in the [repository](https://github.com/open-craft/frontend-component-header). + diff --git a/src/plugin-slots/NotificationSlot/index.jsx b/src/plugin-slots/NotificationSlot/index.jsx new file mode 100644 index 000000000..f8b21e15a --- /dev/null +++ b/src/plugin-slots/NotificationSlot/index.jsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { PluginSlot } from '@openedx/frontend-plugin-framework'; + +const NotificationTraySlot = () => ( + +); + +export default NotificationTraySlot; diff --git a/src/studio-header/HeaderBody.tsx b/src/studio-header/HeaderBody.tsx index 598aec381..7abc9b474 100644 --- a/src/studio-header/HeaderBody.tsx +++ b/src/studio-header/HeaderBody.tsx @@ -18,6 +18,7 @@ import UserMenu from './UserMenu'; import BrandNav from './BrandNav'; import NavDropdownMenu from './NavDropdownMenu'; import messages from './messages'; +import NotificationTraySlot from '../plugin-slots/NotificationSlot'; const HeaderBody = ({ logo, @@ -116,6 +117,9 @@ const HeaderBody = ({ )} + {searchButtonAction && (