From 05c1df77917f6f42cb25705eea0551399d9b410b Mon Sep 17 00:00:00 2001 From: "kshitij.sobti" Date: Fri, 4 Oct 2024 22:56:53 +0530 Subject: [PATCH] feat: Add plugin slots for progress page components Adds a slot for different components in the progress tab to allow them to be overridden with custom components. (cherry picked from commit 0c462fa80065d4d38090e276ac9ca847e646ed6f) --- src/course-home/progress-tab/ProgressTab.jsx | 28 +++++------- .../README.md | 44 +++++++++++++++++++ .../index.jsx | 20 +++++++++ .../ProgressTabCourseGradeSlot/README.md | 43 ++++++++++++++++++ .../ProgressTabCourseGradeSlot/index.jsx | 20 +++++++++ .../ProgressTabGradeBreakdownSlot/README.md | 43 ++++++++++++++++++ .../ProgressTabGradeBreakdownSlot/index.jsx | 33 ++++++++++++++ .../ProgressTabRelatedLinksSlot/README.md | 43 ++++++++++++++++++ .../ProgressTabRelatedLinksSlot/index.jsx | 20 +++++++++ 9 files changed, 276 insertions(+), 18 deletions(-) create mode 100644 src/plugin-slots/ProgressTabCertificateStatusSlot/README.md create mode 100644 src/plugin-slots/ProgressTabCertificateStatusSlot/index.jsx create mode 100644 src/plugin-slots/ProgressTabCourseGradeSlot/README.md create mode 100644 src/plugin-slots/ProgressTabCourseGradeSlot/index.jsx create mode 100644 src/plugin-slots/ProgressTabGradeBreakdownSlot/README.md create mode 100644 src/plugin-slots/ProgressTabGradeBreakdownSlot/index.jsx create mode 100644 src/plugin-slots/ProgressTabRelatedLinksSlot/README.md create mode 100644 src/plugin-slots/ProgressTabRelatedLinksSlot/index.jsx diff --git a/src/course-home/progress-tab/ProgressTab.jsx b/src/course-home/progress-tab/ProgressTab.jsx index 1b829037eb..585b12b2c4 100644 --- a/src/course-home/progress-tab/ProgressTab.jsx +++ b/src/course-home/progress-tab/ProgressTab.jsx @@ -2,14 +2,13 @@ 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 = () => { @@ -17,11 +16,7 @@ const ProgressTab = () => { 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) { @@ -39,18 +34,15 @@ const ProgressTab = () => { {/* Main body */}
{!disableProgressGraph && } - {!wideScreen && } - -
- - -
+ {!wideScreen && } + +
{/* Side panel */}
- {wideScreen && } - + {wideScreen && } +
diff --git a/src/plugin-slots/ProgressTabCertificateStatusSlot/README.md b/src/plugin-slots/ProgressTabCertificateStatusSlot/README.md new file mode 100644 index 0000000000..f4d29f3be3 --- /dev/null +++ b/src/plugin-slots/ProgressTabCertificateStatusSlot/README.md @@ -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 `

` elements in a `

`. + +![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}) => ( +
+

📚: {courseId}

+
+ ), + }, + }, + ] + } + }, +} + +export default config; +``` diff --git a/src/plugin-slots/ProgressTabCertificateStatusSlot/index.jsx b/src/plugin-slots/ProgressTabCertificateStatusSlot/index.jsx new file mode 100644 index 0000000000..b59cda13b9 --- /dev/null +++ b/src/plugin-slots/ProgressTabCertificateStatusSlot/index.jsx @@ -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 }) => ( + + + +); + +ProgressTabCertificateStatusSlot.propTypes = { + courseId: PropTypes.string.isRequired, +}; + +export default ProgressTabCertificateStatusSlot; diff --git a/src/plugin-slots/ProgressTabCourseGradeSlot/README.md b/src/plugin-slots/ProgressTabCourseGradeSlot/README.md new file mode 100644 index 0000000000..bf7190ecb0 --- /dev/null +++ b/src/plugin-slots/ProgressTabCourseGradeSlot/README.md @@ -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 `

` elements in a `

`. + +![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}) => ( +
+

📚: {courseId}

+
+ ), + }, + }, + ] + } + }, +} + +export default config; +``` diff --git a/src/plugin-slots/ProgressTabCourseGradeSlot/index.jsx b/src/plugin-slots/ProgressTabCourseGradeSlot/index.jsx new file mode 100644 index 0000000000..fd41276dd8 --- /dev/null +++ b/src/plugin-slots/ProgressTabCourseGradeSlot/index.jsx @@ -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 }) => ( + + + +); + +ProgressTabCourseGradeSlot.propTypes = { + courseId: PropTypes.string.isRequired, +}; + +export default ProgressTabCourseGradeSlot; diff --git a/src/plugin-slots/ProgressTabGradeBreakdownSlot/README.md b/src/plugin-slots/ProgressTabGradeBreakdownSlot/README.md new file mode 100644 index 0000000000..da8fdb657d --- /dev/null +++ b/src/plugin-slots/ProgressTabGradeBreakdownSlot/README.md @@ -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 `

` elements in a `

`. + +![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}) => ( +
+

📚: {courseId}

+
+ ), + }, + }, + ] + } + }, +} + +export default config; +``` diff --git a/src/plugin-slots/ProgressTabGradeBreakdownSlot/index.jsx b/src/plugin-slots/ProgressTabGradeBreakdownSlot/index.jsx new file mode 100644 index 0000000000..de37ba54da --- /dev/null +++ b/src/plugin-slots/ProgressTabGradeBreakdownSlot/index.jsx @@ -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 ( + +
+ + +
+
+ ); +}; + +ProgressTabGradeBreakdownSlot.propTypes = { + courseId: PropTypes.string.isRequired, +}; + +export default ProgressTabGradeBreakdownSlot; diff --git a/src/plugin-slots/ProgressTabRelatedLinksSlot/README.md b/src/plugin-slots/ProgressTabRelatedLinksSlot/README.md new file mode 100644 index 0000000000..c70a044d5a --- /dev/null +++ b/src/plugin-slots/ProgressTabRelatedLinksSlot/README.md @@ -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 `

` elements in a `

`. + +![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}) => ( +
+

📚: {courseId}

+
+ ), + }, + }, + ] + } + }, +} + +export default config; +``` diff --git a/src/plugin-slots/ProgressTabRelatedLinksSlot/index.jsx b/src/plugin-slots/ProgressTabRelatedLinksSlot/index.jsx new file mode 100644 index 0000000000..5b4c6264ec --- /dev/null +++ b/src/plugin-slots/ProgressTabRelatedLinksSlot/index.jsx @@ -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 }) => ( + + + +); + +ProgressTabRelatedLinksSlot.propTypes = { + courseId: PropTypes.string.isRequired, +}; + +export default ProgressTabRelatedLinksSlot;