Skip to content

Commit 0fe0d64

Browse files
committed
fixup! fixup! fixup! feat: Syllabus page for learner MFE
1 parent ab98147 commit 0fe0d64

File tree

8 files changed

+116
-79
lines changed

8 files changed

+116
-79
lines changed

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
frontend-slot-syllabus-tab
1+
frontend-plugin-syllabus-tab
22
##########################
33

44
Purpose
@@ -13,7 +13,7 @@ In ``frontend-app-learning`` create a file called ``env.config.jsx`` with the
1313
following contents:
1414

1515
```javascript
16-
import { slotConfig } from '@open-craft/frontend-slot-syllabus-tab';
16+
import { slotConfig } from '@open-craft/frontend-plugin-syllabus-tab';
1717
1818
1919
const config = {
@@ -28,5 +28,5 @@ export default config;
2828
Install this repo as:
2929

3030
```bash
31-
npm install --no-save https://github.com/open-craft/frontend-slot-syllabus-tab.git
31+
npm install --no-save https://github.com/open-craft/frontend-plugin-syllabus-tab.git
3232
```

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"name": "@open-craft/frontend-slot-syllabus-tab",
2+
"name": "@open-craft/frontend-plugin-syllabus-tab",
33
"version": "0.1.0",
44
"description": "Slot for frontend-app-learning to add a tab for displaying the syllabus",
55
"repository": {
66
"type": "git",
7-
"url": "git+https://github.com/open-craft/frontend-slot-syllabus-tab.git"
7+
"url": "git+https://github.com/open-craft/frontend-plugin-syllabus-tab.git"
88
},
99
"browserslist": [
1010
"extends @edx/browserslist-config"
@@ -19,12 +19,12 @@
1919
},
2020
"author": "OpenCraft",
2121
"license": "AGPL-3.0",
22-
"homepage": "https://github.com/open-craft/frontend-slot-syllabus-tab#readme",
22+
"homepage": "https://github.com/open-craft/frontend-plugin-syllabus-tab#readme",
2323
"publishConfig": {
2424
"access": "public"
2525
},
2626
"bugs": {
27-
"url": "https://github.com/open-craft/frontend-slot-syllabus-tab/issues"
27+
"url": "https://github.com/open-craft/frontend-plugin-syllabus-tab/issues"
2828
},
2929
"peerDependencies": {
3030
"@edx/frontend-platform": "^8.0.0",

src/components/PrintSyllabus.tsx

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import * as React from "react";
2+
import { useRef } from "react";
3+
import { useIntl } from '@edx/frontend-platform/i18n';
4+
import messages from "../messages";
5+
import {Button} from '@openedx/paragon';
6+
7+
export const PrintSyllabus = ({blockData}) => {
8+
const intl = useIntl()
9+
const iframeRef = useRef(null);
10+
const blocks = blockData?.blocks;
11+
const rootBlock = blockData?.blocks[blockData.root];
12+
const makeList = (items: string[] | null) => {
13+
if (!items) {
14+
return "";
15+
}
16+
const itemsList = items.filter(item => !!item).join("</li><li>");
17+
return itemsList
18+
? "<ul><li>" + items.filter(item => !!item).join("</li><li>") + "</li></ul>"
19+
: "";
20+
};
21+
const syllabusList = makeList(rootBlock.children.map(sectionId =>
22+
"<h1>" + blocks[sectionId].display_name + "</h1>" +
23+
makeList(blocks[sectionId].children.map(subsectionId =>
24+
"<h2>" + blocks[subsectionId].display_name + "</h2>" +
25+
makeList(blocks[subsectionId].children.map(unitId =>
26+
"<h3>" + blocks[unitId].display_name + "</h3>" +
27+
makeList(blocks[unitId].children.flatMap((blockId) => (
28+
blocks[blockId]?.links?.map(link => link.text)
29+
)))
30+
))
31+
))
32+
));
33+
34+
35+
const srcdoc = `<html>
36+
<head>
37+
<title>${intl.formatMessage(messages.syllabusTitle)}</title><!-- -->
38+
<style>
39+
body > ul {
40+
padding: 0.125rem;
41+
margin: 0;
42+
list-style: none;
43+
}
44+
45+
body > ul > li {
46+
border: 1px solid black;
47+
margin: 0.5rem 0;
48+
padding: 0 0.5rem;
49+
}
50+
51+
body > ul > li > ul {
52+
break-inside: avoid;
53+
break-after: auto;
54+
list-style: none;
55+
}
56+
body ul ul ul ul li:before {
57+
content: '\\01F517 ';
58+
margin-right: 0.5rem;
59+
}
60+
body ul ul ul ul {
61+
list-style: none;
62+
padding-left: 0;
63+
}
64+
body ul > li {
65+
break-inside: avoid;
66+
break-after: auto;
67+
}
68+
body ul > li ul {
69+
break-after: auto;
70+
}
71+
72+
ul {
73+
margin: 0;
74+
padding-left: 1rem;
75+
}
76+
</style>
77+
</head>
78+
<body>
79+
${syllabusList}
80+
</body>
81+
</html>
82+
`;
83+
return (
84+
<div className="d-flex justify-content-end my-2 flex-column">
85+
<iframe srcDoc={srcdoc} ref={iframeRef} className="d-flex w-100" style={{height:'800px'}}></iframe>
86+
<Button variant="outline-primary"
87+
onClick={() => iframeRef.current.contentWindow.print()}>Print</Button>
88+
</div>
89+
)
90+
}

src/components/Syllabus.tsx

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,12 @@
11
import { Button, Icon, SearchField } from '@openedx/paragon';
22
import { Link as LinkIcon } from '@openedx/paragon/icons';
33
import * as React from 'react';
4-
import { useEffect, useRef, useState } from 'react';
4+
import { useEffect, useState } from 'react';
55
import { useParams } from 'react-router-dom';
66
import { Block, BlockMap, UsageId, useBlockData, usePanels, } from '../hooks';
77
import { BlockCollapsible } from './BlockCollapsible';
88
import { HighlightMatch } from './HighlightMatch';
9-
10-
const PrintSyllabus = ({blockData}) => {
11-
const iframeRef = useRef(null);
12-
const blocks = blockData?.blocks;
13-
const rootBlock = blockData?.blocks[blockData.root];
14-
const makeList = (items: string[] | null) => {
15-
if (!items) {
16-
return "";
17-
}
18-
const itemsList = items.filter(item => !!item).join("</li><li>");
19-
return itemsList
20-
? "<ul><li>" + items.filter(item => !!item).join("</li><li>") + "</li></ul>"
21-
: "";
22-
};
23-
const syllabusList = makeList(rootBlock.children.map(sectionId =>
24-
blocks[sectionId].display_name +
25-
makeList(blocks[sectionId].children.map(subsectionId =>
26-
blocks[subsectionId].display_name +
27-
makeList(blocks[subsectionId].children.map(unitId =>
28-
blocks[unitId].display_name +
29-
makeList(blocks[unitId].children.flatMap((blockId) => (
30-
blocks[blockId]?.links?.map(link => link.text)
31-
)))
32-
))
33-
))
34-
));
35-
36-
37-
const srcdoc = `<html>
38-
<head>
39-
<title>Syllabus</title>
40-
<style>
41-
body > ul {
42-
break-inside: avoid;
43-
break-after: auto;
44-
}
45-
ul ul {
46-
break-inside: avoid;
47-
break-before: avoid;
48-
break-after: avoid;
49-
}
50-
li {
51-
break-inside: avoid;
52-
}
53-
ul {
54-
margin: 0;
55-
padding-left: 1rem;
56-
list-style: square;
57-
}
58-
</style>
59-
</head>
60-
<body>
61-
${syllabusList}
62-
</body>
63-
</html>
64-
`;
65-
return (
66-
<div className="d-flex justify-content-end my-2">
67-
<iframe srcDoc={srcdoc} ref={iframeRef} className="d-none"></iframe>
68-
<Button variant="outline-primary"
69-
onClick={() => iframeRef.current.contentWindow.print()}>Print</Button>
70-
</div>
71-
)
72-
}
9+
import { PrintSyllabus } from "./PrintSyllabus";
7310

7411
const filteredBlocks = (
7512
rootId: UsageId | undefined,

src/components/SyllabusTabLink.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const SyllabusTabLink = () => {
1717
className={classNames('nav-item flex-shrink-0 nav-link', { active: !!match })}
1818
to={generatePath(SYLLABUS_ROUTE, { courseId })}
1919
>
20-
{intl.formatMessage(messages.syllabusTabTitle)}
20+
{intl.formatMessage(messages.syllabusTitle)}
2121
</Link>
2222
);
2323
};

src/hooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const getCourseBlocksUrl = (courseId: string) => {
6161
url.searchParams.append('student_view_data', 'video,html,problem');
6262
url.searchParams.append('username', username);
6363
return url.toString();
64-
// ?username=kshitij&course_id=course-v1%3AOpenedX%2BDemoX%2BDemoCourse&depth=all`,)
64+
6565
};
6666

6767
export const useBlockData = (courseId?: string) => {

src/messages.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import { defineMessages } from '@edx/frontend-platform/i18n';
22

33
const messages = defineMessages({
4-
syllabusTabTitle: {
5-
id: 'plugins.syllabus.tab.title',
4+
syllabusTitle: {
5+
id: 'plugins.syllabus.title',
66
defaultMessage: 'Syllabus',
7-
description: 'Title of the syllabus tab.',
7+
description: 'For use in various places, e.g. the tab title.',
88
},
9+
collapseAll: {
10+
id: 'plugins.syllabus.collapseAll',
11+
defaultMessage: 'Collapse all',
12+
description: 'Label for the button that collapses the course syllabus.',
13+
},
14+
expandAll: {
15+
id: 'plugins.syllabus.expandAll',
16+
defaultMessage: 'Expand all',
17+
description: 'Label for the button that expands the course syllabus.',
18+
}
919
});
1020

1121
export default messages;

0 commit comments

Comments
 (0)