Skip to content

Commit 5b7f76b

Browse files
KristinAokifeanil
authored andcommitted
fix: breadcrumb preview link
1 parent cf4bea3 commit 5b7f76b

File tree

6 files changed

+308
-236
lines changed

6 files changed

+308
-236
lines changed

src/courseware/course/CourseBreadcrumbs.test.jsx

Lines changed: 0 additions & 134 deletions
This file was deleted.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import React, { useState } from 'react';
2+
import { getConfig } from '@edx/frontend-platform';
3+
import {
4+
useToggle,
5+
ModalPopup,
6+
Menu,
7+
} from '@openedx/paragon';
8+
import { Link, useLocation } from 'react-router-dom';
9+
import JumpNavMenuItem from '../JumpNavMenuItem';
10+
11+
interface Props {
12+
content: {
13+
default: boolean,
14+
id: string,
15+
label: string,
16+
sequences: {
17+
id: string,
18+
}[],
19+
} [];
20+
withSeparator: boolean | false,
21+
separator: string | '';
22+
courseId: string;
23+
sequenceId: string | '';
24+
unitId: string | '';
25+
isStaff: boolean | false;
26+
}
27+
28+
const BreadcrumbItem: React.FC<Props> = ({
29+
content,
30+
withSeparator,
31+
separator,
32+
courseId,
33+
sequenceId,
34+
unitId,
35+
isStaff,
36+
}) => {
37+
const defaultContent = content.filter(
38+
(destination: { default: boolean }) => destination.default,
39+
)[0] || { id: courseId, label: '', sequences: [] };
40+
41+
const showRegularLink = getConfig().ENABLE_JUMPNAV !== 'true' || content.length < 2 || !isStaff;
42+
const [isOpen, open, close] = useToggle(false);
43+
const [target, setTarget] = useState(null);
44+
45+
const { pathname } = useLocation();
46+
const isPreview = pathname.startsWith('/preview');
47+
const baseUrl = defaultContent.sequences.length
48+
? `/course/${courseId}/${defaultContent.sequences[0].id}`
49+
: `/course/${courseId}/${defaultContent.id}`;
50+
const link = isPreview ? `/preview${baseUrl}` : baseUrl;
51+
return (
52+
<>
53+
{withSeparator && separator && (
54+
<li className="col-auto p-0 mx-2 text-primary-500 text-truncate text-nowrap" role="presentation" aria-hidden>{separator}</li>
55+
)}
56+
57+
<li
58+
style={{
59+
overflow: 'hidden',
60+
textOverflow: 'ellipsis',
61+
whiteSpace: 'nowrap',
62+
}}
63+
data-testid="breadcrumb-item"
64+
>
65+
{showRegularLink ? (
66+
<Link
67+
className="text-primary-500"
68+
to={link}
69+
>
70+
{defaultContent.label}
71+
</Link>
72+
) : (
73+
<>
74+
{
75+
// @ts-ignore
76+
<a className="text-primary-500" variant="link" onClick={open} ref={setTarget}>
77+
{defaultContent.label}
78+
</a>
79+
}
80+
<ModalPopup positionRef={target} isOpen={isOpen} onClose={close}>
81+
<Menu>
82+
{content.map((item) => (
83+
<JumpNavMenuItem
84+
key={item.label}
85+
isDefault={item.default}
86+
sequences={item.sequences}
87+
courseId={courseId}
88+
title={item.label}
89+
currentSequence={sequenceId}
90+
currentUnit={unitId}
91+
onClick={close}
92+
/>
93+
))}
94+
</Menu>
95+
</ModalPopup>
96+
</>
97+
)}
98+
</li>
99+
</>
100+
);
101+
};
102+
103+
export default BreadcrumbItem;

src/courseware/course/CourseBreadcrumbs.jsx renamed to src/courseware/course/breadcrumbs/CourseBreadcrumbs.jsx

Lines changed: 11 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,12 @@
1-
import React, { useMemo, useState } from 'react';
1+
import React, { useMemo } from 'react';
22
import PropTypes from 'prop-types';
3-
import { getConfig } from '@edx/frontend-platform';
43
import { FormattedMessage } from '@edx/frontend-platform/i18n';
54
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
65
import { faHome } from '@fortawesome/free-solid-svg-icons';
76
import { useSelector } from 'react-redux';
8-
import { useToggle, ModalPopup, Menu } from '@openedx/paragon';
97
import { Link } from 'react-router-dom';
10-
import { useModel, useModels } from '../../generic/model-store';
11-
import JumpNavMenuItem from './JumpNavMenuItem';
12-
13-
const CourseBreadcrumb = ({
14-
content,
15-
withSeparator,
16-
courseId,
17-
sequenceId,
18-
unitId,
19-
isStaff,
20-
}) => {
21-
const defaultContent = content.filter(
22-
(destination) => destination.default,
23-
)[0] || { id: courseId, label: '', sequences: [] };
24-
25-
const showRegularLink = getConfig().ENABLE_JUMPNAV !== 'true' || content.length < 2 || !isStaff;
26-
const [isOpen, open, close] = useToggle(false);
27-
const [target, setTarget] = useState(null);
28-
return (
29-
<>
30-
{withSeparator && (
31-
<li className="col-auto p-0 mx-2 text-primary-500 text-truncate text-nowrap" role="presentation" aria-hidden>/</li>
32-
)}
33-
34-
<li
35-
style={{
36-
overflow: 'hidden',
37-
textOverflow: 'ellipsis',
38-
whiteSpace: 'nowrap',
39-
}}
40-
data-testid="breadcrumb-item"
41-
>
42-
{showRegularLink ? (
43-
<Link
44-
className="text-primary-500"
45-
to={
46-
defaultContent.sequences.length
47-
? `/course/${courseId}/${defaultContent.sequences[0].id}`
48-
: `/course/${courseId}/${defaultContent.id}`
49-
}
50-
>
51-
{defaultContent.label}
52-
</Link>
53-
) : (
54-
<>
55-
{
56-
// eslint-disable-next-line
57-
<a className="text-primary-500" onClick={open} ref={setTarget}>
58-
{defaultContent.label}
59-
</a>
60-
}
61-
<ModalPopup positionRef={target} isOpen={isOpen} onClose={close}>
62-
<Menu>
63-
{content.map((item) => (
64-
<JumpNavMenuItem
65-
key={item.label}
66-
isDefault={item.default}
67-
sequences={item.sequences}
68-
courseId={courseId}
69-
title={item.label}
70-
currentSequence={sequenceId}
71-
currentUnit={unitId}
72-
onClick={close}
73-
/>
74-
))}
75-
</Menu>
76-
</ModalPopup>
77-
</>
78-
)}
79-
</li>
80-
</>
81-
);
82-
};
83-
CourseBreadcrumb.propTypes = {
84-
content: PropTypes.arrayOf(
85-
PropTypes.shape({
86-
default: PropTypes.bool,
87-
id: PropTypes.string,
88-
label: PropTypes.string,
89-
}),
90-
).isRequired,
91-
sequenceId: PropTypes.string,
92-
unitId: PropTypes.string,
93-
withSeparator: PropTypes.bool,
94-
courseId: PropTypes.string,
95-
isStaff: PropTypes.bool,
96-
};
97-
98-
CourseBreadcrumb.defaultProps = {
99-
withSeparator: false,
100-
sequenceId: null,
101-
unitId: null,
102-
courseId: null,
103-
isStaff: null,
104-
};
8+
import { useModel, useModels } from '../../../generic/model-store';
9+
import BreadcrumbItem from './BreadcrumbItem';
10510

10611
const CourseBreadcrumbs = ({
10712
courseId,
@@ -110,14 +15,16 @@ const CourseBreadcrumbs = ({
11015
unitId,
11116
isStaff,
11217
}) => {
113-
const course = useModel('coursewareMeta', courseId);
18+
const course = useModel('coursewareMeta', courseId);
11419
const courseStatus = useSelector((state) => state.courseware.courseStatus);
11520
const sequenceStatus = useSelector(
11621
(state) => state.courseware.sequenceStatus,
11722
);
23+
console.log( useModels('sections', course.sectionIds));
24+
11825

11926
const allSequencesInSections = Object.fromEntries(
120-
useModels('sections', course.sectionIds).map((section) => [
27+
useModels('sections', course.sectionIds)?.map((section) => [
12128
section.id,
12229
{
12330
default: section.id === sectionId,
@@ -152,6 +59,8 @@ const CourseBreadcrumbs = ({
15259
}
15360
return [chapters, sequentials];
15461
}, [courseStatus, sequenceStatus, allSequencesInSections]);
62+
console.log(links);
63+
15564

15665
return (
15766
<nav aria-label="breadcrumb" className="d-inline-block col-sm-10 mb-3">
@@ -171,14 +80,15 @@ const CourseBreadcrumbs = ({
17180
</Link>
17281
</li>
17382
{links.map((content, i) => (
174-
<CourseBreadcrumb
83+
<BreadcrumbItem
17584
// eslint-disable-next-line react/no-array-index-key
17685
key={i}
17786
courseId={courseId}
17887
sequenceId={sequenceId}
17988
content={content}
18089
unitId={unitId}
18190
withSeparator
91+
separator="/"
18292
isStaff={isStaff}
18393
/>
18494
))}

0 commit comments

Comments
 (0)