Skip to content

Commit 6f11596

Browse files
feat: add frontend-plugin-framework header slot (#1504)
1 parent 8cc6b8c commit 6f11596

File tree

7 files changed

+103
-7
lines changed

7 files changed

+103
-7
lines changed

src/course-home/goal-unsubscribe/GoalUnsubscribe.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom';
33
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
44
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
55

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

@@ -38,7 +38,7 @@ const GoalUnsubscribe = ({ intl }) => {
3838

3939
return (
4040
<>
41-
<Header showUserDropdown={false} />
41+
<HeaderSlot showUserDropdown={false} />
4242
<main id="main-content" className="container my-5 text-center">
4343
{isLoading && (
4444
<PageLoading srMessage={`${intl.formatMessage(messages.loading)}`} />

src/generic/CourseAccessErrorPage.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React, { useEffect } from 'react';
2-
import { LearningHeader as Header } from '@edx/frontend-component-header';
32
import { useParams, Navigate } from 'react-router-dom';
43
import { useDispatch, useSelector } from 'react-redux';
54
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
65
import FooterSlot from '@openedx/frontend-slot-footer';
76
import { LOADED, LOADING } from '@src/constants';
7+
import HeaderSlot from '../plugin-slots/HeaderSlot';
88
import useActiveEnterpriseAlert from '../alerts/active-enteprise-alert';
99
import { AlertList } from './user-messages';
1010
import { fetchDiscussionTab } from '../course-home/data/thunks';
@@ -28,7 +28,7 @@ const CourseAccessErrorPage = ({ intl }) => {
2828
if (courseStatus === LOADING) {
2929
return (
3030
<>
31-
<Header />
31+
<HeaderSlot />
3232
<PageLoading
3333
srMessage={intl.formatMessage(messages.loading)}
3434
/>
@@ -41,7 +41,7 @@ const CourseAccessErrorPage = ({ intl }) => {
4141
}
4242
return (
4343
<>
44-
<Header />
44+
<HeaderSlot />
4545
<main id="main-content" className="container my-5 text-center" data-testid="access-denied-main">
4646
<AlertList
4747
topic="outline"

src/plugin-slots/HeaderSlot/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Header Slot
2+
3+
### Slot ID: `header_slot`
4+
### Props:
5+
* `courseOrg`
6+
* `courseNumber`
7+
* `courseTitle`
8+
* `showUserDropdown`
9+
10+
## Description
11+
12+
This slot is used to replace/modify/hide the entire learning header.
13+
14+
## Example
15+
16+
The following `env.config.jsx` will replace the learning header entirely.
17+
18+
![Screenshot of custom component](./images/header_custom_component.png)
19+
20+
```js
21+
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
22+
23+
const config = {
24+
pluginSlots: {
25+
header_slot: {
26+
keepDefault: false,
27+
plugins: [
28+
{
29+
op: PLUGIN_OPERATIONS.Insert,
30+
widget: {
31+
id: 'custom_header_component',
32+
type: DIRECT_PLUGIN,
33+
RenderWidget: ({courseOrg, courseNumber, courseTitle, showUserDropdown}) => (
34+
<>
35+
<h1 style={{textAlign: 'center'}}>🌞</h1>
36+
<p style={{textAlign: 'center'}}>courseOrg: {courseOrg}</p>
37+
<p style={{textAlign: 'center'}}>courseNumber: {courseNumber}</p>
38+
<p style={{textAlign: 'center'}}>courseTitle: {courseTitle}</p>
39+
<p style={{textAlign: 'center'}}>showUserDropdown: {showUserDropdown ? '👍' : '👎'}</p>
40+
<h1 style={{textAlign: 'center'}}>🌚</h1>
41+
</>
42+
),
43+
},
44+
},
45+
]
46+
}
47+
},
48+
}
49+
50+
export default config;
51+
```
Loading

src/plugin-slots/HeaderSlot/index.jsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import PropTypes from 'prop-types';
2+
import { PluginSlot } from '@openedx/frontend-plugin-framework';
3+
4+
import { LearningHeader as Header } from '@edx/frontend-component-header';
5+
6+
const HeaderSlot = ({
7+
courseOrg, courseNumber, courseTitle, showUserDropdown,
8+
}) => (
9+
<PluginSlot
10+
id="header_slot"
11+
slotOptions={{
12+
mergeProps: true,
13+
}}
14+
pluginProps={{
15+
courseOrg,
16+
courseNumber,
17+
courseTitle,
18+
showUserDropdown,
19+
}}
20+
>
21+
<Header
22+
courseOrg={courseOrg}
23+
courseNumber={courseNumber}
24+
courseTitle={courseTitle}
25+
showUserDropdown={showUserDropdown}
26+
/>
27+
</PluginSlot>
28+
);
29+
30+
HeaderSlot.propTypes = {
31+
courseOrg: PropTypes.string,
32+
courseNumber: PropTypes.string,
33+
courseTitle: PropTypes.string,
34+
showUserDropdown: PropTypes.bool,
35+
};
36+
37+
HeaderSlot.defaultProps = {
38+
courseOrg: null,
39+
courseNumber: null,
40+
courseTitle: null,
41+
showUserDropdown: true,
42+
};
43+
44+
export default HeaderSlot;

src/plugin-slots/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# `frontend-app-learning` Plugin Slots
22

3+
* [`header_slot`](./HeaderSlot/)
34
* [`footer_slot`](./FooterSlot/)
45
* [`sequence_container_slot`](./SequenceContainerSlot/)
56
* [`unit_title_slot`](./UnitTitleSlot/)

src/tab-page/TabPage.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { useDispatch, useSelector } from 'react-redux';
55
import { Navigate } from 'react-router-dom';
66

77
import { Toast } from '@openedx/paragon';
8-
import { LearningHeader as Header } from '@edx/frontend-component-header';
98
import FooterSlot from '@openedx/frontend-slot-footer';
9+
import HeaderSlot from '../plugin-slots/HeaderSlot';
1010
import PageLoading from '../generic/PageLoading';
1111
import { getAccessDeniedRedirectUrl } from '../shared/access';
1212
import { useModel } from '../generic/model-store';
@@ -64,7 +64,7 @@ const TabPage = ({ intl, ...props }) => {
6464
</>
6565
)}
6666

67-
<Header courseOrg={org} courseNumber={number} courseTitle={title} />
67+
<HeaderSlot courseOrg={org} courseNumber={number} courseTitle={title} />
6868

6969
{courseStatus === 'loading' && (
7070
<PageLoading srMessage={intl.formatMessage(messages.loading)} />

0 commit comments

Comments
 (0)