diff --git a/src/courseware/course/Course.jsx b/src/courseware/course/Course.jsx
index 748d8a40..7458fe7a 100644
--- a/src/courseware/course/Course.jsx
+++ b/src/courseware/course/Course.jsx
@@ -90,6 +90,7 @@ function Course({
courseId={courseId}
sectionId={section ? section.id : null}
sequenceId={sequenceId}
+ unitId={unitId}
//* * [MM-P2P] Experiment */
mmp2p={MMP2P}
/>
diff --git a/src/courseware/course/CourseBreadcrumbs.jsx b/src/courseware/course/CourseBreadcrumbs.jsx
index 14d76d31..013941fb 100644
--- a/src/courseware/course/CourseBreadcrumbs.jsx
+++ b/src/courseware/course/CourseBreadcrumbs.jsx
@@ -5,32 +5,18 @@ import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHome } from '@fortawesome/free-solid-svg-icons';
import { useSelector } from 'react-redux';
-import { Hyperlink, MenuItem, SelectMenu } from '@edx/paragon';
+import { SelectMenu } from '@edx/paragon';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
-import {
- sendTrackingLogEvent,
- sendTrackEvent,
-} from '@edx/frontend-platform/analytics';
import { useModel, useModels } from '../../generic/model-store';
/** [MM-P2P] Experiment */
import { MMP2PFlyoverTrigger } from '../../experiments/mm-p2p';
+import ConnectedJumpNavMenuItem from './JumpNavMenuItem';
function CourseBreadcrumb({
- content, withSeparator,
+ content, withSeparator, courseId, unitId,
}) {
- const defaultContent = content.filter(destination => destination.default)[0];
- const administrator = getAuthenticatedUser() ? getAuthenticatedUser().administrator : false;
- function logEvent(target) {
- const eventName = 'edx.ui.lms.jump_nav.selected';
- const payload = {
- target_name: target.label,
- id: target.id,
- current_id: defaultContent.id,
- widget_placement: 'breadcrumb',
- };
- sendTrackEvent(eventName, payload);
- sendTrackingLogEvent(eventName, payload);
- }
+ const defaultContent = content.filter(destination => destination.default)[0] || { id: courseId, label: '' };
+ const { administrator } = getAuthenticatedUser();
return (
<>
@@ -46,20 +32,20 @@ function CourseBreadcrumb({
>
{ getConfig().ENABLE_JUMPNAV !== 'true' || content.length < 2 || !administrator
? (
- {defaultContent.label}
+
+ {defaultContent.label}
)
: (
{content.map(item => (
-
+
))}
)}
@@ -72,58 +58,71 @@ CourseBreadcrumb.propTypes = {
content: PropTypes.arrayOf(
PropTypes.shape({
default: PropTypes.bool,
- url: PropTypes.string,
id: PropTypes.string,
label: PropTypes.string,
}),
).isRequired,
+ unitId: PropTypes.string,
withSeparator: PropTypes.bool,
+ courseId: PropTypes.string,
};
CourseBreadcrumb.defaultProps = {
withSeparator: false,
+ unitId: null,
+ courseId: null,
};
export default function CourseBreadcrumbs({
courseId,
sectionId,
sequenceId,
+ unitId,
/** [MM-P2P] Experiment */
mmp2p,
}) {
const course = useModel('coursewareMeta', courseId);
const courseStatus = useSelector(state => state.courseware.courseStatus);
- const sections = course ? Object.fromEntries(useModels('sections', course.sectionIds).map(section => [section.id, section])) : null;
- const possibleSequences = sections && sectionId ? sections[sectionId].sequenceIds : [];
- const sequences = Object.fromEntries(useModels('sequences', possibleSequences).map(sequence => [sequence.id, sequence]));
const sequenceStatus = useSelector(state => state.courseware.sequenceStatus);
+ const allSequencesInSections = Object.fromEntries(useModels('sections', course.sectionIds).map(section => [section.id, {
+ default: section.id === sectionId,
+ title: section.title,
+ sequences: useModels('sequences', section.sequenceIds),
+ }]));
+
const links = useMemo(() => {
- const temp = [];
+ const chapters = [];
+ const sequentials = [];
if (courseStatus === 'loaded' && sequenceStatus === 'loaded') {
- temp.push(course.sectionIds.map(id => ({
- id,
- label: sections[id].title,
- default: (id === sectionId),
- // navigate to first sequence in section, (TODO: navigate to first incomplete sequence in section)
- url: `${getConfig().BASE_URL}/course/${courseId}/${sections[id].sequenceIds[0]}`,
- })));
- temp.push(sections[sectionId].sequenceIds.map(id => ({
- id,
- label: sequences[id].title,
- default: id === sequenceId,
- // first unit it section (TODO: navigate to first incomplete in sequence)
- url: `${getConfig().BASE_URL}/course/${courseId}/${sequences[id].id}/${sequences[id].unitIds[0]}`,
- })));
+ Object.entries(allSequencesInSections).forEach(([id, section]) => {
+ chapters.push({
+ id,
+ label: section.title,
+ default: section.default,
+ sequences: section.sequences,
+ });
+ if (section.default) {
+ section.sequences.forEach(sequence => {
+ sequentials.push({
+ id: sequence.id,
+ label: sequence.title,
+ default: sequence.id === sequenceId,
+ sequences: [sequence],
+ });
+ });
+ }
+ });
}
- return temp;
- }, [courseStatus, sections, sequences]);
+ return [chapters, sequentials];
+ }, [courseStatus, sequenceStatus, allSequencesInSections]);
+
return (