Compare commits

...

4 Commits

Author SHA1 Message Date
Brian Smith
4edaa1a2a4 feat: update to header with new FPF pluginProps (#1525) 2024-11-22 15:21:03 -05:00
Brian Smith
6f1159617e feat: add frontend-plugin-framework header slot (#1504) 2024-10-23 11:45:57 -04:00
Brian Smith
8cc6b8cdde feat(deps): update header to 5.6.0 (#1502) 2024-10-22 19:19:47 -04:00
edX requirements bot
048488fb25 chore: update browserslist DB (#1499)
Co-authored-by: abdullahwaheed <42172960+abdullahwaheed@users.noreply.github.com>
2024-10-21 11:08:06 -07:00
9 changed files with 115 additions and 17 deletions

20
package-lock.json generated
View File

@@ -12,7 +12,7 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/browserslist-config": "1.2.0",
"@edx/frontend-component-header": "^5.3.3",
"@edx/frontend-component-header": "^5.8.0",
"@edx/frontend-lib-learning-assistant": "^2.2.4",
"@edx/frontend-lib-special-exams": "^3.1.3",
"@edx/frontend-platform": "^8.0.0",
@@ -2323,18 +2323,19 @@
}
},
"node_modules/@edx/frontend-component-header": {
"version": "5.3.4",
"resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-5.3.4.tgz",
"integrity": "sha512-niuaXu0+qWPHud9Bs1pqmNXvZc9jpf8WS270/2YEH5owokd+BiDwQ6MWkvS9qbuQIVGPGTSZFFTttUKmQO5O0A==",
"license": "AGPL-3.0",
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-5.8.0.tgz",
"integrity": "sha512-AgLgt1y5vrqx6cU3IDr7HKngJImTN48gCIaXdCQ4YhR4PpX3p+ZS9R5Ih0dapWtvnX0Oo2hT2ggUKORV0h90rw==",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "6.6.0",
"@fortawesome/free-brands-svg-icons": "6.6.0",
"@fortawesome/free-regular-svg-icons": "6.6.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@openedx/frontend-plugin-framework": "^1.3.0",
"axios-mock-adapter": "1.22.0",
"babel-polyfill": "6.26.0",
"classnames": "^2.5.1",
"jest-environment-jsdom": "^29.7.0",
"react-responsive": "8.2.0",
"react-transition-group": "4.4.5"
@@ -2344,7 +2345,8 @@
"@openedx/paragon": ">= 21.5.7 < 23.0.0",
"prop-types": "^15.5.10",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
"react-dom": "^16.9.0 || ^17.0.0",
"react-router-dom": "^6.14.2"
}
},
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-brands-svg-icons": {
@@ -7274,9 +7276,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001668",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz",
"integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==",
"version": "1.0.30001669",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz",
"integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==",
"funding": [
{
"type": "opencollective",

View File

@@ -35,7 +35,7 @@
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/browserslist-config": "1.2.0",
"@edx/frontend-component-header": "^5.3.3",
"@edx/frontend-component-header": "^5.8.0",
"@edx/frontend-lib-learning-assistant": "^2.2.4",
"@edx/frontend-lib-special-exams": "^3.1.3",
"@edx/frontend-platform": "^8.0.0",

View File

@@ -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';
@@ -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)}`} />

View File

@@ -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';
@@ -28,7 +28,7 @@ const CourseAccessErrorPage = ({ intl }) => {
if (courseStatus === LOADING) {
return (
<>
<Header />
<HeaderSlot />
<PageLoading
srMessage={intl.formatMessage(messages.loading)}
/>
@@ -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"

View File

@@ -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;
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -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;

View File

@@ -1,5 +1,6 @@
# `frontend-app-learning` Plugin Slots
* [`header_slot`](./HeaderSlot/)
* [`footer_slot`](./FooterSlot/)
* [`sequence_container_slot`](./SequenceContainerSlot/)
* [`unit_title_slot`](./UnitTitleSlot/)

View File

@@ -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';
@@ -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)} />