Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add frontend-plugin-framework header slot #1504

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/course-home/goal-unsubscribe/GoalUnsubscribe.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';

import { LearningHeader as Header } from '@edx/frontend-component-header';
import HeaderSlot from '../../plugin-slots/HeaderSlot';
import PageLoading from '../../generic/PageLoading';
import { unsubscribeFromCourseGoal } from '../data/api';

Expand Down Expand Up @@ -38,7 +38,7 @@ const GoalUnsubscribe = ({ intl }) => {

return (
<>
<Header showUserDropdown={false} />
<HeaderSlot showUserDropdown={false} />
<main id="main-content" className="container my-5 text-center">
{isLoading && (
<PageLoading srMessage={`${intl.formatMessage(messages.loading)}`} />
Expand Down
6 changes: 3 additions & 3 deletions src/generic/CourseAccessErrorPage.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useEffect } from 'react';
import { LearningHeader as Header } from '@edx/frontend-component-header';
import { useParams, Navigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import FooterSlot from '@openedx/frontend-slot-footer';
import { LOADED, LOADING } from '@src/constants';
import HeaderSlot from '../plugin-slots/HeaderSlot';
import useActiveEnterpriseAlert from '../alerts/active-enteprise-alert';
import { AlertList } from './user-messages';
import { fetchDiscussionTab } from '../course-home/data/thunks';
Expand All @@ -28,7 +28,7 @@ const CourseAccessErrorPage = ({ intl }) => {
if (courseStatus === LOADING) {
return (
<>
<Header />
<HeaderSlot />
<PageLoading
srMessage={intl.formatMessage(messages.loading)}
/>
Expand All @@ -41,7 +41,7 @@ const CourseAccessErrorPage = ({ intl }) => {
}
return (
<>
<Header />
<HeaderSlot />
<main id="main-content" className="container my-5 text-center" data-testid="access-denied-main">
<AlertList
topic="outline"
Expand Down
51 changes: 51 additions & 0 deletions src/plugin-slots/HeaderSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Header Slot

### Slot ID: `header_slot`
### Props:
* `courseOrg`
* `courseNumber`
* `courseTitle`
* `showUserDropdown`

## Description

This slot is used to replace/modify/hide the entire learning header.

## Example

The following `env.config.jsx` will replace the learning header entirely.

![Screenshot of custom component](./images/header_custom_component.png)

```js
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
header_slot: {
keepDefault: false,
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_header_component',
type: DIRECT_PLUGIN,
RenderWidget: ({courseOrg, courseNumber, courseTitle, showUserDropdown}) => (
<>
<h1 style={{textAlign: 'center'}}>🌞</h1>
<p style={{textAlign: 'center'}}>courseOrg: {courseOrg}</p>
<p style={{textAlign: 'center'}}>courseNumber: {courseNumber}</p>
<p style={{textAlign: 'center'}}>courseTitle: {courseTitle}</p>
<p style={{textAlign: 'center'}}>showUserDropdown: {showUserDropdown ? '👍' : '👎'}</p>
<h1 style={{textAlign: 'center'}}>🌚</h1>
</>
),
},
},
]
}
},
}

export default config;
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions src/plugin-slots/HeaderSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';

import { LearningHeader as Header } from '@edx/frontend-component-header';

const HeaderSlot = ({
courseOrg, courseNumber, courseTitle, showUserDropdown,
}) => (
<PluginSlot
id="header_slot"
slotOptions={{
mergeProps: true,
}}
pluginProps={{
courseOrg,
courseNumber,
courseTitle,
showUserDropdown,
}}
>
<Header
courseOrg={courseOrg}
courseNumber={courseNumber}
courseTitle={courseTitle}
showUserDropdown={showUserDropdown}
/>
</PluginSlot>
);

HeaderSlot.propTypes = {
courseOrg: PropTypes.string,
courseNumber: PropTypes.string,
courseTitle: PropTypes.string,
showUserDropdown: PropTypes.bool,
};

HeaderSlot.defaultProps = {
courseOrg: null,
courseNumber: null,
courseTitle: null,
showUserDropdown: true,
};

export default HeaderSlot;
1 change: 1 addition & 0 deletions src/plugin-slots/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# `frontend-app-learning` Plugin Slots

* [`header_slot`](./HeaderSlot/)
* [`footer_slot`](./FooterSlot/)
* [`sequence_container_slot`](./SequenceContainerSlot/)
* [`unit_title_slot`](./UnitTitleSlot/)
4 changes: 2 additions & 2 deletions src/tab-page/TabPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useDispatch, useSelector } from 'react-redux';
import { Navigate } from 'react-router-dom';

import { Toast } from '@openedx/paragon';
import { LearningHeader as Header } from '@edx/frontend-component-header';
import FooterSlot from '@openedx/frontend-slot-footer';
import HeaderSlot from '../plugin-slots/HeaderSlot';
import PageLoading from '../generic/PageLoading';
import { getAccessDeniedRedirectUrl } from '../shared/access';
import { useModel } from '../generic/model-store';
Expand Down Expand Up @@ -64,7 +64,7 @@ const TabPage = ({ intl, ...props }) => {
</>
)}

<Header courseOrg={org} courseNumber={number} courseTitle={title} />
<HeaderSlot courseOrg={org} courseNumber={number} courseTitle={title} />

{courseStatus === 'loading' && (
<PageLoading srMessage={intl.formatMessage(messages.loading)} />
Expand Down
Loading