Skip to content

Commit d0a8778

Browse files
xitij2000farhaanbukhsh
authored andcommitted
feat: Add slots to add tab links for courses
Adds new slot that allow adding new links to course tabs.
1 parent f8381e7 commit d0a8778

File tree

6 files changed

+137
-31
lines changed

6 files changed

+137
-31
lines changed

src/course-tabs/CourseTabLink.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import classNames from 'classnames';
2+
import React from 'react';
3+
4+
interface CourseTabLinkProps {
5+
slug: string;
6+
activeTabSlug?: string;
7+
url: string;
8+
title: string;
9+
}
10+
11+
export const CourseTabLink = ({
12+
slug, activeTabSlug, url, title,
13+
}: CourseTabLinkProps) => (
14+
<a
15+
href={url}
16+
className={classNames('nav-item flex-shrink-0 nav-link', { active: slug === activeTabSlug })}
17+
>
18+
{title}
19+
</a>
20+
);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { CourseTabLink } from '@src/course-tabs/CourseTabLink';
2+
import React from 'react';
3+
4+
interface CourseTabLinkListProps {
5+
tabs: Array<{
6+
title: string;
7+
slug: string;
8+
url: string;
9+
}>,
10+
activeTabSlug?: string;
11+
}
12+
13+
export const CourseTabLinksList = ({ tabs, activeTabSlug }: CourseTabLinkListProps) => (
14+
<>
15+
{tabs.map(({ url, title, slug }) => (
16+
<CourseTabLink
17+
key={slug}
18+
url={url}
19+
slug={slug}
20+
title={title}
21+
activeTabSlug={activeTabSlug}
22+
/>
23+
))}
24+
</>
25+
);
Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
import React from 'react';
2-
import PropTypes from 'prop-types';
3-
import { useIntl } from '@edx/frontend-platform/i18n';
42
import classNames from 'classnames';
5-
6-
import messages from './messages';
7-
import Tabs from '../generic/tabs/Tabs';
3+
import { useIntl } from '@edx/frontend-platform/i18n';
4+
import { CourseTabLinksSlot } from '../plugin-slots/CourseTabLinksSlot';
85
import { CoursewareSearch, CoursewareSearchToggle } from '../course-home/courseware-search';
96
import { useCoursewareSearchState } from '../course-home/courseware-search/hooks';
107

8+
import Tabs from '../generic/tabs/Tabs';
9+
import messages from './messages';
10+
11+
interface CourseTabsNavigationProps {
12+
activeTabSlug?: string;
13+
className?: string | null;
14+
tabs: Array<{
15+
title: string;
16+
slug: string;
17+
url: string;
18+
}>;
19+
}
20+
1121
const CourseTabsNavigation = ({
12-
activeTabSlug, className, tabs,
13-
}) => {
22+
activeTabSlug = undefined,
23+
className = null,
24+
tabs,
25+
}:CourseTabsNavigationProps) => {
1426
const intl = useIntl();
1527
const { show } = useCoursewareSearchState();
1628

@@ -23,15 +35,7 @@ const CourseTabsNavigation = ({
2335
className="nav-underline-tabs"
2436
aria-label={intl.formatMessage(messages.courseMaterial)}
2537
>
26-
{tabs.map(({ url, title, slug }) => (
27-
<a
28-
key={slug}
29-
className={classNames('nav-item flex-shrink-0 nav-link', { active: slug === activeTabSlug })}
30-
href={url}
31-
>
32-
{title}
33-
</a>
34-
))}
38+
<CourseTabLinksSlot tabs={tabs} activeTabSlug={activeTabSlug} />
3539
</Tabs>
3640
</div>
3741
<div className="search-toggle">
@@ -44,19 +48,4 @@ const CourseTabsNavigation = ({
4448
);
4549
};
4650

47-
CourseTabsNavigation.propTypes = {
48-
activeTabSlug: PropTypes.string,
49-
className: PropTypes.string,
50-
tabs: PropTypes.arrayOf(PropTypes.shape({
51-
title: PropTypes.string.isRequired,
52-
slug: PropTypes.string.isRequired,
53-
url: PropTypes.string.isRequired,
54-
})).isRequired,
55-
};
56-
57-
CourseTabsNavigation.defaultProps = {
58-
activeTabSlug: undefined,
59-
className: null,
60-
};
61-
6251
export default CourseTabsNavigation;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Course Tab Links Slot
2+
3+
### Slot ID: `org.openedx.frontend.learning.course_tab_links.v1`
4+
5+
### Props:
6+
* `activeTabSlug`: The slug of the currently active tab.
7+
8+
## Description
9+
10+
This slot is used to replace/modify/hide the course tabs.
11+
12+
## Example
13+
14+
### Added link to Course Tabs
15+
![Added "Custom Tab" to course tabs](./course-tabs-custom.png)
16+
17+
The following `env.config.jsx` will add a new course tab call "Custom Tab".
18+
19+
```js
20+
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
21+
22+
import { CourseTabLink } from '@src/course-tabs/CourseTabLink';
23+
24+
25+
const config = {
26+
pluginSlots: {
27+
"org.openedx.frontend.learning.course_tab_links.v1": {
28+
keepDefault: true,
29+
plugins: [
30+
{
31+
op: PLUGIN_OPERATIONS.Insert,
32+
widget: {
33+
id: 'custom_tab',
34+
type: DIRECT_PLUGIN,
35+
RenderWidget: ({ activeTabSlug })=> (
36+
<CourseTabLink
37+
url="/some/path"
38+
slug="custom-link"
39+
title="Custom Tab"
40+
activeTabSlug={activeTabSlug}
41+
/>
42+
),
43+
},
44+
},
45+
],
46+
},
47+
},
48+
}
49+
50+
export default config;
51+
```
13.1 KB
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { PluginSlot } from '@openedx/frontend-plugin-framework';
2+
import { CourseTabLinksList } from '@src/course-tabs/CourseTabLinksList';
3+
import React from 'react';
4+
5+
type CourseTabList = Array<{
6+
title: string;
7+
slug: string;
8+
url: string;
9+
}>;
10+
11+
export const CourseTabLinksSlot = ({ tabs, activeTabSlug }: {
12+
tabs: CourseTabList,
13+
activeTabSlug?: string
14+
}) => (
15+
<PluginSlot
16+
id="org.openedx.frontend.learning.course_tab_links.v1"
17+
pluginProps={{ activeTabSlug }}
18+
>
19+
<CourseTabLinksList tabs={tabs} activeTabSlug={activeTabSlug} />
20+
</PluginSlot>
21+
);

0 commit comments

Comments
 (0)