+
{isDisplaySequenceLevel && backButtonTitle ? (
) : (
-
+
{intl.formatMessage(messages.courseOutlineTitle)}
)}
+ {onToggleCollapse && (
+ )}
);
-
- if (isActiveEntranceExam || currentSidebar !== ID) {
+ if (isActiveEntranceExam) {
return null;
}
-
if (courseOutlineStatus === LOADING) {
return (
{
{sidebarHeading}
);
};
-
-CourseOutlineTray.ID = ID;
-
-export default CourseOutlineTray;
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.scss b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.scss
index a574f02736..ed06a6424a 100644
--- a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.scss
+++ b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.scss
@@ -13,7 +13,10 @@
}
.outline-sidebar-heading-wrapper {
- border: 1px solid #d7d3d1;
+ border-width: var(--learning-sidebar-outline-heading-wrapper-border-width, 1px);
+ border-style: solid;
+ border-color: var(--learning-sidebar-outline-heading-wrapper-border-color, var(--pgn-color-light-700));
+ background-color: var(--learning-sidebar-outline-heading-wrapper-bg-color, var(--pgn-color-light-200));
&.sticky {
position: sticky;
@@ -24,12 +27,18 @@
.outline-sidebar-heading {
font-weight: var(--pgn-typography-font-weight-bold);
+ color: var(--learning-sidebar-outline-heading-text-color, var(--pgn-color-dark-500));
}
}
.course-sidebar-section {
- background: var(--pgn-color-white);
- border: 1px solid #d7d3d1;
+ background: var(--learning-sidebar-outline-section-bg-color, var(--pgn-color-white));
+
+ border-width: var(--learning-sidebar-outline-section-border-width, 1px);
+ border-style: solid;
+ border-color: var(--learning-sidebar-outline-section-border-color, var(--pgn-color-light-700));
+
+ margin-bottom: var(--learning-sidebar-outline-section-margin-bottom, var(--pgn-spacing-spacer-2));
button {
line-height: 1.75rem;
@@ -38,11 +47,17 @@
&:focus::before {
border-radius: 0;
}
+
+ padding: var(--learning-sidebar-outline-section-padding-y, var(--pgn-spacing-spacer-3-5)) var(--learning-sidebar-outline-section-padding-x, var(--pgn-spacing-spacer-4));
+ }
+ &.active-section button {
+ background-color: var(--learning-sidebar-outline-section-active-bg-color, var(--pgn-color-light-100));
}
}
.outline-sidebar-toggle-btn {
font-size: 1.5rem;
+ background-color: var(--learning-sidebar-outline-toggle-btn-bg-color, var(--pgn-color-light-200));
.collapsed & {
transform: scale(-1, 1);
@@ -78,7 +93,7 @@
}
&:last-child .pgn_collapsible {
- margin-bottom: 0px !important;
+ margin-bottom: 0 !important;
}
}
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.test.jsx b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.test.jsx
index aba41c8291..653a9bc8d5 100644
--- a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.test.jsx
+++ b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.test.jsx
@@ -74,7 +74,7 @@ describe('
', () => {
await expect(screen.queryByText(messages.loading.defaultMessage)).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: section.title })).toBeInTheDocument();
expect(screen.getByRole('button', { name: messages.toggleCourseOutlineTrigger.defaultMessage })).toBeInTheDocument();
- expect(screen.getByRole('button', { name: `${sequence.title} , ${courseOutlineMessages.incompleteAssignment.defaultMessage}` })).toBeInTheDocument();
+ expect(screen.getByRole('button', { name: new RegExp(`${sequence.title} , ${courseOutlineMessages.incompleteAssignment.defaultMessage}`) })).toBeInTheDocument();
expect(screen.getByText(unit.title)).toBeInTheDocument();
});
@@ -115,13 +115,13 @@ describe('
', () => {
const sidebarBackBtn = screen.queryByRole('button', { name: section.title });
expect(sidebarBackBtn).toBeInTheDocument();
- expect(screen.getByRole('button', { name: `${sequence.title} , ${courseOutlineMessages.incompleteAssignment.defaultMessage}` })).toBeInTheDocument();
+ expect(screen.getByRole('button', { name: new RegExp(`${sequence.title} , ${courseOutlineMessages.incompleteAssignment.defaultMessage}`) })).toBeInTheDocument();
await user.click(sidebarBackBtn);
expect(sidebarBackBtn).not.toBeInTheDocument();
expect(screen.queryByText(messages.courseOutlineTitle.defaultMessage)).toBeInTheDocument();
- await user.click(screen.getByRole('button', { name: `${section.title} , ${courseOutlineMessages.incompleteSection.defaultMessage}` }));
+ await user.click(screen.getByRole('button', { name: new RegExp(`${section.title} , ${courseOutlineMessages.incompleteSection.defaultMessage}`) }));
expect(screen.queryByRole('button', { name: section.title })).toBeInTheDocument();
});
});
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.tsx b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.tsx
new file mode 100644
index 0000000000..88f30fcfbe
--- /dev/null
+++ b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTray.tsx
@@ -0,0 +1,20 @@
+import { CourseOutline } from './CourseOutline';
+import { ID } from './constants';
+import { useCourseOutlineSidebar } from './hooks';
+
+const CourseOutlineTray = () => {
+ const {
+ currentSidebar,
+ shouldDisplayFullScreen,
+ handleToggleCollapse,
+ } = useCourseOutlineSidebar();
+
+ if (currentSidebar !== ID) {
+ return null;
+ }
+ return
;
+};
+
+CourseOutlineTray.ID = ID;
+
+export default CourseOutlineTray;
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTrigger.jsx b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTrigger.jsx
index abccd14aed..3d6039598f 100644
--- a/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTrigger.jsx
+++ b/src/courseware/course/sidebar/sidebars/course-outline/CourseOutlineTrigger.jsx
@@ -4,17 +4,17 @@ import { useIntl } from '@edx/frontend-platform/i18n';
import { IconButton } from '@openedx/paragon';
import { MenuOpen as MenuOpenIcon } from '@openedx/paragon/icons';
-import { useCourseOutlineSidebar } from './hooks';
+import { useCourseOutlineData, useCourseOutlineSidebar } from './hooks';
import { ID } from './constants';
import messages from './messages';
const CourseOutlineTrigger = ({ isMobileView }) => {
const intl = useIntl();
+ const { isActiveEntranceExam } = useCourseOutlineData();
const {
currentSidebar,
shouldDisplayFullScreen,
handleToggleCollapse,
- isActiveEntranceExam,
} = useCourseOutlineSidebar();
const isDisplayForDesktopView = !isMobileView && !shouldDisplayFullScreen && currentSidebar !== ID;
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.jsx b/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.tsx
similarity index 97%
rename from src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.jsx
rename to src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.tsx
index cb026fb46b..7664b02357 100644
--- a/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.jsx
+++ b/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.test.tsx
@@ -1,6 +1,6 @@
import { render, screen } from '@testing-library/react';
-import CompletionIcon from './CompletionIcon';
+import { CompletionIcon } from './CompletionIcon';
describe('CompletionIcon', () => {
it('renders check circle icon when completion is equal to total and completion tracking is enabled', () => {
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.jsx b/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.tsx
similarity index 70%
rename from src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.jsx
rename to src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.tsx
index 9b3a855db8..a3fa67f5d7 100644
--- a/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.jsx
+++ b/src/courseware/course/sidebar/sidebars/course-outline/components/CompletionIcon.tsx
@@ -1,4 +1,3 @@
-import PropTypes from 'prop-types';
import {
CheckCircle as CheckCircleIcon,
LmsCompletionSolid as LmsCompletionSolidIcon,
@@ -6,7 +5,15 @@ import {
import { DashedCircleIcon } from '../icons';
-const CompletionIcon = ({ completionStat: { completed = 0, total = 0 }, enabled }) => {
+export interface CompletionIconProps {
+ completionStat: {
+ completed: number;
+ total: number;
+ };
+ enabled: boolean;
+}
+
+export const CompletionIcon = ({ completionStat: { completed = 0, total = 0 }, enabled }: CompletionIconProps) => {
const percentage = total !== 0 ? Math.min((completed / total) * 100, 100) : 0;
const remainder = 100 - percentage;
@@ -20,12 +27,4 @@ const CompletionIcon = ({ completionStat: { completed = 0, total = 0 }, enabled
}
};
-CompletionIcon.propTypes = {
- completionStat: PropTypes.shape({
- completed: PropTypes.number,
- total: PropTypes.number,
- }).isRequired,
- enabled: PropTypes.bool.isRequired,
-};
-
export default CompletionIcon;
diff --git a/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSection.jsx b/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSection.jsx
index 034575743b..92881ffcc2 100644
--- a/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSection.jsx
+++ b/src/courseware/course/sidebar/sidebars/course-outline/components/SidebarSection.jsx
@@ -1,3 +1,6 @@
+import {
+ CourseOverviewSectionCompletionIconSlot,
+} from '@src/plugin-slots/CourseOutlineSidebarSectionCompletionIconSlot';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useIntl } from '@edx/frontend-platform/i18n';
@@ -5,8 +8,7 @@ import { Button, Icon } from '@openedx/paragon';
import { ChevronRight as ChevronRightIcon } from '@openedx/paragon/icons';
import courseOutlineMessages from '@src/course-home/outline-tab/messages';
-import CompletionIcon from './CompletionIcon';
-import { useCourseOutlineSidebar } from '../hooks';
+import { useCourseOutlineData } from '../hooks';
const SidebarSection = ({ section, handleSelectSection }) => {
const intl = useIntl();
@@ -18,13 +20,17 @@ const SidebarSection = ({ section, handleSelectSection }) => {
completionStat,
} = section;
- const { activeSequenceId, isEnabledCompletionTracking } = useCourseOutlineSidebar();
+ const { activeSequenceId, isEnabledCompletionTracking } = useCourseOutlineData();
const isActiveSection = sequenceIds.includes(activeSequenceId);
const sectionTitle = (
<>
-
+
{title}
@@ -41,13 +47,10 @@ const SidebarSection = ({ section, handleSelectSection }) => {
);
return (
-
+