feat: Add slots to add tab links for courses
Adds new slot that allow adding new links to course tabs.
This commit is contained in:
committed by
Farhaan Bukhsh
parent
f8381e7900
commit
d0a8778015
20
src/course-tabs/CourseTabLink.tsx
Normal file
20
src/course-tabs/CourseTabLink.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
interface CourseTabLinkProps {
|
||||
slug: string;
|
||||
activeTabSlug?: string;
|
||||
url: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export const CourseTabLink = ({
|
||||
slug, activeTabSlug, url, title,
|
||||
}: CourseTabLinkProps) => (
|
||||
<a
|
||||
href={url}
|
||||
className={classNames('nav-item flex-shrink-0 nav-link', { active: slug === activeTabSlug })}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
);
|
||||
25
src/course-tabs/CourseTabLinksList.tsx
Normal file
25
src/course-tabs/CourseTabLinksList.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { CourseTabLink } from '@src/course-tabs/CourseTabLink';
|
||||
import React from 'react';
|
||||
|
||||
interface CourseTabLinkListProps {
|
||||
tabs: Array<{
|
||||
title: string;
|
||||
slug: string;
|
||||
url: string;
|
||||
}>,
|
||||
activeTabSlug?: string;
|
||||
}
|
||||
|
||||
export const CourseTabLinksList = ({ tabs, activeTabSlug }: CourseTabLinkListProps) => (
|
||||
<>
|
||||
{tabs.map(({ url, title, slug }) => (
|
||||
<CourseTabLink
|
||||
key={slug}
|
||||
url={url}
|
||||
slug={slug}
|
||||
title={title}
|
||||
activeTabSlug={activeTabSlug}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
@@ -1,16 +1,28 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import messages from './messages';
|
||||
import Tabs from '../generic/tabs/Tabs';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { CourseTabLinksSlot } from '../plugin-slots/CourseTabLinksSlot';
|
||||
import { CoursewareSearch, CoursewareSearchToggle } from '../course-home/courseware-search';
|
||||
import { useCoursewareSearchState } from '../course-home/courseware-search/hooks';
|
||||
|
||||
import Tabs from '../generic/tabs/Tabs';
|
||||
import messages from './messages';
|
||||
|
||||
interface CourseTabsNavigationProps {
|
||||
activeTabSlug?: string;
|
||||
className?: string | null;
|
||||
tabs: Array<{
|
||||
title: string;
|
||||
slug: string;
|
||||
url: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
const CourseTabsNavigation = ({
|
||||
activeTabSlug, className, tabs,
|
||||
}) => {
|
||||
activeTabSlug = undefined,
|
||||
className = null,
|
||||
tabs,
|
||||
}:CourseTabsNavigationProps) => {
|
||||
const intl = useIntl();
|
||||
const { show } = useCoursewareSearchState();
|
||||
|
||||
@@ -23,15 +35,7 @@ const CourseTabsNavigation = ({
|
||||
className="nav-underline-tabs"
|
||||
aria-label={intl.formatMessage(messages.courseMaterial)}
|
||||
>
|
||||
{tabs.map(({ url, title, slug }) => (
|
||||
<a
|
||||
key={slug}
|
||||
className={classNames('nav-item flex-shrink-0 nav-link', { active: slug === activeTabSlug })}
|
||||
href={url}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
))}
|
||||
<CourseTabLinksSlot tabs={tabs} activeTabSlug={activeTabSlug} />
|
||||
</Tabs>
|
||||
</div>
|
||||
<div className="search-toggle">
|
||||
@@ -44,19 +48,4 @@ const CourseTabsNavigation = ({
|
||||
);
|
||||
};
|
||||
|
||||
CourseTabsNavigation.propTypes = {
|
||||
activeTabSlug: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
tabs: PropTypes.arrayOf(PropTypes.shape({
|
||||
title: PropTypes.string.isRequired,
|
||||
slug: PropTypes.string.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
})).isRequired,
|
||||
};
|
||||
|
||||
CourseTabsNavigation.defaultProps = {
|
||||
activeTabSlug: undefined,
|
||||
className: null,
|
||||
};
|
||||
|
||||
export default CourseTabsNavigation;
|
||||
51
src/plugin-slots/CourseTabLinksSlot/README.md
Normal file
51
src/plugin-slots/CourseTabLinksSlot/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Course Tab Links Slot
|
||||
|
||||
### Slot ID: `org.openedx.frontend.learning.course_tab_links.v1`
|
||||
|
||||
### Props:
|
||||
* `activeTabSlug`: The slug of the currently active tab.
|
||||
|
||||
## Description
|
||||
|
||||
This slot is used to replace/modify/hide the course tabs.
|
||||
|
||||
## Example
|
||||
|
||||
### Added link to Course Tabs
|
||||

|
||||
|
||||
The following `env.config.jsx` will add a new course tab call "Custom Tab".
|
||||
|
||||
```js
|
||||
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
|
||||
|
||||
import { CourseTabLink } from '@src/course-tabs/CourseTabLink';
|
||||
|
||||
|
||||
const config = {
|
||||
pluginSlots: {
|
||||
"org.openedx.frontend.learning.course_tab_links.v1": {
|
||||
keepDefault: true,
|
||||
plugins: [
|
||||
{
|
||||
op: PLUGIN_OPERATIONS.Insert,
|
||||
widget: {
|
||||
id: 'custom_tab',
|
||||
type: DIRECT_PLUGIN,
|
||||
RenderWidget: ({ activeTabSlug })=> (
|
||||
<CourseTabLink
|
||||
url="/some/path"
|
||||
slug="custom-link"
|
||||
title="Custom Tab"
|
||||
activeTabSlug={activeTabSlug}
|
||||
/>
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config;
|
||||
```
|
||||
BIN
src/plugin-slots/CourseTabLinksSlot/course-tabs-custom.png
Normal file
BIN
src/plugin-slots/CourseTabLinksSlot/course-tabs-custom.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
21
src/plugin-slots/CourseTabLinksSlot/index.tsx
Normal file
21
src/plugin-slots/CourseTabLinksSlot/index.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { PluginSlot } from '@openedx/frontend-plugin-framework';
|
||||
import { CourseTabLinksList } from '@src/course-tabs/CourseTabLinksList';
|
||||
import React from 'react';
|
||||
|
||||
type CourseTabList = Array<{
|
||||
title: string;
|
||||
slug: string;
|
||||
url: string;
|
||||
}>;
|
||||
|
||||
export const CourseTabLinksSlot = ({ tabs, activeTabSlug }: {
|
||||
tabs: CourseTabList,
|
||||
activeTabSlug?: string
|
||||
}) => (
|
||||
<PluginSlot
|
||||
id="org.openedx.frontend.learning.course_tab_links.v1"
|
||||
pluginProps={{ activeTabSlug }}
|
||||
>
|
||||
<CourseTabLinksList tabs={tabs} activeTabSlug={activeTabSlug} />
|
||||
</PluginSlot>
|
||||
);
|
||||
Reference in New Issue
Block a user