Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add plugin slots for progress page components #44

Open
wants to merge 1 commit into
base: opencraft-release/redwood.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions src/course-home/progress-tab/ProgressTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,21 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { breakpoints, useWindowSize } from '@openedx/paragon';

import CertificateStatus from './certificate-status/CertificateStatus';
import CourseCompletion from './course-completion/CourseCompletion';
import CourseGrade from './grades/course-grade/CourseGrade';
import DetailedGrades from './grades/detailed-grades/DetailedGrades';
import GradeSummary from './grades/grade-summary/GradeSummary';
import ProgressHeader from './ProgressHeader';
import RelatedLinks from './related-links/RelatedLinks';

import ProgressTabCertificateStatusSlot from '../../plugin-slots/ProgressTabCertificateStatusSlot';
import ProgressTabCourseGradeSlot from '../../plugin-slots/ProgressTabCourseGradeSlot';
import ProgressTabGradeBreakdownSlot from '../../plugin-slots/ProgressTabGradeBreakdownSlot';
import ProgressTabRelatedLinksSlot from '../../plugin-slots/ProgressTabRelatedLinksSlot';
import { useModel } from '../../generic/model-store';

const ProgressTab = () => {
const {
courseId,
} = useSelector(state => state.courseHome);

const {
gradesFeatureIsFullyLocked, disableProgressGraph,
} = useModel('progress', courseId);

const applyLockedOverlay = gradesFeatureIsFullyLocked ? 'locked-overlay' : '';
const { disableProgressGraph } = useModel('progress', courseId);

const windowWidth = useWindowSize().width;
if (windowWidth === undefined) {
Expand All @@ -39,18 +34,15 @@ const ProgressTab = () => {
{/* Main body */}
<div className="col-12 col-md-8 p-0">
{!disableProgressGraph && <CourseCompletion />}
{!wideScreen && <CertificateStatus />}
<CourseGrade />
<div className={`grades my-4 p-4 rounded raised-card ${applyLockedOverlay}`} aria-hidden={gradesFeatureIsFullyLocked}>
<GradeSummary />
<DetailedGrades />
</div>
{!wideScreen && <ProgressTabCertificateStatusSlot courseId={courseId} />}
<ProgressTabCourseGradeSlot courseId={courseId} />
<ProgressTabGradeBreakdownSlot courseId={courseId} />
</div>

{/* Side panel */}
<div className="col-12 col-md-4 p-0 px-md-4">
{wideScreen && <CertificateStatus />}
<RelatedLinks />
{wideScreen && <ProgressTabCertificateStatusSlot courseId={courseId} />}
<ProgressTabRelatedLinksSlot courseId={courseId} />
</div>
</div>
</>
Expand Down
44 changes: 44 additions & 0 deletions src/plugin-slots/ProgressTabCertificateStatusSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Progress Tab Certificate Status Slot

### Slot ID: `progress_tab_certificate_status_slot`
### Props:
* `courseId`

## Description

This slot is used to replace or modify the Certificate Status component in the
Progress Tab.

## Example

The following `env.config.jsx` will render the `course_id` and `unit_id` of the course as `<p>` elements in a `<div>`.

![Screenshot of Content added after the Sequence Container](./images/post_sequence_container.png)

```js
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
progress_tab_certificate_status_slot: {
plugins: [
{
// Insert custom content after certificate status
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_certificate_status_content',
type: DIRECT_PLUGIN,
RenderWidget: ({courseId}) => (
<div>
<p>📚: {courseId}</p>
</div>
),
},
},
]
}
},
}

export default config;
```
20 changes: 20 additions & 0 deletions src/plugin-slots/ProgressTabCertificateStatusSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import CertificateStatus from '../../course-home/progress-tab/certificate-status/CertificateStatus';

const ProgressTabCertificateStatusSlot = ({ courseId }) => (
<PluginSlot
id="progress_tab_certificate_status_slot"
pluginProps={{
courseId,
}}
>
<CertificateStatus />
</PluginSlot>
);

ProgressTabCertificateStatusSlot.propTypes = {
courseId: PropTypes.string.isRequired,
};

export default ProgressTabCertificateStatusSlot;
43 changes: 43 additions & 0 deletions src/plugin-slots/ProgressTabCourseGradeSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Progress Tab Course Grade Slot

### Slot ID: `progress_tab_course_grade_slot`
### Props:
* `courseId`

## Description

This slot is used to replace or modify the Course Grades view in the Progress Tab.

## Example

The following `env.config.jsx` will render the `course_id` and `unit_id` of the course as `<p>` elements in a `<div>`.

![Screenshot of Content added after the Sequence Container](./images/post_sequence_container.png)

```js
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
progress_tab_course_grade_slot: {
plugins: [
{
// Insert custom content after course grade widget
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_course_grade_content',
type: DIRECT_PLUGIN,
RenderWidget: ({courseId}) => (
<div>
<p>📚: {courseId}</p>
</div>
),
},
},
]
}
},
}

export default config;
```
20 changes: 20 additions & 0 deletions src/plugin-slots/ProgressTabCourseGradeSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import CourseGrade from '../../course-home/progress-tab/grades/course-grade/CourseGrade';

const ProgressTabCourseGradeSlot = ({ courseId }) => (
<PluginSlot
id="progress_tab_course_grade_slot"
pluginProps={{
courseId,
}}
>
<CourseGrade />
</PluginSlot>
);

ProgressTabCourseGradeSlot.propTypes = {
courseId: PropTypes.string.isRequired,
};

export default ProgressTabCourseGradeSlot;
43 changes: 43 additions & 0 deletions src/plugin-slots/ProgressTabGradeBreakdownSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Progress Tab Grade Summary Slot

### Slot ID: `progress_tab_grade_summary_slot`
### Props:
* `courseId`

## Description

This slot is used to replace or modify the Grade Summary view in the Progress Tab.

## Example

The following `env.config.jsx` will render the `course_id` and `unit_id` of the course as `<p>` elements in a `<div>`.

![Screenshot of Content added after the Sequence Container](./images/post_sequence_container.png)

```js
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
progress_tab_grade_summary_slot: {
plugins: [
{
// Insert custom content after grade summary widget
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_grade_summary_content',
type: DIRECT_PLUGIN,
RenderWidget: ({courseId}) => (
<div>
<p>📚: {courseId}</p>
</div>
),
},
},
]
}
},
}

export default config;
```
33 changes: 33 additions & 0 deletions src/plugin-slots/ProgressTabGradeBreakdownSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useModel } from '@src/generic/model-store';
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import React from 'react';
import DetailedGrades from '../../course-home/progress-tab/grades/detailed-grades/DetailedGrades';
import GradeSummary from '../../course-home/progress-tab/grades/grade-summary/GradeSummary';

const ProgressTabGradeBreakdownSlot = ({ courseId }) => {
const { gradesFeatureIsFullyLocked } = useModel('progress', courseId);
const applyLockedOverlay = gradesFeatureIsFullyLocked ? 'locked-overlay' : '';
return (
<PluginSlot
id="progress_tab_grade_breakdown_slot"
pluginProps={{
courseId,
}}
>
<div
className={`grades my-4 p-4 rounded raised-card ${applyLockedOverlay}`}
aria-hidden={gradesFeatureIsFullyLocked}
>
<GradeSummary />
<DetailedGrades />
</div>
</PluginSlot>
);
};

ProgressTabGradeBreakdownSlot.propTypes = {
courseId: PropTypes.string.isRequired,
};

export default ProgressTabGradeBreakdownSlot;
43 changes: 43 additions & 0 deletions src/plugin-slots/ProgressTabRelatedLinksSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Progress Tab Related Links Slot

### Slot ID: `progress_tab_related_links_slot`
### Props:
* `courseId`

## Description

This slot is used to replace or modify the related links view in the Progress Tab.

## Example

The following `env.config.jsx` will render the `course_id` and `unit_id` of the course as `<p>` elements in a `<div>`.

![Screenshot of Content added after the Sequence Container](./images/post_sequence_container.png)

```js
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';

const config = {
pluginSlots: {
progress_tab_related_links_slot: {
plugins: [
{
// Insert custom content after related links widget
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'custom_related_links_content',
type: DIRECT_PLUGIN,
RenderWidget: ({courseId}) => (
<div>
<p>📚: {courseId}</p>
</div>
),
},
},
]
}
},
}

export default config;
```
20 changes: 20 additions & 0 deletions src/plugin-slots/ProgressTabRelatedLinksSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import PropTypes from 'prop-types';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import RelatedLinks from '../../course-home/progress-tab/related-links/RelatedLinks';

const ProgressTabRelatedLinksSlot = ({ courseId }) => (
<PluginSlot
id="progress_tab_related_links_slot"
pluginProps={{
courseId,
}}
>
<RelatedLinks />
</PluginSlot>
);

ProgressTabRelatedLinksSlot.propTypes = {
courseId: PropTypes.string.isRequired,
};

export default ProgressTabRelatedLinksSlot;
Loading