Skip to content

Commit 07ca2eb

Browse files
committed
Merge branch 'master' into chris/FAL-4292-selection-states
2 parents afb4aa5 + 9072bb6 commit 07ca2eb

File tree

78 files changed

+1789
-574
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1789
-574
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN=false
3737
ENABLE_TAGGING_TAXONOMY_PAGES=true
3838
ENABLE_CERTIFICATE_PAGE=true
3939
ENABLE_COURSE_IMPORT_IN_LIBRARY=false
40+
ENABLE_COURSE_OUTLINE_NEW_DESIGN=false
4041
BBB_LEARN_MORE_URL=''
4142
HOTJAR_APP_ID=''
4243
HOTJAR_VERSION=6

.env.development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ ENABLE_ASSETS_PAGE=false
3838
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN=true
3939
ENABLE_CERTIFICATE_PAGE=true
4040
ENABLE_COURSE_IMPORT_IN_LIBRARY=true
41+
ENABLE_COURSE_OUTLINE_NEW_DESIGN=true
4142
ENABLE_NEW_VIDEO_UPLOAD_PAGE=true
4243
ENABLE_TAGGING_TAXONOMY_PAGES=true
4344
BBB_LEARN_MORE_URL=''

.env.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ ENABLE_ASSETS_PAGE=false
3434
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN=true
3535
ENABLE_CERTIFICATE_PAGE=true
3636
ENABLE_COURSE_IMPORT_IN_LIBRARY=true
37+
ENABLE_COURSE_OUTLINE_NEW_DESIGN=false
3738
ENABLE_TAGGING_TAXONOMY_PAGES=true
3839
BBB_LEARN_MORE_URL=''
3940
INVITE_STUDENTS_EMAIL_TO="[email protected]"

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"@openedx/frontend-plugin-framework": "^1.7.0",
6464
"@openedx/paragon": "^23.5.0",
6565
"@redux-devtools/extension": "^3.3.0",
66-
"@reduxjs/toolkit": "2.11.1",
66+
"@reduxjs/toolkit": "2.11.2",
6767
"@tanstack/react-query": "5.90.12",
6868
"@tinymce/tinymce-react": "^6.0.0",
6969
"classnames": "2.5.1",

src/course-libraries/CourseLibraries.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,15 @@ export const CourseLibraries = () => {
198198
<SubHeader
199199
title={intl.formatMessage(messages.headingTitle)}
200200
subtitle={intl.formatMessage(messages.headingSubtitle)}
201-
headerActions={!showReviewAlert && outOfSyncCount > 0 && tabKey === CourseLibraryTabs.all && (
201+
headerActions={(!showReviewAlert && outOfSyncCount > 0 && tabKey === CourseLibraryTabs.all) ? (
202202
<Button
203203
variant="primary"
204204
onClick={onAlertReview}
205205
iconBefore={Cached}
206206
>
207207
{intl.formatMessage(messages.reviewUpdatesBtn)}
208208
</Button>
209-
)}
209+
) : null}
210210
hideBorder
211211
/>
212212
<section className="mb-4">

src/course-outline/CourseOutline.test.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getConfig } from '@edx/frontend-platform';
1+
import { getConfig, setConfig } from '@edx/frontend-platform';
22
import { cloneDeep } from 'lodash';
33
import { closestCorners } from '@dnd-kit/core';
44
import { logError } from '@edx/frontend-platform/logging';
@@ -17,6 +17,7 @@ import {
1717
act, fireEvent, initializeMocks, render, screen, waitFor, within,
1818
} from '@src/testUtils';
1919
import { XBlock } from '@src/data/types';
20+
import { userEvent } from '@testing-library/user-event';
2021
import {
2122
getCourseBestPracticesApiUrl,
2223
getCourseLaunchApiUrl,
@@ -182,12 +183,10 @@ describe('<CourseOutline />', () => {
182183
});
183184

184185
it('render CourseOutline component correctly', async () => {
185-
const { getByText } = renderComponent();
186+
renderComponent();
186187

187-
await waitFor(() => {
188-
expect(getByText(messages.headingTitle.defaultMessage)).toBeInTheDocument();
189-
expect(getByText(messages.headingSubtitle.defaultMessage)).toBeInTheDocument();
190-
});
188+
expect(await screen.findByText('Demonstration Course')).toBeInTheDocument();
189+
expect(await screen.findByText(messages.headingSubtitle.defaultMessage)).toBeInTheDocument();
191190
});
192191

193192
it('logs an error when syncDiscussionsTopics encounters an API failure', async () => {
@@ -2486,4 +2485,20 @@ describe('<CourseOutline />', () => {
24862485
});
24872486
expect(axiosMock.history.delete[0].url).toBe(getDownstreamApiUrl(courseSectionMock.id));
24882487
});
2488+
2489+
it('check that the new status bar and expand bar is shown when flag is set', async () => {
2490+
setConfig({
2491+
...getConfig(),
2492+
ENABLE_COURSE_OUTLINE_NEW_DESIGN: 'true',
2493+
});
2494+
renderComponent();
2495+
const btn = await screen.findByRole('button', { name: 'Collapse all' });
2496+
expect(btn).toBeInTheDocument();
2497+
expect(await screen.findByRole('link', { name: 'View live' })).toBeInTheDocument();
2498+
expect(await screen.findByRole('button', { name: 'Add' })).toBeInTheDocument();
2499+
expect(await screen.findByRole('button', { name: 'More actions' })).toBeInTheDocument();
2500+
const user = userEvent.setup();
2501+
await user.click(btn);
2502+
expect(await screen.findByRole('button', { name: 'Expand all' })).toBeInTheDocument();
2503+
});
24892504
});

src/course-outline/CourseOutline.tsx

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { useState, useEffect, useCallback } from 'react';
22
import { useIntl } from '@edx/frontend-platform/i18n';
3+
import { getConfig } from '@edx/frontend-platform';
34
import {
45
Container,
56
Layout,
67
Row,
78
TransitionReplace,
89
Toast,
910
StandardModal,
11+
Button,
12+
ActionRow,
1013
} from '@openedx/paragon';
1114
import { Helmet } from 'react-helmet';
12-
import { CheckCircle as CheckCircleIcon } from '@openedx/paragon/icons';
15+
import { CheckCircle as CheckCircleIcon, CloseFullscreen, OpenInFull } from '@openedx/paragon/icons';
1316
import { useSelector } from 'react-redux';
1417
import {
1518
arrayMove,
@@ -44,7 +47,6 @@ import {
4447
getTimedExamsFlag,
4548
} from './data/selectors';
4649
import { COURSE_BLOCK_NAMES } from './constants';
47-
import StatusBar from './status-bar/StatusBar';
4850
import EnableHighlightsModal from './enable-highlights-modal/EnableHighlightsModal';
4951
import SectionCard from './section-card/SectionCard';
5052
import SubsectionCard from './subsection-card/SubsectionCard';
@@ -61,9 +63,12 @@ import {
6163
} from './drag-helper/utils';
6264
import { useCourseOutline } from './hooks';
6365
import messages from './messages';
66+
import headerMessages from './header-navigations/messages';
6467
import { getTagsExportFile } from './data/api';
6568
import OutlineAddChildButtons from './OutlineAddChildButtons';
6669
import { SidebarProvider } from './common/context/SidebarContext';
70+
import { StatusBar } from './status-bar/StatusBar';
71+
import { LegacyStatusBar } from './status-bar/LegacyStatusBar';
6772

6873
const CourseOutline = () => {
6974
const intl = useIntl();
@@ -142,6 +147,9 @@ const CourseOutline = () => {
142147
resetScrollState,
143148
} = useCourseOutline({ courseId });
144149

150+
// Show the new actions bar if it is enabled in the configuration.
151+
// This is a temporary flag until the new design feature is fully implemented.
152+
const showNewActionsBar = getConfig().ENABLE_COURSE_OUTLINE_NEW_DESIGN?.toString().toLowerCase() === 'true';
145153
// Use `setToastMessage` to show the toast.
146154
const [toastMessage, setToastMessage] = useState<string | null>(null);
147155

@@ -315,8 +323,9 @@ const CourseOutline = () => {
315323
) : null}
316324
</TransitionReplace>
317325
<SubHeader
318-
title={intl.formatMessage(messages.headingTitle)}
326+
title={courseName}
319327
subtitle={intl.formatMessage(messages.headingSubtitle)}
328+
hideBorder
320329
headerActions={(
321330
<CourseOutlineHeaderActionsSlot
322331
isReIndexShow={isReIndexShow}
@@ -330,6 +339,23 @@ const CourseOutline = () => {
330339
/>
331340
)}
332341
/>
342+
{showNewActionsBar
343+
? (
344+
<StatusBar
345+
courseId={courseId}
346+
isLoading={isLoading}
347+
statusBarData={statusBarData}
348+
/>
349+
) : (
350+
<LegacyStatusBar
351+
courseId={courseId}
352+
isLoading={isLoading}
353+
statusBarData={statusBarData}
354+
openEnableHighlightsModal={openEnableHighlightsModal}
355+
handleVideoSharingOptionChange={handleVideoSharingOptionChange}
356+
/>
357+
)}
358+
<hr className="mt-4 mb-0 w-100 text-light-400" />
333359
<Layout
334360
lg={[{ span: 9 }, { span: 3 }]}
335361
md={[{ span: 9 }, { span: 3 }]}
@@ -340,14 +366,24 @@ const CourseOutline = () => {
340366
<Layout.Element>
341367
<article>
342368
<div>
369+
{showNewActionsBar && (
370+
<ActionRow className="mt-3">
371+
{Boolean(sectionsList.length) && (
372+
<Button
373+
variant="outline-primary"
374+
id="expand-collapse-all-button"
375+
data-testid="expand-collapse-all-button"
376+
iconBefore={isSectionsExpanded ? CloseFullscreen : OpenInFull}
377+
onClick={headerNavigationsActions.handleExpandAll}
378+
>
379+
{isSectionsExpanded
380+
? intl.formatMessage(headerMessages.collapseAllButton)
381+
: intl.formatMessage(headerMessages.expandAllButton)}
382+
</Button>
383+
)}
384+
</ActionRow>
385+
)}
343386
<section className="course-outline-section">
344-
<StatusBar
345-
courseId={courseId}
346-
isLoading={isLoading}
347-
statusBarData={statusBarData}
348-
openEnableHighlightsModal={openEnableHighlightsModal}
349-
handleVideoSharingOptionChange={handleVideoSharingOptionChange}
350-
/>
351387
{!errors?.outlineIndexApi && (
352388
<div className="pt-4">
353389
{sections.length ? (

src/course-outline/card-header/TitleButton.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ const TitleButton = ({
4747
onClick={onTitleClick}
4848
title={title}
4949
>
50-
{prefixIcon}
50+
<div className="mr-2">
51+
{prefixIcon}
52+
</div>
5153
<span className={`${namePrefix}-card-title mb-0 truncate-1-line`}>
5254
{title}
5355
</span>

src/course-outline/card-header/TitleLink.tsx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,23 @@ const TitleLink = ({
1414
namePrefix,
1515
prefixIcon,
1616
}: TitleLinkProps) => (
17-
<Button
18-
as={Link}
19-
variant="tertiary"
20-
data-testid={`${namePrefix}-card-header__title-link`}
21-
className="item-card-header__title-btn align-items-end"
22-
to={titleLink}
23-
title={title}
24-
>
25-
{prefixIcon}
26-
<span className={`${namePrefix}-card-title mb-0 truncate-1-line`}>
27-
{title}
28-
</span>
29-
</Button>
17+
<>
18+
<div className="mr-2">
19+
{prefixIcon}
20+
</div>
21+
<Button
22+
as={Link}
23+
variant="tertiary"
24+
data-testid={`${namePrefix}-card-header__title-link`}
25+
className="item-card-header__title-btn align-items-end"
26+
to={titleLink}
27+
title={title}
28+
>
29+
<span className={`${namePrefix}-card-title mb-0 truncate-1-line text-left`}>
30+
{title}
31+
</span>
32+
</Button>
33+
</>
3034
);
3135

3236
export default TitleLink;

0 commit comments

Comments
 (0)